Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 11.5 Challenge
- Interacting with the Cisco IOS XE RESTCONF API
- Perform the following tasks to complete this challenge:
- Gather Data Using Postman
- Gather the full running configuration using Postman and ensure the response is in JSON format.
- Issue an API call to collect information for all leaf objects.
- Make an API call to gather all static routes configured on the system.
- Make an API call to gather all IP related configuration for interface loopback 100.
- Making Configuration Changes Using Postman
- Add the following static routes to the IOS XE router.
- 10.0.0.0 255.0.0.0 via 192.168.1.1
- 20.20.20.0 255.255.255.0 via 192.168.1.1
- 30.30.30.0 255.255.255.0 via 192.168.1.1
- 172.16.0.0 255.255.0.0 via 192.168.1.1
- Without using any DELETE APIs, ensure that Loopback 100 has a primary address of 100.100.1.1/255.255.255.0 and does not have any secondary addresses.
- Troubleshoot Python Script Consuming RESTCONF API
- Navigate to the files/module2/lab5 directory and execute a script xe_rc_static_routes.py. Troubleshoot and fix this script.
- All IOS-XE labs for this course are using the Cisco Cloud Services Router 1000V (CSR 1KV) running version 16.3. The RESTCONF interface is not yet supported by Cisco TAC.
- Gather Data Using Postman
- Task 1
- Gather the full running configuration using Postman and ensure that the response is in JSON format.Use the following URL: http://csr1kv/restconf/api/config/native
- Answer
- Verify that you have received an HTTP response code of 200 and the top part of your JSON object looks like:
- {
- "ned:native": {
- "device-model-version": {
- "major": "2",
- "minor": "1",
- "bug-fix": "0"
- },
- "boot": {},
- "hw-module": {},
- "module": {},
- "parser": {},
- "service": {
- "timestamps": {},
- "complete": {},
- "counters": {}
- },
- GET
- Authorization
- Content-Type
- Accept
- Authorization
- http://csrl kvfrestco nffapi/config/native
- Headers (3)
- Body
- Pre-request Script
- Tests
- application/vnd.yang.data+json
- application/vnd.yang.data+json
- Basic Y21zY286Y21zY28-
- Task 2
- Issue the same API call, but now collect information for all leaf (and children) objects. Hint: Use a query filter.
- Answer
- Verify that you have received an HTTP response code of 200, and the top part of your JSON object looks like:
- {
- "ned:native": {
- "device-model-version": {
- "major": "2",
- "minor": "1",
- "bug-fix": "0"
- },
- "boot": {},
- "hw-module": {},
- "module": {},
- "parser": {},
- "service": {
- "timestamps": {
- "debug": {
- "datetime": {
- "msec": [
- null
- ]
- }
- },
- "log": {
- "datetime": {
- "msec": [
- null
- ]
- }
- }
- },
- "complete": {},
- "counters": {}
- },
- GET
- Authorization
- Content-Type
- Accept
- Authorization
- http://csrl kv/restconf/a pi/config/native?deep
- Headers (3)
- Body
- Pre-request Script
- Tests
- application/vnd.yang.data+json
- application/vnd.yang.data+json
- Basic Y21zY286Y21zY28-
- Task 3
- Make an API call to gather all static routes that are configured on the system. Make sure you can see all next-hops for each route.
- Answer
- Ensure that you receive a 200 response and your result looks like:
- {
- "ned:route": {
- "ip-route-interface-forwarding-list": [
- {
- "prefix": "0.0.0.0",
- "mask": "0.0.0.0",
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ]
- }
- ],
- "static": {}
- }
- }
- GET
- Authorization
- Content-Type
- Accept
- Authorization
- http://csrl kv/restconff a pi/config/native/i p/route?deep
- Headers (3)
- Body
- Pre-request Script
- Tests
- application/vnd.yang.data+json
- application/vnd.yang.data+json
- Basic Y21zY286Y21zY28=
- Task 4
- Make an API call to gather all IP-related configuration for interface loopback 100.
- Answer
- Ensure that you receive a 200 response and the top part of your JSON response looks like:
- {
- "ned:Loopback": {
- "name": 100,
- "cemoudp": {},
- "crypto": {},
- "encapsulation": {},
- "isis": {
- "authentication": {},
- "ipv6": {}
- },
- "lisp": {
- "mobility": {}
- },
- "snmp": {
- "trap": {
- "link-status-capas": {
- "link-status": {}
- }
- }
- },
- "bfd": {},
- "bandwidth": {},
- "cdp": {},
- "mpls": {
- "accounting": {},
- "ldp": {},
- "traffic-eng": {
- "flooding": {}
- }
- },
- "ip": {
- "access-group": {},
- "arp": {
- "inspection": {}
- },
- "address": {
- "primary": {
- "address": "10.100.1.1",
- "mask": "255.255.255.0"
- },
- "secondary": [
- {
- "address": "10.200.2.1"
- },
- {
- "address": "10.220.22.1"
- }
- ]
- },
- GET
- Authorization
- http://csrl kv/restco nf/a pi/config/native/interface/Loopback/100
- Headers (3)
- Body
- Pre-request Script
- e
- Content-Type
- Accept
- Authorization
- Tests
- application/vnd.yang.data+json
- application/vnd.yang.data+json
- Basic Y21zY286Y21zY28-
- Making Configuration Changes Using Postman
- Task 5
- Add the following static routes to the IOS XE router.
- 10.0.0.0 255.0.0.0 via 192.168.1.1
- 20.20.20.0 255.255.255.0 via 192.168.1.1
- 30.30.30.0 255.255.255.0 via 192.168.1.1
- 172.16.0.0 255.255.0.0 via 192.168.1.1
- Note
- Ensure you use PATCH.
- Answer
- Verify that you have received an HTTP response code of 204 and that see you the new routes in the running configuration:
- PATCH
- Authorization
- Content-Type
- Accept
- Authorization
- key
- http://csrl kv/restconff a pilconfig/native/ip/route
- Headers (3)
- Body •
- Pre-request Script
- Tests
- application/vnd.yang.data+json
- application/vnd.yang.data+json
- Basic Y21zY286Y21zY28=
- value
- Postman HTTP PATCH body:
- {
- "ned:route": {
- "ip-route-interface-forwarding-list": [
- {
- "prefix": "10.0.0.0",
- "mask": "255.0.0.0",
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ]
- },
- {
- "prefix": "20.20.20.0",
- "mask": "255.255.255.0",
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ]
- },
- {
- "prefix": "30.30.30.0",
- "mask": "255.255.255.0",
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ]
- },
- {
- "prefix": "172.16.0.0",
- "mask": "255.255.0.0",
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ]
- }
- ]
- }
- }
- Ensure that the routes have been added to the router.
- csr1kv# show run | inc route
- ip route 0.0.0.0 0.0.0.0 192.168.1.1
- ip route 10.0.0.0 255.0.0.0 192.168.1.1
- ip route 20.20.20.0 255.255.255.0 192.168.1.1
- ip route 30.30.30.0 255.255.255.0 192.168.1.1
- ip route 172.16.0.0 255.255.0.0 192.168.1.1
- csr1kv#
- Task 6
- Without using any DELETE APIs, ensure that Loopback 100 has a primary address of 100.100.1.1/255.255.255.0 and does not have any secondary addresses.
- Note
- Remember that you currently must exit configuration mode after making a change for it to be readable via RESTCONF (critical for troubleshooting and testing).
- Answer
- Verify that you have received an HTTP response code of 204 and that see the new configuration looks like:
- =8ZAZlZA98ZAZIZA
- uosÇeaep•îu puA/uoueD!1dde
- Isanbal-aad
- • KP08
- (E) suapeaH
- 001 110/r.dug
- uouezuoqany
- . uouezuol_pnv
- Lnd
- Postman HTTP PUT body:
- {
- "ned:Loopback": {
- "name": 100,
- "ip": {
- "address": {
- "primary": {
- "address": "100.100.1.1",
- "mask": "255.255.255.0"
- }
- }
- }
- }
- }
- Ensure that the secondary IP addresses have been removed.
- csr1kv# show run int lo100
- Building configuration...
- Current configuration : 66 bytes
- !
- interface Loopback100
- ip address 100.100.1.1 255.255.255.0
- end
- Troubleshoot Python Script Consuming RESTCONF API
- Task 7
- Navigate to the files/module2/lab5 directory and execute a script xe_rc_static_routes.py. Troubleshoot and fix this script so that it address the expected static routes.
- Note
- Do not forget you can print the API response with the statement print response.text, i.e. you do not need to use the json module for the print statement when troubleshooting.
- Answer
- You should see this output:
- $ python xe_rc_static_routes.py
- API Call #1 - DISPLAY CURRENT ROUTES with NEXT-HOPS
- -----------
- Status Code: 200
- {
- "ned:route": {
- "ip-route-interface-forwarding-list": [
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "0.0.0.0",
- "mask": "0.0.0.0"
- },
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "10.0.0.0",
- "mask": "255.0.0.0"
- },
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "20.20.20.0",
- "mask": "255.255.255.0"
- },
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "30.30.30.0",
- "mask": "255.255.255.0"
- },
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "172.16.0.0",
- "mask": "255.255.0.0"
- }
- ],
- "static": {}
- }
- }
- API Call #2 - ADD ROUTES
- -----------
- Status Code: 204
- API Call #3 - VERIFY ROUTES ADDED
- -----------
- Status Code: 200
- {
- "ned:route": {
- "ip-route-interface-forwarding-list": [
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "0.0.0.0",
- "mask": "0.0.0.0"
- },
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "10.0.0.0",
- "mask": "255.0.0.0"
- },
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "20.20.20.0",
- "mask": "255.255.255.0"
- },
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "30.30.30.0",
- "mask": "255.255.255.0"
- },
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "50.40.40.0",
- "mask": "255.255.255.0"
- },
- {
- "fwd-list": [
- {
- "fwd": "192.168.1.1"
- }
- ],
- "prefix": "172.16.0.0",
- "mask": "255.255.0.0"
- }
- ],
- "static": {}
- }
- }
- You should also verify that the route has been added to the CLI:
- csr1kv# show run | inc route
- ip route 0.0.0.0 0.0.0.0 192.168.1.1
- ip route 10.0.0.0 255.0.0.0 192.168.1.1
- ip route 20.20.20.0 255.255.255.0 192.168.1.1
- ip route 30.30.30.0 255.255.255.0 192.168.1.1
- ip route 50.40.40.0 255.255.255.0 192.168.1.1
- ip route 172.16.0.0 255.255.0.0 192.168.1.1
- Solution Script:
- #!/usr/bin/env python
- import requests
- import json
- import time
- import collections
- from requests.auth import HTTPBasicAuth
- requests.packages.urllib3.disable_warnings()
- if __name__ == "__main__":
- auth = HTTPBasicAuth('cisco', 'cisco')
- headers = {
- 'Accept': 'application/vnd.yang.data+json',
- 'Content-Type': 'application/vnd.yang.data+json'
- }
- print 'API Call #1 - DISPLAY CURRENT ROUTES with NEXT-HOPS'
- print '-----------'
- url = 'http://csr1kv/restconf/api/config/native/ip/route?deep'
- response = requests.get(url, verify=False, headers=headers, auth=auth)
- print 'Status Code: ' + str(response.status_code)
- if response.text:
- parse = json.loads(response.text)
- print json.dumps(parse, indent=4)
- time.sleep(2)
- print 'API Call #2 - ADD ROUTES'
- print '-----------'
- url = 'http://csr1kv/restconf/api/config/native/ip/route'
- route = collections.OrderedDict()
- route['prefix'] = '50.40.40.0'
- route['mask'] = '255.255.255.0'
- route['fwd-list'] = [{'fwd': '192.168.1.1'}]
- ip_route_list = [route]
- routes_to_add = {
- "ned:route": {
- "ip-route-interface-forwarding-list": ip_route_list
- }
- }
- response = requests.patch(url, data=json.dumps(routes_to_add), verify=False, headers=headers, auth=auth)
- print 'Status Code: ' + str(response.status_code)
- if response.text:
- parse = json.loads(response.text)
- print json.dumps(parse, indent=4)
- time.sleep(2)
- print 'API Call #3 - VERIFY ROUTES ADDED'
- print '-----------'
- url = 'http://csr1kv/restconf/api/config/native/ip/route?deep'
- response = requests.get(url, verify=False, headers=headers, auth=auth)
- print 'Status Code: ' + str(response.status_code)
- if response.text:
- parse = json.loads(response.text)
- print json.dumps(parse, indent=4)
- Ensure that the following configuration commands exist on the device:
- ip route 10.0.0.0 255.0.0.0 192.168.1.1
- ip route 20.20.20.0 255.255.255.0 192.168.1.1
- ip route 30.30.30.0 255.255.255.0 192.168.1.1
- ip route 50.40.40.0 255.255.255.0 192.168.1.1
- ip route 172.16.0.0 255.255.0.0 192.168.1.1
- Ensure loopback100 looks like this:
- interface loopback100
- ip address 100.100.1.1 255.255.255.0
- By ensuring these commands don’t exist for loopback100:
- ip address 10.200.2.1 255.255.255.0 secondary
- ip address 10.220.22.1 255.255.255.0 secondary
- 11.5 Challenge
- Interacting with the Cisco IOS XE NETCONF API
- Now that you have tested RESTCONF, you need to compare it to working with NETCONF as they are both model-driven from YANG models on IOS XE. This lab challenges you to configure an IOS XE device using NETCONF and the ncclient.
- You will complete the following tasks:
- SSH to your CSR1KV and verify that you do not have a Loopback200 interface.
- Navigate to files/module2/lab6 to review and execute the xe_nc_configure_interface.py script.
- Update the script so that another secondary IP address gets configured on the device. Use the IP address of 11.11.11.1/24 for the new secondary address.
- Create a filter within the get_filter variable to print the configuration of just Loopback200 and uncomment the appropriate print statements.
- Ensure that the appropriate configuration commands exist on the device.
- Consume NETCONF with Python
- Task 1
- SSH to your CSR1KV and verify that you do not have a Loopback200 interface.
- Answer
- csr1kv# show run int lo200
- ^
- % Invalid input detected at '^' marker.
- csr1kv#
- Task 2
- Navigate to files/module2/lab6, then review and execute the xe_nc_configure_interface.py script.
- Note
- This is a working script that configured a loopback200 interface with a primary IP address and secondary address.
- Answer
- csr1kv# show run int lo200
- Building configuration...
- Current configuration : 111 bytes
- !
- interface Loopback200
- ip address 9.9.9.9 255.255.255.0
- secondary ip address 10.200.20.1 255.255.255.0
- end
- Task 3
- Update the script so that another secondary IP address gets configured on the device. Use the IP address of 11.11.11.1/24 for the new secondary address.
- Answer
- csr1kv# show run int lo200
- Building configuration...
- Current configuration : 158 bytes
- !
- interface Loopback200
- ip address 9.9.9.9 255.255.255.0 secondary
- ip address 11.11.11.1 255.255.255.0 secondary
- ip address 10.200.20.1 255.255.255.0
- end
- csr1kv#
- Task 4
- Create a filter within the get_filter variable to print the configuration of just Loopback200. Uncomment the appropriate print statements.
- Note
- You can use Postman and perform GETs using XML encoding for help (if needed).
- Answer
- $ python xe_nc_configure_interface.py
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
- <native xmlns="http://cisco.com/ns/yang/ned/ios">
- <interface>
- <Loopback>
- <name>200</name>
- <ip>
- <address>
- <primary>
- <address>10.200.20.1</address>
- <mask>255.255.255.0</mask>
- </primary>
- <secondary>
- <address>9.9.9.9</address>
- <mask>255.255.255.0</mask>
- <secondary/>
- </secondary>
- <secondary>
- <address>11.11.11.1</address>
- <mask>255.255.255.0</mask>
- <secondary/>
- </secondary>
- </address>
- </ip>
- </Loopback>
- </interface>
- </native>
- </data>
- Solution Script:
- #!/usr/bin/env python
- from lxml import etree
- from ncclient import manager
- if __name__ == "__main__":
- with manager.connect(host='csr1kv', port=830, username='cisco', password='cisco',
- hostkey_verify=False, device_params={'name': 'csr'},
- allow_agent=False, look_for_keys=False) as device:
- nc_filter = """
- <config>
- <native xmlns="http://cisco.com/ns/yang/ned/ios">
- <interface>
- <Loopback>
- <name>200</name>
- <ip>
- <address>
- <primary>
- <address>10.200.20.1</address>
- <mask>255.255.255.0</mask>
- </primary>
- <secondary>
- <address>9.9.9.9</address>
- <mask>255.255.255.0</mask>
- <secondary/>
- </secondary>
- <secondary>
- <address>11.11.11.1</address>
- <mask>255.255.255.0</mask>
- <secondary/>
- </secondary>
- </address>
- </ip>
- </Loopback>
- </interface>
- </native>
- </config>
- """
- nc_reply = device.edit_config(target='running', config=nc_filter)
- get_filter = """
- <native xmlns="http://cisco.com/ns/yang/ned/ios">
- <interface>
- <Loopback>
- <name>200</name>
- </Loopback>
- </interface>
- </native>
- """
- # UNCOMMENT THE NEXT TWO LINES FOR THE LAB AFTER YOU
- # GET THE NEW SECONDARY IP WORKING
- nc_get_reply = device.get(('subtree', get_filter))
- print etree.tostring(nc_get_reply.data_ele, pretty_print=True)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement