使用 Ansible 库将 Fabric 主机清单作为 Ansible 的清单(2017 版本)
免责
因为这是一段超级简化的代码,所以我只看到了大概的运行结果。
前提 – tí
请提供一种选项来将以下内容以中文原生语言进行释义:
前提 – 意味着事情发生或推理的基础。
这是在这种环境下的对话记录。
$ ansible --version
ansible 2.2.0.0
config file = /home/takei_kazuya/ansible/ansible.cfg
configured module search path = Default w/o overrides
$ fab --version
Fabric 1.12.0
Paramiko 1.17.2
总结一下就是
这里是适用于最新版本的”使用Ansible库存创建Fabric主机列表的简易配方”。
# 前略
from ansible.inventory import Inventory
from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager
ansible_loader = DataLoader()
ansible_var_manager = VariableManager()
ansible_inventory = Inventory(ansible_loader, ansible_var_manager, '/etc/ansible/hosts')
env.roledefs = ansible_inventory.get_group_dict()
# 以下略
本题
使用Fabric进行构建管理,同时在部署过程中采用Ansible时,希望使用Ansible的清单文件是一种常见情况。在Qiita上也有一篇文章讲述了如何从Fabric中美观地参考Ansible的清单文件。
所以,当我参考(或者说复制粘贴,除了库存文件)并执行时,
# 前略
from ansible.inventory import Inventory
inventory = Inventory('MY_INVENTORY')
env.roledefs = inventory.groups_list()
# 攻略
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/fabric/main.py", line 666, in main
docstring, callables, default = load_fabfile(fabfile)
File "/usr/lib/python2.6/site-packages/fabric/main.py", line 167, in load_fabfile
imported = importer(os.path.splitext(fabfile)[0])
File "/home/attakei/infra/fabfile.py", line 17, in <module>
ansible_inventory = Inventory(ansible_inventory_file)
TypeError: __init__() takes at least 3 arguments (2 given)
没有移动。 (Dong4 ka3 na2 kai1.)
我們將一邊查看最新的存儲庫,一邊逐漸進行修正。
Inventory的init方法的参数不同。
根据上述错误信息,看起来__init__的参数似乎与之前不同?
根据当前的Inventory.init,确实需要至少两个参数,而且inventory文件似乎是可选的。
那么,我们应该在最初的loader和variable_manager中传递什么呢?
我希望能够快速查看ansible-playbook的实体。
我觉得可以将ansible.parsing.dataloader.DataLoader的实例传递给loader,将ansible.vars.VariableManager的实例传递给variable_manager。
groups_list已经不存在了
当运行 Inventory() 时,上述的错误可以解决,但是现在的问题是 inventory.groups_list() 失败了。从代码上看,这个方法现在不存在。
根据笼统的理解,Inventory.get_group_dict() 看起来是一个替代方法。
这边是已经出来了。
# 前略
from ansible.inventory import Inventory
from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager
ansible_loader = DataLoader()
ansible_var_manager = VariableManager()
ansible_inventory = Inventory(ansible_loader, ansible_var_manager, '/etc/ansible/hosts')
env.roledefs = ansible_inventory.get_group_dict()
# 以下略
以下是需要補充的事項。
这段代码只能指定一个inventory文件,有点不方便。
可能在fabric的一侧也有一种更智能的方法,但在我的环境中,我们只能将inventory放入环境变量中来应对。
from fabric.api import env
from ansible.inventory import Inventory
from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager
ansible_inventory_file = os.environ.get('INVENTORY', '/etc/ansible/hosts')
ansible_loader = DataLoader()
ansible_var_manager = VariableManager()
ansible_inventory = Inventory(ansible_loader, ansible_var_manager, ansible_inventory_file)
env.roledefs = ansible_inventory.get_group_dict()