Junos PyEZ gamit ang halimbawa ng gawain ng paghahanap ng mga libreng ipv4 subnet

Isang artikulo tungkol sa pagtatrabaho sa Junos PyEZ - "Python microframework na nagbibigay-daan sa iyong pamahalaan at i-automate ang mga device na nagpapatakbo ng Junos OS" automation at pamamahala, lahat ng gusto namin. Ang pagsulat ng script na inilarawan sa artikulong ito ay may ilang layunin - pag-aaral ng Python at pag-automate ng mga gawain para sa pagkolekta ng impormasyon o pagbabago ng mga configuration sa kagamitan na nagpapatakbo ng Junos OS. Ang pagpili ng partikular na kumbinasyong ito ng Python + Junos PyEZ ay ginawa dahil sa mababang hadlang sa pagpasok sa Python programming language at ang kadalian ng paggamit ng Junos PyEZ library, na hindi nangangailangan ng ekspertong kaalaman sa Junos OS.

Gawain

Pag-audit ng mga libreng ipv4 subnet na pag-aari ng kumpanya. Ang criterion na ang isang subnet ay libre ay ang kawalan ng isang entry tungkol dito sa mga ruta sa switch na kumikilos bilang isang router na nagpapatakbo ng Junos OS.

Pagpapatupad

Python + Junos PyEZ, bagama't nagkaroon ng tukso na gawin ito sa pamamagitan ng paramiko at ssh.exec_command, Bilang resulta, kakailanganin mong i-configure ang network management protocol ng netconf device sa kagamitang sinusuri. Gumagana ang Netconf sa hardware sa pamamagitan ng remote procedure call RPC at gumagamit ng XML, sa halimbawang ito, upang ibigay ang impormasyong natatanggap nito.

Ang pag-install ng kasalukuyang bersyon ng Junos PyEZ mula sa PyPI ay ginagawa gamit ang sumusunod na utos:

$ pip install junos-eznc

Maaari ka ring mag-install mula sa pangunahing sangay ng proyekto sa GitHub gamit ang sumusunod na utos:

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

At isa pang pagpipilian sa pamamagitan ng

$ pip install -r requirements.txt 

Ang command na ito ay mag-i-install ng mga aklatan na nawawala sa system at kinakailangan para sa operasyon. Sa aking bersyon mga kinakailangan.txt Mayroon lamang dalawa sa kanila, ang mga pinakabagong bersyon ay ipinahiwatig sa oras ng pagsulat ng script:

junos-eznc
netaddr

Ang script bilang default ay kinukuha ang pangalan ng kasalukuyang user sa system, maaari kang mag-log in sa ilalim ng pangalan ng isa pang user gamit ang key show_route.py -u getpass.getpass ay kumukuha ng password mula sa stdin upang hindi mananatili ang password sa sistema. Upang kumonekta sa kagamitan, kakailanganin mo ring ilagay ang hostname o IP address nito kapag na-prompt. Natanggap na ang lahat ng data na kailangan para sa awtorisasyon sa device.

Sinusuportahan ng Junos PyEZ ang pagkonekta sa kagamitan na nagpapatakbo ng Junos OS gamit ang console, telnet o netconf sa pamamagitan ng ssh. Tinatalakay ng artikulo ang huling opsyon.

Upang kumonekta sa kagamitan, gamitin ang klase ng Device ng jnpr.junos module

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

Ang isang kahilingan ay ginawa para sa lahat ng mga ruta na kilala sa router sa pamamagitan ng remote procedure call o remote procedure call, alinman ang mas maginhawa.

data = dev.rpc.get_route_information()

Katulad na utos sa Junos OS

user@router> show route | display xml

Sa pamamagitan ng pagdaragdag ng rpc sa dulo ng command, nakakakuha kami ng request tag at maaari itong itugma sa pangalan ng RPC method, sa ganitong paraan malalaman namin ang iba pang pangalan ng interes. Kapansin-pansin na ang syntax para sa pagsulat ng request tag ay iba sa pangalan ng pamamaraan, ibig sabihin, dapat mong palitan ang mga gitling ng mga salungguhit.

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

Ang natitirang bahagi ay nakabalot sa isang habang loop, upang hindi ulitin ang kahilingan sa router kung kinakailangan upang suriin ang isa pang subnet mula sa mga alam na ng router. Ito ay nagkakahalaga ng pagbanggit na ang router kung saan ako gumagawa ng kahilingan ay nakakaalam ng mga ruta lamang sa pamamagitan ng OSPF, kaya para sa isang gilid router mas mahusay na baguhin ang kahilingan nang kaunti upang mabawasan ang oras ng pagtakbo ng script

data = dev.rpc.get_ospf_route_information()

Ngayon tingnan natin ang mga nilalaman ng while loop

Sa simula, hihilingin sa user na magpasok ng subnet na may mask at hindi hihigit sa tatlong octet mula sa network ng parehong subnet, ito ay kinakailangan upang itakda ang hanay ng paghahanap. Hindi ko talaga gusto ang pagpapatupad na ito ng pagtukoy sa pamantayan at hanay ng paghahanap, ngunit sa ngayon ay wala pa akong nahanap na mas mahusay na solusyon. Susunod, mula sa nagresultang listahan ng mga subnet route_list, gamit ang isang variable na naglalaman ng hindi hihigit sa tatlong octet, pipiliin ko ang mga subnet na interesado ako

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

Sa pamamagitan ng IPNetwork, ang netaddr module, nakakatanggap ako ng mga subnet sa anyo ng isang listahan ng mga ipv4 address

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

Gamit ang IPNetwork, kumuha ako ng hanay ng mga address mula sa isang network na pinasok ng user na may mask at bumubuo ng isang listahan ng lahat ng mga address mula sa hanay na ito para sa paghahambing sa listahan ng mga inookupahang address.

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

Ipinapakita ko ang resultang listahan ng mga libreng address sa anyo ng mga subnet

print(netaddr.IPSet(freeip))

Nasa ibaba ang kumpletong script, nasubok sa mga switch na ginamit bilang router, mga modelong 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

Pinagmulan: www.habr.com

Magdagdag ng komento