cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1425
Views
15
Helpful
17
Replies

extracting Application policy site scope selections with DNAC API

for the operational purpose we need to export hierarchy visualised in Site Scope selection of Application Policy.
I think it's only possible with DNAC API, but i'm lost with calls from Application Policy section.
Can anybody be of help on it with exact how-tos?
Thank you

1 Accepted Solution

Accepted Solutions

imho DNAC API lacks of many calls to simplify automation. in this particular case mix of available API calls with manual extractions&analiysis from DNAC hints to extremely unmature solution. no sense to update this tread with developments like mentioned above.

View solution in original post

17 Replies 17

If you can get the site scope ID associated with the Application Policy ID, then note down the id value from this GET request to retrieve the list of Application Policies , then do a GET request for GET request to retrieve the list of Site Scopes. Make a GET request to retrieve the hierarchy of the Site Scope, i think this is GET https://<DNAC_IP>/dna/controller/site-scope/<Site_Scope_ID>/hierarchy (replace with your details)

You can export the hierarchy data in various formats, such as JSON, CSV, or XML, for example, if you want to export it as a JSON file, create a new file (e.g., hierarchy.json) and paste the hierarchy data from the hierarchy of the Site Scope. You can use a tool like jq to parse and format the JSON data.

This is a nice example

curl -X GET \
  https://<DNAC_IP>/dna/controller/site-scope/<Site_Scope_ID>/hierarchy \
  -H 'Content-Type: application/json' \
  -H 'X-Auth-Token: <YOUR_AUTH_TOKEN>' \
  | jq '.[] | {name, type, id, parentId, children}' > hierarchy.json

 

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

i was thinking about this iterative approach. i took all application policies list with dnacentersdk package get_application_policy(). It's basically the primitive from DNAC API. it returns giant result which human is impossible to parse to identify needed ID:

andydoesntlikeuucp_0-1723563088218.png

could u please assist here with what i need & sequence of calls to implement?
tnx in advance

You could do this with list comprehension and a loop for example...

 

policies = dna_client.get_application_policy()

# Filter policies by name
filtered_policies = [policy for policy in policies if policy['name'] == 'app-pol-TestQos']

# Extract and print IDs
for policy in filtered_policies:
    policy_id = policy['id']
    print(f"Policy ID: {policy_id}")

 

Once you have the filtered policies, you can easily access the id attribute of each policy.

Hope this helps.

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

something wrong with indexing:

filtered_policies = [policy for policy in policies if policy['name'] == 'app-pol-TestQos']
~~~~~~^^^^^^^^
TypeError: string indices must be integers, not 'str'

any other way to address required part by field-name?

we obtain App Policy ID with this , right?


& could u pls bring more details on what calls sequence i have to leverage here "If you can get the site scope ID associated with the Application Policy ID, then note down the id value from this GET request to retrieve the list of Application Policies , then do a GET request for GET request to retrieve the list of Site Scopes." 

You need to ensure that policies are a list of dictionaries, where each dictionary represents an application policy. then, you can access the field using the dictionary syntax etc... You noted you are using the SDK, sadly i am not familiar with this enough, my example was based on the API directly to DNA-C itself, such as GET https://<DNAC_IP>/dna/controller/application-policy - you can find all API calls here https://developer.cisco.com/docs/dna-center/cisco-dna-center-2-3-7-api-overview/

Hope this helps.

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

well... following piece of code

policies = dnac.application_policy.get_application_policy()['response']
filtered_policies = [policy for policy in policies if policy.policyScope == 'app-pol-TestQoS'] #thanks to @bigevilbeard for hint to this pretty construction :0)
for entry in filtered_policies:
 print(entry)

& i've managed to obtain list of policies with target policyScope. example entry:

{'id': '0c35a5cb-708a-4387-a55e-d70fb0247749', 'instanceId': 210011835, 'instanceCreatedOn': 1723546976396, 'instanceUpdatedOn': 1723546976396, 'instanceVersion': 0, 'createTime': 1723546880805, 'deployed': False, 'isSeeded': False, 'isStale': False, 'lastUpdateTime': 1723546880805, 'name': 'app-pol-TestQoS_consumer-media', 'namespace': 'policy:application:app-pol-TestQoS', 'provisioningState': 'UNKNOWN', 'qualifier': 'application', 'resourceVersion': 0, 'targetIdList': [], 'type': 'policy', 'cfsChangeInfo': [], 'customProvisions': [], 'externalIntentSourceInfos': [], 'deletePolicyStatus': 'NONE', 'internal': False, 'isDeleted': False, 'isEnabled': True, 'isScopeStale': False, 'iseReserved': False, 'policyScope': 'app-pol-TestQoS', 'policyStatus': 'ENABLED', 'priority': 100, 'pushed': False, 'advancedPolicyScope': {'id': '71c4977e-2acd-4dd3-8de7-752e561caffd', 'instanceId': 210584385, 'instanceCreatedOn': 1723546976396, 'instanceUpdatedOn': 1723546976396, 'instanceVersion': 0, 'name': 'app-pol-TestQoS', 'advancedPolicyScopeElement': [{'id': 'a60a711b-bd78-42de-9bb3-58cdab323b0e', 'instanceId': 210585386, 'instanceCreatedOn': 1723546976396, 'instanceUpdatedOn': 1723546976396, 'instanceVersion': 0, 'groupId': ['86b740fd-672c-481b-b9ee-703f7b2c58ee'], 'ssid': [], 'displayName': '0'}], 'displayName': '0'}, 'contractList': [], 'exclusiveContract': {'id': 'e93bec0d-158a-4b7c-928e-c39a63a475ae', 'instanceId': 210586386, 'instanceCreatedOn': 1723546976396, 'instanceUpdatedOn': 1723546976396, 'instanceVersion': 0, 'clause': [{'id': '6ab483f6-cd43-4f50-a877-4d80d8be8695', 'instanceId': 209870674, 'instanceCreatedOn': 1723546976396, 'instanceUpdatedOn': 1723546976396, 'instanceVersion': 0, 'priority': 1, 'type': 'BUSINESS_RELEVANCE', 'relevanceLevel': 'BUSINESS_IRRELEVANT', 'displayName': '0'}], 'displayName': '0'}, 'identitySource': {'id': '783181a1-8167-4f99-89d1-fde67f10b6ce', 'instanceId': 210563353, 'instanceCreatedOn': 1723546292342, 'instanceUpdatedOn': 1723546292342, 'instanceVersion': 0, 'state': 'INACTIVE', 'type': 'APIC_EM', 'displayName': '210563353'}, 'producer': {'id': '4eb18c10-7963-44eb-b404-c821ed01e698', 'instanceId': 210587387, 'instanceCreatedOn': 1723546976396, 'instanceUpdatedOn': 1723546976396, 'instanceVersion': 0, 'scalableGroup': [{'idRef': '9c342a28-0af4-4c5c-805d-774ac42e189a'}], 'displayName': '0'}, 'displayName': '0'}

what's the part of it i have to use at next step? Anyone? Somebody?

Amazing...to extract the Site Scope ID associated with the Application Policy ID, you can access the 'advancedPolicyScope' attribute and then extract the id value from it. 
Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

it's this piece of data with 2 'id's. 1st or 2nd? what is the next API call to use with id-values as argument? 
{'id': '71c4977e-2acd-4dd3-8de7-752e561caffd', 'instanceId': 210584385, 'instanceCreatedOn': 1723546976396, 'instanceUpdatedOn': 1723546976396, 'instanceVersion': 0, 'name': 'app-pol-TestQoS', 'advancedPolicyScopeElement': [{'id': 'a60a711b-bd78-42de-9bb3-58cdab323b0e', 'instanceId': 210585386, 'instanceCreatedOn': 1723546976396, 'instanceUpdatedOn': 1723546976396, 'instanceVersion': 0, 'groupId': ['86b740fd-672c-481b-b9ee-703f7b2c58ee'], 'ssid': [], 'displayName': '0'}], 'displayName': '0'}

Interesting. The two id values, the first id (71c4977e-2acd-4dd3-8de7-752e561caffd) is part of the advancedPolicyScope dictionary, which suggests it's related to the policy scope. The second id (a60a711b-bd78-42de-9bb3-58cdab323b0e) is part of the advancedPolicyScopeElement dictionary, which is a child of advancedPolicyScope. So to me this suggests it's related to a specific element within the policy scope.

 

 
Based on the API documentation and the context, I would this using the first id (71c4977e-2acd-4dd3-8de7-752e561caffd) as the Site Scope ID. Use this in API call  GET https://<DNAC_IP>/dna/controller/site-scope/<Site_Scope_ID>/hierarchy, and replace the site scope.
 
Hope this helps.
Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

things stop to be pleasant... within my dnac 2.3.7.6 api i cannot find neither branch /controller nor site-scope node...

andydoesntlikeuucp_0-1723645269613.png

 

Well thats a pain. See if you can do this with /dna/intent/api/v1/network/{siteId} then export the hierarchy visualised in the Site Scope selection of the Application Policy, try and use the following API endpoint: GET /dna/intent/api/v1/network/{siteId}/site-topology

Hope this helps.

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

more & more interesting: there is no GET for this branch:

andydoesntlikeuucp_0-1723647663737.png

 

You are correct, there is no GET method for /dna/intent/api/v1/network/{siteId}. The API endpoint only supports PUT and POST methods, I just double checked the swagger file. I guess this leaves only?

		"/dna/intent/api/v1/topology/site-topology": {
			"get": {
				"operationId": "getSiteTopology",
				"tags": [
					"Topology"
				],
				"summary": "Get Site Topology",
				"description": "Returns site topology",
				"consumes": [
					"application/json"
				],
				"produces": [
					"application/json"
				],
				"parameters": [],
				"responses": {
					"200": {
						"description": "The request was successful. The result is contained in the response body.",
						"schema": {
							"$ref": "#/definitions/SiteResult"
						}
					},
					"204": {
						"description": "The request was successful, however no content was returned."
					},
					"206": {
						"description": "The GET request included a Range Header, and the server responded with the partial content matching the range."
					},
					"400": {
						"description": "The client made a request that the server could not understand (for example, the request syntax is incorrect)."
					},
					"401": {
						"description": "The client's authentication credentials included with the request are missing or invalid."
					},
					"403": {
						"description": "The server recognizes the authentication credentials, but the client is not authorized to perform this request."
					},
					"404": {
						"description": "The client made a request for a resource that does not exist."
					},
					"409": {
						"description": "The target resource is in a conflicted state (for example, an edit conflict where a resource is being edited by multiple users). Retrying the request later might succeed."
					},
					"415": {
						"description": "The client sent a request body in a format that the server does not support (for example, XML to a server that only accepts JSON)."
					},
					"500": {
						"description": "The server could not fulfill the request."
					},
					"501": {
						"description": "The server has not implemented the functionality required to fulfill the request."
					},
					"503": {
						"description": "The server is (temporarily) unavailable."
					},
					"504": {
						"description": "The server did not respond inside time restrictions and timed-out."
					}
				}
			}
		},

 

 

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

not sure i got your Q... basically we need some textual(json,csv etc) representation of entire Site tree to have an idea to which of its nodes/branches App Policy has been applied & to which it wasnt.
i feel it will be faster to expand entire Site tree (yes, there is no control to make it & u need click each & every triangle in hierarchy to display its subordinaries) & then manually update previously prepared excel sheet with topology...