Skip to content

Commit 5b07db4

Browse files
committed
Update script for IOS-XE 16.5(1).
* Add support for arguments * Add support for Python 2 * Correct AO sandbox credentials
1 parent 792e7cb commit 5b07db4

File tree

1 file changed

+127
-92
lines changed

1 file changed

+127
-92
lines changed

restconf_update_ipaddress/updateip.py

Lines changed: 127 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,175 +1,210 @@
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

2424
import json
25-
import requests
25+
import requests
2626
import sys
27+
from argparse import ArgumentParser
2728
from collections import OrderedDict
2829

2930
# These variables target the RESTCONF Always-On Sandbox hosted by Cisco DevNet
3031
HOST = 'ios-xe-mgmt.cisco.com'
3132
PORT = '9443'
3233
USER = '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
3739
MANAGEMENT_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
4347
headers = {'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+
142149
def 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

174209
if __name__ == '__main__':
175-
sys.exit(main())
210+
sys.exit(main())

0 commit comments

Comments
 (0)