Мақола дар бораи кор бо Junos PyEZ - "Microframework Python, ки ба шумо имкон медиҳад, ки дастгоҳҳои Junos OS-ро идора ва автоматӣ кунед" автоматизатсия ва идоракунии, ҳама чизеро, ки мо дӯст медорем. Навиштани скрипте, ки дар ин мақола тавсиф шудааст, якчанд ҳадаф дошт - омӯзиши Python ва автоматикунонии вазифаҳо барои ҷамъоварии маълумот ё тағир додани конфигуратсияҳо дар таҷҳизоте, ки дар Junos OS кор мекунад. Интихоби ин комбинатсияи мушаххаси Python + Junos PyEZ аз сабаби монеаи пасти ворид шудан ба забони барномасозии Python ва осонии истифодаи китобхонаи Junos PyEZ, ки дониши коршиносии Junos OS-ро талаб намекунад, сурат гирифт.
Мақсад
Аудити зершабакаҳои ройгони ipv4, ки ба ширкат тааллуқ доранд. Меъёри ройгон будани зершабака ин мавҷуд набудани сабт дар бораи он дар хатсайрҳо дар коммутаторе мебошад, ки ҳамчун роутер бо Junos OS амал мекунад.
Реализация
Python + Junos PyEZ, гарчанде ки васвасаи иҷрои он тавассути paramiko ва ssh.exec_command вуҷуд дошт,
Насб кардани версияи ҷории 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 OS-ро бо истифода аз консол, 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 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()")
Қисми боқимонда дар як ҳалқаи 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
Манбаъ: will.com