Network Automation along with Cisco DNA Middle SDK – Part 2

Hey look! It had been made by one to Component 2 of the System Automation with DNAC SDK! Welcome!

In Part 1 of the series we experienced establishing the SDK; importing into your python task; and making your very first call utilizing the SDK to authenticate against an example of the DevNet Sandbox;

Let’s roll-up our sleeves and dig in to the next component of using the SDK. In this installment of your blog series, we shall look at how basic it really is to leverage python to programmatically operate IOS commands during your whole infrastructure with DNAC’s order runner APIs. We shall also assume you possess installed the SDK and know how authentication works already.

What is Control Runner?

Command Runner is really a function in Cisco DNA Middle which allows you to execute a small number of read-only (for the present time) IOS instructions on the gadgets managed by DNAC

Here is how an inventory could be got by you of most supported IOS commands.

commands = dnac.control_runner.get_all_keywords_of_clis_accepted()

dnac – Our connection object we produced from Part hands down the series
order_runner – Order runner class. Contacting it shall permit us to gain access to the underlying strategies
have_all_keywords_of_clis_accepted() – This is actually the method we have been after to screen a listing of all supported keywords.

Makes sense? That people know very well what Command Runner is currently, let’s dig into utilizing the APIs to create a straightforward use case.

Command Runner stream

The use case we have been about to build is really a simple configuration backup together. In order to make this happen task we will have to:

  1. Retrieve a listing of all managed products
  2. Execute a `display run` on each gadget using Control Runner APIs
  3. Retrieve the total outcomes and save them in order to file

But before we achieve this, understanding Command Runner circulation is prudent.

command-runner-help DNAC SDK

Cisco DNA Middle API phone calls are asynchronous, this means for every executed task an activity id is established. Upon task completion articles could be retrieved from /document endpoint.

Endpoints and strategies used

  • POST /dna/program/api/v1/auth/token
  • GET /dna/intent/api/v1/network-gadget
  • POST /dna/intent/api/v1/network-device-poller/cli/read-request
  • GET /dna/intent/api/v1/task/task_id
  • GET /dna/intent/api/v1/file/file_Id

This sounds complex too, right? Not really, by using our convenient dandy SDK we’re able to handle all this very easily.

Let’s go on it step by action


– Develop a new connection item and assign it to a variable

dnac = DNACenterAPI(username=dnac_creds['username'], password=dnac_creds['password'], foundation_url=dnac_creds['url'])

Retrieve set of devices

– Utilizing the devices course to call get_gadget_list() solution to retrieve a listing of all managed gadgets.
– Upon 200 Alright loop through the set of Hubs and Switches and extract these devices id, we have to leverage it to perform the control on each gadget
– Access gadget id variable via gadget.id move it to and contact cmd_run() function

def find_device_list():
    devices = dnac.devices.have_device_list()
    devicesuid_list = []
    for device in products.response:
        if device.loved ones == 'Switches and Hubs':
    print("Device Administration IP  ".format(device.managementIpAddress))

Execute Command Runner

– Once we iterate over each gadget, we shall have to execute show run command. to take action use command_runner course and contact read run_read_just_commands_on_devices() method. This technique demands two inputs of kind list: instructions and deviceUuids
– Upon execution DNAC will come back a taskId (asynchronous, keep in mind?)
– Check its improvement via task course by calling get_job_by_id() method. After the job has been effectively executed (you may use the built-in mistake managing within the SDK to check on but that’s for another post) grab the came back fileId
– Now simply accessibility the file course and contact the download_a_document_by_fileid() technique et VOILA!

def cmd_run(device_checklist):
    for device in gadget_list:
        print("Executing Order on ".format(device))
        run_cmd = dnac.order_runner.run_study_only_commands_on_gadgets(commands=["show work"],deviceUuids=[gadget])
        print("Job started! Job ID is ".format(work_cmd.response.taskId))
        task_info = dnac.job.get_task_by_id(work_cmd.response.taskId)
        task_progress = job_info.response.progress
        print("Task Position : ".format(task_improvement))
        while task_improvement == 'CLI Runner request development':
            task_progress = dnac.job.get_task_by_id(work_cmd.response.taskId).reaction.progress
        task_improvement= json.loads(task_improvement)
        cmd_output = dnac.document.download_a_file_by_fileid(task_improvement['fileId'])
        print("Keeping config for device ... n")


That was a whole lot! Fortunately the SDK handled a whole lot of the large lifting for all of us here. It is a great exemplory case of configuration administration. You could utilize this as a bottom to start out building out a straightforward configuration drift monitoring device considering that the config will be returned as JSON information. We can easily make use of JSON query to check on for any construction drift and immediately rebase it to the initial config. This could be taken a step further by leveraging Git for version control of one’s device config even.

Check out the assets below for complete program code and notice you in a month or more with Part 3!


%d bloggers like this: