The weekly challenge specifically designed to improve your skills and prepare you for the Cisco Certified DevNet Expert certification. In this weeks challenge, you will use netmiko to send a few simple config commands to an IOS-XE device. Dive in, solve the challenge, and once you’ve cracked it, share your solution.
Kindly forwards the link to your Github profile showcasing your solution to luca.gubler@devnet-academy.com or post a comment with the link.
Interested in becoming a Cisco Certified DevNet Expert? Check out my e-learning where I teach you all the skills you need to pass the exam.
Hi Expert
Our network operations team is looking to streamline some common tasks that are currently done manually. One such task is the configuration of interfaces on our Cisco IOS devices. Given the sheer number of devices and frequency of these operations, automation can save us a significant amount of time and reduce manual errors.
Objective
Your task is to create a Python script using the netmiko library that will automate the configuration of an interface on a Cisco IOS device. The script should be able to:
- Select the correct interface.
- Set a description for the interface.
Requirements
- The script should prompt the user for:
- Interface to configure (e.g. GigabitEthernet2).
- The interface description text (e.g. DEVNET_EXPERT).
- Use the netmiko send_config_set function to configure the interface and the description
- After successfully configuring the interface, the script should display the following success message:
- Success! GigabitEthernet2 – DEVNET_EXPERT
Sample Usage
This is how it should look like when your solution is ready.
$ python3 configure_interfaces.py
Interface: GigabitEthernet2
Description: DEVNET_EXPERT
Success! GigabitEthernet2 - DEVNET_EXPERT
Resource
Use the following script as a starting point:
from netmiko import ConnectHandler
from ntc_templates.parse import parse_output
def main():
# TODO Prompt the user for interface and description using the input() function
interface = ...
description = ...
device_connection = ConnectHandler(
device_type="cisco_ios",
host="131.226.217.143",
username="admin",
password="C1sco12345"
)
# TODO Configure the interface and description
device_connection.send_config_set()
output = device_connection.send_command(f"show interfaces {interface}")
parsed_output = parse_output(
command = f"show interfaces {interface}",
data=output,
platform="cisco_ios"
)
# TODO Print the success message with data from parsed_output
print()
if __name__ == "__main__":
main()
First we will create a prompt to ask the user for the interface and description input. We can do that using the input method.
from netmiko import ConnectHandler
from ntc_templates.parse import parse_output
def main():
# TODO Prompt the user for interface and description using the input() function
interface = input("Interface: ")
description = input("Description: ")
device_connection = ConnectHandler(
device_type="cisco_ios",
host="131.226.217.143",
username="admin",
password="C1sco12345"
)
# TODO Configure the interface and description
device_connection.send_config_set()
output = device_connection.send_command(f"show interfaces {interface}")
parsed_output = parse_output(
command = f"show interfaces {interface}",
data=output,
platform="cisco_ios"
)
# TODO Print the success message with data from parsed_output
print()
if __name__ == "__main__":
main()
Next we will configure the interface. We can use the send_config_set() method from the netmiko library to send a list of commands to the device. To configure an interface and its description, we have to send the two commands interface GigabitEthernet2 and description DEVNET_EXPERT to the device. But if we send the command like this, the interface name and description will be hardcoded, but we want to use the values the user specified in the CLI. To do that, we use a Python f-string and edit the command to use variables. Below you can see how we do that.
from netmiko import ConnectHandler
from ntc_templates.parse import parse_output
def main():
# TODO Prompt the user for interface and description using the input() function
interface = input("Interface: ")
description = input("Description: ")
device_connection = ConnectHandler(
device_type="cisco_ios",
host="131.226.217.143",
username="admin",
password="C1sco12345"
)
# TODO Configure the interface and description
device_connection.send_config_set([f"interface {interface}", f"description {description}"])
output = device_connection.send_command(f"show interfaces {interface}")
parsed_output = parse_output(
command = f"show interfaces {interface}",
data=output,
platform="cisco_ios"
)
# TODO Print the success message with data from parsed_output
print()
if __name__ == "__main__":
main()
The last step is to print a success message if the interface has been configured. It should look like this: Success! GigabitEthernet2 – DEVNET_EXPERT. But instead of using the interface name and description from the user input, you should use the values returned from device output. First we will print out the complete parsed_output to see how its structured.
from netmiko import ConnectHandler
from ntc_templates.parse import parse_output
def main():
# TODO Prompt the user for interface and description using the input() function
interface = input("Interface: ")
description = input("Description: ")
device_connection = ConnectHandler(
device_type="cisco_ios",
host="131.226.217.143",
username="admin",
password="C1sco12345"
)
# TODO Configure the interface and description
device_connection.send_config_set([f"interface {interface}", f"description {description}"])
output = device_connection.send_command(f"show interfaces {interface}")
parsed_output = parse_output(
command = f"show interfaces {interface}",
data=output,
platform="cisco_ios"
)
# TODO Print the success message with data from parsed_output
print(parsed_output)
if __name__ == "__main__":
main()
$ python3 solution/configure_interfaces.py
Interface: GigabitEthernet2
Description: DEVNET_EXPERT
[{'interface': 'GigabitEthernet2', 'link_status': 'up', 'protocol_status': 'up', 'hardware_type': 'vNIC', 'address': '0050.56bf.2530', 'bia': '0050.56bf.2530', 'description': 'DEVNET_EXPERT', 'ip_address': '10.90.90.90/24', 'mtu': '1500', 'duplex': 'Full Duplex', 'speed': '1000Mbps', 'media_type': 'Virtual', 'bandwidth': '1000000 Kbit', 'delay': '10 usec', 'encapsulation': 'ARPA', 'last_input': 'never', 'last_output': '00:05:46', 'last_output_hang': 'never', 'queue_strategy': 'fifo', 'input_rate': '0', 'output_rate': '0', 'input_pps': '0', 'output_pps': '0', 'input_packets': '259', 'output_packets': '228', 'runts': '0', 'giants': '0', 'input_errors': '0', 'crc': '0', 'frame': '0', 'overrun': '0', 'abort': '', 'output_errors': '0', 'vlan_id': '', 'vlan_id_inner': '', 'vlan_id_outer': ''}]
The first thing I notice when I look at this output is that its returned as a list (see the brackets surrounding the output). Inside the list I see a dictionary with the interface and the description. To access the interface, I can use the following command parsed_output[0][‘interface’]. The finished code now looks like this
from netmiko import ConnectHandler
from ntc_templates.parse import parse_output
def main():
# TODO Prompt the user for interface and description using the input() function
interface = input("Interface: ")
description = input("Description: ")
device_connection = ConnectHandler(
device_type="cisco_ios",
host="131.226.217.143",
username="admin",
password="C1sco12345"
)
# TODO Configure the interface and description
device_connection.send_config_set([f"interface {interface}", f"description {description}"])
output = device_connection.send_command(f"show interfaces {interface}")
parsed_output = parse_output(
command = f"show interfaces {interface}",
data=output,
platform="cisco_ios"
)
# TODO Print the success message with data from parsed_output
print(f"Success! {parsed_output[0]['interface']} - {parsed_output[0]['description']}")
if __name__ == "__main__":
main()
