NjĂ« artikull rreth punĂ«s me Junos PyEZ â âPython microframework qĂ« ju lejon tĂ« menaxhoni dhe automatizoni pajisjet qĂ« funksionojnĂ« me Junos OSâ automatizimi dhe menaxhimi, ashtu siç na pĂ«lqen. Shkrimi i skenarit tĂ« pĂ«rshkruar nĂ« kĂ«tĂ« artikull kishte disa qĂ«llime â tĂ« studiohej Python dhe tĂ« automatizoheshin detyrat pĂ«r mbledhjen e informacionit ose ndryshimin e konfiguracionit nĂ« pajisjet qĂ« funksionojnĂ« me Junos OS. Zgjedhja e lidhjes Python + Junos PyEZ u bĂ« pĂ«r shkak tĂ« pragut tĂ« ulĂ«t tĂ« hyrjes nĂ« gjuhĂ«n e programimit Python dhe thjeshtĂ«sisĂ« sĂ« pĂ«rdorimit tĂ« bibliotekĂ«s Junos PyEZ, e cila nuk kĂ«rkon njohuri ekspertĂ«sh pĂ«r Junos OS.
Detyra
Auditimi i subneteve tĂ« lira ipv4 qĂ« i pĂ«rkasin kompanisĂ«. Kritere pĂ«r tĂ« pĂ«rcaktuar qĂ« subneti Ă«shtĂ« i lirĂ« â Ă«shtĂ« mungesa e njĂ« regjistrimi pĂ«r tĂ« nĂ« itineraret nĂ« switch-in qĂ« ka rolin e router-it nĂ«n administrimin e Junos OS.
Realizimi
Python + Junos PyEZ, ndonëse kishte tundimin të bëhej përmes paramiko dhe ssh.exec_command, si pasojë do të nevojitet ndarja e protokollit të menaxhimit të pajisjeve netconf në pajisjen e pyetur. Netconf punon me pajisjet përmes thirrjeve të procedurave të largëta (remote procedure call RPC) dhe përdor XML, në shembullin e shqyrtuar, për të ofruar informacionin e marrë.
Instalimi i versionit aktual të Junos PyEZ nga PyPI, bëhet me komandën e mëposhtme:
$ pip install junos-ezncGjithashtu mund të instalohet nga dega kryesore e projektit në GitHub me komandën e mëposhtme:
$ pip install git+https://github.com/Juniper/py-junos-eznc.gitDhe një mundësi tjetër është përmes
$ pip install -r requirements.txt kjo komandë do të instalojë bibliotekat që mungojnë në sistem të nevojshme për funksionim. Në versionin tim requirements.txt ka vetëm dy, versionet e caktuara janë të fundit në momentin e shkrimit të skenarit:
junos-eznc
netaddrSkenari fillimisht merr emrin e përdoruesit aktual në sistem, mund të kyçeni nën emrin e një përdoruesi tjetër duke përdorur çelësin show_route.py -u getpass.getpass merr fjalëkalimin nga stdin kështu që fjalëkalimi nuk do të mbetet në sistem. Për të lidhur me pajisjen gjithashtu do të nevojitet të futni sipas kërkesës hostname-in ose adresën IP të saj. Të dhënat e nevojshme për autorizimin në pajisje janë marrë.
Junos PyEZ mbështet lidhjen me pajisjet që funksionojnë me Junos OS duke përdorur konsolën, telnet ose netconf përmes ssh. Në artikullin e shqyrtuar është trajtuar opsioni i fundit.
Për të lidhur me pajisjen, përdoret klasa Device e modulit jnpr.junos
with jnpr.junos.Device(host=router,
user=args.name,
passwd=password) as dev:Kërkohet informacion për të gjitha itineraret e njohura nga routeri përmes thirrjes së procedurave të largëta ose thirrjen e procedurave të largëta, siç preferohet.
data = dev.rpc.get_route_information()Komanda e ngjashme në Junos OS
user@router> show route | display xmlDuke shtuar në fund të komandës rpc, do të marrim etiketën e kërkesës dhe mund të lidhim atë me emrin e metodës RPC, në këtë mënyrë mund të zbulojmë edhe emra të tjerë interesant. Duhet theksuar se sintaksa e shkruajtur e etiketës së kërkesës ndryshon nga emri i metodës, saktësisht duhet të zëvendësohen shenjat e defisëve me thekse të ulëta.
user@router> show route | display xml rpc
route_list = data.xpath("//rt-destination/text()")Pjesa tjetër e kam vendosur në një cikël while, për të mos kryer përsëri kërkesën në router, nëse do të kontrollohet në një subnet tjetër të njohur nga routeri. Duhet përmendur se router-i nga i cili kërkoj, njeh itineraret vetëm përmes OSPF, kështu që për router-in kufitar është më mirë të ndryshoni pak kërkesën për të reduktuar kohën e punës së skenarit.
data = dev.rpc.get_ospf_route_information()Tani le të kthehemi në përmbajtjen e ciklit while
Fillimisht përdoruesit do t'i kërkohet të fusë subnetin me maskë dhe jo më shumë se tre oktet nga rrjeti i këtij subneti, kjo është e domosdoshme për të vendosur gamën e kërkimit. Nuk më pëlqen shumë kjo realizim për të vendosur kriterin dhe gamën e kërkimit, por derisa nuk kam gjetur ndonjë zgjidhje më të mirë. Më pas nga lista e marrë e subneteve route_list, duke përdorur variablën që përmban jo më shumë se tre oktet, zgjedh subnetet që më interesojnë.
tmp = re.search(r'^%sS*' % subnet_search, route_list[i])Përmes IPNetwork, modulit netaddr, marr subnetet në formën e një liste ipv4 adresash.
range_subnet = netaddr.IPNetwork(tmp.group(0))Duke përdorur IPNetwork nga rrjeti i futur nga përdoruesi me maskë, marr gamën e adresave dhe formoj një listë të të gjitha adresave nga kjo gamë për t'i krahasuar me listën e adresave të zëna.
for i in set(net_list).difference(set(busyip)):
freeip.append(i)Lista e marrë e adresave të lira e shfaq në formën e subneteve.
print(netaddr.IPSet(freeip))Më poshtë është skenari i plotë, është testuar në switches që përdoren si routera, modele 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
Burimi: habr.com
