11
11
This script has been tested with Python 3.5, however may work with other versions.
12
12
13
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.
14
+ a target. To execute this script against a different device, update the
15
+ variables and command-line arguments that list the connectivity, management
16
+ interface, and url_base for RESTCONF.
16
17
17
18
Requirements:
18
19
Python
24
25
import json
25
26
import requests
26
27
import sys
28
+ import os
27
29
from argparse import ArgumentParser
28
30
from collections import OrderedDict
31
+ from getpass import getpass
29
32
import urllib3
30
33
31
34
# Disable SSL Warnings
32
35
urllib3 .disable_warnings (urllib3 .exceptions .InsecureRequestWarning )
33
36
34
-
35
- # These variables target the RESTCONF Always-On Sandbox hosted by Cisco DevNet
36
- HOST = 'ios-xe-mgmt.cisco.com'
37
- PORT = '443'
38
- USER = 'root'
39
- PASS = 'D_Vay!_10&'
40
-
41
- # Identifies the interface on the device used for management access
42
- # Used to ensure the script isn't used to update the IP leveraged to manage device
43
- MANAGEMENT_INTERFACE = "GigabitEthernet1"
44
-
45
- # Create the base URL for RESTCONF calls
46
- url_base = "https://{h}:{p}/restconf" .format (h = HOST , p = PORT )
47
-
48
37
# Identify yang+json as the data formats
49
38
headers = {'Content-Type' : 'application/yang-data+json' ,
50
39
'Accept' : 'application/yang-data+json' }
51
40
52
41
53
42
# Function to retrieve the list of interfaces on a device
54
- def get_configured_interfaces ():
55
- url = url_base + "/data/ietf-interfaces:interfaces"
56
-
43
+ def get_configured_interfaces (url_base , username , password ):
57
44
# this statement performs a GET on the specified url
58
- response = requests .get (url ,
59
- auth = (USER , PASS ),
60
- headers = headers ,
61
- verify = False
62
- )
45
+ try :
46
+ response = requests .get (url_base ,
47
+ auth = (username , password ),
48
+ headers = headers ,
49
+ verify = False
50
+ )
51
+ response .raise_for_status ()
52
+ except Exception as e :
53
+ print (e , file = sys .stderr )
54
+ sys .exit (1 )
63
55
64
56
# return the json as text
65
57
return response .json ()["ietf-interfaces:interfaces" ]["interface" ]
66
58
67
59
68
60
# Used to configure the IP address on an interface
69
- def configure_ip_address (interface , ip ):
61
+ def configure_ip_address (url_base , interface , ip , username , password ):
70
62
# RESTCONF URL for specific interface
71
- url = url_base + "/data/ietf-interfaces:interfaces/ interface={i}" .format (i = interface )
63
+ url = url_base + "/interface={i}" .format (i = interface )
72
64
73
65
# Create the data payload to reconfigure IP address
74
66
# Need to use OrderedDicts to maintain the order of elements
@@ -89,32 +81,43 @@ def configure_ip_address(interface, ip):
89
81
)])
90
82
91
83
# Use PUT request to update data
92
- response = requests .put (url ,
93
- auth = (USER , PASS ),
94
- headers = headers ,
95
- verify = False ,
96
- json = data
97
- )
84
+ try :
85
+ response = requests .put (url ,
86
+ auth = (username , password ),
87
+ headers = headers ,
88
+ verify = False ,
89
+ json = data
90
+ )
91
+ response .raise_for_status ()
92
+ except Exception as e :
93
+ print (e , file = sys .stderr )
94
+ sys .exit (1 )
95
+
98
96
print (response .text )
99
97
100
98
101
99
# Retrieve and print the current configuration of an interface
102
- def print_interface_details (interface ):
103
- url = url_base + "/data/ietf-interfaces:interfaces/ interface={i}" .format (i = interface )
100
+ def print_interface_details (url_base , interface , username , password ):
101
+ url = url_base + "/interface={i}" .format (i = interface )
104
102
105
103
# this statement performs a GET on the specified url
106
- response = requests .get (url ,
107
- auth = (USER , PASS ),
108
- headers = headers ,
109
- verify = False
110
- )
104
+ try :
105
+ response = requests .get (url ,
106
+ auth = (username , password ),
107
+ headers = headers ,
108
+ verify = False
109
+ )
110
+ response .raise_for_status ()
111
+ except Exception as e :
112
+ print (e , file = sys .stderr )
113
+ sys .exit (1 )
111
114
112
115
intf = response .json ()["ietf-interfaces:interface" ]
113
116
# return the json as text
114
- print ("Name: " , intf ["name" ])
117
+ print ("Name: " , intf [0 ][ "name" ])
115
118
try :
116
- print ("IP Address: " , intf ["ietf-ip:ipv4" ]["address" ][0 ]["ip" ], "/" ,
117
- intf ["ietf-ip:ipv4" ]["address" ][0 ]["netmask" ])
119
+ print ("IP Address: " , intf [0 ][ "ietf-ip:ipv4" ]["address" ][0 ]["ip" ], "/" ,
120
+ intf [0 ][ "ietf-ip:ipv4" ]["address" ][0 ]["netmask" ])
118
121
except KeyError :
119
122
print ("IP Address: UNCONFIGURED" )
120
123
print ()
@@ -124,15 +127,15 @@ def print_interface_details(interface):
124
127
125
128
# Ask the user to select an interface to configure. Ensures input is valid and
126
129
# NOT the management interface
127
- def interface_selection (interfaces ):
130
+ def interface_selection (interfaces , mgmt_if ):
128
131
# Ask User which interface to configure
129
132
sel = input ("Which Interface do you want to configure? " )
130
133
131
134
# Validate interface input
132
135
# Must be an interface on the device AND NOT be the Management Interface
133
- while sel == MANAGEMENT_INTERFACE or not sel in [intf ["name" ] for intf in interfaces ]:
136
+ while sel == mgmt_if or not sel in [intf ["name" ] for intf in interfaces ]:
134
137
print ("INVALID: Select an available interface." )
135
- print (" " + MANAGEMENT_INTERFACE + " is used for management." )
138
+ print (" " + mgmt_if + " is used for management." )
136
139
print (" Choose another Interface" )
137
140
sel = input ("Which Interface do you want to configure? " )
138
141
@@ -149,13 +152,36 @@ def get_ip_info():
149
152
150
153
151
154
def main ():
152
- global do_input
153
-
154
155
"""
155
156
Simple main method calling our function.
156
157
"""
158
+
159
+ parser = ArgumentParser (
160
+ prog = sys .argv [0 ], description = 'RESTCONF interface management tool' )
161
+ parser .add_argument ('--hostname' , '-a' , type = str ,
162
+ help = 'sandbox hostname or IP address' ,
163
+ default = 'ios-xe-mgmt.cisco.com' )
164
+ parser .add_argument ('--username' , '-u' , type = str ,
165
+ help = 'sandbox username' , default = 'developer' )
166
+ # Identifies the interface on the device used for management access
167
+ # Used to ensure the script isn't used to update the IP leveraged to manage
168
+ # device
169
+ parser .add_argument ('--management_if' , '-m' , type = str ,
170
+ help = 'management interface' , default = 'GigabitEthernet1' )
171
+ parser .add_argument ('--port' , '-P' , type = int ,
172
+ help = 'sandbox web port' , default = 443 )
173
+ args = parser .parse_args ()
174
+
175
+ password = os .getenv ('DEVNET_RESTCONF_PASSWORD' )
176
+ if password is None :
177
+ password = getpass ()
178
+
179
+ # Create the base URL for RESTCONF calls
180
+
181
+ url_base = "https://{h}:{p}/restconf/data/ietf-interfaces:interfaces" .format (h = args .hostname , p = args .port )
182
+
157
183
# Get a List of Interfaces
158
- interfaces = get_configured_interfaces ()
184
+ interfaces = get_configured_interfaces (url_base , args . username , password )
159
185
160
186
print ("The router has the following interfaces: \n " )
161
187
for interface in interfaces :
@@ -164,23 +190,24 @@ def main():
164
190
print ("" )
165
191
166
192
# Ask User which interface to configure
167
- selected_interface = interface_selection (interfaces )
193
+ selected_interface = interface_selection (interfaces , args . management_if )
168
194
print (selected_interface )
169
195
170
196
# Print Starting Interface Details
171
197
print ("Starting Interface Configuration" )
172
- print_interface_details (selected_interface )
198
+ print_interface_details (url_base , selected_interface , args .username ,
199
+ password )
173
200
174
201
# As User for IP Address to set
175
202
ip = get_ip_info ()
176
203
177
204
# Configure interface
178
- configure_ip_address (selected_interface , ip )
205
+ configure_ip_address (url_base , selected_interface , ip , args . username , password )
179
206
180
207
# Print Ending Interface Details
181
208
print ("Ending Interface Configuration" )
182
- print_interface_details (selected_interface )
183
-
209
+ print_interface_details (url_base , selected_interface , args . username ,
210
+ password )
184
211
185
212
if __name__ == '__main__' :
186
213
sys .exit (main ())
0 commit comments