Junos PyEZ-ը՝ օգտագործելով անվճար ipv4 ենթացանցերի որոնման առաջադրանքի օրինակը

Junos PyEZ-ի հետ աշխատելու մասին հոդված՝ «Python միկրոշրջանակ, որը թույլ է տալիս կառավարել և ավտոմատացնել Junos OS-ով աշխատող սարքերը» ավտոմատացում և կառավարում, այն ամենը, ինչ մենք սիրում ենք: Այս հոդվածում նկարագրված սցենարը գրելն ուներ մի քանի նպատակ՝ սովորել Python և ավտոմատացնել առաջադրանքները՝ տեղեկատվություն հավաքելու կամ Junos OS-ով աշխատող սարքավորումների կոնֆիգուրացիաները փոխելու համար: Python + Junos PyEZ-ի այս հատուկ համակցության ընտրությունը կատարվել է Python ծրագրավորման լեզվի մուտքի ցածր խոչընդոտի և Junos PyEZ գրադարանի հեշտ օգտագործման պատճառով, որը չի պահանջում Junos OS-ի փորձագիտական ​​գիտելիքներ:

Առաջադրանք

Ընկերությանը պատկանող անվճար ipv4 ենթացանցերի աուդիտ: Ենթացանցն անվճար լինելու չափանիշը դրա մասին մուտքի բացակայությունն է անջատիչի երթուղիներում, որը գործում է որպես Junos OS-ով աշխատող երթուղիչ:

Իրականացման

Python + Junos PyEZ, չնայած կար գայթակղություն դա անել paramiko-ի և ssh.exec_command-ի միջոցով, Արդյունքում, դուք պետք է կարգավորեք netconf սարքի ցանցի կառավարման արձանագրությունը հարցվող սարքավորման վրա: Netconf-ն աշխատում է ապարատային սարքերի հետ RPC-ի հեռակա ընթացակարգի միջոցով և օգտագործում է XML, այս օրինակում, իր ստացած տեղեկատվությունը տրամադրելու համար:

PyPI-ից Junos PyEZ-ի ընթացիկ տարբերակը տեղադրելը կատարվում է հետևյալ հրամանով.

$ pip install junos-eznc

Կարող եք նաև տեղադրել նախագծի հիմնական մասնաճյուղից GitHub-ում հետևյալ հրամանով.

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

Եվ ևս մեկ տարբերակ միջոցով

$ pip install -r requirements.txt 

Այս հրամանը կտեղադրի գրադարաններ, որոնք բացակայում են համակարգից և անհրաժեշտ են շահագործման համար: Իմ տարբերակով պահանջները. txt Դրանցից ընդամենը երկուսն են, վերջին տարբերակները նշված են սցենարը գրելու պահին.

junos-eznc
netaddr

Սկրիպտը լռելյայնորեն վերցնում է համակարգի ընթացիկ օգտատիրոջ անունը, դուք կարող եք մուտք գործել մեկ այլ օգտատիրոջ անունով՝ օգտագործելով show_route.py բանալին -u getpass.getpass-ը վերցնում է գաղտնաբառը stdin-ից, որպեսզի գաղտնաբառը չմնա: համակարգում։ Սարքավորմանը միանալու համար անհրաժեշտ կլինի նաև մուտքագրել նրա հոսթի անունը կամ IP հասցեն, երբ ձեզ հուշեն: Սարքի թույլտվության համար անհրաժեշտ բոլոր տվյալները ստացվել են:

Junos PyEZ-ն աջակցում է Junos OS-ով աշխատող սարքավորումներին միանալու համար՝ օգտագործելով վահանակ, telnet կամ netconf ssh-ի միջոցով: Հոդվածում քննարկվում է վերջին տարբերակը:

Սարքավորումներին միանալու համար օգտագործեք jnpr.junos մոդուլի Device դասը

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

Հարցում է արվում երթուղիչին հայտնի բոլոր երթուղիների համար՝ հեռակառավարման ընթացակարգով զանգի կամ հեռակառավարման ընթացակարգի զանգի միջոցով, որն ավելի հարմար է:

data = dev.rpc.get_route_information()

Նմանատիպ հրաման Junos OS-ում

user@router> show route | display xml

Հրամանի վերջում ավելացնելով rpc, մենք ստանում ենք հարցման պիտակ և կարող ենք այն համապատասխանեցնել RPC մեթոդի անվան հետ, այս կերպ մենք կարող ենք պարզել այլ հետաքրքրող անուններ։ Հարկ է նշել, որ հարցման պիտակը գրելու շարահյուսությունը տարբերվում է մեթոդի անունից, մասնավորապես, դուք պետք է փոխարինեք գծիկները ընդգծումներով:

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

Մնացած մասը փաթաթված էր մի քիչ հանգույցով, որպեսզի չկրկնվի հարցումը երթուղիչին, եթե անհրաժեշտ լիներ ստուգել այլ ենթացանցում, որոնց մասին երթուղիչն արդեն գիտի: Հարկ է նշել, որ երթուղիչը, որի վրա ես հարցում եմ անում, գիտի երթուղիները միայն OSPF-ի միջոցով, ուստի եզրային երթուղիչի համար ավելի լավ է մի փոքր փոխել հարցումը, որպեսզի կրճատի սցենարի գործարկման ժամանակը:

data = dev.rpc.get_ospf_route_information()

Հիմա եկեք նայենք while օղակի բովանդակությանը

Սկզբում օգտագործողին կառաջարկվի մուտքագրել ենթացանց դիմակով և ոչ ավելի, քան երեք օկտետ նույն ենթացանցի ցանցից, դա անհրաժեշտ է որոնման տիրույթը սահմանելու համար: Ինձ իսկապես դուր չի գալիս չափանիշների և որոնման տիրույթի հստակեցման այս իրականացումը, բայց մինչ այժմ ես ավելի լավ լուծում չեմ գտել: Հաջորդը, ենթացանցերի route_list-ի ստացված ցանկից, օգտագործելով երեք ութից ոչ ավելի պարունակող փոփոխական, ես ընտրում եմ ինձ հետաքրքրող ենթացանցերը:

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

IPNetwork-ի, netaddr մոդուլի միջոցով ես ստանում եմ ենթացանցեր ipv4 հասցեների ցանկի տեսքով

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

Օգտագործելով IPNetwork-ը, ես օգտվողի կողմից մուտքագրված ցանցից ստանում եմ հասցեների մի շարք դիմակով և ստեղծում եմ այս տիրույթից բոլոր հասցեների ցանկը՝ զբաղեցրած հասցեների ցանկի հետ համեմատելու համար:

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

Ստացված անվճար հասցեների ցանկը ցուցադրում եմ ենթացանցերի տեսքով

print(netaddr.IPSet(freeip))

Ստորև ներկայացված է ամբողջական սցենարը, որը փորձարկվել է որպես երթուղիչ օգտագործվող անջատիչների վրա, մոդելներ 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

Добавить комментарий