Send Email with Python

You can send email in python with snmplib library.

(more…)

Add Physical Interfaces into mininet switch

untuk menambahkan physical interface kedalam mininet switch, dapat menggunakan script dibawah ini :

#!/usr/bin/python

from mininet.net import Mininet
from mininet.node import RemoteController, OVSSwitch
from mininet.cli import CLI
from mininet.link import Intf
from mininet.log import setLogLevel, info

def myNetwork():
    net = Mininet( topo=None,controller=RemoteController,switch=OVSSwitch)

    info( '*** Add Controller\n')
    net.addController('c0', ip='127.0.0.1', port=6633)

    info( '*** Add switches\n')
    s1 = net.addSwitch('s1')
    Intf( 'ens4', node=s1 )

    info( '*** Add hosts\n')
    h1 = net.addHost('h1', ip='10.0.0.1')

    info( '*** Add links\n')
    net.addLink(h1, s1)

    info( '*** Starting network\n')
    net.start()
    CLI(net)
    net.stop()

if __name__ == '__main__':
    setLogLevel( 'info' )
    myNetwork()

Script tersebut menambahkan interface ens4 kedalam s1 didalam mininet.

Creating Simple YANG Model

YANG model adalah bahasa yang dibuat khusus memodelkan jaringan. sekarang mari kita coba membuat yang model

module vyos-interface {
    prefix "interfaces";
    namespace "https://btech.id/";

    organization
      "Boer Technology";
    contact
      "zufar@btech.co.id";

    description
      "This is YANG Module for VyOS interface";

    typedef ipv4-prefix {
        type string {
            pattern
            '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
            + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
            + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
        }
    }

    container interface {
        list ethernet {
            key "name";
            leaf name {
                type string;
            }
            leaf address {
                type interfaces:ipv4-prefix;
            }
            leaf description {
                type string;
            }
        }
    }
}
  • module, adalah nama module yang tersebut, nama harus sama dengan nama file .yang
  • prefix, adalah tanda yang digunakan bahwa menggunakan resource di module tersebut, akan berguna jika kita mengimport data dari module lain.
  • namespace, semua YANG data model mempunyai namespace yang unik, module yang di publish di RFC, namespace dialokasikan oleh IANA. untuk private organization, namespace bebas dan harus didefinisikan.
  • organization, contact, description, penjelasan mengenai module tersebut
  • typedef, merupakan object yang mendefinisikan sebuah tipe data baru. pada contoh program diatas kita mendefinisikan tipe data ipv4-prefix. pattern saya ambil dari https://github.com/YangModels/yang/blob/master/standard/ietf/RFC/ietf-inet-types%402013-07-15.yang
  • container, merupakan kontainer yang berisi data yang lain, dapat di nestedkan (nested container)
  • list, merupakan object yang berisi kumpulan data, list tidak berisi value tertentu.
  • leaf, merupakan object yang memiliki satu value tertentu.

cek yang model tersebut :

zufar@zufar:~/Documents/Technology/Programming/YANG$ pyang -f tree vyos-interface.yang
module: vyos-interface
   +--rw interface
      +--rw ethernet* [name]
         +--rw name           string
         +--rw address?       ipv4-prefix
         +--rw description?   string

generate module tersebut menjadi module python :

zufar@zufar:~/Documents/Technology/Programming/YANG$ export PYBINDPLUGIN=`/usr/bin/env python -c \
>         'import pyangbind; import os; print "%s/plugin" % os.path.dirname(pyangbind.__file__)'`
zufar@zufar:~/Documents/Technology/Programming/YANG$ pyang --plugindir $PYBINDPLUGIN -f pybind vyos-interface.yang > vyos_interface.py

buat program python berdasarkan tree dari file YANG :

import vyos_interface                                              1

interface = vyos_interface.vyos_interface()                        2

new_interface = interface.interface.ethernet.add("eth0")           3
new_interface.address = "192.168.1.1/24"                           4
new_interface.description = "YANG generate"                        4

import json                                                        5
print (json.dumps(interface.get(), indent=4))                      5
  1. import module tersebut
  2. buat sebuah variable dari module tersebut, dengan memanggil fungsi module dari tree.
  3. lihat fungsi bintang pada tree? jika ada fungsi bintang, tambahkan .add() dimana value diisi dengan [name]
  4. tambahkan value lain seperti address dan description
  5. generate dengan indentasi 4, kedalam bentuk json

jalankan program tersebut :

zufar@zufar:~/Documents/Technology/Programming/YANG$ python generate.py
{
    "interface": {
        "ethernet": {
            "eth0": {
                "address": "192.168.1.1/24",
                "description": "YANG generate",
                "name": "eth0"
            }
        }
    }
}

Basic Netmiko

Netmiko adalah sebuah library python yang meringkas penggunaan dari paramiko (high level than paramiko) dan menggunakan paramiko sebagai base untuk melakukan SSH. Netmiko dibuild khusus untuk perangkat jaringan, berikut beberapa perangkat yang sudah ditest :

Supports:

Arista vEOS
Cisco ASA
Cisco IOS
Cisco IOS-XE
Cisco IOS-XR
Cisco NX-OS
Cisco SG300
Dell OS10
HP Comware7
HP ProCurve
Juniper Junos
Linux

Limited testing

Alcatel AOS6/AOS8
Avaya ERS
Avaya VSP
Brocade VDX
Brocade MLX/NetIron
Calix B6
Cisco WLC
Dell-Force10
Dell PowerConnect
Huawei
Mellanox
NetApp cDOT
Palo Alto PAN-OS
Pluribus
Ruckus ICX/FastIron
Ubiquiti EdgeSwitch
Vyatta VyOS

konfigurasi perangkat cisco ios dan vyos

R1(config)#hostname R1
R1(config)#ip domain-name btech.id        
R1(config)#crypto key generate rsa 
The name for the keys will be: R1.btech.id
Choose the size of the key modulus in the range of 360 to 2048 for your
  General Purpose Keys. Choosing a key modulus greater than 512 may take
  a few minutes.

How many bits in the modulus [512]: 2048
% Generating 2048 bit RSA keys, keys will be non-exportable...[OK]

*Mar  1 00:02:27.167: %SSH-5-ENABLED: SSH 1.99 has been enabled
R1(config)#ip ssh version 2
R1(config)#username btech privilege 15 secret btech
R1(config)#line vty 0 4
R1(config-line)#transport input ssh 
R1(config-line)#login local

[edit]
vyos@vyos# set interfaces ethernet eth1 address dhcp
[edit]
vyos@vyos# set service ssh port 22
[edit]
vyos@vyos# commit
[ interfaces ethernet eth1 address dhcp ]
Starting DHCP client on eth1 ...

[edit]
vyos@vyos# save
Saving configuration to '/config/config.boot'...
Done

install library netmiko :

ubuntu@ubuntu:~$ sudo pip install netmiko
[sudo] password for ubuntu: 
The directory '/home/ubuntu/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.                                                                                                   
The directory '/home/ubuntu/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.                                                                                                          
Collecting netmiko
  Downloading https://files.pythonhosted.org/packages/96/f8/4ecb91398a14bc1942322e87203859b04421cdb2b8b5c7d9b3fc9a168e21/netmiko-2.1.1.tar.gz (71kB)
    100% |████████████████████████████████| 71kB 713kB/s 
Requirement already satisfied (use --upgrade to upgrade): paramiko>=2.0.0 in /usr/local/lib/python2.7/dist-packages (from netmiko)
Collecting scp>=0.10.0 (from netmiko)
  Downloading https://files.pythonhosted.org/packages/ef/8c/399c5ddffc8c1bd2593ee6c8937ed31f005dcfa0c591da149f7b4b993f14/scp-0.11.0-py2.py3-none-any.whl
Collecting pyyaml (from netmiko)
  Downloading https://files.pythonhosted.org/packages/9e/a3/1d13970c3f36777c583f136c136f804d70f500168edc1edea6daa7200769/PyYAML-3.13.tar.gz (270kB)
    100% |████████████████████████████████| 276kB 549kB/s 
Collecting pyserial (from netmiko)
  Downloading https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e209f59c30/pyserial-3.4-py2.py3-none-any.whl (193kB)
    100% |████████████████████████████████| 194kB 562kB/s 
Collecting textfsm (from netmiko)
  Downloading https://files.pythonhosted.org/packages/a1/0d/a1b490503545b3b4600b965eae5d44cc2b6ce27cfb44f4debc563dbb56d3/textfsm-0.4.1.tar.gz
Requirement already satisfied (use --upgrade to upgrade): pyasn1>=0.1.7 in /usr/local/lib/python2.7/dist-packages (from paramiko>=2.0.0->netmiko)
Requirement already satisfied (use --upgrade to upgrade): bcrypt>=3.1.3 in /usr/local/lib/python2.7/dist-packages (from paramiko>=2.0.0->netmiko)
Requirement already satisfied (use --upgrade to upgrade): cryptography>=1.5 in /usr/local/lib/python2.7/dist-packages (from paramiko>=2.0.0->netmiko)
Requirement already satisfied (use --upgrade to upgrade): pynacl>=1.0.1 in /usr/local/lib/python2.7/dist-packages (from paramiko>=2.0.0->netmiko)
Requirement already satisfied (use --upgrade to upgrade): six>=1.4.1 in /usr/local/lib/python2.7/dist-packages (from bcrypt>=3.1.3->paramiko>=2.0.0->netmiko)
Requirement already satisfied (use --upgrade to upgrade): cffi>=1.1 in /usr/local/lib/python2.7/dist-packages (from bcrypt>=3.1.3->paramiko>=2.0.0->netmiko)
Requirement already satisfied (use --upgrade to upgrade): enum34; python_version < "3" in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.5->paramiko>=2.0.0->netmiko)
Requirement already satisfied (use --upgrade to upgrade): asn1crypto>=0.21.0 in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.5->paramiko>=2.0.0->netmiko)
Requirement already satisfied (use --upgrade to upgrade): idna>=2.1 in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.5->paramiko>=2.0.0->netmiko)
Requirement already satisfied (use --upgrade to upgrade): ipaddress; python_version < "3" in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.5->paramiko>=2.0.0->netmiko)
Requirement already satisfied (use --upgrade to upgrade): pycparser in /usr/local/lib/python2.7/dist-packages (from cffi>=1.1->bcrypt>=3.1.3->paramiko>=2.0.0->netmiko)
Installing collected packages: scp, pyyaml, pyserial, textfsm, netmiko
  Running setup.py install for pyyaml ... done
  Running setup.py install for textfsm ... done
  Running setup.py install for netmiko ... done
Successfully installed netmiko-2.1.1 pyserial-3.4 pyyaml-3.13 scp-0.11.0 textfsm-0.4.1
You are using pip version 8.1.1, however version 10.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

buat programnya :

# import library netmiko
from netmiko import ConnectHandler

# Define cisco ios
# device_type list https://github.com/ktbyers/netmiko/blob/master/netmiko/ssh_dispatcher.py
cisco_ios = {
    'device_type':'cisco_ios',
    'ip':'192.168.122.250',
    'username':'btech',
    'password':'btech',
    'port' : 22
}

vyos = {
    'device_type':'vyos',
    'ip':'192.168.122.111',
    'username':'vyos',
    'password':'vyos',
    'port' : 22
}

# add all device into list
device = [cisco_ios,vyos]

# use looping
for node in device:
    connect = ConnectHandler(**node)
    output = connect.send_command('show arp')
    print "\n\n##### Device {0} #####".format(node['device_type'])
    print (output)

jalankan dan lihat hasilnya :

ubuntu@ubuntu:~/netmiko$ python program.py 


##### Device cisco_ios #####
Protocol  Address          Age (min)  Hardware Addr   Type   Interface
Internet  192.168.122.129         0   0c9e.2e63.4800  ARPA   FastEthernet0/0
Internet  192.168.122.250         -   c201.0a97.0000  ARPA   FastEthernet0/0


##### Device vyos #####
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.122.1            ether   52:54:00:39:6a:c8   C                     eth1
192.168.122.129          ether   0c:9e:2e:63:48:00   C                     eth1

Parsing Python Dictionary into Mysql Database

Tutorial kali ini akan melakukan parsing dari data dictionary python kedalam mysql database. pertama instalasi dan konfigurasi mysql server :

$ sudo apt install mysql-server

nano /etc/mysql/mysql.conf.d/mysqld.cnf
#bind-address           = 127.0.0.1
bind-address            = 0.0.0.0

$ mysql -u root -p
CREATE USER 'vyosuser'@'%' IDENTIFIED BY 'vyospassword';
CREATE DATABASE vyos;
USE vyos;
CREATE TABLE User (
    name varchar(255)	NOT NULL,
    ipaddress varchar(255) NOT NULL,
    user varchar(255) 	NOT NULL,
    password varchar(255)	NOT NULL

);
GRANT ALL PRIVILEGES ON vyos.* TO 'vyosuser'@'%';
FLUSH PRIVILEGES;

root@ubuntu:~# systemctl restart mysql
root@ubuntu:~# systemctl status mysql
● mysql.service - MySQL Community Server
   Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: en
   Active: active (running) since Fri 2018-07-13 13:02:43 EDT; 7s ago
  Process: 3229 ExecStartPost=/usr/share/mysql/mysql-systemd-start post (code=ex
  Process: 3217 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exit
 Main PID: 3228 (mysqld)
    Tasks: 28
   Memory: 134.0M
      CPU: 297ms
   CGroup: /system.slice/mysql.service
           └─3228 /usr/sbin/mysqld

Jul 13 13:02:42 ubuntu systemd[1]: Stopped MySQL Community Server.
Jul 13 13:02:42 ubuntu systemd[1]: Starting MySQL Community Server...
Jul 13 13:02:43 ubuntu systemd[1]: Started MySQL Community Server.

siapkan data yang akan diparsing :

{
    "host": [{
            "ipaddress": "192.168.1.1",
            "user": "vyos1",
            "password": "vyos1"
        },
        {
            "ipaddress": "192.168.1.2",
            "user": "vyos2",
            "password": "vyos2"
        }
    ]
}

instalasi module mysql di server otomasi :

sudo apt install libmysqlclient-dev
sudo pip install MySQL-python

buat program :

# Import mysql python module
import ast
import MySQLdb

# import data from inventory
# open json and read into raw text
raw = open('inventory.json').read()

# loads the raw into loads() function to create dict string type
data = ast.literal_eval(raw)

# connect to mysql database
conn = MySQLdb.connect(host= "192.168.122.60",user="vyosuser",passwd="vyospassword",db="vyos")

# setup cursor
cursor=conn.cursor()

# use looping & append data
for host in data["host"].iteritems():
    cursor.execute("""INSERT INTO User (name, ipaddress, user, password) VALUES ('%s','%s','%s','%s')"""%(host[0],host[1]["ipaddress"],host[1]["user"],host[1]["password"]))
    conn.commit()

# close connection
conn.close()

jalankan program tersebut, lalu coba cek di database :

mysql> SELECT * FROM User;
Empty set (0.00 sec)

mysql> SELECT * FROM User;
+--------+-------------+-------+----------+
| name   | ipaddress   | user  | password |
+--------+-------------+-------+----------+
| Spine1 | 192.168.1.1 | vyos1 | vyos1    |
| Spine2 | 192.168.2.1 | vyos2 | vyos2    |
+--------+-------------+-------+----------+
2 rows in set (0.00 sec)

mysql>

 

Append Dictionary Python

karena format json dan dictionary dipython sangat mirip, saya menggunakan permisalan di json. kasusnya kita mempunyai file inventory seperti berikut :

{
    "host": {
        "Spine1": {
            "ipaddress": "192.168.1.1",
            "user": "vyos1",
            "password": "vyos1"
        },
        "Spine2": {
            "ipaddress": "192.168.2.1",
            "user": "vyos2",
            "password": "vyos2"
        }
    }
}

kita harus menambahkan sebuah data lagi (spine3 dan yang lain kedalam data tersebut, contohnya :

{
    'Spine4': {
        'password': 'vyos1',
        'ipaddress': '192.168.1.1',
        'user': 'vyos1'
    }
}

oke, mari kita buat programnya :

import ast

# open json and read into raw text
raw = open('inventory.json').read()

# loads the raw into loads() function to create dict string type
data = ast.literal_eval(raw)

# add data that will be append to main data
data2 = {'Spine4': {
    'password': 'vyos1',
    'ipaddress': '192.168.1.1',
    'user': 'vyos1'
}}

# append the data2 to data
data["host"].update(data2)

# check data
print (data)

jalankan program tersebut :

zufar@zufar:~/Documents/Technology/Programming/Python/mysql-dict$ python program.py
{'host': {'Spine1': {'password': 'vyos1', 'ipaddress': '192.168.1.1', 'user': 'vyos1'}, 'Spine2': {'password': 'vyos2', 'ipaddress': '192.168.2.1', 'user': 'vyos2'}, 'Spine4': {'password': 'vyos1', 'ipaddress': '192.168.1.1', 'user': 'vyos1'}}}

oke, bisa terlihat data tertambahkan. mari kita coba perbaiki agar mudah dibaca :

{
    'host': {
        'Spine1': {
            'password': 'vyos1',
            'ipaddress': '192.168.1.1',
            'user': 'vyos1'
        },
        'Spine2': {
            'password': 'vyos2',
            'ipaddress': '192.168.2.1',
            'user': 'vyos2'
        },
        'Spine4': {
            'password': 'vyos1',
            'ipaddress': '192.168.1.1',
            'user': 'vyos1'
        }
    }
}

 

 

Paramiko with SSH-Keys

Paramiko bukan hanya sebuah module untuk melakukan SSH ke perangkat jaringan. tetapi bisa kedalam sebuah standard server. paramiko dapat menggunakan SSH key untuk masuk selain menggunakan password. pertama, generate key di server python.

ubuntu@ubuntu:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ubuntu/.ssh/id_rsa): 
Created directory '/home/ubuntu/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/ubuntu/.ssh/id_rsa.
Your public key has been saved in /home/ubuntu/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:WY7Ejx0t7B5J/kwmXA72QFVagbkqVpeGXfgkMaaMbow ubuntu@ubuntu
The key's randomart image is:
+---[RSA 2048]----+
|          ..=*+. |
|       . = +=+o  |
|        + %o+B   |
|       = #oX* .  |
|      E S.@+=    |
|       .o..B     |
|       . .. o    |
|                 |
|                 |
+----[SHA256]-----+
ubuntu@ubuntu:~$ cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDByQCm4EoUysOguza03n/FYdvfCKn/zMzVMin7saoWmdMnV05MTGjn4rB8XZigsC2UNMfVikfKcH0owGTuXZjMQtKaidxQkMGNZxEZPKyT9kXRfPrdSTAcbi0Flq4daHQils3cLrOd3O2F4Q2XFEI5U24rlOupTgvhpTVjpNl+++ha31oQ/3iNmeHzVe1HjyzZMxeqoOGLqciSw/MbaMVq+pTnz14nkcjuYB6FtNGcPfp6e51lnY/rfIIEwTdbddKzG0DtPplXpZJGhLeelRV+K5FAut+qF8hbMcfEb8922LPy93F0kq3CeW3UPgMB0hGcOQhXF5O66qkOcdsnia8j ubuntu@ubuntu

copykan public key yang digenerate kedalam directory user (file authorized_keys) yang diinginkan (root atau user biasa) di server yang ingin diotomasi :

root@ubuntu:~# mkdir .ssh/
root@ubuntu:~# nano .ssh/authorized_keys

buat program

import sys
import time
import paramiko

host = str(sys.argv[1])
port = int(sys.argv[2])
user = str(sys.argv[3])

# Create Session
session = paramiko.SSHClient()

# get private key from user
key = paramiko.RSAKey.from_private_key_file('/home/ubuntu/.ssh/id_rsa')

# set policy when connecting to server with unknown host key and add hostname & key to known_hosts
session.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# Connect to Server
session.connect(host, username=user, port=port, pkey=key)

# invoke a shell
shell = session.invoke_shell()

# send command to device
shell.send("pwd")

# add time to be able to load all data
time.sleep(1)

# receive data in maximal 5000 bytes
output = shell.recv(5000)

# print the output
print(output)

# close the session
shell.close()

jalankan program tersebut

ubuntu@ubuntu:~/paramiko$ python lab2.py "192.168.122.60" 22 "root"
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-116-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

99 packages can be updated.
47 updates are security updates.


Last login: Fri Jul 13 10:13:20 2018 from 192.168.122.129
pwdroot@ubuntu:~# pwd
ubuntu@ubuntu:~/paramiko$

Basic Paramiko

paramiko adalah module yang mengimplementasikan SSHv2 yang bekerja dibalik ansible. berikut instalasi paramiko

sudo pip install paramiko

tutorial kali ini menjalankan paramiko di perangkat cisco router. yang pertama harus dilakukan adalah mengeset cisco router untuk SSH

R1#
R1#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R1(config)#hostname R1
R1(config)#ip domain-name btech.id  
R1(config)#crypto key generate rsa 
The name for the keys will be: R1.btech.id
Choose the size of the key modulus in the range of 360 to 2048 for your
  General Purpose Keys. Choosing a key modulus greater than 512 may take
  a few minutes.

How many bits in the modulus [512]: 1024
% Generating 512 bit RSA keys, keys will be non-exportable...[OK]

*Mar  1 00:14:27.519:  RSA key size needs to be atleast 768 bits for ssh version 2
*Mar  1 00:14:27.523: %SSH-5-ENABLED: SSH 1.5 has been enabled
R1(config)#username btech privilege 15 secret passbtech
R1(config)#line vty 0 4
R1(config-line)#login local
R1(config-line)#transport input ssh 
R1(config)#ip ssh version 2

sekarang kita buat program untuk menunjukan interface :

import sys
import time
import paramiko

host = str(sys.argv[1])
port = int(sys.argv[2])
user = str(sys.argv[3])
passwd = str(sys.argv[4])

# Create Session
session = paramiko.SSHClient()

# set policy when connecting to server with unknown host key and add hostname & key to known_hosts
session.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# Connect to Cisco Router
# disable looking for private key in .ssh/
# disable connecting to SSH Agent
session.connect(host, username=user, password=passwd,port=port, look_for_keys=False, allow_agent=False)

# invoke a shell
shell = session.invoke_shell()

# send command to device
shell.send("show ip int br\n")

# add time to be able to load all data
time.sleep(1)

# receive data in maximal 5000 bytes
output = shell.recv(5000)

# print the output
print(output)

# close the session
shell.close()

jalankan program tersebut

ubuntu@ubuntu:~/paramiko$ python lab1.py "192.168.122.250" 22 "btech" "passbtech"

R1#show ip int br
Interface                  IP-Address      OK? Method Status                Protocol
FastEthernet0/0            192.168.122.250 YES DHCP   up                    up      
FastEthernet0/1            unassigned      YES unset  administratively down down    
R1#
ubuntu@ubuntu:~/paramiko$ 

 

Creating Static Configuration Template with jinja2

membuat konfigurasi perangkat jaringan melelahkan jika kita membuatnya satu persatu. alangkah baiknya dilakukan dengan cara lain yaitu menggunakan python dengan jinja2 template. yang pertama harus dilakukan adalah membuat template jinja2 (template.j2) :

set system host-name {{ hostname }}
{% for interface in interface_list.ethernet %}
set interface {{ interface.type }} {{ interface.name }} address {{ interface.address}}
set interface {{ interface.type }} {{ interface.name }} description "{{ interface.description }}"
{% endfor %}

setelah itu, buat file inventory yang akan diisikan (inventory.yaml) :

system:
  hostname: "R1"
interface:
  ethernet:
    - name: "eth0"
      address: "192.168.1.1/24"
      description: "Ethernet0 Configuration"
      type: "ethernet"
    - name: "eth1"
      address: "192.168.2.1/24"
      description: "Ethernet1 Configuration"
      type: "ethernet"

lalu buat script pythonnya :

import yaml
from jinja2 import Environment, FileSystemLoader

# open json and read into raw text
raw = open('inventory.yaml').read()
 
# loads the raw into loads() function to create dict
data = yaml.load(raw)

# Set environment jinja2 in current folder
ENV = Environment(loader=FileSystemLoader('.'))

# get template from jinja2
template = ENV.get_template("template.j2")

# parse and print template jinja2 with variable from yaml
print(template.render(hostname=data["system"]["hostname"],interface_list=data["interface"]))

setelah itu coba jalankan script pythonnya :

zufar@zufar:~/Documents/Technology/Programming/Python/configuration$ python program.py
set system host-name R1

set interface ethernet eth0 address 192.168.1.1/24
set interface ethernet eth0 description "Ethernet0 Configuration"

set interface ethernet eth1 address 192.168.2.1/24
set interface ethernet eth1 description "Ethernet1 Configuration"

zufar@zufar:~/Documents/Technology/Programming/Python/configuration$

Multi Device Configuration with telnetlib

untuk melakukan konfigurasi ke beberapa device sekaligus, kita dapat memanfaatkan fungsi looping seperti for untuk melakukan ini :

# Import module
import telnetlib
import time
import ast

# open json and read into raw text
raw = open('inventory.json').read()

# loads the raw into loads() function to create dict string type
data = ast.literal_eval(raw)

# define looping variable
looping = 0

# using looping
for host in data["host"]:

    # open connection
    connect = telnetlib.Telnet(host=data["host"][looping])

    # find prompt login?
    connect.read_until('login: ')

    # enter username
    connect.write(data["username"][looping]+'\n')

    # find prompt password?
    connect.read_until('Password: ')

    # enter password
    connect.write(data["password"][looping]+'\n')

    # find prompt $?
    connect.read_until('$ ')

    # Enter Configure Mode
    connect.write('configure\n')

    # find prompt #?
    connect.read_until('# ')

    # Enter Configure Mode
    connect.write('set system host-name '+data["hostname"][looping]+'\n')

    # Commit and save
    connect.write('commit\n')
    connect.write('save\n')

    # show interfaces
    connect.write('run show configuration\n')

    # read output
    time.sleep(1)
    output =  connect.read_very_eager()
    print (output)

    # close connection
    connect.close()

    # increase looping variable
    looping = looping + 1

lalu buat file inventorynya :

{
    "host":["192.168.122.250","192.168.122.146"],
    "username":["vyos","vyos"],
    "password":["vyos","vyos"],
    "hostname":["R1","R2"]
}

bisa dilihat bahwa  script python diatas akan membaca berapa jumlah host yang ada didalam dictionary lalu melakukan eksekusi untuk mengkonfigurasi hostname. berikut output yang dikeluarkan :

zufar@zufar:~/Documents/Technology/Programming/Python/telnetlib$ python lab7.py
set system host-name R1

  Configuration path: [system host-name R1] already exists

[edit]
vyos@R1# commit
No configuration changes to commit
[edit]
vyos@R1# save
Saving configuration to '/config/config.boot'...
Done
[edit]
vyos@R1# run show configuration
interfaces {
    ethernet eth0 {
        address dhcp
        hw-id 0c:a4:23:bf:21:00
    }
    loopback lo {
    }
}
service {
    telnet {
    }
}
system {
    config-management {
        commit-revisions 20
    }
    console {
        device ttyS0 {
            speed 9600
        }
    }
    host-name R1
    login {
:
set system host-name R2
[edit]
vyos@vyos# commit
[ system host-name R2 ]
Stopping enhanced syslogd: rsyslogd.
Starting enhanced syslogd: rsyslogd.

[edit]
vyos@vyos# save
Saving configuration to '/config/config.boot'...
Done
[edit]
vyos@vyos# run show configuration
interfaces {
    ethernet eth0 {
        address dhcp
        hw-id 0c:a4:23:a7:1f:00
    }
    loopback lo {
    }
}
service {
    telnet {
    }
}
system {
    config-management {
        commit-revisions 20
    }
    console {
        device ttyS0 {
            speed 9600
        }
    }
    host-name R2
    login {
:
zufar@zufar:~/Documents/Technology/Programming/Python/telnetlib$

 

1 2