Artiklu dwar ix-xogħol ma' Junos PyEZ - "Python microframework li jippermettilek timmaniġġja u awtomat tagħmir li jħaddem Junos OS" awtomazzjoni u ġestjoni, dak kollu li nħobbu. Il-kitba tal-iskrittura deskritta f'dan l-artikolu kellha diversi għanijiet - it-tagħlim ta 'Python u l-awtomatizzazzjoni tal-kompiti għall-ġbir ta' informazzjoni jew il-bidla tal-konfigurazzjonijiet fuq tagħmir li jħaddem Junos OS. L-għażla ta 'din il-kombinazzjoni speċifika ta' Python + Junos PyEZ saret minħabba l-ostaklu baxx għad-dħul fil-lingwa ta 'programmar Python u l-faċilità ta' użu tal-librerija Junos PyEZ, li ma teħtieġx għarfien espert ta 'Junos OS.
Kompitu
Verifika tas-subnets ipv4 b'xejn li jappartjenu lill-kumpanija. Il-kriterju li subnet hija ħielsa huwa n-nuqqas ta 'dħul dwarha fir-rotot fuq is-swiċċ li jaġixxi bħala router li jħaddem Junos OS.
Реализация
Python + Junos PyEZ, għalkemm kien hemm it-tentazzjoni li tagħmel dan permezz ta' paramiko u ssh.exec_command,
L-installazzjoni tal-verżjoni attwali ta 'Junos PyEZ minn PyPI issir bil-kmand li ġej:
$ pip install junos-eznc
Tista 'wkoll tinstalla mill-fergħa prinċipali tal-proġett fuq GitHub bil-kmand li ġej:
$ pip install git+https://github.com/Juniper/py-junos-eznc.git
U għażla oħra permezz
$ pip install -r requirements.txt
Dan il-kmand se jinstalla libreriji li huma neqsin mis-sistema u li huma meħtieġa għat-tħaddim. Fil-verżjoni tiegħi rekwiżiti.txt Hemm tnejn minnhom biss, l-aħħar verżjonijiet huma indikati fil-ħin tal-kitba tal-iskrittura:
junos-eznc
netaddr
L-iskript awtomatikament jieħu l-isem tal-utent attwali fis-sistema, tista’ tidħol taħt l-isem ta’ utent ieħor billi tuża ċ-ċavetta show_route.py -u getpass.getpass jieħu l-password minn stdin sabiex il-password ma tibqax fis-sistema. Biex tikkonnettja mat-tagħmir, ser ikollok bżonn ukoll li ddaħħal l-isem tal-host jew l-indirizz IP tiegħu meta tintalab. Id-dejta kollha meħtieġa għall-awtorizzazzjoni fuq l-apparat waslet.
Junos PyEZ jappoġġja l-konnessjoni ma 'tagħmir li jħaddem Junos OS billi juża l-console, telnet jew netconf permezz ta' ssh. L-artikolu jiddiskuti l-aħħar għażla.
Biex tikkonnettja mat-tagħmir, uża l-klassi Device tal-modulu jnpr.junos
with jnpr.junos.Device(host=router,
user=args.name,
passwd=password) as dev:
Issir talba għar-rotot kollha magħrufa lir-router permezz ta' sejħa ta' proċedura remota jew sejħa ta' proċedura remota, skont liema jkun l-aktar konvenjenti.
data = dev.rpc.get_route_information()
Kmand simili fuq Junos OS
user@router> show route | display xml
Billi żżid rpc fl-aħħar tal-kmand, niksbu tikketta ta 'talba u nistgħu nqabbluha mal-isem tal-metodu RPC, b'dan il-mod nistgħu nsibu ismijiet oħra ta' interess. Ta 'min jinnota li s-sintassi għall-kitba tat-tikketta tat-talba hija differenti mill-isem tal-metodu, jiġifieri, għandek tissostitwixxi s-singi b'sottolinja.
user@router> show route | display xml rpc
<rpc-reply >route_list = data.xpath("//rt-destination/text()")
Il-bqija tal-parti kienet imgeżwer f'xi loop, sabiex ma tirrepetix it-talba lir-router jekk kien meħtieġ li tiċċekkja f'subnet ieħor minn dawk li r-router diġà jaf dwarhom. Ta’ min isemmi li r-router li fuqu qed nagħmel it-talba jaf ir-rotot biss permezz tal-OSPF, għalhekk għal router edge huwa aħjar li tbiddel ftit it-talba biex tnaqqas il-ħin ta’ tħaddim tal-iscript
data = dev.rpc.get_ospf_route_information()
Issa ejja nħarsu lejn il-kontenut tal-loop while
Fil-bidu, l-utent se jintalab jidħol f'subnet b'maskra u mhux aktar minn tliet ottetti min-netwerk tal-istess subnet, dan huwa meħtieġ biex tissettja l-firxa tat-tfittxija. Ma tantx inħobb din l-implimentazzjoni li tispeċifika l-kriterji u l-firxa tat-tiftix, iżda s'issa ma sibtx soluzzjoni aħjar. Sussegwentement, mil-lista li tirriżulta tas-subnets route_list, billi tuża varjabbli li fiha mhux aktar minn tliet ottetti, nagħżel is-subnets li jinteressani
tmp = re.search(r'^%sS*' % subnet_search, route_list[i])
Permezz tal-IPNetwork, il-modulu netaddr, nirċievi subnets fil-forma ta’ lista ta’ indirizzi ipv4
range_subnet = netaddr.IPNetwork(tmp.group(0))
Bl-użu tal-IPNetwork, nikseb firxa ta 'indirizzi minn netwerk imdaħħal mill-utent b'maskra u niġġenera lista tal-indirizzi kollha minn din il-firxa għal tqabbil mal-lista ta' indirizzi okkupati.
for i in set(net_list).difference(set(busyip)):
freeip.append(i)
Jiena nuri l-lista li tirriżulta ta 'indirizzi ħielsa fil-forma ta' subnets
print(netaddr.IPSet(freeip))
Hawn taħt hemm l-iskript komplut, ittestjat fuq swiċċijiet użati bħala router, mudelli 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
Sors: www.habr.com