Site Guide

Introduction

Site API allows the user to create a hierarchy on its network with area, buildings and floors, thus replicating the physical world infrastructure and grouping devices on Cisco DNA Center like they are setup in the real world.

Once the hierarchy is created and has devices assigned to it, it is possible to use the Site API to query the site health.

Goal

The goals of this guide are:

  1. Create an area
  2. Create a building
  3. Get the site count
  4. Get a list of sites
  5. Get the site's devices
  6. Get the site health

Sites workflow

Endpoints and methods used

  • POST /dna/system/api/v1/auth/token
  • POST /dna/intent/api/v1/site
  • GET /dna/intent/api/v1/site/count
  • GET /dna/intent/api/v1/site
  • GET /dna/intent/api/v1/membership/{site_id}
  • GET /dna/intent/api/v1/site-health

Prerequisites

For this guide, it is recommended that the developer is familiar with authenticating to Cisco DNA Center API.

Environment

This guide was developed using:

Authentication

First, we need to authenticate and retrieve a token from the API.

Do not use verify=False or urllib3.disable_warnings() if you are not sure of its purpose. Read Authentication and Authorization.

import requests
from requests.auth import HTTPBasicAuth
import urllib3
urllib3.disable_warnings()

BASE_URL = 'https://<IP Address>'
AUTH_URL = '/dna/system/api/v1/auth/token'
USERNAME = '<USERNAME>'
PASSWORD = '<PASSWORD>'

response = requests.post(BASE_URL + AUTH_URL, auth=HTTPBasicAuth(USERNAME, PASSWORD), verify=False)
token = response.json()['Token']
headers = {'X-Auth-Token': token, 'Content-Type': 'application/json'}

Site API

The Site API is composed of eight APIs.

Site API allows the user to create a logical hierarchy of area, building and floor, assign devices to that hierarchy, get the list of devices in a hierarchy and get the health information of the site.

Site Creation API

During this guide we will create a DNA Center Guide area and a DNA Center Guide Building under the area.

With the token, we can procede to create the area and building. We will need the siteId of the building to be used after the discovery to assign the devices to that building.

SITE_URL = '/dna/intent/api/v1/site'
site_area = {
    "type": "area",
    "site": {
        "area": {
            "name": "DNA Center Guide",
            "parentName": "Global"
        }
    }
}

site_headers = headers
site_headers['__runsync'] = 'true'
site_headers['__runsynctimeout'] = '30'
response = requests.post(BASE_URL + SITE_URL,
                         headers=site_headers, json=site_area,
                         verify=False)
area_id = response.json()['siteId']

site_building = {
    "type": "building",
    "site": {
        "building": {
            "name": "DNA Center Guide Building",
            "parentName": "Global/DNA Center Guide",
            "latitude": "37.409424",
            "longitude": "-121.928868"
        }
    }
}

response = requests.post(BASE_URL + SITE_URL,
                         headers=site_headers, json=site_building,
                         verify=False)

Site API, by default, is an asynchronous API, however like other APIs it has the option to return the response synchronously using the header __runsync. Check more information about this in the Asynchronous API guide

Get Site Count

Once we create the sites, we can proceed to query for site count using the Site API.

SITE_COUNT_URL = '/dna/intent/api/v1/site/count'
response = requests.get(BASE_URL + SITE_COUNT_URL,
                        headers=headers, verify=False)
print(response.json()['response'])

Get Site List

With the Site API we can also get a list of sites in our Cisco DNA Center.

SITE_URL = '/dna/intent/api/v1/site'
response = requests.get(BASE_URL + SITE_URL, headers=headers, verify=False)
print(response.json()['response'])

Get Site Devices

Devices can be assigned to sites using the Site API and then using the API, it is possible to query the devices that are part of a site. You can check the Discovery Guide to see an example of devices being added to a site.

In order to get a list of devices that are part of the site, you need to have the site id which you can get from the previous example.

MEMBERSHIP_SITE_URL = '/dna/intent/api/v1/membership/{site_id}'
response = requests.get(BASE_URL + MEMBERSHIP_SITE_URL.format(site_id=site_id),
                        headers=headers, verify=False)
print(response.json()['site']['response'])

Get Site Health

Finally, it is possible to get the site health using the API.

SITE_HEALTH_URL = '/dna/intent/api/v1/site-health'
response = requests.get(BASE_URL + SITE_HEALTH_URL.format(site_id=site_id),
                        headers=headers, verify=False)
print(response.json()['response'])

Code

The repository for this guide is here. The final code with functions is shown below.

# Modules import
import requests
from requests.auth import HTTPBasicAuth
import time
import sys

# Disable SSL warnings. Not needed in production environments with valid certificates
import urllib3
urllib3.disable_warnings()

# Authentication
BASE_URL = 'https://<IP Address>'
AUTH_URL = '/dna/system/api/v1/auth/token'
USERNAME = '<USERNAME>'
PASSWORD = '<PASSWORD>'

# URLs
SITE_URL = '/dna/intent/api/v1/site'
SITE_COUNT_URL = '/dna/intent/api/v1/site/count'
MEMBERSHIP_SITE_URL = '/dna/intent/api/v1/membership/{site_id}'
SITE_HEALTH_URL = '/dna/intent/api/v1/site-health'

# Get Authentication token
def get_dnac_jwt_token():
    response = requests.post(BASE_URL + AUTH_URL,
                             auth=HTTPBasicAuth(USERNAME, PASSWORD),
                             verify=False)
    token = response.json()['Token']
    return token

# Create site
def create_site(headers, site):
    headers['__runsync'] = 'true'
    headers['__runsynctimeout'] = '30'
    response = requests.post(BASE_URL + SITE_URL,
                             headers=headers, json=site,
                             verify=False)
    return response.json()

# Get list of site's devices
def get_site_devices(headers, site_id):
    response = requests.get(BASE_URL + MEMBERSHIP_SITE_URL.format(site_id=site_id),
                            headers=headers, verify=False)
    return response.json()['site']['response']

# Get list of sites
def get_sites(headers):
    response = requests.get(BASE_URL + SITE_URL,
                            headers=headers, verify=False)
    return response.json()['response']

# Get sites count
def get_site_count(headers):
    response = requests.get(BASE_URL + SITE_COUNT_URL,
                            headers=headers, verify=False)
    return response.json()['response']

# Get site's health
def get_site_health(headers, site_id):
    response = requests.get(BASE_URL + SITE_HEALTH_URL.format(site_id=site_id),
                            headers=headers, verify=False)
    return response.json()['response']



def main():
    # obtain the Cisco DNA Center Auth Token
    token = get_dnac_jwt_token()
    headers = {'X-Auth-Token': token, 'Content-Type': 'application/json'}

    site_area = {
        "type": "area",
        "site": {
            "area": {
                "name": "DNA Center Guide",
                "parentName": "Global"
            }
        }
    }

    print('Printing area ID...')
    response = create_site(headers, site_area)
    area_id = response['siteId']
    print(area_id)

    site_building = {
        "type": "building",
        "site": {
            "building": {
                "name": "DNA Center Guide Building",
                "parentName": "Global/DNA Center Guide",
                "latitude": "37.409424",
                "longitude": "-121.928868"
            }
        }
    }

    print('\nPrinting building ID...')
    response = create_site(headers, site_building)
    building_id = response['siteId']
    print(building_id)

    print('\nPrinting site count...')
    response = get_site_count(headers)
    print(response)

    print('\nPrinting sites')
    response = get_sites(headers)
    print(response)

    print('\nPrinting site\'s devices')
    site_id = response[1]['id']
    response = get_site_devices(headers, site_id)
    print(len(response))

    print('\nPrinting site\'s health')
    response = get_site_health(headers, site_id)
    site_name = response[0]['siteName']
    site_health = response[0]['healthyNetworkDevicePercentage']
    print('Name: {site_name}, Average health: {site_health}'
          .format(site_name=site_name, site_health=site_health))




if __name__ == "__main__":
    main()