Session 4: Integration with Enterprise Networks Hardware
In this session we discuss integration with network devices using REST APIs. Before we start with the API development, you need to have some basic knowledge and skills of how APIs work, how they are accessed, what are the authorisation methods, and how to pass some header information with our requests.
To answer these questions, we are going to use different tools e.g. cURL, Postman, and simple Python scripts to utilise REST APIs in the context of networking, particularly, network devices. In this video, we provide a step-by-step guide on how to use these APIs and interact with a networking platform.
Please use the following info/credentials to call the APIs.
- IOSXE Device
- Host: sandbox-iosxe-latest-1.cisco.com
- Username: developer
- Password: C1sco12345
- SSH Port: 22
- RESTCONF: 443
- Test SSH Connection:
- Open
Terminal
ssh developer@sandbox-iosxe-latest-1.cisco.com -p 22
- Enter the password:
C1sco12345
- Open
- Use cURL and REST/RESTCONF to Retrieve ietf-interfaces data in a JSON format
- Open
Terminal
- Retrieve data about all interfaces:
curl -vk -u developer:C1sco12345 -H "accept:application/yang-data+json" https://sandbox-iosxe-latest-1.cisco.com:443/restconf/data/ietf-interfaces:interfaces
- Retrieve data of a specific interface:
curl -vk -u developer:C1sco12345 -H "accept:application/yang-data+json" https://sandbox-iosxe-latest-1.cisco.com:443/restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet1
- Note: if you don't pass the header
-H "accept:application/yang-data+json"
, the data will be retrieved in default formatxml
- Open
- Using Postman to execute APIs
- Let's call the same API as we did in the cURL example:
- Install Postmane:
sudo snap install postman
- Open Postman and use this
https://sandbox-iosxe-latest-1.cisco.com:443/restconf/data/ietf-interfaces:interfaces
request URL with GET method. - Navigate to
Authorisation
, selectBasic Auth
, and enter your username(developer
) and password (C1sco12345
). - Navigate to
Headers
and add theAccept
header key withapplication/yang-data+json
value. Send
request
- Install Postmane:
- Let's call the same API as we did in the cURL example:
- IOSXE Device
- HTTP Request – Clicking this would display a dropdown list of different requests such as GET, POST, COPY, DELETE, etc. In Postman API testing, the most commonly used requests are GET and POST.
- Request URL – Also known as an endpoint, this is where you will identify the link to where the API will communicate with.
- Authorisation – In order to access APIs, proper authorisation is needed. It may be in the form of a username and password, bearer token, etc. In our case, we are using Basic Auth in the form of a username and password.
- Headers – You can set headers such as content type (
Accept
) JSON depending on the needs of the organisation. - Status - HTTP Response Status Code and Message
- Response Data in JSON format
Using JavaScript
- Enable cross-origin requests to anywhere:
https://cors-anywhere.herokuapp.com/corsdemo
- Enable cross-origin requests to anywhere:
<!DOCTYPE html> <html> <body> <h1>Calling a REST API using JavaScript</h1> <button type="button" onclick="loadDoc()">Request data</button> <p id="demo"></p> <script> function loadDoc() { var xhttp = new XMLHttpRequest(); var username="developer"; var password="C1sco12345"; xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("demo").innerHTML = this.response; } }; xhttp.open("GET", "https://cors-anywhere.herokuapp.com/https://sandbox-iosxe-latest-1.cisco.com:443/restconf/data/ietf-interfaces:interfaces", false); xhttp.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password)); xhttp.setRequestHeader("Accept", "application/yang-data+json"); xhttp.setRequestHeader("Access-Control-Allow-Origin", "*"); xhttp.send(); } </script> </body> </html>
Using Python to consume APIs
The following Python script calls the same API as we described in the previous sections. You have greater flexibility in Python or any other programming language to consume APIs and manipulate the extracted data according to your organisation needs.
To run these scripts, please copy and save it as a python file (with .py
extension) and run it via terminal:
- Python 3.*:
python3 script_name.py
- Python 2.*:
python script_name.py
- Python 3.*:
import requests import json import urllib3 urllib3.disable_warnings() HOST = 'sandbox-iosxe-latest-1.cisco.com' USER = 'developer' PASS = 'C1sco12345' url = "https://sandbox-iosxe-latest-1.cisco.com:443/restconf/data/ietf-interfaces:interfaces" headers = {'Content-Type': 'application/yang-data+json', 'Accept': 'application/yang-data+json'} response = requests.get(url, auth=(USER, PASS), headers=headers, verify=False) # print(response.content) interfaces = response.json() print("*******All Interfaces*******") print(json.dumps(interfaces, indent=2)) print("*******The first interface name*******") print(interfaces['ietf-interfaces:interfaces']['interface'][0]['name']) print("*******The first interface IP address*******") print(interfaces['ietf-interfaces:interfaces']['interface'][0]['ietf-ip:ipv4']['address'][0]['ip'])
Calling Cisco DNA Center APIs
In this section we will address Token-based authentication for APIs. Please use the following credentials while you are calling the DNA Center APIs:
- Host: sandboxdnac2.cisco.com
- Username: devnetuser
- Password: Cisco123!
Authentication API
Using Postman:
- Method
POST
- Request URL:
https://sandboxdnac2.cisco.com/dna/system/api/v1/auth/token
- Authorisation:
Basic Auth
with username and password - Header: Key:
Accept
, Value:application/json
- Response: Successful Token Generation
- Method
Using Python
import requests import json import urllib3 urllib3.disable_warnings() url = 'https://sandboxdnac2.cisco.com/dna/system/api/v1/auth/token' username = 'devnetuser' password = 'Cisco123!' headers={'content-type': 'application/json'} token = requests.post(url, auth=(username,password),headers=headers,verify=False,) data = token.json() print(data['Token'])
Get VLAN Details
In this example we will present how to use Token-based authentication to call an API.
Using Postman:
- Method
GET
- Request URL:
https://sandboxdnac2.cisco.com/
- Authorisation: Inherit auth from parent
- Header: Key:
X-Auth-Token
, Value: Obtained token from the Authentication API without double quotation - Response: Returns the list of VLAN names in JSON format
- Method
Using Python
from textwrap import indent import requests import json import urllib3 urllib3.disable_warnings() token = "Your Token obtained from the Authentication API" url = 'https://sandboxdnac2.cisco.com/dna/intent/api/v1/topology/vlan/vlan-names' headers= {'X-Auth-Token': '{}'.format(token),'content-type': 'application/json',} response = requests.get(url,headers=headers,verify=False,) print(json.dumps(response.json(), indent=2))
Additional Scripts
Here you can access a collection of python scripts for network management as well as samples that use exposed external APIs (NETCONF/RESTCONF, SNMP, SSH, REST, etc). The following example demonstrates using Netmiko library to work with interfaces and send configuration commands to device. Device info are stored in a .env
file.
Make sure you have installed the below required libraries:
python3 -m pip install netmiko
python3 -m pip install python-decouple
# Import libraries import os from netmiko import ConnectHandler from decouple import config import json dev_type = config('device_type') host = config('host') user = config('username') passwd = config('passwd') port = config('port') cisco_881 = { 'device_type': dev_type, 'host': host, 'username': user, 'password': passwd, 'port' : port, # optional, defaults to 22 'secret': '' # optional, defaults to '' } # Open CLI connection to device net_connect = ConnectHandler(**cisco_881) # Enable global configuration mode net_connect.enable() # Send command to device interfaces = net_connect.send_command('show ip int brief', use_textfsm=True) noi = len(interfaces) print("This device has " +str(noi) + " Interfaces") # Print the list of interfaces to the screen print(interfaces) config_command = ['int GigabitEthernet3', 'no shut'] output = net_connect.send_config_set(config_command) # Print the raw command output to the screen print(output) # Print the list of interfaces to the screen print(interfaces)