Junos PyEZ gebruik die voorbeeld van die taak om gratis ipv4-subnette te soek

'n Artikel oor die werk met Junos PyEZ - "Python-mikroraamwerk wat jou in staat stel om toestelle met Junos OS"-outomatisering en -bestuur te bestuur en te outomatiseer, alles waarvan ons hou. Die skryf van die skrif wat in hierdie artikel beskryf word, het verskeie doelwitte gehad - om Python te leer en take te outomatiseer vir die insameling van inligting of die verandering van konfigurasies op toerusting wat Junos OS bestuur. Die keuse van hierdie spesifieke kombinasie van Python + Junos PyEZ is gemaak as gevolg van die lae hindernis vir toegang tot die Python-programmeertaal en die gebruiksgemak van die Junos PyEZ-biblioteek, wat nie kundige kennis van Junos OS vereis nie.

Taak

Oudit van gratis ipv4-subnette wat aan die maatskappy behoort. Die maatstaf dat 'n subnet gratis is, is die afwesigheid van 'n inskrywing daaroor in die roetes op die skakelaar wat optree as 'n router wat Junos OS bestuur.

Implementering

Python + Junos PyEZ, hoewel daar 'n versoeking was om dit te doen deur paramiko en ssh.exec_command, As gevolg hiervan sal u die netconf-toestelnetwerkbestuurprotokol moet opstel op die toerusting wat gepeil word. Netconf werk met hardeware via afstandprosedure-oproep RPC en gebruik XML, in hierdie voorbeeld, om die inligting te verskaf wat dit ontvang.

Die installering van die huidige weergawe van Junos PyEZ vanaf PyPI word gedoen met die volgende opdrag:

$ pip install junos-eznc

U kan ook vanaf die hooftak van die projek op GitHub installeer met die volgende opdrag:

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

En nog een opsie via

$ pip install -r requirements.txt 

Hierdie opdrag sal biblioteke installeer wat in die stelsel ontbreek en wat nodig is vir werking. In my weergawe vereistes.txt Daar is net twee van hulle, die nuutste weergawes word aangedui ten tyde van die skryf van die draaiboek:

junos-eznc
netaddr

By verstek neem die script die naam van die huidige gebruiker in die stelsel aan; jy kan aanmeld onder die naam van 'n ander gebruiker met die show_route.py -u sleutel getpass.getpass neem die wagwoord van stdin af sodat die wagwoord nie in die stelsel sal bly nie. Om aan die toerusting te koppel, sal jy ook sy gasheernaam of IP-adres moet invoer wanneer dit gevra word. Alle data wat nodig is vir magtiging op die toestel is ontvang.

Junos PyEZ ondersteun verbinding met toerusting wat Junos OS gebruik deur die konsole, telnet of netconf via ssh te gebruik. Die artikel bespreek laasgenoemde opsie.

Om aan toerusting te koppel, gebruik die Toestelklas van die jnpr.junos-module

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

'n Versoek word gemaak vir alle roetes wat aan die roeteerder bekend is via afstandprosedure-oproep of afstandprosedure-oproep, wat ook al die gerieflikste is.

data = dev.rpc.get_route_information()

Soortgelyke opdrag op Junos OS

user@router> show route | display xml

Deur rpc aan die einde van die opdrag by te voeg, kry ons 'n versoekmerker en kan dit ooreenstem met die naam van die RPC-metode, op hierdie manier kan ons ander name van belang uitvind. Dit is opmerklik dat die sintaksis vir die skryf van die versoekmerker verskil van die metodenaam, naamlik dat u die koppeltekens met onderstrepings moet vervang.

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

Die res van die deel is in 'n rukkie-lus toegedraai, om nie die versoek aan die router te herhaal as dit nodig was om 'n ander subnet in te gaan van dié waarvan die router reeds weet nie. Dit is die moeite werd om te noem dat die roeteerder waarop ek die versoek rig roetes slegs deur OSPF ken, so vir 'n randroeteerder is dit beter om die versoek 'n bietjie te verander om die skrip se looptyd te verminder

data = dev.rpc.get_ospf_route_information()

Kom ons kyk nou na die inhoud van die while lus

Aan die begin sal die gebruiker gevra word om 'n subnet met 'n masker in te voer en nie meer as drie oktette vanaf die netwerk van dieselfde subnet nie, dit is nodig om die soekreeks in te stel. Ek hou nie regtig van hierdie implementering om die kriteria en soekreeks te spesifiseer nie, maar tot dusver het ek nie 'n beter oplossing gevind nie. Volgende, uit die resulterende lys van subnette route_list, met behulp van 'n veranderlike wat nie meer as drie oktette bevat nie, kies ek die subnette wat my interesseer

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

Deur IPNetwork, die netaddr-module, ontvang ek subnette in die vorm van 'n lys ipv4-adresse

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

Deur IPNetwork te gebruik, kry ek 'n reeks adresse van 'n gebruiker-ingevoerde netwerk met 'n masker en genereer 'n lys van alle adresse uit hierdie reeks vir vergelyking met die lys van besette adresse.

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

Ek vertoon die gevolglike lys gratis adresse in die vorm van subnette

print(netaddr.IPSet(freeip))

Hieronder is die volledige skrif, getoets op skakelaars wat as 'n router gebruik word, modelle 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

Bron: will.com

Voeg 'n opmerking