Search code examples
ansible

Ansible Extract Values from Output


I have a Web API call that grabs network device details and outputs a few different values. I would like to pull out the switch name and switch port from this output and register them seperately as variables for another task to call. I'm not sure how to accomplish this though.

Config:

<some task config omitted>
      register: spm_results

    - debug:
        var: spm_results.content

Output:

ok: [localhost] => {
    "spm_results.content": "00:1a:1e:cd:84:e2,Aruba a Hewlett Packard Enterprise Compa,M-1-DA,Gi3/0/4,prod,10.7.5.60\n"
}

I would like to match the switch name (M-1-DA in above output) based on this type of regex [a-zA-Z]-[0-999]-D[a-zA-Z] and the switchport by looking for ^Gi and register them both as different variables.

Any help would be greatly appreciated!

Unable to find specific required code to accomplish this


Solution

  • There are more options:

    1. split the line. You can trim it first
      content: "{{ spm_results.content | trim | split(',') }}"
    

    gives

      content:
      - 00:1a:1e:cd:84:e2
      - Aruba a Hewlett Packard Enterprise Compa
      - M-1-DA
      - Gi3/0/4
      - prod
      - 10.7.5.60
    

    Then, the matching of the items is trivial

      mac: "{{ content.0 }}"
      vendor: "{{ content.1 }}"
      switch: "{{ content.2 }}"
      port: "{{ content.3 }}"
      env: "{{ content.4 }}"
      ip: "{{ content.5 }}"
    
    1. Optionally, create a list of field names and use the filter community.general.dict
      fieldnames: [mac, vendor, switch, port, env, ip]
      hw: "{{ content |
              zip(fieldnames) |
              map('reverse') |
              community.general.dict }}"
    

    gives the dictionary

      hw:
        env: prod
        ip: 10.7.5.60
        mac: 00:1a:1e:cd:84:e2
        port: Gi3/0/4
        switch: M-1-DA
        vendor: Aruba a Hewlett Packard Enterprise Compa
    
    1. The next option is the filter community.general.from_csv
      hw: "{{ spm_results.content |
              community.general.from_csv(dialect='unix', fieldnames=fieldnames) }}"
    

    gives the list

      hw:
      - env: prod
        ip: 10.7.5.60
        mac: 00:1a:1e:cd:84:e2
        port: Gi3/0/4
        switch: M-1-DA
        vendor: Aruba a Hewlett Packard Enterprise Compa
    

    Example of a complete playbook for testing

    - hosts: localhost
    
      vars:
    
        spm_results:
          content: >
            00:1a:1e:cd:84:e2,Aruba a Hewlett Packard Enterprise Compa,M-1-DA,Gi3/0/4,prod,10.7.5.60
    
        content: "{{ spm_results.content | trim | split(',') }}"
        mac: "{{ content.0 }}"
        vendor: "{{ content.1 }}"
        switch: "{{ content.2 }}"
        port: "{{ content.3 }}"
        env: "{{ content.4 }}"
        ip: "{{ content.5 }}"
    
        fieldnames: [mac, vendor, switch, port, env, ip]
        hw: "{{ content |
                zip(fieldnames) |
                map('reverse') |
                community.general.dict }}"
        
        h2: "{{ spm_results.content |
                community.general.from_csv(dialect='unix', fieldnames=fieldnames) }}"
    
      tasks:
    
        - debug:
            var: content
        - debug:
            var: switch
    
        - debug:
            var: hw
    
        - debug:
            var: h2