cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2368
Views
10
Helpful
9
Replies

DNAC - static port assignment with python

Rajesh Kongath
Level 1
Level 1

Greetings

dnac version 2.2.2.5

we have huge site where we have to assign pools statically, obviously its a cumbersome task due to slow GUI and many pools. Hence we thought of using " /dna/intent/api/v1/business/sda/hostonboarding/user-device". Unfortunately we are ending up with an error while trying more than one port at a time. I am really a newbie in python, appreciate your support.

 

I tried to follow @Aninda Chatterjee 's code achieve the ports assignment, however that ending with another error mentioning "Device not found" - however i really like his logic, appreciate the efforts.

 

Every time when we run the code, a dnac event generated as follows " Service request processing has failed with error: This intent (with name 'edge-1.company.com') is outdated as the controller has a newer intent. Resubmit the intent based on the current state of controller.

 

my code attached below for your reference

#Import required libraries
import requests
import json
from requests.auth import HTTPBasicAuth

# GET the AUTH TOKEN
token = requests.post("https://<DNAC-IP>/dna/system/api/v1/auth/token",auth=HTTPBasicAuth(username="<username>",password="<password>”),
                headers={'content-type': 'application/json'},verify=False,)
data = token.json()
# Assign Token to a variable
token=data['Token']

ports=['4','5']
print  (ports)

for i in ports:
    payload={
    "siteNameHierarchy": "<SiteHierarchy>",
    "deviceManagementIpAddress": "<deviceIP>",
    "interfaceName": "GigabitEthernet1/0/"+i,
    "dataIpAddressPoolName": "IP_Pool",
    "authenticateTemplateName": "Closed Authentication"
    }
    print (payload)
    response =  requests.post ('https://<DNAC-IP>/dna/intent/api/v1/business/sda/hostonboarding/user-device',json=payload,headers={
                    'X-Auth-Token': '{}'.format(token),
                    'Content-type': 'application/json',
                },
                
                verify=False
            )
    print (response)

Thanks in advance. 

 

 

 

1 Accepted Solution

Accepted Solutions

Rajesh Kongath
Level 1
Level 1

Adding a delay solved the issue..

however, adding 10 second for each port for a stack with 5 members is a joke. looking for any alternative, thanks.

 

import time
 
# Within the loop
time.sleep(10)
 

View solution in original post

9 Replies 9

Rajesh Kongath
Level 1
Level 1

Adding a delay solved the issue..

however, adding 10 second for each port for a stack with 5 members is a joke. looking for any alternative, thanks.

 

import time
 
# Within the loop
time.sleep(10)
 

Honestly, the code I wrote is pretty bad and was an extremely quick and dirty way of testing something. As you've tested, a manual delay is potentially the only way for now. The reason that this issue happens is that a second port assignment is sent to DNAC before the first one is fully processed (newer intent vs older intent).

 

Typically, there would be ways to make it faster - using python threading or async code. However, as you'll quickly realize (when you try to implement async code for this use case), this API has a concurrency of 1. Which means you cannot call this API multiple times concurrently (I've added my refactored code but it will not work for the reasons above - what you can try and do is remove the threading portion of it and just add delays).

 

We've roadmapped bulk port assignment via the API but it is not implemented yet. I can check and find out when it's coming.

Thank You Aninda for the clarification. I can see improvements in the API, for example until 2.2.2.5 we were not able to apply interface description but in 2.2.2.6, interface description also working. I hope bulk port assignment will be done soon!

 

Allow me to ask a newbie API question. as we have 3 nodes in the cluster, can we improve the performance of the script by sending each post request to different node?   

Johannes_Grimm1
Level 1
Level 1

Hi Rajesh and Aninda,

 

I just came across the thread and don't know if the answer is still relevant.

 

Working with static timers is always dangerous. My approach would be to filter the TaskID from the response and query the endTime parameter for completion. If the endTime is not yet present, the check is repeated with an increased wait interval. A function could look like the following (using dnacentersdk for simplicity):

 

def intent_execution_details(taskId):
    n = 1
    status = None
    while (status == None):
        time.sleep(n)
        status = dnac.task.get_task_by_id(taskId).response.endTime
        n = n * 2
        if n > 64:
            raise Exception("Call with " + taskId + " takes too much time.")

 

 

AxelFox1982
Level 1
Level 1

Another "bump" of this topic more than a year later.
I'm facing the same issue. While my code works perfectly, it takes an eternity to provision multiple ports.
My code picks up the task ID returned in the API response and then queries the status of the task every 10 seconds.
Only when the task is complete I continue with the next port.
The problem is ... each task to provision a single port triggers a re-provision of the switch, taking over 1 minute each time. So to provision 100 ports on the same switch/stack, you're looking at about 2 hours.

There does appear to be something available (or perhaps still in development) to do it in bulk for ports that have the same parameters, since I see the following in the API documentation (on DNAC version 2.3.5.3) :
PortAssignment API.png

But I can't get it to work, so I think it's not implemented yet or the documentation is not correct.
The API call doesn't accept a JSON object with the "interfaceNames" array and without the "interfaceName" string, since the "interfaceName" string is mandatory.
When I put the first interface in "interfaceName" and additional interfaces in the "interfaceNames" array, the API call accepts the object and succeeds, but still only provisions the first interface, so the "interfaceNames" array is ignored/not used.

If you are following the documentation (which I believe you are), please open a TAC case so they can work with Engineering to figure out if this is a documentation error or supported feature.

Hi AxelFox,
Im hitting the same issue, where you ever able to get this working?

Hi Tim,

If you are referring to the "interfaceNames" array not working. No, we never got that to work, but we noticed that the API documentation on the DNAC (version 2.3.5.x) includes this parameter, but the online documentation for the same version doesn't.
The built-in DNAC documentation also links to the online documentation of version 2.3.7. So probably this is a new feature in 2.3.7 and they included the wrong documentation pages in the 2.3.5 release.

I haven't been able to retest on 2.3.7 yet, since we're not in the EFT program and still running 2.3.5(.5) currently.

Kind regards,
AxelFox.

 

Preston Chilcote
Cisco Employee
Cisco Employee

@AxelS @Tim van Lanen You'll get more attention from Engineering (and hence a faster fix) if you open a TAC Case AND submit a Make a Wish via Catalyst Center GUI.