Reputation: 185
This is my ansible script:
tasks:
- name: parse
ansible.netcommon.cli_parse:
command: show interface {{item.interface}}
parser:
name: ansible.netcommon.ntc_templates
with_items: "{{ interfaces }}"
when: inventory_hostname == 'WAN-01A'
register: int
- debug:
msg: "{{int.results|map(attribute='parsed')|list}}"
when: inventory_hostname == 'WAN-01A'
vars:
interfaces:
- interface: Bundle-Ether1
- interface: Bundle-Ether1.100
output of debug:
[
{
"interface": "Bundle-Ether1",
"link_status": "up",
"protocol_status": "up",
"hardware_type": "Aggregated Ethernet interface",
"address": "",
"bia": "",
"description": "SCLAB-WAN-01B",
"ip_address": "10.210.255.4/31",
"mtu": "",
"duplex": "",
"speed": "",
"media_type": "",
"bandwidth": "",
"delay": "",
"encapsulation": "",
"last_input": "",
"last_output": "",
"last_output_hang": "",
"queue_strategy": "",
"input_rate": "2000",
"output_rate": "2000",
"input_packets": "",
"output_packets": "",
"input_errors": "0",
"crc": "0",
"abort": "0",
"output_errors": ""
},
{
"interface": "Bundle-Ether1.100",
"link_status": "up",
"protocol_status": "up",
"hardware_type": "VLAN sub",
"address": "",
"bia": "",
"description": "",
"ip_address": "10.0.0.1/30",
"mtu": "",
"duplex": "",
"speed": "",
"media_type": "",
"bandwidth": "",
"delay": "",
"encapsulation": "802.1Q Virtual LAN",
"last_input": "",
"last_output": "",
"last_output_hang": "",
"queue_strategy": "",
"input_rate": "0",
"output_rate": "0",
"input_packets": "",
"output_packets": "",
"input_errors": "",
"crc": "",
"abort": "",
"output_errors": ""
}
]
what i want is , i need to print only specific values (don't want all info) for each interface like:
[
{
"interface": "Bundle-Ether1",
"link_status": "up",
"protocol_status": "up",
"description": "WAN-01B",
"ip_address": "10.210.255.4/31",
"input_errors": "0",
"crc": "0",
"output_errors": ""
},
{
"interface": "Bundle-Ether1.100",
"link_status": "up",
"protocol_status": "up",
"address": "",
"description": "",
"ip_address": "10.0.0.1/30",
"input_errors": "",
"crc": "",
"output_errors": ""
}
]
how can I modify debug int.results|map(attribute='parsed')|list
to get the above result?
Upvotes: 1
Views: 2466
Reputation: 185
Thank you, Vladimir, I made a little modification, I have added item[0] rest everything is the same then it worked
{{ dict(wanted_fields|zip(wanted_fields|map('extract', item[0]))) }}
Upvotes: 1
Reputation: 68044
Q: "Print only specific values ... for each interface"
Given the list of wanted fields
wanted_fields:
- interface
- link_status
- protocol_status
- address
- description
- ip_address
- input_errors
- crc
- output_errors
A: Let Jinja create the list in the loop. For example
- debug:
msg: "{{ mylist|from_yaml }}"
vars:
parsed: "{{ int.results|map(attribute='parsed')|list }}"
mylist: |-
{% for item in parsed %}
- {{ dict(wanted_fields|zip(wanted_fields|map('extract', item))) }}
{% endfor %}
gives
msg:
- address: ''
crc: '0'
description: SCLAB-WAN-01B
input_errors: '0'
interface: Bundle-Ether1
ip_address: 10.210.255.4/31
link_status: up
output_errors: ''
protocol_status: up
- address: ''
crc: ''
description: ''
input_errors: ''
interface: Bundle-Ether1.100
ip_address: 10.0.0.1/30
link_status: up
output_errors: ''
protocol_status: up
If you want to iterate the list
- debug:
msg: "{{ dict(wanted_fields|zip(wanted_fields|map('extract', item))) }}"
loop: "{{ int.results|map(attribute='parsed')|list }}"
loop_control:
label: "{{ item.ip_address }}"
gives
ok: [localhost] => (item=10.210.255.4/31) =>
msg:
address: ''
crc: '0'
description: SCLAB-WAN-01B
input_errors: '0'
interface: Bundle-Ether1
ip_address: 10.210.255.4/31
link_status: up
output_errors: ''
protocol_status: up
ok: [localhost] => (item=10.0.0.1/30) =>
msg:
address: ''
crc: ''
description: ''
input_errors: ''
interface: Bundle-Ether1.100
ip_address: 10.0.0.1/30
link_status: up
output_errors: ''
protocol_status: up
Credit @lxop (formatted to simplify comparison). The "filters-only" option gives the same result
- debug:
msg: "{{ parsed|
map('dict2items')|
map('selectattr', 'key', 'in', wanted_fields)|
map('list')|
map('items2dict')|
list }}"
vars:
parsed: "{{ int.results|map(attribute='parsed')|list }}"
Upvotes: 0
Reputation: 8595
It can get a bit convoluted, but you can do this filtering with the following chain of filters:
vars:
wanted_fields:
- interface
- link_status
- protocol_status
# etc
tasks:
- debug:
msg: '{{ int.results | map(attribute='parsed') | list | map("dict2items") | map("selectattr", "key", "in", wanted_fields) | map("list") | map("items2dict") | list }}'
This chain converts each dictionary in your output list into a list of little dicts that look like
{
"key": "interface",
"value": "Bundle-Ether1"
}
then filters those based on the value of the "key"
field (does the name appear in your "wanted_fields"
list), then reassembles the filtered little dicts into a single regular dict again (for each interface). Each of the filters are inside a map()
filter because you need to apply the operations to each of the items in your output list, rather than just the list on its own.
Upvotes: 1