[英]how to convert an ansible playbook (yaml) to a python data structure
首先,这是我关于 SO 的第一个问题——它可能不完全符合 SO 标准。
我正在尝试弄清楚如何将 ansible 剧本文件转换为 python 数据结构,如本文档中提到的来自 docs.ansible14BEC50D236ADD9A0DADDAD
# create data structure that represents our play, including tasks, this is basically what our YAML loader does internally.
play_source = dict(
name="Ansible Play",
hosts=host_list,
gather_facts='no',
tasks=[
dict(action=dict(module='shell', args='ls'), register='shell_out'),
dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}'))),
dict(action=dict(module='command', args=dict(cmd='/usr/bin/uptime'))),
]
)
我想这样做的原因是,Play() 不接受原始 yaml 文件,并且该示例很好地挂钩到提供的 ResultsCollectorJSONCallback(),这为我提供了一种捕获 output 的好方法。我非常很清楚有一个 Playbook Executor 但并没有完全削减它,因为所有 output 都被转储到标准输出。
这段代码可以将其捕获到每个主机的文件中(也来自文档):
print("UP ***********")
for host, result in results_callback.host_ok.items():
print('{0} >>> {1}'.format(host, result._result['stdout']))
print("FAILED *******")
for host, result in results_callback.host_failed.items():
print('{0} >>> {1}'.format(host, result._result['msg']))
print("DOWN *********")
for host, result in results_callback.host_unreachable.items():
print('{0} >>> {1}'.format(host, result._result['msg']))
我试图找到 ansible 将 yaml 转换为 python 数据结构的任何文档。 评论清楚地说“这基本上是我们的 YAML 加载程序在内部所做的。” 但我无法弄清楚他们是如何做到的,甚至试图弄清楚 PlaybookExecutor 是如何做到的,但要看到真正发生的事情非常复杂。 我希望在 ansible 的 yaml 解析例程中的某处找到一个 yaml_to_datastructure function 但未能找到它。 有人有这方面的经验吗?
问候, Sjoerd
传递给Play().load
的数据只是剧本中单个剧本的内容。 也就是说,如果我有一个看起来像这样的剧本:
- hosts: localhost
tasks:
- debug:
msg: "This is a test"
我可以像这样加载它:
>>> import yaml
>>> from ansible.inventory.manager import InventoryManager
>>> from ansible.parsing.dataloader import DataLoader
>>> from ansible.vars.manager import VariableManager
>>> from ansible.playbook.play import Play
>>> loader = DataLoader()
>>> inventory = InventoryManager(loader=loader)
[WARNING]: No inventory was parsed, only implicit localhost is available
>>> variable_manager = VariableManager(loader=loader, inventory=inventory)
>>> with open('playbook.yml') as fd:
... playbook = yaml.safe_load(fd)
...
>>> play = Play().load(playbook[0], variable_manager=variable_manager, loader=loader)
等等。
注意我将playbook[0]
传递给Play().load
(剧本中的第一个剧本),而不是整个剧本。
但是,如果您的目标是使用 Python 运行 Ansible 剧本,那么使用 ansible -runner可能会更好。 看起来像:
>>> import ansible_runner
>>> res = ansible_runner.interface.run(private_data_dir='.',playbook='playbook.yml')
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
PLAY [localhost] ***************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "This is a test"
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
此时, res.events
包含由 playbook 运行生成的各个事件,并且可能包含您可能想要的所有数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.