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.
Es gibt keine spezifischen Anforderungen für dieses Dokument.
Die Informationen in diesem Dokument basierend auf folgenden Software- und Hardware-Versionen:
switch(config)# feature nxsdk
switch(config)# feature bash-shell
switch(config)# run bash
bash-4.2$ vi /isan/bin/nxsdk-app.py
Anmerkung: Es empfiehlt sich, Python-Dateien im Verzeichnis /isan/bin/zu erstellen. Python-Dateien benötigen Ausführungsberechtigungen, um ausgeführt zu werden - platzieren Sie Python-Dateien nicht im /bootflash-Verzeichnis oder in einem seiner Unterverzeichnisse.
Anmerkung: Es ist nicht erforderlich, Python-Dateien über NX-OS zu erstellen und zu bearbeiten. Der Entwickler kann die Anwendung in seiner lokalen Umgebung erstellen und die fertigen Dateien mithilfe eines Dateiübertragungsprotokolls seiner Wahl auf das Gerät übertragen. Für Entwickler ist es jedoch möglicherweise effizienter, ihr Skript mithilfe der NX-OS-Dienstprogramme zu debuggen und Fehler zu beheben.
sdkThread-Funktion
Anmerkung: Ab NX-SDK v1.5.0 kann ein dritter boolescher Parameter an die NxSdk.getSdkInst-Methode übergeben werden, die erweiterte Ausnahmen bei True aktiviert und erweiterte Ausnahmen bei False deaktiviert. Diese Methode ist hier dokumentiert.
Zu den gebräuchlichen Methoden gehören:
Anmerkung: 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 über eine Pipeline an das angeforderte Datenformat übergeben. Wenn der Piped-Befehl eine aussagekräftige Ausgabe zurückgibt, wird dieses Datenformat unterstützt. Wenn Sie beispielsweise show mac address-table dynamic | json in NX-OS gibt JSON-Ausgabe zurück, dann wird das R_JSON-Datenformat 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: Zeigt Befehle und Config-Befehle an.
Diese beiden Methoden ermöglichen die Erstellung von Befehlen show bzw. config:
Anmerkung: 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 Befehl intern im Die NX-SDK-Anwendung und die Syntax beschreiben, welche Schlüsselwörter und Parameter in dem Befehl verwendet werden können. Aus diesem Grund kann die API-Dokumentation für diesen Befehl hilfreicher sein.
Anmerkung: Dieser Befehl ist eine Unterklasse von cliP.newCliCmd("cmd_type", "cmd_name", "syntax") wobei cmd_type entweder CONF_CMD oder SHOW_CMD ist (abhängig vom konfigurierten Befehlstyp), cmd_name ein eindeutiger Name für den Befehl intern im In der benutzerdefinierten NX-SDK-Anwendung und der Syntax wird beschrieben, welche Schlüsselwörter und Parameter in dem Befehl verwendet werden können. Aus diesem Grund kann die API-Dokumentation für diesen Befehl hilfreicher sein.
Beide Befehlstypen haben zwei unterschiedliche Komponenten: Parameter und Schlüsselwörter:
1. Parameter sind Werte, die verwendet werden, um die Ergebnisse des Befehls zu ändern. 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. Dieser gibt an, dass nur Routen angezeigt werden sollen, die die angegebene IP-Adresse enthalten.
2. Schlüsselwörter ändern die Ergebnisse des Befehls allein durch ihre Präsenz. Im Befehl show mac address-table dynamic gibt es beispielsweise ein dynamic-Schlüsselwort, das angibt, dass nur dynamisch erlernte MAC-Adressen angezeigt werden sollen.
Beide Komponenten werden bei der Erstellung eines NX-SDK-Befehls in der Syntax definiert. Es sind Methoden für das NxCliCmd-Objekt vorhanden, um die spezifische Implementierung beider Komponenten zu ändern.
Codebeispiele häufig verwendeter Befehlskomponenten finden Sie im Abschnitt Beispiele für benutzerdefinierte CLI-Befehle dieses Dokuments.
Nach dem Erstellen benutzerdefinierter CLI-Befehle muss ein Objekt aus der weiter unten in diesem Dokument beschriebenen pyCmdHandler-Klasse erstellt und als CLI-Rückrufhandlerobjekt für das NxCliParser-Objekt festgelegt werden. Dies wird wie folgt demonstriert:
cmd_handler = pyCmdHandler()
cliP.setCmdHandler(cmd_handler)
Anschließend muss das NxCliParser-Objekt zur NX-OS CLI-Parserstruktur hinzugefügt werden, damit die benutzerdefinierten CLI-Befehle für den Benutzer sichtbar sind. Dies geschieht mit dem Befehl cliP.addToParseTree(), wobei cliP das von der sdk.getCliParser()-Methode zurückgegebene NxCliParser-Objekt ist.
sdkThread-Funktionsbeispiel
Hier ist ein Beispiel für eine typische sdkThread-Funktion unter Verwendung der zuvor erläuterten Funktionen. Diese Funktion (u. a. innerhalb einer typischen benutzerdefinierten NX-SDK Python-Anwendung) 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 innerhalb der nx_sdk_py-Bibliothek geerbt. Die in der pyCmdHandler-Klasse definierte postCliCb(self, clicmd)-Methode wird immer dann aufgerufen, wenn CLI-Befehle von einer NX-SDK-Anwendung stammen. Mit der postCliCb(self, clicmd)-Methode wird also definiert, 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 davon ausgegangen, 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 dem gleichen 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. Sie 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 werden Sie diese Parameter wahrscheinlich irgendwann in der postCliCb(self, clicmd) Funktion verwenden müssen. Dies kann mit der Methode clicmd.getParamValue("<parameter>") erfolgen, wobei <parameter> der Name des Befehlsparameters ist, für den der Wert in eckigen Klammern (<>) angegeben werden soll. Diese Methode ist hier dokumentiert. Der von dieser Funktion zurückgegebene Wert muss jedoch in den benötigten Typ konvertiert werden. Dies kann mithilfe der folgenden Methoden durchgeführt werden:
Die postCliCb(self, clicmd)-Funktion (oder alle nachfolgenden Funktionen) wird in der Regel auch dort angezeigt, wo die Ausgabe des Befehls show auf der Konsole ausgegeben wird. Dies geschieht mit der clicmd.printConsole() Methode.
Anmerkung: Wenn die Anwendung auf einen Fehler, eine nicht behandelte Ausnahme oder auf andere Weise plötzlich beendet wird, wird die Ausgabe der Funktion clicmd.printConsole() überhaupt nicht angezeigt. Aus diesem Grund empfiehlt es sich beim Debuggen der Python-Anwendung, entweder Debug-Meldungen mithilfe eines von der sdk.getTracer()-Methode zurückgegebenen NxTrace-Objekts im Syslog zu protokollieren, oder print-Anweisungen zu verwenden und die Anwendung über die Binärdatei /isan/bin/python 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. Der Zweck dieser Anwendung besteht darin, die Bewegung einer benutzerdefinierten IP-Adresse über die Schnittstellen eines Nexus-Geräts hinweg zu verfolgen. Hierzu findet der Code die MAC-Adresse der eingegebenen IP-Adresse über den Parameter <ip> im ARP-Cache des Geräts und verifiziert dann anhand der MAC-Adresstabelle des Geräts, in welchem VLAN diese MAC-Adresse gespeichert ist. Mithilfe dieser MAC- und VLAN-Adresse zeigt der Befehl show system internal l2fm l2dbg macdb address <mac> vlan <vlan> eine Liste der SNMP-Schnittstellenindizes an, mit denen diese Kombination kürzlich verknüpft wurde. Der Code verwendet dann den Befehl show interface snmp-ifindex, um die aktuellen SNMP-Schnittstellenindizes in für Benutzer 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 für Syntaxparameter veranschaulicht, die beim Erstellen benutzerdefinierter CLI-Befehle mit der cliP.newShowCmd() oder der cliP.newConfigCmd()-Methode verwendet werden, wobei cliP das vom sdk.getCliParser()-Methode.
Anmerkung: Die Unterstützung für Syntax mit öffnenden und schließenden Klammern ("(" und ")") wurde in NX-SDK v1.5.0 eingeführt und ist in NX-OS 7.0(3)I7(3) enthalten. Es wird davon ausgegangen, dass der Benutzer NX-SDK v1.5.0 verwendet, wenn er einem der folgenden Beispiele folgt, die Syntax mit öffnenden und schließenden Klammern enthalten.
Dieser Befehl show verwendet ein einzelnes Schlüsselwort mac und fügt dem Schlüsselwort eine Hilfszeichenfolge mit dem Namen Shows all misprogrammierte 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 nur einen Parameter <mac>. Die umschließenden Winkelklammern um das Wort mac zeigen an, dass es sich um einen Parameter handelt. Dem Parameter wird eine Hilfszeichenfolge mit MAC-Adressen hinzugefügt, die auf Fehlprogrammierung überprüft werden soll. Der Parameter nx_sdk_py.P_MAC_ADDR in der nx_cmd.updateParam()-Methode wird verwendet, um den Parametertyp als MAC-Adresse zu definieren, wodurch Endbenutzereingaben eines anderen Typs, z. B. einer Zeichenfolge, Ganzzahl oder 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] verwenden. Die umschließenden Klammern um das Wort mac zeigen an, dass dieses Schlüsselwort optional ist. Eine Hilfszeichenfolge von Zeigt alle falsch programmierten MAC-Adressen auf diesem Gerät an 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 einzelnen Parameter annehmen [<mac>]. Die umschließenden Klammern um das Wort < mac > bedeuten, dass dieser Parameter optional ist. Die umschließenden Winkelklammern um das Wort mac zeigen an, dass es sich um einen Parameter handelt. Dem Parameter wird eine Hilfszeichenfolge mit MAC-Adressen hinzugefügt, die auf Fehlprogrammierung überprüft werden soll. Der Parameter nx_sdk_py.P_MAC_ADDR in der nx_cmd.updateParam()-Methode wird verwendet, um den Parametertyp als MAC-Adresse zu definieren, wodurch Endbenutzereingaben eines anderen Typs, z. B. einer Zeichenfolge, Ganzzahl oder 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 ein einzelnes mac-Schlüsselwort unmittelbar gefolgt vom Parameter <mac-address>. Die umschließenden Winkelklammern um das Wort "mac-address" zeigen an, dass es sich um einen Parameter handelt. Dem Schlüsselwort wird eine Hilfszeichenfolge hinzugefügt, die die MAC-Adresse auf Fehlprogrammierung überprüft. Dem Parameter wird eine Hilfszeichenfolge mit MAC-Adressen hinzugefügt, die auf Fehlprogrammierung überprüft werden soll. Der Parameter nx_sdk_py.P_MAC_ADDR in der nx_cmd.updateParam()-Methode wird verwendet, um den Parametertyp als MAC-Adresse zu definieren, wodurch Endbenutzereingaben eines anderen Typs, z. B. einer Zeichenfolge, Ganzzahl oder IP-Adresse, verhindert werden.
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 unterschiedliche Parameter verfügen. Das erste Schlüsselwort "mac" hat den Parameter <mac-address>, und das zweite Schlüsselwort "ip" hat den Parameter <ip-address>. Die umschließenden spitzen Klammern um die Wörter mac-address und ip-address geben an, dass es sich um Parameter handelt. Eine Hilfszeichenfolge von MAC-Adresse auf Fehlprogrammierung überprüfen wird zum mac-Schlüsselwort hinzugefügt. Dem Parameter <mac-address> wird eine Hilfszeichenfolge der MAC-Adresse hinzugefügt, die auf Fehlprogrammierung überprüft. Der Parameter nx_sdk_py.P_MAC_ADDR 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, Ganzzahl oder IP-Adresse. Eine Hilfszeichenfolge von Check IP address for misprograming wird zum Schlüsselwort ip hinzugefügt. Dem <ip-address> Parameter wird eine Hilfszeichenfolge der IP-Adresse hinzugefügt, die auf Fehlprogrammierung überprüft werden soll. Der Parameter nx_sdk_py.P_IP_ADDR 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 Ganzzahl 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 unterschiedliche Parameter verfügen. Das erste Schlüsselwort "mac" hat den Parameter <mac-address>, und das zweite Schlüsselwort "ip" hat den Parameter <ip-address>. Die umschließenden spitzen Klammern um die Wörter mac-address und ip-address geben an, dass es sich um Parameter handelt. Eine Hilfszeichenfolge von MAC-Adresse auf Fehlprogrammierung überprüfen wird zum mac-Schlüsselwort hinzugefügt. Dem Parameter <mac-address> wird eine Hilfszeichenfolge der MAC-Adresse hinzugefügt, die auf Fehlprogrammierung überprüft. Der Parameter nx_sdk_py.P_MAC_ADDR 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, Ganzzahl oder IP-Adresse. Eine Hilfszeichenfolge von Check IP address for misprograming wird zum Schlüsselwort ip hinzugefügt. Dem <ip-address> Parameter wird eine Hilfszeichenfolge der IP-Adresse hinzugefügt, die auf Fehlprogrammierung überprüft werden soll. Der Parameter nx_sdk_py.P_IP_ADDR 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 Ganzzahl oder eine IP-Adresse. Dieser Befehl show kann optional das Schlüsselwort [clear] verwenden. Eine Hilfszeichenfolge Löscht Adressen, die als falsch programmiert erkannt wurden, wird zu diesem optionalen Schlüsselwort hinzugefügt.
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 unterschiedliche Parameter verfügen. Das erste Schlüsselwort "mac" hat den Parameter <mac-address>, und das zweite Schlüsselwort "ip" hat den Parameter <ip-address>. Die umschließenden spitzen Klammern um die Wörter mac-address und ip-address geben an, dass es sich um Parameter handelt. Eine Hilfszeichenfolge von Check MAC address for misprogrammingwird zum mac-Schlüsselwort hinzugefügt. Dem Parameter <mac-address> wird eine Hilfszeichenfolge der MAC-Adresse hinzugefügt, die auf Fehlprogrammierung überprüft. Der Parameter nx_sdk_py.P_MAC_ADDR 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, Ganzzahl oder IP-Adresse. Eine Hilfszeichenfolge von Check IP address for misprograming wird zum Schlüsselwort ip hinzugefügt. Dem <ip-address> Parameter wird eine Hilfszeichenfolge der IP-Adresse hinzugefügt, die auf Fehlprogrammierung überprüft werden soll. Der Parameter nx_sdk_py.P_IP_ADDR 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 Ganzzahl oder eine IP-Adresse. Dieser Befehl show kann optional einen Parameter annehmen [<Modul>]. Eine Hilfszeichenfolge Nur leere Adressen auf dem angegebenen Modul wird zu diesem optionalen Parameter hinzugefügt.
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, die Python NX-SDK-Bibliothek jedoch SWIG verwendet, um C++-Bibliotheken in Python-Bibliotheken zu übersetzen. Alle zum Zeitpunkt der Codeausführung aufgetretenen Ausnahmen führen zu einem Anwendungskern-Dump, ähnlich dem hier:
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 Mehrdeutigkeit dieser Fehlermeldung empfiehlt es sich, zum Debuggen von Python-Anwendungen Debug-Meldungen im Syslog mithilfe eines NxTrace-Objekts zu protokollieren, das von der sdk.getTracer()-Methode zurückgegeben wird. Dies wird wie folgt demonstriert:
#! /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, können Sie als Alternative print-Anweisungen verwenden und die Anwendung über die Binärdatei /isan/bin/python der Bash-Shell ausführen. Die Ausgabe dieser Druckanweisungen wird jedoch nur sichtbar, wenn sie auf diese Weise ausgeführt wird. Wenn die Anwendung über die VSH-Shell ausgeführt wird, wird keine Ausgabe erzeugt. Ein Beispiel für die Verwendung von Druckanweisungen finden Sie 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")
Sobald eine Python-Anwendung vollständig in der Bash-Shell getestet wurde und bereitgestellt werden kann, sollte sie über VSH in der Produktionsumgebung installiert werden. Auf diese Weise kann die Anwendung beim Neuladen des Geräts oder beim System-Switchover in einem Szenario mit zwei Supervisors beibehalten werden. Um eine Anwendung über VSH bereitzustellen, müssen Sie ein RPM-Paket unter Verwendung einer NX-SDK- und ENXOS-SDK-Buildumgebung erstellen. Cisco DevNet bietet ein Docker-Image, das die Erstellung von RPM-Paketen vereinfacht.
Anmerkung: Hilfe zur Installation von Docker auf Ihrem spezifischen Betriebssystem finden Sie in der Docker-Installationsdokumentation.
Ziehen Sie auf einem Docker-fähigen Host die gewünschte Image-Version mit dem Befehl docker pull dockercisco/nxsdk:<tag>, wobei <tag> das Tag der gewünschten Image-Version ist. Die verfügbaren Bildversionen und die dazugehörigen Tags können Sie hier einsehen. Dies wird mit dem Tag v1 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 sich das Tag Ihrer Wahl unterscheidet, 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, und navigieren Sie zum NX-SDK-Verzeichnis, und ziehen Sie dann die neuesten Dateien aus git:
cd /NX-SDK/
git pull
Wenn Sie eine ältere Version des NX-SDK verwenden müssen, können Sie den NX-SDK-Zweig mithilfe des jeweiligen Versionstags mit dem Befehl git clone -b v<version> https://github.com/CiscoDevNet/NX-SDK.git klonen, wobei <version> die gewünschte Version des NX-SDK ist. Dies wird hier mit NX-SDK v1.0.0 demonstriert:
cd /
rm -rf /NX-SDK
git clone -b v1.0.0 https://github.com/CiscoDevNet/NX-SDK.git
Als Nächstes übertragen Sie Ihre Python-Anwendung in den Docker-Container. Es gibt verschiedene Möglichkeiten, dies zu tun.
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 Schalter:
Anmerkung: Der Dateiname muss keine Dateierweiterungen wie .py enthalten. Wenn in diesem Beispiel der Dateiname python_app anstatt python_app.py lautet, wird das RPM-Paket ohne Probleme generiert.
Hier wird die Verwendung des Skripts rpm_gen.py dargestellt.
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 Dateipfad zum RPM-Paket wird in der letzten Zeile der Skriptausgabe 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, können Sie dies ganz einfach mit dem Befehl docker cp <container>:<container_filepath> <host_filepath> tun, wobei <container> der Name des NX-SDK Docker-Containers (in diesem Fall nxsdk) ist, <container_filepath> der vollständige Dateipfad des RPM-Pakets im Container (in diesem Fall: /NX-SDK/rpm/RPMS/test_python_app-1.0-1.0.0.x86_64.rpm) und <host_filepath> ist der vollständige Dateipfad auf unserem Docker-Host, an den das RPM-Paket übertragen werden soll (in diesem Fall: /root/Anm.). 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 mit der von Ihnen bevorzugten Dateiübertragungsmethode auf das Nexus-Gerät. Sobald sich das RPM-Paket auf dem Gerät befindet, muss es wie eine SMU installiert und aktiviert werden. Dies wird wie folgt demonstriert, unter der Annahme, dass das RPM-Paket in 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
Anmerkung: Wenn Sie das RPM-Paket mit dem Befehl install add installieren, geben Sie das Speichergerät und den genauen Dateinamen des Pakets an. Wenn Sie das RPM-Paket nach der Installation aktivieren, schließen Sie das Speichergerät und den Dateinamen nicht ein - verwenden Sie den Namen des Pakets selbst. Sie können den Paketnamen mit dem Befehl show install inactive überprüfen.
Sobald das RPM-Paket aktiviert ist, können Sie die Anwendung mit NX-SDK über den Konfigurationsbefehl nxsdk service <application-name> starten, wobei <application-name> der Name der Python-Datei (und später der Anwendung) ist, die bei der früheren Verwendung des Skripts rpm_gen.py definiert wurde. Dies wird wie folgt demonstriert:
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
Mit dem Befehl show nxsdk internal service (Interner Dienst anzeigen) können Sie überprüfen, ob die Anwendung gestartet ist und gestartet 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 in NX-OS auf die von dieser Anwendung erstellten benutzerdefinierten CLI-Befehle zugegriffen werden kann:
N9K-C93180LC-EX# show test? test_python_app Nexus Sdk Application
Feedback