[PYTHON] J'ai essayé de fonctionner à partir de Postman en utilisant Cisco Guest Shell comme serveur API

introduction

Cisco Guest Shell est un environnement de conteneur basé sur Linux séparé du périphérique hôte (IOS-XE), et les paramètres IOS-XE peuvent être automatiquement contrôlés à l'aide de Python ou similaire. Cette fois, j'ai construit un serveur API sur Guest Shell en utilisant le framework Web Python "Flask", j'ai obtenu le résultat de la commande show de Postman et j'ai changé les paramètres de l'interface.

Configuration du CSR1000V

IOS-XE L'interface virtuelle «VirtualPortGroup0» (192.168.30.1) est créée du côté IOS-XE et associée à l'adresse de l'invité Shell (192.168.30.2) pour permettre l'accès à l'invité Shell de l'extérieur. Je vais l'omettre car cela dépend de l'environnement, mais pour l'accès Internet, j'ai également configuré PAT pour convertir l'adresse de l'invité Shell en adresse Gigabit Ethernet1.

Config Config



Router(config)#iox

Router(config)#ip http server

Router(config)#interface GigabitEthernet1
Router(config-if)# ip address 192.168.100.196 255.255.255.0
Router(config-if)# exit

Router(config)#interface VirtualPortGroup0
Router(config-if)# ip address 192.168.30.1 255.255.255.0
Router(config-if)# exit

Router(config)#app-hosting appid guestshell
Router(config-app-hosting)# app-vnic gateway0 virtualportgroup 0 guest-interface 0
Router(config-app-hosting-gateway0)# guest-ipaddress 192.168.30.2 netmask 255.255.255.0
Router(config-app-hosting-gateway0)# app-default-gateway 192.168.30.1 guest-interface 0
Router(config-app-hosting)# name-server0 192.168.100.1
Router(config-app-hosting)# end

Router#guestshell enable

Commande de confirmation


Router#show iox-service

IOx Infrastructure Summary:
---------------------------
IOx service (CAF) 1.10.0.1 : Running
IOx service (HA)          : Not Supported
IOx service (IOxman)      : Running
IOx service (Sec storage) : Not Supported
Libvirtd   1.3.4          : Running

Router#show app-hosting list
App id                                   State
---------------------------------------------------------
guestshell                               RUNNING

Guest Shell Utilisez les paramètres par défaut tels quels.

Router#guestshell
[guestshell@guestshell ~]$ sudo ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.30.2  netmask 255.255.255.0  broadcast 192.168.30.255
(réduction)

[guestshell@guestshell ~]$ netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.30.1    0.0.0.0         UG        0 0          0 eth0
192.168.30.0    0.0.0.0         255.255.255.0   U         0 0          0 eth0

Installer des packages Python

J'ai utilisé le Python 2.7.5 préinstallé pour installer Flask et le modèle de l'analyseur de commandes show ntc_templates.

[guestshell@guestshell ~]$ python -V
Python 2.7.5
[guestshell@guestshell ~]$ pip -V
pip 20.2.3 from /usr/lib/python2.7/site-packages/pip (python 2.7)
[guestshell@guestshell ~]$ pip install flask
[guestshell@guestshell ~]$ pip install ntc_templates

Obtenez les résultats de la commande show avec HTTP GET

Code Python

J'ai créé api.py directement dans le répertoire personnel de Guest Shell.

[guestshell@guestshell ~]$ pwd
/home/guestshell
[guestshell@guestshell ~]$ touch api.py

Le déroulement général du traitement est le suivant.

De plus, pour accéder de l'extérieur, host = '0.0.0.0' est spécifié comme argument de ʻapp.run ()`.

api.py


from flask import Flask, jsonify, request
from cli import configurep, cli
from ntc_templates.parse import parse_output

app = Flask(__name__)

@app.route("/show/<command>", methods=["GET"])
def getCommand(command):
    cmd = "show " + command.replace("_", " ")
    try:
        sh_output = cli(cmd)
        sh_output_parsed = parse_output(platform="cisco_ios", command=cmd, data=sh_output)
        return jsonify(sh_output_parsed)
    except:
        return jsonify([{"result": "Fail to parse the output"}])

if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0', port=8080)

Exécution Python / démarrage du serveur API

[guestshell@guestshell ~]$ python api.py
 * Serving Flask app "api" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)

HTTP GET de Postman

Voici un exemple d'obtention du résultat de la commande show show ip interface brief de Postman. Entrez l'URI comme suit dans GET. Bien qu'il soit abrégé en ʻip_int_brief` à la fin, il peut être analysé sans aucun problème s'il s'agit d'une abréviation autorisée par les modèles NTC. 0927_01.png

Modifier les paramètres d'interface avec HTTP POST

Code Python

J'ai ajouté le code à api.py ci-dessus. Le déroulement général du traitement est le suivant.

--L'exécution est déclenchée par HTTP POST depuis le client API vers l'URI http: // <adresse IP du shell d'invité> / set / interface. Décrivez les paramètres de configuration de l'interface au format JSON dans le Body. --Exécute la fonction setInterface () --Générer la commande CLI en fonction des paramètres de réglage --Modifiez les paramètres et enregistrez les paramètres avec le module Cisco CLI Python

Après modification, exécutez Python / redémarrez le serveur API.

api.py(Ajouts)


@app.route("/set/interface", methods=["POST"])
def setInterface():
    interface_cmd = "interface " + request.json['interface']

    if 'state' in request.json:
        if request.json['state'] == "enabled":
            state_cmd = "no shutdown"
        elif request.json['state']  == "disabled":
            state_cmd = "shutdown"
    else:
            state_cmd = ""

    if 'description' in request.json:
        description_cmd = "description " + request.json['description']
    else:
        description_cmd = ""

    if 'address' in request.json:
        address_cmd = "ip address " + request.json['address'] + " " + request.json['netmask']
    else:
        address_cmd = ""

    configurep([interface_cmd, state_cmd, description_cmd, address_cmd, "end"])
    cli("write")

    return jsonify([{"result": "Success"}])

HTTP POST de Postman

Voici un exemple de définition de la description, d'adresse IP et d'ouverture d'un port à partir de Postman.

Entrez l'URI comme indiqué ci-dessous dans POST, et spécifiez Content-Type dans ʻapplication / json` dans Header. 0927_02.png

Décrivez les paramètres de réglage dans Body. Parmi les éléments suivants, le nom d'interface «interface» est requis, mais l'autre «état» ouvert / fermé, la description «description» et l'adresse IP «adresse / masque de réseau» sont facultatifs. 0927_03.png

Cliquez sur le bouton Envoyer et en cas de succès, le message suivant s'affiche. 0927_04.png

Vous pouvez également vérifier l'état des paramètres à partir de l'écran du terminal pendant l'exécution de api.py.

192.168.100.100 - - [27/Sep/2020 05:59:20] "POST /set/interface HTTP/1.1" 200 -
Line 1 SUCCESS: interface GigabitEthernet2
Line 2 SUCCESS: no shutdown
Line 3 SUCCESS: description TEST
Line 4 SUCCESS: ip address 10.1.1.1 255.255.255.0
Line 5 SUCCESS: end

Les paramètres ont été modifiés et enregistrés du côté IOS-XE sans aucun problème.

Router#sh conf | begin interface GigabitEthernet2
interface GigabitEthernet2
 description TEST
 ip address 10.1.1.1 255.255.255.0
 negotiation auto
 no mop enabled
 no mop sysid

finalement

À titre d'exemple simple, j'ai réussi à créer un serveur API avec Guest Shell. Cependant, Guest Shell peut exécuter des commandes d'affichage / modifier les paramètres de l'appareil sans authentification, il peut donc y avoir des problèmes du point de vue de la sécurité et de la gestion des traces. En outre, pour cette application, il peut être préférable de contrôler avec Off-Box en utilisant un outil externe tel qu'Ansible au lieu du format On-Box comme Guest Shell.

Recommended Posts

J'ai essayé de fonctionner à partir de Postman en utilisant Cisco Guest Shell comme serveur API
J'ai essayé d'obtenir rapidement des données d'AS / 400 en utilisant pypyodbc
J'ai essayé d'obtenir rapidement des données d'AS / 400 en utilisant pypyodbc Préparation 1
J'ai essayé d'utiliser l'API UnityCloudBuild de Python
Je souhaite utiliser DB en utilisant l'ORM de Django à partir d'une application externe
J'ai essayé d'obtenir une AMI en utilisant AWS Lambda
J'ai essayé de devenir un Ann Man en utilisant OpenCV
J'ai essayé de créer une API list.csv avec Python à partir de swagger.yaml
J'ai essayé de rechercher des vidéos à l'aide de l'API de données Youtube (débutant)
J'ai essayé d'obtenir diverses informations de l'API codeforces
J'ai essayé de sortir le journal d'accès au serveur en utilisant Node.js
J'ai essayé de créer l'API Quip
J'ai essayé d'analyser mon chanteur préféré (SHISHAMO) en utilisant l'API Spotify
J'ai touché l'API de Tesla
J'ai essayé d'envoyer du courrier depuis le serveur Sakura avec flask-mail
[Python] J'ai essayé d'obtenir diverses informations en utilisant l'API de données YouTube!
J'ai essayé d'utiliser l'API checkio
J'ai essayé d'extraire des caractères des sous-titres (OpenCV: API Google Cloud Vision)
[Python] [Excel] Exploiter des feuilles Excel à partir de Python en utilisant openpyxl (en utilisant une feuille de test comme exemple)
J'ai essayé de résumer diverses phrases à l'aide de l'API de synthèse automatique "summpy"
J'ai essayé d'utiliser Azure Speech to Text.
J'ai essayé d'utiliser l'API de données YOUTUBE V3
J'ai essayé de classer le texte en utilisant TensorFlow
J'ai essayé d'utiliser la recherche sélective comme R-CNN
J'ai essayé de toucher l'API COTOHA
J'ai créé une API Web
J'ai essayé d'utiliser Headless Chrome de Selenium
J'ai essayé d'utiliser l'API BigQuery Storage
J'ai essayé de comprendre attentivement la machine vectorielle de support (Partie 1: J'ai essayé le noyau polynomial / RBF en utilisant MakeMoons comme exemple).
J'ai essayé d'expliquer l'analyse de régression multiple aussi facilement que possible à l'aide d'exemples concrets.
J'ai essayé d'extraire le dessin au trait de l'image avec Deep Learning
[Python] J'ai essayé d'obtenir le nom du type sous forme de chaîne de caractères à partir de la fonction type
J'ai essayé de créer un environnement à vérifier régulièrement en utilisant Selenium avec AWS Fargate
J'ai essayé d'exécuter du code Python à partir de .Net en utilisant Pythonnet (édition Hallo World)
J'ai essayé d'utiliser l'API à distance avec GAE / J
J'ai essayé d'accéder à l'API Qiita depuis le début
J'ai essayé d'obtenir une image en grattant
Je souhaite envoyer un e-mail depuis Gmail en utilisant Python.
J'ai essayé d'utiliser l'API Google Cloud Vision
Essayez de créer un serveur HTTP en utilisant Node.js
J'ai essayé d'utiliser Firebase pour le serveur de cache de Django
J'ai essayé d'utiliser Linux avec Discord Bot
J'ai créé un jeu ○ ✕ avec TensorFlow
J'ai essayé de notifier la mise à jour de "Devenir romancier" en utilisant "IFTTT" et "Devenir un romancier API"
J'ai essayé de noter la syntaxe trop humoristique et humoristique en utilisant l'API COTOHA.
[Bouclier d'épée Pokémon] J'ai essayé de visualiser la base de jugement de l'apprentissage en profondeur en utilisant la classification des trois familles comme exemple
J'ai essayé de détecter l'iris à partir de l'image de la caméra
Notification PUSH de Python vers Android à l'aide de l'API de Google
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé d'approcher la fonction sin en utilisant le chainer
J'ai essayé APN (notification à distance) à l'aide de l'API REST Parse.com
J'ai essayé de découvrir notre obscurité avec l'API Chatwork
J'ai essayé d'utiliser l'API de Sakenowa Data Project
[Python] J'ai essayé d'exécuter un serveur local en utilisant flask
J'ai essayé d'utiliser PySpark de Jupyter 4.x sur EMR
J'ai essayé de lire les données d'un fichier en utilisant Node.js.