Junos PyEZ utilizendu l'esempiu di u compitu di circà i subnets ipv4 gratuiti

Un articulu nantu à u travagliu cù Junos PyEZ - "Microframework Python chì vi permette di gestisce è automatizà i dispositi chì eseguenu Junos OS" automatizazione è gestione, tuttu ciò chì amemu. A scrittura di u script descrittu in questu articulu hà avutu parechji scopi - imparà Python è automatizà i travaglii per a cullizzioni d'infurmazioni o cambià a cunfigurazione nantu à l'equipaggiu chì esegue Junos OS. L'scelta di sta cumminazione specifica di Python + Junos PyEZ hè stata fatta per via di a bassa barriera per l'ingressu à a lingua di prugrammazione Python è a facilità d'utilizazione di a biblioteca Junos PyEZ, chì ùn hà micca bisognu di cunniscenze esperte di Junos OS.

Objettivu

Audit of free ipv4 subnets appartenenti à a cumpagnia. U criteriu chì una subnet hè libera hè l'absenza di una entrata nantu à questu in e rotte nantu à u switch chì agisce cum'è un router chì esegue Junos OS.

Реализация

Python + Junos PyEZ, ancu s'ellu ci era una tentazione di fà per mezu di paramiko è ssh.exec_command, In u risultatu, avete bisognu di cunfigurà u protokollu di gestione di a rete di u dispositivu netconf nantu à l'equipaggiu chì hè stata sonda. Netconf travaglia cù hardware per via di a prucedura remota chjamata RPC è usa XML, in questu esempiu, per furnisce l'infurmazioni chì riceve.

L'installazione di a versione attuale di Junos PyEZ da PyPI hè fatta cù u cumandimu seguente:

$ pip install junos-eznc

Pudete ancu installà da u ramu principale di u prugettu in GitHub cù u cumandimu seguente:

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

È una altra opzione via

$ pip install -r requirements.txt 

Questu cumandimu installerà e librerie chì mancanu da u sistema è sò necessarii per u funziunamentu. In a mo versione esigenze.txt Ci sò solu dui, l'ultime versioni sò indicati à u mumentu di a scrittura di u script:

junos-eznc
netaddr

U script per difettu piglia u nome di l'utilizatore attuale in u sistema, pudete log in sottu u nome di un altru utilizatore utilizendu a chjave show_route.py -u getpass.getpass piglia a password da stdin perchè a password ùn resta micca. in u sistema. Per cunnette à l'equipaggiu, avete ancu bisognu di inserisce u so hostname o l'indirizzu IP quandu vi dumanda. Tutti i dati necessarii per l'autorizazione in u dispusitivu sò stati ricevuti.

Junos PyEZ supporta a cunnessione à l'equipaggiu chì esegue Junos OS utilizendu a cunsola, telnet o netconf via ssh. L'articulu discute l'ultima opzione.

Per cunnette à l'equipaggiu, utilizate a classa Dispositivu di u modulu jnpr.junos

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

Una dumanda hè fatta per tutte e rotte cunnisciute da u router via una chjama di procedura remota o una chjama di procedura remota, quale hè più cunvene.

data = dev.rpc.get_route_information()

Cumandante simile in Junos OS

user@router> show route | display xml

Agghiuncennu rpc à a fine di u cumandamentu, avemu un tag di dumanda è ponu currisponde à u nome di u metudu RPC, in questu modu pudemu truvà altri nomi d'interessu. Hè nutate chì a sintassi per scrive l'etiqueta di dumanda hè sfarente di u nome di u metudu, vale à dì, duvete rimpiazzà i trattini cù underscore.

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

U restu di a parte hè stata impannillata in un ciclu di tempu, per ùn ripetiri a dumanda à u router s'ellu era necessariu di verificà in una altra subnet da quelli chì u router hà digià cunnisciutu. Hè vale à dì chì u router nantu à quale aghju fattu a dumanda cunnosce e rotte solu per OSPF, cusì per un router di punta hè megliu cambià a dumanda un pocu per riduce u tempu di esecuzione di u script.

data = dev.rpc.get_ospf_route_information()

Avà fighjemu u cuntenutu di u ciclu while

À u principiu, l'utilizatore serà dumandatu à entre in una subnet cù una maschera è micca più di trè otteti da a reta di a listessa subnet, questu hè necessariu di stabilisce a gamma di ricerca. Ùn mi piace micca veramente sta implementazione di specificà i criterii è a gamma di ricerca, ma finu à avà ùn aghju micca truvatu una suluzione megliu. In seguitu, da a lista resultanti di subnets route_list, utilizendu una variàbile chì ùn cuntene micca più di trè ottetti, selezziunate i subnets chì m'interessanu.

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

Per mezu di IPNetwork, u modulu netaddr, riceve subnets in forma di una lista di indirizzi ipv4

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

Utilizendu IPNetwork, aghju ottene una gamma di indirizzi da una reta di l'utilizatori cù una maschera è generà una lista di tutti l'indirizzi da questa gamma per paragunà cù a lista di l'indirizzi occupati.

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

Puderaghju a lista resultanti di indirizzi gratuiti in forma di subnets

print(netaddr.IPSet(freeip))

Quì sottu hè u script cumpletu, pruvatu nantu à i switches utilizati cum'è router, mudelli 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

Source: www.habr.com

Add a comment