Skip to content

Commit ef55577

Browse files
authored
Update updateip.py
take hostname, username, etc. from command line prompt for password check for errors and handle exceptions from requests
1 parent 0f10a10 commit ef55577

File tree

1 file changed

+78
-45
lines changed

1 file changed

+78
-45
lines changed

restconf_update_ipaddress/updateip.py

Lines changed: 78 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
This script has been tested with Python 3.5, however may work with other versions.
1212
1313
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.
1617
1718
Requirements:
1819
Python
@@ -26,49 +27,46 @@
2627
import sys
2728
from argparse import ArgumentParser
2829
from collections import OrderedDict
30+
from getpass import getpass
2931
import urllib3
3032

3133
# Disable SSL Warnings
3234
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
3335

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-
4136
# Identifies the interface on the device used for management access
4237
# Used to ensure the script isn't used to update the IP leveraged to manage device
4338
MANAGEMENT_INTERFACE = "GigabitEthernet1"
4439

45-
# Create the base URL for RESTCONF calls
46-
url_base = "https://{h}:{p}/restconf".format(h=HOST, p=PORT)
47-
4840
# Identify yang+json as the data formats
4941
headers = {'Content-Type': 'application/yang-data+json',
5042
'Accept': 'application/yang-data+json'}
5143

5244

5345
# Function to retrieve the list of interfaces on a device
54-
def get_configured_interfaces():
55-
url = url_base + "/data/ietf-interfaces:interfaces"
56-
46+
def get_configured_interfaces(url_base, username, password):
5747
# 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-
)
48+
try:
49+
response = requests.get(url_base,
50+
auth=(username, password),
51+
headers=headers,
52+
verify=False
53+
)
54+
except Exception as e:
55+
print(e, file=sys.stderr)
56+
sys.exit(1)
57+
58+
if response.status_code >= 300:
59+
print('request error:', str(response.status_code), response.reason, file=sys.stderr)
60+
sys.exit(1)
6361

6462
# return the json as text
6563
return response.json()["ietf-interfaces:interfaces"]["interface"]
6664

6765

6866
# Used to configure the IP address on an interface
69-
def configure_ip_address(interface, ip):
67+
def configure_ip_address(url_base, interface, ip, username, password):
7068
# RESTCONF URL for specific interface
71-
url = url_base + "/data/ietf-interfaces:interfaces/interface={i}".format(i=interface)
69+
url = url_base + "/interface={i}".format(i=interface)
7270

7371
# Create the data payload to reconfigure IP address
7472
# Need to use OrderedDicts to maintain the order of elements
@@ -89,32 +87,50 @@ def configure_ip_address(interface, ip):
8987
)])
9088

9189
# 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-
)
90+
try:
91+
response = requests.put(url,
92+
auth=(username, password),
93+
headers=headers,
94+
verify=False,
95+
json=data
96+
)
97+
except Exception as e:
98+
print(e, file=sys.stderr)
99+
sys.exit(1)
100+
101+
if response.status_code >= 300:
102+
print('request error:', str(response.status_code), response.reason, file=sys.stderr)
103+
sys.exit(1)
104+
98105
print(response.text)
99106

100107

101108
# 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)
109+
def print_interface_details(url_base, interface, username, password):
110+
url = url_base + "/interface={i}".format(i=interface)
104111

105112
# 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-
)
113+
try:
114+
response = requests.get(url,
115+
auth=(username, password),
116+
headers=headers,
117+
verify=False
118+
)
119+
except Exception as e:
120+
print(e, file=sys.stderr)
121+
sys.exit(1)
122+
123+
if response.status_code >= 300:
124+
print('request error:', str(response.status_code), response.reason, file=sys.stderr)
125+
sys.exit(1)
126+
111127

112128
intf = response.json()["ietf-interfaces:interface"]
113129
# return the json as text
114-
print("Name: ", intf["name"])
130+
print("Name: ", intf[0]["name"])
115131
try:
116-
print("IP Address: ", intf["ietf-ip:ipv4"]["address"][0]["ip"], "/",
117-
intf["ietf-ip:ipv4"]["address"][0]["netmask"])
132+
print("IP Address: ", intf[0]["ietf-ip:ipv4"]["address"][0]["ip"], "/",
133+
intf[0]["ietf-ip:ipv4"]["address"][0]["netmask"])
118134
except KeyError:
119135
print("IP Address: UNCONFIGURED")
120136
print()
@@ -149,13 +165,29 @@ def get_ip_info():
149165

150166

151167
def main():
152-
global do_input
153-
154168
"""
155169
Simple main method calling our function.
156170
"""
171+
172+
parser = ArgumentParser(
173+
prog=sys.argv[0], description='RESTCONF interface management tool')
174+
parser.add_argument('--hostname', '-a', type=str,
175+
help='sandbox hostname or IP address',
176+
default='ios-xe-mgmt.cisco.com')
177+
parser.add_argument('--username', '-u', type=str,
178+
help='sandbox username', default='developer')
179+
parser.add_argument('--port', '-P', type=int,
180+
help='sandbox web port', default=443)
181+
args = parser.parse_args()
182+
183+
password = getpass()
184+
185+
# Create the base URL for RESTCONF calls
186+
187+
url_base = "https://{h}:{p}/restconf/data/ietf-interfaces:interfaces".format(h=args.hostname, p=args.port)
188+
157189
# Get a List of Interfaces
158-
interfaces = get_configured_interfaces()
190+
interfaces = get_configured_interfaces(url_base, args.username, password)
159191

160192
print("The router has the following interfaces: \n")
161193
for interface in interfaces:
@@ -169,18 +201,19 @@ def main():
169201

170202
# Print Starting Interface Details
171203
print("Starting Interface Configuration")
172-
print_interface_details(selected_interface)
204+
print_interface_details(url_base, selected_interface, args.username,
205+
password)
173206

174207
# As User for IP Address to set
175208
ip = get_ip_info()
176209

177210
# Configure interface
178-
configure_ip_address(selected_interface, ip)
211+
configure_ip_address(url_base, selected_interface, ip, args.username, password)
179212

180213
# Print Ending Interface Details
181214
print("Ending Interface Configuration")
182-
print_interface_details(selected_interface)
183-
215+
print_interface_details(url_base, selected_interface, args.username,
216+
password)
184217

185218
if __name__ == '__main__':
186219
sys.exit(main())

0 commit comments

Comments
 (0)