What you'll learn
- Reserve the Cisco Catalyst Center DevNet sandbox and connect to it over VPN using the OpenConnect client
- Explain the difference between the northbound intent API and the southbound API in Cisco Catalyst Center
- Request an authentication token from the Catalyst Center REST API with Python before calling other endpoints
- Retrieve site data from Catalyst Center by turning API documentation examples into a complete Python request
- Create sites in the Catalyst Center network hierarchy and confirm them through the API
- Use the command runner API to run show commands on managed Catalyst 9000 switches from the controller
Free 57-minute video lesson with a full transcript and knowledge checks. No account needed to watch.
Getting Sandbox Access
In this video we discuss how to get access to the reservable Cisco Catalyst Center sandbox. We first download the openconnect VPN client, reserve the sandbox and connect to the private network to access the Catalyst Center controller.
Knowledge Check
What is required to access the reservable Cisco Catalyst Center DevNet Sandbox?
Getting an Authentication Token
In this video we learn how to retrieve an authentication token via the REST API. This token is very important as it will allow us to make all of the subsequent requests to the controller's API.
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
authentication_url = "https://10.10.20.85/dna/system/api/v1/auth/token"
username = 'administrator'
password = 'Cisco1234!'
authentication_request = requests.post(url=authentication_url, auth=(username, password), verify=False).json()
print(authentication_request["Token"])Knowledge Check
What is the purpose of the northbound API in the Cisco Catalyst Center?
Getting Site Data
In this video we use the Catalyst Center web interface to manually create two "sites". With these sites now created within the controller, we can use Python to retrieve site information via the REST API.
import requests
import urllib3
from rich import print
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
authentication_url = "https://10.10.20.85/dna/system/api/v1/auth/token"
site_url = "https://10.10.20.85/dna/intent/api/v1/site"
username = 'administrator'
password = 'Cisco1234!'
authentication_request = requests.post(url=authentication_url, auth=(username, password), verify=False).json()
my_token = authentication_request["Token"]
headers = {
"x-auth-token": my_token,
"Accept": "application/json"
}
site_request = requests.get(url=site_url, headers=headers, verify=False).json()
print(site_request["response"])Knowledge Check
What is the purpose of the 'x-auth-token' in the API request headers when retrieving site information from the Cisco Catalyst Center?
Creating New Sites
Previously we created two new sites on the controller using the Catalyst Center web interface. In this video learn how to perform the task using Python and the REST API. Check it out!
import requests
import urllib3
from rich import print
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
authentication_url = "https://10.10.20.85/dna/system/api/v1/auth/token"
site_url = "https://10.10.20.85/dna/intent/api/v1/site"
username = 'administrator'
password = 'Cisco1234!'
authentication_request = requests.post(url=authentication_url, auth=(username, password), verify=False).json()
my_token = authentication_request["Token"]
headers = {
"x-auth-token": my_token,
"Accept": "application/json",
"Content-Type": "application/json",
}
payload = {
"type": "area",
"site": {
"area": {
"name": "Germany",
"parentName": "Global"
}
}
}
site_request = requests.post(url=site_url, headers=headers, json=payload, verify=False)
print(site_request.text)Knowledge Check
What type of HTTP request is used to programmatically add a new site via the REST API in Cisco Catalyst Center?
Running Show Commands
Now that we know how to retrieve information programmatically using the REST API, let's turn our attention to using the Catalyst Center's "Command Runner". This feature allows us to instruct the controllers to run CLI "show commands" against our managed devices. Let's see how it works!
import requests
import urllib3
from rich import print
import json
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
base_url = "https://10.10.20.85"
authentication_url = base_url + "/dna/system/api/v1/auth/token"
devices_url = base_url + "/dna/intent/api/v1/network-device"
command_runner_url = base_url + "/dna/intent/api/v1/network-device-poller/cli/read-request"
task_url = base_url + "/dna/intent/api/v1/task/"
file_url = base_url + "/dna/intent/api/v1/file/"
username = "administrator"
password = "Cisco1234!"
authentication_request = requests.post(url=authentication_url, auth=(username, password), verify=False).json()
my_token = authentication_request["Token"]
headers = {
"x-auth-token": my_token,
"Accept": "application/json",
"Content-Type": "application/json"
}
devices_response = requests.get(url=devices_url, headers=headers, verify=False).json()
devices_list = devices_response["response"]
device_ids = []
for device in devices_list:
device_ids.append(device["id"])
payload = {
"commands": ["show ip interface brief", "show run"],
"deviceUuids": device_ids
}
cli_response = requests.post(url=command_runner_url, headers=headers, json=payload, verify=False).json()
task_id = cli_response["response"]["taskId"]
task_request = requests.get(url=task_url + task_id, headers=headers, verify=False).json()
progress_string = task_request["response"]["progress"]
progress_dict = json.loads(progress_string)
file_id = progress_dict["fileId"]
file_request = requests.get(url=file_url + file_id, headers=headers, verify=False).json()
for output in file_request:
command_success = output["commandResponses"]["SUCCESS"]
for command in command_success:
print("\n")
print(command_success[command])Knowledge Check
What is the primary purpose of the 'command runner' feature in Cisco Catalyst Center?
Validation
Let's now validate what we've learned in this skill!
Instructions:
Launch the lab below. Go to the Cisco Devnet Sandbox and reserve the Catalyst Center sandbox. Use openconnect to connect to the sandbox using the credentials that will have been emailed to you upon making the reservation. Note: the "sudo" password for the Linux mint VM in the lab is "Cisco!23".
Once you have connected to the sandbox, write a Python script that uses the requests library and send an HTTPS request to the Catalyst Center controller which will return Overall Client Health information. Consult the Catalyst Center API documentation to determine the relevant endpoint information.
Check out the video solution below!
Knowledge Check
How much experience do you have using the Catalyst Center REST API?
This interactive assessment is available in the full learning experience.
View Transcript
Getting Sandbox Access
0:00Alright friends, so in this particular video, what we're going to be doing is going to the DevNet Sandbox. And what we're going to do is reserve the Cisco Catalyst Center Sandbox. And quite simply, this is going to give us access to Cisco Catalyst Center, and we'll begin testing it, the API, and seeing how we can actually interact with it. Sound good? Well, let's go and do it then. So if I go to my browser over here. So if you search for Cisco DevNet Sandbox, you will come to this link right here. You're going to have to log in, and once you do, you can choose to launch the sandbox.
0:33And all you're going to do is search for Catalyst Center. So in my case here, we can see it's right here, okay? So say for example, if I happen to just go here and choose launch, what it's going to do, it's going to tell me the amount of time, or offer me the amount of time that I want to be using this reservable sandbox. So if, say for example, you want it for one day or for maybe two days, whatever it may be, you just specify the time, then you review, and then finally you can go and launch your environment. Now in my case, what I've already done before I began recording is, I happen to do this beforehand effectively.
1:06The reason being is because this sandbox, it takes about an hour to get actually operational, okay? So it takes a little bit of time. So in my case, what I have done is if I go here, we're now going to see here that everything is in the upstate and on. And effectively, I now have access to this environment. Now one thing we're going to have to do in order to be able to reach this environment, you might notice that we have a lot of private IP address in here. See this here, 10.10.2025, 10.10.2020, so on and so forth. That is because in order to be able to access this, we need to have a VPN connection into the sandbox itself, because it is not the always-on public sandbox.
1:44This is the private reservable one. So in this case, we're going to have to have two things in play. We're going to have to have our login details to connect to the VPN, and we're going to have to have the VPN software. So in my case here, and all I'm going to do here is say sudo apt install, and I'm going to install something called Open Connect. This is going to be my VPN client. So in my case here, I have already installed this. You're not going to see anything be installed. But if at home you want to install it, that would be the command that you would issue. So with that now installed, what I would then do is go to my emails.
2:16This would be my DevNet account. And inside of here, once the lab is set up, you're going to see you have all of these connection details. So in my case here, I can see my lab address is right here. I have a username of ipv0. And below, I've got this blurred out a little bit. But below, we can see the actual password that I need. This is for the VPN connection, okay? So just the VPN connection. So if I just say, for example, copy the lab address right here, and what I'm going to do here is I'm going to say sudo Open Connect to use the VPN software, and I'm going to go and paste in the lab URL like so.
2:48So if I hit Enter, it's going to begin creating the connection. And then down here, I'm going to have to type in that username. So mine is ipv0. And if I hit Enter, and now what I'm going to do is to copy my password here. And then all I do is just paste it. And you're not going to see the password appear because it's a password. It's not meant to be seen, but I've pasted it. And if I hit Enter, we're going to begin building that connection. And now we can see here we have an established connection. See this right here, established connection, no problem at all. So whilst leaving this open, I'm going to open up another terminal window.
3:19So in my case here, I'll just go here. And that will leave the connection active. And effectively, I should be able to ping those devices. So if I go back to my environment, if I go to instructions, we're going to see here all the connection information. So for example, to connect to the actual controller, the IP address is 10.10.20.85. Login is administrator. And the password is cisco1234 with an exclamation mark. So what that means is with the VPN connected, I should be able to ping this address. So let's just go here, copy here. And I'll just ping this and paste it in.
3:50Enter, we can see here we're now able to connect to that device. Now, if I go to the browser within my virtual machine and I type in the IP address, so 10.10.20.85, and to enter, we're going to see here we actually get a connection to the Catalyst Center. So if I say login, type in the username of administrator. In fact, just let me zoom in a little touch here. And the password will be cisco1234, exclamation mark. Let me just show this password so you can see if I now login, nothing is going to happen because I have misspelled administrator. I've said administrator, which is not correct. Let's try that again and hit enter.
4:22Give it a moment. Alrighty, oh, so now we can see here we have access to the Cisco Catalyst Center DevNet Sandbox. With this now in play, what we want to be able to do is to not just access it via the graphical user interface, we want to access it programmatically using its REST API.
Getting an Authentication Token
0:00All right friends, we now have access to the Cisco Catalyst Center controller. What we now want to do is to begin talking to it using the Python programming language, i.e. using its REST API. So in order to be able to do this, the first thing we're going to have to do is to look at the documentation. So let's go and see what that looks like there, okay? All right, so if you search for the Cisco Catalyst Center API documentation, we're going to see we have this link right here. So let's go and click on this. Now straight away you're going to notice something that this here, Catalyst Center, it used to be known as Cisco's DNA Center. And in fact, when we happen to make requests to particular URIs, you're going to notice we see DNA quite a lot. That is because that is the old name of the product and it still is relevant within the actual API calls. So with that said, let's go and do it then. Now just before we go on any further, you're going to notice this thing right here. We have this intent API, otherwise known as the northbound API. In essence, when we're talking about a northbound API, this just refers to the fact that we're actually talking to the controller itself. Whereas if you hear the term southbound API, that is when the controller talks to the actual networking devices that it's managing.
1:13But in our case here, we have some Python, we want to talk to the controller, it's referred to as northbound, which is the intent API. Now another thing to note here, very, very important, it says Catalyst Center platform REST methods require authentication. What this means is we're going to have to acquire a security token and then it's by using the security token and other requests, we are actually authenticated to make those requests. Now again, that might sound a little bit confusing. We'll definitely see it in action and it should become a little bit clearer. Now again, here it gives you a little bit of an overview of the network domain within the controller itself. We have a concept known as sites. So within here, we can create and manage sites, we can assign particular devices to sites, so that could be wireless access points, that could be switches, we can obtain site information, we can get a count of the site and see site membership, as well as the hierarchy of other sites. That means sites within sites, that type of thing, okay. Similarly, we can also get topology information, so that would relate to network health, as well as network physical, layer two, layer three and VLAN information. If we want to retrieve information such as timestamps, MAC addresses, UUIDs, capabilities, interfaces, that type of thing, we would look at our devices section and we can also have options for getting information
2:30on clients, on users, as well as issues. Now for now, what I want to do is I want to first look at this token thing, okay. See this right here? The authentication token. Let's find out how to get that, okay. So what I'm going to do here is on the left hand side, if I go to the API reference here, what I'm now going to do is to choose next to take me into this. Now check this out, let me just move this outside. So down the left hand side, we're going to see all of these options we were talking about before for sites, topology, devices, clients, users, issues. In my case though, the first thing that I want to do is to go to this option right here, authentication API. See this right here?
3:02This here is going to be the end point that I target with a POST request to actually return my token. So check this out, let me just copy this here, okay. And let me just go into my virtual environment and just activate it. And what I'll do is I'll create a new directory, let's just call this maybe catalyst stuff. Alrighty, oh so let me go and create a little file, let's just call this one example1. Alright, so in order to be able to make an HTTP request over Python, I'm going to be importing the requests library. Alright, so what I'm going to do here is I'm going to create a little variable and I'll just call this maybe authentication URL. So at this point here, what I'm going to do is say HTTPS colon forward slash forward slash and now I want to specify the IP address of the actual controller itself. Now remember, the controller here has an IP address of 10.10.20.85, that's for the actual controller, okay. This is what we're talking to, the northbound API. So I'll say 10.10.20.85.
3:56And now at this point here, what I want to do is I want to go and tack on the information that we just saw. So see this point right here? Let's just copy this and add this on. So let's just grab you and I'll just paste this in like so and let me get rid of the double forward slash. Now what I want to do is I want to specify what my username and password is in order to be able to create this login. So I'll just say username is equal to. Now how do I log into Catalyst Center? Well remember, if you recall, it says here the credentials are administrator. And by the way, I should just be clear here that you might be watching this in the future. These IP addresses, these credentials might change, so make sure that you check it with your own environment, okay. So I'll say the username is equal to administrator and I will say the password is equal to cisco1234 exclamation mark.
4:43That's how I log into Catalyst Center. Now what I want to do is I want to create a request. So I'll just say authentication request and I'll make that equal to and what I want to do is I want to use the request library. I'm going to use a post request. Now why is it a post request? Well that's because as we see here, it tells us it has to be a post request. And what I'm going to do here is I'm going to say the url is equal to the authentication url I just defined above and what I'm going to do here is I'm going to say auth is equal to and I'm going to pass in a tuple. So I'm going to have my parentheses and I will just say username which is the username variable right here and then I'll have a comma and then specify the password as well that I'm passing in. Then I'm going to have a comma after that and I will say verify is equal to false because I don't care about self-signed certificates.
5:27And at this point here, if I just zoom out a little bit, this here is my basic request. So what I'm going to do here is I'm going to just go and print out the authentication request. So if I just save this like so and if I just go back here and I say python3 example1.py and to enter as we can see here straight away we get a warning because we have an insecure request but we also get that 200 response. So what I could do is I could say show me the text and then also to suppress the actual warnings what I can do is I can import urllib3 and at the top I'll just say urllib3 and I'll just say disable warnings and I'm just going to disable the insecure request warning okay. Now again this has nothing to do with Cisco DNA Center it's just to make the output a little bit prettier so let's just save this and run it again. So now check this out right here we're actually getting back the response we see here we have this token key and this here all of this this happens to be my token.
6:18Now what I want to do is I actually want to be able to save this token so I'm going to have to parse out the output here but right now as it stands this is just string like data it's not actually a Python dictionary so in order to be able to convert that what I'm therefore going to do is I'm going to say when I get my authentication request back what I want to do is use the JSON method to put it into a Python dictionary. So now if I delete the actual text right here and just run it again what we're now getting back might look the same but it's now actually a Python dictionary so I can actually go and parse out this particular key. So I can just say print out the token key and if I run it again now here we're just getting that authentication token so what we now want to do is you want to be able to save this information into a variable whereby we can use it for our future requests. So let's do that in the very next video and we'll continue on making more REST API calls.
Getting Site Data
0:00Alright friends, now that we have our token, we can now use it to begin getting information about our topology, our devices, our sites, that type of thing. So let's go and build on this information. Alright, alright, so let's maybe say that the very first thing that we want to do is to get information about the sites that we have within our Catalyst Center. Now, because I have the reservable sandbox, this is not pre-populated with a whole bunch of information. So if I just try to get the site information as it is right now, it's not going to be available because it's going to be empty, there's no sites configured.
0:32Now, at this stage here, what I could do is I could go ahead and I could use the actual API itself to go and programmatically create a site. But honestly, I don't want to do that because that's a little bit more involved, or at least I don't want to do that right now. We will do it, but not right now. So in order just to get some basic sites up and running so we can get some responses back, let's go into the actual web GUI interface and begin just configuring them there, okay? So let's go back into our virtual machine browser. Okay, so let's just log back into Catalyst Center on here.
1:05Alright, so we log back in. So if I go up to the top left here, and I go to design, we're going to see we have this option for a network hierarchy. If we just click on this link right here, what we're going to see here is no sites found. See that right there? This means that if we happen to retrieve our sites, it's going to be an empty object. So just to get things up and running, let's just do it quite simply by clicking here to add the site. So I'll add an area and we'll just call this area. Let's just call it Scotland, okay, since that's where I'm from and I'll just add this like so.
1:36And let's also maybe add another site just to have a little bit more information. We'll add another area. Let's just call this one England, which is our nice little neighbors down south. And if I just add this, all right, all we're going to see here down the left hand side, we now have England and Scotland and they are both in the global region, so to speak. Now at this stage here, we're going to have some data to actually retrieve. Let's go and see how we can actually get that site information via the REST API. So once again, we go back to the documentation. Now we're looking for sites. So probably good idea to click this one right here.
2:07So let's just click this like so. Now check this out. This actually expands and we can see all of these different options. Okay, so if you want to maybe get site energy, for example, you can choose this one right here. It's going to tell you the actual endpoint you're going to have to use and any type of information you might want to supply. Similarly, perhaps you want to, oh, I don't know, maybe you want to delete a site, you would click on this here. It would tell you to send a delete request to this particular endpoint and specify the site ID. Now in our case, as opposed to deleting a particular site, if we just go and choose to get a site and click this here, tells us this would be the endpoint we would actually use. Now notice, by the way, here's the thing, see on the left-hand side, or rather left-hand side, see on the right-hand side, definitely right-hand side, we actually have an example of being able to specify a cURL request, which is just a command line utility to make these HTTP calls.
2:57This is how we would actually make that request via the command line to get that information using cURL, and also if we just choose the Python tab, we get some example little code right here. So see this right here, this would be a rough example of what we would do. Now just to be clear here, in our case, if we just copy this blindly and we just went over to our little command line here, and I created, let's say, example two right here, and I go in here and just paste this in and just save this, whilst this is a good template, it's actually quite incomplete. For example, it doesn't give us a full URL. See this right here?
3:29This just gives us the actual endpoint. This is not actually specifying the actual server we're trying to connect to, the 10.10.20.85 server, and we're also going to have no authentication. We've not actually requested our token. So if you just try to run this, like so, and to enter, we're going to see here, we're going to get an error. So this is not going to make sense, but it does give us a rough idea of the types of things we might want to be doing. For example, sending a GET request to this particular endpoint. So all we'll do is we'll go and make a modification. So what I will do here is, let's just perhaps copy all the stuff in example one, and we'll go into example two, and let's just delete this for the moment, and paste in example one stuff. Now at this stage here, remember, this allowed us to get back our token. See, by parsing out this particular key here?
4:12So what I'm going to do is, as opposed to printing this out, I'm going to just delete this stuff here, and I'm just going to say my underscore token is equal to this right here. So pretty much we send off the POST request to the authentication URL, we grab the token key, and whatever is returned, we put into this variable. We can now reuse this for other requests. So at this point here, what I'm now going to do is I'm going to create a dictionary called headers, and this here is quite important. Try to remember this. What I'm going to do here is say x-off-token, and corresponding to that is going to be the my token variable, okay?
4:48So I'll say colon, and then I'll say my underscore token, then I'll have a comma. Now as we saw in the example, we can have an except header, and we can give the value of application forward slash json. Now at this stage here, what I'm going to do is do similar to what we did before. I'm going to say site underscore request, and I'm going to take the request library. I'll use the GET request, and in fact, before I go any further, what I'm going to do is I'm going to go and create a site URL. So I'll say site URL is equal to, and for now, let's just copy this right here. So the IP address of the actual server, and then pretty much what we actually saw in the documentation here. See this right here?
5:24This is the part we want to tack on at the end. So we can just copy this like so, and just paste this in. So now we have the site URL, and at this stage here, what I'm going to do is say the URL is equal to the site URL. I'm going to say the headers are equal to the headers I've just defined above, which means I'm going to be passing in my token as an x-off-token with this request to authenticate what I'm trying to do. And then again, I'm going to say verify is equal to false. And once again, just to get the output as a dictionary, I'm going to grab the JSON method to transform that, okay?
5:55Then what I'll do is I'll just print out the site request. Now again, just to make things a little bit prettier, what I like to use is the rich library. So I'll just say from rich import print. So that means we'll print things in a prettier way. So just to recap, what we do is we send the first request, the POST request, off to the authentication URL. That returns the token. We grab it via this particular key, put it into this variable. We then make a second request, which is a GET request to a different URL. This is going to be the site URL right here. And this time we're passing in the token via the headers, which allows us to authenticate and make this GET request.
6:29And all we just do is print out the response. So let's go back here and see if we get a little bit better luck this time, okay? So back up and I'll say python3 example2.py and to enter. Open appears. We happen to have an issue. That is because I have a mistake. I don't know why I'm saying site request. That should actually be site URL. So apologies about that mistake. Just save you, try it again, arrow up and to enter. So we can see here in the response, we have the site hierarchy of global. And below this we have our England site and then indented within we have some other information related to England.
7:04And scrolling on down, we're also going to see the Scotland site, which is also a part of the global hierarchy as we can see right here. So again, if we want to parse out this information, looking at the output, we can see we have this response key. So if I just go in here and I say print out the response here and I run it again, hit enter. Now we're going to get back this list object so we can access each element via its index position. So if I say response and say index position zero, that gets the first element in the list. So arrow up, run it again.
7:35So now we're just seeing the global hierarchy right here. If I go back up, change this to index position one, we should expect to see England. So let's run it again. Here is all the information relating to England, like so. And if I arrow up again, use position two, we should see the next element in the list, which is going to be Scotland. And as we can see right here, this is the response for Scotland. And if I try to do index position three, we're not going to have any more indexes. So we're actually going to get an error, which you can see right there. So the list is now out of range. So in effect, what we can see here is, is by first getting our token via the authentication URL, saving that token and putting it into the XAuth token header, we can now begin making requests to other endpoints within the API documentation. In our case here, we specified the site URL and then we're able to manipulate that data in a programmatic manner.
Creating New Sites
0:00Alright friends, now previously what we just did was we sent a GET request to retrieve information about the sites within our controller. In order to be able to do this, we manually created these sites within the web GUI interface. Now in this case here, what we're now going to do is to see how we can programmatically add on these sites via the REST API. So how are we going to do this? You guessed it, we're going to go to the API documentation. So let's go and check this out. Alright, so let's go back to the documentation. And before we sent a GET request, this time though we want to create a site.
0:33So if I click this, we're going to see here, this is the endpoint we target, this time with a POST request. And we're also going to have to supply some type of payload which specifies what it is we want to be creating. So if we go down here, we can see in the request body, we can see the schema definition. So in this case here, we're going to have to specify the type of thing that we want to create. Is that going to be an area? Is it going to be a building or a floor? And we're also going to have another key called a site key. And if we expand this right here, we're going to see we can specify if we are creating an area.
1:05Let's expand this, we can see we can give a name of the actual area as well as the parent name, which would be in our case here, the global hierarchical name. So the main things to note here is we can see the type of information we have to supply as a payload. And we can see we have to send a POST request to this particular endpoint. So let's go and build this information out then. So what we'll do here is once again, if I just copy over example two, and let's create example three, and we'll go and open this up. All right, so inside here, what I'm going to do is really quite similar to what we saw before.
1:38What we're going to do is send a request to get our authentication token, which is what we do right here. We save this. And one thing we're going to note here is that the site URL is actually going to be the same. It's going to be the IP address and then DNA intent APIs v1 site. Again, we can just confirm this by saying DNA intent API v1 site. Main big difference though is that this time here, when we send that request to the site URL, it's going to be a POST request. And we're also going to have to specify a body along with that, okay?
2:09Now also, by the way, given the fact we are going to be sending data, in my headers, I'm also going to add the content type header. So I'll say content-type. And the content type here is simply going to be, as we see above, application forward slash JSON. So let's just modify this. And what we're also going to do is to create our little payload. So I'll say the payload is equal to. Now again, we just follow the information that we saw before. If we go back into the documentation, going down here, we can see the first key is going to be the type key. So let's represent that. We'll just say type.
2:40And the corresponding values, what can we have? It can be an area, a building, or a floor. And also, by the way, if you remember, that actually corresponds to what we saw. Remember, when we tried to add a site, we chose to add an area. And the area happened to be England and Scotland. Let's go and create one now for, let's maybe say, Germany, okay? So we'll say type here is going to be of type area. We'll have a comma. We'll then specify our next key, which is going to be site. Again, where am I getting that? Which we can see right here, site object. If I expand this, we're going to be specifying an area. So again, let's expand. We're going to have name and parent name.
3:12So once again, just copying out all the information, the site. And let's just open up a little dictionary. That's going to be of type area. And again, inside of here, we're going to have the name key. And this will be the name of the actual area we're going to be creating. So let's just say this one is going to be called Germany. And let's have a comma and the parent name. But as we saw before, this is just going to be the global hierarchy. Now, at this stage here, if I go down, what I'm going to do is add in a few options right here. I'm also going to say JSON is equal to the payload that I've just defined. In essence, what that's going to do, it's going to take this Python dictionary that we're supplying and translate it into the correct JSON form.
3:48Because after all, the content type we're going to be sending is application forward slash JSON, as we can see right here. Okay, so all I'm going to do here is just remove the JSON object right here. And all I will do here is just print out the text response. I'll say .text. And this should allow us to create a new site programmatically just using the API. Okay, so let's just save this. All right, so let's try to run this by saying python3 example3.py and to enter. And as we can see here, we get the response saying the request has been accepted for execution.
4:18So to verify this, I could just go directly to the web GUI interface and we should see a new site. However, if I go in to example2.py, if we just send off that get request to get all of our sites, as we can see right here, and we just print out the response, we should see Germany also within the output now. So if I just go back. So if I now run example2.py and to enter, now we get back a response. We can see here at the bottom we have Scotland. If I scroll up a little bit further, we can see we actually also have Germany.
4:49And a little bit further up, we can see we have England. So very, very clearly, we now can see we have Germany in the output. And we can also verify this by just going back to the hierarchy here. And if I just refresh this, give it a moment. Indeed, we can see here we now have this German site employee.
Running Show Commands
0:00Alright friends, so previously we have seen how we can get a token from our Catalyst Center API and then once we have that token we can use it to send requests to particular endpoints to perform particular tasks. So previously we could effectively get information on sites, we could create sites and if we so wished we could choose other endpoints to do similar things. Now as opposed to just demonstrating more and more and more of these endpoints, what I want to do is to show you a very unique feature or maybe a not unique feature but a very very useful feature, one known as the command runner. Now effectively what this is going to allow us to do, it's going to allow us to interact with the REST API and tell the controller to run regular show commands on the devices that are actually under our management. So the first thing to state here is that if we happen to log into the Catalyst Center web GUI interface and we scroll on down to the network snapshot, we're going to see here we have three sites, no surprises there, that's England, Scotland and Germany but we also can see here by default we have four networking devices and if we scroll down a little bit further to the licensed devices we can actually see here that these four devices are indeed Cisco switches. So if we click this right here what we're going to see here, in essence we have four of these Catalyst 9000 series virtual switches. So we want to send show commands to these particular devices,
1:20you know things like show run, show version, show IP interface brief, that type of thing but we want to do it directly from the controller. So let's go and see how we can actually make this happen then. All right so what I want to do is down the left hand side let me just collapse sites and the thing that I want to go to here is this option command runner. Now if I look at this option here, post request, we can run read-only commands on devices to get the real-time configuration. This is the one we want so if I just click on this one here and let's just minimize this, look at the actual post request right here it is dna intent api v1 network device polar cli read request. This is the one we want to remember if we want to be using the command runner and send commands and we're going to send a post request to this particular endpoint. Now again looking at the schema definition what we're going to have to do is supply some information that is going to be the commands that we want to be sending and in our case we also want to supply the device UUIDs. This is going to be the unique identifier for each of the switches that we want to run the command against. So let's go and begin building out our little script and see how we can actually do this then. So let's go back to our terminal and what I will do is I'll create an example called example4.py and let's go and open this one up. All right now what I'm going to do here is write this one from scratch because there's
2:37going to be a few things that are a little bit different okay. So check this out at the very top what I'm going to do is import the request library, no surprises there. What we'll also do is import the urllib3 library and to make things more readable what I'll do is I'll say from rich import prints. Now for the moment that will get us up and running but we will have to also include more things later on but we'll build on that. So let's just go and disable the warnings. Now what I'm going to do here is to create a base URL. Pretty much this is going to be the consistent part of the URL that is not going to change. The reason being why I'm doing this will become a little bit clearer when we get a little bit further down the script. But let's just say for now this is what I want to do is just specify the IP address of the device itself and anytime I want to make a particular request to a particular endpoint I can just append to this base URL okay.
3:23So let's just create a variable called authorization URL and again it's going to be the same type of one we saw before. Let's just put in that endpoint and for the moment let me just go and specify the username which as we know is going to be administrator. Specify the password which as we know is cisco1234 exclamation mark and the first thing I'm going to do is to go and get that token again. So what I will do for quickness I'll just copy in the rough logic, grab you and let's just paste this in. Now in order for the authentication URL to actually make sense what I'm going to do is to take the starting part the base URL and add it onto that okay. So I'll just say base URL plus this endpoint so it's basically going to concatenate this part here and then tack on this at the end.
4:03So now we have the token right here and similar to what we saw before let's go and create our headers now with that token inside of it okay. So again there we go right there that's our headers now at this point here what I want to do is I want to go and get the list of all my devices the four switches under my control and in essence the reason for that is because if you remember from the command runner what we're going to have to do is to get each device ID so in order to get the device ID we have to get all of our devices first. So let me just go and check out devices right here so what I want to do here is I want to choose this option get device list we can see this is the endpoint that we need so what I'm going to do is copy this and note this is going to be a get request so inside here what I'm going to do is I'm going to create a new URL let's just call this devices URL and it's going to be equal to the base URL plus whatever this is right here so now what we want to do is to send off that request so let's go and just maybe create a little variable called devices response and all we'll do is use the request library with a get request and I'm going to say the URL is equal to the devices URL for this one for the authentication I will say headers are equal to the headers I have defined above which has the token inside and in fact you know what let's also add in our accept header and what I'll also say is verify
5:22is equal to false and what I want to do is I want to get this response back as a Python dictionary so let's use the JSON method and for the moment let's just try to print out the device response so let's see how successful this is at the moment so if we save this and let's go here we'll say Python 3 example 4.py oh appears we happen to have an issue with the syntax that's because I am missing a comma here so let's try that again save here arrow up hit enter and check this out right here now we're actually getting back the response if we scroll all the way up what we can actually see here is we have this response key and inside of it we have a list object so what I could do is create a little list called devices list and it can just be based on the device response and what we do is get that response key to return just a list object so what I now should be able to do is to look through each of these devices okay so if I just say print device if I look through and print all devices like so and let's just run the script again all righty also here is one switch scrolling up here's the next one scroll up a little bit further here's the next and a little bit further here is the fourth one right here now the interesting part or the part that I'm interested in should I say is this portion right here see the id key this is going to be different for each of these devices and they uniquely identify each of these devices so what I could do is for each one I could just grab the id key and effectively this will give
6:41me the information that I need for the command runner okay so if I run it again all we're seeing here is the four unique ids for each of these switches under my management now at this stage here what I want to do is I want to take this information and put it into a list object so here's what I'm going to do as opposed to just printing this out what I'm going to do here is I'm going to go and create a empty list so I'll just say device maybe underscore ids have as an empty list and for each device that I'm looping through what I want to do is I want to take the device ids list object and what I want to do is I want to append the device that I'm looping through and get the id key so now what I should have is at the end of this is if I print this out I should actually have a list object with all of the device ids inside the lister case it's going to look a little bit different from this if I enter see this right here we have a list object with all of the elements within this is what we want now at this point here what we want to do is we want to begin using the command runner okay now again if we go back to the command runner option let's just collapse this get down to the command runner again like so go to the post request let's grab this endpoint remember it's going to be a post so let's copy you and go over here and at this stage what I'm going to do is let's maybe call this command runner url and that's going to be equal to the base url and we're going to add on and paste in this right here and then we can begin making that
7:58request via the command runner okay now we have this list object as opposed to printing this out what I'm going to do now is I'm going to go and specify a payload so I'll say payload is equal to and again if we remember what we see in the documentation the schema is going to be as follows we're going to specify a commands key as well as a device uuids key and again if you happen to look at the information here we actually see a list of strings here the square brackets going to be a list here and also a list here and that is by the way we got all the device ids in the form of a list that's why we want it okay so let's go and construct this we want this key first so let's copy you okay I have my quotations paste it in as the key and now I'm going to define a list and pretty much this is going to allow me to specify any of the commands that I want to run so what I could do is I could say show ip interface brief that could be the first command and if I wanted to send a second command I could do like you know show run that type of thing and if I wanted the third I would just keep adding more elements in the list but in my case here let's keep it simple and just run one command but it still has to be within this list object okay now the next thing I'm going to do is specify the device uuids as we saw before so I'll say device uuids and at this stage here what I want to do is I want to put in the device ids list that's got all of the unique
9:16identifiers within them okay that is the list element and now what I want to do is to use requests to send this off okay so once again let's just maybe say cli response and we'll take the request library this time what is it going to be it's going to be a post request the url is going to be equal to the command url or the command runner url should I say once again the headers will be equal to the headers above that means we have the token within to authenticate and because we're sending off this payload as a dictionary we want to transfer it to json so I'll say json is equal to the payload that we're sending and I'll say verify is equal to false and now what I can do here is try to print out the cli response that we're getting back okay all right so we're looking kind of good but what I'm going to do here I've just noticed I'm going to have to add a comma here for each item in the dictionary and also spell request correctly that's also important okay so let's save this and give it a go so let's run the script to enter all right it also we're getting back the 202 response but what we actually want to get is you want to get the python dictionary so I'll say dot json and if I now rerun it and to enter what we're seeing here is a response and the task id now this might be a little bit strange because you might have been expecting that we would see the results of the show commands that we've tried to send but this is not what's going on quite just yet all right so here's what's happening see once we send off
10:35these commands we're not getting the response back straight away in essence what is happening is the catalyst center is creating a background task and this background task is running all these commands in essence once everything is done dna center is going to reply back with a file id and what we want to do is you want to get that file id because that's going to contain all of the response information from the actual show commands so what I'm saying here is we have a little bit of logic to do in order to be able to get the actual output so let's go and begin building that out so the first thing we're going to have to do here is we want to get the actual task id so what we do here is get the response key and the task id key so we can say response and then we get the task id key like so so now if I print this and run it again like so this here is the id of the task that we just ran okay now notice it's a little bit different from the previous one that's because it's a completely new task but the thing is we want to get this task information okay so what we want to do here is we're going to just assign that value whatever it happens to be into a little variable so we'll just call this the task id variable and grab it like so all right friends so at this point here I have taken the task id and I've saved it into a variable value and what I want to do is I want to make a request to the task endpoint so if I go to the left hand side choose
11:53on task and go down to get task by id like so this is the endpoint that we want to have okay now check this out it's going to be a get request to this particular portion but this part here this is going to be the dynamic value we're going to have to populate so at this stage here what I'm going to do is I'm going to create a variable called task url and that's going to be a combination of the base url and adding on to that we're going to paste in copied right there now remember this is not the full url we're also going to have to add on that dynamic value so at this stage here what I'm going to do is to create a task request and I'll use the request library with a get request and what I'm going to do here is I'm going to say the url is equal to the task url we just defined above but that's not all we're going to concatenate it with the task id we just parsed it above now at this point here what I'm going to do here is say the headers are equal to the headers that means we're going to have our authentication via the token and I'm going to say verify is equal to false and what I want to do here is I want to get back the python dictionary coming back so I'll say and at this point here I'm going to just go and print out the request okay and just see what we get so let's run example 4.py and to enter all right to check this out we get back the response we have a progress key and inside of this we want to get the file id now there's a little bit of an issue here but I know there's issues and issues and issues it's a little bit more complicated
13:10but what we're going to do first is get the response key and then the progress key which will isolate this portion right here okay so if I just say print out response and the next key is going to be progress if I save this and run the script again what we can see here is we're getting back the file id and it's this thing here that I want to be targeting it's inside here that's got all the information from the show commands that we actually sent now here's the thing whilst this might actually look like a python dictionary it really is a string believe it or not we can actually test this for a start first thing I can do is I could try to call the file id key right here but as you're going to see it's not actually a key so it's going to yield on errors if I try to run it again tells me string indices must be integers not str so this tells us we're dealing with a string and again if I want to go back here I can actually print out the type of response we're getting back to be doubly sure so just save this like so and give it a run so we can see here this object does look like a dictionary actually as a string value so what I want to do is I want to load it in and convert it into a dictionary using the json library so up to the top what I'm going to do here is the import json and here's what I'm going to do I'm going to grab all this stuff and I'll just save it into a variable let's just call this maybe progress string is equal to this okay
14:28and what I want to do is to make it into a dictionary so let's call it progress dic and I'm going to take the json method or json method json library use the load function I'm going to load in that progress string so now if I print this out see the type of information that we have let's run it again now we're seeing we're getting a dictionary object so if we just print out the actual output save here here is the information but now it's a dict so we can actually parse out this key so let's just grab file id all right so let's save this and run it again okay finally finally finally now we're getting back the file id okay this is going to contain all the information of the show commands that we sent to our device or to our devices plural should I say so what I'm going to do here is just grab this and save it into a variable called file underscore id now the last thing I want to do to actually get the information here is I'm going to have to send one last response again what I'm going to do here is go into the file option and what I want to do is I want to download a file by the field which is this here right okay so I'm going to grab this endpoint let's go up to the top and let's just say file url is equal to the base url and we're going to add on paste you in so the last request and we use the request library it's going to be a get request the url is going to be equal to the file url but again we're going to have to add on a
15:43dynamic value which is the file id right here okay this is the dynamic value that we're actually seeing right here in the documentation again we say headers are equal to the headers verify is equal to false and what we'll do here is print out the file request txt and let's save this okay so let's run the script oh appears we happen to have some type of error what I want to do here actually is go here make sure we have a forward slash so we're separating the file id from this endpoint apologies about that let's save here clear the screen and if I try to run this again all right finally finally we're now getting back this information but it's not very clear so what I'll do here is go down and let's maybe grab the json object to get it as a dictionary just print this like so let's run it again all right now again scrolling up we can see here we have a list object what I'm going to do here is I'm going to look through each element I'm going to grab the command responses key and then the success key okay I'll just say for let's maybe call this output and file request what I want to do is to print out the output grab the command responses key and grab the success key and what I will do is I'll print out a new line just so we get a little bit of space between each output okay so if I save this and clear the screen hit enter we're slowly getting more output but again what you can see here is we actually have a key which is the name
16:59of the command we sent and what I'm going to do here is parse that out also so I'll just say command success is equal to this right here I'll just say for command and command success print out a new line and then print out command success and I will grab the command key which is going to be the show ip interface brief key so now finally hopefully that should be us if we clear the screen and run it again and bam there we go right there so I know that was a lot of work but as we can see this is switch number four here is the output of that command scrolling on up switch number two right here we can see the output of its command same again switch three same again switch four and if you so wished if you wanted to what you could do is you could add more commands by just appending this we do show run save here and rerun the script all right so here is switch two we see the output of show ip interface brief and above we see switch two's show running information so all this stuff here this is all the config on switch two and scrolling on up here is switch one's show ip interface brief here is the running config so on so forth as well as all the output for all of the other devices
Validation
0:00Alright friends, so let's now validate what we've learned within this skill. So the instructions are, launch the lab below. So let's go down here and choose to launch it like so. Now whilst this is loading, we're going to have to go to the DevNet sandbox and reserve the Cisco Catalyst Center sandbox. So pretty much once you've logged into the sandbox, you should be able to launch it like so. What you're going to do is search for Catalyst Center and choose to launch that. And then simply review the summary and choose to launch the environment. And once you've done that, once the sandbox is ready, they're going to email you some information.
0:32So again, that might take about an hour before it's fully prepared and you get your email. But once you do, what I want you to do is to connect to the sandbox using the OpenConnect client. Be aware that you're going to have to use the pseudopassword on the Linux Mint machine and the password is going to be cisco!23. Now once you've connected to the sandbox, I want you to write a Python script that uses the request library and send an HTTPF request to the Catalyst Center controller which is going to return overall client health information.
1:04Now you may be wondering, how do we even get overall client health information? Well, the hint is as you are to consult the Catalyst Center API documentation to determine the relevant endpoint information. So friends, go give that a go and I will see you in the very next video where we walk through the solution.
Validation
0:00All right friends so let's go and walk through the answers then. So like I say you should have launched the lab environment. So in this case here let me just go into my Mint Linux here by double clicking it. All right so what I'm going to do here is I'm going to say sudo open connect and I'm going to go and paste in the address I was given via my email. So if I just hit enter what I'm going to do is to type in the super user password which is cisco exclamation two three and to enter. So now we're going to begin the connection and I'm going to have to specify my username. Again this is from the email so mine is ipv0.
0:33So hit enter and now I'm going to have to specify the password that was also in the email. All right so now I have connected what I now want to do is to open up a new terminal window and leave this one running. So if I just right click this and say new window like so and all I'll do is just full screen this and what I'll do is go and create a little file. Okay so what I'll do is first go in and activate my virtual environment like I've done before say source bin activate and what I'll do here is just create a little file let's just call this one validation.py okay call it anything you so wish. So this stage here what I will do is import the request library and to disable my little warnings I will just say import urllib3 and what I'm now going to do is to create my authentication URL. So in my case here the URL is going to be https colon forward slash forward slash the address of the server is 10.10.20.85 and if you remember the authentication URL is dna system forward slash api forward slash v1 then auth then token.
1:29Now at this stage here what I want to do is to go and find information related to the overall client health information. So we go to the api documentation for Cisco Catalyst Sensor, go down to the api reference, choose next. Now because we're going to be looking for overall client health makes sense to go and look in the clients right here and down here notice we have this option for overall client health. So let's click this here and we can see this is the endpoint we want to be using and once again it's going to be a get request. So let's just maybe call this client health URL. We do our https colon forward slash forward slash and again same IP address and it's going to be dna then it's going to be intent forward slash api forward slash v1 and then it'll be client dash health. Now specify my username which is going to be administrator as per the lab instructions. Password is also going to be cisco1234 exclamation mark and now I'm going to go and create my authentication request. I'll just say auth request and I'll use the request library.
2:25This is going to be a post request and I'll say URL is equal to authentication URL. I'll say auth is equal to and it's going to be a tuple and I'll pass in the username and comma and specify the password. Then I'm going to say verify is equal to false and apologies about the ugly line wrapping and I'll just say I want to get the JSON object to return the python dictionary and I'll just say my token is equal to the auth request and I'm going to go and grab the token key from the response. At this stage here what I'm going to do is create my headers. This is going to be in the form of a dictionary and I will say x-auth-token remember that very important. I'm going to pass in my token like so have a comma and I'll have an accept header and say that I want to accept application JSON and then I can just close off my dictionary like so and now what I'm going to do is I'm going to go and create my health request. Okay so I'll just say health underscore request is equal to and I'll use the request library again with the get method. The URL this time is going to be the client health URL. This time I'm going to say headers are equal to the headers that we've defined which is going to have our token verify is equal to false and again I'll get the JSON object and all I'll do is I'll print out the health request. In fact you know what let's just change that to be health request singular a little bit better and what we should get back is a response
3:41key. Okay so if I just say response. Okay so let's just save this and give it a go. So I'll say python3 validation.py and hit enter. Open up here as we don't have any module name requests let's just say pip3 install requests like so into the virtual environment give it a moment there we go right there and just try to rerun things again and look at this right here in fact you know what I can do let's just say pip3 install rich to make it a little bit prettier to look at. Let's go back into the script itself and what I'll do here is just say from rich import prints and just save this and let's rerun the script again and bam look at this right here what we're getting back is all of the client health information about the devices under our control. So friends that is us for our validation challenge on automating Cisco Catalyst Sensor. I hope this has been informative for you I'd like to thank you for viewing.
Frequently asked questions
What does the Understand Cisco Catalyst Center lesson cover?
In this 57-minute lesson, the team member reserves the Cisco Catalyst Center DevNet sandbox, connects over VPN with the OpenConnect client, and requests an authentication token from the Catalyst Center REST API using Python. They then retrieve and create sites in the network hierarchy and use the command runner API to run show commands on managed Catalyst 9000 switches from the controller.
What is the difference between the northbound intent API and the southbound API in Cisco Catalyst Center?
The northbound API, which Catalyst Center calls the intent API, is how scripts and tools talk to the controller itself. The southbound API is how the controller talks to the networking devices it manages.
Why do Cisco Catalyst Center API calls still reference DNA in the URIs?
Catalyst Center was previously known as Cisco DNA Center, and the old name still appears in many API request paths. The lesson points this out while walking through the Catalyst Center API documentation so learners recognize it when building requests.
Can I copy the Python example from the Catalyst Center API documentation and run it as is?
The lesson shows that the documentation's Python and cURL examples are a useful template but incomplete, because they give only the endpoint, not the full controller URL, and include no authentication token. The learner turns that example into a complete Python request that first obtains a token and then retrieves site data.
How long does it take to get the Cisco Catalyst Center DevNet sandbox ready?
The trainer notes that the reservable Catalyst Center sandbox takes about an hour to become operational, and an email with connection details arrives once it is ready. Team Leads can plan around that by having learners reserve the sandbox before starting the hands-on portions of the lesson.
How does this lesson fit into the ENAUTO 300-435 v2.0 course and CCNP Enterprise?
This lesson is part of the Cisco CCNP Automating and Programming Cisco Enterprise Solutions (ENAUTO 300-435) v2.0 course, which runs about 18 hours per learner and also covers controllers such as Cisco Meraki and Cisco SD-WAN. The course maps to the CCNP Enterprise certification, giving an IT Director a controller-based automation building block for network engineers working toward it.
Team training path
Turn this skill into assignable team training
This free skill is a preview of the courses your team can assign, track, and report on with CBT Nuggets.
Free training library
More free lessons in Cisco
Cisco
Describe Network Architectures
Free lesson from Cisco CCNP Service Provider Core (350-501 SPCOR) v1.1 · 2h 7m
Cisco
Describe Software-Defined Networking
Free lesson from Implement an SD-Access Fabric with Cisco DNA Center · 39m
Cisco
Tools for Route Manipulation and Control
Free lesson from Cisco CCNP Enterprise Advanced Routing and Services (300-410 ENARSI) v1.1 · 1h 48m
Cisco
IS-IS Foundations and Design
Free lesson from Cisco CCNP Designing Enterprise Networks (300-420 ENSLD) v1.1 · 1h 17m
Cisco
Build a Cisco Firepower Lab in ESXi
Free lesson from Cisco CCNP Securing Networks with Cisco Firepower (300-710 SNCF) · 1h 15m
Cisco
Describe Wireless Physics
Free lesson from Cisco CCNP Designing Cisco Enterprise Wireless Networks (300-425 ENWLSD) v1.1 · 57m
$59
seat / mo, billed annually
