Flashpost: How many clients are there in your campus?

Just quick one I would like to share with you. I’ve been using Cisco’s APIC-EM for some time now and even though I think the list of available features is somewhat short it’s still usefull to get a lot of information from the API.

Cisco seems to be moving on to DNA Center which looks so much more interesting but APIC-EM may still be interesting because you don’t need any additional licenses.

For those of you who don’t know what APIC-EM is, in short, it’s a network inventory tool which can also do path tracing and qos settings. It misses a lot of functionality other tools may have but it works great and doesn’t require a lot of work configuring.

Enough of the theoretical stuff, let’s dive right into the script! This is the result of a few hours work so don’t expect fancy error-handling but do expect some bugs.

I wrote this script because I needed the amount of clients connected to a campus switch. The information is allready in the APIC-EM WUI but because you are limited and how you can filter and which information is displayed I decided to get acquainted with the APIC-EM API.

Below the script I added a description of the returned fields so you can easily edit the output if needed.

import requests
import json
import getpass
import sys
import urllib3

#disable insecure ssl warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

#set header to json
hdr = {'content-type': 'application/json'}

#apic-em data
base_url = 'https://apicem-url-or-ip'
user = input('Username:')
password = getpass.getpass()

#get service ticket
data_json = {
	'username': user,
	'password': password
}
post_url = base_url + '/api/v1/ticket'
resp = requests.post(post_url, json.dumps(data_json), headers=hdr,verify=False)

if resp.status_code != 200:
	print('Response code: ', resp.status_code)
	sys.exit()
	
response_json = resp.json()
ticket = response_json['response']['serviceTicket']
hdr = {'content-type': 'application/json', 'X-Auth-Token': ticket}

#get devices
post_url = base_url + '/api/v1/network-device'
resp = requests.get(post_url, json.dumps(data_json), headers=hdr,verify=False)

response_json = resp.json()

for switch in response_json['response']:
	#get hosts
	post_url = base_url + '/api/v1/host?connectedNetworkDeviceIpAddress=' + switch['managementIpAddress']
	host_resp = requests.get(post_url, json.dumps(data_json), headers=hdr,verify=False)
	host_json = host_resp.json()
	if len(host_json['response']) > 0:
		print(switch['hostname'],'(',switch['managementIpAddress'],'): ',len(host_json['response']),' clients')

The last line is where the output is printed, so if needed edit that one with any fields listed below to get more information in your output.

Host fields:

{
  "version": "",
  "response": [
    {
      "source": "",
      "id": "",
      "connectedAPMacAddress": "",
      "connectedAPName": "",
      "connectedInterfaceId": "",
      "connectedInterfaceName": "",
      "connectedNetworkDeviceId": "",
      "connectedNetworkDeviceIpAddress": "",
      "hostIp": "",
      "hostMac": "",
      "hostType": "",
      "pointOfAttachment": "",
      "pointOfPresence": "",
      "avgUpdateFrequency": "",
      "subType": "",
      "vlanId": "",
      "lastUpdated": "",
      "hostName": "",
      "attributeInfo": "object"
    }
  ]
}

Device fields:

 {
  "version": "",
  "response": [
	{
	"errorCode": null,
	"serialNumber": "",
	"macAddress": "",
	"family": "",
	"apManagerInterfaceIp": "",
	"bootDateTime": "",
	"collectionStatus": "",
	"interfaceCount": "",
	"lineCardCount": "",
	"lineCardId": "",
	"managementIpAddress": "",
	"memorySize": "",
	"platformId": "",
	"reachabilityFailureReason": "",
	"reachabilityStatus": "",
	"snmpContact": "",
	"snmpLocation": "",
	"tunnelUdpPort": "",
	"type": "",
	"location": "",
	"softwareVersion": "",
	"role": "",
	"roleSource": "",
	"collectionInterval": "",
	"inventoryStatusDetail": "",
	"upTime": "",
	"errorDescription": "",
	"series": "",
	"lastUpdateTime": "",
	"locationName": "",
	"tagCount": "",
	"hostname": "",
	"lastUpdated": "",
	"instanceUuid": "",
	"id": ""
	}
  ]
}

As always, if you have any questions feel free to comment.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.