i have ansible-playbook to loop ping from leaf router to spine. The ansible task was successfully executed, it can be seen as follows:
- 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]}} :", $4}'
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'] ]
but instead of writing it manually, I want to call the device name and ip from a variable that holds all the data. The variable I have is called "get_devices" and contains data in the form of device name, device ip, and device type (spine/leaf). I'm new to Ansible, and I'm considering creating spine and leaf variables like this:
- 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]}} :", $4}'
register: p
with_nested:
- [ ' {{ spine.ip_address}} ','{{ spine.name }}' ]
- [ ' {{ leaf.ip_address}} ','{{ leaf.name }}' ]
but, it resulted in an error like this :
fatal: [localhost]: FAILED! => {"msg": "'spine' is undefined"}
any idea how i can fix this? or if there are other ways to do this, please let me know. Thank you.
Edit : this is some part of the result of 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",
}
},
. . .
CodePudding user response:
another answer following your logic and using 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}} :", $4}'
register: p
loop: "{{ spine | product(leaf)|list }}"
result:
"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 :\", $4}'"
"msg": "ping 10.0.0.1 -c 2 -s 10.0.0.6 | grep -i received | awk '{print \"Leaf-02 :\\n\",\" Spine-01 :\", $4}'"
CodePudding user response:
Given the list
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
Group the routers and create the dictionaries
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') }}"
gives
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
Then iterate the nested lists of spine and leaf routers, e.g.
- debug:
msg: >-
ping {{ item.0.value }} -c 2 -s {{ item.1.value }} |
grep -i received |
awk '{print "{{ item.1.key }} :\n"," {{ item.0.key }} :", $4}'
with_nested:
- "{{ spine|dict2items }}"
- "{{ leaf|dict2items }}"
will create the commands
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 :", $4}'
msg: ping 10.0.0.1 -c 2 -s 10.0.0.6 | grep -i received | awk '{print "Leaf-02 :\n"," Spine-01 :", $4}'