Showing posts with label Python. Show all posts
Showing posts with label Python. 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
--------------------------------------------------

05 December, 2014

Python Lesson 2

### Tuples

- A sequence (like strings + lists)
- An immutable (r/o) list
      * Static program data
- Def 
      * An ordered set of data
      * a single row in DB table

atuple = ( 'perl', 'ruby', 'python', 3,14, 400 )
             s        s        s       f    i 

### Clear screen
>>> def wiper():
print("\n" * 100)
>>> wiper() 

>>> atuple = ("CBT", "Nuggets", "is", 1.0)
>>> atuple
('CBT', 'Nuggets', 'is', 1.0)

>>> newtup = (1, "Tbilisi", 3.14)
>>> type(newtup)
<class 'tuple'>

>>> len(newtup)
3

>>> type(newtup[2])
<class 'float'>
>>> type(newtup[1])
<class 'str'>
>>> type(newtup[0])
<class 'int'>

>>> ntup2 = newtup[0:2]
>>> ntup2
(1, 'Tbilisi')

>>> newtup
(1, 'Tbilisi', 3.14)
>>> newtup.index("Tbilisi")
1
>>> newtup.index("tbilisi")
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    newtup.index("tbilisi")
ValueError: tuple.index(x): x not in tuple

>>> newtup.count(3.14)
1                       !(we have ony one time this value)
>>> multitup = ("tim", 12, 14, "tim", 24.232, "tim")
>>> multitup.count("tim")   
3                                             !(3 times)


>>> foo = ["spam", 335, "eggs", 323.234]
>>> foo
['spam', 335, 'eggs', 323.234]
>>> type(foo)
<class 'list'>

>>> foo2 = foo[0:3]
>>> foo2
['spam', 335, 'eggs']

>>> foo2.remove(335)
>>> foo2
['spam', 'eggs']

>>> footup = tuple(foo2)
>>> footup
('spam', 'eggs')
>>> type(footup)
<class 'tuple'>

>>> foo2
['spam', 'eggs']
>>> foo2.append(3.14)
>>> foo2
['spam', 'eggs', 3.14]

>>> foo2.count("eggs")
1
>>> foo2.append("eggs")
>>> foo2.count("eggs")
2

>>> foo2.insert(1, "Tbilisi")
>>> foo2
['spam', 'Tbilisi', 'eggs', 3.14, 'eggs']

>>> foo2.insert(0, "Georgia")
>>> foo2
['Georgia', 'spam', 'Tbilisi', 'eggs', 3.14, 'eggs']

>>> foo2.reverse()
>>> foo2
['eggs', 3.14, 'eggs', 'Tbilisi', 'spam', 'Georgia']

### Dictionary
>>> months = {1: "January", 2: "February", 3: "March"}
>>> type(months)
<class 'dict'>

>>> months[2]
'February'
>>> months[4]
Traceback (most recent call last):
  File "<pyshell#111>", line 1, in <module>
    months[4]
KeyError: 4

>>> months[4] = "April"
>>> months
{1: 'January', 2: 'February', 3: 'March', 4: 'April'}

>>> months.keys()
dict_keys([1, 2, 3, 4])

>>> months.values()
dict_values(['January', 'February', 'March', 'April'])

>>> months[5] = "TEST"
>>> months[5]
'TEST'
>>> months[5] = "TEST-TEST"
>>> months[5]
'TEST-TEST'


>>> months = {1: "January", 2: "February", 3: "March"}
>>> months
{1: 'January', 2: 'February', 3: 'March'}

>>> list2 = list(months)
>>> list2
[1, 2, 3]

>>> list3 = list(months.values())
>>> list3
['January', 'February', 'March']

>>> tup = ("some", "data", "here")
>>> months[4] = tup
>>> months
{1: 'January', 2: 'February', 3: 'March', 4: ('some', 'data', 'here')}

>>> L1 = ["one", "two", "three", "four"]
>>> L2 = [1,2,3,4]
>>> L1
['one', 'two', 'three', 'four']
>>> L2
[1, 2, 3, 4]
>>> L1.append(L2)
>>> L1
['one', 'two', 'three', 'four', [1, 2, 3, 4]]

>>> adict = {"one":"uno", "two":"dos", "three":"tres"}
>>> adict
{'one': 'uno', 'two': 'dos', 'three': 'tres'}
>>> len(adict)
3
>>> L1 = ['one', 'two', 'three', 'four', [1, 2, 3, 4]]
>>> len(L1)
5
>>> string1 = "Nuggets"
>>> len(string1)
7
>>> adict
{'one': 'uno', 'two': 'dos', 'three': 'tres'}
>>> adict.pop("three")                             !(remove)
'tres'
>>> adict
{'one': 'uno', 'two': 'dos'}

! Create basic Script 

val1 = input("Enter str element 1/3: ")
val2 = int(input("Enter int element 2/3: "))
val3 = float(input("Enter float element 3/3: "))

lst = [val1, val2, val3]
tpl = (val1, val2, val3)
dict = {"First element: ":val1, "Second element":val2, "Third element":val3}

print("\n")
print("Here is your list: ", lst)
print("Here is your tuple: ", tpl)
print("Here is your dictionary: ", dict)

print("\n")
val4 = input("Add a new str list element: ")
lst.append(val4)
print("Here is your new list", lst)

! Run This Script

Enter str element 1/3: Tbilisi
Enter int element 2/3: 2014
Enter float element 3/3: 2.15


Here is your list:  ['Tbilisi', 2014, 2.15]

Here is your tuple:  ('Tbilisi', 2014, 2.15)
Here is your dictionary:  {'First element: ': 'Tbilisi', 'Second element': 2014, 'Third element': 2.15}


Add a new str list element: By CBT Nuggets
Here is your new list ['Tbilisi', 2014, 2.15, 'By CBT Nuggets']

04 December, 2014

Python Lesson 1

Python Lesson 1

Vocabulary

### Python Program Flow: 
                             --> stdlibe  (Standard Library)
- Programs    --> Module(s) ->        
                             --> imports
- Modules     --> Statements
- Statements  --> Expressions
- Expressions --> Objects

### Python is : 
- Dinamiclly Typed
- Strongly Typed

>>> a = 2
>>> b = 'Tim'

>>> type (a)
<class 'int'>

>>> type (b)
<class 'str'>

>>> c = 3.14
>>> type (c)
<class 'float'>

### Create simple function
>>> def adder (x,y):
print(x + y)

>>> adder (2,2)
4

More Example: 

>>> def oto (x,y):
print (x * y)

>>> oto (5,5)
25

>>> def tamta (x,y):
print (x / y)

>>> tamta (8,2)
4.0

>>> tamta (8, '2')                 (int and Str it will fail)
Traceback (most recent call last):
  File "<pyshell#40>", line 1, in <module>
    tamta (8, '2')
  File "<pyshell#36>", line 2, in tamta
    print (x / y)
TypeError: unsupported operand type(s) for /: 'int' and 'str'

Note: If we make str + str it will work

>>> 'Tbil' + 'isi'
'Tbilisi'

### Python Core Data Types
- Immutable ( Number, String , Tuple )
- Mutable   ( List , Dictionary , Files ) 

### Numbers 
Precence / Obsence  Dec. pt.  (int = 0 , 1 , -2 and Float = 3,14 , 5,10 , -1,50)

- type ()          -> Verify data type
- isinstance ()    -> test for d.t (Bool)
- int () ; float() -> type conversion

operators : + , - , * , / , // , % , ** , < , > , == , != , AND , OR , NOT 

#Order of operations : (PEMDAS)
P: Parenthesis
E: Exponentitation
M: Multiplication
D: Division
A: Addition
S: Subtraction

### Some Examples Of Calc
>>> 2+2
4
>>> 3-10
-7
>>> 10*10
100
>>> 100/10
10.0
>>> division = 100/10
>>> type (division)
<class 'float'>
>>> 100/6
16.666666666666668

>>> isinstance(division)
Traceback (most recent call last):
  File "<pyshell#106>", line 1, in <module>
    isinstance(division)
TypeError: isinstance expected 2 arguments, got 1

>>> help(isinstance)
Help on built-in function isinstance in module builtins:

isinstance(...)

    isinstance(object, class-or-type-or-tuple) -> bool
    
    Return whether an object is an instance of a class or of a subclass thereof.
    With a type as second argument, return whether that is the object's type.
    The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for
    isinstance(x, A) or isinstance(x, B) or ... (etc.).

>>> isinstance(division, int)
False
>>> isinstance(division, float)
True

>>> division
10.0
>>> int(division)
10
>>> division = int(division)
>>> division
10

>>> cbt = 'CBT Nuggets'
>>> type(cbt)
<class 'str'>
>>> cbt2 = int(cbt)
Traceback (most recent call last):
  File "<pyshell#120>", line 1, in <module>
    cbt2 = int(cbt)
ValueError: invalid literal for int() with base 10: 'CBT Nuggets'
>>> numstring = '100'
>>> numconv = int(numstring)
>>> numconv
100

>>> c = 'cbt'
>>> n = "nuggets"
>>> n1 = 'cbt nuggets"
SyntaxError: EOL while scanning string literal
>>> n * 5
'nuggetsnuggetsnuggetsnuggetsnuggets'
>>> cnew = 'cbt '
>>> cnew * 5
'cbt cbt cbt cbt cbt '
>>> c + n
'cbtnuggets'
>>> c + ' ' n
SyntaxError: invalid syntax
>>> c + ' ' + n
'cbt nuggets'

>>> concat = c + ' ' + n
>>> concat
'cbt nuggets'
>>> len(concat)     (Lenght, Number of carracters)
11
>>> corp = 'CBT Nuggets'
>>> corp[6:10]
'gget'
>>> corp[ :4]
'CBT '
>>> corp[4: ]
'Nuggets'
>>> corp[0:3]
'CBT'

### String Methods 
- st.find()   --> Gives offset ID
- st.replace() --> repl. substring
- st.split()   --> cuts string @ delimiter outputs a list
- st.upper()   
- st.lower()

>>> corp
'CBT Nuggets'
>>> corp.find(CBT)
Traceback (most recent call last):
  File "<pyshell#44>", line 1, in <module>
    corp.find(CBT)
NameError: name 'CBT' is not defined
>>> corp.find('CBT')
0
>>> corp.find('gets')
7
>>> corp.split(' ')
['CBT', 'Nuggets']
>>> slist = corp.split(' ')
>>> slist
['CBT', 'Nuggets']
>>> corp
'CBT Nuggets'

###
First Simple Script to determine raised to the 8th.
ui = input("Enter a number: ")
print("The data type is originally", (type(ui)))
uconv = int(ui)
print("Now the d.t. is", (type(uconv)))
power = uconv ** 8
print(ui, "raised to the 8th power is: ", power)
      
! Run Script
Enter a number: 2
The data type is originally <class 'str'>
Now the d.t. is <class 'int'>
2 raised to the 8th power is:  256