Showing posts with label Scripting. Show all posts
Showing posts with label Scripting. Show all posts

31 March, 2019

#3 - Python - Netmiko Scripts to Automate Tasks in Cisco Devices

In this section i will introduce some improovment of this Script.

As you see now we have separate file and new argv structure to run the script:

python@python:~$ ls -l
-* command3.py (Main Script with some improvements)
-* credential_tools.py (Script witch gets User and Password with Prompt)
-* devices.json ( Here we have list of the devices in Json format
-* commands.txt (Here we paste all Needed Commands to configure on Devices)


### command3.py
python@python:~$ cat command3.py
#!/usr/bin/python

import netmiko
import json
import credential_tools
import sys
import signal

# Avoid and  ignore some Errors
signal.signal(signal.SIGPIPE, signal.SIG_DFL) # IOError: Broken Pipe
signal.signal(signal.SIGINT, signal.SIG_DFL)  # KeyboardInterrupt: Ctrl-C


# Usage of the script-> : Usage: [Script].py [Commands].txt [Devices].json
if len(sys.argv) < 3:
   print("Error...")
   print("Usage: [Script].py [Commands].txt [Devices].json")
   exit()

# Bypass some esceptions and document it to avoid Script failure.
netmiko_exceptions = (netmiko.ssh_exception.NetMikoTimeoutException,
                      netmiko.ssh_exception.NetMikoAuthenticationException)

# Get User Credentials using external module with is imported as "credential_tools"
username, password = credential_tools.get_credentials()

# Read Commands from file:
with open(sys.argv[1]) as cmd_file:
    commands = cmd_file.readlines()

# Read Device list from File:
with open(sys.argv[2]) as dev_file:
    devices = json.load(dev_file)

# Main Netmiko connection Script
for device in devices:
    device["username"] = username
    device["password"] = password
    try:
        print("-"*80)
        connection = netmiko.ConnectHandler(**device)
        # Define  and get hostname from Netmiko processes:
        hostname = connection.base_prompt
        print("Selected Device: " + hostname)
        print("***Connecting to Device: " + device["ip"] + "\n")
        for command in commands:
            print("## Output of " + command)
            print(connection.send_command(command) + "\n")
        #Disconnect and close SSH session
        print("***Disconnecting From Device...")
        print("-"*80)
        connection.disconnect()
    # If Exception present bypass...
    except netmiko_exceptions as e:
         print("Failed to:", device["ip"], e)

### credential_tools.py
python@python:~$ cat credential_tools.py

from getpass import getpass

def get_input(prompt=""):
    try:
        line = raw_input(prompt)
    except NameError:
        line = input(prompt)
    return line

def get_credentials():
    """Prompts for, and returns, a username and password."""
    username = get_input("Enter Username: ")
    password = None
    while not password:
       password = getpass()
       password_verify = getpass("Retype Your Password: ")
       if password != password_verify:
          print("Password do not match. Try again! ")
          password = None
    return username, password

# devices.json
python@python:~$ cat devices.json
[
 {
  "ip": "10.0.10.105",
  "device_type": "cisco_ios"
 },
 {
  "ip": "10.0.10.106",
  "device_type": "cisco_ios"
 },
 {
  "ip": "10.0.10.107",
  "device_type": "cisco_ios"
 },
 {
  "ip": "10.0.10.108",
  "device_type": "cisco_ios"
 }
]

### commands.txt
python@python:~$ cat commands.txt
show clock
show ver | in time
show ip interface brief | exc unas
show arp
show ip route connected | beg Gate

### Run the Script...
Result:
python@python:~$ ./command3.py commands.txt devices.json
Enter Username: admin
Password: *****
Retype Your Password: *****
--------------------------------------------------------------------------------
Selected Device: XZSNR0801
***Connecting to Device: 10.0.10.105

## Output of show clock

*20:20:43.917 UTC Sun Mar 31 2019

## Output of show ver | in time

XZSNR0801 uptime is 3 days, 2 hours, 3 minutes

## Output of show ip interface brief | exc unas

Interface                  IP-Address      OK? Method Status                Protocol
GigabitEthernet1/0         10.0.10.105     YES manual up                    up

## Output of show arp

Protocol  Address          Age (min)  Hardware Addr   Type   Interface
Internet  10.0.10.6               0   94db.c903.c580  ARPA   GigabitEthernet1/0
Internet  10.0.10.29              0   94db.c903.c580  ARPA   GigabitEthernet1/0
Internet  10.0.10.105             -   ca00.14d4.001c  ARPA   GigabitEthernet1/0
Internet  10.0.10.106            84   ca06.14d4.001c  ARPA   GigabitEthernet1/0
Internet  10.0.10.107            83   ca07.1920.001c  ARPA   GigabitEthernet1/0
Internet  10.0.10.254             0   e055.3d4d.8b28  ARPA   GigabitEthernet1/0

## Output of show ip route connected | beg Gate

Gateway of last resort is not set

      10.0.0.0/8 is variably subnetted, 2 subnets, 2 masks
C        10.0.10.0/24 is directly connected, GigabitEthernet1/0
L        10.0.10.105/32 is directly connected, GigabitEthernet1/0

***Disconnecting From Device...
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Selected Device: XZSNR0802
***Connecting to Device: 10.0.10.106

## Output of show clock

*20:21:23.825 UTC Sun Mar 31 2019

## Output of show ver | in time

XZSNR0802 uptime is 3 days, 1 hour, 51 minutes

## Output of show ip interface brief | exc unas

Interface                  IP-Address      OK? Method Status                Protocol
GigabitEthernet1/0         10.0.10.106     YES manual up                    up

## Output of show arp

Protocol  Address          Age (min)  Hardware Addr   Type   Interface
Internet  10.0.10.6               0   94db.c903.c580  ARPA   GigabitEthernet1/0
Internet  10.0.10.29              0   94db.c903.c580  ARPA   GigabitEthernet1/0
Internet  10.0.10.105            84   ca00.14d4.001c  ARPA   GigabitEthernet1/0
Internet  10.0.10.106             -   ca06.14d4.001c  ARPA   GigabitEthernet1/0

## Output of show ip route connected | beg Gate

Gateway of last resort is not set

      10.0.0.0/8 is variably subnetted, 2 subnets, 2 masks
C        10.0.10.0/24 is directly connected, GigabitEthernet1/0
L        10.0.10.106/32 is directly connected, GigabitEthernet1/0

***Disconnecting From Device...
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
('Failed to:', u'10.0.10.107', NetMikoAuthenticationException(u'Authentication failure: unable to connect cisco_ios 10.0.10.107:22\nAuthentication failed.',))
--------------------------------------------------------------------------------
('Failed to:', u'10.0.10.108', NetMikoTimeoutException(u'Connection to device timed-out: cisco_ios 10.0.10.108:22',))

#2 - Python - Netmiko scripts to automate Network Tasks

To have more attractive code we have changed some functions, now we have 3 files in game.
Also we have excluded some exeptions like timeout and authentication failure to prevent script stops when its hepens.
We also have function to prompt for Username and Password and verify the password to confirm.

python@python:~$ ls -lh
-* command2.py          (Main Script we are working on)
-* devices.json             (We use this file to read Device list from there)
-* credential_tools.py  (Exported some tools such credential management to do not load a main script)


### command2.py
python@python:~$ cat command2.py

#!/usr/bin/python
import netmiko
import json
#Import our tools to manage credentials
import credential_tools

#Configure Exceptions for timeout and authentication failure
netmiko_exceptions = (netmiko.ssh_exception.NetMikoTimeoutException,
                      netmiko.ssh_exception.NetMikoAuthenticationException)

username, password = credential_tools.get_credentials()

#Open the file witch contains device list in json format
with open('devices.json') as dev_file:
    devices = json.load(dev_file)

for device in devices:
    device["username"] = username
    device["password"] = password
    try:
        print("-"*80)
        print("Connecting to Device ", device["ip"])
        connection = netmiko.ConnectHandler(**device)
        print(connection.send_command("show running-config | in hostname"))
        print(connection.send_command("show clock"))
        print(connection.send_command("show ip interface brief"))
        connection.disconnect()
    except netmiko_exceptions as e:
         print("Failed to ", device["ip"], e)


### devices.json 
python@python:~$ cat devices.json
[
 {
  "ip": "10.0.10.105",
  "device_type": "cisco_ios"
 },
 {
  "ip": "10.0.10.106",
  "device_type": "cisco_ios"
 },
 {
  "ip": "10.0.10.107",
  "device_type": "cisco_ios"
 },
 {
  "ip": "10.0.10.108",
  "device_type": "cisco_ios"
 }
]

### credential_tools.py 
python@python:~$ cat credential_tools.py

from getpass import getpass

def get_input(prompt=""):
    try:
        line = raw_input(prompt)
    except NameError:
        line = input(prompt)
    return line

def get_credentials():
    """Prompts for, and returns, a username and password."""
    username = get_input("Enter Username: ")
    password = None
    while not password:
       password = getpass()
       password_verify = getpass("Retype Your Password: ")
       if password != password_verify:
          print("Password do not match. Try again! ")
          password = None
    return username, password

### Run the Script...
Result :
python@python:~$ ./command2.py
Enter Username: admin
Password: ******
Retype Your Password: ******
--------------------------------------------------------------------------------
('Connecting to Device ', u'10.0.10.105')
hostname XZXNR0801
*14:31:31.939 UTC Sun Mar 31 2019
Interface                  IP-Address      OK? Method Status                Protocol
FastEthernet0/0            unassigned      YES unset  administratively down down
GigabitEthernet1/0         10.0.10.105     YES manual up                    up
--------------------------------------------------------------------------------
('Connecting to Device ', u'10.0.10.106')
hostname XZXNR0802
*14:32:07.111 UTC Sun Mar 31 2019
Interface                  IP-Address      OK? Method Status                Protocol
FastEthernet0/0            unassigned      YES manual administratively down down
GigabitEthernet1/0         10.0.10.106     YES manual up                    up
--------------------------------------------------------------------------------
('Connecting to Device ', u'10.0.10.107')
('Failed to ', u'10.0.10.107', NetMikoAuthenticationException(u'Authentication failure: unable to connect cisco_ios 10.0.10.107:22\nAuthentication failed.',))
--------------------------------------------------------------------------------
('Connecting to Device ', u'10.0.10.108')
('Failed to ', u'10.0.10.108', NetMikoTimeoutException(u'Connection to device timed-out: cisco_ios 10.0.10.108:22',))

#1 - Basic Python - Netmiko scripts to automate Network Tasks


#!/usr/bin/python

import netmiko
import json

connection = netmiko.ConnectHandler(ip="10.0.10.105", device_type="cisco_ios", username="admin", password="cisco")

connection
print("-"*50)
print(connection.send_command("show running-config | in hostname"))
print(connection.send_command("show clock"))
print(connection.send_command("show ip interface brief"))
print("-"*50)
connection.disconnect

Result :

python@python:~$ ./command.py
--------------------------------------------------
hostname ZXYNR0801
*14:22:46.559 UTC Sun Mar 31 2019
Interface                  IP-Address      OK? Method Status                Protocol
FastEthernet0/0            unassigned      YES unset  administratively down down
GigabitEthernet1/0         10.0.10.105     YES manual up                    up
--------------------------------------------------