Advertisement
Guest User

Untitled

a guest
Jul 26th, 2017
773
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.94 KB | None | 0 0
  1. 11.5 Challenge
  2. Interacting with the Cisco IOS XE RESTCONF API
  3. Perform the following tasks to complete this challenge:
  4. Gather Data Using Postman
  5. Gather the full running configuration using Postman and ensure the response is in JSON format.
  6. Issue an API call to collect information for all leaf objects.
  7. Make an API call to gather all static routes configured on the system.
  8. Make an API call to gather all IP related configuration for interface loopback 100.
  9. Making Configuration Changes Using Postman
  10. Add the following static routes to the IOS XE router.
  11. 10.0.0.0 255.0.0.0 via 192.168.1.1
  12. 20.20.20.0 255.255.255.0 via 192.168.1.1
  13. 30.30.30.0 255.255.255.0 via 192.168.1.1
  14. 172.16.0.0 255.255.0.0 via 192.168.1.1
  15. 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.
  16. Troubleshoot Python Script Consuming RESTCONF API
  17. Navigate to the files/module2/lab5 directory and execute a script xe_rc_static_routes.py. Troubleshoot and fix this script.
  18. 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.
  19. Gather Data Using Postman
  20. Task 1
  21. 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
  22. Answer
  23. Verify that you have received an HTTP response code of 200 and the top part of your JSON object looks like:
  24. {
  25. "ned:native": {
  26. "device-model-version": {
  27. "major": "2",
  28. "minor": "1",
  29. "bug-fix": "0"
  30. },
  31. "boot": {},
  32. "hw-module": {},
  33. "module": {},
  34. "parser": {},
  35. "service": {
  36. "timestamps": {},
  37. "complete": {},
  38. "counters": {}
  39. },
  40. GET
  41. Authorization
  42. Content-Type
  43. Accept
  44. Authorization
  45. http://csrl kvfrestco nffapi/config/native
  46. Headers (3)
  47. Body
  48. Pre-request Script
  49. Tests
  50. application/vnd.yang.data+json
  51. application/vnd.yang.data+json
  52. Basic Y21zY286Y21zY28-
  53. Task 2
  54. Issue the same API call, but now collect information for all leaf (and children) objects. Hint: Use a query filter.
  55. Answer
  56. Verify that you have received an HTTP response code of 200, and the top part of your JSON object looks like:
  57. {
  58. "ned:native": {
  59. "device-model-version": {
  60. "major": "2",
  61. "minor": "1",
  62. "bug-fix": "0"
  63. },
  64. "boot": {},
  65. "hw-module": {},
  66. "module": {},
  67. "parser": {},
  68. "service": {
  69. "timestamps": {
  70. "debug": {
  71. "datetime": {
  72. "msec": [
  73. null
  74. ]
  75. }
  76. },
  77. "log": {
  78. "datetime": {
  79. "msec": [
  80. null
  81. ]
  82. }
  83. }
  84. },
  85. "complete": {},
  86. "counters": {}
  87. },
  88. GET
  89. Authorization
  90. Content-Type
  91. Accept
  92. Authorization
  93. http://csrl kv/restconf/a pi/config/native?deep
  94. Headers (3)
  95. Body
  96. Pre-request Script
  97. Tests
  98. application/vnd.yang.data+json
  99. application/vnd.yang.data+json
  100. Basic Y21zY286Y21zY28-
  101. Task 3
  102. 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.
  103. Answer
  104. Ensure that you receive a 200 response and your result looks like:
  105. {
  106. "ned:route": {
  107. "ip-route-interface-forwarding-list": [
  108. {
  109. "prefix": "0.0.0.0",
  110. "mask": "0.0.0.0",
  111. "fwd-list": [
  112. {
  113. "fwd": "192.168.1.1"
  114. }
  115. ]
  116. }
  117. ],
  118. "static": {}
  119. }
  120. }
  121. GET
  122. Authorization
  123. Content-Type
  124. Accept
  125. Authorization
  126. http://csrl kv/restconff a pi/config/native/i p/route?deep
  127. Headers (3)
  128. Body
  129. Pre-request Script
  130. Tests
  131. application/vnd.yang.data+json
  132. application/vnd.yang.data+json
  133. Basic Y21zY286Y21zY28=
  134. Task 4
  135. Make an API call to gather all IP-related configuration for interface loopback 100.
  136. Answer
  137. Ensure that you receive a 200 response and the top part of your JSON response looks like:
  138. {
  139. "ned:Loopback": {
  140. "name": 100,
  141. "cemoudp": {},
  142. "crypto": {},
  143. "encapsulation": {},
  144. "isis": {
  145. "authentication": {},
  146. "ipv6": {}
  147. },
  148. "lisp": {
  149. "mobility": {}
  150. },
  151. "snmp": {
  152. "trap": {
  153. "link-status-capas": {
  154. "link-status": {}
  155. }
  156. }
  157. },
  158. "bfd": {},
  159. "bandwidth": {},
  160. "cdp": {},
  161. "mpls": {
  162. "accounting": {},
  163. "ldp": {},
  164. "traffic-eng": {
  165. "flooding": {}
  166. }
  167. },
  168. "ip": {
  169. "access-group": {},
  170. "arp": {
  171. "inspection": {}
  172. },
  173. "address": {
  174. "primary": {
  175. "address": "10.100.1.1",
  176. "mask": "255.255.255.0"
  177. },
  178. "secondary": [
  179. {
  180. "address": "10.200.2.1"
  181. },
  182. {
  183. "address": "10.220.22.1"
  184. }
  185. ]
  186. },
  187. GET
  188. Authorization
  189. http://csrl kv/restco nf/a pi/config/native/interface/Loopback/100
  190. Headers (3)
  191. Body
  192. Pre-request Script
  193. e
  194. Content-Type
  195. Accept
  196. Authorization
  197. Tests
  198. application/vnd.yang.data+json
  199. application/vnd.yang.data+json
  200. Basic Y21zY286Y21zY28-
  201. Making Configuration Changes Using Postman
  202. Task 5
  203. Add the following static routes to the IOS XE router.
  204. 10.0.0.0 255.0.0.0 via 192.168.1.1
  205. 20.20.20.0 255.255.255.0 via 192.168.1.1
  206. 30.30.30.0 255.255.255.0 via 192.168.1.1
  207. 172.16.0.0 255.255.0.0 via 192.168.1.1
  208. Note
  209. Ensure you use PATCH.
  210. Answer
  211. Verify that you have received an HTTP response code of 204 and that see you the new routes in the running configuration:
  212. PATCH
  213. Authorization
  214. Content-Type
  215. Accept
  216. Authorization
  217. key
  218. http://csrl kv/restconff a pilconfig/native/ip/route
  219. Headers (3)
  220. Body •
  221. Pre-request Script
  222. Tests
  223. application/vnd.yang.data+json
  224. application/vnd.yang.data+json
  225. Basic Y21zY286Y21zY28=
  226. value
  227. Postman HTTP PATCH body:
  228. {
  229. "ned:route": {
  230. "ip-route-interface-forwarding-list": [
  231. {
  232. "prefix": "10.0.0.0",
  233. "mask": "255.0.0.0",
  234. "fwd-list": [
  235. {
  236. "fwd": "192.168.1.1"
  237. }
  238. ]
  239. },
  240. {
  241. "prefix": "20.20.20.0",
  242. "mask": "255.255.255.0",
  243. "fwd-list": [
  244. {
  245. "fwd": "192.168.1.1"
  246. }
  247. ]
  248. },
  249. {
  250. "prefix": "30.30.30.0",
  251. "mask": "255.255.255.0",
  252. "fwd-list": [
  253. {
  254. "fwd": "192.168.1.1"
  255. }
  256. ]
  257. },
  258. {
  259. "prefix": "172.16.0.0",
  260. "mask": "255.255.0.0",
  261. "fwd-list": [
  262. {
  263. "fwd": "192.168.1.1"
  264. }
  265. ]
  266. }
  267. ]
  268. }
  269. }
  270. Ensure that the routes have been added to the router.
  271. csr1kv# show run | inc route
  272. ip route 0.0.0.0 0.0.0.0 192.168.1.1
  273. ip route 10.0.0.0 255.0.0.0 192.168.1.1
  274. ip route 20.20.20.0 255.255.255.0 192.168.1.1
  275. ip route 30.30.30.0 255.255.255.0 192.168.1.1
  276. ip route 172.16.0.0 255.255.0.0 192.168.1.1
  277. csr1kv#
  278. Task 6
  279. 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.
  280. Note
  281. Remember that you currently must exit configuration mode after making a change for it to be readable via RESTCONF (critical for troubleshooting and testing).
  282. Answer
  283. Verify that you have received an HTTP response code of 204 and that see the new configuration looks like:
  284. =8ZAZlZA98ZAZIZA
  285. uosÇeaep•îu puA/uoueD!1dde
  286. Isanbal-aad
  287. • KP08
  288. (E) suapeaH
  289. 001 110/r.dug
  290. uouezuoqany
  291. . uouezuol_pnv
  292. Lnd
  293. Postman HTTP PUT body:
  294. {
  295. "ned:Loopback": {
  296. "name": 100,
  297. "ip": {
  298. "address": {
  299. "primary": {
  300. "address": "100.100.1.1",
  301. "mask": "255.255.255.0"
  302. }
  303. }
  304. }
  305. }
  306. }
  307. Ensure that the secondary IP addresses have been removed.
  308. csr1kv# show run int lo100
  309. Building configuration...
  310.  
  311. Current configuration : 66 bytes
  312. !
  313. interface Loopback100
  314. ip address 100.100.1.1 255.255.255.0
  315. end
  316. Troubleshoot Python Script Consuming RESTCONF API
  317. Task 7
  318. 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.
  319. Note
  320. 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.
  321. Answer
  322. You should see this output:
  323. $ python xe_rc_static_routes.py
  324. API Call #1 - DISPLAY CURRENT ROUTES with NEXT-HOPS
  325. -----------
  326. Status Code: 200
  327. {
  328. "ned:route": {
  329. "ip-route-interface-forwarding-list": [
  330. {
  331. "fwd-list": [
  332. {
  333. "fwd": "192.168.1.1"
  334. }
  335. ],
  336. "prefix": "0.0.0.0",
  337. "mask": "0.0.0.0"
  338. },
  339. {
  340. "fwd-list": [
  341. {
  342. "fwd": "192.168.1.1"
  343. }
  344. ],
  345. "prefix": "10.0.0.0",
  346. "mask": "255.0.0.0"
  347. },
  348. {
  349. "fwd-list": [
  350. {
  351. "fwd": "192.168.1.1"
  352. }
  353. ],
  354. "prefix": "20.20.20.0",
  355. "mask": "255.255.255.0"
  356. },
  357. {
  358. "fwd-list": [
  359. {
  360. "fwd": "192.168.1.1"
  361. }
  362. ],
  363. "prefix": "30.30.30.0",
  364. "mask": "255.255.255.0"
  365. },
  366. {
  367. "fwd-list": [
  368. {
  369. "fwd": "192.168.1.1"
  370. }
  371. ],
  372. "prefix": "172.16.0.0",
  373. "mask": "255.255.0.0"
  374. }
  375. ],
  376. "static": {}
  377. }
  378. }
  379. API Call #2 - ADD ROUTES
  380. -----------
  381. Status Code: 204
  382. API Call #3 - VERIFY ROUTES ADDED
  383. -----------
  384. Status Code: 200
  385. {
  386. "ned:route": {
  387. "ip-route-interface-forwarding-list": [
  388. {
  389. "fwd-list": [
  390. {
  391. "fwd": "192.168.1.1"
  392. }
  393. ],
  394. "prefix": "0.0.0.0",
  395. "mask": "0.0.0.0"
  396. },
  397. {
  398. "fwd-list": [
  399. {
  400. "fwd": "192.168.1.1"
  401. }
  402. ],
  403. "prefix": "10.0.0.0",
  404. "mask": "255.0.0.0"
  405. },
  406. {
  407. "fwd-list": [
  408. {
  409. "fwd": "192.168.1.1"
  410. }
  411. ],
  412. "prefix": "20.20.20.0",
  413. "mask": "255.255.255.0"
  414. },
  415. {
  416. "fwd-list": [
  417. {
  418. "fwd": "192.168.1.1"
  419. }
  420. ],
  421. "prefix": "30.30.30.0",
  422. "mask": "255.255.255.0"
  423. },
  424. {
  425. "fwd-list": [
  426. {
  427. "fwd": "192.168.1.1"
  428. }
  429. ],
  430. "prefix": "50.40.40.0",
  431. "mask": "255.255.255.0"
  432. },
  433. {
  434. "fwd-list": [
  435. {
  436. "fwd": "192.168.1.1"
  437. }
  438. ],
  439. "prefix": "172.16.0.0",
  440. "mask": "255.255.0.0"
  441. }
  442. ],
  443. "static": {}
  444. }
  445. }
  446. You should also verify that the route has been added to the CLI:
  447. csr1kv# show run | inc route
  448. ip route 0.0.0.0 0.0.0.0 192.168.1.1
  449. ip route 10.0.0.0 255.0.0.0 192.168.1.1
  450. ip route 20.20.20.0 255.255.255.0 192.168.1.1
  451. ip route 30.30.30.0 255.255.255.0 192.168.1.1
  452. ip route 50.40.40.0 255.255.255.0 192.168.1.1
  453. ip route 172.16.0.0 255.255.0.0 192.168.1.1
  454. Solution Script:
  455. #!/usr/bin/env python
  456.  
  457. import requests
  458. import json
  459. import time
  460. import collections
  461. from requests.auth import HTTPBasicAuth
  462. requests.packages.urllib3.disable_warnings()
  463.  
  464. if __name__ == "__main__":
  465.  
  466. auth = HTTPBasicAuth('cisco', 'cisco')
  467. headers = {
  468. 'Accept': 'application/vnd.yang.data+json',
  469. 'Content-Type': 'application/vnd.yang.data+json'
  470. }
  471.  
  472. print 'API Call #1 - DISPLAY CURRENT ROUTES with NEXT-HOPS'
  473. print '-----------'
  474.  
  475. url = 'http://csr1kv/restconf/api/config/native/ip/route?deep'
  476. response = requests.get(url, verify=False, headers=headers, auth=auth)
  477.  
  478. print 'Status Code: ' + str(response.status_code)
  479. if response.text:
  480. parse = json.loads(response.text)
  481. print json.dumps(parse, indent=4)
  482.  
  483. time.sleep(2)
  484.  
  485. print 'API Call #2 - ADD ROUTES'
  486. print '-----------'
  487.  
  488. url = 'http://csr1kv/restconf/api/config/native/ip/route'
  489.  
  490. route = collections.OrderedDict()
  491.  
  492. route['prefix'] = '50.40.40.0'
  493. route['mask'] = '255.255.255.0'
  494. route['fwd-list'] = [{'fwd': '192.168.1.1'}]
  495. ip_route_list = [route]
  496.  
  497. routes_to_add = {
  498. "ned:route": {
  499. "ip-route-interface-forwarding-list": ip_route_list
  500. }
  501. }
  502.  
  503. response = requests.patch(url, data=json.dumps(routes_to_add), verify=False, headers=headers, auth=auth)
  504.  
  505. print 'Status Code: ' + str(response.status_code)
  506. if response.text:
  507. parse = json.loads(response.text)
  508. print json.dumps(parse, indent=4)
  509.  
  510. time.sleep(2)
  511.  
  512. print 'API Call #3 - VERIFY ROUTES ADDED'
  513. print '-----------'
  514.  
  515. url = 'http://csr1kv/restconf/api/config/native/ip/route?deep'
  516. response = requests.get(url, verify=False, headers=headers, auth=auth)
  517.  
  518. print 'Status Code: ' + str(response.status_code)
  519. if response.text:
  520. parse = json.loads(response.text)
  521. print json.dumps(parse, indent=4)
  522. Ensure that the following configuration commands exist on the device:
  523. ip route 10.0.0.0 255.0.0.0 192.168.1.1
  524. ip route 20.20.20.0 255.255.255.0 192.168.1.1
  525. ip route 30.30.30.0 255.255.255.0 192.168.1.1
  526. ip route 50.40.40.0 255.255.255.0 192.168.1.1
  527. ip route 172.16.0.0 255.255.0.0 192.168.1.1
  528. Ensure loopback100 looks like this:
  529. interface loopback100
  530. ip address 100.100.1.1 255.255.255.0
  531. By ensuring these commands don’t exist for loopback100:
  532. ip address 10.200.2.1 255.255.255.0 secondary
  533. ip address 10.220.22.1 255.255.255.0 secondary
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540. 11.5 Challenge
  541. Interacting with the Cisco IOS XE NETCONF API
  542. 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.
  543. You will complete the following tasks:
  544. SSH to your CSR1KV and verify that you do not have a Loopback200 interface.
  545. Navigate to files/module2/lab6 to review and execute the xe_nc_configure_interface.py script.
  546. 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.
  547. Create a filter within the get_filter variable to print the configuration of just Loopback200 and uncomment the appropriate print statements.
  548. Ensure that the appropriate configuration commands exist on the device.
  549. Consume NETCONF with Python
  550. Task 1
  551. SSH to your CSR1KV and verify that you do not have a Loopback200 interface.
  552. Answer
  553. csr1kv# show run int lo200
  554. ^
  555. % Invalid input detected at '^' marker.
  556.  
  557. csr1kv#
  558. Task 2
  559. Navigate to files/module2/lab6, then review and execute the xe_nc_configure_interface.py script.
  560. Note
  561. This is a working script that configured a loopback200 interface with a primary IP address and secondary address.
  562. Answer
  563. csr1kv# show run int lo200
  564. Building configuration...
  565.  
  566. Current configuration : 111 bytes
  567. !
  568. interface Loopback200
  569. ip address 9.9.9.9 255.255.255.0
  570. secondary ip address 10.200.20.1 255.255.255.0
  571. end
  572. Task 3
  573. 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.
  574. Answer
  575. csr1kv# show run int lo200
  576. Building configuration...
  577.  
  578. Current configuration : 158 bytes
  579. !
  580. interface Loopback200
  581. ip address 9.9.9.9 255.255.255.0 secondary
  582. ip address 11.11.11.1 255.255.255.0 secondary
  583. ip address 10.200.20.1 255.255.255.0
  584. end
  585.  
  586. csr1kv#
  587. Task 4
  588. Create a filter within the get_filter variable to print the configuration of just Loopback200. Uncomment the appropriate print statements.
  589. Note
  590. You can use Postman and perform GETs using XML encoding for help (if needed).
  591. Answer
  592. $ python xe_nc_configure_interface.py
  593. <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
  594. <native xmlns="http://cisco.com/ns/yang/ned/ios">
  595. <interface>
  596. <Loopback>
  597. <name>200</name>
  598. <ip>
  599. <address>
  600. <primary>
  601. <address>10.200.20.1</address>
  602. <mask>255.255.255.0</mask>
  603. </primary>
  604. <secondary>
  605. <address>9.9.9.9</address>
  606. <mask>255.255.255.0</mask>
  607. <secondary/>
  608. </secondary>
  609. <secondary>
  610. <address>11.11.11.1</address>
  611. <mask>255.255.255.0</mask>
  612. <secondary/>
  613. </secondary>
  614. </address>
  615. </ip>
  616. </Loopback>
  617. </interface>
  618. </native>
  619. </data>
  620. Solution Script:
  621. #!/usr/bin/env python
  622.  
  623. from lxml import etree
  624. from ncclient import manager
  625.  
  626. if __name__ == "__main__":
  627.  
  628. with manager.connect(host='csr1kv', port=830, username='cisco', password='cisco',
  629. hostkey_verify=False, device_params={'name': 'csr'},
  630. allow_agent=False, look_for_keys=False) as device:
  631.  
  632.  
  633. nc_filter = """
  634. <config>
  635. <native xmlns="http://cisco.com/ns/yang/ned/ios">
  636. <interface>
  637. <Loopback>
  638. <name>200</name>
  639. <ip>
  640. <address>
  641. <primary>
  642. <address>10.200.20.1</address>
  643. <mask>255.255.255.0</mask>
  644. </primary>
  645. <secondary>
  646. <address>9.9.9.9</address>
  647. <mask>255.255.255.0</mask>
  648. <secondary/>
  649. </secondary>
  650. <secondary>
  651. <address>11.11.11.1</address>
  652. <mask>255.255.255.0</mask>
  653. <secondary/>
  654. </secondary>
  655. </address>
  656. </ip>
  657. </Loopback>
  658. </interface>
  659. </native>
  660. </config>
  661. """
  662.  
  663. nc_reply = device.edit_config(target='running', config=nc_filter)
  664.  
  665. get_filter = """
  666. <native xmlns="http://cisco.com/ns/yang/ned/ios">
  667. <interface>
  668. <Loopback>
  669. <name>200</name>
  670. </Loopback>
  671. </interface>
  672. </native>
  673. """
  674.  
  675. # UNCOMMENT THE NEXT TWO LINES FOR THE LAB AFTER YOU
  676. # GET THE NEW SECONDARY IP WORKING
  677. nc_get_reply = device.get(('subtree', get_filter))
  678. print etree.tostring(nc_get_reply.data_ele, pretty_print=True)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement