[PYTHON] Essayez de configurer SSH (Exscript) du logiciel au routeur

Ceci est un article de 12/2 minutes de NetOpsCoding AdventCalender.

Cette fois, je vais essayer d'automatiser les paramètres du routeur, qui sera la porte du démon, tout en créant un logiciel d'automatisation de réseau.

En ce qui concerne ce qu'est la porte démon, à partir de 2015, certaines API ne sont pas fournies pour définir / contrôler les routeurs, et même si elles sont fournies, ce sont souvent des API spécifiques au fournisseur et il s'agit d'un environnement multifournisseur. Dans ce réseau, il est facile de mettre en œuvre un programme d'automatisation pour chaque modèle de routeur / OS.

Dans de telles circonstances, des spécifications pour les API standard de l'industrie telles que NETCONF / YANG / RESTCONF / Telemetry sont en cours d'élaboration. Cependant, à l'heure actuelle, des problèmes persistent lors de son utilisation dans un environnement multifournisseur, tels que ceux qui présentent des différences de fabricant dans le contenu de la description pouvant être défini, ceux qui ne fonctionnent qu'avec le dernier système d'exploitation et ceux qui prennent en charge des fonctions limitées. Je vais.

Par conséquent, cette fois, je vais implémenter le flux de saisie des paramètres du routeur à partir du logiciel à l'aide de SSH, qui est la méthode la plus polyvalente, sans utiliser du tout l'API fournie. En d'autres termes, le logiciel remplace la séquence dans laquelle l'opérateur réseau se connecte réellement au routeur à l'aide de SSH et entre les paramètres à l'aide de la CLI.

La méthode d'automatisation à l'aide des packages SSH et Telnet fournis pour chaque langage de programmation est beaucoup plus polyvalente que l'utilisation de NETCONF, etc. (tout ce qu'une personne peut définir comme CLI est OK). D'autre part, le logiciel doit analyser les résultats de sortie et les messages d'erreur des commandes d'affichage qui sont à l'origine confirmées visuellement par des humains. En particulier, cela n'est pas recommandé car des messages d'erreur inconnus peuvent apparaître ou le logiciel peut être modifié chaque fois que le résultat de l'affichage change en raison de la mise à niveau de la version du système d'exploitation du routeur, mais pour le moment, il n'est pas recommandé d'utiliser Telnet / SSH. Il y a de nombreux cas où il ne peut pas être défini, c'est donc une bonne idée de le retenir comme l'un des moyens.

Environnement d'exécution

Le package Exscript est utilisé pour acquérir et définir des informations par SSH vers le routeur. Expect est célèbre en tant que package SSH, mais Exscript prend en charge IOS, IOS-XR, JunOS, etc. en plus de Linux / Unix. Par conséquent, lors de la réception du résultat de sortie du routeur, c'est très pratique car il n'est pas nécessaire d'effectuer un traitement d'analyse dédié au routeur.

Cette fois, nous allons créer un programme de paramétrage SSH en utilisant le routeur JUNOS comme exemple, mais si SSH / Telnet peut être utilisé, il peut être défini dans le même flux avec des routeurs d'autres fabricants.

Préparation préalable

Assurez-vous que vous pouvez SSH dans le routeur à partir du serveur cible en utilisant votre compte d'utilisateur et votre mot de passe. Aucun paramètre spécial autre que SSH n'est requis.

Programme qui exécute la commande show

Tout d'abord, écrivons un programme qui exécute une commande qui affiche le contenu défini dans l'interface par connexion ssh au routeur.

show_junos.py


#! /usr/bin/env python
# -*- coding: utf-8 -*-

from Exscript.protocols import SSH2
from Exscript.Account import Account

username = 'user1'
password = 'pass1'
ipv4 = '192.168.0.1'

#Établir une session SSH
session = SSH2()
session.connect(ipv4)

#Connectez-vous au routeur
session.login(Account(name=username, password=password))

#Envoyez une commande au routeur et obtenez le résultat de sortie
print '='*40
print 'Step 1. run show command'
print '='*40
session.execute('show configuration interfaces xe-0/0/0 | no-more')
print session.response


#Déconnexion de la session SSH
if session:
    session.send('exit\r')
    session.close()
else:
    raise AttributeError('Cannot find a livied session')

Lorsque le programme est exécuté, le contenu défini dans l'interface du routeur JUNOS est émis.

$ python show_junos.py

========================================
Step 1. run show command
========================================
show configuration interfaces xe-0/0/0 | no-more
disable;

user1@router>

Ici, vous pouvez voir que seul "désactiver" est défini pour l'interface xe- / 0/0/0.

Programme pour saisir les paramètres d'interface

En concevant l'argument de la fonction "session.execute ()" du programme ci-dessus, les paramètres seront saisis dans le routeur.

Ici, enregistrez la configuration que vous souhaitez saisir à l'avance sous forme de fichier texte et chargez le fichier de configuration lorsque le programme est exécuté.

junos_config.txt


delete interfaces xe-0/0/0 disable
set interfaces xe-0/0/0 unit 0 family inet address 10.0.0.1/30

JUNOS propose plusieurs façons de charger la configuration dans le routeur.

  1. Comment configurer à l'aide de la commande set de la CLI du routeur
  2. Comment transférer et placer le fichier de configuration sur le routeur et le charger avec la commande load

Ici, en tant que méthode à usage général qui peut également être exécutée sur un routeur Cisco, etc., définie dans "1. Comment définir à l'aide de la commande set de la CLI du routeur".

Le programme créé est le suivant.

set_junos.py


#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from Exscript.protocols import SSH2
from Exscript.Account import Account

username = 'user1'
password = 'pass1'
ipv4 = '192.168.0.1'

session = SSH2()
session.connect(ipv4)
session.login(Account(name=username, password=password))


print '='*40
print 'Step 1. run show command'
print '='*40
session.execute('show configuration interfaces xe-0/0/0 | no-more')
print session.response


print '='*40
print 'Step 2. read config file'
print '='*40
config_filename = sys.argv[1]
with open(config_filename, 'r') as config_file :
    config_lines = config_file.readlines()
    print config_filename
    print config_lines


print '='*40
print 'Step 3. run configure command'
print '='*40
session.execute('configure')
for config_line in config_lines :
    session.execute(config_line)
    print session.response


print '='*40
print 'Step 4. commit check'
print '='*40
session.execute('show | compare')
print session.response
session.execute('commi check')
print session.response


print '='*40
print 'Step 5. commit'
print '='*40
print 'Do you commit? y/n'
choice = raw_input().lower()
if choice == 'y':
    session.execute('commit')
    print session.response
else:
    session.execute('rollback')
    print session.response
session.execute('exit')
print session.response


print '='*40
print 'Step 6. run show command(again)'
print '='*40
session.execute('show configuration interfaces xe-0/0/0 | no-more')
print session.response


if session:
    session.send('exit\r')
    session.close()
else:

Dans ce qui précède, pour faciliter le suivi du flux, je l'ai écrit sans me soucier des détails tels que la conception de l'affichage, la gestion des erreurs et la vérification de la valeur de retour du routeur. En fait, il est nécessaire d'écrire la gestion des erreurs, la gestion des délais, etc. en fonction de la chaîne de caractères renvoyée par le routeur. Au fur et à mesure que le nombre d'instructions de gestion des erreurs augmente, il devient difficile à voir, il est donc recommandé d'en faire une fonction au besoin.

Et voici le résultat de l'exécution du programme.

python set_junos.py junos_config.txt

========================================
Step 1. run show command
========================================
show configuration interfaces xe-0/0/0 | no-more
disable;

user1@router>
========================================
Step 2. read config file
========================================
junos_config.txt
['delete interfaces xe-0/0/0 disable\n', 'set interfaces xe-0/0/0 unit 0 family inet address 10.0.0.1/30\n']
========================================
Step 3. run configure command
========================================
delete interfaces xe-0/0/0 disable

[edit]
user1@router#

[edit]
user1@router#
set interfaces xe-0/0/0 unit 0 family inet address 10.0.0.1/30

[edit]
user1@router#

[edit]
user1@router#
========================================
Step 4. commit check
========================================
show | compare
[edit interfaces xe-0/0/0]
-   disable;
[edit interfaces xe-0/0/0]
+    unit 0 {
+        family inet {
+            address 10.0.0.1/30;
+        }
+    }

[edit]
user1@router#
commit check
configuration check succeeds

[edit]
user1@router#
========================================
Step 5. commit
========================================
Do you commit? y/n
y
commit
commit complete

[edit]
user1@router#
exit
Exiting configuration mode

user1@router>
========================================
Step 6. run show command(again)
========================================
show configuration interfaces xe-0/0/0 | no-more
unit 0 {
    family inet {
        address 10.0.0.1/30;
    }
}

user1@router>

De cette façon, vous pouvez écrire un programme pour configurer le routeur en utilisant SSH à partir du logiciel.

Ce n’est pas le but.

Comme mentionné au milieu, lors de la définition des paramètres dans le routeur, "traitement lorsque la configuration est incorrecte", "traitement lorsque le routeur renvoie une erreur", "traitement lorsque la session SSH ne peut pas être établie" Il est nécessaire de mettre en œuvre comme un programme.

De plus, cette fois, le programme est créé sur le principe que "les gens jugent" "confirment la commande show" et "s'il faut ou non exécuter la validation", mais du point de vue de l'automatisation,

Le programme lui-même
(1)Vérifiez le résultat de la commande show et de la sortie d'erreur
(2)Entrez la configuration
(3)Après avoir jugé qu'il n'y a pas de problème
(4)Valider et exécuter
(5)Vérifiez que les paramètres réseau sont comme prévu

Un processus est requis.

Si vous essayez d'implémenter le processus ci-dessus, vous devrez analyser la sortie avec la commande show, ce qui entraînera inévitablement un programme compliqué.

Afin de réduire la complexité de cette programmation, des mécanismes simples pour des logiciels tels que NETCONF et Telemetry sont en cours de préparation. Cependant, NETCONF et RESTCONF facilitent uniquement l'acquisition des paramètres et des informations sur le routeur, et les autres processus doivent encore être mis en œuvre par les développeurs eux-mêmes.Il existe donc encore des défis en matière d'automatisation. Je suis.

finalement

Il n'y a pas de fin aux problèmes, mais le flux de faire des choses qui bougent progressivement petit à petit par essais et erreurs et faire évoluer davantage le programme tout en réduisant notre propre travail est la tendance à l'automatisation de l'exploitation du réseau. Je sens que c'est un raccourci. Tout d'abord, faisons de notre mieux ensemble étape par étape car nous pouvons le faire nous-mêmes. Et si vous allez plus loin, vantez-vous-en sur les blogs et les événements de codage NetOps. Ce que vous êtes en difficulté, c'est que tout le monde est en difficulté. Nous nous réjouissons de votre fierté.

Recommended Posts

Essayez de configurer SSH (Exscript) du logiciel au routeur
Essayez de configurer NETCONF (ncclient) du logiciel au routeur
Paramètres pour spécifier les adresses IP autorisées pour la connexion SSH
[Postgresql] Connexion SSH au serveur de base de données externe à partir du client
Essayez d'introduire le thème sur Pelican
Connexion SSH de Windows à GCP
Essayez Cython dans les plus brefs délais
Le moyen le plus rapide d'essayer EfficientNet
Du «dessin» à «l'écriture» du diagramme de configuration: essayez de dessiner le diagramme de configuration AWS avec des diagrammes
La façon la plus simple d'essayer PyQtGraph
Essayez d'utiliser le framework web de Python Django (1) - De l'installation au démarrage du serveur
Essayez de faire face à la somme partielle
Comment faire fonctionner Linux depuis la console
Python amateur tente de résumer la liste ①
Comment accéder à la banque de données de l'extérieur
Essayez d'écrire du code à partir de 1 en utilisant le chainer du cadre d'apprentissage automatique (édition mnist)
Connexion SSH au serveur cible à partir de Windows en un clic sur un raccourci
Essayons le projet de génération de musique TensorFlow "Magenta" du réglage de l'environnement de développement à la génération de chansons.
Essayez de résoudre le problème du fizzbuzz avec Keras
Connectez-vous à un serveur distant avec SSH
Essayez d'ajouter la distorsion de l'objectif fisheye à l'image
Essayez de décomposer la procession du daimyo en Tucker
Essayez de résoudre le problème de l'héritage de classe Python
Paramètre pour afficher le journal de l'exécution de cron
Essayez de résoudre le diagramme homme-machine avec Python
Comment essayer l'algorithme des amis d'amis avec pyfof
Modifiez le point décimal de la journalisation de, à.
Comment faire fonctionner Linux depuis l'extérieur Procédure
POST des images depuis ESP32-CAM (MicroPython) vers le serveur
Comment mesurer la vitesse de la ligne depuis le terminal
De l'introduction de pyethapp à l'exécution du contrat
Essayez d'accéder à l'API YQL directement depuis Python 3
Essayez de simuler le mouvement du système solaire
Histoire de passer de Pipenv à la poésie
Essayez de publier sur Qiita pour la première fois
Essayez de créer une table d'enregistrement de bataille avec matplotlib à partir des données de "Schedule-kun"
Donnez les données de séquence de points de latitude et de longitude et essayez d'identifier la route à partir des données d'OpenStreetMap