Junos PyEZ doako ipv4 azpisareak bilatzeko zereginaren adibidea erabiliz

Junos PyEZ-ekin lan egiteari buruzko artikulu bat - "Junos OS exekutatzen duten gailuak kudeatu eta automatizatzeko aukera ematen dizun Python microframework" automatizazioa eta kudeaketa, maite dugun guztia. Artikulu honetan deskribatutako scripta idazteak hainbat helburu zituen: Python ikastea eta Junos OS exekutatzen duten ekipoetan informazioa biltzeko edo konfigurazioak aldatzeko zereginak automatizatzea. Python + Junos PyEZ-en konbinazio espezifiko hau aukeratzea Python programazio-lengoaian sartzeko oztopo baxuaren ondorioz eta Junos PyEZ liburutegiaren erabilera errazaren ondorioz egin da, ez baitu Junos OS-en ezagutza aditurik behar.

Task

Enpresaren doako ipv4 azpisareen auditoretza. Azpisare bat librea den irizpidea Junos OS exekutatzen duen bideratzaile gisa jarduten duen switch-eko bideetan horri buruzko sarrerarik ez izatea da.

Inplementazioa

Python + Junos PyEZ, paramiko eta ssh.exec_command bidez egiteko tentazioa egon bazen ere, Ondorioz, netconf gailuen sarearen kudeaketa protokoloa konfiguratu beharko duzu galdetzen ari den ekipoan. Netconf-ek hardwarearekin lan egiten du urruneko prozedura-deiaren bidez RPC eta XML erabiltzen du, adibide honetan, jasotzen duen informazioa emateko.

PyPI-tik Junos PyEZ-en uneko bertsioa instalatzea komando honekin egiten da:

$ pip install junos-eznc

GitHub-en proiektuaren adar nagusitik ere instala dezakezu komando honekin:

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

Eta beste aukera bat bidez

$ pip install -r requirements.txt 

Komando honek sisteman falta diren eta funtzionatzeko beharrezkoak diren liburutegiak instalatuko ditu. Nire bertsioan eskakizunak.txt Bi bakarrik daude, azken bertsioak gidoia idazteko momentuan adierazten dira:

junos-eznc
netaddr

Lehenespenez, scriptak sistemako uneko erabiltzailearen izena hartzen du; beste erabiltzaile baten izenarekin saioa hasi dezakezu show_route.py gakoa erabiliz -u getpass.getpass-ek stdin-etik pasahitza onartzen du, beraz, pasahitza ez da izango. sisteman geratu. Ekipamendura konektatzeko, bere ostalari-izena edo IP helbidea ere sartu beharko duzu eskatzen zaizunean. Gailuan baimentzeko beharrezkoak diren datu guztiak jaso dira.

Junos PyEZ-ek Junos OS exekutatzen duten ekipoetara konektatzea onartzen du kontsola, telnet edo netconf erabiliz ssh bidez. Artikuluak azken aukera hau eztabaidatzen du.

Ekipamendura konektatzeko, erabili jnpr.junos moduluko Gailu klasea

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

Bideratzaileak ezagutzen dituen ibilbide guztietarako eskaera egiten da urruneko prozedura-deiaren edo urruneko prozedura-deien bidez, erosoena dena.

data = dev.rpc.get_route_information()

Antzeko komandoa Junos OS-n

user@router> show route | display xml

Komandoaren amaieran rpc gehituz, eskaera etiketa bat lortzen dugu eta RPC metodoaren izenarekin lotu dezakegu, modu honetan interesgarri diren beste izen batzuk aurki ditzakegu. Aipatzekoa da eskaera etiketa idazteko sintaxia metodoaren izenatik ezberdina dela, hots, marratxoak azpimarraz ordezkatu behar dituzula.

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

Gainerako zatia while begizta batean bilduta zegoen, bideratzaileari eskaera errepikatu ez zedin, bideratzaileak lehendik ezagutzen dituen beste azpisare batean egiaztatu behar bazen. Aipatzekoa da eskaera egiten ari naizen bideratzaileak OSPF bidez bakarrik ezagutzen dituela ibilbideak, beraz, ertzeko bideratzaile baterako hobe da eskaera apur bat aldatzea scriptaren exekuzio-denbora murrizteko.

data = dev.rpc.get_ospf_route_information()

Ikus ditzagun while begiztaren edukia

Hasieran, erabiltzaileari azpisare bat sartzeko eskatuko zaio maskara batekin eta hiru zortzikote baino gehiago azpisare bereko saretik, hau beharrezkoa da bilaketa-tartea ezartzeko. Ez zait asko gustatzen irizpideak eta bilaketa-barrutia zehaztearen ezarpen hau, baina orain arte ez dut irtenbide hoberik aurkitu. Ondoren, ondoriozko azpisareen zerrendatik route_list, hiru zortzikote baino gehiago ez dituen aldagai bat erabiliz, interesatzen zaizkidan azpisareak hautatzen ditut.

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

IPNetwork, netaddr moduluaren bidez, azpisareak jasotzen ditut ipv4 helbideen zerrenda moduan

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

IPNetwork erabiliz, erabiltzaileak sartutako sare batetik helbide sorta bat lortzen dut maskara batekin eta sorta honetako helbide guztien zerrenda sortzen dut okupatutako helbideen zerrendarekin alderatzeko.

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

Sortutako doako helbideen zerrenda azpisare moduan bistaratzen dut

print(netaddr.IPSet(freeip))

Jarraian, script osoa dago, bideratzaile gisa erabiltzen diren etengailuetan probatua, ex4550, ex4600 ereduetan


#!/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

Iturria: www.habr.com

Gehitu iruzkin berria