cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
5410
Views
29
Helpful
7
Comments
aradford
Cisco Employee
Cisco Employee

Introduction

If you have been using APIC-EM for a little while, you are probably wondering about getting extra information from devices.

CommandRunner is a new application on APIC-EM that allows you to run multiple commands (currently max of 5 at a time) on a number of devices.

commandRunner.png

Naturally, this is exposed through an API and this blog looks at some tools to use that API.

API

The API for CommandRunner are quite simple.  There is a POST request that provides a list of deviceIds and commands to run.

https://adam-iwan/api/v1/network-device-poller/cli/read-request POST

{

"name" : "show ver",

"commands" : ["show ver | inc IOS-XE Soft"],

"deviceUuids" : [ "068e3625-b413-42b4-a07d-134081c1ff01"]

}

The response will be a task

{

  "response": {

    "taskId": "c563edd1-8932-4da4-aa37-c7cc9dbb3a10",

    "url": "/api/v1/task/c563edd1-8932-4da4-aa37-c7cc9dbb3a10"

  },

  "version": "1.0"


You then need to get the task body, to find a file containing the output.

https://adam-iwan/api/v1/task/c563edd1-8932-4da4-aa37-c7cc9dbb3a10 GET

"response": {

    "version": 1487283738594,

    "progress": "{\"fileId\":\"2d316e98-2667-4a6e-a084-6e039a5817be\"}",

    "startTime": 1487283736972,

    "endTime": 1487283738595,

    "username": "admin",

    "serviceType": "Network Poller Service",

    "isError": false,

    "lastUpdate": 1487283738594,

    "rootId": "c563edd1-8932-4da4-aa37-c7cc9dbb3a10",

    "id": "c563edd1-8932-4da4-aa37-c7cc9dbb3a10"

},

"version": "1.0"

}

Then get the file body to see the contents

https://adam-iwan/api/v1/file/2d316e98-2667-4a6e-a084-6e039a5817be  GET

[{

       "deviceUuid": "068e3625-b413-42b4-a07d-134081c1ff01",

       "commandResponses": {

              "SUCCESS": {

                      "show ver | inc IOS-XE Soft": "Cisco IOS Software, IOS-XE Software, Catalyst L3 Switch Software (CAT3K_CAA-UNIVERSALK9-M), Version 03.06.05E RELEASE SOFTWARE (fc2)\n"

              },

              "BLACKLISTED": {},

              "FAILURE": {}

       }

}]

Installation

The tools are published at the following repository https://github.com/aradford123/APIC-Command-Runner

Instructions for installing on a MAC/Linux machine follow:

git clone https://github.com/aradford123/APIC-Command-Runner

Then i recommend creating a virtualenv

cd APIC-Command-Runner

virtualenv -p python3 env

source env/bin/activate

Remember, if you exit your shell or logout, you will need to run the command "source env/bin/activate" each time to activate the virtual environment.

Finally you need to install the uniq library.  NOTE: If you have this already, you need version 1.4

pip install –r requirements.txt

Examples

To run the script you need to add your controller and the credentials for it.  You can do this in two ways:

  1. edit the apic_config.py file
  2. use the APIC, APIC_USER and APIC_PASSWORD environment variables.  For example the shell command "export APIC='sandboxapic.cisco.com'" would set the controller to the DevNet cloud controller. Be very careful with quotes. Here is an example of a file containing all of the variables.

$ cat env_vars

export APIC="apic-em"

export APIC_USER="admin"

export APIC_PASSWORD="password"

$ source ./env_vars

If you run the script without any augments you will get a list of valid commands.

$ ./cmd_runner.py

tag: None

no ips or tags for network devices

ValidCommands: call-home, cd, cping, crypto, dir, eping, grep, help, mediatrace, monitor, more, mping, mstat, ping, pwd, sdlc, show, standby, start-chat, systat, tarp, test, traceroute, ucse, verify, where, which-route

The cmd_runner.py script runs a command on one or more devices. Devices can be specified by IP address or tag.

$ ./cmd_runner.py --ip 192.168.14.16 --command "show clock"

tag: None

['show clock']

[

  {

    "commandResponses": {

      "FAILURE": {},

      "BLACKLISTED": {},

      "SUCCESS": {

        "show clock": "20:44:40.509 UTC Sat Feb 25 2017"

      }

    },

    "deviceUuid": "5abffd04-f981-46be-8640-789af2e910d6"

  }

]

The response shows you the devices that were successful, those that failed, and those commands that are blacklisted.

You can run a command on all devices with a certain tag.  When the 1.4 release came out, you need to find out the version of NBAR protocol pack on the devices.  I have tagged my IWAN devices with the tag "iwan", so the command will run on all of them.  The "—human" option just displays the managementIpAddress of the device, and the output.

$ ./cmd_runner.py --tag iwan --command 'show ip nbar protocol-pack active |  inc Ver' --human

tag: iwan

['show ip nbar protocol-pack active |  inc Ver']

  1. 192.168.3.129: show ip nbar protocol-pack active |  inc Ver:

Version:                         28.0

NBAR Engine Version:             23

{}

  1. 192.168.13.1: show ip nbar protocol-pack active |  inc Ver:

Version:                         28.0

NBAR Engine Version:             23

{}

  1. 10.10.3.13: show ip nbar protocol-pack active |  inc Ver:

Version:                         28.0

NBAR Engine Version:             23

{}

  1. 10.10.2.13: show ip nbar protocol-pack active |  inc Ver:

Version:                         28.0

NBAR Engine Version:             23

{}

You can also use this API to run "test" commands:

$ ./cmd_runner.py --tag switch --command 'test cable-diagnostics tdr interface g1/0/1' --human

tag: switch

['test cable-diagnostics tdr interface g1/0/1']

  1. 10.10.2.130: test cable-diagnostics tdr interface g1/0/1:

TDR test started on interface Gi1/0/1

A TDR test can take a few seconds to run on an interface

Use 'show cable-diagnostics tdr' to read the TDR results.

{}

  1. 192.168.12.160: test cable-diagnostics tdr interface g1/0/1:

TDR test started on interface Gi1/0/1

A TDR test can take a few seconds to run on an interface

Use 'show cable-diagnostics tdr' to read the TDR results.

{}

  1. 10.10.14.2: test cable-diagnostics tdr interface g1/0/1:

TDR test started on interface Gi1/0/1

A TDR test can take a few seconds to run on an interface

Use 'show cable-diagnostics tdr' to read the TDR results.

{}

  1. 192.168.14.16: test cable-diagnostics tdr interface g1/0/1:

TDR test started on interface Gi1/0/1

A TDR test can take a few seconds to run on an interface

Use 'show cable-diagnostics tdr' to read the TDR results.

{}

  1. 10.10.10.110: test cable-diagnostics tdr interface g1/0/1:

TDR test started on interface Gi1/0/1

A TDR test can take a few seconds to run on an interface

Use 'show cable-diagnostics tdr' to read the TDR results.

{}

You then need to run the "show command" to get the results.

$ ./cmd_runner.py --tag switch --command 'show cable-diagnostics tdr interface g1/0/1' --human

tag: switch

['show cable-diagnostics tdr interface g1/0/1']

  1. 192.168.12.160: show cable-diagnostics tdr interface g1/0/1:

TDR test last run on: February 25 21:13:42

Interface Speed Local pair Pair length        Remote pair Pair status

--------- ----- ---------- ------------------ ----------- --------------------

Gi1/0/1 1000M Pair A     33   +/- 10 meters Pair A      Normal             

                Pair B     33 +/- 10 meters Pair B Normal             

                Pair C     33 +/- 10 meters Pair C Normal             

                Pair D     33 +/- 10 meters Pair D      Normal

{}

  1. 192.168.14.16: show cable-diagnostics tdr interface g1/0/1:

TDR test last run on: February 25 21:13:42

Interface Speed Local pair Pair length        Remote pair Pair status

--------- ----- ---------- ------------------ ----------- --------------------

Gi1/0/1 1000M Pair A     25   +/- 10 meters Pair A      Normal             

                Pair B     25 +/- 10 meters Pair B Normal             

                Pair C     25   +/- 10 meters Pair C      Normal             

                Pair D     25 +/- 10 meters Pair D      Normal

{}

  1. 10.10.10.110: show cable-diagnostics tdr interface g1/0/1:

TDR test last run on: February 25 21:13:42

Interface Speed Local pair Pair length        Remote pair Pair status

--------- ----- ---------- ------------------ ----------- --------------------

Gi1/0/1 1000M Pair A     0    +/- 10 meters Pair B      Normal             

                Pair B     0 +/- 10 meters Pair A      Normal             

                Pair C     0 +/- 10 meters Pair D Normal             

                Pair D     0 +/- 10 meters Pair C      Normal

{}

  1. 10.10.2.130: show cable-diagnostics tdr interface g1/0/1:

TDR test last run on: February 25 21:13:42

Interface Speed Local pair Pair length        Remote pair Pair status

--------- ----- ---------- ------------------ ----------- --------------------

Gi1/0/1 1000M Pair A     0    +/- 10 meters Pair A      Normal             

                Pair B     0 +/- 10 meters Pair B Normal             

                Pair C     0 +/- 10 meters Pair C Normal             

                Pair D     0 +/- 10 meters Pair D      Normal

{}

  1. 10.10.14.2: show cable-diagnostics tdr interface g1/0/1:

TDR test last run on: February 25 21:13:42

Interface Speed Local pair Pair length        Remote pair Pair status

--------- ----- ---------- ------------------ ----------- --------------------

Gi1/0/1 1000M Pair A     0    +/- 10 meters Pair A      Normal             

                Pair B     0 +/- 10 meters Pair B Normal             

                Pair C     0 +/- 10 meters Pair C Normal             

                Pair D     0 +/- 10 meters Pair D      Normal

{}

Enabling CommandRunner

CommandRunner is not enabled by default.  You have to download and install it from CCO.  First login to CCO, and select the CommandRunner application.

download software.png

Use the "Admin->App Management" menu to get to the screen to upload onto the controller.

app management.png

Then drag and drop.

draganddrop.png

Once the application has been installed (that will take a few minutes) you need to enable it.

enable.png

What Next?

I will keep adding to these utilities as I get time.  They are not officially (or unofficially J) supported, just examples of tools to make life easier.

In the meantime, if you would like to learn more about this, you could come hang out with us in The Cisco Devnet DNA Community. We’ll have a continuous stream of blogs like this and you can ask questions and we’ll get you answers.

In addition, we have a Github repository where you can get examples related to APIC-EM

Thanks for reading,

  @adamradford123

7 Comments
b-yassamine
Level 1
Level 1

did the last APIC-EM release use yang as a modeling language ?

aradford
Cisco Employee
Cisco Employee

not yet, Yang is not supported on older devices (which APIC-EM) also supports.  It will be introduced soon

b-yassamine
Level 1
Level 1

thanks adam

Jason Belk
Cisco Employee
Cisco Employee

Looks cool! Thanks for putting up examples. Though, I am still looking for a way to gather operational data (show commands) from older non-yang IOS devices, in a structured data returned format. It seems often doing such things either requires really complex RegEx or just dumping the entire output into one big string to be parsed by some other module. The closest we have been able to get to pulling specific information, such as just one piece of show version, like the current image file being run, is getting that specific SNMP OID, which is tedious and not scalable across all platforms. Looking forward to having all IOS on polaris / yang and netconf enabled programmatic access.

aradford
Cisco Employee
Cisco Employee

Did you see the example in the code using TextFSM to parse output.

You define a template for the command (in this case 'show inline power') and can run the output through the template.

Screen Shot 2017-04-13 at 5.02.42 am.png

The template file is pretty simple, it does use some regexp, but is much simpler than full processing.

I was thinking of updating the blog to talk about this?

Jason Belk
Cisco Employee
Cisco Employee

Hi Adam,

Wow, had not used or heard of FSM before, but now your code makes a lot more sense. Tried it out :

(adam)   :fsm jabelk$ python test_inline.py

[['1', '390.0', '0.0', '390.0'], ['2', '390.0', '0.0', '390.0']]

(adam)  :fsm jabelk$

I think it would worth calling out in the blog, or even having a separate blog to discuss it specifically. Until netconf/yang is standard on vanilla IOS, lots of legacy devices are going to need this type of programmatic interim manipulation. I see a lot of cool blog posts on IOS XE /XR uses of API's, but this is the first I have found that helps me as engineer who has a lot of legacy IOS devices that will do not support yang etc.

aradford
Cisco Employee
Cisco Employee

Thanks for feedback Jason.

I will do a Part2 to this one.

I initially did the "show power inline" example as I had a customer who wanted to see power usage on their switches and the version of code did not have any MIBS to it, only CLI. :-)

Adam

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: