Junos PyEZ با استفاده از مثال وظیفه جستجوی زیرشبکه های رایگان ipv4

مقاله ای در مورد کار با Junos PyEZ - "Microframework Python که به شما امکان می دهد دستگاه های دارای سیستم عامل Junos را مدیریت و مدیریت کنید" اتوماسیون و مدیریت، همه چیزهایی که دوست داریم. نوشتن اسکریپت شرح داده شده در این مقاله چندین هدف داشت - یادگیری پایتون و خودکارسازی وظایف برای جمع آوری اطلاعات یا تغییر تنظیمات روی تجهیزاتی که سیستم عامل Junos را اجرا می کنند. انتخاب این ترکیب خاص از Python + Junos PyEZ به دلیل وجود مانع کم برای ورود به زبان برنامه نویسی پایتون و سهولت استفاده از کتابخانه Junos PyEZ بوده است که نیازی به دانش تخصصی Junos OS ندارد.

کار

ممیزی زیرشبکه های رایگان ipv4 متعلق به شرکت. معیار رایگان بودن یک زیرشبکه عدم وجود ورودی در مورد آن در مسیرهای روی سوئیچ است که به عنوان روتری که سیستم عامل Junos را اجرا می کند عمل می کند.

اجرا

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 با استفاده از کنسول، telnet یا 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

user@router> show route | display xml

با افزودن rpc به انتهای دستور، یک تگ درخواست دریافت می کنیم و می توانیم آن را با نام متد RPC تطبیق دهیم، به این ترتیب می توانیم به نام های مورد علاقه دیگر پی ببریم. شایان ذکر است که نحو نوشتن تگ درخواست با نام متد متفاوت است، یعنی باید خط فاصله را با زیرخط جایگزین کنید.

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

بقیه قسمت در یک حلقه while پیچیده شده بود تا در صورت نیاز به بررسی در زیرشبکه دیگری از آنهایی که روتر قبلاً در مورد آنها می داند ، درخواست را به روتر تکرار نکنید. لازم به ذکر است که روتری که من درخواست می کنم مسیرها را فقط از طریق 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

اضافه کردن نظر