Junos PyEZ billi tuża l-eżempju tal-kompitu ta 'tiftix għal subnets ipv4 b'xejn

Artiklu dwar ix-xogħol ma' Junos PyEZ - "Python microframework li jippermettilek timmaniġġja u awtomat tagħmir li jħaddem Junos OS" awtomazzjoni u ġestjoni, dak kollu li nħobbu. Il-kitba tal-iskrittura deskritta f'dan l-artikolu kellha diversi għanijiet - it-tagħlim ta 'Python u l-awtomatizzazzjoni tal-kompiti għall-ġbir ta' informazzjoni jew il-bidla tal-konfigurazzjonijiet fuq tagħmir li jħaddem Junos OS. L-għażla ta 'din il-kombinazzjoni speċifika ta' Python + Junos PyEZ saret minħabba l-ostaklu baxx għad-dħul fil-lingwa ta 'programmar Python u l-faċilità ta' użu tal-librerija Junos PyEZ, li ma teħtieġx għarfien espert ta 'Junos OS.

Kompitu

Verifika tas-subnets ipv4 b'xejn li jappartjenu lill-kumpanija. Il-kriterju li subnet hija ħielsa huwa n-nuqqas ta 'dħul dwarha fir-rotot fuq is-swiċċ li jaġixxi bħala router li jħaddem Junos OS.

Реализация

Python + Junos PyEZ, għalkemm kien hemm it-tentazzjoni li tagħmel dan permezz ta' paramiko u ssh.exec_command, Bħala riżultat, ser ikollok bżonn tikkonfigura l-protokoll tal-ġestjoni tan-netwerk tal-apparat netconf fuq it-tagħmir li qed jiġi mistħarreġ. Netconf jaħdem ma 'hardware permezz ta' sejħa proċedura remota RPC u juża XML, f'dan l-eżempju, biex jipprovdi l-informazzjoni li jirċievi.

L-installazzjoni tal-verżjoni attwali ta 'Junos PyEZ minn PyPI issir bil-kmand li ġej:

$ pip install junos-eznc

Tista 'wkoll tinstalla mill-fergħa prinċipali tal-proġett fuq GitHub bil-kmand li ġej:

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

U għażla oħra permezz

$ pip install -r requirements.txt 

Dan il-kmand se jinstalla libreriji li huma neqsin mis-sistema u li huma meħtieġa għat-tħaddim. Fil-verżjoni tiegħi rekwiżiti.txt Hemm tnejn minnhom biss, l-aħħar verżjonijiet huma indikati fil-ħin tal-kitba tal-iskrittura:

junos-eznc
netaddr

L-iskript awtomatikament jieħu l-isem tal-utent attwali fis-sistema, tista’ tidħol taħt l-isem ta’ utent ieħor billi tuża ċ-ċavetta show_route.py -u getpass.getpass jieħu l-password minn stdin sabiex il-password ma tibqax fis-sistema. Biex tikkonnettja mat-tagħmir, ser ikollok bżonn ukoll li ddaħħal l-isem tal-host jew l-indirizz IP tiegħu meta tintalab. Id-dejta kollha meħtieġa għall-awtorizzazzjoni fuq l-apparat waslet.

Junos PyEZ jappoġġja l-konnessjoni ma 'tagħmir li jħaddem Junos OS billi juża l-console, telnet jew netconf permezz ta' ssh. L-artikolu jiddiskuti l-aħħar għażla.

Biex tikkonnettja mat-tagħmir, uża l-klassi Device tal-modulu jnpr.junos

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

Issir talba għar-rotot kollha magħrufa lir-router permezz ta' sejħa ta' proċedura remota jew sejħa ta' proċedura remota, skont liema jkun l-aktar konvenjenti.

data = dev.rpc.get_route_information()

Kmand simili fuq Junos OS

user@router> show route | display xml

Billi żżid rpc fl-aħħar tal-kmand, niksbu tikketta ta 'talba u nistgħu nqabbluha mal-isem tal-metodu RPC, b'dan il-mod nistgħu nsibu ismijiet oħra ta' interess. Ta 'min jinnota li s-sintassi għall-kitba tat-tikketta tat-talba hija differenti mill-isem tal-metodu, jiġifieri, għandek tissostitwixxi s-singi b'sottolinja.

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

Il-bqija tal-parti kienet imgeżwer f'xi loop, sabiex ma tirrepetix it-talba lir-router jekk kien meħtieġ li tiċċekkja f'subnet ieħor minn dawk li r-router diġà jaf dwarhom. Ta’ min isemmi li r-router li fuqu qed nagħmel it-talba jaf ir-rotot biss permezz tal-OSPF, għalhekk għal router edge huwa aħjar li tbiddel ftit it-talba biex tnaqqas il-ħin ta’ tħaddim tal-iscript

data = dev.rpc.get_ospf_route_information()

Issa ejja nħarsu lejn il-kontenut tal-loop while

Fil-bidu, l-utent se jintalab jidħol f'subnet b'maskra u mhux aktar minn tliet ottetti min-netwerk tal-istess subnet, dan huwa meħtieġ biex tissettja l-firxa tat-tfittxija. Ma tantx inħobb din l-implimentazzjoni li tispeċifika l-kriterji u l-firxa tat-tiftix, iżda s'issa ma sibtx soluzzjoni aħjar. Sussegwentement, mil-lista li tirriżulta tas-subnets route_list, billi tuża varjabbli li fiha mhux aktar minn tliet ottetti, nagħżel is-subnets li jinteressani

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

Permezz tal-IPNetwork, il-modulu netaddr, nirċievi subnets fil-forma ta’ lista ta’ indirizzi ipv4

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

Bl-użu tal-IPNetwork, nikseb firxa ta 'indirizzi minn netwerk imdaħħal mill-utent b'maskra u niġġenera lista tal-indirizzi kollha minn din il-firxa għal tqabbil mal-lista ta' indirizzi okkupati.

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

Jiena nuri l-lista li tirriżulta ta 'indirizzi ħielsa fil-forma ta' subnets

print(netaddr.IPSet(freeip))

Hawn taħt hemm l-iskript komplut, ittestjat fuq swiċċijiet użati bħala router, mudelli 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

Sors: www.habr.com

Żid kumment