บทความเกี่ยวกับการทำงานร่วมกับ Junos PyEZ - “ไมโครเฟรมเวิร์ก Python ที่ช่วยให้คุณจัดการและทำให้อุปกรณ์ที่ใช้ Junos OS เป็นอัตโนมัติ” การทำงานอัตโนมัติและการจัดการ ทุกสิ่งที่เราชอบ การเขียนสคริปต์ที่อธิบายไว้ในบทความนี้มีเป้าหมายหลายประการ - การเรียนรู้ Python และการทำงานอัตโนมัติสำหรับการรวบรวมข้อมูลหรือการเปลี่ยนแปลงการกำหนดค่าบนอุปกรณ์ที่ใช้ Junos OS ทางเลือกของชุดค่าผสมเฉพาะของ Python + Junos PyEZ เกิดขึ้นเนื่องจากมีอุปสรรคต่ำในการเข้าสู่ภาษาการเขียนโปรแกรม Python และความสะดวกในการใช้งานไลบรารี Junos PyEZ ซึ่งไม่ต้องการความรู้จากผู้เชี่ยวชาญเกี่ยวกับ Junos OS
งาน
การตรวจสอบซับเน็ต ipv4 ฟรีที่เป็นของบริษัท เกณฑ์ที่ซับเน็ตว่างคือการไม่มีรายการเกี่ยวกับซับเน็ตในเส้นทางบนสวิตช์ที่ทำหน้าที่เป็นเราเตอร์ที่ใช้ Junos OS
การดำเนินงาน
Python + Junos PyEZ แม้ว่าจะมีสิ่งล่อใจให้ทำผ่าน paramiko และ ssh.exec_command
การติดตั้ง Junos PyEZ เวอร์ชันปัจจุบันจาก PyPI ทำได้ด้วยคำสั่งต่อไปนี้:
$ pip install junos-eznc
คุณยังสามารถติดตั้งจากสาขาหลักของโปรเจ็กต์บน GitHub ด้วยคำสั่งต่อไปนี้:
$ pip install git+https://github.com/Juniper/py-junos-eznc.git
และอีกหนึ่งทางเลือกผ่านทาง
$ pip install -r requirements.txt
คำสั่งนี้จะติดตั้งไลบรารีที่ขาดหายไปจากระบบและจำเป็นสำหรับการดำเนินการ ในเวอร์ชั่นของฉัน Requirement.txt มีเพียงสองรายการเท่านั้น เวอร์ชันล่าสุดจะถูกระบุในขณะที่เขียนสคริปต์:
junos-eznc
netaddr
ตามค่าเริ่มต้น สคริปต์จะใช้ชื่อผู้ใช้ปัจจุบันในระบบ คุณสามารถเข้าสู่ระบบด้วยชื่อผู้ใช้อื่นได้โดยใช้คีย์ show_route.py -u getpass.getpass รับรหัสผ่านจาก stdin ดังนั้นรหัสผ่านจะไม่คงอยู่ในระบบ หากต้องการเชื่อมต่อกับอุปกรณ์ คุณจะต้องป้อนชื่อโฮสต์หรือที่อยู่ IP เมื่อได้รับแจ้ง ได้รับข้อมูลทั้งหมดที่จำเป็นสำหรับการอนุญาตบนอุปกรณ์แล้ว
Junos PyEZ รองรับการเชื่อมต่อกับอุปกรณ์ที่ใช้ Junos OS โดยใช้คอนโซล telnet หรือ netconf ผ่าน ssh บทความนี้กล่าวถึงตัวเลือกหลัง
หากต้องการเชื่อมต่อกับอุปกรณ์ ให้ใช้คลาส Device ของโมดูล jnpr.junos
with jnpr.junos.Device(host=router,
user=args.name,
passwd=password) as dev:
มีการร้องขอสำหรับทุกเส้นทางที่เราเตอร์รู้จักผ่านการเรียกขั้นตอนระยะไกลหรือการเรียกขั้นตอนระยะไกล แล้วแต่ว่าจะสะดวกกว่ากัน
data = dev.rpc.get_route_information()
คำสั่งที่คล้ายกันบน Junos OS
user@router> show route | display xml
โดยการเพิ่ม rpc ที่ส่วนท้ายของคำสั่ง เราจะได้รับแท็กคำขอและสามารถจับคู่กับชื่อของวิธี RPC ได้ ด้วยวิธีนี้ เราจะสามารถค้นหาชื่ออื่นๆ ที่น่าสนใจได้ เป็นที่น่าสังเกตว่าไวยากรณ์ในการเขียนแท็กคำขอนั้นแตกต่างจากชื่อวิธีการ กล่าวคือ คุณควรแทนที่ยัติภังค์ด้วยขีดล่าง
user@router> show route | display xml rpc
<rpc-reply >route_list = data.xpath("//rt-destination/text()")
ส่วนที่เหลือถูกพันไว้ใน while loop เพื่อไม่ให้ส่งคำขอไปยังเราเตอร์ซ้ำหากจำเป็นต้องตรวจสอบในเครือข่ายย่อยอื่นจากเครือข่ายที่เราเตอร์รู้อยู่แล้ว เป็นที่น่าสังเกตว่าเราเตอร์ที่ฉันกำลังร้องขอนั้นรู้เส้นทางผ่าน OSPF เท่านั้น ดังนั้นสำหรับเราเตอร์ Edge จะดีกว่าถ้าเปลี่ยนคำขอเล็กน้อยเพื่อลดเวลาการทำงานของสคริปต์
data = dev.rpc.get_ospf_route_information()
ตอนนี้เรามาดูเนื้อหาของ while loop กัน
ในตอนแรกผู้ใช้จะถูกขอให้ป้อนเครือข่ายย่อยด้วยมาสก์และไม่เกินสามออคเต็ตจากเครือข่ายของเครือข่ายย่อยเดียวกัน ซึ่งจำเป็นสำหรับการตั้งค่าช่วงการค้นหา ฉันไม่ชอบการใช้การระบุเกณฑ์และช่วงการค้นหานี้มากนัก แต่จนถึงตอนนี้ฉันยังไม่พบวิธีแก้ปัญหาที่ดีกว่านี้ ถัดไป จากรายการผลลัพธ์ของเครือข่ายย่อย Route_list โดยใช้ตัวแปรที่มีออคเต็ตไม่เกินสามออคเต็ต ฉันเลือกเครือข่ายย่อยที่ฉันสนใจ
tmp = re.search(r'^%sS*' % subnet_search, route_list[i])
ผ่าน IPNetwork ซึ่งเป็นโมดูล netaddr ฉันได้รับเครือข่ายย่อยในรูปแบบของรายการที่อยู่ ipv4
range_subnet = netaddr.IPNetwork(tmp.group(0))
เมื่อใช้ IPNetwork ฉันได้รับช่วงที่อยู่จากเครือข่ายที่ผู้ใช้ป้อนพร้อมมาสก์ และสร้างรายการที่อยู่ทั้งหมดจากช่วงนี้เพื่อเปรียบเทียบกับรายการที่อยู่ที่ถูกครอบครอง
for i in set(net_list).difference(set(busyip)):
freeip.append(i)
ฉันแสดงรายการที่อยู่ว่างที่เป็นผลลัพธ์ในรูปแบบของเครือข่ายย่อย
print(netaddr.IPSet(freeip))
ด้านล่างนี้คือสคริปต์ฉบับสมบูรณ์ ซึ่งทดสอบกับสวิตช์ที่ใช้เป็นเราเตอร์ รุ่น 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
ที่มา: will.com