# Jupyter Notebook
# DevNet
# REST API
# Get ServiceTicket/ Token
# List Hosts on the network
# List Network Devices
# Perform Path Trace
import datetime
print ("Current date and time: ")
print(datetime.datetime.now())
print('Hello World')
print("Here are three network tests executed by APIC EM for enterprise networks")
print("- List all active hosts")
print("- List all network devices")
print("- Perform Path Trace in order to test connections in the datacenter")
#01_get_ticket.py
#This script retrieves an authentication token from APIC-EM and prints out it's value
#It is standalone, there is no dependency.
print ("Current date and time: ")
print(datetime.datetime.now())
print("Part 1 - Get ServiceTicket or token")
import json # Import JSON encoder and decoder module
import requests # requests module used to send REST requests to API
requests.packages.urllib3.disable_warnings() # Disable SSH warnings
print ("Current date and time: ")
print(datetime.datetime.now())
print("Importing necessary modules and disabling SSH warnings")
# TICKET API URL
# retrieves an authentication token from APIC-EM
# sandbox_url = 'https://devnetsbx-netacad-apicem-2.cisco.com/'
sandbox_url = 'https://devnetsbx-netacad-apicem-3.cisco.com/'
print ("Current date and time: ")
print(datetime.datetime.now())
post_url = sandbox_url+'api/v1/ticket'
print("URL for getting service ticket has just been created")
print(post_url)
# All APIC-EM REST API request and response content type is JSON.
headers = {'content-type': 'application/json'}
print ("Current date and time: ")
print(datetime.datetime.now())
print('HTTP Header created')
print("Using JSON to communicate parameters")
# JSON input body content -- 2: w0ISNW79 -- 3: Xj3BDqbU
body_json = {
'username': 'devnetuser',
'password': 'Xj3BDqbU'
}
print ("Current date and time: ")
print(datetime.datetime.now())
print("Username and password for access to the sandbox has just been defined")
print('Username and password passed in JSON format')
# Make request and get response - "resp" is the response of this request
resp = requests.post(post_url, json.dumps(body_json), headers=headers,verify=False)
print ("Current date and time: ")
print(datetime.datetime.now())
print("The request and all the necessary parameters have been sent")
# Create object to contain the request status
status = str(resp.status_code) #status code property of resp object
print ("Current date and time: ")
print(datetime.datetime.now())
print("Ticket request status: " + status) #display response code
# Create object to contain the converted json-formatted response
response_json = resp.json()
print ("Current date and time: ")
print(datetime.datetime.now())
print("The RAW json reply is being processed")
#parse data for service ticket
serviceTicket = response_json['response']['serviceTicket']
print ("Current date and time: ")
print(datetime.datetime.now())
print("The service ticket number is: " + serviceTicket)
print ("Current date and time: ")
print(datetime.datetime.now())
print("We now have a service ticket for the jobs following")
#Based on: lab1-1-get-host.py
#02_get_host_sol
#This script prints out all hosts that are connected to APIC-EM network devices in a tabular list format.
#02_get_host.py
#gets an inventory of hosts from \host endpoint
print ("Current date and time: ")
print(datetime.datetime.now())
print("Part 2 - List of hosts")
import requests
import json
from tabulate import *
print ("Current date and time: ")
print(datetime.datetime.now())
print("Importing necessary modules")
# HOST API URL
post_url = sandbox_url+'api/v1/host'
print ("Current date and time: ")
print(datetime.datetime.now())
print("URL for requesting list of active hosts has just been created")
print(post_url)
# All APIC-EM REST API request and response content type is JSON.
ticket = serviceTicket
headers = {'content-type':'application/json','X-Auth-Token':ticket}
print ("Current date and time: ")
print(datetime.datetime.now())
print("Using JSON to communicate parameters and passing the token that was created earlier")
print("Ticket: "+ticket)
print ("Current date and time: ")
print(datetime.datetime.now())
try:
resp = requests.get(post_url,headers=headers,params="",verify = False)
response_json = resp.json() # Get the json-encoded content from response
print ('Status of GET /host request: ',str(resp.status_code)) # This is the http request status
print ('Printing json reply')
print ('==============================================================')
print(response_json)
print ('==============================================================')
except:
print ('Something is wrong with GET /host request!')
sys.exit()
# Now create a list of host info to be held in host_list
host_list=[]
i=0
for item in response_json['response']:
i+=1
host_list.append([i,item['hostType'],item['hostIp']])
print ("Current date and time: ")
print(datetime.datetime.now())
print('Looping accross all detected hosts')
print ("Current date and time: ")
print(datetime.datetime.now())
print("Here's the list of active hosts")
print (tabulate(host_list,headers=['Number','Type','IP'],tablefmt='rst'))
#Based on: lab1-1-get-host.py
#04_get_device_sol
print ("Current date and time: ")
print(datetime.datetime.now())
print("This script prints out all network devices that are connected to APIC-EM network devices in a tabular list format")
import requests
import json
import sys
from tabulate import *
print ("Current date and time: ")
print(datetime.datetime.now())
print("Importing necessary modules")
# NETWORK-DEVICE API URL
post_url = sandbox_url+'api/v1/network-device'
print ("Current date and time: ")
print(datetime.datetime.now())
print("Preparing URL for list of network devices")
print(post_url)
# Setup API request headers.
ticket = serviceTicket
headers = {'content-type' : 'application/json','X-Auth-Token': ticket}
print ("Current date and time: ")
print(datetime.datetime.now())
print('Ticket: ' + ticket)
print("Using JSON to communicate parameters and passing the token that was created earlier")
print ("Current date and time: ")
print(datetime.datetime.now())
device_list=[]
try:
resp = requests.get(post_url,headers=headers,params='',verify = False)
response_json = resp.json() # Get the json-encoded content from response
print ('Status of GET /device request: ',resp.status_code) # This is the http request status
except:
print ('Something wrong with GET /host request!')
sys.exit()
# Now create a list of host summary info
i=0
for item in response_json['response']:
i+=1
device_list.append([i,item['type'],item['managementIpAddress']])
print('Looping accross all detected network devices')
print ("Current date and time: ")
print(datetime.datetime.now())
print ("List of network devices")
print (tabulate(device_list,headers=['Number','Type','IP'],tablefmt='rst'))
#04_path_trace_sol.py
#Path Trace testing network connectivity
print ("Current date and time: ")
print(datetime.datetime.now())
print("Part 3 - Path Trace Testing Network Connectivity")
#==================================================
# Section 1. Setup the environment and variables required to interact with the APIC-EM
#===================================================
import requests
import json
import time
import sys
from tabulate import *
requests.packages.urllib3.disable_warnings() #disables certificate security warning
print ("Current date and time: ")
print(datetime.datetime.now())
print("Importing necessary modules and disabling SSH warnings")
# Path Trace API URL for flow_analysis endpoint
post_url = sandbox_url+'api/v1/flow-analysis'
print("Preparing URL for path trace")
print ("Current date and time: ")
print(datetime.datetime.now())
print(post_url)
# Get service ticket number using imported function
ticket = serviceTicket
print ("Current date and time: ")
print(datetime.datetime.now())
print("The token or serviceticket has to be passed in the request")
print("Ticket: "+ticket)
# Create headers for requests to the API
headers = {
"content-type" : "application/json",
"X-Auth-Token": ticket
}
print ("Current date and time: ")
print(datetime.datetime.now())
print('HTTP Header created')
print("Alongside the token, the system informs that json will be used in communicatons with the services")
#============================
# Section 2. Display list of devices and IPs by calling get_host() and get_devices()
#============================
#++++++++++++++++++++++++++++++++++++++++++
print ("Current date and time: ")
print(datetime.datetime.now())
print('List of hosts on the network: ')
print (tabulate(host_list,headers=['Number','Type','IP'],tablefmt='rst'))
print('\n') #prints blank line to format output
print('List of devices on the network: ')
print (tabulate(device_list,headers=['Number','Type','IP'],tablefmt='rst'))
# ============================
# Section 3. Get the source and destination IP addresses for the Path Trace
# ============================
print ("Current date and time: ")
print(datetime.datetime.now())
while True:
#++++++++++++++++++++++++++++++++++++++++++
s_ip = input('Please enter the source IP address for the path trace: ')
d_ip = input('Please enter the destinaion IP address for the path trace: ')
#++++++++++++++++++++++++++++++++++++++++++
#Various error traps should be completed here - POSSIBLE CHALLENGE
if s_ip != '' or d_ip != '':
#this creates a python dictionary that will be dumped as a
path_data = {
"sourceIP": s_ip,
"destIP": d_ip
}
print('Source IP address is: ' + path_data['sourceIP']) #stud: optional challenge
print('Destination IP address is: ' + path_data['destIP']) #stud: optional challenge
break #Exit loop if values supplied
else:
print("\n\nYOU MUST ENTER IP ADDRESSES TO CONTINUE.\nUSE CTRL-C TO QUIT\n")
continue #Return to beginning of loop and repeat
#============================
# Section 4. Initiate the Path Trace and get the flowAnalysisId
#============================
#++++++++++++++++++++++++++++++++++++
# Post request to initiate Path Trace
path = json.dumps(path_data) #variable to hold the path_data
resp = requests.post(post_url,path,headers=headers,verify=False)
# Inspect the return, get the Flow Analysis ID, put it into a variable
resp_json = resp.json()
flowAnalysisId = resp_json["response"]["flowAnalysisId"]
print ("Current date and time: ")
print(datetime.datetime.now())
print('FLOW ANALYSIS ID: ' + flowAnalysisId)
print(path)
#============================
# Section 5. Check status of Path Trace request, output results when COMPLETED
#============================
print("This section might take some time to run")
status = ""
#Add Flow Analysis ID to the endpoint URL in order to check the status of this specific path trace
#++++++++++++++++++++++++++++++++++++
check_url = post_url + "/" + flowAnalysisId
#++++++++++++++++++++++++++++++++++++
checks = 0 #variable to increment within the while loop. Will trigger exit from loop after x iterations
print ("START - Current date and time: ")
start=datetime.datetime.now()
print(datetime.datetime.now())
while status != 'COMPLETED':
checks += 1
r = requests.get(check_url,headers=headers,params="",verify = False)
response_json = r.json()
#++++++++++++++++++++++++++++++++++++
status = response_json["response"]["request"]["status"]
#++++++++++++++++++++++++++++++++++++
print('REQUEST STATUS: ' + status)
#wait one second before trying again
time.sleep(2)
if checks == 15: #number of iterations before exit of loop; change depending on conditions
print("Number of status checks exceeds limit. Possible problem with Path Trace.")
#break
sys.exit()
elif status == 'FAILED':
print('Problem with Path Trace')
print('Problem with FlowAnalysisId: ' + check_url)
#break
sys.exit()
print('REQUEST STATUS: ' + status)
print(check_url)
print("Response in json format")
print ('==============================================================')
print(response_json)
print ('==============================================================')
print ("STOP - Current date and time: ")
print('START TIME: ' + str(start))
stop = datetime.datetime.now()
print('END TIME: ' + str(stop))
print('TIME NEEDED: '+ str(stop-start))
#============================
# Section 6. Display results
#============================
#+++++++++++Add Values+++++++++++++++
# Create required variables
path_source = response_json['response']['request']['sourceIP'] #the source address for the trace, printed below
path_dest = response_json['response']['request']['destIP'] #the destination address for the trace, printed below
networkElementsInfo = response_json['response']['networkElementsInfo'] #variable holding a list of all the network element dictionaries
print ("Current date and time: ")
print(datetime.datetime.now())
print("Responses are being processed")
print("Path Source "+path_source)
print("Path Dest "+path_dest)
print("Network Elements Information "+json.dumps(networkElementsInfo))
all_devices = [] # create a list variable to store the hosts and devices
device_no = 1 #this variable is an ordinal number for each device, incremented in the loop
#Iterate through returned Path Trace JSON and populate list of path information
for networkElement in networkElementsInfo:
# test if the devices DOES NOT have a "name", absence of "name" identifies an end host
if not 'name' in networkElement: #assigns values to the variables for the hosts
name = 'Unnamed Host'
ip = networkElement['ip']
egressInterfaceName = 'UNKNOWN'
ingressInterfaceName = 'UNKNOWN'
device = [device_no,name,ip,ingressInterfaceName,egressInterfaceName]
# if there is the "name" key, then it is an intermediary device
else: #assigns values to the variables for the intermediary devices
name = networkElement['name']
ip = networkElement['ip']
if 'egressInterface' in networkElement: #not all intermediary devices have ingress and egress interfaces
egressInterfaceName = networkElement['egressInterface']['physicalInterface']['name']
else:
egressInterfaceName = 'UNKNOWN'
if 'ingressInterface' in networkElement:
ingressInterfaceName = networkElement['ingressInterface']['physicalInterface']['name']
else:
ingressInterfaceName = 'UNKNOWN'
device = [device_no,name,ip,ingressInterfaceName,egressInterfaceName] #create the list of info to be displayed
all_devices.append(device) #add this list of info for the device as a new line in this variable
device_no += 1 #increments the ordinal variable for the device in the list
print ("Current date and time: ")
print(datetime.datetime.now())
print("Looping through all the devices")
print ("Current date and time: ")
print(datetime.datetime.now())
print('Path trace \nSource: ' + path_source + '\nDestination: ' + path_dest) #print the source and destination IPs for the trace
print('List of devices on path:')
print (tabulate(all_devices,headers=['Item','Name','IP','Ingress Int','Egress Int'],tablefmt="rst")) #print the table of devices in the path trace