---
# System prepended metadata

title: DevNet Associate 2 (200-901)

---

# DevNet Associate 2 (200-901)

## 18. Data Models and YANG
### What is Data Model
- Data model
    - Data format to recieve and request the data. Agreeing on the structure of data. Data Schema.
    - How data is supposed to be transmitted between two devices so there's no misconfiguration, misinterpretation of data
- Example
    ![](https://i.imgur.com/4BN8UE3.png)
    - Data Model Components: module, leaf(characteristics), and leaf's restrictions(data type, length etc.)
    - Implement

### How YANG Works
- Monitoring interface statistics.
![](https://i.imgur.com/Fq6Quuc.png)
- Four different Switch types: can I use agreed upon format for requesting interfaces from one deivce to the next, regardless of the platform/vendor?
- History
    - 2002: IETF; shortcoming of SNMP- vendor specific database, not flexible on configuration
    - Network Monitoring and Configuration protocol
    - 2003: NETCONF working group formed
    - YANG working group
        - YANG: Data modeling language. Consisted of module and leaf.
        - IETF: Standardized YANG data model created by standardized organization so it's vendor free. But each vendors/devices have different features, naming conventions so each vendors has its own data models.
    - 2006: YANG was created with RFC 6020
- YANG
    - A specific way to define a Data Model.
    - Network devices use YANG Modeling to tell us what kind of data models they support. That way we can send data to the network device and get data back in a standardized format.
    ```
    module Interfaces:    // ports on devices
        containers interfaces:    // subtopics, split up functionalities(configuration changes, monitoring, gets config but not set config). In this container, we get config data.
            list interface:    // What we will get back. Each interface in list has to uniquely identified by a key. It can be a unique value of any attributes we're about to specify. Shows which interface you're going to use. 
                key "name";
                leaf name:    // Each list will send leaf data with meeting requriment specifics below.
                    type string
                    mandatory true    // whether return of this information is mandatory or not
                    configuration true
                    
        container interfaces-state    // get statistics, administrative info
            leaf admin-status:
                type enumeration:    // We will get three different results which are hard-coded.
                    enum "up"    // interface status 'up'
                    enum "down"    // interface 'shutdown'
                    enum "testing"
    ```
    - There's a standardized module 'ietf-interfaces'.

### YANG in Action
![](https://i.imgur.com/GcLJtSG.png)
- Models: Capabilities. For example, ietf-interfaces. Go to netconf.org and find the data model you are looking for, maybe ospf (tons of it out there), and you could see what containers are there that you can query.
- Container: Specify actual module of YANG data we want to present.
- List: we want to go into
- key: identify key that we want to query out.
![](https://i.imgur.com/LF2Nxca.jpg)
![](https://i.imgur.com/S5bEiPq.png)


- First line: 'Hey we agree on YANG data model'
- name, type enabled, ipv4// specific data
- ipv4 follows its own YANG data model. "urn:ietf:params~" is the module name. Data model can be reused in other modules too.
- ipv6 follows different data model
- last line: name of the interface, parsed into Python object. GigabitEthernet2.
- How YANG in Action: specified what I wanted to filter in what data model, and returned to me in exact same data model that I could parse and use as a Python object. 


### YANG Tools to Make Your Life Easier
- yangcatalog.org -> YANG Search -> Search 'routes' -> 
- Search 'standard' to filter industry standard YANG Containers
    - ![](https://i.imgur.com/Zq7fXeD.png)
    - Container name: bad-routes-rcvd, Organization: ietf, Maturity: adopted => good thing
    - ![](https://i.imgur.com/4UXyuG2.png)
    - This is the 'routes' container with 'ietf-routing' I was looking for.
- Structure of this YANG Data Model
    - ![](https://i.imgur.com/lBTdOBR.png)
    - Other information: route-preference, last-updated(maybe not in the picture)

- yang explorer
    - ![](https://i.imgur.com/ABidn38.png)
    - Download it from Github
    - Function: Connect to a device and download all available YANG Data Models on it. Even build your own scripts or queries in this.
    - Create device profile
        - ![](https://i.imgur.com/JUC4OcD.png)
        - User: Guest/multiple to be able to use this device profile
        - IP address for NETCONF
        - Port(default 830)
        - NetConf Username/Password(same as SSH)
        - RestConf Username/Password
    - Manage Models
        - Device -> Refresh -> Choose the model you just created
            - Get all available models
            - ![](https://i.imgur.com/LQx2NfS.png)
            - Pick 'ietf-interfaces' -> Sync button -> Going to download 'ietf-interfaces' and other models it depends on

        - Workspace
            - ![](https://i.imgur.com/6cvDcXM.png)
            - I see 'ietf-interfaces' model, its version.
            - Check it and click 'Subscribe' button
            - ![](https://i.imgur.com/5xOrrhI.png)
            - You can see it in Explorer. You can dig in interfaces, names, options here.

        - Build script
            - Description 'get-config': This was for getting configurations.
            - What this is going to look like when I run it in NETCONF(RPC)/Python/YDK(Yand Development Kit)/List of device capabilities setting. 
            - We generated Filter tags. Below is the filter XML based on the model that came directly off the device.
            - ![](https://i.imgur.com/CTJIMYX.png)

        - Run command and see output in YANG explorer
- Use YANG Catalog to discover which model you want to work with, check to see the device capabilities in YANG Explorer>Manage Models. Import them in YANG Explorer and generate your own code using RPC/Python/YDK function in NetConf or RestConf.

## 19. Develop NETCONF Scripts for Cisco IOS-XE Devices
### NETCONF, circa 2006
- History
    - In 2006, RFC4741 NETCONF was brought by IETF. It's purpose was to replace SNMP. It wasn't effective until YANG came out on 2010.
    - NETCONF: transport protocol, to transmit data. But the way to transmit wasn't strong enough, until YANG came out.
    - YANG(2010): 
    - RFC 6241 overhauled NETCONF in 2011. Network Programmability actually starts from here.
- NETCONF
    - Connect into network device using NETCONF.
    - NETCONF use SSH on TCP(connection oriented), Authentication, Encryption, Port 830
    - Core Capabilities
        ![](https://i.imgur.com/QQud78Z.png)
        1. GET operational state of devices
            - Device details, status, interface, counter, statistics, VLAN details. Monitoring tool.
        2. GET configuration
            - How interface/VLANs are configured
        3. Edit configuration
            - SNMP: was't good at setting configuration. 
        => Now with NETCONF, we have a standardized way to get operational data, config data, edit config data on our device.
        - 1, 2, 3 in a structured way using xml. 
        Steps
        1. Connect into device using NETCONF which works like SSH(Auth, encrypted, connected). NETCONF tells we're about to GET config data from the device.
        2. Specify what data we want in the form of YANG payload(ex. Get/Edit config data ) and also specify which YANG model we're passing in.
        3.  Network device receives that payload and 'ah I see you're using YANG model. You used GET request. And in YANG model you specified interface'. So I'm going to return to you the response in the exact same model'
        - Netconf: Carrying data and telling it what kind of command we're trying to execute.
        - YANG: specifies exact data we're trying to query and the structure we want to return it.
- IETF-Interfaces
    - In this model, there are two key containers(models of data).  
        1. Interfaces, it returned configuration data of our specific interface on the device.
        2. Interfaces-state, it returned operational status of the devices.

- Including all above, for example,
    - We can connect to a device using NETCONF. Specify we're going to use **GET** command, and pass in Interfaces-state model, asking for operational status like gigabit ethernet 2. 
    - We can then parse out the details and make decision on how we want to move next. 
    - Use **GET-Config** and pass in the Interfaces model, specifying gig eth 2 and we'll receive the actual configuration back in an xml format which we can parse further.
    - If we don't like what we're seeing, we can use **Edit-config** command and passing it again, another interfaces model, but specifying the corrected xml payload telling it how to set this configuration.

- How actual transmission of data works in xml.
    - ![](https://i.imgur.com/V2Y9cv5.png)
    - Reads from bottom-to-top
    1. SSH connection - encrypted, authentication
    2. Specifies RPC(Remote Procedure Call) - Pre-programmed commands or actions to take. ex. We specify 'rpc' and expecting to get 'rpc-reply'. In 'rpc', there's a 'message id' inside. It makes up random message id(i.e. 123 here). When we get 'rpc-reply', I expect to see exact same message id in the 'rpc-reply' so that way we can know which reply correlates to which rpc request.
    4. Inside RPC, there's this command. GET, GET-config, EDIT-config.
    5. Within these items we specify the actual payload 'data' often in an YANG structure. Data will be 'what we're getting' or 'what we're editting', all structured in xml.

- Whole connection process when NETCONF is connected to the network device
    ![](https://i.imgur.com/hF4U62l.png)
    - Our computer is Manager, remote network device is Agent. 
    1. Make the SSH connection. 
    2. Get back the list of capabilities, which is a list of all the YANG data models.
    3. In YANG data models, we'll determine how we're going to proceed. 
    4. and 5. In this case, we want to GET the configruation, on interface. Compose an 'rpc'. Specify 'get-config' and send the data into the network device.
    6. We'll receive the 'rpc-reply' which has the same message id with the 'rpc' we sent. 
    7. Process the data back, the structured xml.

    - Configurations exist in more than one place. 
        - running config, startup-config, candidate-config
    - The config that's running on the device is called 'running-config'. But it's not always the same config that's used when the device boots up. That's called 'startup-config'. To save it for next boot up, copy 'running-config' to 'startup-config'.
    - 'candidate-config': Make edits to config and doesn't impact to device at all. It's making edits on 'candidate-config'. Only after you issue *commit* command, it commits the candidate to the running-configuration.
    - Some Cisco devices are beginning to adpot this, Juniper devices had this for a long time.

### Enabling NETCONF on an IOS-XE Device
![](https://i.imgur.com/GdsQmLX.png)
1. Bring CSR1000v and connect it into NX-OS device.
2. I need to configure interface GE2(gigabit ethernet 2). 
3. Check if I have the correct VM Image and VM Flavor(CSR1000v).
![](https://i.imgur.com/pdnwToc.png)
4. Launch Simulation.
5. Right click 'CSR1000v'> Telnet to console port.
6. Booted up, host name changed, connect into the console.
7. In console, 
    - > enable
    - > conf t
    - > line con 0
    - > logging synchronous 
    - > exit
    - (config)# hostname csr1000v // set hostname
    - (config)# ip domain name abc.inc // specify domain of this device
    - (config)# username cisco privilege 15 password cisco // set username and password. Highest level of privilege and access is 15.
    - (config)# > crypto key generate rsa // Generate encryption certificates. ex. SSH. Later down when we use RESTCONF, HTTPS.
    - Result: How many bits in the modules [512]: 1024 // min 1024
    - Result: SH has been enabled
    - (config)# ip ssh version 2
    - (config)# line vty 0 4 // Five remote connections into this device using the protocol we specified(SSH 2).
    - (config-line)# login local // I want to prompt me to login using at least the local credentials, the username and password we just created.
    - (config-line)# transport input ssh // Allowing SSH connections in, on our management ip addresses.
    - Result: Now we've got SSH enabled on this device.
    - (config-line)# exit
    - (config)# int gigabitEthernet 2 // we've identified earlier as the connection interface we're going to connecting in on.
    - (config-if)# no ip addr // clear out ip address if there was one
    - (config-if)# ip address 172.16.1.6 255.255.255.0
    - (config-if)# no shutdown // same with 'no shut '
    - (config-if)# exit
    - Result: Interface GigabitEthernet2 is changed its state up.
    - (config)# ip route 0.0.0.0 0.0.0.0 172.16.1.1 // Ping outside of the network by giving static default route(0.0.0.0 0.0.0.0) to gateway of 172.16.1.1.
    - (config)# do ping 172.16.1.1 // As a sanity check.
    - Result: Success rate is 100 percent(5/5). 
    - (config)# netconf ssh // Enabling NETCONF on the SSH protocol.
    - (config)# netconf-yang // Enable NETCONF protocol with model-driven programmability.
    - Result: ![](https://i.imgur.com/iHb3fpb.png)
    - (config)# exit
    - # write mem // In admin mode
    - Result: Configuration has been built and saved.
    - ![](https://i.imgur.com/vze7aMA.png)
    - Result: NETCONF running data store.

    - For sanity check, there's a code connects into device, it'll get basic information, operational information, and config information on GigEthernet2.
    - ![](https://i.imgur.com/NYXR8IL.png)

### Getting NETCONF Data with NCCLIENT
- NETCONF-1.py
![](https://i.imgur.com/FCGsGy6.png)
![](https://i.imgur.com/TuNVkda.png)
- line 4 to 5: Specifying which router we're going to connect to in Cisco DevNet Sandbox as a dictonary format. Host(or ip address), port, username, password.
- line 1: Our computer is Manager and we talk to Client. When we run pip install ncclient, which is to prepare devnet environment, NCCLIENT is a NETCONF SDK. It handles most of the xml translations, hello handshake, identifying RPC, what the operation is, transmitting the payload, getting RPC-reply, etc.
- line 7: Connect using the NETCONF protocol to the router, the port, the username, and the password. And turn off the hostkey_verify because we generated our own SSH certificate, that would fail. It's not a trusted certificate. Also, store this connection to the variable 'm'.
- line 8: close the connection.

- NETCONF-2.py
![](https://i.imgur.com/ZeDo2KO.png)
- line 8: For every capability from the server_capabilities handshake, print capability.
- Result: ![](https://i.imgur.com/KzTArIr.jpg)
- We can see what are all the models this device supports. Most of them are specific to Cisco-IOS-XE.

- NETCONF-3.py
![](https://i.imgur.com/REE3kmc.png)
![](https://i.imgur.com/xtC3jyZ.png)
- Getting back operational data and config data for GiabitEthernet2.
- line 7: I'm building 'netconf_filter'. It's a XML structure all contained within the <filter></filter> tags. 
- line 8: Interfaces container. Returns configuration data to us. So here, it's going to return config data of GigabitEthernet2.
- line 13: Interfaces-state container. Get operational state of GigEthernet2. Packets in/out, administrative status up/down. 
- I've now got a filter of XML data. I'm going to ask manager to inject it into the RPC-reply. 
- line 24: Print out the capabilities.
- line 26: Use manager connection and I'm going to pass in the get command. This will get either operational state data or config data. Parameter is the 'netconf_filter' I just specified above. NCCLINET is smart enough to open 'rpc' bracket, issue 'get-rpc' and specify the filter of xml data to filter out the results to be just config and operational state data of GigEthernet2.
- line 27: Take xml response and turning it back to pretty looking output. Using xml.dom.minidom, I need to import it to use.
- Result
![](https://i.imgur.com/RJOknyP.png)
![](https://i.imgur.com/ECyK6F3.png)
- Have 'message-id'.
- Actual data return. 
    - Interfaces container: actual configuration data on that GigabitEthernet2. decription, type, enabled, ip address 2.2.2.2.
    - Interfaces-state: Operational data. Admin-status, phys-address(mac address), statistics of packets in/out(highlighted).

- NETCONF-4.py
![](https://i.imgur.com/n0nW7Fg.png)
![](https://i.imgur.com/l2aaJxY.png)

- line 36: Getting the info in xml response.
- line 37: Parse out that xml to Python object(dictionary).
- line 48: Raw data into object called 'interface-python. I need to add .xml for the passing variable.
- line 51: [#text] to get raw text.
- Result
![](https://i.imgur.com/mnQiGtN.png)
- The result in ordered, Python dictonary object.

- line 54: I'm going to pull out the configuration data by parsing into [interfaces] container [interface] list object. 
- line 55: Parse out operational data by going into [interfaces-state] container and [interface] object.
- Result
![](https://i.imgur.com/8R5Jo0X.png)

- NETCONF-5.py: Modular format. Cleaning up code.
![](https://i.imgur.com/YcVufiI.png)
![](https://i.imgur.com/jwMvhuW.png)
![](https://i.imgur.com/s7CfH7s.png)
- line5: Within same folder, I can specify external files to use import within this. 'router_info.py' has a router object stored here. I can make for loop to use this code on multiple routers.
- line 9: Rather than specifying that raw xml filter, I can specify xml file by using 'open' command. 
- This script is reusable because we can specify different routers, different filters and tweak how we want to handle this situations.

### Automation with NETCONF and NCCLIENT
- Set up xml as template and dynamically set the variables using the .format() method in python. Then use 'edit_config' rpc, pass in config you're sending in, specify which data store you want to config this against.

![](https://i.imgur.com/gg6TY82.png)
![](https://i.imgur.com/8HoMzcn.png)
- line 4 in ios_config.xml: This is a template with dynamic variables, name tags and description tags. We can dynamically pass interface name and description. 
- line 4 and 5: Open ios_config.xml in config_template.
- line 7 and 8: Setting the variables on xml file to what we want.
- line 10: Manager connect to connect into the device.
- line 11: Use edit_config rpc and specify what config, set target to be executed against this running config.
- Result: 'ok'
![](https://i.imgur.com/J5FU4aw.png)

![](https://i.imgur.com/FhFI6UD.png)
- >en
- >show run interface gig2
- Result
![](https://i.imgur.com/4N5mBLK.png)


## 20. Develop RESTCONF Scripts for Cisco IOS-XE
### RESTCONF circa 2017
![](https://i.imgur.com/f7EDr8L.png)
- How does REST API in .json apply to a network device into RESTCONF?
- We're going to develop an application which connects in over REST API using either JSON or XML. End result is we interact with network infrastructure whether it's device or software controller, SDN.

- SNMP -> NETCONF -> RESTCONF
- Why NETCONF wasn't enough?
    - XML is heavy and difficult to work with. Not human readable enough. And dealing with RPCs, handshakes, operational data, etc wasn't familiar to software developers. 
    - API is reletavly easy to build using ASP.Net core(Microsoft implementation using C-Sharp), Node.js(REST API middle tier version of Javascript, easy to deploy)

- REST API, RESTCONF popular now. Why?
    - 2017: Built upon all of the major successes of NETCONF. Like structured data, rpcs, capabilities, handshakes. + RPCs aren't really needed anymore.
    - In RPC, we use GET, Edit-config. But in REST API we can use HTTP protocol such as HTTPGET and specify in the url what data or body we want.
    - HTTP method: GET, POST(writes data), PUT(updates data), PATCH(replace), DELETE
    - We can use these HTTP methods in conjunction with YANG data models in order to make these configuration changes. The YANG data models are going to be passed in, in the payload. Or more, we can pass in the specific items that we want to use in the url itself.

- GET request
    - url: https://ipaddress/root/dataStore/yangModule/container/leaf
    - root: API or RESTCONF. This tells our device this is what we're trying to hit this protocol and access this protocol.
    - dataStore: running, candidate, startup
    - yangModule: ietf-interfaces
    - container: YANG container. Interface's state.
    - leaf: specify exact interface ex.gigEthernet2

    - Response: JSON response of interface state, every interface on that device.

- To create new data: POST https
    ![](https://i.imgur.com/dIVtbzs.png)
    ![](https://i.imgur.com/5YYoFlz.png)

    - url: https://ipaddress/root/dataStore/yangModule/container/leaf
    - ipaddress: host. ex. ios-xe-mgmt-latest.cisco.com + port. ex. 9443, RESTCONF is listening on port 9443.
    - root: ex. restconf
    - dataStore: ex. calling data in this example
    - yangModule: ex. Cisco-IOS-XE-interfaces-oper
    - container: ex.interfaces
    - username, password: specified in environment variable
    - headers: ex. application/yang-data+json. That way we know it's going to use YANG module, YANG container and we're going to accept YANG response.
    - Specify {JSON} body what we want to have set. 
    - And RESTCONF will handle rest of them for us.

    - Response: JSON responses in YANG format.
    ![](https://i.imgur.com/5W0XeBw.png)

- Is NETCONF dead? 
    - No. 2006~ using now. Chance you're going to run into it in the wild.
    - But if you're developing moving forward from scratch, RESTCONF is your go-to because you have amazing tools to work with it. Like Postman.

### Enabling RESTCONF on IOS-XE Devices
![](https://i.imgur.com/dqGmPib.png)
- csr1000v>en
- csr1000v>conf t
- csr1000v(config)#restconf
- csr1000v(config)#ip http server // Start HTTP services running
- csr1000v(config)#ip http authentication local // Makes me prompt for my username and password using cisco username & password. 
- csr1000v(config)#ip http secure-server // Use SSL
- ==> RESTCONF is up and running in my environment.

- Sanity check on Postman
    ![](https://i.imgur.com/BJi14ZG.png)
    - Send get interfaces request.
    - Result was RESTCONF interface started running and working.
    ![](https://i.imgur.com/2HSCwiH.png)

### Exploring Device APIs and Models with Postman
- Like a NETCONF where it returned to us a list of all of the modules that are useful to us, we can actually use RESTCONF to get all of the device capabilities too.

![](https://i.imgur.com/QaOTqoQ.png)
- We have environment variables on host, port, authorization(username and password. Provided by Cisco DevNet Sandbox), headers(application/yang-data+json).
- Go into restconf/root the dataStore. Go to netconf-state and get the list of capabilities
- Return: JSON output of every capabilities on this device.

![](https://i.imgur.com/igUY6lC.png)
- 'I want to get the operational state of a specific interface. I want to have the most verbose output. Cisco IOS-XE has a 'Cisco-IOS-XE-interfaces-oper' model and this is an operational status for their interfaces. The contianer is called interfaces.
- Result: Return of operational state of every interface on the Cisco IOS-XE devices. Verbose, structured JSON output that is easy to read. ex. Ethernet statistics, IP statistics, In/Out packets, VRF data, IPv4 configuration, operational statistics.

![](https://i.imgur.com/TZt6Sr8.png)
- We can change 'Cisco-IOS-XE-interfaces-oper' model to 'ietf-interfaces' model but will have much less result. It's because Cisco IOS XE model was specifically designed to provide more data back to us. Built around all of the capabilities that Cisco device actually has.

- Adding a leaf to get more specific result that I want. Here, interface=GigabitEthernet1.
 ![](https://i.imgur.com/C4p9uqw.png)

- Specific subset of data inside interface.
![](https://i.imgur.com/Cfu7Cpo.png)

- POST request to add loopback interface.
![](https://i.imgur.com/IQyVwec.png)

- Posting to RESTCONF/data, ietf-interfaces beacuse it's the simplest structure to post data in.
- Using same Authorization and YANG Headers. But now the Body is the actual structure of the YANG data model. I'm specifying 'Loopback100' as a name, description 'Added by CBT Nuggets', type, enabled, ipv4 address using ietf-ip model.
- Result: 201 Created
- Sanity check with 'GET interfaces' if the Loopback100 interface is created well.
![](https://i.imgur.com/suXyUe9.png)
- I can check description 'Added by CBT Nuggets' is there. 

- DELETE command
- Use the same URL with DELETE command.
![](https://i.imgur.com/AXASTqL.png)
- Result: 204 No Content

- Using Postman, we can get the capabilities of the deivce, we can build queries for specific models down into specific leaves in that model and it gets specific characteristic of those leaves with options. 
- We can use POST, PUT, DELETE, whatever we want to as long as we provide the correct model and JSON body.
- Plus, Postman > Code > Python: You can change your URL API to Python code.

### Developing RESTCONF in Python with Requests
- Breaking down using the request library in Python to access a RESTCONF device and use Python logic to parse out the result and return useful information back.

![](https://i.imgur.com/bBFMghR.png)
- import json: Python has native ability to work with JSON as long as you import json.
- import pprint: pretty print

- line 6: Specifying router information. Different from Postman is, we need to specify *port number* when using Python.
- line 10: Headers are python dictionary. You do have to specify. We're going to be sending yang-data+json and we're accepting yang-data+json response.
- line 13: url with host and port variables. 
- line 16: Using requests library, we GET the data. We can use POST, PUT, DELETE method by specifying here. Verify=False because we're using self-signed certificate which is not an official one. We will get return of JSON response out of this line.
- line 20: response.json() to convert it to Python dictionary.
- line 24: We can check operational status of our data by using 'if' conditional statement.
- Result
    ![](https://i.imgur.com/0ox3DpO.png)
    - Interface status is up

## 21. Nexus Programmability with NX-API CLI
### Introducing NX-OS and NX-API CLI
- NETCONF and RESTCONF is provided to us by the IETF but vendors have their own protocols.
- Nexus devices runs on two different types of OS
    1. NX-OS on top of Linux. Features are ...
        - You can run Containers on docker
        - Run Ansible
        - Run Python script natively on the device. 
        - Report back to Central Python Management system or Streaming analytic system. It's similar to SNMP. But we're sending structured data, where we can customize the reports, dashboards.
        - There's a custom API for Nexus device called NX-API.
            - NX-API CLI: Older version
                - Accessed over HTTP/HTTPS
                - Not RESTful API
                - Everything is POST method. No GET, PUT, PATCH, DELETE.
                - ![](https://i.imgur.com/Fu3TWZx.png)
                - Look at 'input' over the picture. It is the message I want to post. When I POST this message into NX-API CLI, I'll get structured JSON data back. That's the magic of NX-OS.
                - We can take all of this CLI commands, issue those commands through JSON POST, and get structured data output. Then interact in programmatic way.
                - Benefit: Keep using same CLI commands, POST them into device and get output back.
            - NX-API REST: Newer version
    2. ACI mode

### Enable NX-API
![](https://i.imgur.com/B0v0KdR.png)
- Configure NX-API on nx-osv-2
![](https://i.imgur.com/IDzvJ0N.png)
- Press Enter -> Logged in
- NX-OSV-2# show ip int brief
- NX-OSV-2# conf t
- NX-OSV-2(config)# feature nxapi // Enable NX-API
- NX-OSV-2(config)# nxapi sandbox // To explore NX-API CLI in Sandbox
- NX-OSV-2(config)# exit
- NX-OSV-2# copy running-config startup-config

- Sandbox: Internet>172.16.1.4>Authentication credential required

### Explore the NX-API Sandbox
- Nexus device running NX-OS is just running Linux. 
- NX-API Sandbox gives you a tool where you can explore what your show commands, config commands do on your device by getting the response back.
- But remember, when you hit POST it actually POSTs it to the device, so you're making a change there.

![](https://i.imgur.com/FpnQkzP.png)
![](https://i.imgur.com/Vy0OwYG.png)
![](https://i.imgur.com/F2xjASC.png)
- CLI Command: show ip int brief
- On Request below: Automatically generated JSON payload and even in Python script. Only thing I need to change in the Python script is a YOURIP(url), USERID, PASSWORD and if I want to add functionality or logic into how to handle this request.
- Response: Post that command to the interface on the device. And get 'show ip int brief' results, return to me in structured JSON format.

![](https://i.imgur.com/8h1NVoc.png)
- json-rpc: Structured data format. This is like when we were specifying application/yang-data+json. We're specifying JSON-RPC as a content-type or an accept header. It's sending data as a JSON data and in that JSON data, it specifies the method(RPC) and in this case it's CLI. Telling the device that RPC that we're about to issue is the CLI and that RPC is telling 'Go run the CLI command that I pass in.'

![](https://i.imgur.com/jbZ8IEB.png)
- CLI_ASCII: You're going to get Metadata. Message is flat response in one item. If you had text parser and you needed it backwards compatible, that's only use case.

![](https://i.imgur.com/FzZGs5p.png)
- Message format: xml, json => INS API
- Transport data in xml or json. 
- When Nexus device trying to get their NX-API, whether you're using JSON RPC or not, it's going to be
    - http://ip/ins
- Doesn't matter which message format you're using, you're hitting it on ins. Meaning: Nexus and Cisco are throwing all their way behind Insieme in this API.
- Command type
    - cli_show: show command
    - cli_show_ascii: show command, output in flat Metadata
    - cli_conf: configure command
    - bash: Linux commands directly on the device over this API


### Exploring NX-API CLI in Postman
- Advantage over Sandbox: Managing your environments, different devices. Also, set up environment variables in different post for different request and save in nice organized space.
- POST http://{{h}}:{{p}}/ins
- Authorization: username, password
- Headers: If we're using Ins, we're using application/json. If we're using json-rpc, it'll be application/json-rpc. Xml, application/xml.
- Body: Create it on NX-API Sandbox with message format(json here) and command type(cli_show) you want. Copy the Request below and paste it in body.
- Response: 200 OK
![](https://i.imgur.com/hOBN806.png)


### Python Scripting for NX-API CLI
![](https://i.imgur.com/42B3aCE.png)

- For HTTP or RESTful/non-RESTful API endpoint. If we're passing data on JSON or XML, we'll use 'requests' library.
- Serialization or Deserialization
    - Python convert to or convert from JSON.
    - line 21: Serialization. Convert to JSON.
    - line 25: Deserialization. Convert from JSON.
- line 4: Target is Nexus device running in VIRL.
- line 8: Specifying content-type of application/json. That way we know it's not going to use json-rpc.
- line 9~: Payload of data itself. I'm specifying structure of it. Copied and pasted it from Developers Sandbox.
- line 19: We're working with NX-API CLI, non-RESTful API. So everything has to be POST.
- line 20: Converting showcmd object to JSON.
- line 24: Because we're using self-signed certificate. 
- line 19~25: I'm going to POST this request and send a JSON response back. 
- line 25: .json() method. It gets the JSON response back and tells it convert to Python dictionary. json() 매서드는 Response 스트림을 가져와 스트림이 완료될때까지 읽는다. 이 메서드는 body 텍스트를 JSON으로 바꾸는 결과로 해결되는 promise를 반환한다. 
- line 27: Convert the response that has Python dictonary back to JSON by using .dumps(). indent and sort_keys are for pretty output.
- Expected Result: Output of 'show ip int brief' from Central Nexus device running in VIRL lab.
- Output: Structured JSON data.
![](https://i.imgur.com/wCOULQ7.png)

## 22. Nexus Programmability with NX-API REST
### NX-API REST Object Model
- Every single thing in Nexus device is an object. ex. VLAN object(has methods-update, set, delete)
- NX-API REST Object Model (for Nexus Devices)
    - Targeting object
        - URL: /api/vlan?id=101 is **targeting VLAN object** on Nexus device.
        - Body: changing a name, perform update method
    - Structure of Object
        - Data Management Engine(DME)
            ![](https://i.imgur.com/RksS1N4.png)
            - Exists on all devices work with object.
            - Running on Nexus device too.
            - Function: Handles request coming from you. Request lands on DME and DME translates how to get that data back to you in the format you specified. 
            - So it doesn't matter what kind of request you're issuing.
            - Northbound: Our request is on top of the list.
            - Southbound: Backend processes is an OS, down of the list. DME gathers the data from the OS and these processes.
            - It's going to use models based on what you requested and what was returned in order to structure the data back to you.

        - How does DME know how to interact with OS and processes to return the correct output?
            - Management Information Tree
                ![](https://i.imgur.com/PehJUC2.png)
                - Not specific to Nexus.
                - Work similar with YANG data model.
                - VLAN: Name, ID
                - Interfaces object: Name, IP address(object)
                - DME in order to return the correct object, follows the structured path down the tree that we will specify.
                - Steps
                    1. Starts at the root = sys
                    2. Always, one parent object with unlimited number of child object.
                    3. Every single objects is class. Class is a custom object that has its own properties and methods associated with it.
                    4. Layer 2 Bridge Domain > VLAN
        - How are these mapped objects actually named?
            - Each object has two names.
                - We call Relative Name and Distinguish Name on Nexus devices.
                1. Relative Name(RN): Simple name
                    - file.txt
                2. Distinguish Name(DN): Full name
                    - C:\Documents\file.txt
                    - Always have to be unique.

- Real life exmaple
    ![](https://i.imgur.com/HUOBE9C.png)
    - Class has a model, a structure so objects those are in same class will have same structure. For example, each interface is going to have exact same structure that's defined by the class.
    - Interfaces and Bridge Domains will have multiple childrens for each VLANs and each interfaces exist.

### Exploring Objects with Visore
- Visore: NX-API REST object model through visual GUI.
- You need Nexus 9K to use NX-API REST or Visore.
    - Go VIRL Server>VIRL Software>Install and download 'nxosv9k' -> VM Maestro>Preferences>Node Subtypes>Fetch from Server: Refresh list of objects that are available
    - To enable NX-API REST is the exact same command as before, feature NX-API.

![](https://i.imgur.com/B3bBrMN.png)
- On console:
    - User Access 
    - nx-osv9000-1 login: cisco
    - Password: cisco
    - nx-osv9000-1# show ip int brief
    ![](https://i.imgur.com/f6yYoRS.png)
- In web browser
    - 172.16.1.68/visore.html
    - Login: username - cisco/password - cisco
    ![](https://i.imgur.com/jcqaAgM.png)
    - topSystem is the class we're looking at. So dn of sys is a class of topSystem.
    - Arrow key after **sys** is a Management Information Tree. If you right click, it will take you one level down to the management tree.
    ![](https://i.imgur.com/m2L9drA.png)
    - We can see all of the children that exists beneath **sys**
    - Click 'bd' to see the list of VLANs.
    ![](https://i.imgur.com/QP2vJmB.png)
    - Each one of these VLAN objects belong to l2BD(Layer 2 Bridge Domain) class.
    - After the arrow on dn, you can see that we have statistics, faults, health reports on each dn.
    ![](https://i.imgur.com/ZUPhhXM.png)
    - I can search by class name. Use this if you know what you're looking for. ex. l2BD
    ![](https://i.imgur.com/H6ppSC0.png)
    - Display URI of last query. The exact endpoint query I could tack on to the end of my web browser url(172.16.1.68).
    ![](https://i.imgur.com/GJzQIID.png)
    - Run specific query with filter as you want. 
    ![](https://i.imgur.com/yfDsy4L.png)
    - This query means all of the interfaces that are actually trunk ports on this switch.
    - You can also get query string from here.
- Structure of URL
    ![](https://i.imgur.com/VXHBD0m.png)
    - http://ip(or hostname)/api/QueryType(class or DN(MO, Managed Object))/identifier.(xml or json for response)?QueryString

### Setting Up Postman Requests
- Explore both classes and managed objects within my VIRL or Nexus 9K environment.
- NX-API REST VIRL
    1. Login and get token back
        - Environment varibales
            ![](https://i.imgur.com/LYrkG2D.png)
            - Host name
            - Port number
            - username and password
            - Token changes everytime I log in.
        - API
            - POST command to ip address and Headers
            ![](https://i.imgur.com/VJL1N3k.png)
        - Body
            ![](https://i.imgur.com/Bmlq3o8.png)
        - Tests
            ![](https://i.imgur.com/Gcx6h0p.png)
            - Build the token Response structure as I want.
            - Below is a Response and the token is now stored in my environment varibale.
            ![](https://i.imgur.com/0eKVeYJ.png)
    2. GET request
        ![](https://i.imgur.com/yXxJ1E8.png)
        - Response of all VLANs in structured JSON data.
    2. Another GET request
        ![](https://i.imgur.com/Zhv7GGV.png)
        - GET request for *phys-[eth1/97]*
    3. PUT request
        ![](https://i.imgur.com/zuzE27U.png)
        - PUT request to *phys-[eth1/97]*, update the description.
        - Body 

### Scripting Python Requests
![](https://i.imgur.com/2O9n6Tw.png)
![](https://i.imgur.com/2BO0Ro1.png)
- Make sure you POST into the Login
- Make the response to requests.post() method.
- Import pprint and use it
- Extract token out of response JSON structure.
- In Python, it's expecting token in the form of cookie using property 'APIC-cookie'. So we have to change it. 
- When we issue GET or PUT request, we're leveraging that cookie in order to issue the request.
- Token and cookie are inside headers. 
- Then we use PUT request and specify the cookies to handle Authentication when we deal with NX-API REST.

## 23. Real-World Nexus Automation for Real-World Network Engineers
### Show CDP Neighbors
- CDP(Cisco Discovery) is enabled by default in Cisco devices.
- When you plug Cisco device to Cisco device, and you configure nothing, those two device will find each other and exchange information.
- show cdp neighbor // Show you all of the other Cisco devices that are connected to it. What interface it's connected on(both party), hostname
- show cdp neighbor detail // Show you IP addresses of the device

### Getting the Data from NX-API CLI
1. Grab the Request Body below
![](https://i.imgur.com/VdfIMnm.png)
2. Write Python code in VS code
```
import requests
import json

switchuser = 'cisco'
switchpassword = 'cisco'

url = 'https://172.16.1.68/ins' // This is working with NX-API CLI so it's '/ins'
myheader = {'content-type':'application/json'}
payload = {        // BODY from NX-API Sandbox
    "ins_api": {
        "version": "1.0",
        "type": "cli_show",
        "chunk": "0",
        "sid": "1",
        "input": "show cdp neighbors",
        "output_format": "json"
    }
}

response = requests.post(url, data=json.dumps(payload), headers=myheader, auth=(switchuser, switchpassword), verify=False).json() // NX-API CLI relies on every command be POSTed.

print(response)
```
3. Respose comming back from "cdp neighbors"
    ![](https://i.imgur.com/PBYvY2E.png)


### Creating the Token: Login to NX-API REST
- We've got the data back now and it's stored in a variable 'response' in Python dictonary.
- Next is, we're going to update each of the interfaces using NX-API REST.
- We need to login to NX-API first, and set the token to be a cookie.
![](https://i.imgur.com/ZMXOF3m.png)
- Add this below the code above.
- Result
![](https://i.imgur.com/JFnTqT2.png)


### Handling the Response Data
- We've got a response from "show cdp neighbors", we've logged in. It's time for building out the code that does the configuration.
- Expected output we'll get
    ![](https://i.imgur.com/VUcwKv3.png)
    - Rows of data. We have more than one response coming back. But we only want to configure one interface at a time.
    - Loop over each responses and make a decision whether or not we want to configure the interface description.

![](https://i.imgur.com/R02ok8i.png)

- line 34: counter for loop
- line 39~44: There are 3 data from the response I need to set up variables. 
    ![](https://i.imgur.com/xrFyXjW.png)
    ![](https://i.imgur.com/rmT1iU8.png)
    - 'inif_id': What I'm going to configure <= local_int
    - 'device_id': Remote device's name <= hostname
    - 'port_id': Remote device's port ID <= remote_int
- Postman - GET against one of the interface, returned this structure back.
![](https://i.imgur.com/R5gVe4H.png)
![](https://i.imgur.com/gL8d2rZ.png)
- line 46~52: Goal of this Python script: Set the description based on what was returned in 'show cdp neighbors' output. So the body I'm putting in to this request has to follow this particular structure.


### POST the Configured Descriptions
![](https://i.imgur.com/XgTmJME.png)
![](https://i.imgur.com/EdZaJoN.png)
- line 55: From the "show cdp neighbors" command output, we have some local interfaces that are management address. I don't want to configure description on management address. 
- line 56: Ethernet -> phys-eth[1/97]
- line 58: Find pattern '[look for any number 1-9]/[look for any number 1-9]*(repeated as many times as it takes)*' from local_int. It returns group of data back to us. So we group up this and convert it to string on line 59~60.
- line 62: We're posting this data into configuration.

- Result
    ![](https://i.imgur.com/bE0kszH.png)
    - We changed Nexus device's description!


## 24. Auto Cisco Meraki Networks
### Cisco Meraki Cloud Platform
- Meraki is a leader of cloud networking.
- When you unbox it and plug it in, you don't need to issue any configuration for the device. It's going to report back into a controller that's in the cloud and these devices will download their configs from the controller.
- This controller is completely managed by Cisco Meraki. You can provision it on the cloud.
- Types of devices
    ![](https://i.imgur.com/D3yOGgS.jpg)
    - MX: Firewall device
    - Meraki SM: Mobile device manager, control security settings on ipad and install apps in remote wide.
    - MC: Phones
- Advantages
    1. Affordable, and for SME to Enterprise Network.
    2. Site-to-site VPN management is amazing. Because they're all reporting into the same controller.
    3. Meraki Dashboard. One login where I can manage all of my clients in one place.
        - Traffic analytics
        - Deep packet inspection
        - Device specific data usage
        - Can configrure separate networks in one portal
        - Multiple clients: Choose which organization I want to work > network inside there.

- Meraki Sandbox
    ![](https://i.imgur.com/22dzU4O.png)
    - What network means in Meraki is a communication between two locations. ex. NY and London
    - Traffic analytics, Different applications it's connecting to.
    - Subnets inside my network?
        ![](https://i.imgur.com/MThAE2Z.png)
        - Configure different VLANs if you have multiple VLANs.
        - Routing, Site-to-site VPN, etc is all under Security & SD-WAN.

- Capabilities
    1. Dashboard API (REST API)
    2. Scanning API if you want to get metrics on 'Who's in your Wi-Fi network?', 'What devices are actualluy available and connecting to?'. => Marketing organization: Track customer movement on physical stores.
    3. Captive Portal API: when you see guest Wi-Fi presented with a page. Opt-in to emails or Facebook account.
    4. Webhooks: from dashboard, we can configure an alerting . Ex. When interface goes down, S2S VPN -> send a email
        - Or POST data to JSON endpoint to store data in sequel server, or stream it into a dashboard, or pass the data along with third party to get text messages.
        - Like in the Solarwinds, monitoring system support Meraki endpoints.

### Dashboard API
- How the Dashboard API can help you in a Meraki enterprise environment.
- Provisioning firewalls in multiple sites is laborious. But from automation, we can actually onboard our clients by creating organization, provisioning devices to each of these organizations, spinning up their individual networks, creating individual subnets, and provisioning read-only user account at the same time so they can log in and see the usage metrics.

1. On Meraki Dashboard Sandbox
    ![](https://i.imgur.com/Ulmlrgq.png)
    - Organization > Settings > Dashboard API access
    ![](https://i.imgur.com/VgP407M.png)
    - > Profile : Get a key.

2. Devnet API docs
    ![](https://i.imgur.com/Ai2lAfW.png)
    - Ex. Get Organizations
    ![](https://i.imgur.com/99nCZRe.png)
    - Ex2. Get Organization Networks
    ![](https://i.imgur.com/cF1Eizs.png)

- Remember it's REST API. POST, PUT, DELETE is all available for you.


### Setting up Postman for Meraki
![](https://i.imgur.com/M6Lq8RK.png)
- Store API Key in environment variable.
![](https://i.imgur.com/IU1W7on.png)
- Endpoint is always 'https://dashboard.meraki.com/api/vo'
- Purpose: GET a list of organizations that are available to our user account. 
- User account is come in the form of headers. 
![](https://i.imgur.com/qjWuNbh.png)
- Tests
- Parse out the results and make sure I'm storing the correct organization ID in an environment variable that I can store later.
- Returned below output
![](https://i.imgur.com/Py31wTk.png)
![](https://i.imgur.com/GiFqYLy.png)

- I got a list of organization ID. And the organizationID of 'DevNet Sandbox' is now stored in environment variable as we coded on the Test.

- Another Example
![](https://i.imgur.com/AKYMOg5.png)

- Setting up the Postman environment isn't difficult. All we need is the API key. If we want to specify Organization Name or Network Name while managing multiple clients, we can simply do it through environment variables.


### Python Automation with Meraki
- Click 'code' in Postman to generate Python Requests then you'll get below script.
![](https://i.imgur.com/1UeZXcY.png)
- Paste it on VScode.
- Changes
    - line 18: requests.request() -> requests.get(), add .json() to convert this to Python dictionary
    - line 2: Add 'import json'
    - line 20: Pretty up the print output. response -> Take the dictionary and convert it back to JSON and perform indentation, clean up. 
    - line 22~24: Extract the organization ID. I can extract whatever data I want in response.
- Result
![](https://i.imgur.com/UV2tN5V.png)


## 25. Automation with the Meraki Python SDK
### Exploring the Meraki SDK
- developer.cisco.com/meraki/
- Meraki Python SDK
    - Install SDK on your laptop.
    - pip install meraki-sdk==1.0.2
    - pip3 install meraki-sdk==1.0.2
    - It removes authentication, header, requests, and all the bothering works.

- Class Reference > Methods and capabilities of SDK
    - For example, VlansController
        - We can do get_network_vlans, get_network_vlans_enabled_state by just calling these methods.
        ![](https://i.imgur.com/KhJr5eK.png)
        ![](https://i.imgur.com/j2eHgHf.png)

### Start Scripting with the SDK
![](https://i.imgur.com/d6B7O4L.png)
- line 1: MerakiSdkClient is what sets up the whole connection.
- line 5: API token we generated in the portal that connects us to the Cisco DevNet Sandbox.
- line 6: This handles all authentication, storing token for all requests. Whenever we need to do those things, I can simply call the meraki object.
- line 8: Get the list of organizations in a variable. 'organizations' is a class, 'get_organizations()' is a method.
- line 10: Get one of these orgId.
- Result
![](https://i.imgur.com/eIzg0sq.png)


### Diving Deeper into the Meraki SDK
![](https://i.imgur.com/S1fzLBH.png)
![](https://i.imgur.com/eVk9NNS.png)
- line 14~15: Specify parameters in dictionary.
- Returned output: list of networks
![](https://i.imgur.com/YRTMonP.png)

- I want to get a list of VLANs from a specified network.
- Code
![](https://i.imgur.com/jVbt9Yj.png)
- Returned output: VLAN returned
![](https://i.imgur.com/2QhKQM0.png)


### Updating Configs with Meraki SDK
![](https://i.imgur.com/au5xSyU.png)
![](https://i.imgur.com/Af09Edu.png)
- 'updateNetworkVlan' is the body(for exmaple, name, description, id)
- UpdateNetworkVlanModel(): You need to create your own model here with correct parameters. 
- You can find how the model should look like on the Postman page. link: documenter.getpostman.com/view/897512/meraki-dashboard-api
![](https://i.imgur.com/9PoXytU.png)

![](https://i.imgur.com/P2NulZN.png)
- line 27: Create open dictionary.
- line 28~30: Add objects in dictionary.
- + line 35: pprint(result_vlan) (couldn't capture this)
- Result: VLAN name was changed to 'Knox wuz here'
![](https://i.imgur.com/H3fxypi.png)


## 26. Automate the Data Center with ACI
![](https://i.imgur.com/AV5vTnd.png)
- ACI configures itself based on our policies such as appropriate connections, accesses, and QoS.
- Application-centric policy
    - Core components of ACI.
    - We tell the data center and the network how to behave based on configurations(policy) we set on the applications.
- Nexus 9000 Fabric
    - Every connection is L3 connection.
    - Routes from one device to the next are shared with the IGP(Interior Gateway Protocol). It's like OSPF or EIGRP.
    - ACI uses is IS-IS protocol(underlay protocol). On top of the IS-IS, it runs VXLAN(overlay protocol). VXLAN carries VLAN and L2 information within the L3 packet itself. => Host applications can have L2 connections anywhere in the Data Center.
- APIC controller
    - Brain for all of the Data Center.
    - At least three APICs required.
    - Hardware: Cisco UCS servers
    - For users: Front end GUI
    - APIC is neither part of the data plane(data being passed between Nexus switches) or control plane(how these devices determine what routes to use when they need to form a traffic).
![](https://i.imgur.com/1KLpjol.png)
- Functions
    - Multi-tenent infrastructure: Because of VXLAN, IS-IS, APIC all working together, we can have multiple tenents using all this infrastructure without any overlap.
    - Tenents are major part how we configure our application policies. Application policies are attached to each tenents.
![](https://i.imgur.com/FTHuqok.png)
- Uni: Universe
- Multiple Tenents
    - Tenent common: Global policies and global rules
    - Tenent A: Each individual tenents
- Two fundamental components
    - Networking: VRFs, Bridge Domains, Subnets, External Networks(connection to other networks that are controlled outside ACI)
    - Policy: Application Profiles(=Application Network Profiles) is a container that holds all of the information below. EPGs, Contracts(ACI is whitelisting environment), and Filters.
![](https://i.imgur.com/7bWSDuj.png)
- Diagram of the flow of allowed traffic in Data Center for these applications.
- Endpoint Groups are allowed to communicate through the Contracts that are listed at the top.

### ACI Object Model
- Everything inside ACI is an object. 
    - Physical components: Switch, interface, adapter
    - Logical components: Valut, Policy, EPG
![](https://i.imgur.com/Ml2KS46.png)

- The Management Information Tree
- Root level: Uni. Universe
- Parent-Child relationship. Each child can have one parent. 
- Each individual object is a Managed Object(MO) because it's managed by ACI.
- Two names. Both are the unique way to identify structure.
    - Relative Name(RN): file.txt
    - Distinguished Name(DN): c:\Document\file.txt
        - Stringing RNs together. Like uni/app/APN.
- Each object belongs to a class. If we have multiple objects as a children of one particular parent, we would know childrens' data structure would be same. Because the class defines properties and methods for each objects.
![](https://i.imgur.com/mKioKMJ.png)
- I need to focus on the class and Parent class to know the strucutre of tree.
- Module and the Class. ACI typically combines these two. So 'fvAp' would be a target class you would hit if you're trying to hit Application Profile(Ap).
- Visore API Sandbox
    - sandboxapicdc.cisco.com/visore.html#/
    - username: admin, password: ciscopsdt
![](https://i.imgur.com/9KjLPWZ.png)
- Run query of 'uni' to find the Root. 
- Arrows in the dn helps us to naviate the path. 
- We can check on faults and health status of the 'uni'.
![](https://i.imgur.com/AR3aTrt.png)
- Show URL and response
    - URL we're trying to hit
    - Response JSON body. What the response structure's going to look like
    - There's a JSON and XML option.
![](https://i.imgur.com/YvyDwSD.png)
- We have a lot of tenents under 'uni'. Each of the tenents will have multiple EPGs, Broadcast Domains, Subnets, etc.
- Find your tenent. See the Relative Names picture above. Follow the Class name of the tenent. ctrl+f & 'fvTenant'. You can also see enant name is tn-(tenent name).

### ACI Programmability
- ACI three pillars: Fabric, controller, and policies.
- It follows an object models which builds Management Information Tree. Similar to Nexus design because it was built by same people.
- ACI Programmability Options
    1. REST API
        - Every click in ACI GUI is a REST API.
        - Right click on any object on ACI GUI, 'Save as...', Grab JSON out of it.
        - It's basically a GET request under the hood back in database.
        - You can hit APIC servers in HTTPS in a programmatic fashion.
    2. COBRA SDK
        - Need to install two components.
        - ACI-COBRA: This interacts directly with controllers setting configurations, getting data back. 
        - ACI-Model: This structures the data and gets data back on specific devices(objects).
    3. ACIToolkit (on Github)
        - Include SDK
        - Example scripts
        - Applications that directly interacts with ACI. Gives us extra monitorability and configurationabilities all for free.

- How structured REST API call works in APIC
    1. Hit Endpoint of our device
        - https://ip/api/[class or MO]/[name or DN].[json/xml]?[QueryString]
    2. Body
        - POST or PUT request, go to GUI and grab JSON and make changes.

### ACI Inspector
- Cisco ACI Sandbox Lab
    - sandboxapicdc.cisco.com
    - userneme/password: admin/ciscopsdt
![](https://i.imgur.com/XLchsfy.png)
- Dashboard is a web GUI that sits on top of API. Every single thing you do here is making an API request under the hood.
- Show API inspector: You can see all the API request that are going on inside this GUI. Each clicks are generating an API. Tenents, fabic, methods, requests, respose bodies, etc. are traced here.
- This is a tool to ease your process into ACI automation.

### ACI REST API with Postman
- Environment
    - url: Cisco DevNet Sandbox for APIC
    - port: 443
    - username/password
    - token: Gets set once we've logged in.

- APIC login task
    ![](https://i.imgur.com/y53sdJy.png)
    ![](https://i.imgur.com/QzSk6LY.png)
    - url: https://{{apic}}:{{port}}/api.aaaLogin.json
    - Headers: we're using application/json as our content type
    - Body: structure that ACI requires
    - Result
    ![](https://i.imgur.com/1Pf2gQV.png)
        - We get token from here and store it on the Environment variable.

- GET Tenants List
    ![](https://i.imgur.com/Jk73wVv.png)
    - Get list of all of the tenants from /api/class/fvTenant.
    - Result
    ![](https://i.imgur.com/IuWkl5q.png)

- GET Application List
    ![](https://i.imgur.com/yKHJfBO.png)
    - Result: list of application profiles with their Distinguish Name. 
    ![](https://i.imgur.com/evX4jEO.png)
    - Application profile is denoted by 'ap'. Tenents are denoted by 'tn'. Application profiles are always children of tenents.
    - When we're looking at the DN of the Application profile, we can not only gather the name of the application profile, but also what tenent that application belongs to.
    - If we follow exact same DN path, we can get this specific data for one of these Application profile.

- GET Application Profile
    ![](https://i.imgur.com/efVYeyu.png)
    - I'm getting an application 'Save_The_Planet' from a tenent 'Heroes'.
    - Because this is targeting a specific MO, we changed URL to be **mo** and **whole dn** of the managed object.
    - Result: Just getting that one result back, the 'Save_The_Planet'.
    ![](https://i.imgur.com/GOicAZA.png)

- POST 
    ![](https://i.imgur.com/cuM9UAw.png)
    - Update information(description) of the targeted object.
    - I need to specify the DN to make sure I'm targeting the right primary key.
    - Result: 200 OK
    - Result2: If I send the above GET Application Profile request again, I can see the description is updated to "Knox wuz here"
    ![](https://i.imgur.com/wkxMApx.png)

### ACI REST API with Python
- Automate the request.
![](https://i.imgur.com/DrR5Eyc.png)
![](https://i.imgur.com/j3V4CnM.png)
![](https://i.imgur.com/zXM4OwK.png)
- line 6~21: Login.
- line 20~21: Post this request and get the token back. Convert payload data to JSON. .json() is for JSON to Python Dictionary.
- line 26~28: Token -> Cookie. Cookie is a dictionary object so match the format.
- line 59~62: Print out the structured JSON data to verify that the description was updated.
- Result: Description is updated.
![](https://i.imgur.com/YkQGEMf.png)

### Easier ACI Automation with the Toolkit
- Documentation?
    - Official ACI toolkit documentation: acitoolkit.readthedocs.io
        - Object Model
        - How policy works
        - Statistics
        - Object references
        - How you can browse applications

- How to install ACI Toolkit?
    - Cisco ACI Toolkit code: github.com/datacenter/acitoolkit
        - Requirement: Python 2.7+
        - Run 
            - git clone https://github.com/datacenter/acitoolkit.git
            - cd acitoolkit
            - python setup.py install

- Applications in ACI Toolkit
    ![](https://i.imgur.com/iemzTv7.png)
- Sample codes are there too.
    ![](https://i.imgur.com/ihVNMib.png)


### Creating a Full Tenant with the ACI Toolkit
- ![](https://i.imgur.com/Ap92wWU.png)
- If we're going to create a tenent with Application Profile and Policy, we need to make sure all of these objects are created. 
- Also, all of the associations between objects need to be set
    ![](https://i.imgur.com/YzIrs1Y.png)
    ![](https://i.imgur.com/YhI7bbq.png)
    ![](https://i.imgur.com/mKb13Ya.png)
    - line 1: import * everything
    - line 11: Instanciating Session class object. This class object is stored in 'session'.
    - line 17: Tenant object, GET tenants with my session.
    - line 25: Creating new Tenant. Tenant name is 'Tenant_Name_Here' and it cannot have space.
    - line 31: We need to create objects below 'Tenant'. Instanciating AppProfile object. Name is 'Knoxs_app', I'm specifying the parent tenant will be the 'new_tenant' we created above. 
    - line 32: EPG is associated with Application Profile.
    - In order to build out connectivity for EPGs, we need to have the bridge domain contexts created.
    - line 34: Creating Context class. Name is 'Knoxs_VRF'. Parent is new_tenant even though it gets associated with the EPG. This creates both context and Bridge Domain.
    - line 38: We're associating that context to the bridge domain. And associating Bridge Domain to the EPG.
    - line 45: Commit the entire config data(Creating Tenant, Application Profile, Objects.) to APIC controller by using 'session.push_to_apic'. 
    - line 59~60: Delete the tenant from APIC controller to clear it up
    
### Running Sample Code from the ACI Toolkit
1. Sample Code 'aci-show-epg.py' in ACI Toolkit
![](https://i.imgur.com/oqMCCVN.png)
![](https://i.imgur.com/nqzHlfJ.png)
- All of the EPGs in human format and you can see what Tenant they belong to, what Appliation Profile they belong to, what's the EPG's name.

2. Sample Code 'aci-show-ip-int-brief.py' in ACI Toolkit.
![](https://i.imgur.com/Ik0r3A7.jpg)
- It's almost same with the output of 'show ip int brief'. Now it's coming from our Python scripts too.

+ A lot of samples like create, delete tenatns, etc.
![](https://i.imgur.com/j3IHjta.png)

### ACI Toolkit Applications
![](https://i.imgur.com/VxkIo8H.png)
- This has ability to Python scripting, connect to ACI and get a full topology of each of our tenants environments and diagram it out in a visual .png format.
- Read README.md and setup.txt first before using application. README has the command to run the Python application script.
- Command: We're running aci-diagram application.
![](https://i.imgur.com/Wq9oOUR.png)
- Result: You'll get a diagram for every teant.
![](https://i.imgur.com/pHcBbTs.png)


## 28. Automate the Campus with DNA Center Platform
### DNA Center Platform Capabilities
![](https://i.imgur.com/ir5LEHk.png)
- DNA Center is a network controller.
    - Software Define Networking, Intent Based Infrastructure. Policies are application accessible, QoS, security.
    - Intent-based Infrastructure requires Catalyst 9000. 
- DNA Center Applications
    ![](https://i.imgur.com/YMgnXhu.png)
    ![](https://i.imgur.com/Axx3nfR.png)
    1. Platform: Automation happens in Platforms via API.
    2. Design: Assign policies, infrastrucures on geographies.
    3. Policy: Set the policy, how we design application, segmentation. Let know your intent.
    4. Provision: Discovering new assets and automatically provisioning.
    5. Assurance: Monitoring, reporting, and troubleshooting

    ![](https://i.imgur.com/5hoPBGG.png)
    - Key to DNA-C is integrating with platforms that we're not designed to work together over API.
    - Intent APIs: Northbound API. Our intent and policies are coming from here. "Hey DNA Center I want network to behave this way"
    - Multivendor SDK: Southbound API. If you don't have Cat9000, you can have your intent work through DNA-C and access those devices via Southbound APIs.
    - Eastbound: Connect into other controllers like Meraki, Stealthwatch.
    - Westbound: Integration with other networking platforms that aren't controllers or Cisco solutions. ex. IPAM(IP address management, DHCP and DNS), Tableau/PowerBI(Dashboard. Telemetry and Analytics
    
### Exploring the Platform's API
- Sandbox DNA-C
    - sandboxdnac.cisco.com
    - username/pwd: devnetuser/Cisco123!
    
    - Platform > View the **API Catalog**
    - ex. POST request for Authentication API
        ![reference link](https://i.imgur.com/GYlitN3.png)
        ![](https://i.imgur.com/RvDcvqc.png)
        - POST request URL
        - Parameters
        - Code generation - Python, and other languages.
        - Try Now: Try out the script. 
        - You can test out each of the methods and run it, get the response back all in DNA-C Platform application.
    - Know Your Network
        - Sites, Networks, Devices, Clients
    - Operational Tools
        - Path Trace: Trace through the path of your network to get to specific IP address. And tell you where the network is failing if there's any issues there.
        - Network Discovery: Find and provision new devices. It contains the list of methods and requests you can use.

### Setting up the Platform(DNA-C) API Requests in Postman
- Environment variables
    ![](https://i.imgur.com/BMncoHa.png)
- Login and Authenticate to DNA-C
    ![](https://i.imgur.com/kIGV6BJ.png)
    - Grab the URL directly from the documentation above.
    - Two headers are required in the documentation. Authentication and Content-type.
    - On the tests, we're getting and storing token to environment variable.
- GET a list of network devices
![](https://i.imgur.com/50mNZIf.png)
- Code
![](https://i.imgur.com/vufrAXD.png)
![](https://i.imgur.com/pktBjJ6.png)

- Result: list of network devices and its information.
    - lastUpdateTime is in a form of Epoch.
    - To be more specific, we can use Querystring.
    - "id" key is set by DNA-C and stored in DNA-C device.
- GET Network device id
    ![](https://i.imgur.com/vOAmB0N.png)
    - GET just that network device using querystring
- GET all interfaces
    ![](https://i.imgur.com/tumOUth.png)
    - '/interface': List of every single interface on every single device across the entire DNA-C enterprise.
- GET specific network device's interfaces detail
    ![](https://i.imgur.com/REKTUCQ.png)
    - It goes into deeper directory to point the specific network device.

### DNA Center Platform Assurance Calls in Python
- Automation in Assurance
- What's the status of all of my wired and wireless devices and what their connection out is, how are we doing?

1. Go to DNA Center to see what APIs we have
2. Select 'Get Overall client'
    ![](https://i.imgur.com/7SU9Dio.png)
    - Check URL, Request headers, Request Query Parameters
3. Test it on Postman
![](https://i.imgur.com/8XeAuF9.png)
- Response
    ![](https://i.imgur.com/QtOIZRH.png)
    ![](https://i.imgur.com/rilTjIQ.png)
    - Response categorizes data based on three core categories that shows you what overall client health score is.
    - First is  "ALL", 82 clients. - Poor, fair
    - Second is "WIRED" health
    - Third is "WIRELESS".
- Ultimate Goal: Take out this massive output and simplify, print out the core results that I really care about.
    ![](https://i.imgur.com/rZlutbC.png)
    ![](https://i.imgur.com/yuneXUS.png)
    - line 37: Print out the total number of Clients
    - line 42: Iterate through ALL, WIRED and WIRELESS.
    - Result
        ![](https://i.imgur.com/kdARoiS.png)
        ![](https://i.imgur.com/5Q9dzCE.png)
        - Convert huge JSON data to clean, human readable format.

- Scenario #2: One particualr client having issue with Wireless items. So I want to see what WAP it's connected to, what WLC that WAP is reporting to.
    ![](https://i.imgur.com/QiwCd4X.png)
    ![](https://i.imgur.com/brgFEyc.png)
    - line 15: Taking MAC Address to my Querystring.
    - line 16: Querystring of empty timestamp queries. Use 'f' in front of the string so that we can specify MAC address within curly braces
    - Output
    ![](https://i.imgur.com/5PVmHoS.png)


## 29. Easier DNA Center Automation with the SDK
### Getting and Exlporing DNA Center SDK
- GET DNA Center SDK
    - pip install dnacentersdk
- Documentation for DNA-C SDK
    - dnacentersdk.readthedocs.io

### Authentication and Networks
- Sample Codes are at 'github.com/dataKnox/codesamples'
    ![](https://i.imgur.com/MZcjcp0.png)
    ![](https://i.imgur.com/QGlIKrF.png)
    - line 1: Importing api from dnacentersdk library
    - line 6: To build initial connection, login, token and session, is we use api module and call DNACenterAPI method. Storing whole session in 'dna' object.
    - line 13: Each site has its own id and the parent id to denote which site it belongs to.
    - line 14: Iterate all of the sites.
    - line 15: 'a7cbac~' is a Global ID. If the parent Id is the Id of Global, we know it's one of the higher level sites. Like Europe in the example. Below is the print out result of this line.
    - Result
    ![](https://i.imgur.com/uLfJe65.png)
- Key point
    - Easily make a new session, we don't need to target specific URLs anymore, not creating custom bodies, not sending session tokens. All of that is handled for us in a single line when we're using SDK.

### Devices
- Get List of devices in DNA Center
    ![](https://i.imgur.com/HXwpZju.png)
    - line 46: id doesn't have default value so id is required parameter. I'm putting '10cdb~' as my id parameter(which is a positional paramter, it knows whatever you're passing in here will go to 'id' field).
    - Result
        - line 35~43
    ![](https://i.imgur.com/0jpjppK.png)
        - line 45~47
    ![](https://i.imgur.com/QdWNLfG.png)

### Clients
- Get the health score of clients
    ![](https://i.imgur.com/3MwfPTX.png)
    - line 52: Get the calendare date in GMT time, time in GMT time. It's stored in int.
    - line 55: To get_overall_client_heath still needs timestamp in epoch time. We need to change int epoch_datetime to string.
    - SDK power: you can have simpler code, less code lines.
    - Result: Client's health
        ![](https://i.imgur.com/U5pILsG.png)

## 30. Automate Cisco Collaboration Platforms
### Explore the Collaboration Platform
- Jabber: Instant Messaging application extended desk phone to desktop and laptop.
- Webex Teams: Group chat collaboration tool. It has increadible REST API to Automate.
- IP phone: Every single phone had a little camera. So when you dial and if you want video phone call. Integrate into Webex Teams, Jabber using your laptop or other devices.
- Webex Devices
    - Webex Board: Wirelessly present, whiteboard, video or audio conference, annotate shared content, use Cisco Webex app to connect with virtual team members through the devices on their choice like laptop or mobile.
    - Webex DX Series: Little screen devices that has mostly all ability of Webex Board.
    - Webex Devices use REST X-API. It only supports xml. 
- Cisco Finesse
    - Large call center. Unified Contact Center Express. Application for people who are working on contact center. It give all of the info they need for communication, monitoring for tracking who's on call, etc.
    - Works with CCX API which is a REST API only supports xml.

- Cisco Unified Communications Manager(CUCM)
    - This runs VoIP operations within Cisco collaboration platform.
    - Automation in CUCM
        - To get user specific details(like  speed dial buttons) for specific usage case, we use UDS(User Data Services). It's a REST API that only supports xml. It's not an administrative API. We aren't making major config changes through UDS. 
        - If we want to make major config changes, we use AXL(Administrative XML Interface). It's not a REST-API. It's SOAP API. There's a Python library called PyAXL for using Python against AXL API.
 
### CUCM_Getting Started with AXL and Soap UI
- Soap API only uses xml.
- To use CUCM Sandbox
    - DevNet Sandbox > Collaboration > CUCM 11.5 > Make a reservation
    - Connect to Cisco VPN.
    - Go to the ip address of CUCM Publisher. ex. 10.10.20.1
    - Cisco CUCM page
    ![](https://i.imgur.com/PHv0PKR.png)
    - Go to Application > Plugins > Click Find > Download Cisco AXL Toolkit
- Cisco AXL page
    - Learn about AXL here.
    - developer.cisco.com/site/axl
- How Soap API work?
    ![](https://i.imgur.com/CvpF9p5.png)
    - How do we test Soap API? We use Soap UI.
    - We use Postman to test REST API.
    - Work similar to RPCs. 
        - Specify name of the method in the tag. ex. <getUser></getUser>
        - Parameter is sended like <name>John</name> between method tags.
        - Sending over http
        - Headers will include Basic Authentication.
- SoapUI
![](https://i.imgur.com/0Su6O9g.png)
- New SOAP Project > Initial WSDL: axlsqltoolkit(just downloaded)>schema>11.5>AXLAPI.wsdl > OK
![](https://i.imgur.com/TYWPy78.png)
- Thses are methods that are available to us in the AXL API interface.
- ex. getUser template
    - Basic template
    ![](https://i.imgur.com/F8N1N7l.png)
    - Modified template for our use
    ![](https://i.imgur.com/njsvbcg.png)
    - userid: username
    - uuid: id number that's in the database
    - Delete the optional part.
    - line 1~3: Basic SOAP headers
    - line 4: Body
    - line 5: Method
    - line 7: Parameter variable I'm sending within method.
    - CCMSERVERNAME -> Specify ip address: 10.10.20.1
    - Auth > Add New Authorization > Basic > username/password: administrator/ciscopsdt
    - Click the Play button
    - Result: User information that we've pointed.

### CUCM_Getting Started with UDS
- We can use user data services API of CUCM to get *basic info* from our device and CUCM instance.
- link: developer.cisco.com/site/user-data-services
- This API isn't big and it doesn't have much methods.
- Plural methods like 'users' typically doesn't need an authentication. Singular 'user' does require authentication because you're getting specific information of user.
- To get right access level, go to CUCM and User Management>Application User>Find>administrator> Add to Access Control Group>We need at least Standard CCM End Users
![](https://i.imgur.com/Xg3DziB.png)
- Postman
    1. GET Users
        ![](https://i.imgur.com/gdhUWYG.png)
        - URL: https://{{url}}/cucm-uds/[request you're looking for]
        - I'm getting 'users' on this request.
        - Authorization: username/pwd
        - Headers: This only works over xml.
        - Result: Get xml response back from 'GET-users' using UDS.
        ![](https://i.imgur.com/Rdft4Fv.png)
    2. GET Servers 
        ![](https://i.imgur.com/VxSMxFW.png)
        - Result: Got Publisher device and Subscriber device. We can see what servers are clustered in my CUCM.
    3. Get User user01 devices
        ![](https://i.imgur.com/0oW3ByK.png)
        - URL: https://{{url}}/cucm-uds/user **/user01/devices**

### Scripting for UDS
- UDS Get Users Python Users
- One different thing from AXL to UDS is we're using xml instead of JSON. 
    ![](https://i.imgur.com/HoSv9E1.png)
    ![](https://i.imgur.com/afEX1jC.png)
    - We've returned list of users back, parse it out from xml, turned it into Python dictionary and automated output with UDS Enpoint of CUCM programmatically.
    - line 2: Parse xml data and pretty it up.
    - line 5: Suppressing warnings from https endpoints using self-signed certificate.
    - Output
    ![](https://i.imgur.com/lOHL1Sz.png)


## 31. Automate Your Teamwork with Webex Teams
- Getting Started with Webex Teams
    - Webex Teams integrates perfectly with Webex Devices.
    - Webex Teams have REST API.
        - members: individual people invited via email
        - rooms: ex. Project Phoenix, Lunch politics, Random
        - messages: sends message to rooms
    - I can automate the creation of teams, members, joining members to the team, rooms and posting of messages. There's even different platform that can develop posting messages. 
    - Bots: A user account for platform. 
    - Automation in action
        ![](https://i.imgur.com/pw5Pkiz.png)
        - Goal: Letting us know this interface just went down. 
            - NX-API CLI or NX-API REST to gather data on this specific device. 
            - Once we collect the data, if an adverse condition evaluates to true, we then POST with a JSON data payload direct to the Webex Teams API right into the Room. So that I can be alerted.
            - Collaboration is Monitoring and Integrating platform.
- Documentation
    ![](https://i.imgur.com/j12WROw.png)
    - link: developer.webex.com
    - Bots
    - Admin APIs: Create administrative API calls like creating teams, rooms and users.
    - Widgets: Ask widget a question within the room. ex. Help Bot
    - Integrations: Extending Webex data to other platforms.
- Webex Teams
    ![](https://i.imgur.com/h2DYVmC.png)
    - Chatting, Connect to a device, Help Bot, Teams, Calls through Webex, Scedule.

### Creating Teams
- We need to generate our own token(valid for 12 hour).
    - developer.webex.com>Login>Documentation>REST API>Getting Started>Your Personal Access Token>Copy Token
- Code
    ![](https://i.imgur.com/x9MP9G5.png)
    - Create a team, room, and chat in order.
    - line 8: Always start with 'https://api.ciscospark.com/v1/', then put an endpoint which I want to target.
    - line 12: Body of team name
    - line 16: POST data to the url.
    - line 21: GET request to the teams url so we see the full body of data that's returned to us from the GET request.
    - line 26: But the only data we want from the teams is 'unique id' of it.

### Creating a Room
- Create a room 
    ![](https://i.imgur.com/GqALcS1.png)
    - line 29: Change the endpoint to 'rooms'.
    - line 30~33: pecify the name of the room and team id.
    - line 39: Get all of the rooms available to me, and also get room ID of 'CBT Rooms'. I need this to send a message.
    - Response from line 38 'print(room_post)' is below
    ![](https://i.imgur.com/eVB6TAK.png)

### Posting Messages to the Room
- Now we have team and room created, now I can just get room data directly by specifing a GET request to the rooms url, performed on line 39. We no longer need *teams* endpoint.
- We're using *team id* just to create *room* within that team, but now that the room is been created, I'm just issuing GET request straight to the '/rooms' url. So we're blocking those code lines.
    ![](https://i.imgur.com/4QjZFMY.png)
    - line 46: Change endpoint to '/messages'.
    - line 47: Specify roomId to let know what room am I posting this message in. 'text' is the text we want to send.

### There's an SDK for That
- Document
    - webexteamssdk.readthedocs.io
- How to use SDK?
    - Basically call the API object, module, method we're trying to work on.
- Code
    ![](https://i.imgur.com/m0sxgou.png)
    ![](https://i.imgur.com/4pjp83A.png)
    - line 1: import WebexTeamsAPI class.
    - line 6: *api* object has a lot of methods to use.
    - ![](https://i.imgur.com/plNSWct.png)
    - line 7: Getting a list of all of the *teams*. But the return is actual team object. So we need to use getattr(line 11) to specify the object and attribute of it.
    - line 12: Creating a team named 'CBT Team' if there's none. 
    - line 19: Get the details of me.
    - line 20: Get the list of all of the people.
    - line 21: Creating a person who has a role of 'administrator'. Got the id of 'admin' from line 24~28.
    - line 31~41: Creating a room, 'CBT Room'.
    - line 45: Create a message. 

## 32. Automate WAN Workloads with SD-WAN
- Cisco SD-WAN Platfor
    - Software Defined Network in WAN.
    ![](https://i.imgur.com/5YOojIM.png)
    - Data needs to report back to HQ. Phone need to connect to HQ too. From these works, jitter and latency comes so we need QoS, VPN.
    - Different Service Providers, SLAs, geographical regions, so customers had multiple connections from one branch to the next. 
        - DSL:High bandwidth link, less reliable.
        - Fiber: Lower bandwidth link, more reliable. MPLS.
        - LTE: Cellularlly.
    ![](https://i.imgur.com/S1FhzbY.png)
    - SD-WAN: One login to rule them all. Whole WAN infrastructure from a single login, provision new WAN devices, monitor uplink status, apply policy, that will **automatically route traffic over the best possible link to the right link destination.**
    - Main differnece: WAN routers now report to controller rather than waiting for you to login and directly configure it. 
    - Controller 
        - It collects data from edge routers and making decision on how to route traffic. 
        - Exists in cloud, DC, or HQ as long as routers have the ability to communicate to Controller.
        - Controller tell "you should send this type of traffic to this link, and this type of traffic to that type of link." based on your traffic. ex. voice traffic - jitter, latency priority QoS, database traffic - able to replicated over encrypted tunnel.
- Four components of SD-WAN
    ![](https://i.imgur.com/69ttiUI.png)
    - vManage: GUI frontend. API endpoint.
    - vSmart Controller: Control Plane. Implement policies for each routers and branches.
    - vEdge Router: Router devices that'll connect to vSmart and download their policies.
    - vBond: Zero-Touch Onboarding. Brings the device to where it's supposed to be when you plug in first time.

### Exploring the vManage API
- Documentation
    - developer.cisco.com/sdwan/learn > Docs: You'll see vManage REST APIs here.
    ![](https://i.imgur.com/kbTyzt1.png)
    - Most of the url endpoints always have root of *dataservice/[target you're trying to actually hit]*
    ![](https://i.imgur.com/R9S49ki.png)
    - Response output that you're expecting.

### Setting Up SD-WAN in Postman
- Pre-built Postman configuration for DevNet
    - github.com/ciscodevnet/postman-for-cisco-sd-wan
    - Clone the repo
    - Postman>File>Import>Two Open API JSON files from download
        1. Environment variable 
        2. Request library
- Steps setting up Postman
    1. Authentication
        ![](https://i.imgur.com/1kmifds.png)

        - Headers: application/x-www-form-urlencoded: Authenticating directly on a website and you're trying to parse out username and password from the body of html document.
        - Body: keys of username and password
        - Returning back: Cookies
    2. Fabric Devices
        ![](https://i.imgur.com/2fJ6fZR.png)
        - Postman uses cookie from 1.
        - Output: Header, column, data(vManage and device groups that belongs to this vManage)
    3. Device Templates
    4. Device Policy
        ![](https://i.imgur.com/aYd5vJV.png)
        - url: Go to dataservice root and go to vedge device. This is how we actually set configuration in the SD-WAN architecture.

### Scripting SD-WAN
- Code
    ![](https://i.imgur.com/UwlL7lF.png)
    ![](https://i.imgur.com/vFf6Vkl.png)
    - line 3~4: Suppress warnings from using self-signed certificate.
    - line 8: Authentication endpoint is *j_security_check*.
    - line 9~12: Creating login dictionary.
    - line 17: We're not converting login dictionary. We're leaving it as Python dictionary.
    - line 15: Build a session to grab a cookie and store it in session.
    - line 21: If the response is not 200 OK or we do get response text back, it's login failure.
    - line 29~~
    - line 29: Change url to device.
    - line 31: Using session object to get the device. It'll return the list of all devices.
    - line :I only print out few info I want.
    - Return
    ![](https://i.imgur.com/37T6syn.png)

## 33. Automate the Cisco Security Platform
### Cisco Security Platform
- Next Generation Firewall(NGFW)
    - Allow/Deny packets based on L3/L4 headers
    - Software Defined Solution 'Firepower': One login to manage all of our Firewalls and Policies
    - Firepower combines capabilities of NGFWs with Intrusion Prevention Devices. 
    - How do they work?
        ![](https://i.imgur.com/vOklF0a.png)
        - Two options
            - Firepower(FP) device like Cisco ASA. It has Cisco Firepower software on it. This has REST API but you need to download and manually install it, and it's specific to ASAs.
            - Dedicated Firepower Threat Defense(FTD). It has its own Firepower REST API. 
        - Firepower Management Center(FMC) is the brain of them. ASA and FTD have own GUI but you have to manage each devices individually. Where FMC is a centralized Software Defined Controller for your Firepower devices.
- How to create threat specific policies from the Firepower Management Center?
    - ISE: Identity Service Engine
        - Authentication services and stores for network client. It has REST API.
    - Umbrella
        - For remote and mobile users. 
        - A cient you install on someone's laptop and this uses DNS and others to redirect traffic to the Umbrella scanner. Scanner will determine whether or not the traffic this remote user is browsing is malicious or not. 
        - It doesn't use proxy so you don't have any real hit on performance or speed.
    - AMP
        - Advanced Malware Protection
        - Scanns Files as they come into the network. 
        - It exist on Firepower devices(FP) or computer, end user's device.
        - Uses Talos, Cisco's Threat Database. As new threats are added to the Talos, Cisco becomes aware of, AMP empowered devices will download these new threats and immediately begin scanning for them.
    - ThreatGrid
        - AMP detects an actual threat, it can send the file to ThreatGrid where ThreatGrid will actually execute the file just to learn what the malware's trying to do. 
        - It does that in a secure, Sandbox-like environment and won't interrupt any of your processes but it can analyze the malware's behavior.
    - All of these things have REST APIs.
    - Center of all these portfolio is FMC
    
### Exploring the FirePower Management Center API
- FMC REST API at FMC - API Explorer
    - Need to reserve to use this at DevNet Sandbox.
    ![](https://i.imgur.com/mnvh4vG.png)
    - See list of url endpoints.
    - Click the action you want to do(Delete, Put, Post, Get).
    - It'll show more information for that particular method call such as parameters.
    ![](https://i.imgur.com/hDskmxD.png)
    - There's an example of urls, request data and response data coming back to me.
    ![](https://i.imgur.com/yqhhTEt.png)
    - Test the API (ex. from copy and pasting example code) and export it to Python/Perl script.
    ![](https://i.imgur.com/CGGFpg6.png)

### FirePower Authentication in Postman
- Firepower environmnet variables
    - url, user, password, token(from login request) from Sandbox reservation.
    1. Login
        ![](https://i.imgur.com/B2CPKXX.png)
        - Authorization: user/pwd
        - Headers: {Content-Type: application/json}
        - Tests: Grabbing token from response header.
        - Response: 204 No Content & New token in environment variable 
    2. Get Networks
        ![](https://i.imgur.com/EpAD6ot.png)
        - Goal: Get full list of networks
        - url: Get the endpoint from API Explorer.
        - Headers: Token from step 1.
        - Result: Full list of networks from Firepower response.
            ![](https://i.imgur.com/N4hVgOH.png)
        - link: specific link to a network object.
    3. Application aware monitoring in FMC
        ![](https://i.imgur.com/Z5prtq3.png)
        - url: To applications node
        - Result: Specific applications that are being monitored.
        ![](https://i.imgur.com/pEE7kIB.png)

### FirePower Authentication in Python
- Automation, Scripting with FMC
- Code
    ![](https://i.imgur.com/iO8GG7d.png)
    - Goal: I want to get list of applications that are available for me.
    - line 4: Base url
    - line 5: Endpoint url
    - line 12: Concatenating base url and endpoint url. We're not parsing out JSON response body because we don't get anything back. We get '204 No Content' back.
    - line 14: Store login_response's response header.
    - line 16: Grab 'X-auth-access-token' key-value from the response header. That stores the token.
    - line 18: Update header with the token we got.
    - line 20: Send GET request to url that has applications endpoint. Change the endpoint if I want to grab other informations like *policy* or *device*. 
    - line 22: Expecting JSON body response.
    - Response
    ![](https://i.imgur.com/4GYKlV9.png)

### 34. Create Access Policies in FMC with Python
### Access Control Policy Overview
- Creating Access Policy(AP) Programmatically
    1. Login
        - DevNet>Security>Firepower Management Center>Reserve
    2. Create base policy
        - With default rules like malware scan, Intrusion Prevention
        - Policy ID: Unique identifier that stored in the FMC Database.
    3. Create Rules
        - Rules for that policy
        - Throughout each steps we'll get JSON response body, we'll print it out to verify that everything's working correctly.
    4. Delete policy
        - Clean up.
- Actual steps
    1. Find Access Policy in API Explorer
    ![](https://i.imgur.com/OSuXOuw.png)
        - Select POST request and see the parameters
        - See the Example Requests.
        ![](https://i.imgur.com/e28zmgh.png)
            - We need type, name and defaultAction.
            - This will give us an Access Policy with an Access Policy ID back. We can build additional rules and actions on there.
    2. Access Policy Rules
        - Find API for this at Firepower Management Center API on Cisco DevNet: developer.cisco.com/firepower/management-center
        - Down in the pave, Explore all learning labs>Threat centric access policies for FMC>Create access control rules
        - We're going to add rule of malware scanning
        ![](https://i.imgur.com/VgCx2SO.png)

### Creating the Policy
- Code
    ![](https://i.imgur.com/owsJDOu.png)
    ![](https://i.imgur.com/mzUxjZR.png)
    - line 8: base url
    - line 9: login url with */generatetoken* endpoint
    - line 15: In FMC we get the token back in the response header, it's not in the response body.
    - line 17~22: Parsing out the response header to get token.
    - line 25: Got it from API-Explorer. Domain ID after */domain/* is a unique id that's generated in Database of Firepower Management Center. Endpoint will be */policy/accesspolicies*
    - line 45: This way we get logging whenever intrusion policy event is triggered.
    - line 49: We're posting payload data of AccessPolicy(class), name, description and defaultAction.
    - line 52: Print out the response so I can read how the policy now looks in FMC Database.
    - line 54: Get the policy id.
    - line 56: Specify url for that endpoint for that exact policy. 

### Creating the Rules and Cleaning Up our Policy
- Code
    ![](https://i.imgur.com/kqXNAZq.png)
    ![](https://i.imgur.com/6PoS7Rk.png)
    - line 87~
    - line 58~: Creating rules inside the policy
    - line 74~: This 'IPv4-Private-All-RFC1918' object exists in FMC and this is how we know we're running scanning on all traffic that's sourced from our internal subnets.
    - line 81: It's a malware scanning file policy called 'New Malware'.
    - This entire collective makes up the rule that's tacking on to the policy we just created.
    - line 88: Post this rules to *rules_url*.
    - line 96: Delete the policy. We use policy url, not rules url. This is the one that ends with our specific policy id. 
    - 
- Summary
    - Access Policy안에서 Policy를 만들고, 그 Policy 안에서 Rule을 만들었다.

## 35. Automate Cisco ASA Firewalls
### Installing the REST API Package
- Note: ASA is not covered in DevNet exam blueprint.
- Steps
    1. Download REST API Package
        - https://bit.ly/2mtlyYk
    2. Enable TFTP server on your local machine and put API package on TFTP server
    3. Start!
- Console commands
    - en
    - show int ip brief
    - copy tftp://172.16.1.2/[file name] disk0: //Copy tftpboot file from tftp server(172.16.1.2) to disk0:
    - conf t// Issue a command to ASA know what this image does
    - (config)>rest-api image disk0:/[file name] // Telling ASA what path to find REST API software
    - (config)>http server enable //Enable the http server
    - (config)>http 0.0.0.0 0.0.0.0 outside //Traffic we're allowing in. Destined to outside interface cause it's just a lab environment
    - (config)>aaa authentication http console LOCAL //Specify authentication for http to be console local. This way we get prompted for local authentication.
    - (config)>route outside 0.0.0.0 0.0.0.0 172.16.1.1 1 //Gateway of address is 172.16.1.1, priority of 1
    - (config)>rest-api agent //Enable REST API
    - show rest-api agent // Resopond: REST API agent is currently enabled.
- REST API is activated on ASA device. You can check it on 'https://172.16.1.1/api/objects/networkobjects'.

### Exploring with On-Box Documentation
- How can I learn more about REST API? What are all the capabilities?
    ![](https://i.imgur.com/Lg9BU3P.png)
    - location: https://172.16.1.1/doc
    - This is the documentation lives on that box itself. It's almost same with the FMC.
    - Access different object, services that are available to us, programmatically from the REST API.
    - ex. Grab a list of interfaces, Monitoring, Routing, VPN, Full Backup, Full Restore
        - url, parameters, examples, test API and see the result, export it out in Python script

### Configuring a Postman Environment
- We have Programmatic access to ASA's REST API endpoint.
- To confirm API working on ASA
    ![](https://i.imgur.com/pg0aH1o.png)
    - Authorization: username/password
    - Return: We don't have any object cause it's lab environment.
    ![](https://i.imgur.com/U7fXhyV.png)
- GET Interfaces]
    ![](https://i.imgur.com/B47ZfX4.png)
    - Authorization: username/password
    - Return: All of the information on physical interfaces back. Including statistics, configuration items(ip address, net mask)
    - ![](https://i.imgur.com/zSnipJL.png)
- GET Routes
    - Goal: Get static routing configuration
    - Return: Static route configured for physical interface that I'm connected to. My outside interface. 
    ![](https://i.imgur.com/xrLvYNJ.png)
        - 'gateway' of 172.16.1.1
        - 'interface': what interface it's coming from.
- Monitoring: Device Status
    ![](https://i.imgur.com/dsemET4.png)
        - CPU utilization, memeory utilization, data utilization, packets being transfered.. 
- Monitoring: Connections in particular device
    ![](https://i.imgur.com/p5Of3iy.png)
        - Local IP address, destination ip, etc.
- We can generate code from Postman, too. It can be generated from ASA documentation or on Postman.

### Scripting Your ASA with Python
- Goal: Get the static routes.
    ![](https://i.imgur.com/jXdICsw.png)
    - line 6~9: Content-Type and Accept is default header so I don't need to specify them. But it's a good practice. Accept is the type of data we're accepting as a respond.
    - line14: Since we're accepting json, we need to change it to Python dictionary by .json(). 
    - Output: Static route of ASA device at 172.16.1.131.
    ![](https://i.imgur.com/ylQHPrA.png)


## 36. Automate Cisco Compute and More with UCS
### Introducing the Cisco UCS Platform
- Cisco UCS
    - Compute and Servers
    - Cisco Intersight: Cloud controller that can handle managing your servers in a secure, highly available method. REST API available.
    - UCS Manager: Single login where you can apply server policies for my centralized management point. 
        - It manages all Cisco UCS servers, just the Cisco platform. Provisioning, monitoring, policies. 
        - RPC-based XML API available. 
        - Similar to NETCONF but it's not NETCONF. 
        - SDK - UCSMSDK
        - Python exist for network engineers and data center interaction. But still lot of systems managers and admins are comfortable with Powershell. So, there's a PowerTool: Powershell module that does same thing with UCSMSDK.
    - UCS Director
        - Run entire data center regardless of what platform you work with. 
        - For example, We have NetApp storage+Dell servers+runs vCenter hypervisor+Network is running ACI with Nexus devices. UCS Director can manage all of it. It's platform agnostic offering that can manage all of the different Data Center platform vendors' offerings.
        - Has a REST API that interacts with XML.

### UCS Manager_PowerTool
- Sandbox>Data Center>UCS Management>Reserve
    ![](https://i.imgur.com/PtW1Hnn.png)
- Connect to VPN and you'll see the ip address of UCS Director and UCS Manager on the Sandbox.
- Download UCS PowerTool at https://bit.ly/31g4Kp2
- Applicaion: Cisco UCS Manager PowerTool
    ![](https://i.imgur.com/UeqkI1W.png)
    - 'Connect-Ucs': Connect to the UCS Powertool.
    - 'Get-UcsBlade': You can see all of the blade servers that's running on the UCS manager. 
    - 'Get-UcsBlade | Select-Object Dn, TotalMemory NumofCpus, Serial': Parse out the properties I like. 
    ![](https://i.imgur.com/gReCAjQ.png)
    - 'Get-Command -Module Cisco.UcsManager': See all of the different operations that are following PowerShell verbs like Set, Update, Remove, Add, Acknowledge, and more.
    - 'get-help watch-ucs': Shows you what UCS does, as well as syntax of how to actually write a command with watch-ucs.

### UCS Manager_Python UCSM SDK
- It's a RPC-XML based API so to simplify it, they're giving us a Python SDK to help us work with UCS Manager.
- On CLI
        - pip install ucsmsdk
- Code
    ![](https://i.imgur.com/NPmU3F5.png)
    - line 2: Instantiate UcsHandle class with passing three parameters in. Ip, username and pwd. 
    - line 3: Loggin into a handle object.
    - line 6: Query based on the class id. We're getting an organizational info.
    - line 10: Get a list of servers. 
    - line 13: Print out full servers.
    - line 16: Print out specific info of servers.
    - line 19: Query based on dn. Get specific dn and print out info of the specific server.

### UCS Director_Exploration and Postman
- UCS Director is a full DC controller.
- There's a compatibility matrix of what UCS Director can support.
- Programmability: REST API
- Steps
    - Log in UCS Director
    - Enable programmatic interactions: Edit my profile>Show Advanced Settings>Copy REST API access key, Enable Developer Menu(O)>Save
    - Log out
    - Log back in
    - Orchestration>REST API Browser>Search ex. 'user and group'> See the REST API and result xml you'll get from this API
    ![](https://i.imgur.com/BOJRVzS.png)
    - @Postman
    - Login
    ![](https://i.imgur.com/1d3FCbo.png)
        - opName: Operation name
        - Return: REST API key comming from that username. Subsequent calls that I make on Postman will automatically use that key. Codes in 'Tests' replaces quotes to nothing so that we get just the string from the key and sets environment variable key with it.
    - Get Users
    ![](https://i.imgur.com/W99OZop.png)
        - Make a call to the ip address of our UCS Director host.
        - Return: List of users that's connected to UCS Director. With this result, we can create more specific or targeted call to a specific user. 'loginName' tag is a user id.
    - Get User: Just the result of 'admin' user
    ![](https://i.imgur.com/Ex3iacR.png)
        - '/admin'
    - Create User
        - Need to post the correct payload(user type, login name, pwd, ...) to endpoint. It hashes out the password.
        - @Postman
        ![](https://i.imgur.com/H391OLt.png)
        - URL: Post payload to the endpoint '/user'
        - Header is specifing request key
        - Body is the sample payload I generated from UCS Director.
        - Result: User is created. Check it with 'Get User' request with using '/user/knox' endpoint.
    - Delete User
        ![](https://i.imgur.com/2FzkZjC.png)
        - I'm not specifying a DELETE request to the user Knox. I'm specifying a POST request to the user endpoint and posting XML payload which has 'DeleteUserConfig' method inside.
        - This behaves like SOAP API but it's a REST API. 