Junos PyEZ үнэгүй ipv4 дэд сүлжээ хайх даалгаврын жишээг ашиглан

Junos PyEZ-тэй ажиллах тухай нийтлэл - "Junos OS үйлдлийн системтэй төхөөрөмжүүдийг удирдах, автоматжуулах боломжийг олгодог Python микрофрэймворк" автоматжуулалт, менежмент, бидний дуртай бүх зүйл. Энэ нийтлэлд тайлбарласан скриптийг бичих нь хэд хэдэн зорилготой байсан - Python сурах, Junos үйлдлийн систем дээр ажилладаг төхөөрөмж дээр мэдээлэл цуглуулах эсвэл тохиргоог өөрчлөх ажлыг автоматжуулах. Python + Junos PyEZ-ийн энэхүү өвөрмөц хослолыг сонгох нь Python програмчлалын хэл рүү нэвтрэхэд саад багатай, Junos PyEZ номын санг ашиглахад хялбар байсан тул Junos OS-ийн талаар мэргэжлийн мэдлэг шаарддаггүй.

Зорилго

Тус компанид хамаарах үнэгүй 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 нь Junos үйлдлийн системтэй төхөөрөмжтэй консол, telnet эсвэл netconf ашиглан ssh-ээр холбогдохыг дэмждэг. Энэ нийтлэлд сүүлчийн сонголтыг авч үзэх болно.

Тоног төхөөрөмжид холбогдохын тулд 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()")

Үлдсэн хэсэг нь чиглүүлэгчийн аль хэдийн мэддэг сүлжээнүүдээс өөр дэд сүлжээнд шалгах шаардлагатай бол чиглүүлэгчийн хүсэлтийг давтахгүйн тулд хэсэг хугацааны гогцоонд ороосон. Миний хүсэлт гаргаж буй чиглүүлэгч нь зөвхөн OSPF-ээр дамждаг чиглүүлэгчийг мэддэг тул захын чиглүүлэгчийн хувьд скриптийн ажиллах хугацааг багасгахын тулд хүсэлтийг бага зэрэг өөрчилсөн нь дээр гэдгийг тэмдэглэх нь зүйтэй.

data = dev.rpc.get_ospf_route_information()

Одоо while циклийн агуулгыг харцгаая

Эхний үед хэрэглэгчээс нэг дэд сүлжээний сүлжээнээс гурваас илүүгүй наймтай, маск бүхий дэд сүлжээнд оруулахыг хүсэх бөгөөд энэ нь хайлтын хүрээг тохируулахад шаардлагатай болно. Шалгуур болон хайлтын хүрээг зааж өгсөн энэ хэрэгжилт надад үнэхээр таалагдахгүй байгаа ч одоог хүртэл би илүү сайн шийдлийг олж чадаагүй байна. Дараа нь, гурваас илүүгүй октет агуулсан хувьсагчийг ашиглан route_list дэд сүлжээнүүдийн жагсаалтаас би сонирхсон дэд сүлжээг сонгоно.

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

Netaddr модуль болох IPNetwork-ээр дамжуулан би дэд сүлжээг 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

сэтгэгдэл нэмэх