Junos PyEZ тегін ipv4 ішкі желілерін іздеу тапсырмасының мысалын пайдаланады

Junos PyEZ-пен жұмыс істеу туралы мақала - «Junos OS жүйесімен жұмыс істейтін құрылғыларды басқаруға және автоматтандыруға мүмкіндік беретін Python микрофремворк» автоматтандыру және басқару, біз жақсы көретін барлық нәрсе. Осы мақалада сипатталған сценарийді жазудың бірнеше мақсаты болды - Python тілін үйрену және Junos ОЖ жұмыс істейтін жабдықта ақпарат жинау немесе конфигурацияларды өзгертуге арналған тапсырмаларды автоматтандыру. Python + Junos PyEZ осы спецификалық комбинациясын таңдау Python бағдарламалау тіліне кіруге кедергінің төмен болуына және Junos OS бойынша сараптамалық білімді қажет етпейтін Junos PyEZ кітапханасын пайдаланудың қарапайымдылығына байланысты жасалды.

Мақсаты

Компанияға тиесілі тегін IPv4 ішкі желілерінің аудиті. Ішкі желі бос деген критерий Junos ОЖ жұмыс істейтін маршрутизатор ретінде әрекет ететін коммутатордағы маршруттарда ол туралы жазбаның болмауы болып табылады.

Реализация

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 консоль, telnet немесе netconf арқылы ssh арқылы Junos ОЖ жұмыс істейтін жабдыққа қосылуды қолдайды. Мақалада соңғы нұсқа қарастырылады.

Жабдыққа қосылу үшін 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

пікір қалдыру