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, во овој пример, за да ги обезбеди информациите што ги добива.

Инсталирањето на тековната верзија на Junos PyEZ од PyPI се врши со следнава команда:

$ 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 користејќи конзола, телнет или netconf преку ssh. Написот ја разгледува последната опција.

За да се поврзете со опрема, користете ја класата Device од модулот jnpr.junos

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

Извор: www.habr.com

Додадете коментар