Ang artikulo sa pagtatrabaho sa Junos PyEZ—"Isang Python microframework na nagbibigay-daan sa iyong pamahalaan at i-automate ang mga device na nagpapatakbo ng Junos OS"—ay tungkol sa automation at pamamahala, sa paraang gusto namin ito. Ang script na inilarawan sa artikulong ito ay isinulat na may ilang layunin sa isip: pag-aaral ng Python at pag-automate ng mga gawain tulad ng pagkolekta ng impormasyon o pagbabago ng mga configuration sa hardware na tumatakbo sa Junos OS. Ang partikular na kumbinasyong Python + Junos PyEZ ay pinili dahil sa mababang curve ng pagkatuto para sa Python programming language at ang kadalian ng paggamit ng Junos PyEZ library, na hindi nangangailangan ng ekspertong kaalaman sa Junos OS.
Gawain
Isang pag-audit ng mga available na IPv4 subnet na pagmamay-ari ng kumpanya. Itinuturing na available ang isang subnet kung hindi ito nakalista sa mga ruta sa switch na kumikilos bilang isang router na nagpapatakbo ng Junos OS.
Pagpapatupad
Python + Junos PyEZ, kahit na natukso akong gawin ito sa pamamagitan ng paramiko at ssh.exec_command, Bilang resulta, kakailanganin mong i-configure ang network device management protocol (NetConf) sa kagamitang sinusuri. Nakikipag-ugnayan ang NetConf sa kagamitan sa pamamagitan ng mga remote procedure call (RPC) at, sa halimbawang ito, gumagamit ng XML upang ipakita ang impormasyong natatanggap nito.
Upang i-install ang kasalukuyang bersyon ng Junos PyEZ mula sa PyPI, patakbuhin ang sumusunod na command:
$ pip install junos-ezncMaaari mo ring i-install ito mula sa pangunahing sangay ng proyekto sa GitHub gamit ang sumusunod na command:
$ pip install git+https://github.com/Juniper/py-junos-eznc.gitAt isa pang pagpipilian sa pamamagitan ng
$ pip install -r requirements.txt I-install ng command na ito ang mga nawawalang library na kinakailangan para sa operasyon. Sa aking bersyon mga kinakailangan.txt Dalawa lang sila, ang mga bersyon na nakalista ay ang pinakabago sa oras ng pagsulat ng script:
junos-eznc
netaddrBilang default, kinukuha ng script ang pangalan ng kasalukuyang user sa system; maaari kang mag-log in sa ilalim ng pangalan ng isa pang user gamit ang show_route.py -u key. tumatanggap ang getpass.getpass ng password mula sa stdin, kaya hindi ito mananatili sa system. Upang kumonekta sa device, kakailanganin mo ring ilagay ang hostname o IP address nito kapag na-prompt. Natanggap na ang lahat ng data na kinakailangan para sa awtorisasyon ng device.
Sinusuportahan ng Junos PyEZ ang pagkonekta sa hardware ng Junos OS gamit ang console, telnet, o netconf sa SSH. Tinatalakay ng artikulong ito ang huling opsyon.
Upang kumonekta sa kagamitan, ginagamit ang klase ng Device ng jnpr.junos module.
with jnpr.junos.Device(host=router,
user=args.name,
passwd=password) as dev:Ang isang kahilingan para sa lahat ng mga ruta na kilala sa router ay ginawa sa pamamagitan ng isang remote procedure call o isang remote procedure call, alinman ang mas maginhawa.
data = dev.rpc.get_route_information()Isang katulad na utos sa Junos OS
user@router> show route | display xmlSa pamamagitan ng pagdaragdag ng rpc sa command, nakakakuha kami ng request tag at maaari itong itugma sa pangalan ng RPC method. Ang pamamaraang ito ay maaari ding gamitin upang maghanap ng iba pang mga pangalan ng interes. Kapansin-pansin na ang syntax para sa pagsusulat ng isang request tag ay iba sa pangalan ng pamamaraan; partikular, ang mga gitling ay dapat palitan ng mga salungguhit.
user@router> show route | display xml rpc
<rpc-reply >route_list = data.xpath("//rt-destination/text()")Ibinalot ko ang natitirang bahagi ng query sa isang while loop upang maiwasan ang muling pag-query sa router kung kailangan kong tingnan ang ibang subnet kaysa sa alam na ng router. Ito ay nagkakahalaga ng pagbanggit na ang router na aking tinatanong ay nakakaalam lamang ng mga ruta sa pamamagitan ng OSPF, kaya para sa gilid ng router, pinakamahusay na bahagyang baguhin ang query upang mabawasan ang oras ng pagpapatupad ng script.
data = dev.rpc.get_ospf_route_information()Ngayon tingnan natin ang mga nilalaman ng while loop.
Sa una, ipo-prompt ang user na magpasok ng subnet na may mask at hanggang tatlong octet mula sa network ng parehong subnet; ito ay kinakailangan upang itakda ang hanay ng paghahanap. Hindi ko talaga gusto ang diskarteng ito sa pagtukoy ng pamantayan at saklaw ng paghahanap, ngunit hindi pa ako nakakahanap ng mas mahusay na solusyon. Susunod, mula sa resultang listahan ng mga subnet, route_list, pipiliin ko ang mga subnet na interesado akong gumamit ng variable na naglalaman ng hanggang tatlong octet.
tmp = re.search(r'^%sS*' % subnet_search, route_list[i])Gamit ang IPNetwork, ang netaddr module, nakakakuha ako ng mga subnet bilang isang listahan ng mga IPv4 address.
range_subnet = netaddr.IPNetwork(tmp.group(0))Gamit ang IPNetwork, nakakakuha ako ng isang hanay ng mga address mula sa network na inilagay ng user na may mask at bumubuo ng isang listahan ng lahat ng mga address mula sa hanay na ito para sa paghahambing sa listahan ng mga inookupahang address.
for i in set(net_list).difference(set(busyip)):
freeip.append(i)Ipinapakita ko ang resultang listahan ng mga libreng address sa anyo ng mga subnet
print(netaddr.IPSet(freeip))Nasa ibaba ang buong script, nasubok sa mga switch na ginamit bilang router, mga modelong 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
Pinagmulan: www.habr.com
