loneknight
loneknight

Reputation: 63

Ansible Regex Expression

I'm looking to find all ports with a certain status on a Cisco router to shut them down. I was hoping to do this via std.out and using regex but have no idea on the regex syntax.

For example, output for the show command will look something like the below output.

 Port       Device          State   Call          DN        Dev State                          
---------- --------------- -------- ------------- ------- ----------- ----
0/1/0      DEV0001         IS       IDLE         2344       ATT
0/1/1      DEV0002         IS       IDLE         2567       ATT
0/1/2      DEV0002         IS       IDLE         2567       DEL

What I'd like to do is to store the port numbers which has Dev State = ATT in a variable so I can shut them down. In Cisco I can filter the show command to say - show port | include ATT - this will only list the ports that contain the Dev State ATT but it wont show any of the Column heading in the output. From this output, I then need to loop through and store the port numbers. Hope this makes sense.

Appreciate any help. Thank you.

Ansible Script:

 tasks:
   - name: show port
     ios_command:
      commands:
        - show port summary | incl ATT
     register: config
   - set_fact
      myvalue: ""{{ config.stdout | regex_search(??) }}""
      when config.stdout | length > 0 

Output of Debug config:

    "stdout_lines": [
        [
            "Total Devices:           4",
            "Total Calls in Progress: 0",
            "Total Call Legs in Use:  0",
            "",
            "Port       Device          Device   Call          Dev     Directory   Dev ",
            "Identifier Name            State    State         Type    Number      Cntl ",
            "---------- --------------- -------- ------------- ------- ----------- ---- ",
            "0/1/0      DEV0001         IS       IDLE          ALG     3880       DEL",
            "0/1/1      DEV0002         IS       IDLE          ALG     3881       ATT",
            "0/1/2      DEV0003         IS       IDLE          ALG                ATT",
            "0/1/3      DEV0004         IS       IDLE          ALG     3882       DEL"
        ]
    ]
} ]

Upvotes: 1

Views: 703

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 67984

  • There should be config.stdout_lines along with config.stdout
  • It's not necessary to test the list. The loop will be skipped if the list is empty.
  • Lines with data are selected by the pattern '^\d/\d/\d\s*(.*)$'
  • It's possible to customize the result by changing the when condition and changing the list of myitems added the list myvalues

The tasks below

    - set_fact:
        myvalues: "{{ myvalues|default([]) + [myitems.4] }}"
      loop: "{{ config.stdout_lines|select('regex', myregex)|list }}"
      vars:
        myregex: '^\d/\d/\d\s*(.*)$'
        myitems: "{{ item.split() }}"
      when: myitems.5 == "ATT"
    - debug:
        var: myvalues

give

    "myvalues": [
        "2344", 
        "2567"
    ]


Generally, it's possible to create a list with the names of the columns and create ditionaries with selected data. For example

    - set_fact:
        cols: "{{ config.stdout_lines.0.split() }}"
    - set_fact:
        myvalues: "{{ myvalues|default([]) +
                      [dict(cols|zip(myitems))] }}"
      loop: "{{ config.stdout_lines|select('regex', myregex)|list }}"
      vars:
        myregex: '^\d/\d/\d\s*(.*)$'
        myitems: "{{ item.split() }}"
      when: myitems.5 == "ATT"
    - debug:
        var: myvalues

gives

    "myvalues": [
        {
            "Call": "IDLE", 
            "DN": "2344", 
            "Dev": "ATT", 
            "Device": "DEV0001", 
            "Port": "0/1/0", 
            "State": "IS"
        }, 
        {
            "Call": "IDLE", 
            "DN": "2567", 
            "Dev": "ATT", 
            "Device": "DEV0002", 
            "Port": "0/1/1", 
            "State": "IS"
        }
    ]

Then any combination of the data can be selected. For example

    - set_fact:
        myports: "{{ myvalues|json_query('[].Port') }}"
    - debug:
        var: myports

give the list of the Ports

    "myports": [
        "0/1/0", 
        "0/1/1"
    ]

Upvotes: 3

Related Questions