What You’ll Learn

What You’ll Need

Install DNA Center SDK

Just like any API or tool, your first stop is to check out the documentation:

pip install dnacentersdk

Quick Start: Let’s Authenticate Using the SDK

By default, DNA Center SDK will look for the following environment variables to create new connection objects:

In our case, we will not use environment variables. We will add it to part of our Python code.

Let’s Get Started!

1: Clone the code repo.

In your terminal, run:

git clone https://github.com/CiscoLearning/dnac-config-manager.git

Kick-start Python in interactive mode:

python3

2: Import the DNA Center SDK.

from dnacentersdk import DNACenterAPI

3: Define the connection string.

In this case, we will create a Python dictionary with the connection string:

dnac_creds = {}
dnac_creds['url'] = 'https://sandboxdnac.cisco.com'
dnac_creds['username'] = 'devnetuser'
dnac_creds['password'] = 'Cisco123!'

4: Instantiate “Connection Object.”

dnac = DNACenterAPI(username=dnac_creds['username'], password=dnac_creds['password'], base_url=dnac_creds['url'], verify=False)

5: Display your Auth Token.

print("Auth Token: ", dnac.access_token)

6: Let’s look at the completed script.

Head over to the working directory from our cloned repo and run the Authentication.py file:

cd dnac-config-manager/
ls -al

7: Run it.

python Authentication.py

Now that we have an understanding on how the DNA Center SDK works and we’ve authenticated, let’s build our use case!

Use Case Definition

I’d like to be able to take a snapshot of all of the device config to detect configuration drift and have a golden image.

Use Case Workflow

What Is Command Runner?

Command Runner is a feature in Cisco DNA Center that allows you to execute a handful of read-only (for now) Cisco IOS commands on the devices managed by DNA Center.

Here is how you can get a list of all supported Cisco IOS commands:

commands = dnac.command_runner.get_all_keywords_of_clis_accepted()

⚠️ Cisco DNA Center API calls are asynchronous, which means that for each executed task, a task ID is created. Upon task completion, content can be retrieved from the /file endpoint.

API endpoints that we are planning on using:

SDK methods that we are planning on using:

Let’s Code It!

Code Use Case

Device Config Backup

0: Using your IDE of choice, create a new ‘.py’ file and import libraries.

Click the + sign next to the cloned folder ciscolive-devwks-2107:

from dnacentersdk import DNACenterAPI
import json
import warnings

1: Authenticate.

By now, we know how to do this. We need to pass Basic Auth and capture our API token.

Copy this step to the editor last; this needs to be at the end of the file.

if __name__ == '__main__':
    dnac_creds = {}
    dnac_creds['url'] = 'https://sandboxdnac.cisco.com'
    dnac_creds['username'] = 'devnetuser'
    dnac_creds['password'] = 'Cisco123!'

    dnac = DNACenterAPI(username=dnac_creds['username'], password=dnac_creds['password'], base_url=dnac_creds['url'],
                        verify=False)
    print("Auth Token: ", dnac.access_token)
    print("Gathering Device Info ... \n")
    get_device_list()

2: Retrieve a list of devices.

Notice anything?

"""
This function handles getting device list
"""
def get_device_list():
    devices = dnac.devices.get_device_list()
    devicesuid_list = []
    for device in devices.response:
        if device.family == 'Switches and Hubs':
            print("Managed Device IP: {} ".format(device.managementIpAddress))
            devicesuid_list.append(device.id)
    print("\n")
    cmd_run(devicesuid_list)

3: Initiate Command Runner.


"""
This function handles command runner execution
"""
def cmd_run(device_list):
    for device in device_list:
        print("Executing Command on {}".format(device))
        run_cmd = dnac.command_runner.run_read_only_commands_on_devices(commands=["show run"], deviceUuids=[device])
        print("Task started! Task ID is {}".format(run_cmd.response.taskId))
        task_info = dnac.task.get_task_by_id(run_cmd.response.taskId)
        task_progress = task_info.response.progress
        print("Task Status : {}".format(task_progress))
        while task_progress == 'CLI Runner request creation':
            task_progress = dnac.task.get_task_by_id(run_cmd.response.taskId).response.progress
        task_progress= json.loads(task_progress)
        cmd_output = dnac.file.download_a_file_by_fileid(task_progress['fileId'], dirpath='file.json', save_file=True)
        print("Saving config for device ... \n")

Run It!

Congratulations! You’ve successfully completed this tutorial!

This is a great example of configuration management. You could use this as a base to start building out a simple configuration drift monitoring tool, given that the config is returned as JSON data. We can easily use a JSON query to check for any configuration drift and automatically rebase it to the original config.

This can be taken a step further even by leveraging Git for version control of your device config.

Learn More