执行一个可解析的剧本后,我需要未到达的节点名称。我曾考虑过使用AnsibleRunner
来运行ansible playbook,并且我知道特殊变量ansible_play_hosts
和ansible_play_hosts_all
,您可以对它们进行区分以获得不可达的节点。但是这些特殊的变量只存在于ansible的上下文中。
那么,在不解析ansible的输出的情况下,如何从AnsibleRunner
(或类似的实用程序(中获取不可访问的节点呢。
运行中对象
目前,我正在创建一个runner对象,并在执行后评估其变量。我看到,在这些事件中,理论上我可以寻找不可达的节点,但这似乎很粗略。
还可以编写一个事件处理程序,专门捕捉那些指示节点不可访问的事件,并以不同的方式处理这些情况。
我还写了一个小的事实注册,注册哪些节点是不可访问的,这些节点将作为最后一项任务执行,但我还不能访问它:
- set_fact:
unreachable: "{{ ansible_play_hosts_all|difference(ansible_play_hosts) }}"
在可靠的API上
易解释的API在其示例中有一个名为host_unreachable
的字典。虽然这听起来很有前途,但我有两个问题:I(我无法运行示例II(API将不向下兼容,因此不应该在外部使用。
一旦您的剧本运行完毕,您要查找的内容实际上可以在Runner.stats
属性中开箱即用。
示例实现
给定:
inv.yml
库存
---
local_test:
vars:
ansible_connection: local
failling_hosts:
- test2
- test3
hosts:
test1:
test2:
test3:
test4:
unreachable:
hosts:
test5:
test.yml
行动手册
---
- hosts: all
tasks:
- name: dummy task for all
debug:
msg: task1 for all hosts
- name: blindly fail some hosts for test
assert:
that: inventory_hostname not in (failling_hosts | d([]))
- name: dummy task for survivors
debug:
msg: task2 for survivors
test.py
python脚本
import ansible_runner
runner = ansible_runner.run(
private_data_dir='.',
inventory='inv.yml',
playbook='test.yml',
quiet=False if len(sys.argv) > 1 and sys.argv[1] == '-v' else True
)
overall_failed = {
'unreachable': runner.stats['dark'].keys(),
'failed': runner.stats['failures'].keys()
}
for elem_type, elements in overall_failed.items():
for i, host in enumerate(elements):
if i == 0:
print(f'nList of {elem_type} hosts:')
print(f't{host}')
我们得到(如果你也想要剧本输出,用-v
运行(:
$ python test.py
List of unreachable hosts:
test5
List of failed hosts:
test2
test3