Junos PyEZ mei it foarbyld fan 'e taak om te sykjen nei fergese ipv4 subnets

In artikel oer wurkjen mei Junos PyEZ - "Python-mikroframework wêrmei jo apparaten kinne beheare en automatisearje mei Junos OS" automatisearring en behear, alles wêr't wy fan hâlde. It skriuwen fan it skript beskreaun yn dit artikel hie ferskate doelen - Python leare en taken automatisearje foar it sammeljen fan ynformaasje of feroarjen fan konfiguraasjes op apparatuer dy't Junos OS draait. De kar foar dizze spesifike kombinaasje fan Python + Junos PyEZ waard makke troch de lege barriêre foar yngong yn 'e Python-programmearringstaal en it gemak fan gebrûk fan' e Junos PyEZ-bibleteek, dy't gjin saakkundige kennis fan Junos OS fereasket.

Objective

Audit fan fergese ipv4 subnets dy't ta it bedriuw hearre. It kritearium dat in subnet fergees is is it ûntbrekken fan in yngong deroer yn 'e rûtes op' e switch dy't fungearret as in router mei Junos OS.

Ymplemintaasje

Python + Junos PyEZ, hoewol d'r in ferlieding wie om it te dwaan fia paramiko en ssh.exec_command, As resultaat moatte jo it netconf-apparaatnetwurkbehearprotokol konfigurearje op 'e apparatuer dy't wurdt ûnderfrege. Netconf wurket mei hardware fia remote proseduere call RPC en brûkt XML, yn dit foarbyld, te foarsjen de ynformaasje dy't it ûntfangt.

It ynstallearjen fan de aktuele ferzje fan Junos PyEZ fan PyPI wurdt dien mei it folgjende kommando:

$ pip install junos-eznc

Jo kinne ek ynstallearje fanút de haadtûke fan it projekt op GitHub mei it folgjende kommando:

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

En noch ien opsje fia

$ pip install -r requirements.txt 

Dit kommando sil biblioteken ynstallearje dy't ûntbrekke yn it systeem en nedich binne foar operaasje. Yn myn ferzje easken.txt D'r binne mar twa fan har, de lêste ferzjes wurde oanjûn op it momint fan it skriuwen fan it skript:

junos-eznc
netaddr

Standert nimt it skript de namme fan de aktuele brûker yn it systeem; jo kinne ynlogge ûnder de namme fan in oare brûker mei de show_route.py -u-kaai getpass.getpass nimt it wachtwurd fan stdin, sadat it wachtwurd net yn it systeem bliuwt. Om ferbining te meitsjen mei de apparatuer, moatte jo ek de hostnamme of it IP-adres dêrfan ynfiere as jo wurde frege. Alle gegevens nedich foar autorisaasje op it apparaat binne ûntfongen.

Junos PyEZ stipet ferbining mei apparatuer mei Junos OS mei de konsole, telnet of netconf fia ssh. It artikel besprekt de lêste opsje.

Om te ferbinen mei apparatuer, brûk de Device-klasse fan 'e jnpr.junos-module

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

In fersyk wurdt dien foar alle rûtes dy't bekend binne oan de router fia oprop op ôfstân proseduere of oprop op ôfstân proseduere, hokker is handiger.

data = dev.rpc.get_route_information()

Similar kommando op Junos OS

user@router> show route | display xml

Troch it tafoegjen fan rpc oan 'e ein fan it kommando, krije wy in fersyktag en kinne it oerienkomme mei de namme fan' e RPC-metoade, op dizze manier kinne wy ​​​​oare nammen fan belang fine. It is de muoite wurdich op te merken dat de syntaksis foar it skriuwen fan it fersyk tag is oars as de metoade namme, nammentlik, jo moatte ferfange de koppeltekens mei underscores.

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

De rest fan it diel waard ferpakt yn in skoft lus, om net werhelje it fersyk oan de router as it wie nedich om te kontrolearjen yn in oar subnet fan dyjingen dy't de router al wit. It is it neamen wurdich dat de router wêrop ik it fersyk meitsje rûtes allinich troch OSPF wit, dus foar in rânerouter is it better om it fersyk in bytsje te feroarjen om de rinnende tiid fan it skript te ferminderjen

data = dev.rpc.get_ospf_route_information()

Litte wy no sjen nei de ynhâld fan 'e while-loop

Oan it begjin sil de brûker frege wurde om in subnet yn te fieren mei in masker en net mear as trije oktetten fan it netwurk fan itselde subnet, dit is nedich om it sykbereik yn te stellen. Ik hâld net echt fan dizze ymplemintaasje fan it opjaan fan de kritearia en sykbereik, mar oant no haw ik gjin bettere oplossing fûn. Folgjende, út 'e resultearjende list fan subnetten route_list, mei in fariabele mei net mear as trije oktetten, selektearje ik de subnetten dy't my ynteressearje

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

Fia IPNetwork, de netaddr-module, krij ik subnetten yn 'e foarm fan in list mei ipv4-adressen

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

Mei it brûken fan IPNetwork krij ik in berik fan adressen fan in troch de brûker ynfierd netwurk mei in masker en generearje in list fan alle adressen út dit berik foar ferliking mei de list mei besette adressen.

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

Ik werjaan de resultearjende list mei fergese adressen yn 'e foarm fan subnets

print(netaddr.IPSet(freeip))

Hjirûnder is it folsleine skript, testen op switches brûkt as router, modellen 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

Boarne: www.habr.com

Add a comment