Junos PyEZ bepul ipv4 subnetlarini qidirish vazifasi misolidan foydalangan holda

Junos PyEZ bilan ishlash haqida maqola - "Junos OS operatsion tizimida ishlaydigan qurilmalarni boshqarish va avtomatlashtirish imkonini beruvchi Python mikroframevori" avtomatlashtirish va boshqarish, biz yaxshi ko'radigan hamma narsa. Ushbu maqolada tasvirlangan skriptni yozish bir nechta maqsadlarga ega edi - Python-ni o'rganish va Junos OS bilan ishlaydigan uskunalarda ma'lumot to'plash yoki konfiguratsiyalarni o'zgartirish uchun vazifalarni avtomatlashtirish. Python + Junos PyEZ ning ushbu o'ziga xos kombinatsiyasini tanlash Python dasturlash tiliga kirish uchun past to'siq va Junos PyEZ kutubxonasidan foydalanish qulayligi tufayli amalga oshirildi, bu Junos OS bo'yicha mutaxassis bilimlarini talab qilmaydi.

Maqsad

Kompaniyaga tegishli bepul IPv4 subnets auditi. Junos OS bilan ishlaydigan yo'riqnoma vazifasini bajaradigan kommutatordagi marshrutlarda u haqida yozuvning yo'qligi quyi tarmoqning bepulligi mezoni hisoblanadi.

Реализация

Python + Junos PyEZ, garchi paramiko va ssh.exec_command orqali buni qilish vasvasasi bo'lsa ham, Natijada, so'rov o'tkazilayotgan uskunada netconf qurilmasi tarmog'ini boshqarish protokolini sozlashingiz kerak bo'ladi. Netconf RPC masofaviy protsedura chaqiruvi orqali apparat bilan ishlaydi va bu misolda olingan ma'lumotlarni taqdim etish uchun XML dan foydalanadi.

PyPI-dan Junos PyEZ-ning joriy versiyasini o'rnatish quyidagi buyruq bilan amalga oshiriladi:

$ pip install junos-eznc

Siz GitHub-dagi loyihaning asosiy bo'limidan quyidagi buyruq bilan o'rnatishingiz mumkin:

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

Va orqali yana bir variant

$ pip install -r requirements.txt 

Ushbu buyruq tizimda etishmayotgan va ishlash uchun zarur bo'lgan kutubxonalarni o'rnatadi. Mening versiyamda talablar.txt Ulardan faqat ikkitasi bor, so'nggi versiyalar skriptni yozish paytida ko'rsatilgan:

junos-eznc
netaddr

Odatiy bo'lib, skript tizimdagi joriy foydalanuvchi nomini oladi; show_route.py -u tugmachasi yordamida boshqa foydalanuvchi nomi bilan tizimga kirishingiz mumkin. getpass.getpass parolni stdin dan oladi, shuning uchun parol tizimda qolmaydi. Uskunaga ulanish uchun siz so'ralganda uning xost nomi yoki IP manzilini ham kiritishingiz kerak bo'ladi. Qurilmada avtorizatsiya qilish uchun zarur bo'lgan barcha ma'lumotlar olindi.

Junos PyEZ ssh orqali konsol, telnet yoki netconf yordamida Junos OS bilan ishlaydigan uskunaga ulanishni qo'llab-quvvatlaydi. Maqolada oxirgi variant muhokama qilinadi.

Uskunaga ulanish uchun jnpr.junos modulining Device sinfidan foydalaning

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

Routerga ma'lum bo'lgan barcha marshrutlarga masofaviy protsedura chaqiruvi yoki masofaviy protsedura chaqiruvi orqali so'rov yuboriladi, qaysi biri qulayroq bo'lsa.

data = dev.rpc.get_route_information()

Junos OS da shunga o'xshash buyruq

user@router> show route | display xml

Buyruqning oxiriga rpc qo'shish orqali biz so'rov yorlig'ini olamiz va uni RPC usuli nomi bilan moslashtira olamiz, shu bilan biz boshqa qiziqish nomlarini bilib olamiz. Shuni ta'kidlash kerakki, so'rov tegini yozish sintaksisi usul nomidan farq qiladi, ya'ni defislarni pastki chiziq bilan almashtirish kerak.

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

Qolgan qismi marshrutizatorga ma'lum bo'lgan boshqa pastki tarmoqni tekshirish kerak bo'lsa, marshrutizatorga so'rovni takrorlamaslik uchun vaqtinchalik halqaga o'ralgan. Shuni ta'kidlash kerakki, men so'rov yuborayotgan router faqat OSPF orqali marshrutlarni biladi, shuning uchun chekka router uchun skriptning ishlash vaqtini qisqartirish uchun so'rovni biroz o'zgartirgan ma'qul.

data = dev.rpc.get_ospf_route_information()

Endi esa while siklining mazmunini ko‘rib chiqamiz

Boshida foydalanuvchidan niqobli va bitta quyi tarmoq tarmog'idan uchtadan ko'p bo'lmagan oktetli pastki tarmoqqa kirish so'raladi, bu qidiruv oralig'ini o'rnatish uchun kerak. Menga mezonlar va qidiruv oralig'ini ko'rsatishning bu amalga oshirilishi yoqmaydi, lekin hozircha men yaxshiroq yechim topmadim. Keyin, ro'yxatdagi pastki tarmoqlar ro'yxatidan uchta oktetdan ko'p bo'lmagan o'zgaruvchidan foydalanib, men o'zimni qiziqtirgan pastki tarmoqlarni tanlayman.

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

IPNetwork, netaddr moduli orqali men subnetlarni ipv4 manzillari ro'yxati ko'rinishida olaman.

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

IPNetwork-dan foydalanib, men foydalanuvchi kiritgan tarmoqdan niqob bilan bir qator manzillarni olaman va egallab olingan manzillar ro'yxati bilan taqqoslash uchun ushbu diapazondagi barcha manzillar ro'yxatini yarataman.

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

Olingan bepul manzillar ro'yxatini pastki tarmoqlar shaklida ko'rsataman

print(netaddr.IPSet(freeip))

Quyida marshrutizator sifatida ishlatiladigan kalitlarda sinovdan o'tgan to'liq skript mavjud, modellar 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

Manba: www.habr.com

a Izoh qo'shish