En artikel om att arbeta med Junos PyEZ - "Python microframework som gör det möjligt för dig att hantera och automatisera enheter som kör Junos OS" automation och hantering, allt vi Àlskar. Att skriva skriptet som beskrivs i den hÀr artikeln hade flera mÄl - att lÀra sig Python och automatisera uppgifter för att samla in information eller Àndra konfigurationer pÄ utrustning som kör Junos OS. Valet av denna specifika kombination av Python + Junos PyEZ gjordes pÄ grund av den lÄga barriÀren för intrÀde i Python-programmeringssprÄket och den enkla anvÀndningen av Junos PyEZ-biblioteket, som inte krÀver expertkunskaper om Junos OS.
Uppgift
Granskning av gratis ipv4-undernÀt som tillhör företaget. Kriteriet att ett subnÀt Àr gratis Àr frÄnvaron av en post om det i rutterna pÄ switchen som fungerar som en router som kör Junos OS.
genomförande
Python + Junos PyEZ, Àven om det fanns en frestelse att göra det genom paramiko och ssh.exec_command, Som ett resultat mÄste du konfigurera netconf-enhetens nÀtverkshanteringsprotokoll pÄ den utrustning som avfrÄgas. Netconf arbetar med hÄrdvara via fjÀrrproceduranrop RPC och anvÀnder XML, i det hÀr exemplet, för att tillhandahÄlla den information den tar emot.
Installation av den aktuella versionen av Junos PyEZ frÄn PyPI görs med följande kommando:
$ pip install junos-ezncDu kan ocksÄ installera frÄn projektets huvudgren pÄ GitHub med följande kommando:
$ pip install git+https://github.com/Juniper/py-junos-eznc.gitOch ytterligare ett alternativ via
$ pip install -r requirements.txt Detta kommando kommer att installera bibliotek som saknas i systemet och som Àr nödvÀndiga för drift. I min version requirements.txt Det finns bara tvÄ av dem, de senaste versionerna anges nÀr manuset skrevs:
junos-eznc
netaddrSom standard tar skriptet namnet pÄ den aktuella anvÀndaren i systemet; du kan logga in under namnet pÄ en annan anvÀndare med hjÀlp av show_route.py -u-tangenten getpass.getpass tar lösenordet frÄn stdin sÄ lösenordet kommer inte att finnas kvar i systemet. För att ansluta till utrustningen mÄste du ocksÄ ange dess vÀrdnamn eller IP-adress nÀr du uppmanas att göra det. Alla data som behövs för auktorisering pÄ enheten har tagits emot.
Junos PyEZ stöder anslutning till utrustning som kör Junos OS med hjÀlp av konsolen, telnet eller netconf via ssh. Artikeln diskuterar det senare alternativet.
För att ansluta till utrustning, anvÀnd enhetsklassen för jnpr.junos-modulen
with jnpr.junos.Device(host=router,
user=args.name,
passwd=password) as dev:En begÀran görs för alla rutter som Àr kÀnda för routern via fjÀrrproceduranrop eller fjÀrrproceduranrop, beroende pÄ vilket som Àr lÀmpligast.
data = dev.rpc.get_route_information()Liknande kommando pÄ Junos OS
user@router> show route | display xmlGenom att lÀgga till rpc i slutet av kommandot fÄr vi en request-tagg och kan matcha den med namnet pÄ RPC-metoden, pÄ sÄ sÀtt kan vi ta reda pÄ andra namn av intresse. Det Àr vÀrt att notera att syntaxen för att skriva begÀrantaggen skiljer sig frÄn metodnamnet, nÀmligen att du bör ersÀtta bindestreck med understreck.
user@router> show route | display xml rpc
<rpc-reply >route_list = data.xpath("//rt-destination/text()")Resten av delen lindades in i en while-loop, för att inte upprepa begÀran till routern om det var nödvÀndigt att checka in ett annat subnÀt frÄn de som routern redan kÀnner till. Det Àr vÀrt att nÀmna att routern som jag gör förfrÄgan pÄ kÀnner till rutter endast genom OSPF, sÄ för en kantrouter Àr det bÀttre att Àndra förfrÄgan lite för att minska skriptets körtid
data = dev.rpc.get_ospf_route_information()LÄt oss nu titta pÄ innehÄllet i while-slingan
I början kommer anvÀndaren att bli ombedd att ange ett subnÀt med en mask och inte mer Àn tre oktetter frÄn nÀtverket i samma subnÀt, detta Àr nödvÀndigt för att stÀlla in sökintervallet. Jag gillar inte riktigt den hÀr implementeringen av att specificera kriterierna och sökintervallet, men Àn sÄ lÀnge har jag inte hittat en bÀttre lösning. DÀrefter, frÄn den resulterande listan över subnÀt route_list, med en variabel som innehÄller högst tre oktetter, vÀljer jag de subnÀt som intresserar mig
tmp = re.search(r'^%sS*' % subnet_search, route_list[i])Genom IPNetwork, netaddr-modulen, tar jag emot subnÀt i form av en lista med ipv4-adresser
range_subnet = netaddr.IPNetwork(tmp.group(0))Med IPNetwork hÀmtar jag en rad adresser frÄn ett anvÀndarinmatat nÀtverk med en mask och genererar en lista över alla adresser frÄn detta omrÄde för jÀmförelse med listan över upptagna adresser.
for i in set(net_list).difference(set(busyip)):
freeip.append(i)Jag visar den resulterande listan med lediga adresser i form av subnÀt
print(netaddr.IPSet(freeip))Nedan Àr det kompletta skriptet, testat pÄ switchar som anvÀnds som router, modeller 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
KĂ€lla: will.com
