Junos PyEZ utilizza l'esempio del compito di ricerca di sottoreti IPv4 libere

Un articolo sul lavoro con Junos PyEZ: "Microframework Python che consente di gestire e automatizzare i dispositivi che eseguono il sistema operativo Junos", automazione e gestione, tutto ciò che amiamo. La scrittura dello script descritto in questo articolo aveva diversi obiettivi: apprendere Python e automatizzare le attività per la raccolta di informazioni o la modifica delle configurazioni sulle apparecchiature che eseguono il sistema operativo Junos. La scelta di questa specifica combinazione di Python + Junos PyEZ è stata fatta per la bassa barriera all'ingresso nel linguaggio di programmazione Python e per la facilità d'uso della libreria Junos PyEZ, che non richiede una conoscenza approfondita del sistema operativo Junos.

Compito

Audit delle sottoreti ipv4 libere di proprietà dell'azienda. Il criterio per definire libera una sottorete è l'assenza di una voce relativa nei percorsi sullo switch che funge da router con sistema operativo Junos.

implementazione

Python + Junos PyEZ, anche se c'era la tentazione di farlo tramite paramiko e ssh.exec_command, Di conseguenza, sarà necessario configurare il protocollo di gestione della rete del dispositivo netconf sull'apparecchiatura sottoposta a polling. Netconf funziona con l'hardware tramite una chiamata di procedura remota RPC e utilizza XML, in questo esempio, per fornire le informazioni che riceve.

L'installazione della versione corrente di Junos PyEZ da PyPI viene eseguita con il seguente comando:

$ pip install junos-eznc

Puoi anche installare dal ramo principale del progetto su GitHub con il seguente comando:

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

E un'altra opzione tramite

$ pip install -r requirements.txt 

Questo comando installerà le librerie mancanti nel sistema e necessarie per il funzionamento. Nella mia versione requirements.txt Ce ne sono solo due, le ultime versioni sono indicate al momento della stesura della sceneggiatura:

junos-eznc
netaddr

Per impostazione predefinita, lo script prende il nome dell'utente corrente nel sistema; puoi accedere con il nome di un altro utente utilizzando la chiave show_route.py -u getpass.getpass prende la password da stdin quindi la password non rimarrà nel sistema. Per connettersi all'apparecchiatura, sarà inoltre necessario inserire il nome host o l'indirizzo IP quando richiesto. Sono stati ricevuti tutti i dati necessari per l'autorizzazione sul dispositivo.

Junos PyEZ supporta la connessione ad apparecchiature che eseguono il sistema operativo Junos utilizzando la console, telnet o netconf tramite ssh. L'articolo discute quest'ultima opzione.

Per connettersi all'apparecchiatura, utilizzare la classe Device del modulo jnpr.junos

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

Viene effettuata una richiesta per tutti i percorsi noti al router tramite chiamata di procedura remota o chiamata di procedura remota, a seconda di quale sia più conveniente.

data = dev.rpc.get_route_information()

Comando simile sul sistema operativo Junos

user@router> show route | display xml

Aggiungendo rpc alla fine del comando otteniamo un tag di richiesta e possiamo abbinarlo al nome del metodo RPC, in questo modo possiamo scoprire altri nomi di interesse. Vale la pena notare che la sintassi per scrivere il tag di richiesta è diversa dal nome del metodo, ovvero è necessario sostituire i trattini con caratteri di sottolineatura.

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

Il resto della parte è stato avvolto in un ciclo while, in modo da non ripetere la richiesta al router nel caso fosse necessario controllare in un'altra sottorete tra quelle che il router già conosce. Vale la pena ricordare che il router su cui sto effettuando la richiesta conosce i percorsi solo tramite OSPF, quindi per un router edge è meglio modificare leggermente la richiesta per ridurre il tempo di esecuzione dello script

data = dev.rpc.get_ospf_route_information()

Ora diamo un'occhiata al contenuto del ciclo while

All'inizio verrà chiesto all'utente di inserire una sottorete con maschera e non più di tre ottetti dalla rete della stessa sottorete, questo è necessario per impostare l'intervallo di ricerca. Non mi piace molto questa implementazione di specificare i criteri e l’intervallo di ricerca, ma finora non ho trovato una soluzione migliore. Successivamente, dall'elenco risultante delle sottoreti route_list, utilizzando una variabile contenente non più di tre ottetti, seleziono le sottoreti che mi interessano

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

Tramite IPNetwork, il modulo netaddr, ricevo le sottoreti sotto forma di elenco di indirizzi ipv4

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

Utilizzando IPNetwork, ottengo un intervallo di indirizzi da una rete inserita dall'utente con una maschera e genero un elenco di tutti gli indirizzi di questo intervallo per il confronto con l'elenco degli indirizzi occupati.

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

Visualizzo l'elenco risultante di indirizzi liberi sotto forma di sottoreti

print(netaddr.IPSet(freeip))

Di seguito è riportato lo script completo, testato su switch utilizzati come router, modelli 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

Fonte: habr.com

Aggiungi un commento