Junos PyEZ ved hjælp af eksemplet med opgaven med at søge efter gratis ipv4-undernet

En artikel om at arbejde med Junos PyEZ - "Python microframework, der gør det muligt for dig at administrere og automatisere enheder, der kører Junos OS" automatisering og administration, alt hvad vi elsker. At skrive scriptet beskrevet i denne artikel havde flere mål - at lære Python og automatisere opgaver til at indsamle information eller ændre konfigurationer på udstyr, der kører Junos OS. Valget af denne specifikke kombination af Python + Junos PyEZ blev truffet på grund af den lave adgangsbarriere til Python-programmeringssproget og den nemme brug af Junos PyEZ-biblioteket, som ikke kræver ekspertviden om Junos OS.

Opgave

Revision af gratis ipv4 undernet tilhørende virksomheden. Kriteriet for, at et undernet er gratis, er fraværet af en post om det i ruterne på switchen, der fungerer som en router, der kører Junos OS.

implementering

Python + Junos PyEZ, selvom der var en fristelse til at gøre det gennem paramiko og ssh.exec_command, Som et resultat bliver du nødt til at konfigurere netconf-enhedens netværksadministrationsprotokol på det udstyr, der bliver pollet. Netconf arbejder med hardware via fjernprocedurekald RPC og bruger XML, i dette eksempel, til at levere de oplysninger, det modtager.

Installation af den aktuelle version af Junos PyEZ fra PyPI udføres med følgende kommando:

$ pip install junos-eznc

Du kan også installere fra projektets hovedgren på GitHub med følgende kommando:

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

Og endnu en mulighed via

$ pip install -r requirements.txt 

Denne kommando vil installere biblioteker, der mangler i systemet og er nødvendige for driften. I min version krav.txt Der er kun to af dem, de seneste versioner er angivet på tidspunktet for skrivning af scriptet:

junos-eznc
netaddr

Som standard tager scriptet navnet på den aktuelle bruger i systemet; du kan logge ind under navnet på en anden bruger ved hjælp af show_route.py -u-tasten getpass.getpass tager adgangskoden fra stdin, så adgangskoden forbliver ikke i systemet. For at oprette forbindelse til udstyret skal du også indtaste dets værtsnavn eller IP-adresse, når du bliver bedt om det. Alle data, der er nødvendige for godkendelse på enheden, er modtaget.

Junos PyEZ understøtter tilslutning til udstyr, der kører Junos OS ved hjælp af konsollen, telnet eller netconf via ssh. Artiklen diskuterer sidstnævnte mulighed.

For at oprette forbindelse til udstyr skal du bruge enhedsklassen i jnpr.junos-modulet

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

Der foretages en anmodning om alle ruter, som routeren kender via fjernprocedurekald eller fjernprocedurekald, alt efter hvad der er mest bekvemt.

data = dev.rpc.get_route_information()

Lignende kommando på Junos OS

user@router> show route | display xml

Ved at tilføje rpc til slutningen af ​​kommandoen får vi et request tag og kan matche det med navnet på RPC metoden, på denne måde kan vi finde ud af andre navne af interesse. Det er værd at bemærke, at syntaksen for at skrive anmodnings-tagget er forskellig fra metodenavnet, nemlig at du skal erstatte bindestreger med understregninger.

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

Resten af ​​delen blev pakket ind i en while-løkke, for ikke at gentage anmodningen til routeren, hvis det var nødvendigt at tjekke et andet undernet ind fra dem, som routeren allerede kender til. Det er værd at nævne, at den router, som jeg laver anmodningen på, kun kender ruter gennem OSPF, så for en edge-router er det bedre at ændre anmodningen lidt for at reducere scriptets køretid

data = dev.rpc.get_ospf_route_information()

Lad os nu se på indholdet af while-løkken

I begyndelsen vil brugeren blive bedt om at indtaste et undernet med en maske og ikke mere end tre oktetter fra netværket i det samme undernet, dette er nødvendigt for at indstille søgeområdet. Jeg kan ikke rigtig lide denne implementering af at specificere kriterierne og søgeområdet, men indtil videre har jeg ikke fundet en bedre løsning. Dernæst, fra den resulterende liste over undernet rute_liste, ved hjælp af en variabel, der ikke indeholder mere end tre oktetter, vælger jeg de undernet, der interesserer mig

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

Gennem IPNetwork, netaddr-modulet, modtager jeg undernet i form af en liste over ipv4-adresser

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

Ved hjælp af IPNetwork henter jeg en række adresser fra et brugerindtastet netværk med en maske og genererer en liste over alle adresser fra dette område til sammenligning med listen over besatte adresser.

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

Jeg viser den resulterende liste over gratis adresser i form af undernet

print(netaddr.IPSet(freeip))

Nedenfor er det komplette script, testet på switches brugt som router, modeller 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

Kilde: www.habr.com

Tilføj en kommentar