JunosデバイスでYANG RPCのアクションスクリプトを作成する
サポートされているJunosデバイスでカスタムリモートプロシージャコール(RPC)を定義するYANGデータモデルを追加できます。非対応の YANG RPC をデバイスに追加する場合、RPC のハンドラーとして機能するアクション スクリプトも提供する必要があります。RPC 定義は、RPC の実行時に呼び出されるアクション・スクリプトを参照します。アクション スクリプトは操作を実行し、RPC に必要な情報を取得し、RPC output
ステートメントで定義されている XML 出力要素を返します。
アクションスクリプトは、Stylesheet Language Alternative SyntaX(SLAX)またはPythonで記述できます。SLAX アクション スクリプトは SLAX op スクリプトと類似しており、Junos XML 管理プロトコルと Junos XML API でサポートされている RPC を通じて利用可能なあらゆる機能を実行できます。Python アクション スクリプトは、Python 言語のすべての機能と構成要素を活用でき、SLAX スクリプトよりも柔軟性が向上します。さらに、Python アクション スクリプトは Junos PyEZ API をサポートしており、RPC の実行や Junos デバイスでの運用および設定タスクの実行を容易にします。Python スクリプトはライブラリを lxml
活用して、XPath の処理を簡素化することもできます。また、Junos OS リリース 19.3R1 以降、Junos OS とアップグレードされた FreeBSD を実行するデバイスは、Python アクション スクリプトで IPv6 を使用してサポートされています。
このトピックでは、RPC 入力引数を解析する方法、スクリプト内の運用および構成データにアクセスする方法、XML 出力を出力する方法、デバイス上でスクリプトを検証および読み込む方法など、アクション スクリプトを作成する方法について説明します。
アクションスクリプト定型
SLAX スクリプト定型プレート
SLAX アクション スクリプトには、基本的なスクリプト機能と、Junos OS 拡張機能 や 名前付きテンプレートなどのスクリプト内で使用されるオプション機能の両方に必要な定型文を含める必要があります。さらに、このスクリプトは、 ステートメントを使用してすべての RPC 入力パラメーターを宣言する param
必要があります。SLAX アクション スクリプト定型プレートは次のとおりです。
version 1.0; ns junos = "http://xml.juniper.net/junos/*/junos"; ns xnm = "http://xml.juniper.net/xnm/1.1/xnm"; ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0"; import "/var/db/scripts/import/junos.xsl"; param $input-param1; param $input-param2; match / { <action-script-results> { /* insert your code here */ } }
Python スクリプトボイラープレート
Python アクション スクリプトには、スクリプトの実行に使用する Python バージョンを指定するインタープリター ディレクティブ行を含める必要があります。 表 1 は、さまざまなリリースで使用できるインタープリター・ディレクティブ行の概要を示しています。
Pythonバージョン | ・インタープリター・ディレクティブ行 | サポート・リリース |
---|---|---|
Python 3 |
|
Junos OS リリース 20.2R1 以降 Junos OS Evolved リリース 21.1R1 以降 |
Python 2.7 |
|
Junos OS リリース 20.1 以前 Junos OS Evolved リリース 22.2 以前 |
Junos OS リリース 20.2R1 およびリリース 22.3R1 Junos OS Evolved以降、デバイスは Python 3 を使用して YANG アクションと変換スクリプトを実行します。以前のリリースでは、Junos OS はこれらのスクリプトの実行に Python 2.7 のみを使用し、Junos OS Evolvedはデフォルトで Python 2.7 を使用してスクリプトを実行します。
さらに、Python アクション スクリプトは、スクリプトで使用されているライブラリ、モジュール、またはオブジェクトをインポートする必要があります。たとえば、標準の Python ライブラリに加えて、Python アクション スクリプトは以下をインポートする場合があります。
-
jcs
ライブラリ — スクリプトで、Junos OS 拡張機能 と Junos OS 名前付きテンプレート 機能を使用できるようにします。 -
jnpr.junos
モジュールとクラス — スクリプトで Junos PyEZ を使用できるようにします。 -
lxml
ライブラリ —XPath の処理を簡素化します。
例えば:
#!/usr/bin/python3 import jcs from jnpr.junos import Device from lxml import etree
RPC 入力引数の解析
入力引数の概要
RPC は、オプション input
のステートメントを使用して入力パラメーターを定義できます。RPC を実行し、入力引数を指定すると、Junos OS は RPC のアクション スクリプトを呼び出し、それらの引数をスクリプトに渡します。Python または SLAX アクション スクリプトでは、通常の Python スクリプトまたは Junos OS SLAX op スクリプトのコマンドライン引数にそれぞれアクセスするのと同じ方法で RPC 入力引数にアクセスできます。
RPC では、以下 input
のステートメントを get-host-status
検討してください。
rpc get-host-status { description "RPC example to retrieve host status"; junos:command "show host-status" { junos:action-execute { junos:script "rpc-host-status.py"; } } input { leaf hostip { description "IP address of the target host"; type string; } leaf level { type enumeration { enum brief { description "Display brief output"; } enum detail { description "Display detailed output"; } } } leaf test { description "empty argument"; type empty; } } ...
RPC は、CLI で実行することも、NETCONF または Junos XML プロトコル セッションを介して実行することもできます。例えば、CLI で以下のコマンドを実行する場合があります。
user@host> show host-status hostip 198.51.100.1 level detail test
同様に、リモート セッションで次の RPC を実行することもできます。
<rpc> <get-host-status> <hostip>198.51.100.1</hostip> <level>detail</level> <test/> </get-host-status> </rpc>
コマンドまたは RPC を実行すると、デバイスはアクション スクリプトを呼び出し、引数を渡します。次のセクションでは、SLAX または Python アクション スクリプトの引数を処理する方法について説明します。
Junos OS リリース 19.2R1 以降、カスタム YANG RPC は Junos OS CLI で RPC のコマンドを実行する際にタイプ empty
の入力パラメーターをサポートしており、アクション スクリプトに渡される値はパラメーター名です。以前のリリースでは、タイプ empty
の入力パラメーターは NETCONF または Junos XML プロトコル セッションで RPC を実行する場合にのみサポートされており、アクション スクリプトに渡される値は文字列 'none'
です。
SLAX スクリプト入力引数
SLAX アクション スクリプトでは、 ステートメントを使用して入力パラメーターを宣言する param
必要があります。パラメータ名は YANG モジュールで定義されたパラメータ名と同じである必要があります。
呼び出されると、スクリプトは対応するパラメーターに各引数の値を割り当てます。この値は、スクリプト全体で参照できます。パラメーターを宣言する場合と、パラメーターの値にアクセスする場合の両方にドル記号 ($) 記号を含める必要があります。パラメーターが type empty
の場合、パラメーター名はその値として渡されます。
param $hostip; param $level; param $test;
SLAX パラメーターの詳細については、 自動化スクリプティング ユーザー ガイドの SLAX パラメーターの概要を参照してください。
Python スクリプト入力引数
Python アクション スクリプトの場合、引数は次のようにスクリプトに渡されます。
-
最初の引数は、常にアクション・スクリプトのファイル・パスです。
-
リスト内の次の引数は、ユーザーが提供する各入力パラメーターの名前と値です。
引数名は、以下のように渡されます。
-
Junos OS リリース 21.1 以前では、デバイスは引数の名前を渡します。
-
Junos OSリリース21.2R1以降では、デバイスは単一のハイフン(-)を単一のハイフン(-)で始め、2つのハイフン(--)を複数文字の引数名にプレフィックスとして付けます。
メモ:CLI で RPC のコマンドを実行すると、引数はコマンド ラインに指定された順序でスクリプトに渡されます。NETCONF または Junos XML プロトコル セッションでは、XML の引数の順序は任意であるため、引数は RPC
input
ステートメントで宣言された順序でスクリプトに渡されます。 -
-
リスト内の最後の 2 つの引数は、ユーザーではなくシステムによって提供され、RPC の名前です
'rpc_name'
。
以下のセクションでは、さまざまなリリースの Python アクション スクリプトに渡される引数の処理方法について説明します。
Python アクション スクリプト(21.2R1 以降)
Junos OS リリース 21.2R1 およびリリース 21.2R1 Junos OS Evolved以降、デバイスが入力引数名を Python アクション スクリプトに渡すと、単一のハイフン(-)が単一のハイフン(-)のプレフィックスとなり、2 つのハイフン(-)が複数文字の引数名にプレフィックスとして付けられます。これにより、標準的なコマンドライン解析ライブラリを使用して引数を処理できます。
前の YANG RPC の例では、アクション スクリプトの sys.argv
入力引数リストは次のとおりです。
['/var/db/scripts/action/rpc-host-status.py', '--hostip', '198.51.100.1', '--level', 'detail', '--test', 'test', '--rpc_name', 'get-host-status']
次のサンプル Python コードでは、ライブラリを argparse
使用して引数を処理します。この場合、パーサーはシステムがスクリプトに rpc_name
渡す引数も考慮する必要があります。
#!/usr/bin/python3 import argparse parser = argparse.ArgumentParser(description='This is a demo script.') parser.add_argument('--hostip', required=True) parser.add_argument('--level', required=False, default='brief') parser.add_argument('--test', required=False) parser.add_argument('--rpc_name', required=True) args = parser.parse_args() # access argument values by using args.hostip, args.level, and args.test
Python アクション スクリプト(21.1 以前)
Junos OS リリース 21.1 以前では、デバイスはコマンドまたは RPC で指定されたとおりに、入力された引数名を Python アクション スクリプトに渡します。一覧から入力引数に sys.argv
アクセスできます。
前の YANG RPC の例では、アクション スクリプトの sys.argv
入力引数リストは次のとおりです。
['/var/db/scripts/action/rpc-host-status.py', 'hostip', '198.51.100.1', 'level', 'detail', 'test', 'test', 'rpc_name', 'get-host-status']
次のサンプル Python コードは、RPC の例のリストから各引数の値を sys.arv
抽出する 1 つの方法を示しています。この例では、まず、使用可能な引数名をキーとして含む辞書を定義し、各引数のデフォルト値を指定します。次に、コードはリスト内の各キーを sys.argv
チェックし、リスト内の引数名のインデックスが存在する場合は取得します。次に、コードは引数の値を隣接するインデックス位置に抽出し、適切なキーの辞書に格納します。このメソッドにより、引数が実行中にスクリプトに異なる順序で渡された場合、特定の引数に対して正しい値が取得されます。
import sys # Define default values for arguments args = {'hostip': None, 'level': 'brief', 'test': None} # Retrieve user input and store the values in the args dictionary for arg in args.keys(): if arg in sys.argv: index = sys.argv.index(arg) args[arg] = sys.argv[index+1]
運用データと設定データの取得
アクションスクリプトは、Junos OSを実行するデバイスから運用および設定データを取得し、必要な情報のデータを解析できます。SLAX アクション スクリプトは、Junos XML 管理プロトコルと Junos XML API でサポートされている RPC を実行することで、デバイスから情報を取得できます。Python アクション スクリプトは、Junos PyEZ API を使用するか cli -c 'command'
、シェルと同様にアクション スクリプトで CLI コマンドを実行することで、運用情報と設定情報を取得できます。メソッドを使用して運用情報を cli -c
取得するには、目的の操作コマンドを含めます。設定情報を取得するには、 コマンドを show configuration
使用します。
次の SLAX スニペットは、同等<get-interface-information>
のshow interfaces
リクエスト タグを使用してローカル デバイスでコマンドを実行します。
var $rpc = <get-interface-information>; var $out = jcs:invoke($rpc); /* parse for relevant information and return as XML tree for RPC output */
次の Python コードでは、Junos PyEZ を使用して RPC を get_interface_information
実行します。RPC は CLI コマンドに show interfaces
相当します。
#!/usr/bin/python3 from jnpr.junos import Device from lxml import etree with Device() as dev: res = dev.rpc.get_interface_information() # parse for relevant information and return as XML tree for RPC output
Junos PyEZ を使用して Junos OS を実行するデバイス上で RPC を実行する方法については、 Junos OS を実行する デバイスで Junos PyEZ を使用して RPC を実行するを参照してください。
次の Python コードは、コマンドを show interfaces | display xml
実行し、文字列出力を XPath 構造を使用して必要なデータを解析できる XML ツリーに変換します。
#!/usr/bin/python3 import subprocess from lxml import etree cmd = ['cli', '-c', 'show interfaces | display xml'] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) tmp = proc.stdout.read() root = etree.fromstring(tmp.strip()) # parse for relevant information and return as XML tree for RPC output
RPC XML 出力の出力
RPC は、オプション output
のステートメントを使用して出力エレメントを定義できます。アクション スクリプトは、RPC 出力に必要な XML 要素を定義し、出力する必要があります。スクリプトによって出力される XML 階層には、RPC output
ステートメントの定義でコンテナおよびリーフ ステートメントによって定義されたツリーが反映されている必要があります。XML 出力を返す場合、アクション スクリプトは RPC 出力階層と出力階層のみを出力する必要があります。SLAX スクリプトは XML を出力するために ステートメントを copy-of
使用する必要があり、Python スクリプトはステートメントを使用 print
できます。
たとえば、次の YANG RPC output
ステートメントを考えてみましょう。
output { container host-status-information { container host-status-info { leaf host { type string; description "Host IP"; } leaf status { type string; description "Host status"; } leaf date { type string; description "Date and time"; } } } }
アクションスクリプトは、次のような対応するXML出力を生成して出力する必要があります。
<host-status-information> <host-status-info> <host>198.51.100.1</host> <status>Active</status> <date>2016-10-10</date> </host-status-info> <host-status-info> <host>198.51.100.2</host> <status>Inactive</status> <date>2016-10-10</date> </host-status-info> </host-status-information>
必要な出力要素の値を取得した後、Python スクリプトは次のコードを使用して XML 出力階層を発行する場合があります。
from lxml import etree ... xml = ''' <host-status-information> <host-status-info> <host>{0}</host> <status>{1}</status> <date>{2}</date> </host-status-info> </host-status-information> '''.format(hostip, pingstatus, now) tree = etree.fromstring(xml) print (etree.tostring(tree))
同様に、SLAX アクション スクリプトでは以下を使用する場合があります。
var $node = { <host-status-information> { <host-status-info> { <host> $ip; <status> $pingstatus; <date> $date; } } } copy-of $node;
デバイスでのアクションスクリプトの検証と読み込み
YANG RPC定義では、 および junos:action-execute
ステートメントとjunos:script
サブステートメントをjunos:command
含めることで、RPCのアクションスクリプトを指定します。このステートメントは、アクションスクリプトのファイル名をその値として取得します。RPC ごとに 1 つのアクション スクリプトのみを定義する必要があります。例えば:
rpc rpc-name { ... junos:command "show sw-info" { junos:action-execute { junos:script "sw-info.py"; } } ... }
Junos OS リリース 17.3 以降、 action-execute
ステートメントは. command
以前のリリースでは、 action-execute
および command
ステートメントは同じレベルに配置され command
、 ステートメントはオプションです。
Junos OS を実行するデバイスの RPC を定義する YANG モジュールは、Junos OS の MPLS 拡張モジュールをインポートする必要があります。
Python アクション スクリプトは、Junos OS を実行するデバイスでスクリプトを実行する前に、以下の要件を満たす必要があります。
-
ファイル所有者は、Junos OS
super-user
ログイン クラスの root またはユーザーのいずれかです。 -
ファイルの所有者のみが、ファイルの書き込み権限を持っています。
-
スクリプトには、 アクションスクリプト定型で説明されているインタープリター指令行が含まれています。
-
language python
またはlanguage python3
ステートメントは、 階層レベルで[edit system scripts]
設定され、符号なしPythonスクリプトの実行を有効にします。
Junos OS リリース 20.2R1 およびリリース 22.3R1 Junos OS Evolved以降、デバイスは Python 3 を使用して YANG アクションと変換スクリプトを実行します。以前のリリースでは、Junos OS はこれらのスクリプトの実行に Python 2.7 のみを使用し、Junos OS Evolvedはデフォルトで Python 2.7 を使用してスクリプトを実行します。
ユーザーは、Junos OSを実行しているデバイスでのみ、符号なしPythonスクリプトを実行できます。スクリプトのファイル権限に、ユーザーが受ける最初のクラスの読み取り権限がユーザー、グループなどの順序で含まれている場合です。
CLIでアクションスクリプトの構文を検証するには、 コマンドを request system yang validate action-script
発行し、スクリプトへのパスを提供します。例えば:
user@host> request system yang validate action-script /var/tmp/sw-info.py Scripts syntax validation : START Scripts syntax validation : SUCCESS
アクションスクリプトを使用するには、対応するRPCを含むYANGモジュールを持つデバイスにロードする必要があります。または request system yang update
コマンドをrequest system yang add
使用して、YANGモジュールとそれに関連するアクションスクリプトをデバイス上の新規または既存のYANGパッケージに追加します。モジュールとアクション スクリプトをデバイスに追加した後、カスタム RPC を実行できます。RPC を実行すると、デバイスは参照先スクリプトを呼び出します。
トラブルシューティングアクションスクリプト
デフォルトでは、アクションスクリプトは、スクリプトの実行時に情報トレースメッセージをログに記録します。トレース メッセージを表示して、RPC がスクリプトを呼び出したことを確認し、スクリプトが正しく実行されたことを確認できます。スクリプトが何らかの理由で失敗した場合、エラーはトレース ファイルに記録されます。
Junos OS
実行中のJunos OSデバイスでアクションスクリプトトレースメッセージを表示するには、 action.log トレースファイルの内容を表示します。
user@host> show log action.log
Junos OS Evolved
Junos OS Evolvedデバイス上のアクションスクリプトトレースメッセージを表示するには、すべてのスクリプトタイプのトレースデータを含むcscriptアプリケーショントレースメッセージを表示します。
user@host> show trace application cscript
empty
の入力パラメーターをサポートしており、アクション スクリプトに渡される値はパラメーター名です。
action-execute
ステートメントは.
command