DNAC API, curl and jq
I’m reviewing the DEVASC exam topics. Here I share some quick notes about curl, jq and Cisco DNA API.
Base64 and newline
Let’s start with authentication. DNAC uses basic authentication. Credentials are encoded with base64 .
The process is simple. We encode the credentials with base64 and use the encoded string to get a token. The token will be used to query the API.
The credentials must be encoded in this format:
username:password
Most Linux distributions include a base64 encoder/decoder:
echo "devnetuser:Cisco123!" | base64
ZGV2bmV0dXNlcjpDaXNjbzEyMyEK
It looks fine right? We get the same original string piping the encoded output to decode it:
echo "devnetuser:Cisco123!" | base64 | base64 --decode
devnetuser:Cisco123!
Let’s try to get the token now:
curl -s -X POST \
https://sandboxdnac.cisco.com/dna/system/api/v1/auth/token \
-H "Authorization: Basic ZGV2bmV0dXNlcjpDaXNjbzEyMyEK"
{"error":"Authentication has failed. Please provide valid credentials."}
Authentication has failed.
The problem is we used echo to encode the credentials but echo silently adds a newline at the end of the string.
Let’s check the echo man page and try again using the -n flag that prevents echo from adding the newline:
echo -n "devnetuser:Cisco123!" | base64
ZGV2bmV0dXNlcjpDaXNjbzEyMyE=
Notice the encoded string is different now. If we try the encode/decode pipe again the newline will not be printed:
echo -n "devnetuser:Cisco123!" | base64 | base64 --decode
devnetuser:Cisco123!
Now we can try again to get the token, now using the correct credentials:
curl -s -X POST \
https://sandboxdnac.cisco.com/dna/system/api/v1/auth/token \
-H "Authorization: Basic ZGV2bmV0dXNlcjpDaXNjbzEyMyE="
Success! Now we got the token.
A final note for this section: we can use variables to avoid the long curl strings. This is the command to assign to a variable named auth the value of the encoded credentials:
auth=$(echo -n "devnetuser:Cisco123!" | base64)
Here’s the same curl with the variable:
curl -s -X POST \
https://sandboxdnac.cisco.com/dna/system/api/v1/auth/token \
-H "Authorization: Basic $auth"
We can do the same for the url:
tokenurl="https://sandboxdnac.cisco.com/dna/system/api/v1/auth/token"
curl -s -X POST \
$tokenurl \
-H "Authorization: Basic $auth"
Introducing jq
Curl output is not always easy to read when working with API. Piping to jq can improve the experience.
curl -s -X POST \
https://sandboxdnac.cisco.com/dna/system/api/v1/auth/token \
-H "Authorization: Basic $auth" \
| jq
{
"Token": "eyJ0eXAiOiJKV1jZDQ3ZTAwNGM2N2RkMGUiLCJhdXRoU291c"
}
We can use jq to extract the token from the output of curl and assign it to a variable:
token=$(curl -s -X POST https://sandboxdnac.cisco.com/dna/system/api/v1/auth/token -H "Authorization: Basic $auth" | jq -r ".Token")
Let’s see the token
echo $token
Get network devices
Cisco DNAC API can be used to get the list of the network devices:
curl -s -X GET \
https://sandboxdnac.cisco.com/dna/intent/api/v1/network-device \
-H "X-Auth-Token: $token" | jq
The output is long and maybe we’re not interested in all of it, jq can help to filer only some values:
curl -s -X GET https://sandboxdnac.cisco.com/dna/intent/api/v1/network-device \
-H "X-Auth-Token: $token" \
| jq ".response | .[] | {hostname:.hostname, platform:.platformId, serial:.serialNumber, ip:.managementIpAddress}"
{
"hostname": "cat_9k_1",
"platform": "C9300-24UX",
"serial": "FCW2136L0AK",
"ip": "10.10.22.66"
}
{
"hostname": "cat_9k_2",
"platform": "C9300-24UX",
"serial": "FCW2140L039",
"ip": "10.10.22.70"
}
Wrap up
That’s all folks! Hope you enjoyed the post and will use is to start learning more about API.