『Cisco Nexus 7000 シリーズ NX-OS 基本設定ガイド、リリース 6.x』
Python API
Python API

Python API

この章では、Cisco Nexus 7000 シリーズ デバイスに Python API を使用する方法について説明します。

この章は、次の項で構成されています。

機能情報の確認

ご使用のソフトウェア リリースで、このモジュールで説明されるすべての機能がサポートされているとは限りません。 最新の警告および機能情報については、https:/​/​tools.cisco.com/​bugsearch/​ の Bug Search Tool およびご使用のソフトウェア リリースのリリース ノートを参照してください。 このモジュールで説明される機能に関する情報、および各機能がサポートされるリリースの一覧については、「新機能および変更された機能に関する情報」の章を参照してください。

Python API の概要

Python は簡単に習得できる強力なプログラミング言語です。 効率的で高水準なデータ構造を持ち、オブジェクト指向プログラミングに対してシンプルで効果的なアプローチを取っています。 Python は、簡潔な構文、動的な型付け、およびインタープリタ型という性質によって、ほとんどのプラットフォームのさまざまな分野でスクリプティングと高速なアプリケーション開発を実現する理想的な言語です。

Python のインタープリタと広範な標準ライブラリは、Python Web サイトから、すべての主要プラットフォームに対応したソース形式またはバイナリ形式で自由に利用できます。

http://www.python.org/

また、このサイトには、サードパーティが無償で提供している多数の Python モジュール、プログラム、およびツールのディストリビューションとそれらへのリンク、さらに追加のドキュメンテーションが掲載されています。

Cisco Nexus 7000 シリーズ デバイスは、インタラクティブ モードと非インタラクティブ(スクリプト)モードの両方で、Python v2.7.2 をサポートします。

Cisco Nexus 7000 シリーズ デバイスの Python スクリプト機能は、スイッチのコマンドライン インターフェイス(CLI)へのプログラムによるアクセスを提供し、さまざまなタスクと、Power-On Auto Provisioning(POAP)または Embedded Event Manager(EEM)アクションを実行します。


(注)  


Cisco NX-OS Release 6.2(8) 以降、システムは JavaScript Object Notation(JSON)およびロギング モジュールをサポートします。

Python インタープリタは Cisco NX-OS ソフトウェアでデフォルトで使用できます。

Python の使用

ここでは、Python スクリプトの作成と実行の方法について説明します。


(注)  


Cisco NX-OS Release 6.2(8) 以降、管理 VRF だけでなく他の VRF でも Python ネットワーク操作を実行できます。

Python ライブラリのインポート

Python で CLI コマンドを実行するには、cisco モジュールをインポートする必要があります。 cisco モジュールには CLI と統合されるコードが含まれています。

CLI コマンドを有効化する、cisco モジュールに含まれている機能は、python コマンドを使用して Python のインタラクティブ モードを起動したり、source コマンドを使用して Python の非インタラクティブ モードを起動したりすると、自動的にインポートされます。


(注)  


Cisco NX-OS Release 6.2(8) 以降では、hashlib ライブラリもインポートできます。

CLI コマンドの API の使用

Cisco Nexus 7000 シリーズ デバイスでは、Python プログラミング言語は CLI コマンドを実行できる 3 つの API を使用します。 これらの API については、次の表で説明します。 これらの API の引数は CLI コマンドの文字列です。 Python インタープリタ経由で CLI コマンドを実行するには、次の API のいずれかの引数文字列として CLI コマンドを入力します。

API

説明

cli()

例:

string = cli (“cli-command”)

制御文字、特殊文字を含む CLI コマンドの未処理の出力を返します。

(注)     

インタラクティブな Python インタープリタは、制御文字および特殊文字を「エスケープ」して出力します。 これは、復帰改行が「\n」として出力されることを意味し、判読が難しくなる可能性があります。 clip() API は、判読性が高い結果を出力します。

clid()

例:

dictionary = clid (“cli-command”) 

XML をサポートする CLI コマンドの場合、この API はコマンド出力を Python ディクショナリとして返します。

この API は、show コマンドの出力の検索時に使用すると便利な場合があります。

clip()

例:

clip (“cli-command”)

CLI コマンドの出力を直接 stdout に出力し、Python には何も返されません。

(注)     
clip (“cli-command”)
と同等です
r=cli(“cli-command”)
print r

CLI からの Python インタープリタの呼び出し

次に、CLI から Python を呼び出す方法を示します。


(注)  


Python インタープリタのプロンプトは「>>>」または「…」で示されます。


switch# show clock                                           
23:54:55.872 UTC Wed May 16 2012                             
switch# python                          !-- Enter Python interpreter
switch# >>> cli("conf term ; interface loopback 1")          
switch(config-if)# >>> cli("ip address 1.1.1.1/24")          
switch(config-if)# >>> cli("exit")      !-- Exit the CLI interface mode
switch(config)# >>> cli("exit")                              
switch# >>> i=0                                              
switch# >>> while i<8:                                       
switch# ...   i=i+1                     !-- Composite command; prompt indicates more input
switch# ...   cmd = "show module %i" % i                     
switch# ...   r=clid(cmd)                                    
switch# ...   if "TABLE_modinfo/model" in r.keys():          
switch# ...     if r["TABLE_modinfo/model"] == "Nurburgring":
switch# ...       print "got a racer in slot %d" % i         
switch# ...                             !-- Empty input indicates end of loop
got a racer in slot 3                                        
switch# >>> exit                        ! -- Exit Python interpreter          
switch#                                                      

VRF の割り当ての変更

Cisco NX-OS Release 6.2(8) 以降、Python ネットワーク操作を実行するために VRF を選択できます。 デフォルトでは、Python でのネットワーク操作は管理 VRF で行います。 ネットワーキングおよびソケット API を使用する前に、次のコマンドを使用して、VRF を変更します。

switch# python
switch# >>> import socket                    
switch# >>> set_vrf ('default')                         
switch# >>> s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)

VRF を他の任意の VRF に変更できます。

表示形式

次に、Python API を使用したさまざまな表示形式を示します。

例 1

switch# >>> cli("conf ; interface loopback 1")
Enter configuration commands, one per line.  End with CNTL/Z 
switch(config-if)# >>> clip('where detail‘)

   mode:                conf
                         interface loopback1
  username:            root
  vdc:                 switch
  routing-context vrf: default


例 2

switch# >>> cli("conf ; interface loopback 1")
Enter configuration commands, one per line.  End with CNTL/Z
switch(config-if)# >>> cli('where detail')

'\x1b[00m  mode:                conf\n                         interface loopback1\n  username:            root\n  vdc:                 switch\n  routing-context vrf: default\n'


例 3

switch# >>> cli("conf ; interface loopback 1")
Enter configuration commands, one per line.  End with CNTL/Z 
switch(config-if)# >>> r = cli('where detail') ; print r

(same output as clip() above!)
   mode:                conf
                         interface loopback1
  username:            root
  vdc:                 switch
  routing-context vrf: default


例 4

switch# >>> cli("conf ; interface loopback 1")
Enter configuration commands, one per line.  End with CNTL/Z 
switch(config-if)# >>> i=0
switch(config-if)# >>> while i<3:
switch(config-if)# ...   i=i+1
switch(config-if)# ...   cli('ip addr 1.1.1.1/24')
switch(config-if)# ...
switch(config-if)# >>> cli('end')
switch# >>> r = clid('show version')
switch# >>> for k in r.keys():
switch# ...  print "%30s" % k, " = %s" % r[k]
switch# ...
             cpu_name  = Intel(R) Xeon(R) CPU
           rr_sys_ver  = 6.2(0.110)
         manufacturer  = Cisco Systems, Inc.
       isan_file_name  = bootflash:///full
             rr_ctime  = Wed May 16 02:40:57 2012
        proc_board_id  = JAF1417AGCB
       bios_cmpl_time  = 02/20/10
    kickstart_ver_str  = 6.1(1) [build 6.1(0.292)] [gdb]
          isan_tmstmp  = 05/16/2012 02:26:02
switch# >>> exit

例 5

この例では、Python に CLI コマンドの未加工出力を、制御および特殊文字を含めて表示します。 たとえば、復帰改行は \n と表示されます。

switch# >>> cli('show vrf')


'VRF-Name                      VRF-ID State              Reason
\ndefault                        1      Up                 --
\nmanagement                     2      Up                 --     \n'
switch# >>>

clip コマンドを入力すると、Python に「void」が返されますが、同じ出力が std に出力されます。

例 6

この例では、Python に対する属性名と値のディクショナリを表示します。

switch# >>> clid('show vrf')
{'TABLE_vrf/vrf_id'; '1', 'TABLE_vrf/vrf_reason': '--',  'TABLE_vrf/vrf_name': 'default', 'TABLE_vrf/vrf_state': 'Up'}
switch# >>> cli

Python インタープリタの非永続性

Python は CLI シェルから分岐します。これは次のことを意味します。

  • Python インタープリタの複数の呼び出しの間で状態は維持されません。

  • Python イ タープリタを終了すると、CLI モードは失われます。

次の例は、Python インタープリタの非永続性を示します。

switch# python            !-- Invoke Python interpreter
switch# >>> i = 2                    
switch# >>> print "var i = %d" % i   
var i = 2                            
switch# >>> cli("configure terminal")
switch(config)# >>> blabla                 
switch(config)# >>> exit           !-- Exit Python interpreter
switch#                            !-- CLI still in exec mode (conf t is lost)
switch# python                     !-- Invoke new Python interpreter
switch# >>> print "var i = %d" % i !-- Previous Python interpreter and variables are lost          
Error: variable 'i' undefined.       
switch# >>> exit                     
switch# conf t ; inter lo 1   
switch(config-if)# python          !-- Invoke new Python interpreter
switch(config-if)# >>>             !-- Inherits the CLI mode (forked from CLI)

非インタラクティブ Python

次の例はスクリプトとその実行方法を示します。


(注)  


bootflash:scripts ディレクトリはデフォルトのスクリプト ディレクトリです。 すべてのスクリプトは bootflash:scripts ディレクトリまたはそのサブディレクトリに保存する必要があります。



(注)  


例の先頭行の前に #!/bin/env tclsh を挿入し、すべての Python スクリプト ファイル名を tcl スクリプト ファイル名で置き換えることにより、Python スクリプトの代わりに tcl スクリプトを実行できます。


switch# show file bootflash:scripts/test1.py !-- bootflash:scripts directory
                                            !-- is the default script directory
#!/bin/env python           !-- Invoke Python to run test1.py script      
                                                            
i=0                                                         
while i<3:                                                  
  r=clip('show version')                                    
  uptime_name='/@/show/version/__readonly__/kern_uptm_secs' 
  print uptime_name, r[uptime_name]                         
  clid('sleep 1')                                           
  i=i+1                                                     
                                                            
switch# source test1.py     !-- Default directory is /bootflash/scripts
/@/show/version/__readonly__/kern_uptm_secs 36              
/@/show/version/__readonly__/kern_uptm_secs 38              
/@/show/version/__readonly__/kern_uptm_secs 40              
switch#     


次の例はスクリプトが引数を受け入れる方法を示します。

root@switch# source ntimes 2 "show clock"  !-- Pass arguments ‘2’ and 'show clock' to script

>>>> iteration 1 for 'show clock'
21:27:21.716 UTC Tue Oct 09 2012
>>>> iteration 2 for 'show clock'
21:27:21.730 UTC Tue Oct 09 2012
root@switch# 

バックグランドでのスクリプトの実行

次の例は、スクリプトをバックグランドで実行する方法を示します。

switch# source background sleep 100
switch# source background sleep 50
switch# show background
username   .   terminal   pid    start  time      script args ...
root  .    .      pts/0    7687  03:31  00:00:00  sleep.py 90  .
root  .    .      pts/0    7696  03:31  00:00:00  sleep.py 50  .
switch# kill background ?
  WORD  Background script to terminate, by process-id or just
        a regex matching any line from 'show background' output

switch# kill background 7687
switch# show background
username   .   terminal   pid    start  time      script args ...
root  .    .      pts/0    7696  03:31  00:00:00  sleep.py 50  .
switch#
switch# exit
Linux(debug)# su john
switch# kill background 7696
bash: line 1: kill: (7696) - Operation not permitted
switch#

スクリプトのオンライン ヘルプ

オンライン ヘルプ プロトコルにより、スクリプトでオンライン ヘルプ、 man ページ、状況に応じた形式を提供することができます。

次の例は、スクリプト ディレクトリに含まれるスクリプトのオンライン ヘルプを示します。

switch# source ?                                                          
  abc           No help             !-- Script does not support online help protocol
  cgrep         'context grep': shows matching line plus the context lines
                (to be used behind a pipe, for show-run type of output)   
                Example of context for 'ip address 1.1.1.1/24': 'eth 2/1' 
  find-if       Find interfaces that match selected attribute values      
                (from 'show intf br')                                     
  ntimes        Runs specified command specified numbers of times         
  redo-history  This is run a list of commands from the history again     
  show-if       Show selected interface attributes                        
  show-version  A better 'show version'                                   
  sys/          Directory !-- Directory contains example scripts packaged in image.
                          !-- These example scripts can be copied to /bootflash for
                          !-- viewing and modification using the 'source copy-sys' command.


次の例は、ntimes スクリプトの man ページ形式のオンライン ヘルプを示します。

switch# source ntimes ?               !-- Filename can be abridged if unique (or tabbed) 
  arg1: the command, in quotes               
  arg2: number of times to run the commands  
  <CR>                                       
  >      Redirect it to a file               
  >>     Redirect it to a file in append mode
  |      Pipe command output to filter       

オンライン ヘルプのプロトコル

スクリプトは、__cli_script.*help という形式の引数で呼び出されます。

引数には次のように 3 つの異なる形式があります。

  • __cli_script_help

    スクリプトの目的を表す 1 行の説明を返す要求。

  • __cli_script_args_help

    引数のヘルプを返す要求。 ファイル名は最初の引数として渡され、それまでに入力されたすべての引数も渡されます。

  • __cli_script_args_help_partial

    最後の引数が「部分的」である場合、引数のヘルプを返す要求。

    たとえば、interface Ethernet 1/? は「部分的」であり、状況依存ヘルプが返されます。この例では、interface Ethernet 1/? により、スロット 1 のライン カードのポート範囲が返されます。

次に、引数ヘルプの表示形式を示します。

  • 標準的な形式(「タイプ|説明」形式)

    print "ftp|Use ftp for file transfer protocol"
    print "scp|Use scp for file transfer protocol"
    exit(0)
    
  • man ページ形式(タブなし)

    print "__man_page"
    print "  whatever…“