1

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"
 ]
 ]
} ]
asked Mar 24, 2020 at 11:51
6
  • Update your question with the output of - debug: var=config Commented Mar 24, 2020 at 20:39
  • I've added the stdout_lines output Commented Mar 24, 2020 at 21:36
  • stdout_lines is a list of list. You need the first item stdout_lines.0, obviously. Commented Mar 24, 2020 at 22:08
  • ok I still get a similar error as before after modifying the line cols: "{{ config.stdout_lines.0.split() }}" "The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'split'\n\nThe error appears to have been in Commented Mar 24, 2020 at 22:35
  • config.stdout_lines.0 is a list. It's not possible split() a list. My answer works fine with the first output example. It's not working with stdout_lines you 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. Commented Mar 24, 2020 at 22:45

1 Answer 1

3
  • 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"
 ]
answered Mar 24, 2020 at 16:44
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks Vladimir. I need the find the ports that match the Call State, not the DN. So the output should be 0/1/0, 0/1/1 and so on.
Sure. Simply change [myitems.4] to [myitems.0]. Port is the first item in the list. I've added an example of how to create any selection.
yep I thought that would be case but I'm having problems executing the script. I get the below error TASK [set_fact] ****************************************************************************************************** fatal: [router1]: FAILED! => {"msg": "Unexpected templating type error occurred on ({{ config.stdout_lines | select('regex', myregex)|list }}): expected string or buffer"} Could it be because of the way the output gets formatted in IOS?
This below post says to use output.stdout | join('') instead of stdout_lines but this gives me "myvalues": "VARIABLE IS NOT DEFINED!" in the debug output. stackoverflow.com/questions/45737295/…
I tried your dictionaries code but I got the below error: TASK [set_fact] *************************************************************************************************************************************************************************** fatal: [router1]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'lines'\n\n

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.