Јунос ПиЕЗ на примеру задатка тражења бесплатних ипв4 подмрежа

Чланак о раду са Јунос ПиЕЗ – „Питхон микрофрамеворк који вам омогућава да управљате и аутоматизујете уређаје који користе Јунос ОС“ аутоматизацију и управљање, све што волимо. Писање скрипте описане у овом чланку имало је неколико циљева – учење Питхон-а и аутоматизацију задатака за прикупљање информација или промену конфигурација на опреми која ради Јунос ОС. Избор ове специфичне комбинације Питхон + Јунос ПиЕЗ направљен је због ниске баријере за улазак у програмски језик Питхон и лакоће коришћења библиотеке Јунос ПиЕЗ, која не захтева стручно познавање Јунос ОС-а.

Задатак

Ревизија бесплатних ипв4 подмрежа које припадају компанији. Критеријум да је подмрежа слободна је одсуство уноса о њој у рутама на комутатору који делује као рутер који покреће Јунос ОС.

Имплементација

Питхон + Јунос ПиЕЗ, иако је постојало искушење да се то уради преко парамико и ссх.екец_цомманд, Као резултат тога, мораћете да конфигуришете протокол за управљање мрежом нетцонф уређаја на опреми која се прозива. Нетцонф ради са хардвером путем удаљеног позива процедуре РПЦ и користи КСМЛ, у овом примеру, да обезбеди информације које прима.

Инсталирање тренутне верзије Јунос ПиЕЗ из ПиПИ-ја се врши следећом командом:

$ pip install junos-eznc

Такође можете да инсталирате из главне гране пројекта на ГитХуб-у помоћу следеће команде:

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

И још једна опција преко

$ pip install -r requirements.txt 

Ова команда ће инсталирати библиотеке које недостају у систему и које су неопходне за рад. У мојој верзији захтеве.ткт Постоје само две, најновије верзије су назначене у тренутку писања скрипте:

junos-eznc
netaddr

Подразумевано, скрипта узима име тренутног корисника у систему; можете се пријавити под именом другог корисника користећи схов_роуте.пи -у кључ гетпасс.гетпасс преузима лозинку са стдин тако да лозинка неће остати у систему. Да бисте се повезали са опремом, такође ћете морати да унесете њено име хоста или ИП адресу када се то од вас затражи. Сви подаци потребни за ауторизацију на уређају су примљени.

Јунос ПиЕЗ подржава повезивање са опремом која користи Јунос ОС користећи конзолу, телнет или нетцонф преко ссх-а. У чланку се говори о последњој опцији.

Да бисте се повезали са опремом, користите класу уређаја модула јнпр.јунос

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

Захтева се за све руте познате рутеру путем позива удаљене процедуре или позива удаљене процедуре, шта год је погодније.

data = dev.rpc.get_route_information()

Слична команда на Јунос ОС-у

user@router> show route | display xml

Додавањем рпц на крај команде добијамо ознаку захтева и можемо да је упаримо са именом РПЦ методе, на тај начин можемо сазнати друга имена која нас занимају. Вреди напоменути да се синтакса за писање ознаке захтева разликује од назива методе, наиме, цртице треба заменити подвлакама.

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

Остатак дела је умотан у вхиле петљу, како се не би понављао захтев рутеру ако је било потребно да се провери у другој подмрежи од оних за које рутер већ зна. Вреди напоменути да рутер на коме постављам захтев познаје руте само преко ОСПФ-а, тако да је за рубни рутер боље да мало промените захтев да бисте смањили време рада скрипте

data = dev.rpc.get_ospf_route_information()

Сада погледајмо садржај вхиле петље

На почетку ће од корисника бити затражено да унесе подмрежу са маском и не више од три октета из мреже исте подмреже, ово је неопходно за подешавање опсега претраге. Не свиђа ми се баш ова имплементација одређивања критеријума и опсега претраге, али до сада нисам нашао боље решење. Затим, са резултирајуће листе подмрежа роуте_лист, користећи променљиву која не садржи више од три октета, бирам подмреже које ме занимају

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

Преко ИПНетворк-а, модула нетаддр, примам подмреже у облику листе ипв4 адреса

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

Користећи ИПНетворк, добијам опсег адреса из мреже коју је унео корисник са маском и генеришем листу свих адреса из овог опсега за поређење са листом заузетих адреса.

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

Приказујем резултујућу листу слободних адреса у облику подмрежа

print(netaddr.IPSet(freeip))

Испод је комплетна скрипта, тестирана на прекидачима који се користе као рутер, модели ек4550, ек4600


#!/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

Извор: ввв.хабр.цом

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