1
1
#!/usr/bin/env python
2
2
"""
3
- This Python script leverages RESTCONF to:
3
+ This Python script leverages RESTCONF to:
4
4
- 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
19
19
- requests
20
-
21
-
20
+
21
+
22
22
"""
23
23
24
24
import json
25
- import requests
25
+ import requests
26
26
import sys
27
+ from argparse import ArgumentParser
27
28
from collections import OrderedDict
28
29
29
30
# These variables target the RESTCONF Always-On Sandbox hosted by Cisco DevNet
30
31
HOST = 'ios-xe-mgmt.cisco.com'
31
32
PORT = '9443'
32
33
USER = 'root'
33
- PASS = 'C!sc0123 '
34
+ PASS = 'D_Vay!_10& '
34
35
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
37
39
MANAGEMENT_INTERFACE = "GigabitEthernet1"
38
40
39
41
# 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
41
45
42
- # Identify yang+json as the data formats
46
+ # Identify yang+json as the data formats
43
47
headers = {'Content-Type' : 'application/vnd.yang.data+json' ,
44
48
'Accept' : 'application/vnd.yang.data+json' }
45
49
46
50
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"
50
55
51
56
# 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 ,
55
60
verify = False
56
- )
61
+ )
57
62
58
63
# return the json as text
59
64
return response .json ()["ietf-interfaces:interfaces" ]["interface" ]
60
65
61
66
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
+
67
73
# Create the data payload to reconfigure IP address
68
74
# Need to use OrderedDicts to maintain the order of elements
69
75
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 ([
75
81
('address' , [OrderedDict ([
76
- ('ip' ,ip ["address" ]),
77
- ('netmask' ,ip ["mask" ])
78
- ])]
82
+ ('ip' , ip ["address" ]),
83
+ ('netmask' , ip ["mask" ])
84
+ ])]
79
85
)
80
- ])
81
- ),
82
- ])
83
- )])
86
+ ])
87
+ ),
88
+ ])
89
+ )])
84
90
85
91
# 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 ,
90
96
json = data
91
- )
97
+ )
92
98
print (response .text )
93
99
94
100
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 )
98
105
99
106
# 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 ,
103
110
verify = False
104
- )
111
+ )
105
112
106
113
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 ('' )
112
119
113
120
return (intf )
114
121
115
122
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
117
124
# 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? " )
121
128
122
129
# Validate interface input
123
130
# 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 ]:
125
132
print ("INVALID: Select an available interface." )
126
- print (" " + MANAGEMENT_INTERFACE + " is used for management." )
133
+ print (" " + args . interface + " is used for management." )
127
134
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
+
130
137
return (sel )
131
138
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 ():
135
142
# Ask User for IP and Mask
136
143
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? " )
139
146
return (ip )
140
147
141
-
148
+
142
149
def main ():
150
+ global do_input
151
+
143
152
"""
144
153
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 )
148
183
149
184
print ("The router has the following interfaces: \n " )
150
- for interface in interfaces :
185
+ for interface in interfaces :
151
186
print (" * {name:25}" .format (name = interface ["name" ]))
152
187
153
188
print ("" )
154
189
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 )
158
193
159
194
# Print Starting Interface Details
160
195
print ("Starting Interface Configuration" )
161
- print_interface_details (selected_interface )
196
+ print_interface_details (args , selected_interface )
162
197
163
198
# As User for IP Address to set
164
199
ip = get_ip_info ()
165
200
166
- # Configure interface
167
- configure_ip_address (selected_interface , ip )
168
-
201
+ # Configure interface
202
+ configure_ip_address (args , selected_interface , ip )
203
+
169
204
# Print Ending Interface Details
170
205
print ("Ending Interface Configuration" )
171
- print_interface_details (selected_interface )
172
-
206
+ print_interface_details (args , selected_interface )
207
+
173
208
174
209
if __name__ == '__main__' :
175
- sys .exit (main ())
210
+ sys .exit (main ())
0 commit comments