CLI_Parse and loops

25 views
Skip to first unread message

colli...@gmail.com

unread,
Nov 19, 2020, 5:20:30 PM11/19/20
to Ansible Project
Hello everyone.   I am having some issues with using the information from cli_parser output. '''
    - name: Create po_ch variable
      ansible.netcommon.cli_parse:
        command: "show etherchannel summary"
        parser:
          name: ansible.netcommon.pyats
        set_fact: po_ch
      tags: debug

    - name: Create a list of interfaces that are PortChannel Memebers
      set_fact: 
        exclude_ints: "{{ item.value.port_channel.port_channel_member_intfs }}"
      loop: "{{ ansible_facts.po_ch.interfaces|dict2items }}"
      tags: debug
    
    - name: Debug new set fact
      debug:
        msg: "{{ exclude_ints }}"
      tags: debug
```
And here is the output

TASK [Create a list of interfaces that are PortChannel Memebers] ***************
task path: /tmp/awx_1417_a6buronn/project/device_tracking.yml:58
ok: [s996sw1] => (item={'key': 'Port-channel1', 'value': {'name': 'Port-channel1', 'bundle_id': 1, 'flags': 'SU', 'oper_status': 'up', 'members': {'GigabitEthernet1/0/37': {'interface': 'GigabitEthernet1/0/37', 'flags': 'P', 'bundled': True, 'port_channel': {'port_channel_member': True, 'port_channel_int': 'Port-channel1'}}, 'GigabitEthernet1/0/38': {'interface': 'GigabitEthernet1/0/38', 'flags': 'D', 'bundled': False, 'port_channel': {'port_channel_member': True, 'port_channel_int': 'Port-channel1'}}}, 'port_channel': {'port_channel_member': True, 'port_channel_member_intfs': ['GigabitEthernet1/0/37', 'GigabitEthernet1/0/38']}}}) => {
    "ansible_facts": {
        "exclude_ints": [
            "GigabitEthernet1/0/37",
            "GigabitEthernet1/0/38"
        ]
    },
    "ansible_loop_var": "item",
    "changed": false,
    "item": {
        "key": "Port-channel1",
 …
ok: [s996sw1] => (item={'key': 'Port-channel3', 'value': {'name': 'Port-channel3', 'bundle_id': 3, 'flags': 'SU', 'oper_status': 'up', 'members': {'GigabitEthernet1/1/2': {'interface': 'GigabitEthernet1/1/2', 'flags': 'P', 'bundled': True, 'port_channel': {'port_channel_member': True, 'port_channel_int': 'Port-channel3'}}, 'GigabitEthernet1/1/4': {'interface': 'GigabitEthernet1/1/4', 'flags': 'P', 'bundled': True, 'port_channel': {'port_channel_member': True, 'port_channel_int': 'Port-channel3'}}}, 'port_channel': {'port_channel_member': True, 'port_channel_member_intfs': ['GigabitEthernet1/1/2', 'GigabitEthernet1/1/4']}}}) => {
    "ansible_facts": {
        "exclude_ints": [
            "GigabitEthernet1/1/2",
            "GigabitEthernet1/1/4"
        ]
    },
    "ansible_loop_var": "item",
    "changed": false,
    "item": {
        "key": "Port-channel3",
        "v…
TASK [Debug new set fact] ******************************************************
task path: /tmp/awx_1417_a6buronn/project/device_tracking.yml:64
ok: [s996sw1] => {
    "msg": [
        "GigabitEthernet1/1/2",
        "GigabitEthernet1/1/4"
    ]
}
META: ran handlers
META: ran handlers


So it loops and the exclude_ints variable only has the last 2 interfaces when there are more than one portchannel on the device. How can I merge these to a list and use that in a when statement further down in the play.  

Any help would be apprciated.

Thank you!


Vladimir Botka

unread,
Nov 20, 2020, 2:36:34 AM11/20/20
to colli...@gmail.com, ansible...@googlegroups.com
On Thu, 19 Nov 2020 14:20:30 -0800 (PST)
"colli...@gmail.com" <colli...@gmail.com> wrote:

> - name: Create a list of interfaces that are PortChannel Memebers
> set_fact:
> exclude_ints: "{{ item.value.port_channel.port_channel_member_intfs
> }}"
> loop: "{{ ansible_facts.po_ch.interfaces|dict2items }}"
> tags: debug

Either concatenate the lists in the loop

- set_fact:
exclude_ints: "{{ exclude_ints|default([]) +
[item.value.port_channel.port_channel_member_intfs]
}}"
loop: "{{ po_ch.interfaces|dict2items }}"

or use json_query

- set_fact:
exclude_ints: "{{ po_ch.interfaces|json_query(query) }}"
vars:
query: '*.port_channel.port_channel_member_intfs'

In both cases the result will be a list of lists

exclude_ints:
- - GigabitEthernet1/0/37
- GigabitEthernet1/0/38
- - GigabitEthernet1/1/2
- GigabitEthernet1/1/4

In both cases it's possible to flatten the list if needed. For example

- set_fact:
exclude_ints: "{{ po_ch.interfaces|json_query(query)|
flatten }}"
vars:
query: '*.port_channel.port_channel_member_intfs'

gives

exclude_ints:
- GigabitEthernet1/0/37
- GigabitEthernet1/0/38
- GigabitEthernet1/1/2
- GigabitEthernet1/1/4

--
Vladimir Botka

J C

unread,
Nov 20, 2020, 8:45:18 AM11/20/20
to Vladimir Botka, ansible...@googlegroups.com
Thanks again Vladimir.  json_query was the answer again.  Need to read up on that some more to understand the syntax.  These examples are extremely helpful.

Again thank you for taking the time
Reply all
Reply to author
Forward
0 new messages