Fetch interface, ip address, description(if available), subnet mask from list of list in ansible

Hi
I wanted to parse the below sample data which is list of list in ansible.
Can you please help .Sample data with sample output is given.
Please let me know if any information required

data = [
[
“Interface Port-channel1.2345 "Management", is up, line protocol is up”,
“\tDescription: Management”,
“\tMAC address a2c0.0000.0029, MTU 1500”,
“\tIP address 10.60.90.20, virtual IP 10.60.90.20, subnet mask 255.255.254.0”,
" Traffic Statistics for "Management":“,
“\t9437514 packets input, 1486785944 bytes”,
“\t317418739 packets output, 98541126401 bytes”,
“\t33398 packets dropped”,
“\tManagement-only interface. Blocked 3 through-the-device packets”,
“”,
“Interface Port-channel10.2006 "IF6-BW-SNSL-Back-2006", is up, line protocol is up”,
“\tDescription: IF6-BW-SNSL-Back-2006”,
“\tMAC address a2c0.0000.002c, MTU 9184”,
“\tIP address 10.609.90.20, subnet mask 255.255.255.128”,
" Traffic Statistics for "IF6-BW-SNSL-Back-2006":”,
“\t4298991716 packets input, 3242974970758 bytes”,
“\t3054164248 packets output, 1762159698989 bytes”,
“\t5307966 packets dropped”,
“Interface Port-channel10.2007 "IF6-BW-SNSL-Back-2007", is up, line protocol is up”,
“\tDescription: IF6-BW-SNSL-Back-2007”,
“\tMAC address a2c0.0000.002e, MTU 9184”,
“\tIP address 10.260.90.20, subnet mask 255.255.255.128”,
" Traffic Statistics for "IF6-BW-SNSL-Back-2007":“,
“\t23160649155 packets input, 7732171808569 bytes”,
“\t3228105731 packets output, 1530585448804 bytes”,
“\t1866450 packets dropped”,
“Interface Port-channel20.2224 "IF4-BW-SNSL-OPG-COMMSEE-STG-Front-2224", is up, line protocol is up”,
“\tDescription: IF4-BW-SNSL-OPG-COMMSEE-STG-Front-2224”,
“\tMAC address a2c0.0000.0034, MTU 9184”,
“\tIP address 10.110.90.20, subnet mask 255.255.255.248”,
" Traffic Statistics for "IF4-BW-SNSL-OPG-COMMSEE-STG-Front-2224":”,
“\t11905903872 packets input, 8331684605255 bytes”,
“\t6579071731 packets output, 5053307770265 bytes”,
“\t5642609 packets dropped”,
“Interface "nlp_int_tap", is up, line protocol is up”,
“\tMAC address a2c0.0000.0016, MTU 1500”,
“\tIP address 10.460.90.20, subnet mask 255.255.255.248”,
" Traffic Statistics for "nlp_int_tap":“,
“\t8401703 packets input, 2715398692 bytes”,
“\t8396416 packets output, 1417467601 bytes”,
“\t1199 packets dropped”
],
[
“Interface Port-channel1.2345 "Management", is up, line protocol is up”,
“\tDescription: Management”,
“\tMAC address a2c0.0000.0024, MTU 1500”,
“\tIP address 10.30.40.50, virtual IP 10.88.70.60, subnet mask 255.255.254.0”,
" Traffic Statistics for "Management":”,
“\t10149073 packets input, 1617915750 bytes”,
“\t201234462 packets output, 60048310288 bytes”,
“\t33408 packets dropped”,
“\tManagement-only interface. Blocked 1 through-the-device packets”,
“”,
“Interface Port-channel10.2273 "IF3-BW-SNSL-COMMSEC-NONPROD-2273", is up, line protocol is up”,
“\tDescription: Back VLAN for COMMSEC NON-PROD - CONTROLLED”,
“\tMAC address a2c0.0000.0064, MTU 9184”,
“\tIP address 10.30.40.51.158, subnet mask 255.255.255.224”,
" Traffic Statistics for "IF3-BW-SNSL-COMMSEC-NONPROD-2273":“,
“\t4649716537 packets input, 1542339911758 bytes”,
“\t3642754601 packets output, 1099579611260 bytes”,
“\t116423 packets dropped”,
“Interface Port-channel10.2274 "IF5-BW-SNSL-COMMSEC-NONPROD-2274", is up, line protocol is up”,
“\tDescription: Back VLAN for COMMSEC NON-PROD - RESTRICTED”,
“\tMAC address a2c0.0000.0066, MTU 9184”,
“\tIP address 10.30.40.90, subnet mask 255.255.255.224”,
" Traffic Statistics for "IF5-BW-SNSL-COMMSEC-NONPROD-2274":”,
“\t2482332748 packets input, 1470527062853 bytes”,
“\t1414194649 packets output, 216009858627 bytes”,
“\t442777 packets dropped”,
“Interface Port-channel10.2275 "IF6-BW-SNSL-COMMSEC-NONPROD-2275", is up, line protocol is up”,
“\tDescription: Back VLAN for COMMSEC NON-PROD - SECURED”,
“\tMAC address a2c0.0000.0068, MTU 9184”,
“\tIP address 10.30.40.80, subnet mask 255.255.255.224”,
" Traffic Statistics for "IF6-BW-SNSL-COMMSEC-NONPROD-2275":“,
“\t0 packets input, 0 bytes”,
“\t3505 packets output, 117436 bytes”,
“\t0 packets dropped”,
“Interface Port-channel10.2276 "IF7-BW-SNSL-COMMSEC-NONPROD-2276", is up, line protocol is up”,
“\tDescription: Back VLAN for COMMSEC NON-PROD - MANAGEMENT”,
“\tMAC address a2c0.0000.006a, MTU 9184”,
“\tIP address 10.30.40.70, subnet mask 255.255.255.192”,
" Traffic Statistics for "IF7-BW-SNSL-COMMSEC-NONPROD-2276":”,
“\t44895243 packets input, 22490344483 bytes”,
“\t28357798 packets output, 7174133070 bytes”,
“\t49915 packets dropped”,
“Interface Port-channel20.2223 "IF4-BW-SNSL-COMMSEC-NONPROD-2223", is up, line protocol is up”,
“\tDescription: Front VLAN for COMMSEC NON-PROD”,
“\tMAC address a2c0.0000.0062, MTU 9184”,
“\tIP address 10.30.40.90, subnet mask 255.255.255.248”,
" Traffic Statistics for "IF4-BW-SNSL-COMMSEC-NONPROD-2223":“,
“\t2247658749 packets input, 262559718829 bytes”,
“\t2477269288 packets output, 1199976079000 bytes”,
“\t793770 packets dropped”,
“Interface "nlp_int_tap", is up, line protocol is up”,
“\tMAC address a2c0.0000.0018, MTU 1500”,
“\tIP address 10.20.40.50, subnet mask 255.255.255.248”,
" Traffic Statistics for "nlp_int_tap":”,
“\t9119310 packets input, 3057269509 bytes”,
“\t9114023 packets output, 1548838262 bytes”,
“\t1196 packets dropped”
]]

Output should be
Its ok to get output in two ways whichever way is easier
Output should be either list of list or list of dictionary
[[“Port-channel1.2345”, “Management”, “10.60.90.20”, “255.255.254.0”], [“Port-channel10.2006”, “IF6-BW-SNSL-Back-2006”, “10.609.90.20”,“255.255.255.128”]]
Note: Get the description only if it is available in data like “\tDescription: Management”, if not any description then keep empty string
like [[“Port-channel1.2345”, “”, “10.60.90.20”, “255.255.254.0”]]

Dictionary format
[{“interface”: “Port-channel1.2345”,“description”:“Management” , “ip_address”:“10.60.90.20”, “subnet_mask”: “255.255.254.0”}]

Hello @Neha001.

It appears to be a duplicate of Fetch interfaces, ip address, description(if available), subnet mask from list of list using ansible

Could you delete either topic?

  1. Open menu at first comment of this topic
  2. Click the delete buton

I am trying to delete but unable to do so

(attachments)

You can’t delete this one, I expect, as it has replies, but this duplicate doesn’t and should be deletable:

Also please edit you top post to use fenced code blocks it will make it more readable and perhaps more likely that someone will suggest a solution as they will be better able to understand the problem.

1 Like

Can anyone please help me on this issue

This is more of a parsing problem than an Ansible problem. But still, here’s one solution. It creates a perl script to parse the data and output a JSON representation of the parts you want. The perl script is removed once it’s no longer needed. There’s a debug task after that which shows how to access the registered data.

I hope this helps.

---
# neha001-01.yml
- name: Parsing networking metadata
  hosts: localhost
  gather_facts: false
  vars:
    data: [
           [
           "Interface Port-channel1.2345 \"Management\", is up, line protocol is up",
           "\tDescription: Management",
           "\tMAC address a2c0.0000.0029, MTU 1500",
           "\tIP address 10.60.90.20, virtual IP 10.60.90.20, subnet mask 255.255.254.0",
           " Traffic Statistics for \"Management\":",
           "\t9437514 packets input, 1486785944 bytes",
           "\t317418739 packets output, 98541126401 bytes",
           "\t33398 packets dropped",
           "\tManagement-only interface. Blocked 3 through-the-device packets",
           "",
           "Interface Port-channel10.2006 \"IF6-BW-SNSL-Back-2006\", is up, line protocol is up",
           "\tDescription: IF6-BW-SNSL-Back-2006",
           "\tMAC address a2c0.0000.002c, MTU 9184",
           "\tIP address 10.609.90.20, subnet mask 255.255.255.128",
           " Traffic Statistics for \"IF6-BW-SNSL-Back-2006\":",
           "\t4298991716 packets input, 3242974970758 bytes",
           "\t3054164248 packets output, 1762159698989 bytes",
           "\t5307966 packets dropped",
           "Interface Port-channel10.2007 \"IF6-BW-SNSL-Back-2007\", is up, line protocol is up",
           "\tDescription: IF6-BW-SNSL-Back-2007",
           "\tMAC address a2c0.0000.002e, MTU 9184",
           "\tIP address 10.260.90.20, subnet mask 255.255.255.128",
           " Traffic Statistics for \"IF6-BW-SNSL-Back-2007\":",
           "\t23160649155 packets input, 7732171808569 bytes",
           "\t3228105731 packets output, 1530585448804 bytes",
           "\t1866450 packets dropped",
           "Interface Port-channel20.2224 \"IF4-BW-SNSL-OPG-COMMSEE-STG-Front-2224\", is up, line protocol is up",
           "\tDescription: IF4-BW-SNSL-OPG-COMMSEE-STG-Front-2224",
           "\tMAC address a2c0.0000.0034, MTU 9184",
           "\tIP address 10.110.90.20, subnet mask 255.255.255.248",
           " Traffic Statistics for \"IF4-BW-SNSL-OPG-COMMSEE-STG-Front-2224\":",
           "\t11905903872 packets input, 8331684605255 bytes",
           "\t6579071731 packets output, 5053307770265 bytes",
           "\t5642609 packets dropped",
           "Interface \"nlp_int_tap\", is up, line protocol is up",
           "\tMAC address a2c0.0000.0016, MTU 1500",
           "\tIP address 10.460.90.20, subnet mask 255.255.255.248",
           " Traffic Statistics for \"nlp_int_tap\":",
           "\t8401703 packets input, 2715398692 bytes",
           "\t8396416 packets output, 1417467601 bytes",
           "\t1199 packets dropped"
           ],
           [
           "Interface Port-channel1.2345 \"Management\", is up, line protocol is up",
           "\tDescription: Management",
           "\tMAC address a2c0.0000.0024, MTU 1500",
           "\tIP address 10.30.40.50, virtual IP 10.88.70.60, subnet mask 255.255.254.0",
           " Traffic Statistics for \"Management\":",
           "\t10149073 packets input, 1617915750 bytes",
           "\t201234462 packets output, 60048310288 bytes",
           "\t33408 packets dropped",
           "\tManagement-only interface. Blocked 1 through-the-device packets",
           "",
           "Interface Port-channel10.2273 \"IF3-BW-SNSL-COMMSEC-NONPROD-2273\", is up, line protocol is up",
           "\tDescription: Back VLAN for COMMSEC NON-PROD - CONTROLLED",
           "\tMAC address a2c0.0000.0064, MTU 9184",
           "\tIP address 10.30.40.51.158, subnet mask 255.255.255.224",
           " Traffic Statistics for \"IF3-BW-SNSL-COMMSEC-NONPROD-2273\":",
           "\t4649716537 packets input, 1542339911758 bytes",
           "\t3642754601 packets output, 1099579611260 bytes",
           "\t116423 packets dropped",
           "Interface Port-channel10.2274 \"IF5-BW-SNSL-COMMSEC-NONPROD-2274\", is up, line protocol is up",
           "\tDescription: Back VLAN for COMMSEC NON-PROD - RESTRICTED",
           "\tMAC address a2c0.0000.0066, MTU 9184",
           "\tIP address 10.30.40.90, subnet mask 255.255.255.224",
           " Traffic Statistics for \"IF5-BW-SNSL-COMMSEC-NONPROD-2274\":",
           "\t2482332748 packets input, 1470527062853 bytes",
           "\t1414194649 packets output, 216009858627 bytes",
           "\t442777 packets dropped",
           "Interface Port-channel10.2275 \"IF6-BW-SNSL-COMMSEC-NONPROD-2275\", is up, line protocol is up",
           "\tDescription: Back VLAN for COMMSEC NON-PROD - SECURED",
           "\tMAC address a2c0.0000.0068, MTU 9184",
           "\tIP address 10.30.40.80, subnet mask 255.255.255.224",
           " Traffic Statistics for \"IF6-BW-SNSL-COMMSEC-NONPROD-2275\":",
           "\t0 packets input, 0 bytes",
           "\t3505 packets output, 117436 bytes",
           "\t0 packets dropped",
           "Interface Port-channel10.2276 \"IF7-BW-SNSL-COMMSEC-NONPROD-2276\", is up, line protocol is up",
           "\tDescription: Back VLAN for COMMSEC NON-PROD - MANAGEMENT",
           "\tMAC address a2c0.0000.006a, MTU 9184",
           "\tIP address 10.30.40.70, subnet mask 255.255.255.192",
           " Traffic Statistics for \"IF7-BW-SNSL-COMMSEC-NONPROD-2276\":",
           "\t44895243 packets input, 22490344483 bytes",
           "\t28357798 packets output, 7174133070 bytes",
           "\t49915 packets dropped",
           "Interface Port-channel20.2223 \"IF4-BW-SNSL-COMMSEC-NONPROD-2223\", is up, line protocol is up",
           "\tDescription: Front VLAN for COMMSEC NON-PROD",
           "\tMAC address a2c0.0000.0062, MTU 9184",
           "\tIP address 10.30.40.90, subnet mask 255.255.255.248",
           " Traffic Statistics for \"IF4-BW-SNSL-COMMSEC-NONPROD-2223\":",
           "\t2247658749 packets input, 262559718829 bytes",
           "\t2477269288 packets output, 1199976079000 bytes",
           "\t793770 packets dropped",
           "Interface \"nlp_int_tap\", is up, line protocol is up",
           "\tMAC address a2c0.0000.0018, MTU 1500",
           "\tIP address 10.20.40.50, subnet mask 255.255.255.248",
           " Traffic Statistics for \"nlp_int_tap\":",
           "\t9119310 packets input, 3057269509 bytes",
           "\t9114023 packets output, 1548838262 bytes",
           "\t1196 packets dropped"
           ]]

    # Output should be
    # Its ok to get output in two ways whichever way is easier
    # Output should be either list of list or list of dictionary
    # [["Port-channel1.2345", "Management", "10.60.90.20", "255.255.254.0"], ["Port-channel10.2006", "IF6-BW-SNSL-Back-2006", "10.609.90.20","255.255.255.128"]]
    # Note: Get the description only if it is available in data like "\tDescription: Management", if not any description then keep empty string
    # like [["Port-channel1.2345", "", "10.60.90.20", "255.255.254.0"]]
  tasks:
    - name: Parse data
      ansible.builtin.shell: |
        scriptname=$(mktemp --suffix=.pl --tmpdir=/tmp neha001XXXX)
        cat > "$scriptname" <<'END_OF_SCRIPT'
        #!/usr/bin/perl
        use strict;
        use Data::Dumper;
        use JSON;
        my $debug = 0;
        my @parsed = ();
        while (<DATA>) {
          print $_ if $debug;
          if ( m/^Interface ([^ "]*) ?"([^"]+)",/ ) {
              push @parsed, ({'Interface' => $1 ? $1 : $2, 'Description' => $2});
              print Data::Dumper->Dump([$parsed[-1]], 'parsed') if $debug;
          }
          if ( m/Description: (.*)/ ) {
              $parsed[-1]->{'Description'} = $1;
              print Data::Dumper->Dump([$parsed[-1]], 'parsed') if $debug;
          }
          if ( m/IP address ([0-9a-f.]+)/i ) {
              ${parsed[-1]}->{'IP'} = $1;
              print Data::Dumper->Dump([$parsed[-1]], 'parsed') if $debug;
          }
          if ( m/subnet mask ([0-9a-f.]+)/i ) {
              ${parsed[-1]}->{'mask'} = $1;
              print Data::Dumper->Dump([$parsed[-1]], 'parsed') if $debug;
          }
        }
        print encode_json \@parsed;
        __DATA__
        {% for data_line in data | flatten %}
        {{   data_line }}
        {% endfor %}
        END_OF_SCRIPT
        chmod 0775 "$scriptname"
        "$scriptname"
        rm "$scriptname"
      args:
        executable: /bin/bash
      register: parsed_data

    - name: Show the parsed data
      ansible.builtin.debug:
        msg: '{{ parsed_data.stdout | from_json }}'

@Neha001

What network OS command is that output from?

It seems easier to use ansible.utils.cli_parce module.

1 Like

Hi ,

Thanks for the reply
but the above data which I shared is the output of below command in ansible and I believe we can use ansible regex to fetch the data

  • name: “switch to each context and gather facts”
    cisco.asa.asa_command:
    commands:
    - changeto context
    - show interface
    register: interface_details

Hi ,

Its the output of below command

Hi ,

Thanks for the reply
but the above data which I shared is the output of below command in ansible and I believe we can use ansible regex to fetch the data

  • name: “switch to each context and gather facts”
    cisco.asa.asa_command:
    commands:
    - changeto context
    - show interface
    register: interface_details
1 Like

I had never seen ansible.utils.cli_parse before. At first glance, I agreed. After about an hour looking at docs and skimming through the source and scratching my head a bit, I’m backing away from “easier”.

“Easier” is relative of course. If these network commands are your bread and butter and one of the examples fits your use case, it probably is easier. If you’re trying to solve a general parsing problem and you’ve breathed perl/python/sed/awk/bash for years, wrapping your head around cli_parse (with the documentation I saw) is by no means “easier”. It might actually be easy, but the limited time I was able to put into it yielded more questions than answers.

Still, it’s an intriguing approach. I’d personally like to see something better documented and more general - it’s heavily network-command-centric. But for people with problems that it solves, it’s clearly a worthwhile tool to have.

Hello sir
can’t we just use a shell command like sed to change [[ to [ and ]] to ] and then access it like a list?
sed -i ‘s/[[/[/g; s/]]/]/g’ data_file.
can you tell me please z.

If the data has been dumped as a single-line of JSON to the file data_file, you can probably make something like that work. Except that “[” is a regex meta-character so you have to escape it. Also you end up with embeded instances of “], [” where the internal lists followed one another.

This apparently works:

sed 's/\[\[/[/g; s/\]\]/]/g; s/\], \[/, /g;'

However, if data_file is being written by an Ansible task to begin with, say something like this:

    - name: Dump data to a file as json
      ansible.builtin.copy:
        content: '{{ data | to_json }}'
        dest: data_file

then why not get rid of the embedded lists with “|flatten” and obviate the need for doing the sed later, like so:

    - name: Dump flattened data to a file as json
      ansible.builtin.copy:
        content: '{{ data | flatten | to_json }}'
        dest: data_file.json

And add a .json extension while we’re at it if it’s supposed to be JSON data.

1 Like

Thanks for the flag @akira6592 - I’ve deleted the duplicate.

2 Likes