Junos PyEZ mînaka peywira lêgerîna li jêrtorên ipv4 belaş bikar tîne

Gotarek li ser xebata bi Junos PyEZ - "Mîkroçarçoveya Python ku dihêle hûn cîhazên ku Junos OS-ê dixebitin" û rêvebirinê bi rêve bibin û otomatîk bikin, her tiştê ku em jê hez dikin. Nivîsandina skrîpta ku di vê gotarê de hatî destnîşan kirin çend armanc hebûn - fêrbûna Python û otomatîkkirina peywiran ji bo berhevkirina agahdarî an guheztina mîhengan li ser alavên ku Junos OS-ê dixebitin. Hilbijartina vê kombînasyona taybetî ya Python + Junos PyEZ ji ber astengiya kêm a têketina zimanê bernamesaziya Python û hêsaniya karanîna pirtûkxaneya Junos PyEZ, ku hewcedariya zanîna pispor a Junos OS-ê nake, hate çêkirin.

Armanc

Kontrolkirina subnetên belaş ipv4 yên ku aîdê pargîdaniyê ne. Pîvana ku subnetek belaş e nebûna têketinek di derheqê wê de di rêyên li ser guhêzbarê de ye ku wekî routerek ku Junos OS-ê dixebitîne tevdigere.

Реализация

Python + Junos PyEZ, her çend ceribandinek hebû ku meriv wiya bi paramiko û ssh.exec_command bike, Wekî encamek, hûn ê hewce bikin ku protokola rêveberiya torê ya cîhaza netconf li ser alavên ku têne lêkolîn kirin mîheng bikin. Netconf bi navgîniya pêvajoyek dûr a RPC re bi hardware re dixebite û di vê nimûneyê de XML bikar tîne da ku agahdariya ku werdigire peyda bike.

Sazkirina guhertoya heyî ya Junos PyEZ ji PyPI bi fermana jêrîn pêk tê:

$ pip install junos-eznc

Her weha hûn dikarin ji şaxê sereke yê projeyê li ser GitHub bi fermana jêrîn saz bikin:

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

Û vebijarkek din bi rêya

$ pip install -r requirements.txt 

Ev ferman dê pirtûkxaneyên ku ji pergalê winda ne û ji bo xebatê hewce ne saz bike. Di versiyona min de daxwazên.txt Tenê du ji wan hene, guhertoyên herî dawî di dema nivîsandina senaryoyê de têne destnîşan kirin:

junos-eznc
netaddr

Skrîpta bi xweber navê bikarhênerê heyî yê pergalê digire, hûn dikarin di bin navê bikarhênerek din de bi karanîna mifteya show_route.py -u getpass.getpass şîfreyê ji stdin digire da ku şîfre namîne di sîstemê de. Ji bo girêdana bi alavan re, hûn ê jî hewce bikin ku dema ku tê xwestin navê mêvandar an navnîşana IP-ya wê têkevin. Hemî daneyên ku ji bo destûrnameyê li ser cîhazê hewce ne hatine wergirtin.

Junos PyEZ piştgirî dide girêdana bi alavên ku Junos OS-ê bi karanîna konsol, telnet an netconf-ê bi ssh-ê dimeşînin. Gotar bijareya paşîn nîqaş dike.

Ji bo girêdana bi alavên, çîna Device ya modula jnpr.junos bikar bînin

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

Daxwazek ji bo hemî rêçikên ku ji router re têne zanîn bi banga prosedûra dûr an banga prosedûra dûr ve tê kirin, kîjan ku hêsantir be.

data = dev.rpc.get_route_information()

Fermana bi heman rengî li ser Junos OS

user@router> show route | display xml

Bi lêzêdekirina rpc li dawiya fermanê, em tagek daxwazê ​​distînin û dikarin wê bi navê rêbaza RPC-ê re hevber bikin, bi vî rengî em dikarin navên din ên balkêş bibînin. Hêjayî gotinê ye ku hevoksaziya nivîsandina etîketa daxwaznameyê ji navê rêbazê cûda ye, ango, divê hûn xêzikan bi binxetê veguherînin.

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

Beşa mayî di nav hûrek hûrdemê de hate pêçandin, da ku daxwazek ji routerê re dubare neke ger hewce bû ku di binnetek din de ji yên ku router jixwe pê dizane kontrol bikin. Hêjayî gotinê ye ku routera ku ez lê daxwazê ​​dikim rêçikan tenê bi OSPF-ê dizane, ji ber vê yekê ji bo routerek qerax çêtir e ku meriv daxwazê ​​hinekî biguhezîne da ku dema xebitandina nivîsê kêm bike.

data = dev.rpc.get_ospf_route_information()

Naha em li naverokên lûleya while binêrin

Di destpêkê de, ji bikarhêner tê xwestin ku bi maskek û ne bêtir ji sê oktetan ji tora heman subnetê têkevin bintorê, ev hewce ye ku rêza lêgerînê were danîn. Ez bi rastî ji vê pêkanîna diyarkirina pîvan û qada lêgerînê hez nakim, lê heya nuha min çareseriyek çêtir nedîtiye. Dûv re, ji navnîşa encam a navnîşa jêrtorê route_list, bi karanîna guhêrbarek ku ji sê oktetan zêdetir tê de ne, ez jêrtorên ku ji min re eleqedar dibin hildibijêrim.

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

Bi rêya IPNetwork, modula netaddr, ez di forma navnîşek navnîşanên ipv4 de subnetan distînim.

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

Bi karanîna IPNetwork-ê, ez ji torgilokek ku bikarhêner bi maskek ketiye nav rêzek navnîşan distînim û navnîşek hemî navnîşanên ji vê rêzê ji bo berhevdana bi navnîşa navnîşanên dagirkirî re çêdikim.

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

Ez navnîşa encam a navnîşanên belaş di forma subnetan de nîşan didim

print(netaddr.IPSet(freeip))

Li jêr skrîpta bêkêmasî ye, ku li ser guhezên ku wekî router têne bikar anîn hatine ceribandin, modelên 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

Source: www.habr.com

Add a comment