Junos PyEZ menggunakan contoh tugas mencari subnet ipv4 percuma

Artikel tentang bekerja dengan Junos PyEZ - "Kerangka mikro Python yang membolehkan anda mengurus dan mengautomasikan peranti yang menjalankan automasi dan pengurusan Junos OS", semua yang kami suka. Menulis skrip yang diterangkan dalam artikel ini mempunyai beberapa matlamat - mempelajari Python dan mengautomasikan tugas untuk mengumpul maklumat atau menukar konfigurasi pada peralatan yang menjalankan Junos OS. Pilihan gabungan khusus Python + Junos PyEZ ini dibuat kerana halangan rendah untuk masuk ke dalam bahasa pengaturcaraan Python dan kemudahan penggunaan perpustakaan Junos PyEZ, yang tidak memerlukan pengetahuan pakar tentang Junos OS.

Petugas

Audit subnet ipv4 percuma milik syarikat. Kriteria bahawa subnet adalah percuma ialah ketiadaan entri mengenainya dalam laluan pada suis yang bertindak sebagai penghala yang menjalankan Junos OS.

РСализация

Python + Junos PyEZ, walaupun terdapat godaan untuk melakukannya melalui paramiko dan ssh.exec_command, Akibatnya, anda perlu mengkonfigurasi protokol pengurusan rangkaian peranti netconf pada peralatan yang ditinjau. Netconf berfungsi dengan perkakasan melalui RPC panggilan prosedur jauh dan menggunakan XML, dalam contoh ini, untuk memberikan maklumat yang diterimanya.

Memasang versi semasa Junos PyEZ daripada PyPI dilakukan dengan arahan berikut:

$ pip install junos-eznc

Anda juga boleh memasang dari cawangan utama projek di GitHub dengan arahan berikut:

$ pip install git+https://github.com/Juniper/py-junos-eznc.git

Dan satu lagi pilihan melalui

$ pip install -r requirements.txt 

Perintah ini akan memasang perpustakaan yang tiada daripada sistem dan diperlukan untuk operasi. Dalam versi saya keperluan.txt Terdapat hanya dua daripadanya, versi terkini ditunjukkan semasa menulis skrip:

junos-eznc
netaddr

Skrip secara lalai mengambil nama pengguna semasa dalam sistem, anda boleh log masuk di bawah nama pengguna lain menggunakan kekunci show_route.py -u getpass.getpass mengambil kata laluan daripada stdin supaya kata laluan tidak akan kekal dalam sistem. Untuk menyambung ke peralatan, anda juga perlu memasukkan nama hos atau alamat IPnya apabila digesa. Semua data yang diperlukan untuk kebenaran pada peranti telah diterima.

Junos PyEZ menyokong penyambungan ke peralatan yang menjalankan Junos OS menggunakan konsol, telnet atau netconf melalui ssh. Artikel membincangkan pilihan terakhir.

Untuk menyambung ke peralatan, gunakan kelas Peranti modul jnpr.junos

with jnpr.junos.Device(host=router,
                           user=args.name,
                           passwd=password) as dev:

Permintaan dibuat untuk semua laluan yang diketahui oleh penghala melalui panggilan prosedur jauh atau panggilan prosedur jauh, yang mana lebih mudah.

data = dev.rpc.get_route_information()

Perintah serupa pada Junos OS

user@router> show route | display xml

Dengan menambahkan rpc pada akhir arahan, kami mendapat teg permintaan dan boleh memadankannya dengan nama kaedah RPC, dengan cara ini kami dapat mengetahui nama lain yang menarik. Perlu diingat bahawa sintaks untuk menulis teg permintaan adalah berbeza daripada nama kaedah, iaitu, anda harus menggantikan tanda sempang dengan garis bawah.

user@router> show route | display xml rpc
<rpc-reply >route_list = data.xpath("//rt-destination/text()")

Selebihnya bahagian itu dibalut dalam gelung sementara, supaya tidak mengulangi permintaan kepada penghala jika perlu menyemak subnet lain daripada subnet yang sudah diketahui oleh penghala. Perlu dinyatakan bahawa penghala tempat saya membuat permintaan mengetahui laluan hanya melalui OSPF, jadi untuk penghala tepi adalah lebih baik untuk menukar sedikit permintaan untuk mengurangkan masa berjalan skrip

data = dev.rpc.get_ospf_route_information()

Sekarang mari kita lihat kandungan gelung while

Pada mulanya, pengguna akan diminta untuk memasukkan subnet dengan topeng dan tidak lebih daripada tiga oktet dari rangkaian subnet yang sama, ini perlu untuk menetapkan julat carian. Saya tidak begitu menyukai pelaksanaan menentukan kriteria dan julat carian ini, tetapi setakat ini saya tidak menemui penyelesaian yang lebih baik. Seterusnya, daripada senarai subnet route_list yang terhasil, menggunakan pembolehubah yang mengandungi tidak lebih daripada tiga oktet, saya memilih subnet yang menarik minat saya

tmp = re.search(r'^%sS*' % subnet_search, route_list[i])

Melalui IPNetwork, modul netaddr, saya menerima subnet dalam bentuk senarai alamat ipv4

range_subnet = netaddr.IPNetwork(tmp.group(0))

Menggunakan IPNetwork, saya memperoleh pelbagai alamat daripada rangkaian yang dimasukkan pengguna dengan topeng dan menjana senarai semua alamat daripada julat ini untuk perbandingan dengan senarai alamat yang diduduki.

for i in set(net_list).difference(set(busyip)):
        freeip.append(i)

Saya memaparkan senarai alamat percuma yang terhasil dalam bentuk subnet

print(netaddr.IPSet(freeip))

Di bawah ialah skrip lengkap, diuji pada suis yang digunakan sebagai penghala, model ex4550, ex4600


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import getpass
import netaddr
import re
import sys

import jnpr.junos

parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user',
                    action='store',
                    dest='name',
                    help='Enter login from tacacs if it differs from the '
                         'username in the system.')
args = parser.parse_args()

if not args.name:
    args.name = getpass.getuser()    # Return the β€œlogin name” of the user.
router = input("Full routers name: ")
password = getpass.getpass("Password: ")

try:
    # Authenticates to a device running Junos, for get information about routs
    # into xml format and selects by tag.
    route_list = []
    with jnpr.junos.Device(host=router,
                           user=args.name,
                           passwd=password) as dev:
        data = dev.rpc.get_route_information()
    route_list = data.xpath("//rt-destination/text()")
except (jnpr.junos.exception.ConnectRefusedError,
        jnpr.junos.exception.ConnectUnknownHostError) as err:
    print("Equipment name or password wrong.")
    sys.exit(1)

while True:
    subnet = input("Net with mask: ")
    subnet_search = input("Input no more three octet: ")
    # Gets a list of busy IP addresses from the received subnets.
    busyip = []
    for i in range(len(route_list)):
        tmp = re.search(r'^%sS*' % subnet_search, route_list[i])
        if tmp:
            range_subnet = netaddr.IPNetwork(tmp.group(0))
            for ip in range_subnet:
                busyip.append("%s" % ip)
    range_subnet = netaddr.IPNetwork(subnet)
    # Gets list ip adresses from subnetworks lists.
    net_list = []
    for ip in range_subnet:
        net_list.append("%s" % ip)
    # Π‘omparing lists.
    freeip = []
    for i in set(net_list).difference(set(busyip)):
        freeip.append(i)
    print(netaddr.IPSet(freeip))

    request = input("To run request again enter yes or y, "
                    "press 'enter', complete request: ")
    if request in ("yes", "y"):
        continue
    else:
        print('Bye')
        break

Sumber: www.habr.com

Tambah komen