cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1758
Views
5
Helpful
3
Replies

DNAC API - Command Runner - Failure to obtain taskId [solved]

wieniec17
Level 1
Level 1

Hi guys,

 

I started playing with the DNAC API and the command runner but I ran into a problem where I want to run ten or more show commands inside the payload. Up to four show commands works fine, but more than that comes back with failure to obtain taskId. I am using Python for the scripting language and the DNAC is the online sandbox provided by Cisco.

I tried scripting this job based on the documentation located here: https://developer.cisco.com/docs/dna-center/#!cisco-dna-center-platform-overview. I also tried other sources and ready-made scripts which I found online and problem is the same.

Is this the limitation of the freely available DNAC sandbox, the DNAC API bug or what is it?

Any guidance in this matter will be greatly appreciated!

1 Accepted Solution

Accepted Solutions

I think I found the answer to my question.

 

I tried to:

 

print(commandrunner['response'])

 

and the message was as follows:

 

{'errorCode': 'Bad request', 'message': 'Invalid input request', 'detail': 'Maximum of 5 commands allowed per request'}

 

So, I guess it is the limitation of the API to a maximum of 5 commands allowed per request.

 

I will test this further by dividing my requests into chunks of 5 commands at a time.

View solution in original post

3 Replies 3

Tomas de Leon
Cisco Employee
Cisco Employee

When running tests using the API and you experience issues:

  • Please provide the URL & Method Used
  • Please provide the Body of the Request that is failing
  • Please provide the method of using the API  (ie. Cisco DNA Center itself, Postman, etc...)
  • Cisco DNA Center version being used
  • Device Type, Model, and software version for this request

This will help the viewing audience to assess the issue and provide feedback.

Hi Tomas,

 

Here goes:

I am using Python for this and the DNAC is the "https://sandboxdnac.cisco.com" (Version 2.2.2.3).

List of devices and their versions is in the attached image, although the WLC seems to be ignored by the command runner.

 

Script is below:

 

....Start of script:.....

 

import requests
from requests.auth import HTTPBasicAuth
import json
import csv
import pandas as pd
import getpass
import time
import urllib3
urllib3.disable_warnings()

'''
DNA Details
'''
print("Enter DNAC Credentials to login:")
DNAC_URL = "https://sandboxdnac.cisco.com"
DNAC_AUTH_URL = '/dna/system/api/v1/auth/token'
DNAC_PORT = 443
DNAC_USER = "devnetuser"
DNAC_PASSWORD = "Cisco123!"

'''
Login
'''

login = requests.post(DNAC_URL + DNAC_AUTH_URL, auth=HTTPBasicAuth(DNAC_USER, DNAC_PASSWORD), verify=False)
token = login.json()['Token']
headers = {'X-Auth-Token': token, 'Content-Type': 'application/json'}

'''
URLs
'''
DEVICES_URL = '/dna/intent/api/v1/network-device'
COMMAND_RUNNER_SEND_URL = '/dna/intent/api/v1/network-device-poller/cli/read-request'
TASK_BY_ID_URL = '/dna/intent/api/v1/task/{task_id}'
FILE_GET_BY_ID = '/dna/intent/api/v1/file/{file_id}'

'''
GETs
'''
get_devices = requests.get(DNAC_URL + DEVICES_URL, headers = headers, verify=False)
get_devices_json = get_devices.json()['response']

devices = []
for device in get_devices.json()['response']:
devices.append(device['id'])

payload = {
"commands": [
"show running-config",
"show ip arp",
"show mac address-table",
"show ip route",
"show interface",
"show ip interface",
"show inventory",
"show version",
"show cdp neighbors detail",
"show cdp neighbors",
"show lldp neighbors",
"show lldp neighbors detail"
],
"deviceUuids": devices,
"timeout": 0
}

commandrunner = requests.post(DNAC_URL + COMMAND_RUNNER_SEND_URL, data=json.dumps(payload), headers=headers, verify=False).json()

time.sleep(10)

task_id = commandrunner['response']['taskId']

get_file_id = requests.get(DNAC_URL + TASK_BY_ID_URL.format(task_id=task_id), headers=headers, verify=False)
progress_json = json.loads(get_file_id.json()['response']['progress'])
file_id = progress_json['fileId']
get_file = requests.get(DNAC_URL + FILE_GET_BY_ID.format(file_id=file_id), headers=headers, verify=False)
file_json = get_file.json()

for item in get_devices_json:
deviceid = item['id']
devicehostname = item['hostname']

for item in file_json:
device = item['deviceUuid']
commandresponse = item['commandResponses']
successfullcommands = commandresponse['SUCCESS']
show_running_config = successfullcommands['show running-config']
show_ip_arp = successfullcommands['show ip arp']
show_mac_address_table = successfullcommands['show mac address-table']
show_ip_route_vrf_xD = successfullcommands['show ip route']
show_interface = successfullcommands['show interface']
show_ip_interface = successfullcommands['show ip interface']
show_inventory = successfullcommands['show inventory']
show_version = successfullcommands['show version']
show_cdp_neighbors_detail = successfullcommands['show cdp neighbors detail']
show_cdp_neighbors = successfullcommands['show cdp neighbors']
show_lldp_neighbors = successfullcommands['show lldp neighbors']
show_lldp_neighbors_detail = successfullcommands['show lldp neighbors detail']
with open(device + "show running-config.txt", 'w') as f:
f.write(show_running_config)
with open(device + "show ip arp.txt", 'w') as f:
f.write(show_ip_arp)
with open(device + "show mac address-table.txt", 'w') as f:
f.write(show_mac_address_table)
with open(device + "show ip route xD.txt", 'w') as f:
f.write(show_ip_route_vrf_xD)
with open(device + "show interface.txt", 'w') as f:
f.write(show_interface)
with open(device + "show ip interface.txt", 'w') as f:
f.write(show_ip_interface)
with open(device + "show inventory.txt", 'w') as f:
f.write(show_inventory)
with open(device + "show version.txt", 'w') as f:
f.write(show_version)
with open(device + "show cdp neighbors detail.txt", 'w') as f:
f.write(show_cdp_neighbors_detail)
with open(device + "show cdp neighbors.txt", 'w') as f:
f.write(show_cdp_neighbors)
with open(device + "show lldp neighbors.txt", 'w') as f:
f.write(show_lldp_neighbors)
with open(device + "show lldp neighbors detail.txt", 'w') as f:
f.write(show_lldp_neighbors_detail)

When running this script, the message I am getting is :


Traceback (most recent call last):
File "C:\temp\DNA\test4.py", line 70, in <module>
task_id = commandrunner['response']['taskId']
KeyError: 'response'

 

I get the same message each time I run the script with more than four show commands inside the payload. If cut the payload down to only four show commands, everything works fine.

 

I think I found the answer to my question.

 

I tried to:

 

print(commandrunner['response'])

 

and the message was as follows:

 

{'errorCode': 'Bad request', 'message': 'Invalid input request', 'detail': 'Maximum of 5 commands allowed per request'}

 

So, I guess it is the limitation of the API to a maximum of 5 commands allowed per request.

 

I will test this further by dividing my requests into chunks of 5 commands at a time.