In dem Dokumentationssatz für dieses Produkt wird die Verwendung inklusiver Sprache angestrebt. Für die Zwecke dieses Dokumentationssatzes wird Sprache als „inklusiv“ verstanden, wenn sie keine Diskriminierung aufgrund von Alter, körperlicher und/oder geistiger Behinderung, Geschlechtszugehörigkeit und -identität, ethnischer Identität, sexueller Orientierung, sozioökonomischem Status und Intersektionalität impliziert. Dennoch können in der Dokumentation stilistische Abweichungen von diesem Bemühen auftreten, wenn Text verwendet wird, der in Benutzeroberflächen der Produktsoftware fest codiert ist, auf RFP-Dokumentation basiert oder von einem genannten Drittanbieterprodukt verwendet wird. Hier erfahren Sie mehr darüber, wie Cisco inklusive Sprache verwendet.
Cisco hat dieses Dokument maschinell übersetzen und von einem menschlichen Übersetzer editieren und korrigieren lassen, um unseren Benutzern auf der ganzen Welt Support-Inhalte in ihrer eigenen Sprache zu bieten. Bitte beachten Sie, dass selbst die beste maschinelle Übersetzung nicht so genau ist wie eine von einem professionellen Übersetzer angefertigte. Cisco Systems, Inc. übernimmt keine Haftung für die Richtigkeit dieser Übersetzungen und empfiehlt, immer das englische Originaldokument (siehe bereitgestellter Link) heranzuziehen.
Für dieses Dokument bestehen keine speziellen Anforderungen.
Die Informationen in diesem Dokument basieren auf den folgenden Software- und Hardwareversionen:
switch(config)# feature nxsdk
switch(config)# feature bash-shell
switch(config)# run bash
bash-4.2$ vi /isan/bin/nxsdk-app.py
Hinweis: Best Practice ist es, Python-Dateien im /isan/bin/directory zu erstellen. Python-Dateien benötigen Ausführungsberechtigungen, um ausgeführt zu werden. Platzieren Sie Python-Dateien nicht im /bootflash-Verzeichnis oder einem der Unterverzeichnisse.
Hinweis: Es ist nicht erforderlich, Python-Dateien über NX-OS zu erstellen und zu bearbeiten. Der Entwickler kann die Anwendung mithilfe der lokalen Umgebung erstellen und die ausgefüllten Dateien mithilfe eines Dateiübertragungsprotokolls seiner Wahl auf das Gerät übertragen. Es kann jedoch für Entwickler effizienter sein, ihr Skript mithilfe von NX-OS-Dienstprogrammen zu debuggen und Fehler zu beheben.
sdkThread-Funktion
Hinweis: Ab NX-SDK v1.5.0 kann ein dritter boolescher Parameter an die NxSdk.getSdkInst-Methode übergeben werden, die erweiterte Ausnahmen aktiviert, wenn True und Advanced Exceptions bei False deaktiviert werden. Diese Methode ist hier dokumentiert.
Einige häufig verwendete Methoden sind:
Hinweis: Die Datenformate R_JSON und R_XML funktionieren nur, wenn der Befehl die Ausgabe in diesen Formaten unterstützt. In NX-OS können Sie überprüfen, ob ein Befehl die Ausgabe in einem bestimmten Datenformat unterstützt, indem Sie die Ausgabe in das angeforderte Datenformat leiten. Wenn der Befehl piped aussagekräftige Ausgaben zurückgibt, wird dieses Datenformat unterstützt. Wenn Sie z. B. show mac address-table ausführen | gibt in NX-OS die JSON-Ausgabe zurück, und das R_JSON-Datenformat wird auch in NX-SDK unterstützt.
Folgende optionale Methoden können hilfreich sein:
N9K-C93180LC-EX# show Tra?
track Tracking information
Transceiver_DOM.py Returns all interfaces with DOM-capable transceivers inserted
In einer Python-Anwendung mit NX-SDK werden benutzerdefinierte CLI-Befehle in der sdkThread-Funktion erstellt und definiert. Es gibt zwei Arten von Befehlen: Anzeigen von Befehlen und Konfigurationsbefehlen.
Diese beiden Methoden ermöglichen die Erstellung von show-Befehlen bzw. Konfigurationsbefehlen:
Hinweis: Dieser Befehl ist eine Unterklasse von cliP.newCliCmd("cmd_type", "cmd_name", "syntax"), wobei cmd_type entweder CONF_CMD oder SHOW_CMD ist (je nach konfiguriertem Befehlstyp), cmd_name ist ein eindeutiger Name für den internen Befehl Die benutzerdefinierte NX-SDK-Anwendung und die Syntax beschreiben, welche Schlüsselwörter und Parameter im Befehl verwendet werden können. Daher kann die API-Dokumentation für diesen Befehl hilfreicher sein.
Hinweis: Dieser Befehl ist eine Unterklasse von cliP.newCliCmd("cmd_type", "cmd_name", "syntax"), wobei cmd_type entweder CONF_CMD oder SHOW_CMD ist (er hängt vom konfigurierten Befehlstyp ab), cmd_name ist ein eindeutiger Name für den -Befehl für die benutzerdefinierte NX-SDK-Anwendung integriert ist, und die Syntax beschreibt, welche Schlüsselwörter und Parameter im Befehl verwendet werden können. Daher kann die API-Dokumentation für diesen Befehl hilfreicher sein.
Beide Befehlstypen haben zwei verschiedene Komponenten: Parameter und Schlüsselwörter:
1. Parameter sind Werte, mit denen die Ergebnisse des Befehls geändert werden. Im Befehl show ip route 192.168.1.0 gibt es beispielsweise ein route-Schlüsselwort gefolgt von einem Parameter, der eine IP-Adresse akzeptiert, das angibt, dass nur Routen angezeigt werden sollen, die die angegebene IP-Adresse enthalten.
2. Schlüsselwörter verändern die Ergebnisse des Befehls allein durch ihre Präsenz. Im Befehl show mac address-table dynamic gibt es beispielsweise ein dynamisches Schlüsselwort, das angibt, dass nur dynamisch erlernte MAC-Adressen angezeigt werden sollen.
Beide Komponenten werden bei der Erstellung in der Syntax eines NX-SDK-Befehls definiert. Es gibt Methoden für das NxCliCmd-Objekt, um die spezifische Implementierung beider Komponenten zu ändern.
Codebeispiele für häufig verwendete Befehlskomponenten können Sie im Abschnitt Custom CLI Command Examples dieses Dokuments anzeigen.
Nachdem benutzerdefinierte CLI-Befehle erstellt wurden, muss ein Objekt aus der später in diesem Dokument beschriebenen pyCmdHandler-Klasse erstellt und als CLI-Rückrufhandlerobjekt für das NxCliParser-Objekt festgelegt werden. Dies wird wie folgt gezeigt:
cmd_handler = pyCmdHandler()
cliP.setCmdHandler(cmd_handler)
Anschließend muss das NxCliParser-Objekt der NX-OS CLI-Parserstruktur hinzugefügt werden, damit benutzerdefinierte CLI-Befehle für den Benutzer sichtbar sind. Dies erfolgt mit dem Befehl cliP.addToParseTree(), wobei cliP das NxCliParser-Objekt ist, das von der sdk.getCliParser()-Methode zurückgegeben wird.
sdkThread-Funktionsbeispiel
Hier ist ein Beispiel für eine typische sdkThread-Funktion mit der Verwendung der zuvor beschriebenen Funktionen. Diese Funktion (unter anderem in einer typischen benutzerdefinierten Python-Anwendung des NX-SDK) verwendet globale Variablen, die bei der Skriptausführung instanziiert werden.
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)
Die pyCmdHandler-Klasse wird von der NxCmdHandler-Klasse in der Bibliothek nx_sdk_py geerbt. Die PostCliCb(self, clicmd)-Methode, die in der pyCmdHandler-Klasse definiert ist, wird immer aufgerufen, wenn CLI-Befehle aus einer NX-SDK-Anwendung stammen. Die postCliCb(self, clicmd)-Methode definiert daher, wie sich die in der sdkThread-Funktion definierten benutzerdefinierten CLI-Befehle auf dem Gerät verhalten.
Die postCliCb(self, clicmd)-Funktion gibt einen booleschen Wert zurück. Wenn True zurückgegeben wird, wird angenommen, dass der Befehl erfolgreich ausgeführt wurde. False sollte zurückgegeben werden, wenn der Befehl aus irgendeinem Grund nicht erfolgreich ausgeführt wurde.
Der clicmd-Parameter verwendet den eindeutigen Namen, der für den Befehl definiert wurde, als er in der sdkThread-Funktion erstellt wurde. Wenn Sie beispielsweise einen neuen show-Befehl mit dem eindeutigen Namen show_xcvr_dom erstellen, wird empfohlen, auf diesen Befehl mit demselben Namen in der postCliCb(self, clicmd)-Funktion zu verweisen, nachdem Sie überprüft haben, ob der Name des clicmd-Arguments show_xcvr_dom enthält. Es wird hier gezeigt:
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()
Wenn ein Befehl erstellt wird, der Parameter verwendet, dann müssen Sie diese Parameter wahrscheinlich irgendwann in der postCliCb(self, clicmd) Funktion verwenden. Dies kann mit der clicmd.getParamValue("<parameter>")-Methode erfolgen, wobei <parameter> der Name des Befehlsparameters ist, der den Wert von eckigen Klammern (<>) abrufen soll. Diese Methode ist hier dokumentiert. Der von dieser Funktion zurückgegebene Wert muss jedoch in den von Ihnen benötigten Typ konvertiert werden. Dies kann mit den folgenden Methoden erfolgen:
Die PostCliCb(self, clicmd)-Funktion (oder alle nachfolgenden Funktionen) wird in der Regel auch dort eingesetzt, wo die Ausgabe des Befehls show auf die Konsole gedruckt wird. Dies erfolgt mit der clicmd.printConsole()-Methode.
Hinweis: Wenn die Anwendung einen Fehler, eine unbehandelte Ausnahme oder auf andere Weise plötzlich beendet, wird die Ausgabe der Funktion clicmd.printConsole() überhaupt nicht angezeigt. Aus diesem Grund empfiehlt es sich beim Debuggen der Python-Anwendung, entweder Debug-Meldungen im Syslog unter Verwendung eines von der sdk.getTracer()-Methode zurückgegebenen NxTrace-Objekts zu protokollieren oder Print-Anweisungen zu verwenden und die Anwendung über die /isan/bin/python Binärdatei der Bash-Shell auszuführen.
pyCmdHandler-Klassenbeispiel
Der folgende Code dient als Beispiel für die oben beschriebene pyCmdHandler-Klasse. Dieser Code stammt aus der Datei ip_move.py in der hier verfügbaren Anwendung ip-move NX-SDK. Diese Anwendung verfolgt die Bewegung einer benutzerdefinierten IP-Adresse über die Schnittstellen eines Nexus-Geräts. Hierzu findet der Code die MAC-Adresse der IP-Adresseingabe über den <ip>-Parameter im ARP-Cache des Geräts und überprüft dann, in welchem VLAN sich die MAC-Adresse befindet, mithilfe der MAC-Adresstabelle des Geräts. Mithilfe dieser MAC- und VLAN-Adresse zeigt der Befehl show system internal l2fm l2dbg macdb address <mac> vlan <vlan> eine Liste von SNMP-Schnittstellenindizes an, die dieser Kombination in letzter Zeit zugeordnet wurden. Der Code verwendet dann den Befehl show interface snmp-ifindex, um aktuelle SNMP-Schnittstellenindizes in lesbare Schnittstellennamen zu übersetzen.
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
In diesem Abschnitt werden einige Beispiele des Syntaxparameters dargestellt, der beim Erstellen benutzerdefinierter CLI-Befehle mit der cliP.newShowCmd()-Methode oder der cliP.newConfigCmd()-Methode verwendet wird, wobei cliP das von der sdk.getCliParser() zurückgegebene NxParser-Objekt ist. Methode.
Hinweis: Die Unterstützung für Syntax mit öffnenden und schließenden Klammern ("(" und ")") wird in NX-SDK v1.5.0 eingeführt, das in NX-OS 7.0(3)I7(3) enthalten ist. Es wird davon ausgegangen, dass der Benutzer NX-SDK v1.5.0 verwendet, wenn er eines der genannten Beispiele befolgt, das auch die Syntax zum Öffnen und Schließen von Klammern umfasst.
Dieser Befehl show verwendet ein einzelnes Schlüsselwort mac und fügt dem Schlüsselwort eine Hilfszeichenfolge mit Zeigt alle falsch programmierten MAC-Adressen auf diesem Gerät hinzu.
nx_cmd = cliP.newShowCmd("show_misprogrammed", "mac")
nx_cmd.updateKeyword("mac", "Shows all misprogrammed MAC addresses on this device")
Dieser Befehl show verwendet einen einzigen Parameter <mac>. Die umschließenden spitzen Klammern um das Wort mac bedeuten, dass es sich um einen Parameter handelt. Dem Parameter wird eine Hilfszeichenfolge von MAC-Adressen hinzugefügt, die auf Fehlprogrammierung überprüft werden soll. Der nx_sdk_py.P_MAC_ADDR-Parameter in der nx_cmd.updateParam()-Methode wird verwendet, um den Parametertyp als MAC-Adresse zu definieren, wodurch Endbenutzereingaben eines anderen Typs wie eine Zeichenfolge, eine ganze Zahl oder eine IP-Adresse verhindert werden.
nx_cmd = cliP.newShowCmd("show_misprogrammed_mac", "<mac>")
nx_cmd.updateParam("<mac>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)
Dieser Befehl show kann optional ein einzelnes Schlüsselwort [mac] enthalten. Die umschließenden Klammern um das Wort mac geben an, dass dieses Schlüsselwort optional ist. Eine Hilfszeichenfolge von Zeigt alle falsch programmierten MAC-Adressen auf diesem Gerät wird dem Schlüsselwort hinzugefügt.
nx_cmd = cliP.newShowCmd( "show_misprogrammed_mac" , "[mac]" )
nx_cmd.updateKeyword( "mac" , "Shows all misprogrammed MAC addresses on this device" )
Dieser Befehl show kann optional einen einzigen Parameter annehmen [<mac>]. Die umschließenden Klammern um das Wort < mac > geben an, dass dieser Parameter optional ist. Die umschließenden spitzen Klammern um das Wort mac bedeuten, dass es sich um einen Parameter handelt. Dem Parameter wird eine Hilfszeichenfolge von MAC-Adressen hinzugefügt, die auf Fehlprogrammierung überprüft werden soll. Der nx_sdk_py.P_MAC_ADDR-Parameter in der nx_cmd.updateParam()-Methode wird verwendet, um den Parametertyp als MAC-Adresse zu definieren, wodurch Endbenutzereingaben eines anderen Typs wie eine Zeichenfolge, eine ganze Zahl oder eine IP-Adresse verhindert werden.
nx_cmd = cliP.newShowCmd("show_misprogrammed_mac", "[<mac>]")
nx_cmd.updateParam("<mac>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)
Dieser show-Befehl verwendet sofort ein einzelnes Schlüsselwort MAC, gefolgt vom Parameter <mac-address>. Die eckigen Klammern um das Wort MAC-Adresse zeigen an, dass es sich um einen Parameter handelt. Dem Schlüsselwort wird eine Hilfszeichenfolge der Check MAC-Adresse für Fehlprogrammierung hinzugefügt. Dem Parameter wird eine Hilfszeichenfolge von MAC-Adressen hinzugefügt, die auf Fehlprogrammierung überprüft werden soll. Der nx_sdk_py.P_MAC_ADDR-Parameter in der nx_cmd.updateParam()-Methode wird verwendet, um den Parametertyp als MAC-Adresse zu definieren. Dies verhindert die Eingabe eines anderen Typs durch den Endbenutzer, z. B. eine Zeichenfolge, eine ganze Zahl oder eine IP-Adresse.
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)
Dieser Befehl show kann eines von zwei Schlüsselwörtern verwenden, die beide über zwei verschiedene Parameter verfügen. Das erste Schlüsselwort MAC hat einen Parameter von <mac-address>, das zweite Schlüsselwort ip hat einen Parameter von <ip-address>. Die umschließenden spitzen Klammern um die Wörter MAC-Adresse und IP-Adresse geben an, dass es sich um Parameter handelt. Dem MAC-Schlüsselwort wird eine Hilfszeichenfolge der Check MAC-Adresse für Fehlprogrammierung hinzugefügt. Dem <mac-address> Parameter wird eine Hilfszeichenfolge von MAC-Adressen hinzugefügt, um auf Fehlprogrammierung zu überprüfen. Der nx_sdk_py.P_MAC_ADDR-Parameter in der nx_cmd.updateParam()-Methode wird verwendet, um den Typ des <mac-address>Parameters als MAC-Adresse zu definieren, wodurch die Eingabe eines anderen Typs durch den Endbenutzer verhindert wird, z. B. eine Zeichenfolge, eine ganze Zahl oder eine IP-Adresse. Eine Hilfszeichenfolge der Check-IP-Adresse für Fehlprogrammierung wird dem ip-Schlüsselwort hinzugefügt. Dem <ip-address>-Parameter wird eine Hilfszeichenfolge von IP-Adressen hinzugefügt, um eine Fehlprogrammierung zu überprüfen. Der nx_sdk_py.P_IP_ADDR-Parameter in der nx_cmd.updateParam()-Methode wird verwendet, um den Typ des <ip-address>Parameters als IP-Adresse zu definieren, wodurch die Eingabe eines anderen Typs durch den Endbenutzer verhindert wird, z. B. eine Zeichenfolge, eine ganze Zahl oder eine IP-Adresse.
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)
Dieser Befehl show kann eines von zwei Schlüsselwörtern verwenden, die beide über zwei verschiedene Parameter verfügen. Das erste Schlüsselwort MAC hat einen Parameter von <mac-address>, das zweite Schlüsselwort ip hat einen Parameter von <ip-address>. Die umschließenden spitzen Klammern um die Wörter MAC-Adresse und IP-Adresse geben an, dass es sich um Parameter handelt. Dem MAC-Schlüsselwort wird eine Hilfszeichenfolge der Check MAC-Adresse für Fehlprogrammierung hinzugefügt. Dem <mac-address> Parameter wird eine Hilfszeichenfolge von MAC-Adressen hinzugefügt, um auf Fehlprogrammierung zu überprüfen. Der nx_sdk_py.P_MAC_ADDR-Parameter in der nx_cmd.updateParam()-Methode wird verwendet, um den Typ des <mac-address>Parameters als MAC-Adresse zu definieren, wodurch die Eingabe eines anderen Typs durch den Endbenutzer verhindert wird, z. B. eine Zeichenfolge, eine ganze Zahl oder eine IP-Adresse. Eine Hilfszeichenfolge der Check-IP-Adresse für Fehlprogrammierung wird dem ip-Schlüsselwort hinzugefügt. Dem <ip-address>-Parameter wird eine Hilfszeichenfolge von IP-Adressen hinzugefügt, um eine Fehlprogrammierung zu überprüfen. Der nx_sdk_py.P_IP_ADDR-Parameter in der nx_cmd.updateParam()-Methode wird verwendet, um den Typ des <ip-address>Parameters als IP-Adresse zu definieren, wodurch die Eingabe eines anderen Typs durch den Endbenutzer verhindert wird, z. B. eine Zeichenfolge, eine ganze Zahl oder eine IP-Adresse. Dieser Befehl show kann optional ein Schlüsselwort [clear] verwenden. Diesem optionalen Schlüsselwort wird eine Hilfszeichenfolge Clears-Adressen hinzugefügt, die als falsch programmiert erkannt wurden.
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")
Dieser Befehl show kann eines von zwei Schlüsselwörtern verwenden, die beide über zwei verschiedene Parameter verfügen. Das erste Schlüsselwort MAC hat einen Parameter von <mac-address>, das zweite Schlüsselwort ip hat einen Parameter von <ip-address>. Die umschließenden spitzen Klammern um die Wörter MAC-Adresse und IP-Adresse geben an, dass es sich um Parameter handelt. Eine Hilfszeichenfolge der Check-MAC-Adresse für Fehlprogrammierung wird dem MAC-Schlüsselwort hinzugefügt. Dem <mac-address> Parameter wird eine Hilfszeichenfolge von MAC-Adressen hinzugefügt, um auf Fehlprogrammierung zu überprüfen. Der nx_sdk_py.P_MAC_ADDR-Parameter in der nx_cmd.updateParam()-Methode wird verwendet, um den Typ des <mac-address>Parameters als MAC-Adresse zu definieren, wodurch die Eingabe eines anderen Typs durch den Endbenutzer verhindert wird, z. B. eine Zeichenfolge, eine ganze Zahl oder eine IP-Adresse. Eine Hilfszeichenfolge der Check-IP-Adresse für Fehlprogrammierung wird dem ip-Schlüsselwort hinzugefügt. Dem <ip-address>-Parameter wird eine Hilfszeichenfolge von IP-Adressen hinzugefügt, um eine Fehlprogrammierung zu überprüfen. Der nx_sdk_py.P_IP_ADDR-Parameter in der nx_cmd.updateParam()-Methode wird verwendet, um den Typ des <ip-address>Parameters als IP-Adresse zu definieren, wodurch die Eingabe eines anderen Typs durch den Endbenutzer verhindert wird, z. B. eine Zeichenfolge, eine ganze Zahl oder eine IP-Adresse. Dieser Befehl show kann optional einen Parameter [<module>] annehmen. Dem optionalen Parameter wird eine Hilfszeichenfolge hinzugefügt, die nur klare Adressen auf dem angegebenen Modul enthält.
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)
Nachdem eine NX-SDK-Python-Anwendung erstellt wurde, muss sie häufig gedebuggt werden. NX-SDK informiert Sie, falls Syntaxfehler im Code auftreten, aber da die Python NX-SDK-Bibliothek SWIG verwendet, um C++-Bibliotheken in Python-Bibliotheken zu übersetzen, führen alle Ausnahmen, die bei der Codeausführung auftreten, zu einem Anwendungskern-Dump, der dieser ähnlich ist:
terminate called after throwing an instance of 'Swig::DirectorMethodException'
what(): SWIG director method error. Error detected when calling 'NxCmdHandler.postCliCb'
Aborted (core dumped)
Aufgrund der mehrdeutigen Natur dieser Fehlermeldung besteht die beste Methode zum Debuggen von Python-Anwendungen darin, Debug-Meldungen im Syslog unter Verwendung eines von der sdk.getTracer()-Methode zurückgegebenen NxTrace-Objekts zu protokollieren. Dies wird wie folgt gezeigt:
#! /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")
Wenn die Protokollierung von Debug-Meldungen im Syslog keine Option ist, besteht eine Alternative darin, Print-Anweisungen zu verwenden und die Anwendung über die Bash-Shell /isan/bin/python-Binärdatei auszuführen. Die Ausgabe dieser Druckanweisungen wird jedoch nur sichtbar, wenn sie auf diese Weise ausgeführt wird. Die Ausführung der Anwendung über die VSH-Shell erzeugt keine Ausgabe. Ein Beispiel für die Verwendung von Druckaussagen ist hier:
#! /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")
Nachdem eine Python-Anwendung vollständig in der Bash-Shell getestet und für die Bereitstellung bereit ist, sollte die Anwendung über VSH in der Produktion installiert werden. Auf diese Weise kann die Anwendung bei einem erneuten Laden des Geräts oder bei einem Systemwechsel in einem Szenario mit zwei Supervisoren beibehalten werden. Um eine Anwendung über VSH bereitzustellen, müssen Sie ein RPM-Paket mit einer NX-SDK- und ENXOS SDK-Buildumgebung erstellen. Cisco DevNet bietet ein Docker-Image, das die Erstellung von RPM-Paketen vereinfacht.
Hinweis: Wenn Sie Hilfe bei der Installation von Docker auf Ihrem Betriebssystem benötigen, lesen Sie die Installationsdokumentation von Docker.
Ziehen Sie auf einem Docker-fähigen Host die gewünschte Image-Version mit dem Befehl docker ull dockercisco/nxsdk:<tag> an, wobei <tag> das Tag der gewünschten Image-Version ist. Sie können die verfügbaren Bildversionen und die zugehörigen Tags hier anzeigen. Dies wird mit dem v1-Tag hier veranschaulicht:
docker pull dockercisco/nxsdk:v1
Starten Sie einen Container mit dem Namen nxsdk aus diesem Bild, und fügen Sie ihn an. Wenn das Tag Ihrer Wahl anders ist, ersetzen Sie v1 durch Ihr Tag:
docker run -it --name nxsdk dockercisco/nxsdk:v1 /bin/bash
Aktualisieren Sie auf die neueste Version von NX-SDK, navigieren Sie zum NX-SDK-Verzeichnis, und rufen Sie dann die neuesten Dateien von git ab:
cd /NX-SDK/
git pull
Wenn Sie eine ältere Version von NX-SDK verwenden möchten, können Sie die NX-SDK-Zweigstelle mit dem entsprechenden Version-Tag mit dem Git Clone -b v<version> https://github.com/CiscoDevNet/NX-SDK.git klonen, wobei <version> die gewünschte Version von NX-SDK ist. Dies wird hier mit NX-SDK v1.0.0 veranschaulicht:
cd /
rm -rf /NX-SDK
git clone -b v1.0.0 https://github.com/CiscoDevNet/NX-SDK.git
Übertragen Sie anschließend Ihre Python-Anwendung auf den Docker-Container. Dafür gibt es verschiedene Möglichkeiten.
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
Verwenden Sie anschließend das Skript rpm_gen.py in /NX-SDK/scripts/, um ein RPM-Paket aus der Python-Anwendung zu erstellen. Dieses Skript verfügt über ein erforderliches Argument und zwei erforderliche Switches:
Hinweis: Der Dateiname muss keine Dateierweiterungen wie .py enthalten. Wenn in diesem Beispiel der Dateiname python_app anstelle von python_app.py lautete, würde das RPM-Paket ohne Problem generiert.
Die Verwendung des Skripts rpm_gen.py wird hier demonstriert.
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
Der filepath zum RPM-Paket ist in der letzten Zeile der Ausgabe des Skripts rpm_gen.py angegeben. Diese Datei muss aus dem Docker-Container auf den Host kopiert werden, damit sie auf das Nexus-Gerät übertragen werden kann, auf dem die Anwendung ausgeführt werden soll. Nachdem Sie den Docker-Container verlassen haben, kann er mit dem Befehl docker cp <container>:<container_filepath> <host_filepath> durchgeführt werden, wobei <container> der Name des NX-SDK-Docker-Containers ist (in diesem Fall nxsdk), <container_filepath> der vollständige Pfad des RPM-Pakets im Container ist /NX-SDK/rpm/RPMS/test_python_app-1.0-1.0.0.x86_64.rpm) und <host_filepath> ist der vollständige Pfad auf unserem Docker-Host, auf den das RPM-Paket übertragen werden soll (in diesem Fall /root/). Dieser Befehl wird hier veranschaulicht:
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
Übertragen Sie dieses RPM-Paket auf das Nexus-Gerät unter Verwendung Ihrer bevorzugten Dateiübertragungsmethode. Sobald sich das RPM-Paket auf dem Gerät befindet, muss es ähnlich wie eine SMU installiert und aktiviert werden. Dies wird folgendermaßen gezeigt, unter der Annahme, dass das RPM-Paket auf den Bootflash des Geräts übertragen wurde.
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
Hinweis: Wenn Sie das RPM-Paket mit dem Befehl install add installieren, geben Sie das Speichergerät und den genauen Dateinamen des Pakets ein. Wenn Sie das RPM-Paket nach der Installation aktivieren, schließen Sie das Speichergerät und den Dateinamen nicht an - verwenden Sie den Namen des Pakets selbst. Sie können den Paketnamen mit dem Befehl show install inactive überprüfen.
Nachdem das RPM-Paket aktiviert wurde, können Sie die Anwendung mit NX-SDK mit dem nxsdk-Service <application-name>-Konfigurationsbefehl starten, wobei <application-name> der Name des Python-Dateinamens (und anschließend die Anwendung) ist, der definiert wurde, als rpm_gen.py-Skript früher verwendet wurde. Dies wird wie folgt gezeigt:
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
Sie können überprüfen, ob die Anwendung aktiv ist und mit dem Befehl show nxsdk internal service ausgeführt wurde:
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
Sie können auch überprüfen, ob die von dieser Anwendung erstellten benutzerdefinierten CLI-Befehle in NX-OS verfügbar sind:
N9K-C93180LC-EX# show test? test_python_app Nexus Sdk Application