Junos PyEZ använder exemplet på uppgiften att söka efter gratis ipv4-undernät

En artikel om att arbeta med Junos PyEZ - "Python microframework som gör det möjligt för dig att hantera och automatisera enheter som kör Junos OS" automation och hantering, allt vi älskar. Att skriva skriptet som beskrivs i den här artikeln hade flera mål - att lära sig Python och automatisera uppgifter för att samla in information eller ändra konfigurationer på utrustning som kör Junos OS. Valet av denna specifika kombination av Python + Junos PyEZ gjordes på grund av den låga barriären för inträde i Python-programmeringsspråket och den enkla användningen av Junos PyEZ-biblioteket, som inte kräver expertkunskaper om Junos OS.

Uppgift

Granskning av gratis ipv4-undernät som tillhör företaget. Kriteriet att ett subnät är gratis är frånvaron av en post om det i rutterna på switchen som fungerar som en router som kör Junos OS.

genomförande

Python + Junos PyEZ, även om det fanns en frestelse att göra det genom paramiko och ssh.exec_command, Som ett resultat måste du konfigurera netconf-enhetens nätverkshanteringsprotokoll på den utrustning som avfrågas. Netconf arbetar med hårdvara via fjärrproceduranrop RPC och använder XML, i det här exemplet, för att tillhandahålla den information den tar emot.

Installation av den aktuella versionen av Junos PyEZ från PyPI görs med följande kommando:

$ pip install junos-eznc

Du kan också installera från projektets huvudgren på GitHub med följande kommando:

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

Och ytterligare ett alternativ via

$ pip install -r requirements.txt 

Detta kommando kommer att installera bibliotek som saknas i systemet och som är nödvändiga för drift. I min version requirements.txt Det finns bara två av dem, de senaste versionerna anges när manuset skrevs:

junos-eznc
netaddr

Som standard tar skriptet namnet på den aktuella användaren i systemet; du kan logga in under namnet på en annan användare med hjälp av show_route.py -u-tangenten getpass.getpass tar lösenordet från stdin så lösenordet kommer inte att finnas kvar i systemet. För att ansluta till utrustningen måste du också ange dess värdnamn eller IP-adress när du uppmanas att göra det. Alla data som behövs för auktorisering på enheten har tagits emot.

Junos PyEZ stöder anslutning till utrustning som kör Junos OS med hjälp av konsolen, telnet eller netconf via ssh. Artikeln diskuterar det senare alternativet.

För att ansluta till utrustning, använd enhetsklassen för jnpr.junos-modulen

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

En begäran görs för alla rutter som är kända för routern via fjärrproceduranrop eller fjärrproceduranrop, beroende på vilket som är lämpligast.

data = dev.rpc.get_route_information()

Liknande kommando på Junos OS

user@router> show route | display xml

Genom att lägga till rpc i slutet av kommandot får vi en request-tagg och kan matcha den med namnet på RPC-metoden, på så sätt kan vi ta reda på andra namn av intresse. Det är värt att notera att syntaxen för att skriva begärantaggen skiljer sig från metodnamnet, nämligen att du bör ersätta bindestreck med understreck.

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

Resten av delen lindades in i en while-loop, för att inte upprepa begäran till routern om det var nödvändigt att checka in ett annat subnät från de som routern redan känner till. Det är värt att nämna att routern som jag gör förfrågan på känner till rutter endast genom OSPF, så för en kantrouter är det bättre att ändra förfrågan lite för att minska skriptets körtid

data = dev.rpc.get_ospf_route_information()

Låt oss nu titta på innehållet i while-slingan

I början kommer användaren att bli ombedd att ange ett subnät med en mask och inte mer än tre oktetter från nätverket i samma subnät, detta är nödvändigt för att ställa in sökintervallet. Jag gillar inte riktigt den här implementeringen av att specificera kriterierna och sökintervallet, men än så länge har jag inte hittat en bättre lösning. Därefter, från den resulterande listan över subnät route_list, med en variabel som innehåller högst tre oktetter, väljer jag de subnät som intresserar mig

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

Genom IPNetwork, netaddr-modulen, tar jag emot subnät i form av en lista med ipv4-adresser

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

Med IPNetwork hämtar jag en rad adresser från ett användarinmatat nätverk med en mask och genererar en lista över alla adresser från detta område för jämförelse med listan över upptagna adresser.

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

Jag visar den resulterande listan med lediga adresser i form av subnät

print(netaddr.IPSet(freeip))

Nedan är det kompletta skriptet, testat på switchar som används som router, 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

Källa: will.com

Lägg en kommentar