Junos PyEZ na primeru naloge iskanja prostih podomrežij ipv4

Članek o delu z Junos PyEZ - »Mikroogrodje Python, ki vam omogoča upravljanje in avtomatizacijo naprav, ki uporabljajo Junos OS« avtomatizacija in upravljanje, vse, kar imamo radi. Pisanje skripta, opisanega v tem članku, je imelo več ciljev - učenje Pythona in avtomatiziranje nalog za zbiranje informacij ali spreminjanje konfiguracij na opremi, ki poganja Junos OS. Izbira te specifične kombinacije Python + Junos PyEZ je bila narejena zaradi nizke ovire za vstop v programski jezik Python in enostavne uporabe knjižnice Junos PyEZ, ki ne zahteva strokovnega znanja Junos OS.

Naloga

Revizija brezplačnih podomrežij ipv4, ki pripadajo podjetju. Kriterij, da je podomrežje prosto, je odsotnost vnosa o njem v smereh na stikalu, ki deluje kot usmerjevalnik z operacijskim sistemom Junos OS.

Реализация

Python + Junos PyEZ, čeprav je obstajala skušnjava, da bi to naredili prek paramiko in ssh.exec_command, Posledično boste morali konfigurirati protokol za upravljanje omrežja naprave netconf na opremi, ki jo preverjate. Netconf deluje s strojno opremo prek oddaljenega klica procedure RPC in v tem primeru uporablja XML za zagotavljanje informacij, ki jih prejme.

Namestitev trenutne različice Junos PyEZ iz PyPI se izvede z naslednjim ukazom:

$ pip install junos-eznc

Namestitev lahko izvedete tudi iz glavne veje projekta na GitHub z naslednjim ukazom:

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

In še ena možnost prek

$ pip install -r requirements.txt 

Ta ukaz bo namestil knjižnice, ki manjkajo v sistemu in so potrebne za delovanje. V moji različici zahteve.txt Obstajata samo dva, najnovejše različice so navedene v času pisanja skripta:

junos-eznc
netaddr

Skript privzeto prevzame ime trenutnega uporabnika v sistemu; prijavite se lahko pod imenom drugega uporabnika s tipko show_route.py -u getpass.getpass vzame geslo iz stdin, tako da geslo ne ostane v sistemu. Za povezavo z opremo boste morali ob pozivu vnesti tudi ime gostitelja ali naslov IP. Vsi podatki potrebni za avtorizacijo na napravi so bili prejeti.

Junos PyEZ podpira povezovanje z opremo z operacijskim sistemom Junos OS s pomočjo konzole, telneta ali netconf prek ssh. Članek obravnava zadnjo možnost.

Za povezavo z opremo uporabite razred Device modula jnpr.junos

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

Izdela se zahteva za vse poti, ki jih usmerjevalnik pozna prek klica oddaljene procedure ali klica oddaljene procedure, kar je bolj priročno.

data = dev.rpc.get_route_information()

Podoben ukaz v Junos OS

user@router> show route | display xml

Z dodajanjem rpc na konec ukaza dobimo oznako zahteve in jo lahko povežemo z imenom metode RPC, na ta način lahko izvemo druga zanimiva imena. Omeniti velja, da se sintaksa za pisanje oznake zahteve razlikuje od imena metode, in sicer bi morali vezaje zamenjati s podčrtaji.

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

Preostali del je bil zavit v zanko while, da ne bi ponovili zahteve usmerjevalniku, če bi bilo treba preveriti drugo podomrežje od tistih, ki jih usmerjevalnik že pozna. Omeniti velja, da usmerjevalnik, na katerem postavljam zahtevo, pozna poti samo prek OSPF, zato je za robni usmerjevalnik bolje, da zahtevo nekoliko spremenite, da skrajšate čas delovanja skripta

data = dev.rpc.get_ospf_route_information()

Zdaj pa poglejmo vsebino zanke while

Na začetku bo uporabnik pozvan, da vnese podomrežje z masko in ne več kot tri oktete iz omrežja istega podomrežja, to je potrebno za nastavitev obsega iskanja. Ta izvedba podajanja kriterijev in obsega iskanja mi ni ravno všeč, vendar do sedaj nisem našel boljše rešitve. Nato iz dobljenega seznama podomrežij route_list z uporabo spremenljivke, ki ne vsebuje več kot tri oktete, izberem podomrežja, ki me zanimajo

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

Prek IPNetwork, modula netaddr, prejemam podomrežja v obliki seznama ipv4 naslovov

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

Z uporabo IPNetwork pridobim obseg naslovov iz uporabniško vnesenega omrežja z masko in ustvarim seznam vseh naslovov iz tega obsega za primerjavo s seznamom zasedenih naslovov.

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

Nastali seznam prostih naslovov prikažem v obliki podomrežij

print(netaddr.IPSet(freeip))

Spodaj je celoten skript, testiran na stikalih, ki se uporabljajo kot usmerjevalnik, modeli 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

Vir: www.habr.com

Dodaj komentar