カスタム YANG モジュールの CLI で有効なコマンド オプションと設定ステートメント値を表示する
特定のJunosデバイスでは、デバイスにカスタムYANGモジュールをロードして、Junos OSでネイティブにサポートされていないデータモデルを追加できます。カスタム YANG データ モデルをデバイスに追加する場合、YANG データ モデルと Junos OS 間の変換ロジックを処理するアクションまたは変換スクリプトも提供する必要があります。スクリプトロジックは、ユーザーが特定のコマンドオプションまたは設定ステートメントに有効な値を提供するようにすることができますが、その論理が常にユーザーに透過的であるとは限りません。Junos OSリリース19.2R1以降、オプションまたはステートメント定義に拡張ステートメントを含め action-expand
、ロジックを処理するスクリプトを参照すると、カスタムYANGデータモデルの特定のコマンドオプションまたは設定ステートメントで使用可能な値のセットが表示されます。
カスタム YANG モジュールのコンテキストに応ったヘルプを理解する
Junos CLIは、運用モードまたは設定モードで疑問符(?)を入力するたびに、コンテキストに応ったヘルプを提供します。コマンドを実行したりステートメントを設定する場合、CLIのコンテキストに応じるヘルプには、コマンドの有効なオプションとオプション値、または設定ステートメント階層の有効な設定ステートメントとリーフステートメント値が表示されます。さらに、コンテキストに応じてヘルプを表示すると、不完全なオプション名、ステートメント名、および値の補完候補が表示されます。
また、CLIは、カスタムYANGデータモデルの特定のコマンドオプションや設定ステートメントに有効な値を表示することもできます。CLI は、ユーザーからの部分的な入力に一致するすべての値または値のサブセットを表示できます。例えば:
user@host> show host-status hostip ? Possible completions: <hostip> Host IP address 10.10.10.1 IPv4 address 10.10.10.2 IPv4 address 172.16.0.1 IPv4 address 198.51.100.1 IPv4 address 198.51.100.10 IPv4 address 2001:db8::1 IPv6 address (DC 1...128) 2001:db8::fdd2 IPv6 address (DC 1...128)
user@host> show host-status hostip 198? Possible completions: <hostip> Host IP address 198.51.100.1 IPv4 address 198.51.100.10 IPv4 address
カスタムYANGモジュール内の特定のコマンドオプションまたは設定ステートメントの有効な値のセットを表示するには:
-
YANGモジュールの
action-expand
定義で説明されているように、YANGモジュールの適切な入力パラメーターまたは設定ステートメントの下で、 およびscript
拡張ステートメント を定義します。 -
ユーザー入力をチェックし、 コマンド オプションまたは設定ステートメントの使用可能な値を計算し、 CLI 拡張スクリプトの作成の説明に従って、適切な出力 を CLI に送信する Python スクリプトを作成します。
メモ:CLI 拡張スクリプトは、CLI の有効な値のみを表示します。モジュールの変換スクリプトまたはアクション・スクリプトには、有効な値のみが受け入れられ、処理されるようにする論理がまだ含まれている必要があります。
-
YANG パッケージの読み込みの説明に従って、デバイス上のカスタム YANG パッケージの一部として YANG モジュール、変換スクリプトまたはアクション スクリプト、CLI 拡張スクリプト を読み込みます。
メモ:JunosデバイスはCLI拡張スクリプトを別の種類のアクションスクリプトとして処理しますが、混乱を避けるためにCLI拡張スクリプトを参照しています。
YANG モジュールの定義
ユーザーがCLIでコンテキストに応じてヘルプを要求する際に、特定のコマンドオプションまたは設定ステートメントの有効な値のセットを表示するカスタムYANGモジュールを定義するには、モジュールは以下を行う必要があります。
例えば、以下のモジュールでは、RPC が入力パラメーターを hostip
定義します。このパラメーターは、ユーザーが CLI の引数に hostip-expand.py
コンテキスト・ヘルプを要求すると Python スクリプトを hostip
呼び出します。このスクリプトは、CLI で引数の有効な値を表示するカスタム ロジックを実装します。
module rpc-host-status { namespace "http://yang.juniper.net/examples/rpc-cli"; prefix jrpc; import junos-extension-odl { prefix junos-odl; } import junos-extension { prefix junos; } 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 "Host IP address"; type string; junos:action-expand { junos:script "hostip-expand.py"; } } leaf level { type enumeration { enum brief { description "Display brief output"; } enum detail { description "Display detailed output"; } } } } output { ... } } }
CLI 拡張スクリプトの作成
カスタムYANGモジュールでコマンドオプションまたは設定ステートメントのステートメントとscript
サブステートメントを定義action-expand
し、そのオプションまたはステートメント値に対してコンテキストに応じてヘルプをCLIで要求すると、デバイスは参照されるPythonスクリプトを呼び出します。スクリプトには、そのパラメーターに使用可能なすべての値を計算して表示するカスタム ロジック、またはユーザーからの部分的な入力に一致する値のサブセットを表示するカスタム ロジックが含まれている必要があります。
例えば、以下のコマンドは引数のすべての有効な値を表示する hostip
必要があります。
user@host> show host-status hostip ?
そして、次のコマンドは、「198」で始まるすべての有効な値を表示する必要があります。
user@host> show host-status hostip 198?
CLI でコマンド オプションまたは設定ステートメントの有効な値を表示するには、Python スクリプトで以下の機能を実行する必要があります。
-
ライブラリを他の
jcs
必要な Python ライブラリと共にインポートします。 -
ユーザー入力を取得して処理します。
CLI で オプションまたはステートメント値に部分的な入力を指定した場合、スクリプトのコマンドライン引数には、ユーザー入力を
symbol
含む文字列である引数が含まれます。メモ:Junos OS リリース 21.2R1 およびリリース 21.2R1 Junos OS Evolved以降、スクリプトのコマンドライン引数には、引数の代わりに引数が
symbol
含まれています--symbol
。 -
パラメーターの有効な値を定義または計算します。
-
コマンド ラインに
jcs.expand()
表示する各値の関数を呼び出します。
このスクリプトは、CLIに jcs:expand()
表示するために、各オプションまたはステートメント値の関数を呼び出す必要があります。この関数の jcs:expand()
構文は次のとおりです。
jcs.expand(value, description, <units>, <range>)
どこ:
value | 指定されたコマンド オプションまたは設定ステートメントの有効な値を定義する文字列。 |
description | 値を記述する文字列。 |
units | (オプション)対応する値の単位を定義する文字列。 |
range | (オプション)対応する値の範囲を定義する文字列。 |
この関数を呼び出す jcs.expand()
たびに、スクリプトは CLI の関数引数に提供される値、説明、単位、および範囲を出力します。例えば、スクリプト内で次のような呼び出し jcs.expand()
が行なえるとします。
jcs.expand("2001:db8:4136::fdd2", "IPv6 address", "DC", "1...128")
対応する CLI 出力は次のとおりです。
Possible completions: <hostip> Host IP address 2001:db8:4136::fdd2 IPv6 address (DC 1...128)
次のサンプル スクリプトでは、まずスクリプトの symbol
コマンド ライン引数の存在を確認し、存在する場合は、対応する変数をユーザーの入力と等しく設定します。次に、スクリプトはユーザーの入力に基づいてパラメーターの有効な値のセットを計算します。最後に、スクリプトは CLI に jcs.expand()
表示する各値の関数を呼び出します。
リリースごとにスクリプトの引数を適切に処理するスクリプトの symbol
バージョンを2つ用意しています。以下のサンプルスクリプトは、Junos OSリリース21.2R1以降を実行しているデバイスで有効であり、ライブラリを argparse
使用して引数を --symbol
解析します。
#!/usr/bin/python3 # Junos OS Release 21.2R1 and later import jcs import argparse parser = argparse.ArgumentParser(description='This is a demo script.') parser.add_argument('--symbol', required=False, default='') args = parser.parse_args() description_ipv4 = "IPv4 address" description_ipv6 = "IPv6 address" expand_colon = ":" expand_units = "DC" expand_range = "1...128" item = ["10.10.10.1", "10.10.10.2", "2001:db8::1", "172.16.0.1", "198.51.100.1", "198.51.100.10", "2001:db8::fdd2"] for ip in item: if ip.startswith(args.symbol) or not args.symbol: if not expand_colon in ip: jcs.expand(ip, description_ipv4) else: jcs.expand(ip, description_ipv6, expand_units, expand_range)
同様に、Junos OS リリース 21.1 以前を実行しているデバイスで有効な以下のサンプル スクリプトは、リストで をsymbol
sys.argv
確認します。
#!/usr/bin/python # Junos OS Release 21.1 and earlier import sys import jcs symbol = "" # Retrieve user input in symbol argument and store the value if "symbol" in sys.argv: index = sys.argv.index("symbol") symbol = sys.argv[index+1] description_ipv4 = "IPv4 address" description_ipv6 = "IPv6 address" expand_colon = ":" expand_units = "DC" expand_range = "1...128" item = ["10.10.10.1", "10.10.10.2", "2001:db8::1", "172.16.0.1", "198.51.100.1", "198.51.100.10", "2001:db8::fdd2"] for ip in item: if ip.startswith(symbol) or not symbol: if not expand_colon in ip: jcs.expand(ip, description_ipv4) else: jcs.expand(ip, description_ipv6, expand_units, expand_range)
CLI 拡張スクリプトは、CLI の コマンド オプションまたは設定ステートメントの有効な値、ユニット、範囲のみを表示します。モジュールの変換スクリプトまたはアクション・スクリプトは、有効な値のみが受け入れられ、処理されるようにする必要があります。
YANG パッケージの読み込み
Junos デバイスで YANG パッケージを読み込む場合、そのパッケージのアクション スクリプトのリストに CLI 拡張スクリプトを含めます。Junos OSは、スクリプトを 自動的に/var/db/scripts/actionディレクトリに コピーします。
新しいパッケージを読み込み、カスタム CLI 拡張スクリプトを含める方法:
例:コマンド・オプションのコンテキスト・ヘルプの表示
この例では、拡張ステートメントとカスタムスクリプトを action-expand
使用して、ユーザーがそのオプションのCLIでコンテキストヘルプを要求する際に、コマンドオプションの1つの可能な値セットを表示するカスタムYANGモジュールを示します。
要件
この例では、以下のハードウェアとソフトウェアのコンポーネントを使用しています。
-
カスタム YANG データ モデルの読み込みをサポートする Junos OS リリース 19.2R1 以降を実行するデバイス。
概要
この例の YANG モジュールは、指定されたホストに ping を実行して結果を返すカスタム RPC を定義しています。YANGモジュール rpc-host-status
は、 rpc-host-status.yang ファイルに保存されます。モジュールは、Junos OS 拡張モジュールをインポートします。これは、デバイス上でカスタム RPC を実行し、CLI で出力とコンテキストに応じてヘルプをカスタマイズするために必要な拡張機能を提供します。
モジュールは RPC を定義しますget-host-status
。ステートメントはjunos:command
、CLIでRPCを実行するために使用されるコマンドを定義します。この場合は.show host-status
および junos:script
ステートメントはjunos:action-execute
、RPC の実行時に呼び出されるアクション・スクリプトを定義します。
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"; } }
hostip
入力パラメーターには、 junos:action-expand
および junos:script
ステートメントが含まれています。このステートメントは、ユーザーがその入力パラメーターに対して CLI でコンテキスト・ヘルプを要求したときに呼び出されるスクリプトを定義します。
input { leaf hostip { description "Host IP address"; type string; junos:action-expand { junos:script "hostip-expand.py"; } } ... }
hostip-expand.py スクリプトは、リリースに応じてスクリプトに渡されるユーザーの入力を、 symbol
または --symbol
として処理します。その後、スクリプトはそのコマンド オプションに対してユーザーが入力できる値のセットを計算して表示します。
Junos OS リリース 21.2R1 以降、リリース 21.2R1 Junos OS Evolved、デバイスが Python アクション スクリプト(CLI 拡張スクリプトを含む)にコマンドライン引数を渡す場合、単一のハイフン(-)を単一文字の引数名にプレフィックスし、2 つのハイフン(-)からマルチ文字の引数名にプレフィックスを付けます。
拡張スクリプトは、CLI で の hostip
有効な値を表示します。アクション スクリプトは、指定された値が有効かどうかを判断するロジックを実装します。この例では、 という名前の新しい YANG パッケージの一部として YANG モジュールとアクション スクリプトをデバイスに追加します rpc-host-status
。
YANG モジュールおよびアクション スクリプト
YANG モジュール
YANG モジュールである rpc-host-status.yang は、RPC、CLI で RPC を実行するために使用されるコマンド、RPC を実行する際に呼び出すアクション スクリプトの名前、ユーザーが対応する入力パラメーターに対してコンテキストに依存するヘルプを要求したときに呼び出す CLI 拡張スクリプトの名前を定義します。
/* * Copyright (c) 2019 Juniper Networks, Inc. * All rights reserved. */ module rpc-host-status { namespace "http://yang.juniper.net/examples/rpc-cli"; prefix jrpc; import junos-extension-odl { prefix junos-odl; } import junos-extension { prefix junos; } organization "Juniper Networks, Inc."; description "Junos OS YANG module for RPC example"; 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 "Host IP address"; type string; junos:action-expand { junos:script "hostip-expand.py"; } } leaf level { type enumeration { enum brief { description "Display brief output"; } enum detail { description "Display detailed output"; } } } } output { container host-status-information { leaf hostip { type string; description "Host IP"; } leaf status { type string; description "Operational status"; } leaf date { type string; description "Date information"; } junos-odl:style brief { junos-odl:format host-status-information-format-brief { junos-odl:header "Brief output\n"; junos-odl:picture "@<<<<<<<<<<<< @"; junos-odl:space; junos-odl:line { junos-odl:field "hostip"; junos-odl:field "status"; } } } junos-odl:style detail { junos-odl:format host-status-information-format-detail { junos-odl:header "Detail output\n"; junos-odl:picture "@<<<<<<<<<<<< @<<<<<<<<<<<< @"; junos-odl:space; junos-odl:line { junos-odl:field "hostip"; junos-odl:field "status"; junos-odl:field "date"; } } } } } } }
アクションスクリプト
対応するアクションスクリプトが rpc-host-status.py。この例では、異なるリリースのスクリプトのコマンドライン引数を適切に処理する、2 つのバージョンのアクション・スクリプトを提供します。
アクションスクリプト(Junos OSリリース21.2R1以降)
#!/usr/bin/python3 # Junos OS Release 21.2R1 and later import os 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('--rpc_name', required=True) args = parser.parse_args() valid_addresses = ["10.10.10.1", "10.10.10.2", "2001:db8::1", "172.16.0.1", "198.51.100.1", "198.51.100.10", "2001:db8::fdd2"] f = os.popen('date') now = f.read() # Ping target host and set the status if args.hostip in valid_addresses: response = os.system('ping -c 1 ' + args.hostip + ' > /dev/null') if response == 0: pingstatus = "Host is Active" else: pingstatus = "Host is Inactive" else: pingstatus = "Invalid host" # Print RPC XML for the given style print ("<host-status-information>") print ("<{}>".format(args.level)) print ("<hostip>{}</hostip>".format(args.hostip)) print ("<status>{}</status>".format(pingstatus)) if args.level == "detail": print ("<date>{}</date>".format(now)) print ("</{}>".format(args.level)) print ("</host-status-information>")
アクションスクリプト(Junos OSリリース21.1以前)
#!/usr/bin/python # Junos OS Release 21.1 and earlier import sys import os args = {'hostip': None, 'level': 'brief'} valid_addresses = ["10.10.10.1", "10.10.10.2", "2001:db8::1", "172.16.0.1", "198.51.100.1", "198.51.100.10", "2001:db8::fdd2"] # 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] f = os.popen('date') now = f.read() # Ping target host and set the status if args['hostip'] in valid_addresses: response = os.system('ping -c 1 ' + args['hostip'] + ' > /dev/null') if response == 0: pingstatus = "Host is Active" else: pingstatus = "Host is Inactive" else: pingstatus = "Invalid host" # Print RPC XML for the given style print ("<host-status-information>") print ("<{}>".format(args['level'])) print ("<hostip>{}</hostip>".format(args['hostip'])) print ("<status>{}</status>".format(pingstatus)) if args['level'] == "detail": print ("<date>{}</date>".format(now)) print ("</{}>".format(args['level'])) print ("</host-status-information>")
CLI 拡張スクリプト
CLI で の有効な値 hostip
を表示するロジックを処理するアクション スクリプトは 、hostip-expand.py。この例では、異なるリリースのスクリプトの引数を適切に処理する、2 つのバージョンのスクリプトを提供します。
CLI 拡張スクリプト(Junos OS リリース 21.2R1 以降)
#!/usr/bin/python3 # Junos OS Release 21.2R1 and later import jcs import argparse parser = argparse.ArgumentParser(description='This is a demo script.') parser.add_argument('--symbol', required=False, default='') args = parser.parse_args() description_ipv4 = "IPv4 address" description_ipv6 = "IPv6 address" expand_colon = ":" expand_units = "DC" expand_range = "1...128" item = ["10.10.10.1", "10.10.10.2", "2001:db8::1", "172.16.0.1", "198.51.100.1", "198.51.100.10", "2001:db8::fdd2"] for ip in item: if ip.startswith(args.symbol) or not args.symbol: if not expand_colon in ip: jcs.expand(ip, description_ipv4) else: jcs.expand(ip, description_ipv6, expand_units, expand_range)
CLI 拡張スクリプト(Junos OS リリース 21.1 以前)
#!/usr/bin/python # Junos OS Release 21.1 and earlier import sys import jcs symbol = "" # Retrieve user input in symbol argument and store the value if "symbol" in sys.argv: index = sys.argv.index("symbol") symbol = sys.argv[index+1] description_ipv4 = "IPv4 address" description_ipv6 = "IPv6 address" expand_colon = ":" expand_units = "DC" expand_range = "1...128" item = ["10.10.10.1", "10.10.10.2", "2001:db8::1", "172.16.0.1", "198.51.100.1", "198.51.100.10", "2001:db8::fdd2"] for ip in item: if ip.startswith(symbol) or not symbol: if not expand_colon in ip: jcs.expand(ip, description_ipv4) else: jcs.expand(ip, description_ipv6, expand_units, expand_range)
構成
Python スクリプトの実行を有効にする
デバイスが符号なしPythonスクリプトを実行できるようにします。
-
Junos OS リリースに
language python
応じて、 またはlanguage python3
ステートメントを設定します。[edit] user@host# set system scripts language (python | python3)
メモ:Junos OS リリース 20.2R1 およびリリース 22.3R1 Junos OS Evolved以降、デバイスは Python 3 を使用して YANG アクションと変換スクリプトを実行します。以前のリリースでは、Junos OS はこれらのスクリプトの実行に Python 2.7 のみを使用し、Junos OS Evolvedはデフォルトで Python 2.7 を使用してスクリプトを実行します。
-
設定をコミットします。
[edit] user@host# commit and-quit
デバイスでの YANG モジュールとスクリプトの読み込み
YANG モジュールとスクリプトを Junos デバイスに追加するには、次の手順に従います。
-
YANG モジュールとスクリプトを Junos デバイスにダウンロードします。
-
Python スクリプトが以下の要件を満たしていることを確認します。
-
ファイル所有者は、Junos OS
super-user
ログイン クラスの root またはユーザーのいずれかです。 -
ファイルの所有者のみが、ファイルの書き込み権限を持っています。
-
スクリプトには、 Junos デバイス上の YANG RPC 用アクション スクリプトの作成で説明されている適切なインタープリター 指令行が含まれています。
-
-
(オプション)YANGモジュールとアクションスクリプトの構文を検証します。
user@host> request system yang validate module /var/tmp/rpc-host-status.yang action-script [ /var/tmp/rpc-host-status.py /var/tmp/hostip-expand.py ] YANG modules validation : START YANG modules validation : SUCCESS Scripts syntax validation : START Scripts syntax validation : SUCCESS
-
YANG モジュールとスクリプトを新しい YANG パッケージに追加します。
user@host> request system yang add package rpc-host-status module /var/tmp/rpc-host-status.yang action-script [ /var/tmp/rpc-host-status.py /var/tmp/hostip-expand.py ] YANG modules validation : START YANG modules validation : SUCCESS Scripts syntax validation : START Scripts syntax validation : SUCCESS TLV generation: START TLV generation: SUCCESS Building schema and reloading /config/juniper.conf.gz ... mgd: commit complete Restarting mgd ...
-
Junos OS CLI を再起動するよう求められたら、 を押して
Enter
デフォルト値であるyes
、 または を入力 yes して 押しますEnter
。WARNING: cli has been replaced by an updated version: ... Restart cli using the new version ? [yes,no] (yes) yes Restarting cli ...
コンテキスト依存型ヘルプの検証
目的
CLI 拡張スクリプトが想定通りに動作することを確認します。
アクション
運用モードから、RPC 定義の ステートメントで定義された junos:command
コマンドを発行して、CLI でコンテキストに応じてヘルプをリクエストし、入力引数と疑問符(?)を含 hostip
めます。
user@host> show host-status hostip ? Possible completions: <hostip> Host IP address 10.10.10.1 IPv4 address 10.10.10.2 IPv4 address 172.16.0.1 IPv4 address 198.51.100.1 IPv4 address 198.51.100.10 IPv4 address 2001:db8::1 IPv6 address (DC 1...128) 2001:db8::fdd2 IPv6 address (DC 1...128)
部分的なユーザー入力で同じ操作を実行し、表示された値が入力と正しく一致していることを確認します。
user@host> show host-status hostip 198? Possible completions: <hostip> Host IP address 198.51.100.1 IPv4 address 198.51.100.10 IPv4 address
意味
この値に対 hostip
してコンテキストに応じてヘルプが要求された場合、デバイスはスクリプトを hostip-expand.py
呼び出します。このスクリプトは、ユーザーの入力(指定されている場合)を処理し、CLI で有効な完了を印刷します。ユーザー入力が指定されていない場合、スクリプトはすべての使用可能な値を印刷します。ユーザー入力が提供されると、スクリプトは一致する値のみを出力します。