【问题标题】:how to convert an ansible playbook (yaml) to a python data structure如何将 ansible playbook (yaml) 转换为 python 数据结构
【发布时间】:2022-01-13 11:29:19
【问题描述】:

首先,这是我关于 SO 的第一个问题 - 它可能不完全符合 SO 标准。

我试图弄清楚如何将 ansible 剧本文件转换为 python 数据结构,如 docs.ansible.com 中提到的in this document

    # 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(),这为我提供了一种捕获输出的好方法。我'我很清楚有一个 Playbook Executor 但并没有完全削减它,因为所有输出都转储到标准输出。

这段代码可以将其捕获到每个主机的文件中(也来自文档):

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 函数,但未能找到它。有没有人有这方面的经验?

我的剧本仅用于测试目的:

--- - 主持人:所有 变成:没有 任务: - 名称:创建文件夹 文件: 路径:/tmp/playbook_user 状态:目录 所有者:playbook_user - 外壳:“uname -a” 寄存器:输出 - 名称:在屏幕上给出输出 调试: var: output.stdout_lines - 名称:将输出保存到本地目录 复制: 内容:“{{ output.stdout | replace('\\n', '\n') }}” dest: "/tmp/playbook_user/test_{{ ansible_date_time.date }}_{{ inventory_hostname }}.txt" - 本地操作: 模块:复制 内容:“{{ output.stdout | replace('\\n', '\n') }}” 目标:/tmp/show_cmd_ouput_{{ inventory_hostname }}.txt 运行一次:真

问候, 斯杰德

【问题讨论】:

标签: python python-3.x ansible


【解决方案1】:

传递给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 运行,可能拥有您想要的所有数据。

【讨论】:

  • 嘿拉斯克。我将尝试 playbook[0] 方法。我没有想到 yaml.safe_load() 会像那样返回 yaml。实际上,我确实简要了解了 de ansible_runner,但我不喜欢输出的呈现方式(更多相同),但如果我可以捕获正在使用 res.event,那么它可能确实是我需要的。只有一个问题:我对捕获事件的 python 知识很少(自从我不到一年前开始使用 python 以来,我从来不需要它)。
猜你喜欢
  • 2020-09-23
  • 1970-01-01
  • 2021-07-17
  • 2015-02-19
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 2018-12-01
  • 2011-07-25
相关资源
最近更新 更多