Junos PyEZ bruker eksemplet på oppgaven med å søke etter gratis ipv4-undernett

En artikkel om å jobbe med Junos PyEZ - "Python mikrorammeverk som lar deg administrere og automatisere enheter som kjører Junos OS" automatisering og administrasjon, alt vi elsker. Å skrive skriptet beskrevet i denne artikkelen hadde flere mål – å lære Python og automatisere oppgaver for å samle informasjon eller endre konfigurasjoner på utstyr som kjører Junos OS. Valget av denne spesifikke kombinasjonen av Python + Junos PyEZ ble gjort på grunn av den lave barrieren for å komme inn i Python-programmeringsspråket og brukervennligheten til Junos PyEZ-biblioteket, som ikke krever ekspertkunnskap om Junos OS.

Oppgave

Revisjon av gratis ipv4-undernett som tilhører selskapet. Kriteriet for at et subnett er gratis er fraværet av en oppføring om det i rutene på svitsjen som fungerer som en ruter som kjører Junos OS.

implementering

Python + Junos PyEZ, selv om det var en fristelse å gjøre det gjennom paramiko og ssh.exec_command, Som et resultat må du konfigurere netconf-enhetens nettverksadministrasjonsprotokoll på utstyret som polles. Netconf jobber med maskinvare via ekstern prosedyrekall RPC og bruker XML, i dette eksemplet, for å gi informasjonen den mottar.

Installering av gjeldende versjon av Junos PyEZ fra PyPI gjøres med følgende kommando:

$ pip install junos-eznc

Du kan også installere fra hovedgrenen til prosjektet på GitHub med følgende kommando:

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

Og ett alternativ til via

$ pip install -r requirements.txt 

Denne kommandoen vil installere biblioteker som mangler i systemet og er nødvendige for drift. I min versjon krav.txt Det er bare to av dem, de nyeste versjonene er angitt når manuset skrives:

junos-eznc
netaddr

Skriptet tar som standard navnet på gjeldende bruker i systemet, du kan logge inn under navnet til en annen bruker ved å bruke nøkkelen show_route.py -u getpass.getpass tar passordet fra stdin slik at passordet ikke blir værende i systemet. For å koble til utstyret, må du også angi vertsnavnet eller IP-adressen når du blir bedt om det. Alle data som er nødvendige for autorisasjon på enheten er mottatt.

Junos PyEZ støtter tilkobling til utstyr som kjører Junos OS ved å bruke konsollen, telnet eller netconf via ssh. Artikkelen diskuterer det siste alternativet.

For å koble til utstyr, bruk Enhetsklassen til jnpr.junos-modulen

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

En forespørsel gjøres for alle ruter kjent for ruteren via ekstern prosedyrekall eller ekstern prosedyrekall, avhengig av hva som er mest praktisk.

data = dev.rpc.get_route_information()

Lignende kommando på Junos OS

user@router> show route | display xml

Ved å legge til rpc på slutten av kommandoen får vi en request tag og kan matche den med navnet på RPC-metoden, på denne måten kan vi finne ut andre navn av interesse. Det er verdt å merke seg at syntaksen for å skrive forespørselskoden er forskjellig fra metodenavnet, nemlig at du bør erstatte bindestrekene med understrekinger.

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

Resten av delen ble pakket inn i en while-løkke, for ikke å gjenta forespørselen til ruteren hvis det var nødvendig å sjekke inn et annet subnett fra de som ruteren allerede vet om. Det er verdt å nevne at ruteren som jeg sender forespørselen på kjenner ruter kun gjennom OSPF, så for en kantruter er det bedre å endre forespørselen litt for å redusere skriptets kjøretid

data = dev.rpc.get_ospf_route_information()

La oss nå se på innholdet i while-løkken

I begynnelsen vil brukeren bli bedt om å angi et undernett med en maske og ikke mer enn tre oktetter fra nettverket til samme undernett, dette er nødvendig for å angi søkeområdet. Jeg liker egentlig ikke denne implementeringen av å spesifisere kriteriene og søkeområdet, men så langt har jeg ikke funnet en bedre løsning. Deretter, fra den resulterende listen over undernett rute_liste, ved å bruke en variabel som ikke inneholder mer enn tre oktetter, velger jeg undernettene som interesserer meg

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

Gjennom IPNetwork, netaddr-modulen, mottar jeg subnett i form av en liste over ipv4-adresser

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

Ved å bruke IPNetwork henter jeg en rekke adresser fra et brukeroppgitt nettverk med en maske og genererer en liste over alle adresser fra dette området for sammenligning med listen over okkuperte adresser.

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

Jeg viser den resulterende listen over gratis adresser i form av undernett

print(netaddr.IPSet(freeip))

Nedenfor er det komplette skriptet, testet på brytere som brukes som ruter, modeller 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

Kilde: www.habr.com

Legg til en kommentar