The role of an Network Engineer is rapidly evolving with the increasing demand for automation to manage complex networks effectively. Whether you’re preparing for a job posting at Amazon Web Services (AWS) or Google or any other leading technology company, having a solid foundation in network engineering combined with proficiency in automation is essential. During my experience so far,I myself have appeared in multiple interviews and have interviewed multiple candidates where I have noticed that since most of the current networking companies have robust software infrastructure built already with software engineers ;network engineers either don’t have to write code or they don’t get chance to write script and codes. This makes them a bit hesitant answering automation related questions and some time even they say “I don’t know automation” which I feel not the right thing because I am sure they have either written a small macro in microsoft excel ,or a small script to perform some calculation, or a program to telnet device and do some operation.So be confident to realise your potential and ready to say “I have written few or small scripts that were needed to expedite my work but if it is needed to write some code with current profile ,I can ramp-up fast and can wrote as I am open to learn and explore more after all its just a language to communicate to machine to perform some task and its learnable”.
This article provides foundational information on Python programming, focusing on lists, dictionaries, tuples, mutability, loops, and more, to help you prepare for roles that require both network engineering knowledge and automation skills.
An Network Engineer typically handles the following responsibilities:
- Design and Implementation: Build and deploy networking devices like optical, switches ,routers etc, including DWDM,IP-MPLS,OSPF,BGP etc and other advanced technologies.
- Network Scaling: Enhance and scale network designs to meet increasing demands.
- Process Development: Create and refine processes for network operation and deployment.
- Cross-Department Collaboration: Work with other teams to design and implement network solutions.
- Standards Compliance: Ensure network adherence to industry and company standards.
- Change Management: Review and implement network changes to improve performance and reliability.
- Operational Excellence: Lead projects to enhance network quality and dependability.
- Problem-Solving and Innovation: Troubleshoot complex issues and develop innovative solutions for network challenges.
Preparing for the Interview
Understanding Core or Leadership Principles
Many companies, like AWS, Google emphasize specific leadership principles or core values. Reflect on your experiences and prepare to discuss how you have applied these principles in your work. Last year I wrote an article in reference to AWS which you can visit here
Some of the common Leadership Principles or core/mission values are
- https://www.amazon.jobs/content/en/our-workplace/leadership-principles
- https://about.google/philosophy/
Behavioural Interview Questions
Expect behavioural questions that assess your problem-solving skills and past experiences. Use the STAR method (Situation, Task, Action, Result) to structure your responses.Most of the fair hire companies will have page dedicated to their hiring process which I will strongly encourage everyone to visit their page like
- https://aws.amazon.com/careers/how-we-hire/
- https://www.google.com/about/careers/applications/interview-tips/
- https://www.metacareers.com/swe-prep-onsite/
Now lets dive into the important piece of this article because we are still a little far from the point where nobody needs to write code but AI will do all necessary code for users by basic autosuggestions statements.
Automation Warm-up session
Pretty much every service provider is using python at this point of time so lets get to know some of the things that will build readers foundation and remove the fear to appear for interviews that has automation as core skill. Just prepare these by heart and I can assure you will do good with the interviews
1. Variables and Data Types
Variables store information that can be used and manipulated in your code. Python supports various data types, including integers, floats, strings, and booleans.
# Variables and data types device_name = "Router1" # String status = "Active" # String port_count = 24 # Integer error_rate = 0.01 # Float is_operational = True # Boolean print(f"Device: {device_name}, Status: {status}, Ports: {port_count}, Error Rate: {error_rate}, Operational: {is_operational}")
2. Lists
Lists are mutable sequences that can store a collection of items. Lists allow you to store and manipulate a collection of items.
# Creating and manipulating lists devices = ["Router1", "Switch1", "Router2", "Switch2"] # Accessing list elements print(devices[0]) # Output: Router1 # Adding an element devices.append("Router3") print(devices) # Output: ["Router1", "Switch1", "Router2", "Switch2", "Router3"] # Removing an element devices.remove("Switch1") print(devices) # Output: ["Router1", "Router2", "Switch2", "Router3"] # Iterating through a list for device in devices: print(device)
3. Dictionaries
# Creating and manipulating dictionaries device_statuses = { "Router1": "Active", "Switch1": "Inactive", "Router2": "Active", "Switch2": "Active" } # Accessing dictionary values print(device_statuses["Router1"]) # Output: Active # Adding a key-value pair device_statuses["Router3"] = "Active" print(device_statuses) # Output: {"Router1": "Active", "Switch1": "Inactive", "Router2": "Active", "Switch2": "Active", "Router3": "Active"} # Removing a key-value pair del device_statuses["Switch1"] print(device_statuses) # Output: {"Router1": "Active", "Router2": "Active", "Switch2": "Active", "Router3": "Active"} # Iterating through a dictionary for device, status in device_statuses.items(): print(f"Device: {device}, Status: {status}")
Dictionaries are mutable collections that store items in key-value pairs. They are useful for storing related data.
4. Tuples
Tuples are immutable sequences, meaning their contents cannot be changed after creation. They are useful for storing fixed collections of items.
# Creating and using tuples network_segment = ("192.168.1.0", "255.255.255.0") # Accessing tuple elements print(network_segment[0]) # Output: 192.168.1.0 # Tuples are immutable # network_segment[0] = "192.168.2.0" # This will raise an error
5. Mutability and Immutability
Understanding the concept of mutability and immutability is crucial for effective programming.
- Mutable objects: Can be changed after creation (e.g., lists, dictionaries).
- Immutable objects: Cannot be changed after creation (e.g., tuples, strings).
# Example of mutability devices = ["Router1", "Switch1"] devices.append("Router2") print(devices) # Output: ["Router1", "Switch1", "Router2"] # Example of immutability network_segment = ("192.168.1.0", "255.255.255.0") # network_segment[0] = "192.168.2.0" # This will raise an error
6. Conditional Statements and Loops
Control the flow of your program using conditional statements and loops.
# Conditional statements device = "Router1" status = "Active" if status == "Active": print(f"{device} is operational.") else: print(f"{device} is not operational.") # Loops # For loop for device in devices: print(device) # While loop count = 0 while count < 3: print(count) count += 1
7. Functions
Functions are reusable blocks of code that perform a specific task.
# Defining and using functions def check_device_status(device, status): if status == "Active": return f"{device} is operational." else: return f"{device} is not operational." # Calling a function result = check_device_status("Router1", "Active") print(result) # Output: Router1 is operational.
8. File Handling
Reading from and writing to files is essential for automating tasks that involve data storage.
# Writing to a file with open("device_statuses.txt", "w") as file: for device, status in device_statuses.items(): file.write(f"{device}: {status}\n") # Reading from a file with open("device_statuses.txt", "r") as file: content = file.read() print(content)
9. Using Libraries
Python libraries extend the functionality of your code. For network automation, libraries like paramiko
and netmiko
are invaluable.
# Using the json library to work with JSON data import json # Convert dictionary to JSON device_statuses_json = json.dumps(device_statuses) print(device_statuses_json) # Parse JSON back to dictionary parsed_device_statuses = json.loads(device_statuses_json) print(parsed_device_statuses)
Advanced Python for Network Automation
1. Network Automation Libraries
Utilize libraries such as paramiko
for SSH connections, netmiko
for multi-vendor device connections, and pyntc
for network management.
2. Automating SSH with Paramiko
import paramiko def ssh_to_device(ip, username, password, command): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(ip, username=username, password=password) stdin, stdout, stderr = ssh.exec_command(command) return stdout.read().decode() # Example usage output = ssh_to_device("192.168.1.1", "admin", "password", "show ip interface brief") print(output)
3. Automating Network Configuration with Netmiko
from netmiko import ConnectHandler device = { 'device_type': 'cisco_ios', 'host': '192.168.1.1', 'username': 'admin', 'password': 'password', } net_connect = ConnectHandler(**device) output = net_connect.send_command("show ip interface brief") print(output)
4. Using Telnet with telnetlib
import telnetlib def telnet_to_device(host, port, username, password, command): try: # Connect to the device tn = telnetlib.Telnet(host, port) # Read until the login prompt tn.read_until(b"login: ") tn.write(username.encode('ascii') + b"\n") # Read until the password prompt tn.read_until(b"Password: ") tn.write(password.encode('ascii') + b"\n") # Execute the command tn.write(command.encode('ascii') + b"\n") # Wait for command execution and read the output output = tn.read_all().decode('ascii') # Close the connection tn.close() return output except Exception as e: return str(e) # Example usage host = "192.168.1.1" port = 3083 username = "admin" password = "password" command = "rtrv-alm-all:::123;" output = telnet_to_device(host, port, username, password, command) print(output)
5. Using SSH with paramiko
import paramiko def ssh_to_device(host, port, username, password, command): try: # Create an SSH client ssh = paramiko.SSHClient() # Automatically add the device's host key (not recommended for production) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Connect to the device ssh.connect(host, port=port, username=username, password=password) # Execute the command stdin, stdout, stderr = ssh.exec_command(command) # Read the command output output = stdout.read().decode() # Close the connection ssh.close() return output except Exception as e: return str(e) # Example usage host = "192.168.1.1" port = 3083 username = "admin" password = "password" command = "rtrv-alm-all:::123;" output = ssh_to_device(host, port, username, password, command) print(output)
6. Using Telnet with telnetlib
with list of devices.
import telnetlib def telnet_to_device(host, port, username, password, command): try: # Connect to the device tn = telnetlib.Telnet(host, port) # Read until the login prompt tn.read_until(b"login: ") tn.write(username.encode('ascii') + b"\n") # Read until the password prompt tn.read_until(b"Password: ") tn.write(password.encode('ascii') + b"\n") # Execute the command tn.write(command.encode('ascii') + b"\n") # Wait for command execution and read the output output = tn.read_all().decode('ascii') # Close the connection tn.close() return output except Exception as e: return str(e) # List of devices devices = [ {"host": "192.168.1.1", "port": 3083, "username": "admin", "password": "password"}, {"host": "192.168.1.2", "port": 3083, "username": "admin", "password": "password"}, {"host": "192.168.1.3", "port": 3083, "username": "admin", "password": "password"} ] command = "rtrv-alm-all:::123;" # Execute command on each device for device in devices: output = telnet_to_device(device["host"], device["port"], device["username"], device["password"], command) print(f"Output from {device['host']}:\n{output}\n")
or
import telnetlib def telnet_to_device(host, port, username, password, command): try: # Connect to the device tn = telnetlib.Telnet(host, port) # Read until the login prompt tn.read_until(b"login: ") tn.write(username.encode('ascii') + b"\n") # Read until the password prompt tn.read_until(b"Password: ") tn.write(password.encode('ascii') + b"\n") # Execute the command tn.write(command.encode('ascii') + b"\n") # Wait for command execution and read the output output = tn.read_all().decode('ascii') # Close the connection tn.close() return output except Exception as e: return str(e) # List of device IPs device_ips = [ "192.168.1.1", "192.168.1.2", "192.168.1.3" ] # Common credentials and port port = 3083 username = "admin" password = "password" command = "rtrv-alm-all:::123;" # Execute command on each device for ip in device_ips: output = telnet_to_device(ip, port, username, password, command) print(f"Output from {ip}:\n{output}\n")
7. Using SSH with paramiko
with list of devices
import paramiko def ssh_to_device(host, port, username, password, command): try: # Create an SSH client ssh = paramiko.SSHClient() # Automatically add the device's host key (not recommended for production) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Connect to the device ssh.connect(host, port=port, username=username, password=password) # Execute the command stdin, stdout, stderr = ssh.exec_command(command) # Read the command output output = stdout.read().decode() # Close the connection ssh.close() return output except Exception as e: return str(e) # List of devices devices = [ {"host": "192.168.1.1", "port": 3083, "username": "admin", "password": "password"}, {"host": "192.168.1.2", "port": 3083, "username": "admin", "password": "password"}, {"host": "192.168.1.3", "port": 3083, "username": "admin", "password": "password"} ] command = "rtrv-alm-all:::123;" # Execute command on each device for device in devices: output = ssh_to_device(device["host"], device["port"], device["username"], device["password"], command) print(f"Output from {device['host']}:\n{output}\n")
or
import paramiko def ssh_to_device(host, port, username, password, command): try: # Create an SSH client ssh = paramiko.SSHClient() # Automatically add the device's host key (not recommended for production) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Connect to the device ssh.connect(host, port=port, username=username, password=password) # Execute the command stdin, stdout, stderr = ssh.exec_command(command) # Read the command output output = stdout.read().decode() # Close the connection ssh.close() return output except Exception as e: return str(e) # List of device IPs device_ips = [ "192.168.1.1", "192.168.1.2", "192.168.1.3" ] # Common credentials and port port = 3083 username = "admin" password = "password" command = "rtrv-alm-all:::123;" # Execute command on each device for ip in device_ips: output = ssh_to_device(ip, port, username, password, command) print(f"Output from {ip}:\n{output}\n")
Proficiency in Python and understanding the foundational concepts of lists, dictionaries, tuples, mutability, loops, and functions are crucial for automating tasks in network engineering. By practising and mastering these skills, you can enhance your problem-solving capabilities, improve network efficiency, and contribute to innovative solutions within your organization.
This guide serves as a starting point for your preparation. Practice coding regularly, explore advanced topics, and stay updated with the latest advancements in network automation. With dedication and the right preparation, you’ll be well-equipped to excel in any network engineering role.
If you feel that any other information that can help you being reader and for others ,feel free to leave comment and I will try to incorporate those in future.
All the best!