この製品のドキュメントセットは、偏向のない言語を使用するように配慮されています。このドキュメントセットでの偏向のない言語とは、年齢、障害、性別、人種的アイデンティティ、民族的アイデンティティ、性的指向、社会経済的地位、およびインターセクショナリティに基づく差別を意味しない言語として定義されています。製品ソフトウェアのユーザインターフェイスにハードコードされている言語、RFP のドキュメントに基づいて使用されている言語、または参照されているサードパーティ製品で使用されている言語によりドキュメントに例外が存在する場合があります。シスコのインクルーシブ ランゲージの取り組みの詳細は、こちらをご覧ください。
シスコは世界中のユーザにそれぞれの言語でサポート コンテンツを提供するために、機械と人による翻訳を組み合わせて、本ドキュメントを翻訳しています。ただし、最高度の機械翻訳であっても、専門家による翻訳のような正確性は確保されません。シスコは、これら翻訳の正確性について法的責任を負いません。原典である英語版(リンクからアクセス可能)もあわせて参照することを推奨します。
このドキュメントに関する固有の要件はありません。
このドキュメントの情報は、次のソフトウェアとハードウェアのバージョンに基づいています。
switch(config)# feature nxsdk
switch(config)# feature bash-shell
switch(config)# run bash
bash-4.2$ vi /isan/bin/nxsdk-app.py
注:ベストプラクティスは、/isan/bin/ディレクトリにPythonファイルを作成することです。Pythonファイルを実行するには、実行パーミッションが必要です。Pythonファイルを/bootflashディレクトリまたはそのサブディレクトリに置かないでください。
注:NX-OSでPythonファイルを作成および編集する必要はありません。開発者は、ローカル環境を使用してアプリケーションを作成し、任意のファイル転送プロトコルを使用して完成したファイルをデバイスに転送できます。ただし、開発者がNX-OSユーティリティを使用してスクリプトをデバッグおよびトラブルシューティングする方が効率的な場合があります。
sdkThread関数
注:NX-SDK v1.5.0以降では、3つ目のブール型パラメータをNxSdk.getSdkInstメソッドに渡せるようになりました。このメソッドでは、Trueの場合に高度な例外が有効になり、Falseの場合に高度な例外が無効になります。この方法については、ここを参照してください。
一般的に使用される方法には、次のものがあります。
注:R_JSONおよびR_XMLデータ形式は、コマンドがこれらの形式の出力をサポートしている場合にのみ機能します。NX-OSでは、コマンドが特定のデータ形式の出力をサポートしているかどうかを、出力を要求されたデータ形式にパイプすることで確認できます。pipedコマンドが意味のある出力を返す場合、そのデータ形式がサポートされています。たとえば、NX-OSでshow mac address-table dynamic | jsonを実行してJSON出力を返す場合、NX-SDKでもR_JSONデータ形式がサポートされます。
次のようなオプションの方法が役立ちます。
N9K-C93180LC-EX# show Tra?
track Tracking information
Transceiver_DOM.py Returns all interfaces with DOM-capable transceivers inserted
NX-SDKを使用するPythonアプリケーションでは、カスタムCLIコマンドが作成され、sdkThread関数内で定義されます。コマンドには、ShowコマンドとConfigコマンドの2種類があります。
次の2つの方法で、それぞれshowコマンドとconfigコマンドを作成できます。
注:このコマンドはcliP.newCliCmd("cmd_type", "cmd_name", "syntax")のサブクラスです。cmd_typeはCONF_CMDまたはSHOW_CMD(設定されているコマンドのタイプに応じて)のいずれかです。cmd_nameはカスタムNX-SDKアプリケーションの内部コマンドの一意の名前です。syntaxにはコマンドで使用できるキーワードととパラメータを示します。このため、参照用にこのコマンドのAPIドキュメントがより役立つ場合があります。
注:このコマンドはcliP.newCliCmd("cmd_type", "cmd_name", "syntax")のサブクラスです。cmd_typeはCONF_CMDまたはSHOW_CMD(設定されているコマンドのタイプによって異なります)、cmd_nameはカスタムNX-SDKアプリケーションの内部コマンドの一意の名前、およびコマンドで使用できるキーワードとパラメータを説明します。このため、参照用にこのコマンドのAPIドキュメントがより役立つ場合があります。
どちらのタイプのコマンドにも、パラメータとキーワードという2つの異なるコンポーネントがあります。
1. パラメータは、コマンドの結果を変更するために使用される値です。たとえば、コマンドshow ip route 192.168.1.0には、IPアドレスを受け入れるパラメータがrouteキーワードの後に続いており、指定されたIPアドレスを含むルートのみが表示されるように指定されています。
2. キーワードは、指定されたキーワードが存在する場合にのみコマンドの結果を変更します。たとえば、show mac address-table dynamicコマンドには、動的に学習したMACアドレスだけを表示するように指定するdynamicキーワードがあります。
どちらのコンポーネントも、作成時にNX-SDKコマンドの構文で定義されます。NxCliCmdオブジェクトのメソッドは、両方のコンポーネントの特定の実装を変更するために存在します。
一般的に使用されるコマンドコンポーネントのコード例を表示するには、このドキュメントの「カスタムCLIコマンドの例」セクションを参照してください。
カスタムCLIコマンドを作成した後、このドキュメントで後述されているpyCmdHandlerクラスのオブジェクトを作成し、NxCliParserオブジェクトのCLIコールバックハンドラオブジェクトとして設定する必要があります。これは、次のように示されます。
cmd_handler = pyCmdHandler()
cliP.setCmdHandler(cmd_handler)
次に、カスタムCLIコマンドがユーザに表示されるように、NxCliParserオブジェクトをNX-OS CLIパーサーツリーに追加する必要があります。これは、cliP.addToParseTree()コマンドで実行されます。ここで、cliPは、sdk.getCliParser()メソッドから返されるNxCliParserオブジェクトです。
sdkThread関数の例
以下に、前述の関数を使用した典型的なsdkThread関数の例を示します。この関数(一般的なカスタムNX-SDK Pythonアプリケーション内の他の関数)は、スクリプトの実行時にインスタンス化されるグローバル変数を使用します。
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)
pyCmdHandlerクラスは、nx_sdk_pyライブラリ内のNxCmdHandlerクラスから継承されます。pyCmdHandlerクラス内で定義されたpostCliCb(self, clicmd)メソッドは、NX-SDKアプリケーションから発信されるCLIコマンドのたびに呼び出されます。したがって、postCliCb(self, clicmd)メソッドでは、sdkThread関数内で定義されたカスタムCLIコマンドがデバイスでどのように動作するかを定義します。
postCliCb(self, clicmd)関数はブール値を返します。Trueが返された場合は、コマンドが正常に実行されたことを想定しています。何らかの理由でコマンドが正常に実行されなかった場合は、Falseが返されます。
clicmdパラメータでは、sdkThread関数で作成されたときにコマンドに定義された一意の名前が使用されます。たとえば、show_xcvr_domという一意の名前で新しいshowコマンドを作成する場合、引数clicmdの名前にshow_xcvr_domが含まれているかどうかを確認した後、postCliCb(self, clicmd)関数で同じ名前でこのコマンドを参照することをお勧めします。次に例を示します。
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()
パラメータを使用するコマンドを作成する場合、通常はpostCliCb(self, clicmd)関数内のどこかでこれらのパラメータを使用する必要があります。これは、clicmd.getParamValue("<parameter>")メソッドで実行できます。ここで、<parameter>は山カッコ(<>)で囲まれた値を取得するコマンドパラメータの名前です。 この方法については、ここを参照してください。ただし、この関数が返す値は、必要な型に変換する必要があります。これは、次の方法で実行できます。
postCliCb(self, clicmd)関数(または後続の関数)も、通常はshowコマンドの出力がコンソールに表示される場所になります。これはclicmd.printConsole()メソッドで行います。
注:アプリケーションでエラーが発生した場合、処理されない例外が発生した場合、またはその他の理由で突然終了した場合は、clicmd.printConsole()関数の出力はまったく表示されません。このため、Pythonアプリケーションをデバッグする場合のベストプラクティスは、sdk.getTracer()メソッドから返されたNxTraceオブジェクトを使用してデバッグメッセージをsyslogに記録するか、またはprintステートメントを使用してBashシェルの/isan/bin/pythonバイナリによってアプリケーションを実行することです。
pyCmdHandlerクラスの例
次のコードは、前述のpyCmdHandlerクラスの例です。このコードは、ip-movement NX-SDKアプリケーション(ここから入手可能)のip_move.pyファイルから取得されます。このアプリケーションの目的は、Nexusデバイスのインターフェイス間でのユーザ定義のIPアドレスの移動を追跡することです。これを行うために、コードはデバイスのARPキャッシュ内の<ip>パラメータを介して入力されたIPアドレスのMACアドレスを見つけ、そのMACアドレスが存在するVLANをデバイスのMACアドレステーブルを使用して確認します。このMACとVLANを使用して、show system internal l2fm l2dbg macdb address <mac> vlan <vlan>コマンドを実行すると、この組み合せが最近関連付けられたSNMPインターフェイスインデックスのリストが表示されます。次に、コードはshow interface snmp-ifindexコマンドを使用して、最新のSNMPインターフェイスインデックスを人間が判読できるインターフェイス名に変換します。
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
このセクションでは、cliP.newShowCmd()メソッドまたはcliP.newConfigCmd()メソッドを使用してカスタムCLIコマンドを作成するときに使用する構文パラメータの例をいくつか紹介します。cliPは、sdk.getCliParser()メソッドによって返されるNxCliParserオブジェクトです。
注:NX-OSリリース7.0(3)I7(3)に含まれるNX-SDK v1.5.0では、開きカッコと閉じカッコを含む構文(「(」と「)」)がサポートされています。 ユーザが、開きカッコと閉じカッコを使用した構文を含むこれらの例のいずれかに従う場合は、NX-SDK v1.5.0を使用することを前提としています。
このshowコマンドは、1つのキーワードmacを受け取り、このデバイス上で誤ってプログラムされたすべてのMACアドレスを表示するのヘルパーストリングをこのキーワードに追加します。
nx_cmd = cliP.newShowCmd("show_misprogrammed", "mac")
nx_cmd.updateKeyword("mac", "Shows all misprogrammed MAC addresses on this device")
このshowコマンドは単一のパラメータ<mac>をとります。単語macを囲む山カッコは、これがパラメータであることを示します。ミスプログラミングをチェックするためのMACアドレスのヘルパーストリングがパラメータに追加されます。nx_cmd.updateParam()メソッドのnx_sdk_py.P_MAC_ADDRパラメータは、パラメータのタイプをMACアドレスとして定義するために使用されます。これにより、エンドユーザは文字列、整数、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)
このshowコマンドは、オプションで1つのキーワード[mac]を使用できます。単語macを囲むカッコは、このキーワードがオプションであることを示します。「このデバイス上の誤ってプログラムされたMACアドレスをすべて表示する」という文字列がキーワードに追加されます。
nx_cmd = cliP.newShowCmd( "show_misprogrammed_mac" , "[mac]" )
nx_cmd.updateKeyword( "mac" , "Shows all misprogrammed MAC addresses on this device" )
このshowコマンドは、オプションで1つのパラメータ[<mac>]を取得できます。< mac >という語を囲むカッコは、このパラメータがオプションであることを示します。単語macを囲む山カッコは、これがパラメータであることを示します。ミスプログラミングをチェックするためのMACアドレスのヘルパーストリングがパラメータに追加されます。nx_cmd.updateParam()メソッドのnx_sdk_py.P_MAC_ADDRパラメータは、パラメータのタイプをMACアドレスとして定義するために使用されます。これにより、エンドユーザは文字列、整数、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)
このshowコマンドは、1つのキーワードmacとそれに続くパラメータ<mac-address>を受け取ります。単語mac-addressを囲む山カッコは、これがパラメータであることを示しています。Check MAC address for misprogrammingのヘルパーストリングがキーワードに追加されます。ミスプログラミングをチェックするためのMACアドレスのヘルパーストリングがパラメータに追加されます。nx_cmd.updateParam()メソッドのnx_sdk_py.P_MAC_ADDRパラメータは、パラメータのタイプをMACアドレスとして定義するために使用されます。これにより、エンドユーザは文字列、整数、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)
このshowコマンドは2つのキーワードのいずれかを使用でき、どちらのキーワードも2つの異なるパラメータを持ちます。最初のキーワードmacのパラメータは<mac-address>で、2番目のキーワードipのパラメータは<ip-address>です。単語mac-addressとip-addressを囲む山カッコは、それらがパラメータであることを示しています。Macキーワードに「Check MAC address for misprogramming」というヘルパーストリングが追加されます。<mac-address>パラメータに、ミスプログラミングをチェックするためのMACアドレスのヘルパーストリングが追加されました。nx_cmd.updateParam()メソッドのnx_sdk_py.P_MAC_ADDRパラメータは、<mac-address>パラメータのタイプをMACアドレスとして定義するために使用されます。これにより、エンドユーザは文字列、整数、IPアドレスなどの別のタイプを入力できなくなります。ipキーワードに「Check IP address for misprograming」というヘルパーストリングが追加されます。ミスプログラミングをチェックするためのIPアドレスのヘルパーストリングが<ip-address>パラメータに追加されます。nx_cmd.updateParam()メソッドのnx_sdk_py.P_IP_ADDRパラメータは、<ip-address>パラメータのタイプをIPアドレスとして定義するために使用されます。これにより、エンドユーザは文字列、整数、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)
このshowコマンドは2つのキーワードのいずれかを使用でき、どちらのキーワードも2つの異なるパラメータを持ちます。最初のキーワードmacのパラメータは<mac-address>で、2番目のキーワードipのパラメータは<ip-address>です。単語mac-addressとip-addressを囲む山カッコは、それらがパラメータであることを示しています。Macキーワードに「Check MAC address for misprogramming」というヘルパーストリングが追加されます。<mac-address>パラメータに、ミスプログラミングをチェックするためのMACアドレスのヘルパーストリングが追加されました。nx_cmd.updateParam()メソッドのnx_sdk_py.P_MAC_ADDRパラメータは、<mac-address>パラメータのタイプをMACアドレスとして定義するために使用されます。これにより、エンドユーザは文字列、整数、IPアドレスなどの別のタイプを入力できなくなります。ipキーワードに「Check IP address for misprograming」というヘルパーストリングが追加されます。ミスプログラミングをチェックするためのIPアドレスのヘルパーストリングが<ip-address>パラメータに追加されます。nx_cmd.updateParam()メソッドのnx_sdk_py.P_IP_ADDRパラメータは、<ip-address>パラメータのタイプをIPアドレスとして定義するために使用されます。これにより、エンドユーザは文字列、整数、IPアドレスなどの別のタイプを入力できなくなります。このshowコマンドは、オプションでキーワード[clear]を使用します。誤プログラミングされることが検出されたアドレスをクリアするヘルパーストリングが、このオプションキーワードに追加されます。
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")
このshowコマンドは2つのキーワードのいずれかを使用でき、どちらのキーワードも2つの異なるパラメータを持ちます。最初のキーワードmacのパラメータは<mac-address>で、2番目のキーワードipのパラメータは<ip-address>です。単語mac-addressとip-addressを囲む山カッコは、それらがパラメータであることを示しています。MACキーワードに「Check MAC address for misprogramming」というヘルパーストリングが追加されます。<mac-address>パラメータに、ミスプログラミングをチェックするためのMACアドレスのヘルパーストリングが追加されました。nx_cmd.updateParam()メソッドのnx_sdk_py.P_MAC_ADDRパラメータは、<mac-address>パラメータのタイプをMACアドレスとして定義するために使用されます。これにより、エンドユーザは文字列、整数、IPアドレスなどの別のタイプを入力できなくなります。ipキーワードに「Check IP address for misprograming」というヘルパーストリングが追加されます。ミスプログラミングをチェックするためのIPアドレスのヘルパーストリングが<ip-address>パラメータに追加されます。nx_cmd.updateParam()メソッドのnx_sdk_py.P_IP_ADDRパラメータは、<ip-address>パラメータのタイプをIPアドレスとして定義するために使用されます。これにより、エンドユーザは文字列、整数、IPアドレスなどの別のタイプを入力できなくなります。このshowコマンドは、オプションでパラメータ[<module>]を指定できます。ヘルパー文字列Only clear addresses on specified moduleは、このオプションパラメータに追加されます。
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)
NX-SDK Pythonアプリケーションを作成したら、頻繁にデバッグが必要になります。NX-SDKは、コード内に構文エラーが存在する場合に通知しますが、Python NX-SDKライブラリはSWIGを使用してC++ライブラリをPythonライブラリに変換するので、コード実行時に例外が発生すると、次のようなアプリケーションコアダンプが生成されます。
terminate called after throwing an instance of 'Swig::DirectorMethodException'
what(): SWIG director method error. Error detected when calling 'NxCmdHandler.postCliCb'
Aborted (core dumped)
このエラーメッセージはあいまいな性質を持つため、Pythonアプリケーションのデバッグに最適な方法は、sdk.getTracer()メソッドから返されたNxTraceオブジェクトを使用して、デバッグメッセージをsyslogに記録することです。これは、次のように示されます。
#! /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")
syslogにデバッグメッセージを記録するオプションがない場合は、別の方法として、print文を使用し、Bashシェルの/isan/bin/pythonバイナリでアプリケーションを実行する方法があります。ただし、これらのprint文の出力は、この方法で実行した場合にのみ表示され、VSHシェルを介してアプリケーションを実行しても出力は生成されません。print文を使用する例を次に示します。
#! /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")
PythonアプリケーションがBashシェルで完全にテストされ、配備の準備が整ったら、そのアプリケーションをVSH経由で実稼働環境にインストールする必要があります。これにより、デバイスのリロード時、またはデュアルスーパバイザのシナリオでシステムのスイッチオーバーが発生した際に、アプリケーションを維持できます。VSHを使用してアプリケーションを展開するには、NX-SDKおよびENXOS SDKビルド環境を使用してRPMパッケージを作成する必要があります。Cisco DevNetは、RPMパッケージを簡単に作成できるDockerイメージを提供します。
注:特定のオペレーティングシステムにDockerをインストールする場合は、Dockerのインストールマニュアルを参照してください。
Docker対応ホストで、docker pull dockercisco/nxsdk:<tag> コマンドを使用して、選択したイメージバージョンをプルします。ここで、<tag> は選択したイメージバージョンのタグです。利用可能なイメージのバージョンと対応するタグは、ここで確認できます。これは、次のv1タグで示されます。
docker pull dockercisco/nxsdk:v1
このイメージからnxsdkという名前のコンテナを起動し、アタッチします。選択したタグが異なる場合は、タグの代わりにv1を使用します。
docker run -it --name nxsdk dockercisco/nxsdk:v1 /bin/bash
NX-SDKを最新バージョンに更新し、NX-SDKディレクトリに移動して、gitから最新のファイルを取得します。
cd /NX-SDK/
git pull
古いバージョンのNX-SDKを使用する必要がある場合は、git clone -b v<version> https://github.com/CiscoDevNet/NX-SDK.gitコマンドを使用して、それぞれのバージョンタグを使用してNX-SDKブランチをクローニングできます。ここで、<version>は必要なNX-SDKのバージョンです。これは、NX-SDK v1.0.0を使用した場合の例です。
cd /
rm -rf /NX-SDK
git clone -b v1.0.0 https://github.com/CiscoDevNet/NX-SDK.git
次に、PythonアプリケーションをDockerコンテナに転送します。これを行うには、いくつかの異なる方法があります。
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
次に、/NX-SDK/scripts/にあるrpm_gen.pyスクリプトを使用して、PythonアプリケーションからRPMパッケージを作成します。このスクリプトには、必須の引数が1つと、必須のスイッチが2つあります。
注:ファイル名には、.pyなどのファイル拡張子を含める必要はありません。この例では、ファイル名がpython_app.pyではなくpython_appの場合、RPMパッケージは問題なく生成されます。
ここでは、rpm_gen.py スクリプトの使用方法を示します。
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
RPMパッケージへのファイルパスは、rpm_gen.pyスクリプト出力の最終行に示されます。このファイルは、アプリケーションを実行するNexusデバイスに転送できるように、Dockerコンテナからホストにコピーする必要があります。Dockerコンテナを終了した後、docker cp <container>:<container_filepath> <host_filepath>コマンドを使用すると簡単に行えます。ここで、<container>はNX-SDK Dockerコンテナ(この場合はnxsdk)、<container_filepath>はコンテナ内のRPMパッケージのフルパス(この場合は/NX-SDK/rpm/RPMS/test_python_app-1.0-1.0.0.x86_64.rpm)、および<host_filepath >は、RPMパッケージの転送先となるDockerホスト上の完全なファイルパスです(この場合は/root/)。 次に、このコマンドの例を示します。
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
ファイル転送の任意の方法を使用して、このRPMパッケージをNexusデバイスに転送します。RPMパッケージがデバイスにインストールされたら、SMUと同様にインストールしてアクティブにする必要があります。これは、RPMパッケージがデバイスのブートフラッシュに転送されたことを前提として、次のように説明されています。
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
注:install addコマンドを使用してRPMパッケージをインストールする場合は、ストレージデバイスとパッケージの正確なファイル名を含めてください。インストール後にRPMパッケージをアクティブ化する場合は、ストレージ・デバイスとファイル名を含めず、パッケージ自体の名前を使用します。show install inactiveコマンドを使用して、パッケージ名を確認できます。
RPMパッケージがアクティブになったら、nxsdk service <application-name>設定コマンドを使用してNX-SDKでアプリケーションを起動できます。ここで、<application-name>は、rpm_gen.pyスクリプトが以前に使用されたときに定義されたPythonファイル名(およびアプリケーション名の後に続くアプリケーション)です。これは、次のように示されます。
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
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
また、このアプリケーションによって作成されたカスタムCLIコマンドがNX-OSでアクセス可能であることも確認できます。
N9K-C93180LC-EX# show test? test_python_app Nexus Sdk Application
フィードバック