我有在linux系统中搜索指定IP的代码:
- name: find IP
set_fact:
ip: "{{ item }}"
with_items: "{{ansible_all_ipv4_addresses}}"
when: "item.startswith('10.')"
并且工作正常,但我无法找到如何根据事实“ip”发现基于IP的接口名称 有人可以提供一些建议或者可能有一些例子如何做到这一点?
答案 0 :(得分:3)
Ansible提供了ansible_interfaces
事实中的接口列表。您可以使用它来迭代可用的接口,检查每个接口是否有给定的IP地址。
这最终会比听起来更棘手,因为你需要构建事实名称,这意味着而不是简单的事情:
ansible_eth0
您需要:
hostvars[inventory_hostname]["ansible_%s" % item]
另一个复杂因素是Ansible将ip地址划分为" primary" (ansible_eth0.ipv4.address
)和"次要" (ansible_eth0.ipv4_secondaries
),其中后者是带有address
个键的字典列表。假设我们正在迭代item
设置为接口名称,我们可以得到这样的主要地址:
hostvars[inventory_hostname]["ansible_%s" % item].ipv4.address
但是!对于没有分配ipv4地址或由于某种原因没有相应ansible_<interface>
事实的接口,这将失败。所以我们需要优雅地处理这种情况:
(hostvars[inventory_hostname]["ansible_%s" % item]|default({}).get('ipv4', {}).get('address')
这使用default
过滤器来确保我们从字典开始,然后我们使用几个级别的Python .get(key, default)
方法。
检查辅助地址是类似的,但要求我们使用map
过滤器,因为ipv4_secondaries
为我们提供了一个字典列表,我们真正想要的是一个地址列表(以便我们可以检查如果我们的目标地址是列出的in
:
((hostvars[inventory_hostname]['ansible_%s' % item]|default({}))
.get('ipv4_secondaries'))|map(attribute='address')|list
全部放在一起:
- hosts: localhost
vars:
target_address: 192.168.122.1
tasks:
- set_fact:
target_interface: "{{ item }}"
when: >
(hostvars[inventory_hostname]['ansible_%s' % item]|default({}))
.get('ipv4', {}).get('address') == target_address
or
target_address in ((hostvars[inventory_hostname]['ansible_%s' % item]|default({}))
.get('ipv4_secondaries'))|map(attribute='address')|list
with_items:
- "{{ ansible_interfaces }}"
- debug:
msg: >-
found interface {{ target_interface }}
with address {{ target_address }}
如果我在我的系统上运行此操作,则剧本运行结束于:
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "found interface virbr0 with address 192.168.24.1"
}
如果我跑:
ansible-playbook playbook.yml -e target_address=192.168.1.75
我明白了:
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "found interface eth0 with address 192.168.1.75"
}
从上面可以看出,这并不是Ansible所要求的那种任务。将所有这些逻辑填充到Ansible模块中可能会更好,这样您就可以使用Python(或其他语言)以更优雅的方式执行查找。
<强>更新强>
Here是针对同一问题的基于模块的解决方案。