使用 with_nested 从 API 开始循环
ansible looping from API using with_nested
我有 ansible-playbook 可以从叶路由器循环 ping 到主干。 ansible任务执行成功,可以看到如下:
- name: PING FROM LEAF TO SPINE
shell: ping {{item[0]}} -c 2 -s {{item[2]}} | grep -i received | awk '{print "{{item[3]}} :\n"," {{item[1]}} :", }'
register: p
with_nested:
- [ ['10.0.0.1','Spine-01'], ['10.0.0.2','Spine-02'] ]
- [ ['10.0.0.3','Leaf-01'], ['10.0.0.6','Leaf-04'], ['10.0.0.9','Leaf-07'] ]
但我不想手动编写,而是想从一个保存所有数据的变量中调用设备名称和 ip。我拥有的变量称为“get_devices”,包含设备名称、设备 ip 和设备类型 (spine/leaf) 形式的数据。我是 Ansible 的新手,我正在考虑像这样创建 spine 和 leaf 变量:
- name: DEFINE VARIABLE SPINE
set_fact: spine = "{{ item }}"
loop: "{{ get_devices.json.results }}"
when: "item.device_role.name == 'Spine'"
- name: DEFINE VARIABLE LEAF
set_fact: leaf = "{{ item }}"
loop: "{{ get_devices.json.results }}"
when: "item.device_role.name == 'Leaf'"
- name: PING FROM LEAF TO SPINE
shell: ping {{item[0]}} -c 2 -s {{item[2]}} | grep -i received | awk '{print "{{item[3]}} :\n"," {{item[1]}} :", }'
register: p
with_nested:
- [ ' {{ spine.ip_address}} ','{{ spine.name }}' ]
- [ ' {{ leaf.ip_address}} ','{{ leaf.name }}' ]
但是,它导致了这样的错误:
fatal: [localhost]: FAILED! => {"msg": "'spine' is undefined"}
知道如何解决这个问题吗?或者如果还有其他方法可以做到这一点,请告诉我。谢谢。
编辑:这是 get_devices.json.results 的部分结果:
{
"name": "Leaf-Ganesha-CRCS-01",
"ip_address": "10.0.0.3"
"device_role": {
"display": "Leaf",
"name": "Leaf",
}
},
{
"name": "Leaf-02",
"ip_address": "10.0.0.6"
"device_role": {
"display": "Leaf",
"name": "Leaf",
}
},
{
"name": "Spine-01",
"ip_address": "10.0.0.1"
"device_role": {
"display": "Spine",
"name": "Spine",
}
},
. . .
给定列表
get_devices.json.results:
- device_role:
display: Leaf
name: Leaf
ip_address: 10.0.0.3
name: Leaf-Ganesha-CRCS-01
- device_role:
display: Leaf
name: Leaf
ip_address: 10.0.0.6
name: Leaf-02
- device_role:
display: Spine
name: Spine
ip_address: 10.0.0.1
name: Spine-01
分组路由器并创建字典
routers: "{{ dict(get_devices.json.results|groupby('device_role.name')) }}"
spine: "{{ routers.Spine|items2dict(key_name='name', value_name='ip_address') }}"
leaf: "{{ routers.Leaf|items2dict(key_name='name', value_name='ip_address') }}"
给予
routers:
Leaf:
- device_role:
display: Leaf
name: Leaf
ip_address: 10.0.0.3
name: Leaf-Ganesha-CRCS-01
- device_role:
display: Leaf
name: Leaf
ip_address: 10.0.0.6
name: Leaf-02
Spine:
- device_role:
display: Spine
name: Spine
ip_address: 10.0.0.1
name: Spine-01
spine:
Spine-01: 10.0.0.1
leaf:
Leaf-02: 10.0.0.6
Leaf-Ganesha-CRCS-01: 10.0.0.3
然后迭代 spine 和 leaf 路由器的嵌套列表,例如
- debug:
msg: >-
ping {{ item.0.value }} -c 2 -s {{ item.1.value }} |
grep -i received |
awk '{print "{{ item.1.key }} :\n"," {{ item.0.key }} :", }'
with_nested:
- "{{ spine|dict2items }}"
- "{{ leaf|dict2items }}"
将创建命令
msg: ping 10.0.0.1 -c 2 -s 10.0.0.3 | grep -i received | awk '{print "Leaf-Ganesha-CRCS-01 :\n"," Spine-01 :", }'
msg: ping 10.0.0.1 -c 2 -s 10.0.0.6 | grep -i received | awk '{print "Leaf-02 :\n"," Spine-01 :", }'
按照您的逻辑并使用 product
的另一个答案:
tasks:
- name: DEFINE VARIABLE SPINE
set_fact:
spine: "{{ spine | d([]) + [ {'name': item.name, 'ip': item.ip_address} ] }}"
loop: "{{ get_devices.json.results }}"
when: "item.device_role.name == 'Spine'"
- name: DEFINE VARIABLE LEAF
set_fact:
leaf: "{{ leaf | d([]) + [ {'name': item.name, 'ip': item.ip_address} ] }}"
loop: "{{ get_devices.json.results }}"
when: "item.device_role.name == 'Leaf'"
- name: PING FROM LEAF TO SPINE
debug:
msg: ping {{item.0.ip}} -c 2 -s {{item.1.ip}} | grep -i received | awk '{print "{{item.1.name}} :\n"," {{item.0.name}} :", }'
register: p
loop: "{{ spine | product(leaf)|list }}"
结果:
"msg": "ping 10.0.0.1 -c 2 -s 10.0.0.3 | grep -i received | awk '{print \"Leaf-Ganesha-CRCS-01 :\n\",\" Spine-01 :\", }'"
"msg": "ping 10.0.0.1 -c 2 -s 10.0.0.6 | grep -i received | awk '{print \"Leaf-02 :\n\",\" Spine-01 :\", }'"
我有 ansible-playbook 可以从叶路由器循环 ping 到主干。 ansible任务执行成功,可以看到如下:
- name: PING FROM LEAF TO SPINE
shell: ping {{item[0]}} -c 2 -s {{item[2]}} | grep -i received | awk '{print "{{item[3]}} :\n"," {{item[1]}} :", }'
register: p
with_nested:
- [ ['10.0.0.1','Spine-01'], ['10.0.0.2','Spine-02'] ]
- [ ['10.0.0.3','Leaf-01'], ['10.0.0.6','Leaf-04'], ['10.0.0.9','Leaf-07'] ]
但我不想手动编写,而是想从一个保存所有数据的变量中调用设备名称和 ip。我拥有的变量称为“get_devices”,包含设备名称、设备 ip 和设备类型 (spine/leaf) 形式的数据。我是 Ansible 的新手,我正在考虑像这样创建 spine 和 leaf 变量:
- name: DEFINE VARIABLE SPINE
set_fact: spine = "{{ item }}"
loop: "{{ get_devices.json.results }}"
when: "item.device_role.name == 'Spine'"
- name: DEFINE VARIABLE LEAF
set_fact: leaf = "{{ item }}"
loop: "{{ get_devices.json.results }}"
when: "item.device_role.name == 'Leaf'"
- name: PING FROM LEAF TO SPINE
shell: ping {{item[0]}} -c 2 -s {{item[2]}} | grep -i received | awk '{print "{{item[3]}} :\n"," {{item[1]}} :", }'
register: p
with_nested:
- [ ' {{ spine.ip_address}} ','{{ spine.name }}' ]
- [ ' {{ leaf.ip_address}} ','{{ leaf.name }}' ]
但是,它导致了这样的错误:
fatal: [localhost]: FAILED! => {"msg": "'spine' is undefined"}
知道如何解决这个问题吗?或者如果还有其他方法可以做到这一点,请告诉我。谢谢。
编辑:这是 get_devices.json.results 的部分结果:
{
"name": "Leaf-Ganesha-CRCS-01",
"ip_address": "10.0.0.3"
"device_role": {
"display": "Leaf",
"name": "Leaf",
}
},
{
"name": "Leaf-02",
"ip_address": "10.0.0.6"
"device_role": {
"display": "Leaf",
"name": "Leaf",
}
},
{
"name": "Spine-01",
"ip_address": "10.0.0.1"
"device_role": {
"display": "Spine",
"name": "Spine",
}
},
. . .
给定列表
get_devices.json.results:
- device_role:
display: Leaf
name: Leaf
ip_address: 10.0.0.3
name: Leaf-Ganesha-CRCS-01
- device_role:
display: Leaf
name: Leaf
ip_address: 10.0.0.6
name: Leaf-02
- device_role:
display: Spine
name: Spine
ip_address: 10.0.0.1
name: Spine-01
分组路由器并创建字典
routers: "{{ dict(get_devices.json.results|groupby('device_role.name')) }}"
spine: "{{ routers.Spine|items2dict(key_name='name', value_name='ip_address') }}"
leaf: "{{ routers.Leaf|items2dict(key_name='name', value_name='ip_address') }}"
给予
routers:
Leaf:
- device_role:
display: Leaf
name: Leaf
ip_address: 10.0.0.3
name: Leaf-Ganesha-CRCS-01
- device_role:
display: Leaf
name: Leaf
ip_address: 10.0.0.6
name: Leaf-02
Spine:
- device_role:
display: Spine
name: Spine
ip_address: 10.0.0.1
name: Spine-01
spine:
Spine-01: 10.0.0.1
leaf:
Leaf-02: 10.0.0.6
Leaf-Ganesha-CRCS-01: 10.0.0.3
然后迭代 spine 和 leaf 路由器的嵌套列表,例如
- debug:
msg: >-
ping {{ item.0.value }} -c 2 -s {{ item.1.value }} |
grep -i received |
awk '{print "{{ item.1.key }} :\n"," {{ item.0.key }} :", }'
with_nested:
- "{{ spine|dict2items }}"
- "{{ leaf|dict2items }}"
将创建命令
msg: ping 10.0.0.1 -c 2 -s 10.0.0.3 | grep -i received | awk '{print "Leaf-Ganesha-CRCS-01 :\n"," Spine-01 :", }'
msg: ping 10.0.0.1 -c 2 -s 10.0.0.6 | grep -i received | awk '{print "Leaf-02 :\n"," Spine-01 :", }'
按照您的逻辑并使用 product
的另一个答案:
tasks:
- name: DEFINE VARIABLE SPINE
set_fact:
spine: "{{ spine | d([]) + [ {'name': item.name, 'ip': item.ip_address} ] }}"
loop: "{{ get_devices.json.results }}"
when: "item.device_role.name == 'Spine'"
- name: DEFINE VARIABLE LEAF
set_fact:
leaf: "{{ leaf | d([]) + [ {'name': item.name, 'ip': item.ip_address} ] }}"
loop: "{{ get_devices.json.results }}"
when: "item.device_role.name == 'Leaf'"
- name: PING FROM LEAF TO SPINE
debug:
msg: ping {{item.0.ip}} -c 2 -s {{item.1.ip}} | grep -i received | awk '{print "{{item.1.name}} :\n"," {{item.0.name}} :", }'
register: p
loop: "{{ spine | product(leaf)|list }}"
结果:
"msg": "ping 10.0.0.1 -c 2 -s 10.0.0.3 | grep -i received | awk '{print \"Leaf-Ganesha-CRCS-01 :\n\",\" Spine-01 :\", }'"
"msg": "ping 10.0.0.1 -c 2 -s 10.0.0.6 | grep -i received | awk '{print \"Leaf-02 :\n\",\" Spine-01 :\", }'"