Dans le cadre de la documentation associée à ce produit, nous nous efforçons d’utiliser un langage exempt de préjugés. Dans cet ensemble de documents, le langage exempt de discrimination renvoie à une langue qui exclut la discrimination en fonction de l’âge, des handicaps, du genre, de l’appartenance raciale de l’identité ethnique, de l’orientation sexuelle, de la situation socio-économique et de l’intersectionnalité. Des exceptions peuvent s’appliquer dans les documents si le langage est codé en dur dans les interfaces utilisateurs du produit logiciel, si le langage utilisé est basé sur la documentation RFP ou si le langage utilisé provient d’un produit tiers référencé. Découvrez comment Cisco utilise le langage inclusif.
Cisco a traduit ce document en traduction automatisée vérifiée par une personne dans le cadre d’un service mondial permettant à nos utilisateurs d’obtenir le contenu d’assistance dans leur propre langue. Il convient cependant de noter que même la meilleure traduction automatisée ne sera pas aussi précise que celle fournie par un traducteur professionnel.
Aucune exigence spécifique n'est associée à ce document.
Les informations contenues dans ce document sont basées sur les versions de matériel et de logiciel suivantes :
switch(config)# feature nxsdk
switch(config)# feature bash-shell
switch(config)# run bash
bash-4.2$ vi /isan/bin/nxsdk-app.py
Remarque : La meilleure pratique est de créer des fichiers Python dans le répertoire /isan/bin/. Les fichiers Python ont besoin d'autorisations d'exécution pour s'exécuter - ne placez pas les fichiers Python dans le répertoire /bootflash ou dans l'un de ses sous-répertoires.
Remarque : Il n'est pas nécessaire de créer et de modifier des fichiers Python via NX-OS. Le développeur peut créer l'application à l'aide de son environnement local et transférer les fichiers terminés vers le périphérique à l'aide d'un protocole de transfert de fichiers de son choix. Cependant, il peut être plus efficace pour le développeur de déboguer et de dépanner son script à l'aide des utilitaires NX-OS.
sdkThread, fonction
Remarque : À partir de NX-SDK v1.5.0, un troisième paramètre booléen peut être passé dans la méthode NxSdk.getSdkInst, qui active Exceptions avancées quand True et désactive Exceptions avancées quand False. Cette méthode est décrite ici .
Voici quelques-unes des méthodes couramment utilisées :
Remarque : Les formats de données R_JSON et R_XML ne fonctionnent que si la commande prend en charge la sortie dans ces formats. Dans NX-OS, vous pouvez vérifier si une commande prend en charge la sortie dans un format de données particulier en dirigeant la sortie vers le format de données demandé. Si la commande redirigée renvoie une sortie significative, ce format de données est pris en charge. Par exemple, si vous exécutez show mac address-table dynamic | json dans NX-OS renvoie une sortie JSON, alors le format de données R_JSON est également pris en charge dans NX-SDK.
Voici quelques méthodes facultatives qui peuvent être utiles :
N9K-C93180LC-EX# show Tra?
track Tracking information
Transceiver_DOM.py Returns all interfaces with DOM-capable transceivers inserted
Dans une application Python avec l'utilisation de NX-SDK, des commandes CLI personnalisées sont créées et définies dans la fonction sdkThread. Il existe deux types de commandes : Commandes Show et commandes Config.
Ces deux méthodes permettent respectivement de créer des commandes show et config :
Remarque : Cette commande est une sous-classe de cliP.newCliCmd("cmd_type", "cmd_name", "syntaxe") où cmd_type est CONF_CMD ou SHOW_CMD (selon le type de commande configuré), cmd_name est un nom unique pour la commande interne à l'application NX-SDK personnalisée, et la syntaxe décrit les mots clés et paramètres pouvant être utilisés dans la commande. Pour cette raison, la documentation de l'API pour cette commande peut être plus utile pour référence.
Remarque : Cette commande est une sous-classe de cliP.newCliCmd("cmd_type", "cmd_name", "syntaxe") où cmd_type est soit CONF_CMD soit SHOW_CMD (cela dépend du type de commande qui est configuré), cmd_name est un nom unique pour la commande interne à l'application NX-SDK personnalisée, et la syntaxe décrit les mots clés et paramètres qui peuvent être utilisés dans la commande. Pour cette raison, la documentation de l'API pour cette commande peut être plus utile pour référence.
Les deux types de commandes ont deux composants différents : Paramètres et mots-clés :
1. Les paramètres sont des valeurs utilisées pour modifier les résultats de la commande. Par exemple, dans la commande show ip route 192.168.1.0, il y a un mot clé route suivi d'un paramètre qui accepte une adresse IP, qui spécifie que seules les routes qui incluent l'adresse IP fournie doivent être affichées.
2. Les mots clés modifient les résultats de la commande par leur seule présence. Par exemple, dans la commande show mac address-table dynamic, il y a un mot clé dynamic, qui spécifie que seules les adresses MAC apprises dynamiquement doivent être affichées.
Les deux composants sont définis dans la syntaxe d'une commande NX-SDK lors de sa création. Il existe des méthodes pour l'objet NxCliCmd afin de modifier l'implémentation spécifique des deux composants.
Afin d'afficher des exemples de code de composants de commande couramment utilisés, consultez la section Exemples de commandes CLI personnalisées de ce document.
Une fois les commandes CLI personnalisées créées, un objet de la classe pyCmdHandler décrite plus loin dans ce document doit être créé et défini comme l'objet gestionnaire de rappel CLI pour l'objet NxCliParser. Ceci est démontré comme suit :
cmd_handler = pyCmdHandler()
cliP.setCmdHandler(cmd_handler)
Ensuite, l'objet NxCliParser doit être ajouté à l'arborescence de l'analyseur CLI de NX-OS afin que les commandes CLI personnalisées soient visibles par l'utilisateur. Pour ce faire, utilisez la commande cliP.addToParseTree(), où cliP est l'objet NxCliParser retourné par la méthode sdk.getCliParser().
sdkThread, fonction - Exemple
Voici un exemple d'une fonction sdkThread typique avec l'utilisation des fonctions expliquées précédemment. Cette fonction (entre autres dans une application Python NX-SDK personnalisée typique) utilise des variables globales, qui sont instanciées lors de l'exécution du script.
cliP = ""
sdk = ""
event_hdlr = ""
tmsg = ""
def sdkThread():
global cliP, sdk, event_hdlr, tmsg
sdk = nx_sdk_py.NxSdk.getSdkInst(len(sys.argv), sys.argv)
if not sdk:
return
sdk.setAppDesc("Returns all interfaces with DOM-capable transceivers inserted")
tmsg = sdk.getTracer()
tmsg.event("[{}] Started service".format(sdk.getAppName()))
cliP = sdk.getCliParser()
nxcmd = cliP.newShowCmd("show_port_bw_util_cmd", "port bw utilization [<port>]")
nxcmd.updateKeyword("port", "Port Information")
nxcmd.updateKeyword("bw", "Port Bandwidth Information")
nxcmd.updateKeyword("utilization", "Port BW utilization in (%)")
nxcmd.updateParam("<port>", "Optional Filter Port Ex) Ethernet1/1", nx_sdk_py.P_INTERFACE)
nxcmd1 = cliP.newConfigCmd("port_bw_threshold_cmd", "port bw threshold <threshold>")
nxcmd1.updateKeyword("threshold", "Port BW Threshold in (%)")
int_attr = nx_sdk_py.cli_param_type_integer_attr()
int_attr.min_val = 1;
int_attr.max_val = 100;
nxcmd1.updateParam("<threshold>", "Threshold Limit. Default 50%", nx_sdk_py.P_INTEGER, int_attr, len(int_attr))
mycmd = pyCmdHandler()
cliP.setCmdHandler(mycmd)
cliP.addToParseTree()
sdk.startEventLoop()
# If sdk.stopEventLoop() is called or application is removed from VSH...
tmsg.event("Service Quitting...!")
nx_sdk_py.NxSdk.__swig_destroy__(sdk)
La classe pyCmdHandler est héritée de la classe NxCmdHandler dans la bibliothèque nx_sdk_py. La méthode postCliCb(self, clicmd) définie dans la classe pyCmdHandler est appelée chaque fois que des commandes CLI proviennent d'une application NX-SDK. Ainsi, la méthode postCliCb(self, clicmd) est où vous définissez comment les commandes CLI personnalisées définies dans la fonction sdkThread se comportent sur le périphérique.
La fonction postCliCb(self, clicmd) renvoie une valeur booléenne. Si True est retourné, alors il est présumé que la commande a été exécutée avec succès. False doit être renvoyé si la commande ne s'est pas exécutée correctement pour une raison quelconque.
Le paramètre clicmd utilise le nom unique qui a été défini pour la commande lors de sa création dans la fonction sdkThread. Par exemple, si vous créez une nouvelle commande show avec un nom unique show_xcvr_dom, alors il est recommandé de faire référence à cette commande par le même nom dans la fonction postCliCb(self, clicmd) après avoir vérifié si le nom de l'argument clicmd contient show_xcvr_dom. Il est démontré ici :
def sdkThread():
<snip>
sh_xcvr_dom = cliP.newShowCmd("show_xcvr_dom", "dom")
sh_xcvr_dom.updateKeyword("dom", "Show all interfaces with transceivers that are DOM-capable")
</snip>
class pyCmdHandler(nx_sdk_py.NxCmdHandler):
def postCliCb(self, clicmd):
if "show_xcvr_dom" in clicmd.getCmdName():
get_dom_capable_interfaces()
Si une commande qui utilise des paramètres est créée, alors vous devrez très probablement utiliser ces paramètres à un moment donné dans la fonction postCliCb(self, clicmd). Cela peut être fait avec la méthode clicmd.getParamValue("<paramètre>"), où <paramètre> est le nom du paramètre de commande dont vous souhaitez obtenir la valeur entre crochets angulaires (<>). Cette méthode est décrite ici. Cependant, la valeur retournée par cette fonction doit être convertie au type dont vous avez besoin. Pour ce faire, utilisez les méthodes suivantes :
La fonction postCliCb(self, clicmd) (ou toute fonction ultérieure) sera également typiquement l'emplacement où la sortie de la commande show est imprimée sur la console. Pour ce faire, utilisez la méthode clicmd.printConsole().
Remarque : Si l'application rencontre une erreur, une exception non gérée, ou s'arrête soudainement, alors le résultat de la fonction clicmd.printConsole() ne sera pas affiché du tout. Pour cette raison, la meilleure pratique quand vous déboguez votre application Python est soit de consigner les messages de débogage dans le syslog avec l'utilisation d'un objet NxTrace retourné par la méthode sdk.getTracer(), soit d'utiliser des instructions print et d'exécuter l'application via le binaire /isan/bin/python du shell Bash.
pyCmdHandler, classe - Exemple
Le code suivant sert d'exemple pour la classe pyCmdHandler décrite ci-dessus. Ce code provient du fichier ip_move.py dans l'application NX-SDK ip-movement disponible ici. L'objectif de cette application est de suivre le mouvement d'une adresse IP définie par l'utilisateur sur les interfaces d'un périphérique Nexus. Pour ce faire, le code recherche l'adresse MAC de l'adresse IP entrée par le paramètre <ip> dans le cache ARP du périphérique, puis vérifie quel VLAN cette adresse MAC réside dans en utilisant la table d'adresses MAC du périphérique. En utilisant ces adresses MAC et VLAN, la commande show system internal l2fm l2dbg macdb address <mac> vlan <vlan> affiche une liste des index d'interface SNMP auxquels cette combinaison a été récemment associée. Le code utilise ensuite la commande show interface snmp-ifindex pour traduire les index d'interface SNMP récents en noms d'interface lisibles par l'homme.
class pyCmdHandler(nx_sdk_py.NxCmdHandler):
def postCliCb(self, clicmd):
global cli_parser
if "show_ip_movement" in clicmd.getCmdName():
target_ip = nx_sdk_py.void_to_string(clicmd.getParamValue("<ip>"))
target_mac = get_mac_from_arp(cli_parser, clicmd, target_ip)
mac_vlan = ""
if target_mac:
mac_vlan = get_vlan_from_cam(cli_parser, clicmd, target_mac)
if mac_vlan:
find_mac_movement(cli_parser, clicmd, target_mac, mac_vlan)
else:
print("No entires in MAC address table")
clicmd.printConsole("No entries in MAC address table for {}".format(target_mac))
else:
clicmd.printConsole("No entries in ARP table for {}".format(target_ip))
return True
def get_mac_from_arp(cli_parser, clicmd, target_ip):
exec_cmd = "show ip arp {}".format(target_ip)
arp_cmd = cli_parser.execShowCmd(exec_cmd, nx_sdk_py.R_JSON)
if arp_cmd:
try:
arp_json = json.loads(arp_cmd)
except ValueError as exc:
return None
count = int(arp_json["TABLE_vrf"]["ROW_vrf"]["cnt-total"])
if count:
intf = arp_json["TABLE_vrf"]["ROW_vrf"]["TABLE_adj"]["ROW_adj"]
if intf.get("ip-addr-out") == target_ip:
target_mac = intf["mac"]
clicmd.printConsole("{} is currently present in ARP table, MAC address {}\n".format(target_ip, target_mac))
return target_mac
else:
return None
else:
return None
else:
return None
def get_vlan_from_cam(cli_parser, clicmd, target_mac):
exec_cmd = "show mac address-table address {}".format(target_mac)
mac_cmd = cli_parser.execShowCmd(exec_cmd, nx_sdk_py.R_JSON)
if mac_cmd:
try:
cam_json = json.loads(mac_cmd)
except ValueError as exc:
return None
mac_entry = cam_json["TABLE_mac_address"]["ROW_mac_address"]
if mac_entry:
if mac_entry["disp_mac_addr"] == target_mac:
egress_intf = mac_entry["disp_port"]
mac_vlan = mac_entry["disp_vlan"]
clicmd.printConsole("{} is currently present in MAC address table on interface {}, VLAN {}\n".format(target_mac, egress_intf, mac_vlan))
return mac_vlan
else:
return None
else:
return None
else:
return None
def find_mac_movement(cli_parser, clicmd, target_mac, mac_vlan):
exec_cmd = "show system internal l2fm l2dbg macdb address {} vlan {}".format(target_mac, mac_vlan)
l2fm_cmd = cli_parser.execShowCmd(exec_cmd)
if l2fm_cmd:
event_re = re.compile(r"^\s+(\w{3}) (\w{3}) (\d+) (\d{2}):(\d{2}):(\d{2}) (\d{4}) (0x\S{8}) (\d+)\s+(\S+) (\d+)\s+(\d+)\s+(\d+)")
unique_interfaces = []
l2fm_events = l2fm_cmd.splitlines()
for line in l2fm_events:
res = re.search(event_re, line)
if res:
day_name = res.group(1)
month = res.group(2)
day = res.group(3)
hour = res.group(4)
minute = res.group(5)
second = res.group(6)
year = res.group(7)
if_index = res.group(8)
db = res.group(9)
event = res.group(10)
src=res.group(11)
slot = res.group(12)
fe = res.group(13)
if "MAC_NOTIF_AM_MOVE" in event:
timestamp = "{} {} {} {}:{}:{} {}".format(day_name, month, day, hour, minute, second, year)
intf_dict = {"if_index": if_index, "timestamp": timestamp}
unique_interfaces.append(intf_dict)
if not unique_interfaces:
clicmd.printConsole("No entries for {} in L2FM L2DBG\n".format(target_mac))
if len(unique_interfaces) == 1:
clicmd.printConsole("{} has not been moving between interfaces\n".format(target_mac))
if len(unique_interfaces) > 1:
clicmd.printConsole("{} has been moving between the following interfaces, from most recent to least recent:\n".format(target_mac))
unique_interfaces = get_snmp_intf_index(unique_interfaces)
clicmd.printConsole("\t{} - {} (Current interface)\n".format(unique_interfaces[-1]["timestamp"], unique_interfaces[-1]["intf_name"]))
for intf in unique_interfaces[-2::-1]:
clicmd.printConsole("\t{} - {}\n".format(intf["timestamp"], intf["intf_name"]))
def get_snmp_intf_index(if_index_dict_list):
global cli_parser
snmp_ifindex = cli_parser.execShowCmd("show interface snmp-ifindex", nx_sdk_py.R_JSON)
snmp_ifindex_json = json.loads(snmp_ifindex)
snmp_ifindex_list = snmp_ifindex_json["TABLE_interface"]["ROW_interface"]
for index_dict in if_index_dict_list:
index = index_dict["if_index"]
for ifindex_json in snmp_ifindex_list:
if index == ifindex_json["snmp-ifindex"]:
index_dict["intf_name"] = ifindex_json["interface"]
return if_index_dict_list
Cette section présente quelques exemples du paramètre de syntaxe utilisé lorsque vous créez des commandes CLI personnalisées avec les méthodes cliP.newShowCmd() ou cliP.newConfigCmd(), où cliP est l'objet NxCliParser renvoyé par la méthode sdk.getCliParser().
Remarque : La prise en charge de la syntaxe avec des parenthèses ouvrantes et fermantes ("(" et ")") est présentée dans NX-SDK v1.5.0, inclus dans NX-OS version 7.0(3)I7(3). On suppose que l'utilisateur utilise NX-SDK v1.5.0 lorsqu'il suit l'un de ces exemples donnés qui incluent une syntaxe utilisant des parenthèses ouvrantes et fermantes.
Cette commande show prend un seul mot-clé mac et ajoute au mot-clé une chaîne d'aide de Shows all misprogrammed MAC addresses on this device.
nx_cmd = cliP.newShowCmd("show_misprogrammed", "mac")
nx_cmd.updateKeyword("mac", "Shows all misprogrammed MAC addresses on this device")
Cette commande show prend un seul paramètre <mac>. Les crochets encadrant le mot mac signifient qu'il s'agit d'un paramètre. Une chaîne d'aide d'adresse MAC pour vérifier les erreurs de programmation est ajoutée au paramètre. Le paramètre nx_sdk_py.P_MAC_ADDR dans la méthode nx_cmd.updateParam() est utilisé pour définir le type du paramètre en tant qu'adresse MAC, ce qui empêche l'utilisateur final d'entrer un autre type, tel qu'une chaîne, un entier ou une adresse IP.
nx_cmd = cliP.newShowCmd("show_misprogrammed_mac", "<mac>")
nx_cmd.updateParam("<mac>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)
Cette commande show peut éventuellement prendre un seul mot clé [mac]. Les crochets encadrant le mot mac signifient que ce mot clé est facultatif. Une chaîne helper de Shows all misprogrammed MAC addresses on this device est ajoutée au mot-clé.
nx_cmd = cliP.newShowCmd( "show_misprogrammed_mac" , "[mac]" )
nx_cmd.updateKeyword( "mac" , "Shows all misprogrammed MAC addresses on this device" )
Cette commande show peut éventuellement prendre un seul paramètre [<mac>]. Les crochets encadrant le mot < mac > indiquent que ce paramètre est facultatif. Les crochets encadrant le mot mac signifient qu'il s'agit d'un paramètre. Une chaîne d'aide d'adresse MAC pour vérifier les erreurs de programmation est ajoutée au paramètre. Le paramètre nx_sdk_py.P_MAC_ADDR dans la méthode nx_cmd.updateParam() est utilisé pour définir le type du paramètre en tant qu'adresse MAC, ce qui empêche l'utilisateur final d'entrer un autre type, tel qu'une chaîne, un entier ou une adresse IP.
nx_cmd = cliP.newShowCmd("show_misprogrammed_mac", "[<mac>]")
nx_cmd.updateParam("<mac>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)
Cette commande show prend un seul mot clé mac immédiatement suivi du paramètre <mac-address>. Les crochets encadrant le mot mac-address indiquent qu'il s'agit d'un paramètre. Une chaîne d'aide de Check MAC address for misprogram est ajoutée au mot-clé. Une chaîne d'aide d'adresse MAC pour vérifier les erreurs de programmation est ajoutée au paramètre. Le paramètre nx_sdk_py.P_MAC_ADDR dans la méthode nx_cmd.updateParam() est utilisé afin de définir le type du paramètre en tant qu'adresse MAC, ce qui empêche l'entrée par l'utilisateur final d'un autre type, tel qu'une chaîne, un entier ou une adresse IP.
nx_cmd = cliP.newShowCmd("show_misprogrammed", "mac <mac-address>")
nx_cmd.updateKeyword("mac", "Check MAC address for misprogramming")
nx_cmd.updateParam("<mac-address>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)
Cette commande show peut prendre l'un des deux mots-clés, qui ont tous deux deux différents paramètres qui les suivent. Le premier mot clé mac a un paramètre de <mac-address>, et le second mot clé ip a un paramètre de <ip-address>. Les crochets encadrant les mots mac-address et ip-address indiquent qu'il s'agit de paramètres. Une chaîne d'aide de Check MAC address for misprogram est ajoutée au mot clé mac. Une chaîne d'aide d'adresse MAC pour vérifier la présence d'erreurs de programmation est ajoutée au paramètre <mac-address>. Le paramètre nx_sdk_py.P_MAC_ADDR dans la méthode nx_cmd.updateParam() est utilisé pour définir le type du paramètre <mac-address> en tant qu'adresse MAC, ce qui empêche l'entrée par l'utilisateur final d'un autre type, tel qu'une chaîne, un entier ou une adresse IP. Une chaîne d'aide de Check IP address for misprograming est ajoutée au mot-clé ip. Une chaîne d'aide d'adresse IP pour vérifier la présence d'erreurs de programmation est ajoutée au paramètre <ip-address>. Le paramètre nx_sdk_py.P_IP_ADDR dans la méthode nx_cmd.updateParam() est utilisé pour définir le type du paramètre <ip-address> en tant qu'adresse IP, ce qui empêche l'entrée par l'utilisateur final d'un autre type, tel qu'une chaîne, un entier ou une adresse IP.
nx_cmd = cliP.newShowCmd("show_misprogrammed", "(mac <mac-address> | ip <ip-address>)")
nx_cmd.updateKeyword("mac", "Check MAC address for misprogramming")
nx_cmd.updateParam("<mac-address>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)
nx_cmd.updateKeyword("ip", "Check IP address for misprogramming")
nx_cmd.updateParam("<ip-address>", "IP address to check for misprogramming", nx_sdk_py.P_IP_ADDR)
Cette commande show peut prendre l'un des deux mots-clés, qui ont tous deux deux différents paramètres qui les suivent. Le premier mot clé mac a un paramètre de <mac-address>, et le second mot clé ip a un paramètre de <ip-address>. Les crochets encadrant les mots mac-address et ip-address indiquent qu'il s'agit de paramètres. Une chaîne d'aide de Check MAC address for misprogram est ajoutée au mot clé mac. Une chaîne d'aide d'adresse MAC pour vérifier la présence d'erreurs de programmation est ajoutée au paramètre <mac-address>. Le paramètre nx_sdk_py.P_MAC_ADDR dans la méthode nx_cmd.updateParam() est utilisé pour définir le type du paramètre <mac-address> en tant qu'adresse MAC, ce qui empêche l'entrée par l'utilisateur final d'un autre type, tel qu'une chaîne, un entier ou une adresse IP. Une chaîne d'aide de Check IP address for misprograming est ajoutée au mot-clé ip. Une chaîne d'aide d'adresse IP pour vérifier la présence d'erreurs de programmation est ajoutée au paramètre <ip-address>. Le paramètre nx_sdk_py.P_IP_ADDR dans la méthode nx_cmd.updateParam() est utilisé pour définir le type du paramètre <ip-address> en tant qu'adresse IP, ce qui empêche l'entrée par l'utilisateur final d'un autre type, tel qu'une chaîne, un entier ou une adresse IP. Cette commande show peut éventuellement prendre un mot clé [clear]. Une chaîne d'assistance Efface les adresses détectées comme étant mal programmées est ajoutée à ce mot clé facultatif.
nx_cmd = cliP.newShowCmd("show_misprogrammed", "(mac <mac-address> | ip <ip-address>) [clear]")
nx_cmd.updateKeyword("mac", "Check MAC address for misprogramming")
nx_cmd.updateParam("<mac-address>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)
nx_cmd.updateKeyword("ip", "Check IP address for misprogramming")
nx_cmd.updateParam("<ip-address>", "IP address to check for misprogramming", nx_sdk_py.P_IP_ADDR)
nx_cmd.updateKeyword("clear", "Clears addresses detected to be misprogrammed")
Cette commande show peut prendre l'un des deux mots-clés, qui ont tous deux deux différents paramètres qui les suivent. Le premier mot clé mac a un paramètre de <mac-address>, et le second mot clé ip a un paramètre de <ip-address>. Les crochets encadrant les mots mac-address et ip-address indiquent qu'il s'agit de paramètres. Une chaîne d'aide de Check MAC address for misprogrammingest ajoutée au mot clé mac. Une chaîne d'aide d'adresse MAC pour vérifier la présence d'erreurs de programmation est ajoutée au paramètre <mac-address>. Le paramètre nx_sdk_py.P_MAC_ADDR dans la méthode nx_cmd.updateParam() est utilisé pour définir le type du paramètre <mac-address> en tant qu'adresse MAC, ce qui empêche l'entrée par l'utilisateur final d'un autre type, tel qu'une chaîne, un entier ou une adresse IP. Une chaîne d'aide de Check IP address for misprograming est ajoutée au mot-clé ip. Une chaîne d'aide d'adresse IP pour vérifier la présence d'erreurs de programmation est ajoutée au paramètre <ip-address>. Le paramètre nx_sdk_py.P_IP_ADDR dans la méthode nx_cmd.updateParam() est utilisé pour définir le type du paramètre <ip-address> en tant qu'adresse IP, ce qui empêche l'entrée par l'utilisateur final d'un autre type, tel qu'une chaîne, un entier ou une adresse IP. Cette commande show peut éventuellement prendre un paramètre [<module>]. Une chaîne helper Only clear addresses sur le module spécifié est ajoutée à ce paramètre optionnel.
nx_cmd = cliP.newShowCmd("show_misprogrammed", "(mac <mac-address> | ip <ip-address>) [<module>]")
nx_cmd.updateKeyword("mac", "Check MAC address for misprogramming")
nx_cmd.updateParam("<mac-address>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)
nx_cmd.updateKeyword("ip", "Check IP address for misprogramming")
nx_cmd.updateParam("<ip-address>", "IP address to check for misprogramming", nx_sdk_py.P_IP_ADDR)
nx_cmd.updateParam("<module>", "Clears addresses detected to be misprogrammed", nx_sdk_py.P_INTEGER)
Une fois qu'une application Python NX-SDK a été créée, elle devra souvent être déboguée. NX-SDK vous informe au cas où il y aurait des erreurs de syntaxe dans votre code, mais parce que la bibliothèque Python NX-SDK utilise SWIG pour traduire les bibliothèques C++ en bibliothèques Python, toute exception rencontrée au moment de l'exécution du code aboutit à un dump de coeur d'application similaire à ceci :
terminate called after throwing an instance of 'Swig::DirectorMethodException'
what(): SWIG director method error. Error detected when calling 'NxCmdHandler.postCliCb'
Aborted (core dumped)
En raison de la nature ambiguë de ce message d'erreur, la meilleure pratique pour déboguer les applications Python est de consigner les messages de débogage dans le syslog avec l'utilisation d'un objet NxTrace retourné par la méthode sdk.getTracer(). Ceci est démontré comme suit :
#! /isan/bin/python
tracer = 0
def evt_thread():
<snip>
tracer = sdk.getTracer()
tracer.event("[NXSDK-APP][INFO] Started service")
<snip>
class pyCmdHandler(nx_sdk_py.NxCmdHandler):
def postCliCb(self, clicmd):
global tracer
tracer.event("[NXSDK-APP][DEBUG] Received command: {}".format(clicmd))
if "show_test_command" in clicmd.getCmdName():
tracer.event("[NXSDK-APP][DEBUG] `show_test_command` recognized")
Si la journalisation des messages de débogage dans le syslog n'est pas une option, une autre méthode consiste à utiliser des instructions print et à exécuter l'application via le binaire /isan/bin/python du shell Bash. Cependant, la sortie de ces instructions d'impression ne sera visible que lorsqu'elle sera exécutée de cette manière - l'exécution de l'application via le shell VSH ne produit aucune sortie. Un exemple d'utilisation d'instructions imprimées est illustré ci-dessous :
#! /isan/bin/python
tracer = 0
def evt_thread():
<snip>
print("[NXSDK-APP][INFO] Started service")
<snip>
class pyCmdHandler(nx_sdk_py.NxCmdHandler):
def postCliCb(self, clicmd):
print("[NXSDK-APP][DEBUG] Received command: {}".format(clicmd))
if "show_test_command" in clicmd.getCmdName():
print("[NXSDK-APP][DEBUG] `show_test_command` recognized")
Une fois qu'une application Python a été entièrement testée dans l'interpréteur de commandes Bash et est prête pour le déploiement, l'application doit être installée en production via VSH. Cela permet à l'application de persister lorsque le périphérique se recharge ou lorsque le système bascule dans un scénario à double superviseur. Pour déployer une application via VSH, vous devez créer un package RPM à l'aide d'un environnement de génération NX-SDK et ENXOS SDK. Cisco DevNet fournit une image Docker qui facilite la création de packages RPM.
Remarque : Pour obtenir de l'aide sur l'installation de Docker sur votre système d'exploitation spécifique, reportez-vous à la documentation d'installation de Docker.
Sur un hôte compatible Docker, extrayez la version d'image de votre choix avec la commande docker pull dockercisco/nxsdk:<tag> , où <tag> est la balise de la version d'image de votre choix. Vous pouvez afficher ici les versions d'image disponibles et leurs balises correspondantes. Ceci est démontré avec la balise v1 ici :
docker pull dockercisco/nxsdk:v1
Démarrez un conteneur nommé nxsdk à partir de cette image et attachez-le. Si la balise de votre choix est différente, remplacez-la par v1 :
docker run -it --name nxsdk dockercisco/nxsdk:v1 /bin/bash
Mettez à jour vers la dernière version de NX-SDK et naviguez jusqu'au répertoire NX-SDK, puis extrayez les derniers fichiers de git :
cd /NX-SDK/
git pull
Si vous avez besoin d'utiliser une version plus ancienne de NX-SDK, vous pouvez cloner la branche NX-SDK en utilisant la balise version respective avec la commande git clone -b v<version> https://github.com/CiscoDevNet/NX-SDK.git, où <version> est la version de NX-SDK dont vous avez besoin. Ceci est démontré ici avec NX-SDK v1.0.0 :
cd /
rm -rf /NX-SDK
git clone -b v1.0.0 https://github.com/CiscoDevNet/NX-SDK.git
Ensuite, transférez votre application Python dans le conteneur Docker. Il y a plusieurs façons de le faire.
root@2dcbe841742a:~# exit
[root@localhost ~]# docker cp /app/python_app.py nxsdk:/root/
[root@localhost ~]# docker start nxsdk
nxsdk
[root@localhost ~]# docker attach nxsdk
root@2dcbe841742a:/# ls /root/
python_app.py
Ensuite, utilisez le script rpm_gen.py situé dans /NX-SDK/scripts/ afin de créer un paquet RPM à partir de l'application Python. Ce script comporte un argument requis et deux commutateurs requis :
Remarque : Le nom de fichier n'a pas besoin de contenir d'extensions de fichier, telles que .py. Dans cet exemple, si le nom du fichier était python_app au lieu de python_app.py, le paquet RPM serait généré sans problème.
L'utilisation du script rpm_gen.py est illustrée ici.
root@7bfd1714dd2f:~# python /NX-SDK/scripts/rpm_gen.py test_python_app -s /root/ -u #################################################################################################### Generating rpm package... <snip> RPM package has been built #################################################################################################### SPEC file: /NX-SDK/rpm/SPECS/test_python_app.spec RPM file : /NX-SDK/rpm/RPMS/test_python_app-1.0-1.0.0.x86_64.rpm
Le chemin d'accès au paquet RPM est indiqué dans la dernière ligne de la sortie du script rpm_gen.py. Ce fichier doit être copié du conteneur Docker sur l'hôte afin de pouvoir être transféré vers le périphérique Nexus sur lequel vous souhaitez exécuter l'application. Après avoir quitté le conteneur Docker, vous pouvez le faire facilement avec la commande docker cp <container>:<container_filepath> <host_filepath>, où <container> est le nom du conteneur Docker NX-SDK (dans ce cas, nxsdk), <container_filepath> est le chemin complet du package RPM à l'intérieur du conteneur (dans ce cas, /NX-SDK/rpm/RPMS/test_python_app-1.0-1.0.0.x86_64.rpm), et <host_filepath> est le chemin d'accès complet du fichier sur l'hôte Docker vers lequel le package RPM doit être transféré (dans ce cas, /root/). Cette commande est illustrée ici :
root@7bfd1714dd2f:/# exit [root@localhost ~]# docker cp nxsdk:/NX-SDK/rpm/RPMS/test_python_app-1.0-1.0.0.x86_64.rpm /root/ [root@localhost ~]# ls /root/ anaconda-ks.cfg test_python_app-1.0-1.0.0.x86_64.rpm
Transférez ce package RPM vers le périphérique Nexus en utilisant la méthode de transfert de fichiers que vous préférez. Une fois le package RPM installé sur le périphérique, il doit être installé et activé de la même manière qu'un SMU. Ceci est démontré comme suit, en supposant que le paquet RPM a été transféré au bootflash du périphérique.
N9K-C93180LC-EX# install add bootflash:test_python_app-1.0-1.0.0.x86_64.rpm [####################] 100% Install operation 27 completed successfully at Tue May 8 06:40:13 2018 N9K-C93180LC-EX# install activate test_python_app-1.0-1.0.0.x86_64 [####################] 100% Install operation 28 completed successfully at Tue May 8 06:40:20 2018
Remarque : Lorsque vous installez le package RPM avec la commande install add, incluez le périphérique de stockage et le nom de fichier exact du package. Lorsque vous activez le package RPM après l'installation, n'incluez pas le périphérique de stockage et le nom de fichier : utilisez le nom du package lui-même. Vous pouvez vérifier le nom du package avec la commande show install inactive.
Une fois le package RPM activé, vous pouvez démarrer l'application avec NX-SDK avec la commande de configuration nxsdk service <application-name>, où <application-name> est le nom du nom de fichier Python (et, par la suite, l'application) qui a été défini lorsque le script rpm_gen.py a été utilisé précédemment. Ceci est démontré comme suit :
N9K-C93180LC-EX# conf Enter configuration commands, one per line. End with CNTL/Z. N9K-C93180LC-EX(config)# nxsdk service-name test_python_app % This could take some time. "show nxsdk internal service" to check if your App is Started & Runnning
Vous pouvez vérifier que l'application est active et a commencé à s'exécuter avec la commande show nxsdk internal service :
N9K-C93180LC-EX# show nxsdk internal service NXSDK Started/Temp unavailabe/Max services : 1/0/32 NXSDK Default App Path : /isan/bin/nxsdk NXSDK Supported Versions : 1.0 Service-name Base App Started(PID) Version RPM Package ------------------------- --------------- ----------------- ---------- ------------------------ test_python_app nxsdk_app4 VSH(23195) 1.0 test_python_app-1.0-1.0.0.x86_64
Vous pouvez également vérifier que les commandes CLI personnalisées créées par cette application sont accessibles dans NX-OS :
N9K-C93180LC-EX# show test? test_python_app Nexus Sdk Application
Commentaires