Récemment, mon article parle de pyATS
Une bibliothèque Python pour la vérification développée par Cisco. Veuillez casser les détails ... Pour plus de détails ↓ Document officiel Mon article d'introduction Quelque chose a parlé dans Qiita récent, en particulier dans le domaine de l'automatisation (je pense)
Ce que j'ai créé, c'est que la configuration préparée est correctement entrée dans le périphérique cible, Le résultat d'entrée est affiché comme une différence dans show running-config, et la sortie structurée acquise par genie learn est Diffed pour afficher la différence d'une manière facile à comprendre. Cette fois, il est conçu pour revenir à la configuration avant le démarrage.
├── check_acl.py ← corps du script
├── testbed
│ └── devnet_always.yml ← banc d'essai
└── vars
├── csr1000v-1.yml ← Vars of Node décrit dans testbed
├── iosxr1.yml
└── sbx-n9kv-ao.yml
testbed Un fichier contenant des informations sur la destination de la connexion, cette fois préparez les éléments suivants À propos, cette explication est article précédent, donc veuillez l'omettre.
devnet_always.yml
---
testbed:
name: SandBox
devices:
sbx-n9kv-ao:
alias: uut
credentials:
default:
username: admin
password: Admin_1234!
connections:
vty:
protocol: ssh
ip: sbx-nxos-mgmt.cisco.com
port: 8181
os: nxos
type: nxos
iosxr1:
alias: rt
credentials:
default:
username: admin
password: C1sco12345
connections:
vty:
protocol: ssh
ip: sbx-iosxr-mgmt.cisco.com
port: 8181
os: iosxr
type: iosxr
csr1000v-1:
alias: xe1
credentials:
default:
username: developer
password: C1sco12345
connections:
vty:
protocol: ssh
ip: ios-xe-mgmt-latest.cisco.com
port: 8181
os: iosxe
type: iosxe
csr1000v:
alias: xe0
credentials:
default:
username: developer
password: C1sco12345
connections:
vty:
protocol: ssh
ip: ios-xe-mgmt.cisco.com
port: 8181
os: iosxe
type: iosxe
Pour expliquer le contenu, «command» est la configuration requise pour entrer les paramètres, et «clear» est la configuration requise pour renvoyer les paramètres.
Ajout de StaticRoute et ACL à csr1000v-1 de IOSXE
csr1000v-1.yml
---
command: |
ip route 8.8.8.8 255.255.255.255 GigabitEthernet1 10.10.20.254
ip access-list extended TEST
permit ip any 8.8.8.8 0.0.0.0 log
remark ****TEST****
clear: |
no ip route 8.8.8.8 255.255.255.255 GigabitEthernet1 10.10.20.254
no ip access-list extended TEST
IOSXR iosxr1 ne prépare que les fichiers et le contenu est vide.
iosxr1.yml
---
command: |
clear: |
Le Vars de csr1000v dans Testbed n'est pas préparé. Ensuite, je présenterai mon propre Script, il est écrit en Python. Moche, cool! S'il vous plaît laissez-moi savoir si vous pensez que, car je ne l'utilise pas pour les affaires, mais je l'utilise à des fins de vérification Cela peut sembler un code de merde pour les programmeurs croquants, mais pardonnez-moi s'il vous plaît. Script
check_acl.py
import logging
import yaml
#Importer le module Genie
from genie.conf import Genie
from genie.utils.diff import Diff
class setupDevices(object):
def __init__(self):
#Pour stocker l'appareil
self.listDevice = list()
#running-Pour stocker la configuration
self.beforeConfig = list()
self.afterConfig = list()
#Stocke uniquement les appareils avec des fichiers vars
self.targetDevice = list()
self.config = dict()
#Pour le stockage de routage
self.beforeRouting = list()
self.afterRouting = list()
#Pour stocker ACL
self.beforeAcl = list()
self.afterAcl = list()
#Initialiser le banc d'essai
try:
self.testbed = Genie.init('testbed/devnet_always.yml')
if self.testbed :
logging.info('testbed init:OK')
for keys in self.testbed.devices:
self.listDevice.append(keys)
except TypeError:
logging.warning("Le fichier testbed est incorrect")
#Vérifiez s'il existe un fichier Var
for device in self.listDevice:
try:
with open('vars/{}.yml'.format(device), 'r') as yml:
device_config = { device + "_config" :yaml.safe_load(yml)}
self.config.update(device_config)
self.targetDevice.append(device)
except FileNotFoundError:
logging.warning("{}Fichier non".format(device))
continue
#Entrez le processus de connexion
self.login()
#S'identifier
def login(self):
logging.info("*"*32 + "S'identifier" + "*"*32)
for device in self.targetDevice:
self.testbed.devices[device].connect(log_stdout=False)
if self.testbed.devices[device].is_connected():
logging.info("{}: connected".format(device))
else:
logging.info("{}: disconnected".format(device))
#Acquisition pré-log
def getBeforeAcl(self):
logging.info("*"*32 + "Confirmation pré-ACL" + "*"*32)
for device in self.targetDevice:
self.beforeAcl.append(self.testbed.devices[device].learn('acl'))
logging.info("{}: beforeAcl get".format(device))
def getBeforeConfig(self):
logging.info("*"*32 + "Acquisition pré-log"+ "*"*32)
for device in self.targetDevice:
self.beforeConfig.append(self.testbed.devices[device].learn('config'))
logging.info("{}: beforeConfig get".format(device))
def getBeforeRoute(self):
logging.info("*"*32 + "Confirmation préalable du tableau de routage" + "*"*32)
for device in self.targetDevice:
self.beforeRouting.append(self.testbed.devices[device].learn('routing'))
logging.info("{}: beforeRouting get".format(device))
#Entrée de configuration
def inputConfig(self):
logging.info("*"*32 + "Entrée de configuration" + "*"*32)
for device in self.targetDevice:
self.testbed.devices[device].configure(self.config[device+"_config"]['command'])
logging.info("{}: input_config".format(device))
#Supprimer la configuration d'entrée
def claerConfig(self):
logging.info("*"*32 + "Config retour" + "*"*32)
for device in self.targetDevice:
self.testbed.devices[device].configure(self.config[device+"_config"]['clear'])
logging.info("{}: clear_config".format(device))
#Acquisition post-journal
def getAfterConfig(self):
logging.info("*"*32 + "Acquisition post-log" + "*"*32)
for device in self.targetDevice:
self.afterConfig.append(self.testbed.devices[device].learn('config'))
logging.info("{}: afterConfig get".format(device))
def getAfterAcl(self):
logging.info("*"*32 + "Confirmation post-ACL" + "*"*32)
for device in self.targetDevice:
self.afterAcl.append(self.testbed.devices[device].learn('acl'))
logging.info("{}: afterAcl get".format(device))
def getAfterRoute(self):
logging.info("*"*32 + "Confirmation ultérieure du tableau de routage" + "*"*32)
for device in self.targetDevice:
self.afterRouting.append(self.testbed.devices[device].learn('routing'))
logging.info("{}: afterRouting get".format(device))
#Se déconnecter
def logout(self):
logging.info("*"*32 + "Se déconnecter" + "*"*32)
for device in self.targetDevice:
self.testbed.devices[device].disconnect()
if self.testbed.devices[device].is_connected():
logging.info("{}: connected".format(device))
else:
logging.info("{}: disconnected".format(device))
#Diff Config
def diffConfig(self):
logging.info("*"*32 + "Diff" + "*"*32)
if self.beforeConfig and self.afterConfig:
for config_b,config_a,device in zip(self.beforeConfig,self.afterConfig,self.self.targetDevice):
config_diff = Diff(config_b,config_a)
config_diff.findDiff()
print("\n====={}_ConfigDiff=====".format(device))
print(config_diff)
if self.beforeRouting and self.afterRouting:
for config_b,config_a,device in zip(self.beforeRouting,self.afterRouting,self.self.targetDevice):
config_diff = Diff(config_b,config_a)
config_diff.findDiff()
print("\n====={}_RouteDiff=====".format(device))
print(config_diff)
if self.beforeAcl and self.afterAcl:
for config_b,config_a,device in zip(self.beforeAcl,self.afterAcl,self.self.targetDevice):
config_diff = Diff(config_b,config_a)
config_diff.findDiff()
print("\n====={}_AclDiff=====".format(device))
print(config_diff)
if __name__ == "__main__":
#Changer le niveau de journal en info
logging.basicConfig(level=logging.INFO)
logging.info("*"*32 + "Commencer le traitement" + "*"*32)
devnet = setupDevices()
devnet.getBeforeConfig()
devnet.getBeforeRoute()
devnet.getBeforeAcl()
devnet.inputConfig()
devnet.getAfterConfig()
devnet.getAfterRoute()
devnet.getAfterAcl()
devnet.claerConfig()
devnet.logout()
devnet.diffConfig()
logging.info("*"*32 + "Fin" + "*"*32)
Si vous collez tout cela en même temps, le journal sera ennuyeux, je vais donc l'expliquer en petits morceaux.
Exécutez le script avec python check_acl.py
.
Le fichier testbed est lu comme un processus au démarrage. Ensuite, lisez le fichier Device name + _config.yml dans le banc d'essai. À ce stade, si le fichier yaml cible n'existe pas, le message "Il n'y a pas de fichier XX" s'affiche.
(nw_automate) 00:26:33 my Script $python check_acl.py
INFO : ********************************Commencer le traitement********************************
INFO : testbed init:OK
WARNING : sbx-n9kv-pas de fichier ao
WARNING :Pas de fichier CSR1000v
Vient ensuite le processus de connexion.
Connectez-vous avec devices [device] .connect (log_stdout = False)
.
À ce stade, puisque log_stdout = False
est spécifié, le journal lors de la connexion n'est pas affiché.
INFO : ********************************S'identifier********************************
INFO : iosxr1: connected
INFO : csr1000v-1: connected
Après vous être connecté, vous obtiendrez divers pré-journaux. Après l'acquisition, divers pré-états seront stockés dans la liste.
Éléments que vous souhaitez vérifier | Ops qui peuvent être obtenus |
---|---|
RunningConfig | device['Nom de l'appareil'].learn('config') |
ACL | device['Nom de l'appareil'].learn('acl') |
Routing | device['Nom de l'appareil'].learn('routing') |
INFO : ********************************Acquisition pré-log********************************
INFO : iosxr1: beforeConfig get
INFO : csr1000v-1: beforeConfig get
INFO : ********************************Confirmation préalable du tableau de routage********************************
INFO : Could not learn <class 'genie.libs.parser.iosxr.show_routing.ShowRouteIpv6Distributor'> 'genie.libs.parser.iosxr.show_routing.ShowRouteIpDistributor'> 'genie.libs.parser.iosxr.show_routing.ShowRouteIpv6Distributor'>
INFO : iosxr1: beforeRouting get
INFO : Could not learn <class 'genie.libs.parser.iosxe.show_routing.ShowIpv6RouteDistributor'>
'genie.libs.parser.iosxe.show_routing.ShowIpRouteDistributor'> 'genie.libs.parser.iosxe.show_routing.ShowIpv6RouteDistributor'>
INFO : csr1000v-1: beforeRouting get
INFO : ********************************Confirmation pré-ACL********************************
INFO : Could not learn <class 'genie.libs.parser.iosxr.show_acl.ShowAclAfiAll'>
Parser Output is empty
INFO : Could not learn <class'genie.libs.parser.iosxr.show_acl.ShowAclEthernetServices'>
INFO : | Commands for learning feature 'Acl'
INFO : | - Commands with empty output
INFO : | cmd: <class 'genie.libs.parser.iosxr.show_acl.ShowAclAfiAll'>
INFO : | cmd: <class 'genie.libs.parser.iosxr.show_acl.ShowAclEthernetServices'>
INFO : iosxr1: beforeAcl get
INFO : | Commands for learning feature 'Acl'
INFO : | cmd: <class 'genie.libs.parser.iosxe.show_acl.ShowAccessLists'>
INFO : csr1000v-1: beforeAcl get
Ensuite, soumettez la configuration décrite dans «[commande]» du fichier Vars. Après la saisie, le post-journal sera le même que le journal pris à l'avance. (réduction···)
INFO : ********************************Entrée de configuration********************************
INFO : iosxr1: input_config
INFO : csr1000v-1: input_config
INFO : ********************************Acquisition post-log********************************
INFO : iosxr1: afterConfig get
INFO : csr1000v-1: afterConfig get
INFO : ********************************Confirmation ultérieure du tableau de routage********************************
Après avoir obtenu le post-log, Config est également restauré.
Retournez avec le contenu décrit dans clear
du fichier vars.
Après cela, déconnectez-vous. Après la déconnexion, l'état actuel de la connexion est vérifié et l'état est affiché.
INFO : ********************************Config retour********************************
INFO : iosxr1: clear_config
INFO : csr1000v-1: clear_config
INFO : ********************************Se déconnecter********************************
INFO : iosxr1: disconnected
INFO : csr1000v-1: disconnected
Enfin, différez les fichiers pré-Confgi et post-Config obtenus. Il y a un signe + ou-au début de la phrase,
Par exemple, ConfigDiff d'iosxr1 affiche joliment la hiérarchie. N'est-ce pas beaucoup plus facile à comprendre que de simplement comparer des textes?
INFO : ********************************Diff********************************
=====iosxr1_ConfigDiff=====
+Wed Dec 18 16:57:14.949 UTC:
-Wed Dec 18 16:56:58.216 UTC:
router static:
address-family ipv4 unicast:
+ 8.8.8.8/32 10.10.20.254:
=====csr1000v-1_ConfigDiff=====
+Current configuration : 7620 bytes:
+ip route 8.8.8.8 255.255.255.255 GigabitEthernet1 10.10.20.254:
-Current configuration : 7557 bytes:
=====iosxr1_RouteDiff=====
info:
vrf:
default:
address_family:
ipv4:
routes:
+ 8.8.8.8/32:
+ active: True
+ metric: 0
+ next_hop:
+ next_hop_list:
+ 1:
+ index: 1
+ next_hop: 10.10.20.254
+ updated: 00:00:08
+ route: 8.8.8.8/32
+ route_preference: 1
+ source_protocol: static
+ source_protocol_codes: S
=====csr1000v-1_RouteDiff=====
info:
vrf:
default:
address_family:
ipv4:
routes:
+ 8.8.8.8/32:
+ active: True
+ metric: 0
+ next_hop:
+ next_hop_list:
+ 1:
+ index: 1
+ next_hop: 10.10.20.254
+ outgoing_interface: GigabitEthernet1
+ route: 8.8.8.8/32
+ route_preference: 1
+ source_protocol: static
+ source_protocol_codes: S
=====iosxr1_AclDiff=====
=====csr1000v-1_AclDiff=====
INFO : ********************************Fin********************************
Je suis désolé que l'article ait été difficile à lire car il ne s'agissait que de code. Cependant, comme vous pouvez le voir à partir des résultats de Diff, la confirmation a été facile.
J'ai écrit Python très dur, mais en fait je peux faire la même chose sans écrire de code. Je publierai une URL de référence. PyATS | Créez un test d'automatisation à grande vitesse à l'aide du Blitz de mouvement spécial caché de Genie [Vérifiez facilement les réseaux multifournisseurs avec pyATS / Genie et Robot Framework] (https://qiita.com/tahigash/items/ceb0809a4a9464c521b3)
Je n'ai pas écrit ce code à partir de zéro, mais j'ai réussi à collecter les informations sur le net et à les mettre en forme. Il existe de nombreux codes utiles sur Github appelés CiscoTestAutomation.
Tous les journaux effectués cette fois
(nw_automate) 00:26:33 my Script $python check_acl.py
INFO : ********************************Commencer le traitement********************************
INFO : testbed init:OK
WARNING : sbx-n9kv-pas de fichier ao
WARNING :Pas de fichier CSR1000v
INFO : ********************************S'identifier********************************
INFO : iosxr1: connected
INFO : csr1000v-1: connected
INFO : ********************************Acquisition pré-log********************************
INFO : iosxr1: beforeConfig get
INFO : csr1000v-1: beforeConfig get
INFO : ********************************Confirmation préalable du tableau de routage********************************
INFO : Could not learn <class 'genie.libs.parser.iosxr.show_routing.ShowRouteIpv6Distributor'>
Parser Output is empty
INFO : +====================================================================================================================================================+
INFO : | Commands for learning feature 'Routing' |
INFO : +====================================================================================================================================================+
INFO : | - Parsed commands |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxr.show_routing.ShowRouteIpDistributor'> |
INFO : |====================================================================================================================================================|
INFO : | - Commands with empty output |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxr.show_routing.ShowRouteIpv6Distributor'> |
INFO : |====================================================================================================================================================|
INFO : iosxr1: beforeRouting get
INFO : Could not learn <class 'genie.libs.parser.iosxe.show_routing.ShowIpv6RouteDistributor'>
Parser Output is empty
INFO : +====================================================================================================================================================+
INFO : | Commands for learning feature 'Routing' |
INFO : +====================================================================================================================================================+
INFO : | - Parsed commands |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxe.show_routing.ShowIpRouteDistributor'> |
INFO : |====================================================================================================================================================|
INFO : | - Commands with empty output |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxe.show_routing.ShowIpv6RouteDistributor'> |
INFO : |====================================================================================================================================================|
INFO : csr1000v-1: beforeRouting get
INFO : ********************************Confirmation pré-ACL********************************
INFO : Could not learn <class 'genie.libs.parser.iosxr.show_acl.ShowAclAfiAll'>
Parser Output is empty
INFO : Could not learn <class 'genie.libs.parser.iosxr.show_acl.ShowAclEthernetServices'>
Parser Output is empty
INFO : +====================================================================================================================================================+
INFO : | Commands for learning feature 'Acl' |
INFO : +====================================================================================================================================================+
INFO : | - Commands with empty output |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxr.show_acl.ShowAclAfiAll'> |
INFO : | cmd: <class 'genie.libs.parser.iosxr.show_acl.ShowAclEthernetServices'> |
INFO : |====================================================================================================================================================|
INFO : iosxr1: beforeAcl get
INFO : +====================================================================================================================================================+
INFO : | Commands for learning feature 'Acl' |
INFO : +====================================================================================================================================================+
INFO : | - Parsed commands |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxe.show_acl.ShowAccessLists'> |
INFO : |====================================================================================================================================================|
INFO : csr1000v-1: beforeAcl get
INFO : ********************************Entrée de configuration********************************
INFO : iosxr1: input_config
INFO : csr1000v-1: input_config
INFO : ********************************Acquisition post-log********************************
INFO : iosxr1: afterConfig get
INFO : csr1000v-1: afterConfig get
INFO : ********************************Confirmation ultérieure du tableau de routage********************************
INFO : Could not learn <class 'genie.libs.parser.iosxr.show_routing.ShowRouteIpv6Distributor'>
Parser Output is empty
INFO : +====================================================================================================================================================+
INFO : | Commands for learning feature 'Routing' |
INFO : +====================================================================================================================================================+
INFO : | - Parsed commands |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxr.show_routing.ShowRouteIpDistributor'> |
INFO : |====================================================================================================================================================|
INFO : | - Commands with empty output |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxr.show_routing.ShowRouteIpv6Distributor'> |
INFO : |====================================================================================================================================================|
INFO : iosxr1: afterRouting get
INFO : Could not learn <class 'genie.libs.parser.iosxe.show_routing.ShowIpv6RouteDistributor'>
Parser Output is empty
INFO : +====================================================================================================================================================+
INFO : | Commands for learning feature 'Routing' |
INFO : +====================================================================================================================================================+
INFO : | - Parsed commands |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxe.show_routing.ShowIpRouteDistributor'> |
INFO : |====================================================================================================================================================|
INFO : | - Commands with empty output |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxe.show_routing.ShowIpv6RouteDistributor'> |
INFO : |====================================================================================================================================================|
INFO : csr1000v-1: afterRouting get
INFO : ********************************Confirmation post-ACL********************************
INFO : Could not learn <class 'genie.libs.parser.iosxr.show_acl.ShowAclAfiAll'>
Parser Output is empty
INFO : Could not learn <class 'genie.libs.parser.iosxr.show_acl.ShowAclEthernetServices'>
Parser Output is empty
INFO : +====================================================================================================================================================+
INFO : | Commands for learning feature 'Acl' |
INFO : +====================================================================================================================================================+
INFO : | - Commands with empty output |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxr.show_acl.ShowAclAfiAll'> |
INFO : | cmd: <class 'genie.libs.parser.iosxr.show_acl.ShowAclEthernetServices'> |
INFO : |====================================================================================================================================================|
INFO : iosxr1: afterAcl get
INFO : +====================================================================================================================================================+
INFO : | Commands for learning feature 'Acl' |
INFO : +====================================================================================================================================================+
INFO : | - Parsed commands |
INFO : |----------------------------------------------------------------------------------------------------------------------------------------------------|
INFO : | cmd: <class 'genie.libs.parser.iosxe.show_acl.ShowAccessLists'> |
INFO : |====================================================================================================================================================|
INFO : csr1000v-1: afterAcl get
INFO : ********************************Config retour********************************
INFO : iosxr1: clear_config
INFO : csr1000v-1: clear_config
INFO : ********************************Se déconnecter********************************
INFO : iosxr1: disconnected
INFO : csr1000v-1: disconnected
INFO : ********************************Diff********************************
=====iosxr1_ConfigDiff=====
+Wed Dec 18 16:57:14.949 UTC:
-Wed Dec 18 16:56:58.216 UTC:
router static:
address-family ipv4 unicast:
+ 8.8.8.8/32 10.10.20.254:
=====csr1000v-1_ConfigDiff=====
+Current configuration : 7620 bytes:
+ip route 8.8.8.8 255.255.255.255 GigabitEthernet1 10.10.20.254:
-Current configuration : 7557 bytes:
=====iosxr1_RouteDiff=====
info:
vrf:
default:
address_family:
ipv4:
routes:
+ 8.8.8.8/32:
+ active: True
+ metric: 0
+ next_hop:
+ next_hop_list:
+ 1:
+ index: 1
+ next_hop: 10.10.20.254
+ updated: 00:00:08
+ route: 8.8.8.8/32
+ route_preference: 1
+ source_protocol: static
+ source_protocol_codes: S
=====csr1000v-1_RouteDiff=====
info:
vrf:
default:
address_family:
ipv4:
routes:
+ 8.8.8.8/32:
+ active: True
+ metric: 0
+ next_hop:
+ next_hop_list:
+ 1:
+ index: 1
+ next_hop: 10.10.20.254
+ outgoing_interface: GigabitEthernet1
+ route: 8.8.8.8/32
+ route_preference: 1
+ source_protocol: static
+ source_protocol_codes: S
=====iosxr1_AclDiff=====
=====csr1000v-1_AclDiff=====
INFO : ********************************Fin********************************
(nw_automate) 00:28:00 my Script $
Recommended Posts