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 and 2.7 , 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
27+ from argparse import ArgumentParser
2728from collections import OrderedDict
2829
2930# These variables target the RESTCONF Always-On Sandbox hosted by Cisco DevNet
3031HOST = 'ios-xe-mgmt.cisco.com'
3132PORT = '9443'
3233USER = 'root'
33- PASS = 'C!sc0123 '
34+ PASS = 'D_Vay!_10& '
3435
35- # Identifies the interface on the device used for management access
36- # Used to ensure the script isn't used to update the IP leveraged to manage device
36+ # Identifies the interface on the device used for management access
37+ # Used to ensure the script isn't used to update the IP leveraged to
38+ # manage device
3739MANAGEMENT_INTERFACE = "GigabitEthernet1"
3840
3941# Create the base URL for RESTCONF calls
40- url_base = "http://{h}:{p}/api" .format (h = HOST , p = PORT )
42+ url_base = "{proto}://{h}:{p}/restconf/api"
43+
44+ do_input = None
4145
42- # Identify yang+json as the data formats
46+ # Identify yang+json as the data formats
4347headers = {'Content-Type' : 'application/vnd.yang.data+json' ,
4448 'Accept' : 'application/vnd.yang.data+json' }
4549
4650
47- # Function to retrieve the list of interfaces on a device
48- def get_configured_interfaces ():
49- url = url_base + "/running/interfaces?deep"
51+ # Function to retrieve the list of interfaces on a device
52+ def get_configured_interfaces (args ):
53+ url = url_base .format (proto = args .proto , h = args .host ,
54+ p = args .port ) + "/running/interfaces?deep"
5055
5156 # this statement performs a GET on the specified url
52- response = requests .get (url ,
53- auth = (USER , PASS ),
54- headers = headers ,
57+ response = requests .get (url ,
58+ auth = (args . username , args . password ),
59+ headers = headers ,
5560 verify = False
56- )
61+ )
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 (args , interface , ip ):
69+ # RESTCONF URL for specific interface
70+ url = url_base .format (proto = args .proto , h = args .host , p = args .port ) + \
71+ "/running/interfaces/interface/{i}" .format (i = interface )
72+
6773 # Create the data payload to reconfigure IP address
6874 # Need to use OrderedDicts to maintain the order of elements
6975 data = OrderedDict ([('ietf-interfaces:interface' ,
70- OrderedDict ([
71- ('name' , interface ),
72- ('type' , 'ianaift :ethernetCsmacd' ),
73- ('ietf-ip:ipv4' ,
74- OrderedDict ([
76+ OrderedDict ([
77+ ('name' , interface ),
78+ ('type' , 'iana-if-type :ethernetCsmacd' ),
79+ ('ietf-ip:ipv4' ,
80+ OrderedDict ([
7581 ('address' , [OrderedDict ([
76- ('ip' ,ip ["address" ]),
77- ('netmask' ,ip ["mask" ])
78- ])]
82+ ('ip' , ip ["address" ]),
83+ ('netmask' , ip ["mask" ])
84+ ])]
7985 )
80- ])
81- ),
82- ])
83- )])
86+ ])
87+ ),
88+ ])
89+ )])
8490
8591 # Use PUT request to update data
86- response = requests .put (url ,
87- auth = (USER , PASS ),
88- headers = headers ,
89- verify = False ,
92+ response = requests .put (url ,
93+ auth = (args . username , args . password ),
94+ headers = headers ,
95+ verify = False ,
9096 json = data
91- )
97+ )
9298 print (response .text )
9399
94100
95- # Retrieve and print the current configuration of an interface
96- def print_interface_details (interface ):
97- url = url_base + "/running/interfaces/interface/{i}?deep" .format (i = interface )
101+ # Retrieve and print the current configuration of an interface
102+ def print_interface_details (args , interface ):
103+ url = url_base .format (proto = args .proto , h = args .host , p = args .port ) + \
104+ "/running/interfaces/interface/{i}?deep" .format (i = interface )
98105
99106 # this statement performs a GET on the specified url
100- response = requests .get (url ,
101- auth = (USER , PASS ),
102- headers = headers ,
107+ response = requests .get (url ,
108+ auth = (args . username , args . password ),
109+ headers = headers ,
103110 verify = False
104- )
111+ )
105112
106113 intf = response .json ()["ietf-interfaces:interface" ]
107- # return the json as text
108- print ("Name: " , intf ["name" ])
109- print ("IP Address: " , intf ["ietf-ip:ipv4" ]["address" ][0 ]["ip" ], "/" ,
110- intf ["ietf-ip:ipv4" ]["address" ][0 ]["netmask" ])
111- print ()
114+ # return the json as text
115+ print ("Name: {}" . format ( intf ["name" ]) )
116+ print ("IP Address: {} / {}" . format ( intf ["ietf-ip:ipv4" ]["address" ][0 ]["ip" ],
117+ intf ["ietf-ip:ipv4" ]["address" ][0 ]["netmask" ]) )
118+ print ('' )
112119
113120 return (intf )
114121
115122
116- # Ask the user to select an interface to configure. Ensures input is valid and
123+ # Ask the user to select an interface to configure. Ensures input is valid and
117124# NOT the management interface
118- def interface_selection (interfaces ):
119- # Ask User which interface to configure
120- sel = input ("Which Interface do you want to configure? " )
125+ def interface_selection (args , interfaces ):
126+ # Ask User which interface to configure
127+ sel = do_input ("Which Interface do you want to configure? " )
121128
122129 # Validate interface input
123130 # Must be an interface on the device AND NOT be the Management Interface
124- while sel == MANAGEMENT_INTERFACE or not sel in [intf ["name" ] for intf in interfaces ]:
131+ while sel == args . interface or not sel in [intf ["name" ] for intf in interfaces ]:
125132 print ("INVALID: Select an available interface." )
126- print (" " + MANAGEMENT_INTERFACE + " is used for management." )
133+ print (" " + args . interface + " is used for management." )
127134 print (" Choose another Interface" )
128- sel = input ("Which Interface do you want to configure? " )
129-
135+ sel = do_input ("Which Interface do you want to configure? " )
136+
130137 return (sel )
131138
132-
133- # Asks the user to provide an IP address and Mask. Data is NOT validated.
134- def get_ip_info ():
139+
140+ # Asks the user to provide an IP address and Mask. Data is NOT validated.
141+ def get_ip_info ():
135142 # Ask User for IP and Mask
136143 ip = {}
137- ip ["address" ] = input ("What IP address do you want to set? " )
138- ip ["mask" ] = input ("What Subnet Mask do you want to set? " )
144+ ip ["address" ] = do_input ("What IP address do you want to set? " )
145+ ip ["mask" ] = do_input ("What Subnet Mask do you want to set? " )
139146 return (ip )
140147
141-
148+
142149def main ():
150+ global do_input
151+
143152 """
144153 Simple main method calling our function.
145- """
146- # Get a List of Interfaces
147- interfaces = get_configured_interfaces ()
154+ """
155+
156+ parser = ArgumentParser (description = 'Select options.' )
157+ parser .add_argument ('--host' , type = str , default = HOST ,
158+ help = 'The device IP or hostname' )
159+ parser .add_argument ('-u' , '--username' , type = str ,
160+ default = USER , help = 'Username for the device' )
161+ parser .add_argument ('-p' , '--password' , type = str ,
162+ default = PASS , help = 'Password for the device' )
163+ parser .add_argument ('--port' , type = int , default = PORT ,
164+ help = 'RESTCONF port for the device' )
165+ parser .add_argument ('--use-ssl' , dest = 'proto' , action = 'store_true' ,
166+ default = False , help = 'Use SSL to connect; default is no encryption' )
167+ parser .add_argument ('-i' , '--mgmt-interface' , dest = 'interface' , type = str ,
168+ default = MANAGEMENT_INTERFACE , help = 'Management interface of the device' )
169+ args = parser .parse_args ()
170+
171+ if args .proto :
172+ args .proto = 'https'
173+ else :
174+ args .proto = 'http'
175+
176+ try :
177+ do_input = raw_input
178+ except NameError :
179+ do_input = input
180+
181+ # Get a List of Interfaces
182+ interfaces = get_configured_interfaces (args )
148183
149184 print ("The router has the following interfaces: \n " )
150- for interface in interfaces :
185+ for interface in interfaces :
151186 print (" * {name:25}" .format (name = interface ["name" ]))
152187
153188 print ("" )
154189
155- # Ask User which interface to configure
156- selected_interface = interface_selection (interfaces )
157- print (selected_interface )
190+ # Ask User which interface to configure
191+ selected_interface = interface_selection (args , interfaces )
192+ print (selected_interface )
158193
159194 # Print Starting Interface Details
160195 print ("Starting Interface Configuration" )
161- print_interface_details (selected_interface )
196+ print_interface_details (args , selected_interface )
162197
163198 # As User for IP Address to set
164199 ip = get_ip_info ()
165200
166- # Configure interface
167- configure_ip_address (selected_interface , ip )
168-
201+ # Configure interface
202+ configure_ip_address (args , selected_interface , ip )
203+
169204 # Print Ending Interface Details
170205 print ("Ending Interface Configuration" )
171- print_interface_details (selected_interface )
172-
206+ print_interface_details (args , selected_interface )
207+
173208
174209if __name__ == '__main__' :
175- sys .exit (main ())
210+ sys .exit (main ())
0 commit comments