Framework for Cisco APIs
This document discusses all the Cisco APIs that are avaiable and compares each of them. For detail, you can access the following orgmode documents:
1 API documents
These are all located in the eg/API directory:
2 15% 3.0 Cisco Platforms and Development
For each of these you should know:
- how to get the documentation for the API?
- how does the API handle authentication?
- what APIs are supported?
- what python sdk or toolkits are available and where do I download them?
3 3.1 Construct a Python script that uses a Cisco SDK given SDK documentation
For each of the files types, best to use the with contstruct to open them for reading into python
with open("myformattedfile") as f: ingestintopython = f.read()
Then the ingested file can be parsed according to the file type, i.e. xml, json, yaml, csv.
Data formats:
Format | Python | Usage |
---|---|---|
library | x should be more descriptive. using here to save space | |
eg xmldict, or jsondict, or yamldict respectively | ||
xml | import | x = xmltodict.parse("ingestintopython") |
xmltodict | intname = x["interface"]["name"] | |
x["interface"]["ipv4"]["address"]["ip"] = "10.1.1.4" | ||
output = xmltodict.unparse(x) | ||
json | import | x = json.loads(ingestintopython) |
json | intname = x["interface"]["name"] | |
x["interface"]["ipv4"]["address"][0]["ip"] = "10.1.1.4" | ||
output = json.dumps(x) | ||
loads and dumps means " json load string" and "dump string" | ||
yaml | PyYAML | x = yaml.load(ingestintopython) |
intname = x["interface"]["name"] | ||
import | x["interface"]["ipv4"]["address"][0]["ip"] = "10.1.1.4" | |
yaml | ||
output = yaml.dump(x, defaultflowstype=False) | ||
csv | csv | # same with open as the rest, but must use csv.reader eg: |
ingestingopython = csv.reader(f) # one line at a time | ||
import | for row in ingestintopython: | |
csv | print("{device} is in {location} and has IP {ip}".format( | |
device = row[0], | ||
location = row[2], | ||
ip = row[1])) | ||
YANG | pyang | See YANG file |
3.0.1 API Libraries
Type | usage | Library | Often used with |
---|---|---|---|
REST APIs | pip intsll requests | requests | RESTCONF |
import requests | native REST APIs | ||
JSON-RPC | |||
NETCONF | pip install ncclient | ncclient | NETCONF YANG |
import ncclient | |||
Network | pip install netmiko | netmiko | |
CLI | import netmiko | ||
SNMP | pip install pysnmp | PySNMP | |
import pysnmp |
See both NETCONF.org and RESTCONF.org for details on both those.
3.1 netmiko for Network CLI API library
Use this only
if the other libraries are not available. Because you will be
manually handling the parsing where before you could let ncclient, or request
do the mundane heavy lifting for you.
- builds on paramiko library for SSH connectivity
- works with multi vendors and multiple operating systems
- send and receive clear text
- will need to run post-processing on the data.
Example gathering info using netmiko
from netmiko import ConnectHandler import re # regexp useful here as we will be parsing text import sys # Add parent directory to path to allow importing device_info (common vars) sys.path.append("..") from device_info import iox_xe1 as device #noqa # set device_type for netmiko device["device_type"] = "cisco_ios" # create a cli command template show_interface_config_temp = "show running-config interface {}" with ConnectHandler(ip = device["address"], port = device["ssh_port"], username = device["username"], password = device["password"], device_type = device["device_type"]) as ch: # create desired CLI command and send to device command = show_interface_config_temp.format("GigabitEthernet2") interface = ch.send_command(command) print(interface) # Use regular expressions to parse the outpout for desired data name = re.search(r'interfacer (.*)', interface).group(1) description = re.search(r'description (.*)', interface).group(1) ip_info = re.search(r'ip address (.*)', interface) ip = ip_info.group(1) netmask = ip_info.group(2) # print the info I wanted print(f'The interface{name} hs ip address {ip}/{netmask}')
Example updating a config using netmiko
from netmiko import ConnectHandler import re # regexp useful here as we will be parsing text import sys # Add parent directory to path to allow importing device_info (common vars) sys.path.append("..") from device_info import iox_xe1 as device #noqa # set device_type for netmiko device["device_type"] = "cisco_ios" # create the details for a loopback interface and store in a dictionary loopback = {"int_name": "Loopback27", "description": "Created looback27 using netmiko", "ip": "10.1.1.5", "netmask": "255.255.0.0"} # create the CLI config as a list. They are a series of commands I want to send interface_config = [ "interfacer {}".format(loopback["int_name"], "description {}".format(loopback["description"], "ip address {}".format(loopback["ip"], loopback["netmask"]), "no shut"] with ConnectHandler(ip = core1["ip"], username=username, password=password, device_type = core1["device_type"]) as ch: # send the configuration to the device. Notice that my config set did # NOT include the command "config t". Netmiko assumes that's what you # want to do when you do a "ch.send_config_set" so it has it covered.:) output = ch.send_config_set(interface_config)
3.2 SNMP as API using PySNMP
This one is more complex. Use examples readily available online.
PySNMP supports both GET and TRAP communications. Data is returnd in custom objects, see http://snmplabs.com/pysnmp/ and https://github.com/etingof/pysnmp
The PySNMP docs has these samples. pysnmp.readthedocs.io/…/quick-start.html pysnmp.readthedocs.io/…/walking-operations.html pysnmp.readthedocs.io/…/modifying-variables.html
3.3 Cisco Configuration Management using Opensource Python modules
There are four common modules, and probably many niche modules, that are used for configuration management. They are:
Network Automation, programmed in python:
- NAPALM
- library providing standard set of functions for working with different network OSes.
- Nornir
- can leverage other tools like NAPALM
Server Automation, programmed in python:
- Ansible
- declarative, agent-less automation framework for managing configuration.
- Many "modules" available from many network vendors, and Unix admin.
- Salt
- config management and remote code execution engine. net automation not yet fully baked.
3.3.1 NAPALM
- very robust and mature
- multivendor
- quite popular and widely used.
- builds on availabe backend libs and interfaces (CLI, NX-API, NETCONF)
- can be used and integrated into Anisble and Nornir.
- config options include "Replace, Merge, Compare Commit, Discard, Rollback
Docs are in readthedocs.io
3.3.2 Ansible
Currently the leading devops tool for network config mgt.
- agentless
- uses ssh
- supports cli and NETCONF as way of interacting with the network device.
- has many usable network modules published by Cisco and others.
One common tools is "Ansible SALT Stack" combines Ansible with SALT.
3.3.3 VIRLUTILS
virlutils is a python utility/libarary. Great for virl and cml. virlutils
is a command-line wrapper
written in python
that lets you very easily access
and control your virl, or cml, environment.
Really useful for NetDevOps workflows, when you are running tests and config changes in a simulation before applying to a production environment. The simulation is VIRL or CML. i.e. great for CI/CD pipelines.
See developer.cisco.com/…/virlutils/
virlutils
is the newer approach to vagrant
.
Examples of common commands:
$ virl up
starts up a virl lab$ virl ls
to list what simulations you have running$ virl nodes
# first have to tell cml which lab is "current"$ virl use <id>
# make <id> the current lab
To use virlutils:
- clone the repo:
- git clone https://github.com/CiscoDevNet/virlutils
- cd virlutils
- use pip or setup.py
- pip install cmlutils
pip install virlutils
or,
- python3 -m venv venv-cmlutils
- source venv-cmlutils/bin/activate
- python setup.py install
- Setup .virlrc with these virl credentials:
VIRL_HOST myvirlserver.zintis.net=
VIRL_USERNAME=admin
VIRL_PASSWORD=M0dellinglabs
CML_VERIFY_CERT=False
# or if you had the cml server .pem file
Alternatively you can use environment variables:
export VIRL_HOST 192.168.11.66
export VIRL_USERNAME=admin
export VIRL_PASSWORD=M0dellinglab
CML_VERIFY_CERT=False
# or/etc/certs/ca_bundle.pem
I ran this and virl ls worked.
This command will be passed the CML controller VM IP, the console path of the node, and the CML controller username (note: you may have to force a TTY allocation in your SSH command. On my mac I did NOT have to.)
More info at developer.cisco.com/…/virltuils
3.4 Using cmlutils / virlutils
Once a lab is up and virlults is working, you should name your lab so that
you can run virl use <name>
You can name it using the cml web interface,
first select your lab, then, the name appears at the top line. This is an
editable field. Call it something good, i.e. <name>
Here's what I did:
$ virl ls Labs on Server ╒════════╤═════════════════════╤═══════════════╤═════════╤══════════╤═════════╤═════════╤══════════════╕ │ ID │ Title │ Description │ Owner │ Status │ Nodes │ Links │ Interfaces │ ╞════════╪═════════════════════╪═══════════════╪═════════╪══════════╪═════════╪═════════╪══════════════╡ │ dcede0 │ Lab at Mon 14:46 PM │ │ admin │ STARTED │ 9 │ 14 │ 82 │ ╘════════╧═════════════════════╧═══════════════╧═════════╧══════════╧═════════╧═════════╧══════════════╛ (venv-pyats) /Users/zintis/bin/python/venv-pyats/cml[667]:
Then I renamed my lab to Zint-cml *and gave it a description too, using the web interface:
$ virl ls Labs on Server ╒════════╤══════════╤══════════════════════╤═════════╤══════════╤═════════╤═════════╤══════════════╕ │ ID │ Title │ Description │ Owner │ Status │ Nodes │ Links │ Interfaces │ ╞════════╪══════════╪══════════════════════╪═════════╪══════════╪═════════╪═════════╪══════════════╡ │ dcede0 │ Zint-cml │ route redistribution │ admin │ STARTED │ 9 │ 14 │ 82 │ ╘════════╧══════════╧══════════════════════╧═════════╧══════════╧═════════╧═════════╧══════════════╛
Then
$ virl use Zint-cml (venv-pyats) /Users/zintis/bin/python/venv-pyats/cml[670]: $ virl nodes Here is a list of nodes in this lab ╒══════╤════════════════════╤════════════════════╤═════════╤══════════╤══════════════════╕ │ ID │ Label │ Type │ State │ Wiped? │ L3 Address(es) │ ╞══════╪════════════════════╪════════════════════╪═════════╪══════════╪══════════════════╡ │ n1 │ unmanaged-switch-0 │ unmanaged_switch │ BOOTED │ False │ │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n2 │ iosv-0 │ iosv │ BOOTED │ False │ 192.168.11.68 │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n3 │ iosv-1 │ iosv │ BOOTED │ False │ 192.168.11.67 │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n4 │ iosv-2 │ iosv │ BOOTED │ False │ 192.168.11.69 │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n5 │ iosv-3 │ iosv │ BOOTED │ False │ 192.168.11.71 │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n6 │ iosv-4 │ iosv │ BOOTED │ False │ 192.168.11.70 │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n7 │ alpine-0 │ alpine │ BOOTED │ False │ │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n8 │ iosv-5 │ iosv │ BOOTED │ False │ 192.168.11.72 │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n0 │ ext-conn-0 │ external_connector │ BOOTED │ False │ │ ╘══════╧════════════════════╧════════════════════╧═════════╧══════════╧══════════════════╛ (venv-pyats) /Users/zintis/bin/python/venv-pyats/cml[671]:
And finaly shutting the lab down:
$ virl down Shutting down lab Zint-cml (ID: dcede0)..... SUCCESS (venv-pyats) /Users/zintis/bin/python/venv-pyats/cml[672]: $ virl ls Labs on Server ╒════════╤══════════╤══════════════════════╤═════════╤══════════╤═════════╤═════════╤══════════════╕ │ ID │ Title │ Description │ Owner │ Status │ Nodes │ Links │ Interfaces │ ╞════════╪══════════╪══════════════════════╪═════════╪══════════╪═════════╪═════════╪══════════════╡ │ dcede0 │ Zint-cml │ route redistribution │ admin │ STOPPED │ 9 │ 14 │ 82 │ ╘════════╧══════════╧══════════════════════╧═════════╧══════════╧═════════╧═════════╧══════════════╛ (venv-pyats) /Users/zintis/bin/python/venv-pyats/cml[673]: $ virl nodes Here is a list of nodes in this lab ╒══════╤════════════════════╤════════════════════╤═════════╤══════════╤══════════════════╕ │ ID │ Label │ Type │ State │ Wiped? │ L3 Address(es) │ ╞══════╪════════════════════╪════════════════════╪═════════╪══════════╪══════════════════╡ │ n1 │ unmanaged-switch-0 │ unmanaged_switch │ STOPPED │ False │ │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n2 │ iosv-0 │ iosv │ STOPPED │ False │ │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n3 │ iosv-1 │ iosv │ STOPPED │ False │ │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n4 │ iosv-2 │ iosv │ STOPPED │ False │ │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n5 │ iosv-3 │ iosv │ STOPPED │ False │ │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n6 │ iosv-4 │ iosv │ STOPPED │ False │ │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n7 │ alpine-0 │ alpine │ STOPPED │ False │ │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n8 │ iosv-5 │ iosv │ STOPPED │ False │ │ ├──────┼────────────────────┼────────────────────┼─────────┼──────────┼──────────────────┤ │ n0 │ ext-conn-0 │ external_connector │ STOPPED │ False │ │ ╘══════╧════════════════════╧════════════════════╧═════════╧══════════╧══════════════════╛ (venv-pyats) /Users/zintis/bin/python/venv-pyats/cml[674]:
3.5 3.2 Describe the capabilities of Cisco network management platforms and APIs
(Meraki, Cisco DNA Center, ACI, Cisco SD-WAN, and NSO)
3.6 3.3 Describe the capabilities of Cisco compute management platforms and APIs
(UCS Manager, UCS Director, and Intersight)
3.7 3.4 Describe the capabilities of Cisco collaboration platforms and APIs
(Webex Teams, Webex devices, Cisco Unified Communication Manager including AXL and UDS interfaces, and Finesse)
3.8 3.5 Describe the capabilities of Cisco security platforms and APIs (Firepower,
Umbrella, AMP, ISE, and ThreatGrid)
3.9 3.6 Describe the device level APIs and dynamic interfaces for IOS XE and NX-OS
3.10 3.7 Identify the appropriate DevNet resource for a given scenario (Sandbox,
Code Exchange, support, forums, Learning Labs, and API documentation)
3.11 3.8 Apply concepts of model driven programmability (YANG, RESTCONF, and
NETCONF) in a Cisco environment
3.12 3.9 Construct code to perform a specific operation based on a set of
requirements and given API reference documentation such as these:
3.12.1 3.9.a Obtain a list of network devices by using
- Meraki,
- Cisco DNA Center,
- ACI,
- Cisco SD-WAN, or NSO
3.12.2 3.9.b Manage spaces, participants, and messages in Webex Teams
3.12.3 3.9.c Obtain a list of clients / hosts seen on a network using
- Meraki or
- Cisco DNA Center
4 3.2
5 API Authentication Links
The exam blue print asks that you know common API authentication mechanisms:
- basic,
- custom token, and
- API keys
The following table compares each APIs auth method.
API | Method | URI |
---|---|---|
<c> | URI | |
DNA Center | Basic |
"https:///dna/system/api/v1/auth/token" or |
Auth |
"https:///dna/system/api/v1/auth/token?hostname=Switch1" | |
with these headers: | ||
Returns | - Content-Type "application/json" | |
a | - Authorization "Basic + base64encodedstring" | |
Token | - Accept "application/json" | |
Webex | token | Retrieve manually from "Your Personal Access Token" in |
https://developer.webex.com/docs/api/getting-started | ||
Meraki API | token | Retrieve it manually from dashboard, my profile. |
ACI REST API | cookie | POST https://{{apic}}/api/aaLogin.json |
ACI SDK | POST https://{{apic}}/api/aaLogin.xml |
|
ACI Toolkit | see ACI API REST API i.e. mysess = Session(URL, LOGIN, PASSWD) |
|
NSO REST API | u + p | $ curl -i -X GET http://localhost:8080/api -u admin:admin |
NSO RESTCONF | token | the token does not support encryption. |
NSO does not support client-certificate based authentication. | ||
SDWAN API | token | |
AMP API | Basic |
Authorization: Basic mybase64string |
Auth |
AMP = {"KEY": "e815426e-bb64-cf4f-71ba-5112febdead5", | |
"ID": "8595782abe51ba411223"} | ||
Token | url = "https://<ampid>:<ampkey>@api.amp.cisco.com/v1/computers" | |
Firepower | oAuth | Request a password-granted access token based on |
Threat | 2.0 | username/password using the admin account, or optionally |
Defence | (token) | request a custom token. After which you the access token |
in your API calls in the Authorization: Bearer header |
||
When token expires, reissue a new one. |
Reminder that curl also support -H "Accept: application/vnd.yang.api+json" style headers.
6 API Tokens from Responses
API | Method | Postman |
---|---|---|
DNA Center | token | X-Auth-Token header. You will have to refresh |
the token quite regularly by running the | ||
authorization code (zp-update-tokens.py) | ||
Webex | token | 'Authorization': "Bearer " + zintis_bearer_code |
header. Also has | ||
Meraki | token | 'X-Cisco-Meraki-API-Key': env_user_zp.ZP_MERAKI_API_KEY' |
ACI REST API | cookie | Browser will get a |
ACI SDK | cookie and use that | |
ACI Toolkit | session = Session(URL, LOGIN, PASSWORD |
|
NSO API | token | for RESTCONF a token, for older REST API just -u -p |
SDWAN API | token | |
AMP API | Basic | |
Returns | ||
a | ||
Token | ||
7 API Documentation / Catalog
API | Documentation / Catalog |
---|---|
DNA Center | From Appliance home page, click Platform |
> View the API Catalog , |
|
> Developer Toolkit (see search box top-R) |
|
Meraki API | From logged in dashboard.meraki.com |
> Help > API Documentation or directly to | |
https://developer.cisco.com/meraki/api-v1/ | |
ACI REST API | https://{{apic}}/api/aaLogin.json |
ACI SDK | https://{{apic}}/api/aaLogin.xml |
ACI Toolkit | |
NSO API | |
SDWAN API | |
AMP API | api-docs.amp.cisco.com/apiresources |
8 API documents
These are all located in the eg/API directory: