Junos PyEZ pulsuz ipv4 alt şəbəkələrini axtarmaq tapşırığından istifadə edir

Junos PyEZ ilə işləmək haqqında məqalə - “Junos OS ilə işləyən cihazları idarə etməyə və avtomatlaşdırmağa imkan verən Python mikroframework” avtomatlaşdırma və idarəetmə, sevdiyimiz hər şey. Bu məqalədə təsvir olunan skriptin yazılmasının bir neçə məqsədi var idi - Python öyrənmək və Junos OS ilə işləyən avadanlıqda məlumat toplamaq və ya konfiqurasiyaları dəyişdirmək üçün tapşırıqları avtomatlaşdırmaq. Python + Junos PyEZ-in bu spesifik kombinasiyasının seçimi Python proqramlaşdırma dilinə daxil olmaq üçün maneənin aşağı olması və Junos OS üzrə ekspert biliklərini tələb etməyən Junos PyEZ kitabxanasından istifadənin asanlığı səbəbindən edilib.

Tapşırıq

Şirkətə məxsus pulsuz ipv4 alt şəbəkələrinin auditi. Alt şəbəkənin pulsuz olması meyarı Junos OS ilə işləyən marşrutlaşdırıcı rolunu oynayan keçiddə marşrutlarda bu barədə qeydin olmamasıdır.

Tətbiq

Python + Junos PyEZ, paramiko və ssh.exec_command vasitəsilə bunu etmək istəyi olsa da, Nəticədə, sorğu edilən avadanlıqda netconf cihaz şəbəkə idarəetmə protokolunu konfiqurasiya etməlisiniz. Netconf uzaqdan prosedur çağırışı RPC vasitəsilə aparatla işləyir və aldığı məlumatı təmin etmək üçün bu misalda XML-dən istifadə edir.

Junos PyEZ-in cari versiyasını PyPI-dən quraşdırmaq aşağıdakı əmrlə həyata keçirilir:

$ pip install junos-eznc

Siz həmçinin GitHub-da layihənin əsas filialından aşağıdakı əmrlə quraşdıra bilərsiniz:

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

Və daha bir seçim vasitəsilə

$ pip install -r requirements.txt 

Bu əmr sistemdə olmayan və işləmək üçün zəruri olan kitabxanaları quraşdıracaq. Mənim versiyamda tələblər.txt Onlardan yalnız ikisi var, ən son versiyalar skript yazarkən göstərilir:

junos-eznc
netaddr

Varsayılan olaraq, skript sistemdəki cari istifadəçinin adını alır; show_route.py -u düyməsini istifadə edərək başqa istifadəçinin adı ilə daxil ola bilərsiniz. getpass.getpass parolu stdin-dən götürür ki, parol sistemdə qalmasın. Avadanlığa qoşulmaq üçün sizdən tələb olunduqda onun host adını və ya IP ünvanını da daxil etməlisiniz. Cihazda avtorizasiya üçün lazım olan bütün məlumatlar qəbul edilib.

Junos PyEZ ssh vasitəsilə konsol, telnet və ya netconf vasitəsilə Junos OS ilə işləyən avadanlıqlara qoşulmağı dəstəkləyir. Məqalədə sonuncu variant müzakirə olunur.

Avadanlığa qoşulmaq üçün jnpr.junos modulunun Cihaz sinifindən istifadə edin

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

Uzaqdan prosedur çağırışı və ya uzaqdan prosedur çağırışı vasitəsilə marşrutlaşdırıcıya məlum olan bütün marşrutlar üçün sorğu verilir, hansı daha əlverişlidir.

data = dev.rpc.get_route_information()

Junos OS-də oxşar əmr

user@router> show route | display xml

Komandanın sonuna rpc əlavə etməklə biz sorğu etiketi əldə edirik və onu RPC metodunun adı ilə uyğunlaşdıra bilərik, bu yolla digər maraq doğuran adları tapa bilərik. Qeyd etmək lazımdır ki, sorğu teqini yazmaq üçün sintaksis metod adından fərqlidir, yəni defisləri alt xətt ilə əvəz etməlisiniz.

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

Qalan hissə, marşrutlaşdırıcının artıq bildiyi başqa bir alt şəbəkədə yoxlamaq lazım gələrsə, marşrutlaşdırıcıya sorğunu təkrarlamamaq üçün bir müddət döngəsinə bükülmüşdür. Qeyd etmək lazımdır ki, sorğu göndərdiyim marşrutlaşdırıcı yalnız OSPF vasitəsilə marşrutları tanıyır, buna görə də kənar marşrutlaşdırıcı üçün skriptin işləmə müddətini azaltmaq üçün sorğunu bir az dəyişdirmək daha yaxşıdır.

data = dev.rpc.get_ospf_route_information()

İndi isə while dövrəsinin məzmununa baxaq

Başlanğıcda istifadəçidən maskalı və eyni alt şəbəkənin şəbəkəsindən üç oktetdən çox olmayan alt şəbəkəyə daxil olması tələb olunacaq, bu, axtarış diapazonunu təyin etmək üçün lazımdır. Kriteriyaların və axtarış aralığının dəqiqləşdirilməsinin bu tətbiqini həqiqətən bəyənmirəm, lakin indiyə qədər daha yaxşı bir həll tapmadım. Sonra, üç oktetdən çox olmayan dəyişəndən istifadə edərək, marşrut_list alt şəbəkələrinin nəticə siyahısından məni maraqlandıran alt şəbəkələri seçirəm.

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

IPNetwork, netaddr modulu vasitəsilə mən alt şəbəkələri ipv4 ünvanlarının siyahısı şəklində alıram.

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

IPNetwork-dən istifadə edərək, mən maskalı istifadəçinin daxil etdiyi şəbəkədən bir sıra ünvanlar əldə edirəm və işğal olunmuş ünvanların siyahısı ilə müqayisə etmək üçün bu diapazondan bütün ünvanların siyahısını yaradıram.

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

Mən nəticədə pulsuz ünvanların siyahısını alt şəbəkələr şəklində göstərirəm

print(netaddr.IPSet(freeip))

Aşağıda ex4550, ex4600 modellərində marşrutlaşdırıcı kimi istifadə edilən açarlarda sınaqdan keçirilmiş tam skript verilmişdir.


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

Mənbə: www.habr.com

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