Junos PyEZ-ի հետ աշխատելու մասին հոդված՝ «Python միկրոշրջանակ, որը թույլ է տալիս կառավարել և ավտոմատացնել Junos OS-ով աշխատող սարքերը» ավտոմատացում և կառավարում, այն ամենը, ինչ մենք սիրում ենք: Այս հոդվածում նկարագրված սցենարը գրելն ուներ մի քանի նպատակ՝ սովորել Python և ավտոմատացնել առաջադրանքները՝ տեղեկատվություն հավաքելու կամ Junos OS-ով աշխատող սարքավորումների կոնֆիգուրացիաները փոխելու համար: Python + Junos PyEZ-ի այս հատուկ համակցության ընտրությունը կատարվել է Python ծրագրավորման լեզվի մուտքի ցածր խոչընդոտի և Junos PyEZ գրադարանի հեշտ օգտագործման պատճառով, որը չի պահանջում Junos OS-ի փորձագիտական գիտելիքներ:
Առաջադրանք
Ընկերությանը պատկանող անվճար ipv4 ենթացանցերի աուդիտ: Ենթացանցն անվճար լինելու չափանիշը դրա մասին մուտքի բացակայությունն է անջատիչի երթուղիներում, որը գործում է որպես Junos OS-ով աշխատող երթուղիչ:
Իրականացման
Python + Junos PyEZ, չնայած կար գայթակղություն դա անել paramiko-ի և ssh.exec_command-ի միջոցով,
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 OS-ով աշխատող սարքավորումներին միանալու համար՝ օգտագործելով վահանակ, telnet կամ netconf ssh-ի միջոցով: Հոդվածում քննարկվում է վերջին տարբերակը:
Սարքավորումներին միանալու համար օգտագործեք jnpr.junos մոդուլի Device դասը
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()")
Մնացած մասը փաթաթված էր մի քիչ հանգույցով, որպեսզի չկրկնվի հարցումը երթուղիչին, եթե անհրաժեշտ լիներ ստուգել այլ ենթացանցում, որոնց մասին երթուղիչն արդեն գիտի: Հարկ է նշել, որ երթուղիչը, որի վրա ես հարցում եմ անում, գիտի երթուղիները միայն 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
Source: www.habr.com