Essayez d'automatiser le fonctionnement des périphériques réseau avec Python

Cet article est l'article du 14ème jour du Calendrier de l'Avent NIFTY 2016. Hier, c'était @ntoofu's Manage Ansible configuration information with graph DB.

Bonjour. Dans mon travail quotidien, je construis, exploite et entretiens l'infrastructure réseau de Nifty Cloud. Cette fois, je voudrais écrire un peu sur l'automatisation du fonctionnement des appareils physiques dans le réseau, qui ne peut pas être vue du côté service de Nifty Cloud.

Par exemple, une telle situation

-Le redémarrage de l'appareil a été exécuté
-L'interface de l'appareil est tombée en panne
-Le module a échoué
-Quoi qu'il en soit, quelque chose ne va pas

Il arrive souvent que quelque chose comme ... se produise et que vous souhaitiez vérifier immédiatement l'état de l'appareil. Dans ces cas, connectez-vous à l'appareil (tant qu'il est toujours accessible) et Il est nécessaire d'appuyer rapidement sur les commandes show pour sécuriser les informations.

On peut dire que les commandes à ce moment-là sont normalisées dans une certaine mesure. (Ce qui suit est une liste que vous pouvez lister ces commandes quel que soit le périphérique / système d'exploitation spécifique)

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

···Tel. Par exemple, pour les périphériques réseau et les systèmes d'exploitation tels que Cisco IOS, vous pouvez vérifier les informations de configuration et l'état en entrant la commande ci-dessus.

Surtout dans une situation très urgente telle qu'une panne J'aimerais faire un travail de routine avec le moins d'intervention humaine possible afin de consacrer du temps à l'enquête.

Dans cet article, afin d'obtenir rapidement le résultat de la commande ci-dessus Je vais présenter l'histoire de l'implémentation d'un script en Python qui se connecte automatiquement à l'appareil, entre les commandes et acquiert la sortie.

Fonctionnement et automatisation des équipements réseau

En général, nous pensons que les opérations pour les périphériques réseau peuvent être divisées en trois types.

--Vérifier les paramètres Entrez des commandes pour vérifier l'état et les paramètres du périphérique, comme la commande show mentionnée ci-dessus.

--Modifier les paramètres Commandes d'entrée pour modifier l'état / les paramètres du périphérique tels que le mode de configuration, la validation et l'écriture

--Surveillance de l'état Surveillance du débit de trafic par SNMP, acquisition de Syslog

En particulier, cet article se concentre sur la vérification des paramètres.

Comme indiqué dans l'article introduit dans la section de référence, Parmi les méthodes de fonctionnement pour les périphériques réseau, le fonctionnement général est par CLI. Le flux de trafic, etc. peut être obtenu par SNMP, mais les types d'informations sont limités. Des API peuvent être implémentées, mais elles varient d'un fabricant à l'autre.

Tous les périphériques sont basés sur le fonctionnement de la CLI, c'est-à-dire que le fonctionnement après la connexion avec ssh ou telnet est la méthode de fonctionnement des périphériques réseau à usage général.

En d'autres termes, automatiser ces opérations signifie Cela signifie que les opérations suivantes que les humains exécutent normalement sur l'interface de ligne de commande sont exécutées par le script.

$ 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
...production

(hostname)#

la mise en oeuvre

Je vais expliquer le contenu du script.

Environnement de montage

Utilisation du module pexpect en Python3 Implémente une opération de proxy pour l'interface CLI par expect.

connectez-vous avec pexpect

Tout d'abord, utilisez pexpect.spawn () pour lancer un processus enfant. Le processus enfant est nommé ici enfant et le processus se poursuit par la suite pour l'enfant. Dans l'argument de spawn, il est nécessaire de spécifier le processus à démarrer dans l'instruction de commande, et ici c'est telnet.

En plaçant le descripteur de fichier du fichier journal dans la variable child.logfile_read, Vous pouvez spécifier la destination de sortie du processus enfant lancé dans un fichier. Vous pouvez également affecter la sortie standard (sys.stdout) à cette variable et voir la sortie sur la console.

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

Traitement utilisant expect, non limité à pexpect,

1. sendline()Envoyer la commande par
2. expect()En attente de la sortie de la chaîne de caractères attendue par

Sera répété. Dans le cas de pexpect, la chaîne de caractères à attendre peut être spécifiée dans la liste, et ici elle est spécifiée comme suit en fonction de la chaîne de caractères attendue.

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

Lorsque vous exécutez pexpect.spawn (telnet [adresseip]), telnet est en cours d'exécution sur le périphérique et le périphérique attend l'entrée suivante. Autrement dit, lorsqu'il est exécuté manuellement, l'état de l'image est le suivant.

$ 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]

Maintenant, exécutez expect comme indiqué ci-dessous.

    index = child.expect(expect_list)

A ce moment, l'élément "Username:" stocké dans le troisième de la liste correspond à la dernière ligne de la sortie de l'appareil. Si une liste est spécifiée comme argument dans expect, la valeur de retour sera le numéro d'élément de la liste. Par conséquent, "3" est stocké dans la variable appelée index. S'il n'y a pas de chaîne correspondante, expect () continuera d'attendre plus de sortie du périphérique. Dans ce cas, le traitement ne se termine pas jusqu'à ce qu'il expire, mais il est également possible de mettre en œuvre le traitement des erreurs en attendant le délai à ce moment.


Dans l'implémentation actuelle, le traitement suivant est effectué en fonction de la valeur d'index. Selon l'appareil et le système d'exploitation, votre nom d'utilisateur peut vous être demandé ou votre mot de passe peut vous être demandé soudainement. Même si vous vous connectez avec succès, vous devrez peut-être saisir à nouveau le mot de passe si le périphérique vous demande d'exécuter enable. Puisqu'il y a une limite à la description du traitement individuellement pour ces appareils, la mise en œuvre par while est maintenant calme. Pour tous les appareils et systèmes d'exploitation censés se connecter, vérifiez le déroulement du processus de connexion en cas d'opération manuelle. Il doit être conçu de manière à ce que le branchement et le traitement se déroulent normalement.

    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

Dans les exemples jusqu'à présent, index contient 3 comme valeur, il sera donc dans la troisième instruction if en tant que branche. Envoie la chaîne demandée par sendline () comme nom d'utilisateur. (la racine est un exemple) À ce stade, la sortie de l'appareil est manuellement comme suit.

Username: root
Password: [Cursor]

Cela correspond au "Mot de passe:" stocké dans expect_list, et la boucle while va plus loin. De même, le mot de passe est entré dans l'appareil et si l'authentification réussit, la connexion est terminée.

Ici, la connexion est terminée lorsque "#" est reçu. Cela suppose une connexion en mode privilégié comme indiqué ci-dessous, mais il y a place à amélioration car cela peut mal fonctionner selon le système d'exploitation.

Username: root
Password: 

(hostname)#

Exécution de commande à l'aide de pexpect

Lorsque la connexion est terminée, l'appareil écoute la commande suivante. Cette fois, en supposant l'entrée de commande de type confirmation (show), j'ai créé la fonction suivante. commandes est une liste, et on suppose que les commandes telles que "show interfaces" sont stockées sous forme de chaîne de caractères pour chaque élément. En particulier, la gestion des erreurs n'est pas implémentée ici.

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

Si vous souhaitez entrer une commande de changement de paramètre, vous devez vérifier les paramètres à l'avance et déterminer s'il se trouve dans un état approprié pour entrer la commande que vous êtes sur le point de définir. Et même après la saisie, il est nécessaire de vérifier si les paramètres sont reflétés en toute sécurité et s'il existe d'autres journaux étranges. Les implémenter en mode veille de chaîne comme décrit jusqu'à présent nécessite beaucoup de patience.

Certaines des tâches qui ont été complètement stylisées sont implémentées parce que la sortie peut être attendue. D'un autre côté, puisqu'il s'agit d'un script qui place le contenu assez près du travail réel, je voudrais m'abstenir de le présenter ici.

À propos, pour "child.logfile_read" défini au démarrage du processus enfant, Toute la sortie des commandes exécutées jusqu'à la connexion est écrite. Cette fois, il s'agit d'une implémentation de démonstration, mais après avoir saisi le mot de passe dans le script, Si vous le définissez pour lancer ce script lorsque vous voyez un Syslog particulier, Par exemple, il est possible d'acquérir les paramètres et l'état de l'appareil immédiatement après l'émission d'une erreur de module.

Certaines commandes nécessitent que des informations de maintenance soient générées à l'intérieur de l'appareil et acquises manuellement par FTP, etc. Je voudrais saisir une autre occasion pour faire ces automatisations.

Pour le futur

Cette fois, j'ai introduit l'automatisation des opérations CLI à l'aide de pexpect. C'est une manière assez boueuse, mais d'un autre côté, il n'y a pas de périphériques réseau qui ne peuvent pas être exploités avec telnet (?), Donc C'est également une méthode qui peut être utilisée avec n'importe quel appareil si elle est correctement conçue.

Je voudrais parler des API REST fournies par des fabricants spécifiques tels que PyEz de Juniper.

Merci beaucoup.


Demain est un message de @hitsumabushi.

référence

Recommended Posts

Essayez d'automatiser le fonctionnement des périphériques réseau avec Python
Essayez de résoudre le diagramme homme-machine avec Python
Essayez d'imaginer les données d'élévation du National Land Research Institute avec Python
Essayez de résoudre le livre des défis de programmation avec python3
Essayez de résoudre le problème d'affectation du médecin de formation avec Python
Essayez d'obtenir le contenu de Word avec Golang
Obtenez l'état de fonctionnement de JR West avec Python
J'ai essayé de trouver l'entropie de l'image avec python
Essayez de gratter les données COVID-19 Tokyo avec Python
Essayez d'obtenir la liste des fonctions du paquet Python> os
Essayez d'exploiter Facebook avec Python
J'ai essayé d'automatiser la mise à jour de l'article du blog Livedoor avec Python et sélénium.
Essayez de déchiffrer les caractères déformés dans le nom du fichier joint avec Python
Récupérez la source de la page à charger indéfiniment avec python.
Essayez d'extraire les caractéristiques des données de capteur avec CNN
Essayez d'importer dans la base de données en manipulant ShapeFile d'informations numériques sur les terres nationales avec Python
Essayez de visualiser les nutriments des flocons de maïs que le champion de M-1 Milkboy a dit avec Python
Premier python ② Essayez d'écrire du code tout en examinant les fonctionnalités de python
Essayez de résoudre le problème N Queen avec SA de PyQUBO
Exportez le contenu de ~ .xlsx dans le dossier en HTML avec Python
De l'introduction de JUMAN ++ à l'analyse morphologique du japonais avec Python
J'ai essayé d'améliorer l'efficacité du travail quotidien avec Python
Essayez de résoudre l'itinéraire le plus court avec les données sociales Python + NetworkX +
PhytoMine-I a essayé d'obtenir les informations génétiques de la plante avec Python
Essayez de reproduire un film couleur avec Python
Essayez de vous connecter à qiita avec Python
Vérifier l'existence du fichier avec python
[Python] Essayez pydash de la version Python de lodash
Python amateur tente de résumer la liste ①
La route de la compilation vers Python 3 avec Thrift
Essayez de calculer la position de l'émetteur à partir du modèle de propagation des ondes radio avec python [Wi-Fi, Beacon]
Mettez Cabocha 0.68 dans Windows et essayez d'analyser la dépendance avec Python
J'ai essayé d'obtenir le code d'authentification de l'API Qiita avec Python.
Essayez de ne faire réagir que le carbone en bout de chaîne avec SMARTS
J'ai essayé de rationaliser le rôle standard des nouveaux employés avec Python
J'ai essayé d'obtenir les informations sur le film de l'API TMDb avec Python
Essayez de résoudre un problème défini de mathématiques au lycée avec Python
[Introduction à Python] Quelle est la méthode de répétition avec l'instruction continue?
Essayez de séparer l'arrière-plan et l'objet en mouvement de la vidéo avec OpenCV
Essayez de résoudre le problème du fizzbuzz avec Keras
Essai du parseur d'emacs-org orgparse pour python
Préparer l'environnement d'exécution de Python3 avec Docker
Fonctionnement automatique de Chrome avec Python + Sélénium + pandas
Mathématiques Todai 2016 résolues avec Python
[Note] Exportez le html du site avec python.
Le moyen le plus simple de synthétiser la voix avec python
Essayez de dessiner une courbe de vie avec python
Calculez le nombre total de combinaisons avec python
Spécifiez le fichier exécutable Python à utiliser avec virtualenv
Vérifiez la date du devoir de drapeau avec Python
Comment essayer l'algorithme des amis d'amis avec pyfof
Dites bonjour au monde avec Python avec IntelliJ
Essayez de créer un code de "décryptage" en Python
Essayez de générer automatiquement des documents Python avec Sphinx
Essayez Progate Free Edition [Python I]
Comment spécifier des attributs avec Mock of Python