Versuchen Sie, den Betrieb von Netzwerkgeräten mit Python zu automatisieren

Dieser Artikel ist der 14. Tagesartikel von NIFTY Adventskalender 2016. Gestern war @ntoofus Ansible-Konfigurationsinformationen mit Grafik-DB verwalten.

Hallo. In meiner täglichen Arbeit baue, betreibe und pflege ich die Netzwerkinfrastruktur in Nifty Cloud. Dieses Mal möchte ich ein wenig über die Automatisierung des Betriebs physischer Geräte im Netzwerk schreiben, die auf der Serviceseite von Nifty Cloud nicht sichtbar ist.

Zum Beispiel eine solche Situation

-Der Neustart des Geräts wurde ausgeführt
-Die Geräteschnittstelle ist abgestürzt
-Modul fehlgeschlagen
-Jedenfalls stimmt etwas nicht

Es kommt oft vor, dass so etwas wie ... auftritt und Sie den Status des Geräts sofort überprüfen möchten. Melden Sie sich in diesen Fällen beim Gerät an (solange es noch verfügbar ist) und Es ist notwendig, sofort show-Befehle zu drücken, um Informationen zu sichern.

Man kann sagen, dass die Befehle zu diesem Zeitpunkt bis zu einem gewissen Grad standardisiert sind. (Im Folgenden finden Sie eine Liste, in der Sie solche Befehle unabhängig vom jeweiligen Gerät / Betriebssystem auflisten können.)

show running-config
show interfaces
show logging
show inventory
show modules
show tech-support

···Eine solche. Bei Netzwerkgeräten und Betriebssystemen wie Cisco IOS können Sie beispielsweise die Einstellungsinformationen und den Status überprüfen, indem Sie den obigen Befehl eingeben.

Besonders in einer sehr dringenden Situation, beispielsweise wenn ein Fehler auftritt Ich möchte Routinearbeiten mit so wenig menschlichem Eingreifen wie möglich durchführen, um Zeit für die Untersuchung aufzuwenden.

In diesem Artikel, um das Ergebnis des obigen Befehls schnell zu erhalten Ich werde die Geschichte der Implementierung eines Skripts in Python vorstellen, das sich automatisch am Gerät anmeldet, Befehle eingibt und Ausgaben abruft.

Betrieb und Automatisierung von Netzwerkgeräten

Im Allgemeinen glauben wir, dass Operationen für Netzwerkgeräte in drei Typen unterteilt werden können.

--Überprüfen Sie die Einstellungen Geben Sie Befehle ein, um den Gerätestatus und die Einstellungen zu überprüfen, z. B. den oben genannten Befehl show.

--Einstellungen ändern Geben Sie Befehle ein, um den Gerätestatus / die Einstellungen wie Konfigurationsmodus, Festschreiben und Schreiben zu ändern

Dieser Artikel befasst sich insbesondere mit der Überprüfung der Einstellungen.

Wie in dem im Referenzabschnitt eingeführten Artikel angegeben, Unter den Betriebsmethoden für Netzwerkgeräte erfolgt der Allzweckbetrieb über die CLI. Verkehrsfluss usw. kann durch SNMP erhalten werden, aber die Arten von Informationen sind begrenzt. APIs können implementiert werden, variieren jedoch von Hersteller zu Hersteller.

Alle Geräte basieren auf dem CLI-Betrieb, dh der Betrieb nach dem Verbinden mit ssh oder Telnet ist die Betriebsmethode für allgemeine Netzwerkgeräte.

Mit anderen Worten bedeutet die Automatisierung dieser Operationen Dies bedeutet, dass die folgenden Vorgänge, die normalerweise von Menschen an der CLI ausgeführt werden, vom Skript ausgeführt werden.

$ telnet 192.168.0.2
Trying 192.168.0.2...
Connected to 192.168.0.2 (192.168.0.2).
Escape character is '^]'.

User Access Verification

Username: root
Password: 

(hostname)#show run
...Ausgabe

(hostname)#

Implementierung

Ich werde den Inhalt des Skripts erklären.

Montageumgebung

Verwenden des pexpect-Moduls in Python3 Implementiert erwartungsgemäß eine Proxy-Operation für die CLI-Schnittstelle.

Login mit pexpect

Verwenden Sie zunächst pexpect.spawn (), um einen untergeordneten Prozess zu starten. Der untergeordnete Prozess wird hier als untergeordnet bezeichnet, und der Prozess wird danach für das untergeordnete Element fortgesetzt. Im Argument von spawn muss der zu startende Prozess in der Befehlsanweisung angegeben werden, und hier handelt es sich um Telnet.

Indem Sie den Dateideskriptor für die Protokolldatei in die Variable child.logfile_read einfügen, Sie können das Ausgabeziel des gestarteten untergeordneten Prozesses für eine Datei angeben. Alternativ können Sie dieser Variablen die Standardausgabe (sys.stdout) zuweisen und die Ausgabe auf der Konsole anzeigen.

def login(ipaddr, passwd):
    child = pexpect.spawn("telnet " + ipaddr)
    logname = "./log/" + "log_" + ipaddr + \
              "_" + datetime.now().strftime("%s") + ".log"
    wb = open(logname, 'wb')
    child.logfile_read = wb

Verarbeitung mit Expect, nicht beschränkt auf Pexpect,

1. sendline()Befehl senden von
2. expect()Warten auf die Ausgabe der erwarteten Zeichenfolge durch

Wird wiederholt. Im Fall von pexpect kann die zu wartende Zeichenfolge in der Liste angegeben werden, und hier wird sie gemäß der erwarteten Zeichenfolge wie folgt angegeben.

    expect_list = [u"#",
                   u">",
                   u"\nlogin: ",
                   u"Username: ",
                   u"Password: ",
                   u"Connection closed by foreign host.",
                   u"Login incorrect"]

Wenn Sie pexpect.spawn (Telnet [IP-Adresse]) ausführen, wird Telnet auf dem Gerät ausgeführt und das Gerät wartet auf die nächste Eingabe. Das heißt, wenn es manuell ausgeführt wird, ist der Status des Bildes wie folgt.

$ telnet 192.168.0.2
Trying 192.168.0.2...
Connected to 192.168.0.2 (192.168.0.2).
Escape character is '^]'.

User Access Verification
Username: [Cursor]

Führen Sie nun erwartungsgemäß wie unten gezeigt aus.

    index = child.expect(expect_list)

Zu diesem Zeitpunkt stimmt das im dritten Teil der Liste gespeicherte Element "Benutzername:" mit der letzten Zeile der Ausgabe des Geräts überein. Wenn eine Liste als erwartetes Argument angegeben wird, ist der Rückgabewert die Elementnummer der Liste. Daher wird "3" in der Variablen index gespeichert. Wenn keine übereinstimmende Zeichenfolge vorhanden ist, wartet Expect () weiterhin auf weitere Ausgaben vom Gerät. In diesem Fall endet die Verarbeitung erst nach Ablauf des Zeitlimits. Es ist jedoch auch möglich, die Fehlerverarbeitung zu implementieren, indem zu diesem Zeitpunkt auf das Zeitlimit gewartet wird.


In der aktuellen Implementierung wird die folgende Verarbeitung gemäß dem Indexwert durchgeführt.

Selbst wenn Sie sich erfolgreich anmelden, müssen Sie das Kennwort möglicherweise erneut eingeben, wenn das Gerät die Aktivierung erfordert. Da es eine Grenze gibt, die Verarbeitung für diese Geräte individuell zu beschreiben, ist die Implementierung bis dahin jetzt ruhig. Überprüfen Sie für alle Geräte und Betriebssysteme, die sich anmelden sollen, wie der Anmeldevorgang bei manuellem Betrieb abläuft. Es muss so gestaltet sein, dass Verzweigung und Verarbeitung normal ablaufen.

    while True:
        if index == 0:  # success to login.
            return child
        elif index == 1:  # need to promoted to enable mode.
            child.sendline("enable")
            index = child.expect(expect_list)
        elif index == 2 or index == 3:  # need to input "root".
            child.sendline("root")
            index = child.expect(expect_list)
        elif index == 4:  # need to input password.
            child.sendline(passwd)
            index = child.expect(expect_list)
        elif index == 5:  # Connection is closed.
            print("Unmatched password, or connection is closed.")
            return -1
        elif index == 6:  # incorrect password.
            print("\nFault: incorrect password.")
            return -1

In den bisherigen Beispielen enthält der Index 3 als Wert, sodass er in der dritten if-Anweisung als Zweig enthalten ist. Sendet die von sendline () angeforderte Zeichenfolge als Benutzernamen. (root ist ein Beispiel) Zu diesem Zeitpunkt erfolgt die Ausgabe des Geräts manuell wie folgt.

Username: root
Password: [Cursor]

Dies stimmt mit dem in erwartungsliste gespeicherten "Passwort:" überein, und die while-Schleife geht weiter. Ebenso wird das Kennwort in das Gerät eingegeben, und wenn die Authentifizierung erfolgreich ist, ist die Anmeldung abgeschlossen.

Hier ist die Anmeldung abgeschlossen, wenn "#" empfangen wird. Dies setzt voraus, dass Sie sich wie unten gezeigt im privilegierten Modus anmelden. Es besteht jedoch Verbesserungsbedarf, da dies je nach Betriebssystem zu Fehlfunktionen führen kann.

Username: root
Password: 

(hostname)#

Befehlsausführung mit pexpect

Wenn die Anmeldung abgeschlossen ist, wartet das Gerät auf den nächsten Befehl. Dieses Mal habe ich unter der Annahme der Befehlseingabe vom Typ Bestätigung (show) die folgende Funktion erstellt. Befehle ist eine Liste, und es wird angenommen, dass Befehle wie "show interfaces" als Zeichenfolge für jedes Element gespeichert werden. Insbesondere wird hier keine Fehlerbehandlung implementiert.

def exec_command(commands, child):
    expect_list = u"#"
    for c in commands:
        child.sendline(c)
        child.expect(expect_list)

Wenn Sie einen Befehl zum Ändern von Einstellungen eingeben möchten, müssen Sie die Einstellungen im Voraus überprüfen und feststellen, ob er sich in einem Zustand befindet, der für die Eingabe des Befehls geeignet ist, den Sie einstellen möchten. Und auch nach der Eingabe muss überprüft werden, ob die Einstellungen sicher wiedergegeben werden und ob andere seltsame Protokolle vorhanden sind. Die bisher beschriebene Implementierung im String-Standby erfordert viel Geduld.

Einige der Aufgaben, die vollständig stilisiert wurden, werden implementiert, da die Ausgabe erwartet werden kann. Auf der anderen Seite möchte ich, da es sich um ein Skript handelt, das den Inhalt festlegt, der der tatsächlichen Arbeit sehr nahe kommt, davon Abstand nehmen, ihn hier einzuführen.

Übrigens, für "child.logfile_read" festgelegt, als der untergeordnete Prozess gestartet wurde, Alle Ausgaben der Befehle, die bisher vom Login ausgeführt wurden, werden geschrieben. Diesmal handelt es sich um eine Demo-Implementierung, aber nachdem Sie das Kennwort in das Skript eingegeben haben, Wenn Sie festlegen, dass dieses Skript angezeigt wird, wenn Sie ein bestimmtes Syslog sehen, Beispielsweise ist es möglich, die Geräteeinstellungen und den Status unmittelbar nach der Ausgabe eines Modulfehlers abzurufen.

Bei einigen Befehlen müssen Wartungsinformationen im Gerät generiert und manuell über FTP usw. erfasst werden. Ich möchte eine weitere Gelegenheit nutzen, um diese Automatisierungen durchzuführen.

Für die Zukunft

Dieses Mal habe ich die Automatisierung des CLI-Betriebs mit pexpect eingeführt. Es ist ein ziemlich schlammiger Weg, aber andererseits gibt es keine Netzwerkgeräte, die nicht mit Telnet (?) Betrieben werden können Es ist auch eine Methode, die bei ordnungsgemäßem Design mit jedem Gerät verwendet werden kann.

Ich möchte über REST-APIs sprechen, die von bestimmten Herstellern wie Junipers PyEz bereitgestellt werden.

Vielen Dank.


Morgen ist ein Beitrag von @hitsumabushi.

Referenz

Recommended Posts

Versuchen Sie, den Betrieb von Netzwerkgeräten mit Python zu automatisieren
Versuchen Sie, das Mensch-Maschine-Diagramm mit Python zu lösen
Versuchen Sie, die Höhendaten des National Land Research Institute mit Python abzubilden
Versuchen Sie, das Programmier-Herausforderungsbuch mit Python3 zu lösen
Versuchen Sie, das Problem der Zuweisung von Schulungsärzten mit Python zu lösen
Versuchen Sie, den Inhalt von Word mit Golang zu erhalten
Holen Sie sich mit Python den Betriebsstatus von JR West
Ich habe versucht, die Entropie des Bildes mit Python zu finden
Versuchen Sie, COVID-19 Tokyo-Daten mit Python zu kratzen
Versuchen Sie, die Funktionsliste des Python> os-Pakets abzurufen
Versuchen Sie, Facebook mit Python zu betreiben
Ich habe versucht, das Artikel-Update des Livedoor-Blogs mit Python und Selen zu automatisieren.
Versuchen Sie, die verstümmelten Zeichen im angehängten Dateinamen mit Python zu entschlüsseln
Holen Sie sich die Quelle der Seite unbegrenzt mit Python zu laden.
Versuchen Sie, Merkmale von Sensordaten mit CNN zu extrahieren
Versuchen Sie, in die Datenbank zu importieren, indem Sie ShapeFile mit numerischen Informationen zum nationalen Land mit Python bearbeiten
Versuchen Sie, die Nährstoffe von Cornflakes zu visualisieren, die M-1-Champion Milkboy mit Python sagte
Erste Python ② Versuchen Sie, Code zu schreiben, während Sie die Funktionen von Python untersuchen
Versuchen Sie, das N Queen-Problem mit SA von PyQUBO zu lösen
Geben Sie den Inhalt von ~ .xlsx im Ordner mit Python in HTML aus
Von der Einführung von JUMAN ++ bis zur morphologischen Analyse von Japanisch mit Python
Ich habe versucht, die Effizienz der täglichen Arbeit mit Python zu verbessern
Versuchen Sie, den kürzesten Weg mit Python + NetworkX + Social Data zu lösen
PhytoMine-I hat versucht, mit Python die genetischen Informationen der Pflanze zu erhalten
Versuchen Sie, Farbfilme mit Python zu reproduzieren
Versuchen Sie, sich mit Python bei qiita anzumelden
Überprüfen Sie die Existenz der Datei mit Python
[Python] Probieren Sie pydash der Python-Version von lodash aus
Python Amateur versucht die Liste zusammenzufassen ①
Der Weg zum Kompilieren zu Python 3 mit Thrift
Versuchen Sie, die Position des Senders aus dem Funkwellenausbreitungsmodell mit Python [Wi-Fi, Beacon] zu berechnen.
Setzen Sie Cabocha 0.68 in Windows ein und versuchen Sie, die Abhängigkeit mit Python zu analysieren
Ich habe versucht, den Authentifizierungscode der Qiita-API mit Python abzurufen.
Versuchen Sie, nur den Kohlenstoff am Ende der Kette mit SMARTS zu reagieren
Ich habe versucht, die Standardrolle neuer Mitarbeiter mit Python zu optimieren
Ich habe versucht, die Filminformationen der TMDb-API mit Python abzurufen
Versuchen Sie, ein festgelegtes Problem der High-School-Mathematik mit Python zu lösen
[Einführung in Python] Wie wird mit der continue-Anweisung wiederholt?
Versuchen Sie, den Hintergrund und das sich bewegende Objekt des Videos mit OpenCV zu trennen
Versuchen Sie, das Fizzbuzz-Problem mit Keras zu lösen
Test von emacs-org parser orgparse für Python
Bereiten Sie die Ausführungsumgebung von Python3 mit Docker vor
Automatischer Betrieb von Chrome mit Python + Selen + Pandas
2016 Todai Mathematik mit Python gelöst
[Hinweis] Exportieren Sie das HTML der Site mit Python.
Der einfachste Weg, um Stimme mit Python zu synthetisieren
Versuchen Sie, mit Python eine Lebenskurve zu zeichnen
Berechnen Sie die Gesamtzahl der Kombinationen mit Python
Geben Sie die ausführbare Python-Datei an, die mit virtualenv verwendet werden soll
Überprüfen Sie das Datum der Flaggenpflicht mit Python
So testen Sie den Friends-of-Friends-Algorithmus mit pyfof
Begrüßen Sie die Welt mit Python mit IntelliJ
Versuchen Sie, in Python einen "Entschlüsselungs" -Code zu erstellen
Versuchen Sie, Python-Dokumente automatisch mit Sphinx zu generieren
Probieren Sie Progate Free Edition [Python I]
So legen Sie Attribute mit Mock of Python fest