11#!/usr/bin/env python
22"""
3- This Python script leverages RESTCONF to:
3+ This Python script leverages RESTCONF to:
44 - retrieve a list of interfaces on a device
5- - ask the user for the interface to configure
6- - displays the interface IP information
7- - asks user for new IP information
8- - updates the IP address on the interface
9- - displays the final IP information on the interface
10-
11- This script has been tested with Python 3.5, however may work with other versions.
12-
13- This script targets the RESTCONF DevNet Sandbox that leverages a CSR1000v as
14- a target. To execute this script against a different device, update the variables
15- that list the connectivity, management interface, and url_base for RESTCONF.
16-
17- Requirements:
18- Python
5+ - ask the user for the interface to configure
6+ - displays the interface IP information
7+ - asks user for new IP information
8+ - updates the IP address on the interface
9+ - displays the final IP information on the interface
10+
11+ This script has been tested with Python 3.5, however may work with other versions.
12+
13+ This script targets the RESTCONF DevNet Sandbox that leverages a CSR1000v as
14+ a target. To execute this script against a different device, update the variables
15+ that list the connectivity, management interface, and url_base for RESTCONF.
16+
17+ Requirements:
18+ Python
1919 - requests
20-
21-
20+
21+
2222"""
2323
2424import json
25- import requests
25+ import requests
2626import sys
2727from collections import OrderedDict
28+ import urllib3
29+
30+ # Disable SSL Warnings
31+ urllib3 .disable_warnings (urllib3 .exceptions .InsecureRequestWarning )
32+
2833
2934# These variables target the RESTCONF Always-On Sandbox hosted by Cisco DevNet
3035HOST = 'ios-xe-mgmt.cisco.com'
3136PORT = '9443'
3237USER = 'root'
33- PASS = 'C!sc0123 '
38+ PASS = 'D_Vay!_10& '
3439
35- # Identifies the interface on the device used for management access
40+ # Identifies the interface on the device used for management access
3641# Used to ensure the script isn't used to update the IP leveraged to manage device
3742MANAGEMENT_INTERFACE = "GigabitEthernet1"
3843
3944# Create the base URL for RESTCONF calls
40- url_base = "http ://{h}:{p}/api " .format (h = HOST , p = PORT )
45+ url_base = "https ://{h}:{p}/restconf " .format (h = HOST , p = PORT )
4146
42- # Identify yang+json as the data formats
43- headers = {'Content-Type' : 'application/vnd. yang. data+json' ,
44- 'Accept' : 'application/vnd. yang. data+json' }
47+ # Identify yang+json as the data formats
48+ headers = {'Content-Type' : 'application/yang- data+json' ,
49+ 'Accept' : 'application/yang- data+json' }
4550
4651
47- # Function to retrieve the list of interfaces on a device
52+ # Function to retrieve the list of interfaces on a device
4853def get_configured_interfaces ():
49- url = url_base + "/running/ interfaces?deep "
54+ url = url_base + "/data/ietf- interfaces:interfaces "
5055
5156 # this statement performs a GET on the specified url
52- response = requests .get (url ,
57+ response = requests .get (url ,
5358 auth = (USER , PASS ),
54- headers = headers ,
59+ headers = headers ,
5560 verify = False
5661 )
5762
5863 # return the json as text
5964 return response .json ()["ietf-interfaces:interfaces" ]["interface" ]
6065
6166
62- # Used to configure the IP address on an interface
63- def configure_ip_address (interface , ip ):
64- # RESTCONF URL for specific interface
65- url = url_base + "/running/ interfaces/interface/ {i}" .format (i = interface )
66-
67+ # Used to configure the IP address on an interface
68+ def configure_ip_address (interface , ip ):
69+ # RESTCONF URL for specific interface
70+ url = url_base + "/data/ietf- interfaces:interfaces /interface= {i}" .format (i = interface )
71+
6772 # Create the data payload to reconfigure IP address
6873 # Need to use OrderedDicts to maintain the order of elements
6974 data = OrderedDict ([('ietf-interfaces:interface' ,
7075 OrderedDict ([
7176 ('name' , interface ),
72- ('type' , 'ianaift :ethernetCsmacd' ),
77+ ('type' , 'iana-if-type :ethernetCsmacd' ),
7378 ('ietf-ip:ipv4' ,
7479 OrderedDict ([
7580 ('address' , [OrderedDict ([
@@ -80,43 +85,46 @@ def configure_ip_address(interface, ip):
8085 ])
8186 ),
8287 ])
83- )])
88+ )])
8489
8590 # Use PUT request to update data
86- response = requests .put (url ,
87- auth = (USER , PASS ),
88- headers = headers ,
89- verify = False ,
91+ response = requests .put (url ,
92+ auth = (USER , PASS ),
93+ headers = headers ,
94+ verify = False ,
9095 json = data
9196 )
9297 print (response .text )
9398
9499
95- # Retrieve and print the current configuration of an interface
100+ # Retrieve and print the current configuration of an interface
96101def print_interface_details (interface ):
97- url = url_base + "/running/ interfaces/interface/ {i}?deep " .format (i = interface )
102+ url = url_base + "/data/ietf- interfaces:interfaces /interface= {i}" .format (i = interface )
98103
99104 # this statement performs a GET on the specified url
100- response = requests .get (url ,
105+ response = requests .get (url ,
101106 auth = (USER , PASS ),
102- headers = headers ,
107+ headers = headers ,
103108 verify = False
104109 )
105110
106111 intf = response .json ()["ietf-interfaces:interface" ]
107- # return the json as text
112+ # return the json as text
108113 print ("Name: " , intf ["name" ])
109- print ("IP Address: " , intf ["ietf-ip:ipv4" ]["address" ][0 ]["ip" ], "/" ,
110- intf ["ietf-ip:ipv4" ]["address" ][0 ]["netmask" ])
114+ try :
115+ print ("IP Address: " , intf ["ietf-ip:ipv4" ]["address" ][0 ]["ip" ], "/" ,
116+ intf ["ietf-ip:ipv4" ]["address" ][0 ]["netmask" ])
117+ except KeyError :
118+ print ("IP Address: UNCONFIGURED" )
111119 print ()
112120
113121 return (intf )
114122
115123
116- # Ask the user to select an interface to configure. Ensures input is valid and
124+ # Ask the user to select an interface to configure. Ensures input is valid and
117125# NOT the management interface
118126def interface_selection (interfaces ):
119- # Ask User which interface to configure
127+ # Ask User which interface to configure
120128 sel = input ("Which Interface do you want to configure? " )
121129
122130 # Validate interface input
@@ -126,35 +134,35 @@ def interface_selection(interfaces):
126134 print (" " + MANAGEMENT_INTERFACE + " is used for management." )
127135 print (" Choose another Interface" )
128136 sel = input ("Which Interface do you want to configure? " )
129-
137+
130138 return (sel )
131139
132-
133- # Asks the user to provide an IP address and Mask. Data is NOT validated.
134- def get_ip_info ():
140+
141+ # Asks the user to provide an IP address and Mask. Data is NOT validated.
142+ def get_ip_info ():
135143 # Ask User for IP and Mask
136144 ip = {}
137145 ip ["address" ] = input ("What IP address do you want to set? " )
138146 ip ["mask" ] = input ("What Subnet Mask do you want to set? " )
139147 return (ip )
140148
141-
149+
142150def main ():
143151 """
144152 Simple main method calling our function.
145- """
146- # Get a List of Interfaces
153+ """
154+ # Get a List of Interfaces
147155 interfaces = get_configured_interfaces ()
148156
149157 print ("The router has the following interfaces: \n " )
150- for interface in interfaces :
158+ for interface in interfaces :
151159 print (" * {name:25}" .format (name = interface ["name" ]))
152160
153161 print ("" )
154162
155- # Ask User which interface to configure
163+ # Ask User which interface to configure
156164 selected_interface = interface_selection (interfaces )
157- print (selected_interface )
165+ print (selected_interface )
158166
159167 # Print Starting Interface Details
160168 print ("Starting Interface Configuration" )
@@ -163,13 +171,13 @@ def main():
163171 # As User for IP Address to set
164172 ip = get_ip_info ()
165173
166- # Configure interface
174+ # Configure interface
167175 configure_ip_address (selected_interface , ip )
168-
176+
169177 # Print Ending Interface Details
170178 print ("Ending Interface Configuration" )
171179 print_interface_details (selected_interface )
172-
180+
173181
174182if __name__ == '__main__' :
175- sys .exit (main ())
183+ sys .exit (main ())
0 commit comments