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"
]
]
} ]
1 Answer 1
- There should be
config.stdout_linesalong withconfig.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
whencondition and changing the list ofmyitemsadded the listmyvalues
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"
]
5 Comments
[myitems.4] to [myitems.0]. Port is the first item in the list. I've added an example of how to create any selection.
stdout_linesis a list of list. You need the first itemstdout_lines.0, obviously.config.stdout_lines.0is a list. It's not possiblesplit()a list. My answer works fine with the first output example. It's not working withstdout_linesyou posted. I'm not going to fix it. The names of the columns can't be used because "Device" is repeating. The lines with data can't be split because of one "Directory" item is missing. I'd expect Cisco to provide you with a format that can be parsed.