Automation

Empowering Network Engineers to Ace Interviews Requiring Automation Skills

Pinterest LinkedIn Tumblr

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
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

 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!

References

Share and Explore the Tech Inside You!!!

Write A Comment