簡體   English   中英

如何將 ansible 劇本(yaml)轉換為 python 數據結構

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM