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 spécification déterminée n'est requise pour 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
Note: 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 aucun de ses sous-répertoires.
Note: 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
Note: À 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 les exceptions avancées quand elles ont la valeur True et désactive les exceptions avancées quand elles ont la valeur False. Cette méthode est documentée ici .
Voici quelques méthodes couramment utilisées :
Note: 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 envoyant la sortie au format de données demandé. Si la commande piped 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 retourne la sortie JSON, puis 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 : Afficher les commandes et configurer les commandes.
Ces deux méthodes permettent de créer respectivement des commandes show et config :
Note: 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 à NSDX-personnalisé. L'application K et la syntaxe décrivent les mots clés et les 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.
Note: Cette commande est une sous-classe de cliP.newCmd(« cmd_type », « cmd_name », « syntaxe ») où cmd_type est CONF_CMD ou SHOW_CMD (cela dépend du type de commande configuré), cmd_name est un nom unique pour la commande interne à la personnalisation L'application X-SDK et la syntaxe décrivent les mots clés et les 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.
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é dynamique, 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. Des méthodes pour l'objet NxCliCmd existent pour modifier l'implémentation spécifique des deux composants.
Afin d'afficher des exemples de code de composants de commande couramment utilisés, affichez la section Exemples de commandes de l'interface de ligne de commande personnalisée 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 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 NX-OS afin que les commandes CLI personnalisées soient visibles par l'utilisateur. Ceci est fait avec la commande cliP.addToParseTree(), où cliP est l'objet NxCliParser retourné par la méthode sdk.getCliParser().
Exemple de fonction sdkThread
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 standard) utilise des variables globales, qui sont instanciées lors de l'exécution de 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 provenant d'une application NX-SDK sont appelées. Ainsi, la méthode postCliCb(self, clicmd) est l'endroit 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) retourne une valeur booléenne. Si True est renvoyé, il est présumé que la commande a été exécutée avec succès. False doit être retourné si la commande n'a pas été exécutée correctement pour une raison quelconque.
Le paramètre clicmd utilise le nom unique 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, 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, vous devrez 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 que vous souhaitez placer entre crochets angulaires (<>). Cette méthode est documentée ici. Cependant, la valeur retournée par cette fonction doit être convertie en type dont vous avez besoin. Pour ce faire, procédez comme suit :
La fonction postCliCb(self, clicmd) (ou toute fonction ultérieure) sera généralement utilisée pour imprimer la sortie de la commande show sur la console. Ceci est fait avec la méthode clicmd.printConsole().
Note: Si l'application rencontre une erreur, une exception non gérée, ou se retire soudainement, alors la sortie de la fonction clicmd.printConsole() ne sera pas affichée du tout. Pour cette raison, la meilleure pratique lorsque 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 d'impression et d'exécuter l'application via le binaire du shell Bash /isan/bin/bin/python.
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 de l'application ip-mouvement NX-SDK disponible ici. L'objectif de cette application est de suivre le déplacement 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'entrée d'adresse IP via le paramètre <ip> dans le cache ARP du périphérique, puis vérifie le VLAN dans lequel réside cette adresse MAC à l'aide de la table d'adresses MAC du périphérique. À l'aide de cette adresse MAC et de ce VLAN, la commande show system internal l2fm l2dbg macdb address <mac> vlan <vlan> affiche la liste des index d'interface SNMP auxquels cette combinaison a récemment été 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 retourné par la méthode sdk.getCliParser().
Note: La prise en charge de la syntaxe avec parenthèses ouvrantes et fermantes ("(" et ")") est introduite dans NX-SDK v1.5.0, incluse dans NX-OS version 7.0(3)I7(3). Il est supposé que l'utilisateur utilise NX-SDK v1.5.0 lorsqu'il suit l'un de ces exemples donnés qui incluent la syntaxe utilisant des parenthèses ouvrantes et fermantes.
Cette commande show prend un seul mot clé mac et ajoute une chaîne d'aide de Shows all bad programmed MAC address on this device au mot clé.
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 d'angle autour du mot mac signifient qu'il s'agit d'un paramètre. Une chaîne d'aide d'adresse MAC pour vérifier la mauvaise programmation est ajoutée au paramètre. Le paramètre nx_sdk_py.P_MAC_ADDR. dans la méthode nx_cmd.updateParam() sert à définir le type du paramètre en tant qu'adresse MAC, ce qui empêche l'entrée de l'utilisateur final d'un autre type, comme 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 entourant le mot mac signifient que ce mot clé est facultatif. Une chaîne d'aide Affiche toutes les adresses MAC mal programmées sur ce périphérique 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 entourant le mot < mac > signifient que ce paramètre est facultatif. Les crochets d'angle autour du mot mac signifient qu'il s'agit d'un paramètre. Une chaîne d'aide d'adresse MAC pour vérifier la mauvaise programmation est ajoutée au paramètre. Le paramètre nx_sdk_py.P_MAC_ADDR. dans la méthode nx_cmd.updateParam() sert à définir le type du paramètre en tant qu'adresse MAC, ce qui empêche l'entrée de l'utilisateur final d'un autre type, comme 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 d'angle autour du mot mac-address signifient qu'il s'agit d'un paramètre. Une chaîne d'aide de Check MAC address pour détecter une mauvaise programmation est ajoutée au mot clé. Une chaîne d'aide d'adresse MAC pour vérifier la mauvaise 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 de l'utilisateur final d'un autre type, comme 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 deux paramètres différents après eux. Le premier mot clé mac a un paramètre <mac-address>, et le second mot clé ip a un paramètre <ip-address>. Les crochets d'angle autour des mots mac-address et ip-address signifient qu'il s'agit de paramètres. Une chaîne d'aide de Check MAC address pour détecter une mauvaise programmation est ajoutée au mot clé mac. Une chaîne d'aide d'adresse MAC pour vérifier la mauvaise programmation est ajoutée au paramètre <mac-address>. Le paramètre nx_sdk_py.P_MAC_ADDR de la méthode nx_cmd.updateParam() est utilisé pour définir le type du <mac-address> comme adresse MAC, ce qui empêche l'utilisateur final de saisir un autre type, comme une chaîne, un entier ou une adresse IP. Une chaîne d'aide de Check IP address pour détecter une mauvaise programmation est ajoutée au mot clé ip. Une chaîne d'aide d'adresse IP permettant de vérifier la mauvaise programmation est ajoutée au paramètre <ip-address>. Le paramètre nx_sdk_py.P_IP_ADDR de la méthode nx_cmd.updateParam() est utilisé pour définir le type du <adresse-ip> comme adresse IP, ce qui empêche l'entrée de l'utilisateur final d'un autre type, comme 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 deux paramètres différents après eux. Le premier mot clé mac a un paramètre <mac-address>, et le second mot clé ip a un paramètre <ip-address>. Les crochets d'angle autour des mots mac-address et ip-address signifient qu'il s'agit de paramètres. Une chaîne d'aide de Check MAC address pour détecter une mauvaise programmation est ajoutée au mot clé mac. Une chaîne d'aide d'adresse MAC pour vérifier la mauvaise programmation est ajoutée au paramètre <mac-address>. Le paramètre nx_sdk_py.P_MAC_ADDR de la méthode nx_cmd.updateParam() est utilisé pour définir le type du <mac-address> comme adresse MAC, ce qui empêche l'utilisateur final de saisir un autre type, comme une chaîne, un entier ou une adresse IP. Une chaîne d'aide de Check IP address pour détecter une mauvaise programmation est ajoutée au mot clé ip. Une chaîne d'aide d'adresse IP permettant de vérifier la mauvaise programmation est ajoutée au paramètre <ip-address>. Le paramètre nx_sdk_py.P_IP_ADDR de la méthode nx_cmd.updateParam() est utilisé pour définir le type du <adresse-ip> comme adresse IP, ce qui empêche l'entrée de l'utilisateur final d'un autre type, comme une chaîne, un entier ou une adresse IP. Cette commande show peut éventuellement prendre un mot clé [clear]. Une chaîne d'aide 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 deux paramètres différents après eux. Le premier mot clé mac a un paramètre <mac-address>, et le second mot clé ip a un paramètre <ip-address>. Les crochets d'angle autour des mots mac-address et ip-address signifient qu'il s'agit de paramètres. Une chaîne d'aide de Check MAC address for misprogrammingis est ajoutée au mot clé mac. Une chaîne d'aide d'adresse MAC pour vérifier la mauvaise programmation est ajoutée au paramètre <mac-address>. Le paramètre nx_sdk_py.P_MAC_ADDR de la méthode nx_cmd.updateParam() est utilisé pour définir le type du <mac-address> comme adresse MAC, ce qui empêche l'utilisateur final de saisir un autre type, comme une chaîne, un entier ou une adresse IP. Une chaîne d'aide de Check IP address pour détecter une mauvaise programmation est ajoutée au mot clé ip. Une chaîne d'aide d'adresse IP permettant de vérifier la mauvaise programmation est ajoutée au paramètre <ip-address>. Le paramètre nx_sdk_py.P_IP_ADDR de la méthode nx_cmd.updateParam() est utilisé pour définir le type du <adresse-ip> comme adresse IP, ce qui empêche l'entrée de l'utilisateur final d'un autre type, comme une chaîne, un entier ou une adresse IP. Cette commande show peut éventuellement prendre un paramètre [<module>]. Chaîne d'aide Seules les adresses claires sur le module spécifié sont ajoutées à ce paramètre facultatif.
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 en cas d'erreur 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, toutes les exceptions rencontrées au moment de l'exécution du code entraînent un vidage du noyau 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 d'impression 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 si elle est exécutée de cette manière. L'exécution de l'application via le shell VSH ne génère aucune sortie. Voici un exemple d'utilisation des instructions d'impression :
#! /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 le shell 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 la commutation du système se produit dans un scénario de double superviseur. Pour déployer une application via VSH, vous devez créer un package RPM à l'aide d'un environnement de build NX-SDK et ENXOS SDK. Cisco DevNet fournit une image Docker qui facilite la création de packages RPM.
Note: Pour obtenir de l'aide pour installer Docker sur votre système d'exploitation spécifique, reportez-vous à la documentation d'installation de Docker.
Sur un hôte compatible Docker, tirez la version d'image de votre choix à l'aide de la commande docker pull dockercisco/nxsdk:<tag>, où <tag> est la balise de la version d'image de votre choix. Vous pouvez voir les versions d'image disponibles et leurs balises correspondantes ici. 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 joignez-le. Si la balise de votre choix est différente, remplacez v1 par votre balise :
docker run -it --name nxsdk dockercisco/nxsdk:v1 /bin/bash
Mettre à jour la dernière version de NX-SDK et accéder au répertoire NX-SDK, puis extraire les derniers fichiers de git :
cd /NX-SDK/
git pull
Si vous avez besoin d'utiliser une version antérieure de NX-SDK, vous pouvez cloner la branche NX-SDK avec l'utilisation de la balise de 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 quelques façons différentes 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 obligatoire et deux commutateurs requis :
Note: Le nom du fichier ne doit contenir aucune extension de fichier, telle que .py. Dans cet exemple, si le nom du fichier était python_app au lieu de python_app.py, le package RPM serait généré sans problème.
L'utilisation du script rpm_gen.py est présenté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 ligne finale du script rpm_gen.py. Ce fichier doit être copié hors du conteneur Docker sur l'hôte afin qu'il puisse être transféré au périphérique Nexus sur lequel vous souhaitez exécuter l'application. Une fois que vous avez 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 de fichier 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 de fichier complet sur notre hôte Docker où le paquet RPM doit être transféré (dans ce cas, /root/). Cette commande est présenté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 que le package RPM est sur le périphérique, il doit être installé et activé de la même manière qu'une 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
Note: Lorsque vous installez le package RPM à l'aide de 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 à l'aide de 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 <nom-application>, où <nom-application> est le nom du fichier Python (et, par la suite, de 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 à l'aide de 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