Junos PyEZ χρησιμοποιώντας το παράδειγμα της εργασίας αναζήτησης δωρεάν υποδικτύων ipv4

Ένα άρθρο σχετικά με την εργασία με το 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, Ως αποτέλεσμα, θα χρειαστεί να διαμορφώσετε το πρωτόκολλο διαχείρισης δικτύου της συσκευής netconf στον εξοπλισμό που ελέγχεται. Το Netconf λειτουργεί με υλικό μέσω απομακρυσμένης διαδικασίας κλήσης RPC και χρησιμοποιεί XML, σε αυτό το παράδειγμα, για να παρέχει τις πληροφορίες που λαμβάνει.

Η εγκατάσταση της τρέχουσας έκδοσης του Junos PyEZ από το PyPI γίνεται με την ακόλουθη εντολή:

$ pip install junos-eznc

Μπορείτε επίσης να εγκαταστήσετε από τον κύριο κλάδο του έργου στο GitHub με την ακόλουθη εντολή:

$ pip install git+https://github.com/Juniper/py-junos-eznc.git

Και μια ακόμη επιλογή μέσω

$ pip install -r requirements.txt 

Αυτή η εντολή θα εγκαταστήσει βιβλιοθήκες που λείπουν από το σύστημα και είναι απαραίτητες για λειτουργία. Στη δική μου εκδοχή απαιτήσεις.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, έτσι ώστε να μην επαναληφθεί το αίτημα στον δρομολογητή εάν ήταν απαραίτητο να γίνει έλεγχος σε άλλο υποδίκτυο από αυτά που γνωρίζει ήδη ο δρομολογητής. Αξίζει να αναφέρουμε ότι ο δρομολογητής στον οποίο υποβάλλω το αίτημα γνωρίζει διαδρομές μόνο μέσω OSPF, επομένως για έναν δρομολογητή edge είναι καλύτερα να αλλάξετε λίγο το αίτημα για να μειώσετε τον χρόνο εκτέλεσης του σεναρίου

data = dev.rpc.get_ospf_route_information()

Τώρα ας δούμε τα περιεχόμενα του βρόχου while

Στην αρχή, ο χρήστης θα κληθεί να εισαγάγει ένα υποδίκτυο με μάσκα και όχι περισσότερες από τρεις οκτάδες από το δίκτυο του ίδιου υποδικτύου, αυτό είναι απαραίτητο για να ορίσετε το εύρος αναζήτησης. Δεν μου αρέσει πολύ αυτή η εφαρμογή του καθορισμού των κριτηρίων και του εύρους αναζήτησης, αλλά μέχρι στιγμής δεν έχω βρει καλύτερη λύση. Στη συνέχεια, από τη λίστα των υποδικτύων 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

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο