Gotarek li ser xebata bi Junos PyEZ - "Mîkroçarçoveya Python ku dihêle hûn cîhazên ku Junos OS-ê dixebitin" û rêvebirinê bi rêve bibin û otomatîk bikin, her tiştê ku em jê hez dikin. Nivîsandina skrîpta ku di vê gotarê de hatî destnîşan kirin çend armanc hebûn - fêrbûna Python û otomatîkkirina peywiran ji bo berhevkirina agahdarî an guheztina mîhengan li ser alavên ku Junos OS-ê dixebitin. Hilbijartina vê kombînasyona taybetî ya Python + Junos PyEZ ji ber astengiya kêm a têketina zimanê bernamesaziya Python û hêsaniya karanîna pirtûkxaneya Junos PyEZ, ku hewcedariya zanîna pispor a Junos OS-ê nake, hate çêkirin.
Armanc
Kontrolkirina subnetên belaş ipv4 yên ku aîdê pargîdaniyê ne. Pîvana ku subnetek belaş e nebûna têketinek di derheqê wê de di rêyên li ser guhêzbarê de ye ku wekî routerek ku Junos OS-ê dixebitîne tevdigere.
Реализация
Python + Junos PyEZ, her çend ceribandinek hebû ku meriv wiya bi paramiko û ssh.exec_command bike,
Sazkirina guhertoya heyî ya Junos PyEZ ji PyPI bi fermana jêrîn pêk tê:
$ pip install junos-eznc
Her weha hûn dikarin ji şaxê sereke yê projeyê li ser GitHub bi fermana jêrîn saz bikin:
$ pip install git+https://github.com/Juniper/py-junos-eznc.git
Û vebijarkek din bi rêya
$ pip install -r requirements.txt
Ev ferman dê pirtûkxaneyên ku ji pergalê winda ne û ji bo xebatê hewce ne saz bike. Di versiyona min de daxwazên.txt Tenê du ji wan hene, guhertoyên herî dawî di dema nivîsandina senaryoyê de têne destnîşan kirin:
junos-eznc
netaddr
Skrîpta bi xweber navê bikarhênerê heyî yê pergalê digire, hûn dikarin di bin navê bikarhênerek din de bi karanîna mifteya show_route.py -u getpass.getpass şîfreyê ji stdin digire da ku şîfre namîne di sîstemê de. Ji bo girêdana bi alavan re, hûn ê jî hewce bikin ku dema ku tê xwestin navê mêvandar an navnîşana IP-ya wê têkevin. Hemî daneyên ku ji bo destûrnameyê li ser cîhazê hewce ne hatine wergirtin.
Junos PyEZ piştgirî dide girêdana bi alavên ku Junos OS-ê bi karanîna konsol, telnet an netconf-ê bi ssh-ê dimeşînin. Gotar bijareya paşîn nîqaş dike.
Ji bo girêdana bi alavên, çîna Device ya modula jnpr.junos bikar bînin
with jnpr.junos.Device(host=router,
user=args.name,
passwd=password) as dev:
Daxwazek ji bo hemî rêçikên ku ji router re têne zanîn bi banga prosedûra dûr an banga prosedûra dûr ve tê kirin, kîjan ku hêsantir be.
data = dev.rpc.get_route_information()
Fermana bi heman rengî li ser Junos OS
user@router> show route | display xml
Bi lêzêdekirina rpc li dawiya fermanê, em tagek daxwazê distînin û dikarin wê bi navê rêbaza RPC-ê re hevber bikin, bi vî rengî em dikarin navên din ên balkêş bibînin. Hêjayî gotinê ye ku hevoksaziya nivîsandina etîketa daxwaznameyê ji navê rêbazê cûda ye, ango, divê hûn xêzikan bi binxetê veguherînin.
user@router> show route | display xml rpc
<rpc-reply >route_list = data.xpath("//rt-destination/text()")
Beşa mayî di nav hûrek hûrdemê de hate pêçandin, da ku daxwazek ji routerê re dubare neke ger hewce bû ku di binnetek din de ji yên ku router jixwe pê dizane kontrol bikin. Hêjayî gotinê ye ku routera ku ez lê daxwazê dikim rêçikan tenê bi OSPF-ê dizane, ji ber vê yekê ji bo routerek qerax çêtir e ku meriv daxwazê hinekî biguhezîne da ku dema xebitandina nivîsê kêm bike.
data = dev.rpc.get_ospf_route_information()
Naha em li naverokên lûleya while binêrin
Di destpêkê de, ji bikarhêner tê xwestin ku bi maskek û ne bêtir ji sê oktetan ji tora heman subnetê têkevin bintorê, ev hewce ye ku rêza lêgerînê were danîn. Ez bi rastî ji vê pêkanîna diyarkirina pîvan û qada lêgerînê hez nakim, lê heya nuha min çareseriyek çêtir nedîtiye. Dûv re, ji navnîşa encam a navnîşa jêrtorê route_list, bi karanîna guhêrbarek ku ji sê oktetan zêdetir tê de ne, ez jêrtorên ku ji min re eleqedar dibin hildibijêrim.
tmp = re.search(r'^%sS*' % subnet_search, route_list[i])
Bi rêya IPNetwork, modula netaddr, ez di forma navnîşek navnîşanên ipv4 de subnetan distînim.
range_subnet = netaddr.IPNetwork(tmp.group(0))
Bi karanîna IPNetwork-ê, ez ji torgilokek ku bikarhêner bi maskek ketiye nav rêzek navnîşan distînim û navnîşek hemî navnîşanên ji vê rêzê ji bo berhevdana bi navnîşa navnîşanên dagirkirî re çêdikim.
for i in set(net_list).difference(set(busyip)):
freeip.append(i)
Ez navnîşa encam a navnîşanên belaş di forma subnetan de nîşan didim
print(netaddr.IPSet(freeip))
Li jêr skrîpta bêkêmasî ye, ku li ser guhezên ku wekî router têne bikar anîn hatine ceribandin, modelên 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