El conjunto de documentos para este producto aspira al uso de un lenguaje no discriminatorio. A los fines de esta documentación, "no discriminatorio" se refiere al lenguaje que no implica discriminación por motivos de edad, discapacidad, género, identidad de raza, identidad étnica, orientación sexual, nivel socioeconómico e interseccionalidad. Puede haber excepciones en la documentación debido al lenguaje que se encuentra ya en las interfaces de usuario del software del producto, el lenguaje utilizado en función de la documentación de la RFP o el lenguaje utilizado por un producto de terceros al que se hace referencia. Obtenga más información sobre cómo Cisco utiliza el lenguaje inclusivo.
Cisco ha traducido este documento combinando la traducción automática y los recursos humanos a fin de ofrecer a nuestros usuarios en todo el mundo contenido en su propio idioma. Tenga en cuenta que incluso la mejor traducción automática podría no ser tan precisa como la proporcionada por un traductor profesional. Cisco Systems, Inc. no asume ninguna responsabilidad por la precisión de estas traducciones y recomienda remitirse siempre al documento original escrito en inglés (insertar vínculo URL).
No hay requisitos específicos para este documento.
La información que contiene este documento se basa en las siguientes versiones de software y hardware.
switch(config)# feature nxsdk
switch(config)# feature bash-shell
switch(config)# run bash
bash-4.2$ vi /isan/bin/nxsdk-app.py
Nota: La práctica recomendada es crear archivos Python en el /isan/bin/ directorio. Los archivos Python necesitan permisos de ejecución para ejecutarse - no coloque los archivos Python en el directorio /bootflash o en cualquiera de sus subdirectorios.
Nota: No es necesario crear y editar archivos Python a través de NX-OS. El desarrollador puede crear la aplicación utilizando su entorno local y transferir los archivos completados al dispositivo mediante un protocolo de transferencia de archivos de su elección. Sin embargo, puede ser más eficaz para el desarrollador depurar y resolver problemas de su secuencia de comandos mediante las utilidades NX-OS.
sdkThread (función)
Nota: A partir de NX-SDK v1.5.0, un tercer parámetro booleano se puede pasar al método NxSdk.getSdkInst, que habilita las excepciones avanzadas cuando es True y deshabilita las excepciones avanzadas cuando es False. Este método se documenta aquí .
Algunos de los métodos más utilizados son:
Nota: Los formatos de datos R_JSON y R_XML sólo funcionan si el comando admite resultados en esos formatos. En NX-OS, puede verificar si un comando admite resultados en un formato de datos determinado canalizando el resultado al formato de datos solicitado. Si el comando piped devuelve un resultado significativo, entonces se soporta ese formato de datos. Por ejemplo, si ejecuta show mac address-table dynamic | json en NX-OS devuelve el resultado de JSON y, a continuación, el formato de datos R_JSON también se admite en NX-SDK.
Algunos métodos opcionales que pueden resultar útiles son:
N9K-C93180LC-EX# show Tra?
track Tracking information
Transceiver_DOM.py Returns all interfaces with DOM-capable transceivers inserted
En una aplicación Python con el uso de NX-SDK, se crean y definen comandos CLI personalizados dentro de la función sdkThread. Hay dos tipos de comandos: Mostrar comandos y Configurar comandos.
Estos dos métodos permiten la creación de los comandos show y los comandos config respectivamente:
Nota: Este comando es una subclase de cliP.newCliCmd("cmd_type", "cmd_name", "sintaxis") donde cmd_type es CONF_CMD o SHOW_CMD (dependiendo del tipo de comando que se configure), cmd_nameSDK es un nombre único para el comando interno de la aplicación NX personalizada y sintaxis describe las palabras clave y los parámetros que se pueden utilizar en el comando. Debido a esto, la documentación de API para este comando podría ser más útil para la referencia.
Nota: Este comando es una subclase de cliP.newCliCmd("cmd_type", "cmd_name", "sintaxis") donde cmd_type es CONF_CMD o SHOW_CMD (depende del tipo de comando configurado), cmd_name es un nombre único para el comando interno del NX-NX-CMD personalizado y sintaxis describe las palabras clave y los parámetros que se pueden utilizar en el comando. Debido a esto, la documentación de API para este comando podría ser más útil para la referencia.
Ambos tipos de comandos tienen dos componentes diferentes: Parámetros y palabras clave:
1. Los parámetros son valores utilizados para cambiar los resultados del comando. Por ejemplo, en el comando show ip route 192.168.1.0, hay una palabra clave route seguida de un parámetro que acepta una dirección IP, que especifica que sólo se deben mostrar las rutas que incluyen la dirección IP proporcionada.
2. Las palabras clave cambian los resultados del comando sólo a través de su presencia. Por ejemplo, en el comando show mac address-table dynamic, hay una palabra clave dynamic, que especifica que sólo se mostrarán las direcciones MAC aprendidas dinámicamente.
Ambos componentes se definen en la sintaxis de un comando NX-SDK cuando se crea. Existen métodos para que el objeto NxCliCmd modifique la implementación específica de ambos componentes.
Para ver ejemplos de código de los componentes de comandos más utilizados, vea la sección Ejemplos de Comandos de CLI Personalizados de este documento.
Una vez creados los comandos CLI personalizados, se debe crear un objeto de la clase pyCmdHandler descrita más adelante en este documento y configurarlo como el objeto controlador de devolución de llamada CLI para el objeto NxCliParser. Esto se demuestra de la siguiente manera:
cmd_handler = pyCmdHandler()
cliP.setCmdHandler(cmd_handler)
A continuación, el objeto NxCliParser debe agregarse al árbol de analizador de CLI de NX-OS para que el usuario pueda ver los comandos de CLI personalizados. Esto se realiza con el comando cliP.addToParseTree(), donde cliP es el objeto NxCliParser devuelto por el método sdk.getCliParser().
Ejemplo de la Función sdkThread
A continuación se muestra un ejemplo de una función sdkThread típica con el uso de las funciones explicadas anteriormente. Esta función (entre otras, en una aplicación personalizada típica de NX-SDK Python) utiliza variables globales, que se crean instancias de la ejecución de secuencias de comandos.
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 clase pyCmdHandler se hereda de la clase NxCmdHandler dentro de la biblioteca nx_sdk_py. El método postCliCb(self, climd) definido en la clase pyCmdHandler se llama siempre que se originan comandos CLI de una aplicación NX-SDK. Por lo tanto, el método postCliCb(self, climd) es donde se define el comportamiento de los comandos CLI personalizados definidos en la función sdkThread en el dispositivo.
La función postCliCb(self, clmd) devuelve un valor booleano. Si se devuelve True, se presume que el comando se ha ejecutado correctamente. False debe devolverse si el comando no se ejecutó correctamente por ninguna razón.
El parámetro climd utiliza el nombre único definido para el comando cuando se creó en la función sdkThread. Por ejemplo, si crea un nuevo comando show con un nombre único de show_xcvr_dom, se recomienda hacer referencia a este comando con el mismo nombre en la función postCliCb(self, climd) después de verificar si el nombre del argumento clmd contiene show_xcvr_dom. Se demuestra aquí:
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 se crea un comando que utiliza parámetros, es muy probable que necesite utilizar esos parámetros en algún momento de la función postCliCb(self, climd). Esto se puede hacer con el método climd.getParamValue("<parámetro>"), donde <parámetro> es el nombre del parámetro de comando que desea obtener el valor de entre corchetes angulares (<>). Este método se documenta aquí. Sin embargo, el valor devuelto por esta función debe convertirse al tipo que necesita. Esto se puede hacer con estos métodos:
La función postCliCb(self, clmd) (o cualquier función subsiguiente) también será normalmente la que se imprima el resultado del comando show en la consola. Esto se realiza con el método clmd.printConsole().
Nota: Si la aplicación encuentra un error, una excepción no controlada o de algún otro modo sale repentinamente, el resultado de la función clmd.printConsole() no se mostrará en absoluto. Por esta razón, la mejor práctica al depurar su aplicación de Python es registrar los mensajes de depuración en el syslog con el uso de un objeto NxTrace devuelto por el método sdk.getTracer(), o utilizar instrucciones de impresión y ejecutar la aplicación a través del /isan/bin/python binario del shell Bash.
Ejemplo de Clase pyCmdHandler
El código siguiente sirve como ejemplo para la clase pyCmdHandler descrita anteriormente. Este código se toma del archivo ip_motion.py de la aplicación ip-motion NX-SDK disponible aquí. El propósito de esta aplicación es realizar un seguimiento del movimiento de una dirección IP definida por el usuario a través de las interfaces de un dispositivo Nexus. Para hacerlo, el código encuentra la dirección MAC de la entrada de dirección IP a través del parámetro <ip> dentro de la memoria caché ARP del dispositivo, luego verifica en qué VLAN reside esa dirección MAC usando la tabla de direcciones MAC del dispositivo. Con este MAC y VLAN, el comando show system internal l2fm l2dbg macdb address <mac> vlan <vlan> muestra una lista de índices de interfaz SNMP con los que esta combinación se ha asociado recientemente. El código luego utiliza el comando show interface snmp-ifindex para traducir los índices de interfaz SNMP recientes a nombres de interfaz legibles por humanos.
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
Esta sección muestra algunos ejemplos del parámetro de sintaxis utilizado cuando se crean comandos CLI personalizados con los métodos cliP.newShowCmd() o cliP.newConfigCmd(), donde cliP es el objeto NxCliParser devuelto por el método sdk.getCliParser().
Nota: La compatibilidad con la sintaxis con los paréntesis de apertura y cierre ("(" y ")") se introduce en NX-SDK v1.5.0, incluida en NX-OS versión 7.0(3)I7(3). Se supone que el usuario utiliza NX-SDK v1.5.0 cuando sigue cualquiera de estos ejemplos dados que incluyen sintaxis utilizando paréntesis de apertura y cierre.
Este comando show toma una sola palabra clave mac y agrega una cadena de ayuda de Shows all misprogramado MAC Addresses en este dispositivo a la palabra clave.
nx_cmd = cliP.newShowCmd("show_misprogrammed", "mac")
nx_cmd.updateKeyword("mac", "Shows all misprogrammed MAC addresses on this device")
Este comando show toma un único parámetro <mac>. Los corchetes angulares que rodean la palabra mac significan que se trata de un parámetro. Se agrega al parámetro una cadena auxiliar de dirección MAC para comprobar si hay programación incorrecta. El parámetro nx_sdk_py.P_MAC_ADDR del método nx_cmd.updateParam() se utiliza para definir el tipo del parámetro como una dirección MAC, que impide que el usuario final introduzca otro tipo, como una cadena, un número entero o una dirección 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)
Este comando show puede opcionalmente tomar una sola palabra clave [mac]. Los corchetes de cierre alrededor de la palabra mac significan que esta palabra clave es opcional. Una cadena de ayuda de Muestra todas las direcciones MAC mal programadas en este dispositivo se agrega a la palabra clave.
nx_cmd = cliP.newShowCmd( "show_misprogrammed_mac" , "[mac]" )
nx_cmd.updateKeyword( "mac" , "Shows all misprogrammed MAC addresses on this device" )
Este comando show puede opcionalmente tomar un único parámetro [<mac>]. Los corchetes de cierre alrededor de la palabra < mac > significan que este parámetro es opcional. Los corchetes angulares que rodean la palabra mac significan que se trata de un parámetro. Se agrega al parámetro una cadena auxiliar de dirección MAC para comprobar si hay programación incorrecta. El parámetro nx_sdk_py.P_MAC_ADDR del método nx_cmd.updateParam() se utiliza para definir el tipo del parámetro como una dirección MAC, que impide que el usuario final introduzca otro tipo, como una cadena, un número entero o una dirección 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)
Este comando show toma una sola palabra clave mac seguida inmediatamente por el parámetro <mac-address>. Los corchetes angulares que rodean la palabra mac-address significan que se trata de un parámetro. Se agrega a la palabra clave una cadena auxiliar de verificación de dirección MAC para la programación incorrecta. Se agrega al parámetro una cadena auxiliar de dirección MAC para comprobar si hay programación incorrecta. El parámetro nx_sdk_py.P_MAC_ADDR del método nx_cmd.updateParam() se utiliza para definir el tipo del parámetro como dirección MAC, que impide la entrada de otro tipo por parte del usuario final, como una cadena, un número entero o una dirección 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)
Este comando show puede tomar una de dos palabras clave, ambas con dos parámetros diferentes a continuación. La primera palabra clave mac tiene un parámetro de <mac-address> , y la segunda palabra clave ip tiene un parámetro de <ip-address>. Los corchetes angulares de las palabras mac-address e ip-address significan que son parámetros. Se agrega una cadena auxiliar de verificación de dirección MAC para la mala programación a la palabra clave mac. Se agrega una cadena auxiliar de dirección MAC para comprobar si hay programación incorrecta al parámetro <mac-address>. El parámetro nx_sdk_py.P_MAC_ADDR del método nx_cmd.updateParam() se utiliza para definir el tipo del parámetro <mac-address> como dirección MAC, que impide la entrada de otro tipo por parte del usuario final, como una cadena, un número entero o una dirección IP. Se agrega una cadena de ayuda de Verificar la dirección IP para la mala programación a la palabra clave ip. Se agrega una cadena auxiliar de dirección IP para comprobar si hay programación incorrecta al parámetro <ip-address>. El parámetro nx_sdk_py.P_IP_ADDR del método nx_cmd.updateParam() se utiliza para definir el tipo del parámetro <ip-address> como dirección IP, que impide la entrada de otro tipo por parte del usuario final, como una cadena, un número entero o una dirección 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)
Este comando show puede tomar una de dos palabras clave, ambas con dos parámetros diferentes a continuación. La primera palabra clave mac tiene un parámetro de <mac-address>, y la segunda palabra clave ip tiene un parámetro de <ip-address>. Los corchetes angulares de las palabras mac-address e ip-address significan que son parámetros. Se agrega una cadena auxiliar de verificación de dirección MAC para la mala programación a la palabra clave mac. Se agrega una cadena auxiliar de dirección MAC para comprobar si hay programación incorrecta al parámetro <mac-address>. El parámetro nx_sdk_py.P_MAC_ADDR del método nx_cmd.updateParam() se utiliza para definir el tipo del parámetro <mac-address> como dirección MAC, que impide la entrada de otro tipo por parte del usuario final, como una cadena, un número entero o una dirección IP. Se agrega una cadena de ayuda de Verificar la dirección IP para la mala programación a la palabra clave ip. Se agrega una cadena auxiliar de dirección IP para comprobar si hay programación incorrecta al parámetro <ip-address>. El parámetro nx_sdk_py.P_IP_ADDR del método nx_cmd.updateParam() se utiliza para definir el tipo del parámetro <ip-address> como dirección IP, que impide la entrada de otro tipo por parte del usuario final, como una cadena, un número entero o una dirección IP. Este comando show opcionalmente podría tomar una palabra clave [clear]. Una cadena de ayuda Borra las direcciones detectadas como mal programadas se agrega a esta palabra clave opcional.
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")
Este comando show puede tomar una de dos palabras clave, ambas con dos parámetros diferentes a continuación. La primera palabra clave mac tiene un parámetro de <mac-address>, y la segunda palabra clave ip tiene un parámetro de <ip-address>. Los corchetes angulares de las palabras mac-address e ip-address significan que son parámetros. Se agrega una cadena auxiliar de verificación de dirección MAC para errores de programación a la palabra clave mac. Se agrega una cadena auxiliar de dirección MAC para comprobar si hay programación incorrecta al parámetro <mac-address>. El parámetro nx_sdk_py.P_MAC_ADDR del método nx_cmd.updateParam() se utiliza para definir el tipo del parámetro <mac-address> como dirección MAC, que impide la entrada de otro tipo por parte del usuario final, como una cadena, un número entero o una dirección IP. Se agrega una cadena de ayuda de Verificar la dirección IP para la mala programación a la palabra clave ip. Se agrega una cadena auxiliar de dirección IP para comprobar si hay programación incorrecta al parámetro <ip-address>. El parámetro nx_sdk_py.P_IP_ADDR del método nx_cmd.updateParam() se utiliza para definir el tipo del parámetro <ip-address> como dirección IP, que impide la entrada de otro tipo por parte del usuario final, como una cadena, un número entero o una dirección IP. Este comando show puede tomar opcionalmente un parámetro [<module>]. Una cadena de ayuda Sólo se agregan direcciones despejadas en el módulo especificado a este parámetro opcional.
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)
Una vez creada una aplicación NX-SDK Python, a menudo tendrá que depurarse. NX-SDK le informa en caso de que haya errores de sintaxis en el código, pero como la biblioteca Python NX-SDK utiliza SWIG para traducir bibliotecas de C++ a bibliotecas de Python, cualquier excepción encontrada en el momento de la ejecución del código da como resultado un vaciado de memoria de la aplicación similar a este:
terminate called after throwing an instance of 'Swig::DirectorMethodException'
what(): SWIG director method error. Error detected when calling 'NxCmdHandler.postCliCb'
Aborted (core dumped)
Debido a la naturaleza ambigua de este mensaje de error, la mejor práctica para depurar aplicaciones Python es registrar mensajes de depuración en el syslog con el uso de un objeto NxTrace devuelto por el método sdk.getTracer(). Esto se demuestra de la siguiente manera:
#! /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 el registro de los mensajes de depuración en el syslog no es una opción, un método alternativo es utilizar sentencias de impresión y ejecutar la aplicación a través del binario /isan/bin/python del shell Bash. Sin embargo, el resultado de estas instrucciones de impresión sólo será visible cuando se ejecute de esta manera; ejecutar la aplicación a través del shell de VSH no produce ningún resultado. A continuación se muestra un ejemplo de uso de instrucciones de impresión:
#! /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")
Una vez que una aplicación de Python se ha probado completamente en el shell de Bash y está lista para su implementación, la aplicación debe instalarse en producción a través de VSH. Esto permite que la aplicación persista cuando el dispositivo se recarga o cuando se produce el switchover del sistema en un escenario de supervisor dual. Para implementar una aplicación a través de VSH, necesita crear un paquete RPM con el uso de un entorno de compilación NX-SDK y ENXOS SDK. Cisco DevNet proporciona una imagen de Docker que permite una fácil creación de paquetes RPM.
Nota: Para obtener ayuda para instalar Docker en su sistema operativo específico, consulte la documentación de instalación de Docker.
En un host compatible con Docker, tire de la versión de imagen que elija con el comando docker pull dockercisco/nxsdk:<tag> donde <tag> es la etiqueta de la versión de imagen que elija. Puede ver las versiones de imagen disponibles y sus etiquetas correspondientes aquí. Esto se demuestra con la etiqueta v1 aquí:
docker pull dockercisco/nxsdk:v1
Inicie un contenedor denominado nxsdk desde esta imagen y adáptelo. Si la etiqueta de su elección es diferente, sustituya v1 por su etiqueta:
docker run -it --name nxsdk dockercisco/nxsdk:v1 /bin/bash
Actualice a la última versión de NX-SDK y navegue hasta el directorio NX-SDK y, a continuación, extraiga los archivos más recientes de git:
cd /NX-SDK/
git pull
Si necesita utilizar una versión anterior de NX-SDK, puede clonar la rama de NX-SDK con la etiqueta de versión respectiva con el comando git clone -b v<version> https://github.com/CiscoDevNet/NX-SDK.git, donde <version> es la versión de NX-SDK que necesita. Esto se demuestra aquí con NX-SDK v1.0.0:
cd /
rm -rf /NX-SDK
git clone -b v1.0.0 https://github.com/CiscoDevNet/NX-SDK.git
A continuación, transfiera la aplicación Python al contenedor Docker. Hay algunas maneras diferentes de hacerlo.
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
A continuación, utilice el script rpm_gen.py ubicado en /NX-SDK/scripts/ para crear un paquete RPM desde la aplicación Python. Este script tiene un argumento obligatorio y dos switches necesarios:
Nota: El nombre de archivo no necesita contener ninguna extensión de archivo, como .py. En este ejemplo, si el nombre de archivo era python_app en lugar de python_app.py, el paquete RPM se generaría sin problema.
El uso del script rpm_gen.py se muestra aquí.
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
La trayectoria de archivo al paquete RPM se indica en la línea final de la salida del script rpm_gen.py. Este archivo debe copiarse del contenedor Docker en el host para que pueda transferirse al dispositivo Nexus en el que desea ejecutar la aplicación. Después de salir del contenedor de Docker, se puede hacer fácilmente con el comando docker cp <container>:<container_filepath> <host_filepath>, donde <container> es el nombre del contenedor de Docker de NX-SDK (en este caso, nxsdk), <container_filepath> es la ruta de archivo completa del paquete RPM dentro del contenedor (en este caso, /NX-SDK /rpm/RPMS/test_python_app-1.0-1.0.x86_64.rpm), y <host_filepath> es la ruta de archivo completa en nuestro host Docker donde se va a transferir el paquete RPM a (en este caso, /root/). Este comando se muestra aquí:
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
Transfiera este paquete RPM al dispositivo Nexus con el uso de su método preferido de transferencia de archivos. Una vez que el paquete RPM se encuentra en el dispositivo, se debe instalar y activar de forma similar a una SMU. Esto se demuestra de la siguiente manera, bajo la suposición de que el paquete RPM fue transferido a la memoria flash de inicialización del dispositivo.
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
Nota: Cuando instale el paquete RPM con el comando install add, incluya el dispositivo de almacenamiento y el nombre de archivo exacto del paquete. Cuando active el paquete RPM después de la instalación, no incluya el dispositivo de almacenamiento ni el nombre de archivo - utilice el nombre del paquete en sí. Puede verificar el nombre del paquete con el comando show install idle.
Una vez que se activa el paquete RPM, puede iniciar la aplicación con NX-SDK con el comando de configuración nxsdk service <application-name>, donde <application-name> es el nombre del nombre de archivo de Python (y, posteriormente, la aplicación) que se definió cuando se utilizó anteriormente la secuencia de comandos rpm_gen.py. Esto se demuestra de la siguiente manera:
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
Puede verificar que la aplicación esté activa y que haya comenzado a ejecutarse con el comando 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
También puede verificar que los comandos CLI personalizados creados por esta aplicación estén accesibles en NX-OS:
N9K-C93180LC-EX# show test? test_python_app Nexus Sdk Application