Junos PyEZ käyttäen esimerkkiä tehtävästä etsiä ilmaisia ​​ipv4-aliverkkoja

Artikkeli työskentelystä Junos PyEZ:n kanssa - "Python-mikrokehys, jonka avulla voit hallita ja automatisoida laitteita, joissa on Junos OS" automaatio ja hallinta, kaikki mitä rakastamme. Tässä artikkelissa kuvatun skriptin kirjoittamisella oli useita tavoitteita - Pythonin oppiminen ja tehtävien automatisointi tiedonkeruussa tai konfiguraatioiden muuttamisessa Junos-käyttöjärjestelmää käyttävissä laitteissa. Tämän erityisen Python + Junos PyEZ -yhdistelmän valinta johtui alhaisesta Python-ohjelmointikieleen pääsyn esteestä ja Junos PyEZ -kirjaston helppokäyttöisyydestä, mikä ei vaadi Junos OS:n asiantuntemusta.

Tehtävä

Yritykselle kuuluvien ilmaisten ipv4-aliverkkojen tarkastus. Kriteeri aliverkon vapaalle on se, että Junos OS:ää käyttävän reitittimenä toimivan kytkimen reiteillä ei ole sitä koskevaa merkintää.

Реализация

Python + Junos PyEZ, vaikka olikin houkutus tehdä se paramikon ja ssh.exec_commandin kautta, Tämän seurauksena sinun on määritettävä netconf-laitteen verkonhallintaprotokolla kyselyssä oleville laitteille. Netconf toimii laitteiston kanssa etäproseduurikutsun RPC:n kautta ja käyttää XML:ää tässä esimerkissä vastaanottamansa tiedon välittämiseen.

Junos PyEZ:n nykyisen version asentaminen PyPI:stä tehdään seuraavalla komennolla:

$ pip install junos-eznc

Voit myös asentaa projektin päähaaralta GitHubissa seuraavalla komennolla:

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

Ja vielä yksi vaihtoehto kautta

$ pip install -r requirements.txt 

Tämä komento asentaa kirjastot, jotka puuttuvat järjestelmästä ja ovat toiminnan kannalta välttämättömiä. Minun versiossani requirements.txt Niitä on vain kaksi, uusimmat versiot ilmoitetaan käsikirjoituksen kirjoittamisen yhteydessä:

junos-eznc
netaddr

Skripti ottaa oletuksena järjestelmän nykyisen käyttäjän nimen, voit kirjautua sisään toisen käyttäjän nimellä avaimella show_route.py -u getpass.getpass ottaa salasanan stdinistä, joten salasana ei jää järjestelmässä. Jotta voit muodostaa yhteyden laitteeseen, sinun on myös annettava sen isäntänimi tai IP-osoite pyydettäessä. Kaikki laitteen valtuutukseen tarvittavat tiedot on vastaanotettu.

Junos PyEZ tukee yhteyden muodostamista laitteisiin, joissa on Junos OS käyttämällä konsolia, telnetiä tai netconfia ssh:n kautta. Artikkelissa käsitellään jälkimmäistä vaihtoehtoa.

Käytä jnpr.junos-moduulin laiteluokkaa muodostaaksesi yhteyden laitteisiin

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

Pyyntö tehdään kaikille reitittimen tuntemille reiteille etämenettelykutsulla tai etämenettelykutsulla sen mukaan, kumpi on kätevämpää.

data = dev.rpc.get_route_information()

Samanlainen komento Junos OS:ssä

user@router> show route | display xml

Lisäämällä rpc komennon loppuun saamme pyyntötunnisteen ja voimme yhdistää sen RPC-menetelmän nimeen, jolloin voimme löytää muita kiinnostavia nimiä. On syytä huomata, että pyyntötunnisteen kirjoittamisen syntaksi eroaa menetelmän nimestä, eli sinun tulee korvata yhdysmerkit alaviivalla.

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

Loput osasta käärittiin while-silmukkaan, jotta pyyntöä ei toistettaisi reitittimelle, jos oli tarpeen tarkistaa toinen aliverkko niistä, joista reititin jo tietää. On syytä mainita, että reititin, jolle teen pyynnön, tietää reitit vain OSPF:n kautta, joten reunareitittimelle on parempi muuttaa pyyntöä hieman skriptin ajoajan lyhentämiseksi.

data = dev.rpc.get_ospf_route_information()

Katsotaanpa nyt while-silmukan sisältöä

Alussa käyttäjää pyydetään syöttämään aliverkko, jossa on maski ja enintään kolme oktettia saman aliverkon verkosta, tämä on tarpeen hakualueen määrittämiseksi. En todellakaan pidä tästä kriteerien ja hakualueen määrittämisestä, mutta toistaiseksi en ole löytänyt parempaa ratkaisua. Seuraavaksi valitsen tuloksena olevasta aliverkkoluettelosta reitti_lista käyttämällä muuttujaa, joka sisältää enintään kolme oktettia, ja valitsen minua kiinnostavat aliverkot

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

IPNetworkin, netaddr-moduulin kautta saan aliverkkoja ipv4-osoitteiden luettelon muodossa

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

IPNetworkin avulla hankin osoitteita käyttäjän syöttämästä verkosta maskilla ja luon luettelon kaikista tämän alueen osoitteista vertailua varten varattujen osoitteiden luetteloon.

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

Näytän tuloksena olevan luettelon ilmaisista osoitteista aliverkkojen muodossa

print(netaddr.IPSet(freeip))

Alla on täydellinen skripti, testattu reitittimenä käytetyillä kytkimillä, malleilla 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

Lähde: will.com

Lisää kommentti