このページで
例:op スクリプトを使用して show interfaces terse コマンドの出力をカスタマイズする
この例では、 op スクリプト を使用して、 コマンドの出力を show interfaces terse
カスタマイズします。XSLT スクリプトの 1 行ごとの説明が提供されます。
要件
この例では、Junos OSを実行しているデバイスを使用しています。
概要と運用スクリプト
デフォルトでは、 コマンドの show interfaces terse
レイアウトは次のようになります。
user@host> show interfaces terse Interface Admin Link Proto Local Remote dsc up up fxp0 up up fxp0.0 up up inet 192.168.71.246/21 fxp1 up up fxp1.0 up up inet 10.0.0.4/8 inet6 fe80::200:ff:fe00:4/64 fc00::10:0:0:4/64 tnp 4 gre up up ipip up up lo0 up up lo0.0 up up inet 127.0.0.1 --> 0/0 lo0.16385 up up inet inet6 fe80::2a0:a5ff:fe12:2f04 lsi up up mtun up up pimd up up pime up up tap up up
Junos XML では、出力フィールドは次のように表されます。
user@host> show interfaces terse | display xml <rpc-reply xmlns:junos="http://xml.juniper.net/junos/10.0R1/junos"> <interface-information xmlns="http://xml.juniper.net/junos/10.0R1/junos-interface" junos:style="terse"> <physical-interface> <name>dsc</name> <admin-status>up</admin-status> <oper-status>up</oper-status> </physical-interface> <physical-interface> <name>fxp0</name> <admin-status>up</admin-status> <oper-status>up</oper-status> <logical-interface> <name>fxp0.0</name> <admin-status>up</admin-status> <oper-status>up</oper-status> ... Remainder of output omitted for brevity ...
XSLT 構文
以下のスクリプトは、 コマンドの出力を show interfaces terse
カスタマイズします。スクリプトの説明を 1 行ずつ説明します。
1 <?xml version="1.0" standalone="yes"?> 2 <xsl:stylesheet version="1.0" 3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 4 xmlns:junos="http://xml.juniper.net/junos/*/junos" 5 xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm" 6 xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0"> 7 <xsl:import href="../import/junos.xsl"/> 8 <xsl:variable name="arguments"> 9 <argument> 10 <name>interface</name> 11 <description>Name of interface to display</description> 12 </argument> 13 <argument> 14 <name>protocol</name> 15 <description>Protocol to display (inet, inet6)</description> 16 </argument> 17 </xsl:variable> 18 <xsl:param name="interface"/> 19 <xsl:param name="protocol"/> 20 <xsl:template match="/"> 21 <op-script-results> 22 <xsl:variable name="rpc"> 23 <get-interface-information> 24 <terse/> 25 <xsl:if test="$interface"> 26 <interface-name> 27 <xsl:value-of select="$interface"/> 28 </interface-name> 29 </xsl:if> 30 </get-interface-information> 31 </xsl:variable> 32 <xsl:variable name="out" select="jcs:invoke($rpc)"/> 33 <interface-information junos:style="terse"> 34 <xsl:choose> 35 <xsl:when test="$protocol='inet' or $protocol='inet6' or $protocol='mpls' or $protocol='tnp'"> 36 <xsl:for-each select="$out/physical-interface/ logical-interface[address-family/address-family-name = $protocol]"> 37 <xsl:call-template name="intf"/> 38 </xsl:for-each> 39 </xsl:when> 40 <xsl:when test="$protocol"> 41 <xnm:error> 42 <message> 43 <xsl:text>invalid protocol: </xsl:text> 44 <xsl:value-of select="$protocol"/> 45 </message> 46 </xnm:error> 47 </xsl:when> 48 <xsl:otherwise> 49 <xsl:for-each select="$out/physical-interface/logical-interface"> 50 <xsl:call-template name="intf"/> 51 </xsl:for-each> 52 </xsl:otherwise> 53 </xsl:choose> 54 </interface-information> 55 </op-script-results> 56 </xsl:template> 57 <xsl:template name="intf"> 58 <xsl:variable name="status"> 59 <xsl:choose> 60 <xsl:when test="admin-status='up' and oper-status='up'"> 61 <xsl:text> </xsl:text> 62 </xsl:when> 63 <xsl:when test="admin-status='down'"> 64 <xsl:text>offline</xsl:text> 65 </xsl:when> 66 <xsl:when test="oper-status='down' and ../admin-status='down'"> 67 <xsl:text>p-offline</xsl:text> 68 </xsl:when> 69 <xsl:when test="oper-status='down' and ../oper-status='down'"> 70 <xsl:text>p-down</xsl:text> 71 </xsl:when> 72 <xsl:when test="oper-status='down'"> 73 <xsl:text>down</xsl:text> 74 </xsl:when> 75 <xsl:otherwise> 76 <xsl:value-of select="concat(oper-status, '/', admin-status)"/> 77 </xsl:otherwise> 78 </xsl:choose> 79 </xsl:variable> 80 <xsl:variable name="desc"> 81 <xsl:choose> 82 <xsl:when test="description"> 83 <xsl:value-of select="description"/> 84 </xsl:when> 85 <xsl:when test="../description"> 86 <xsl:value-of select="../description"/> 87 </xsl:when> 88 </xsl:choose> 89 </xsl:variable> 90 <logical-interface> 91 <name><xsl:value-of select="name"/></name> 92 <xsl:if test="string-length($desc)"> 93 <admin-status><xsl:value-of select="$desc"/></admin-status> 94 </xsl:if> 95 <admin-status><xsl:value-of select="$status"/></admin-status> 96 <xsl:choose> 97 <xsl:when test="$protocol"> 98 <xsl:copy-of select="address-family[address-family-name = $protocol]"/> 99 </xsl:when> 100 <xsl:otherwise> 101 <xsl:copy-of select="address-family"/> 102 </xsl:otherwise> 103 </xsl:choose> 104 </logical-interface> 105 </xsl:template> 106 </xsl:stylesheet>
回線ごとの説明
1~7行目、20行目、105行目と106行目は、すべてのopスクリプトに含まれる定型です。詳細については、「 Op スクリプトに必要な定型プレート」を参照してください。
1 <?xml version="1.0" standalone="yes"?> 2 <xsl:stylesheet version="1.0" 3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 4 xmlns:junos="http://xml.juniper.net/junos/*/junos" 5 xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm" 6 xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0"> 7 <xsl:import href="../import/junos.xsl"/> ... 20 <xsl:template match="/"> ... 105 </xsl:template> 106 </xsl:stylesheet>
8行目から17行目は、 と というarguments
変数を宣言しprotocol
、スクリプトに対する2つの引数を含みますinterface
。この変数宣言により、interface
protocol
スクリプトの引数としてコマンドライン インターフェイス(CLI)に および が表示されます。
8 <xsl:variable name="arguments"> 9 <argument> 10 <name>interface</name> 11 <description>Name of interface to display</description> 12 </argument> 13 <argument> 14 <name>protocol</name> 15 <description>Protocol to display (inet, inet6)</description> 16 </argument> 17 </xsl:variable>
18 行目と 19 行目は、8 行目から 17 行目で作成された引数に対応する 2 つのパラメーターをスクリプトに宣言します。パラメーター名は、引数名と完全に一致する必要があります。
18 <xsl:param name="interface"/> 19 <xsl:param name="protocol"/>
行 20~31 は、 という変数を宣言します rpc
。コマンドは show interfaces terse
変数に rpc
割り当てられます。スクリプトの実行時に引数を interface
含めると、引数の値(インターフェイス名)がスクリプトに渡されます。
20 <xsl:template match="/"> 21 <op-script-results> 22 <xsl:variable name="rpc"> 23 <get-interface-information> 24 <terse/> 25 <xsl:if test="$interface"> 26 <interface-name> 27 <xsl:value-of select="$interface"/> 28 </interface-name> 29 </xsl:if> 30 </get-interface-information> 31 </xsl:variable>
32 行目は、 という名前out
の変数を宣言し、 変数 (show interfaces terse
コマンド) の実行にrpc
適用します。
32 <xsl:variable name="out" select="jcs:invoke($rpc)"/>
33行目では、変更されるコマンドのshow interfaces
出力レベルがterse
(、 detail
、などとは対照的にextensive
)であることを指定します。
33 <interface-information junos:style="terse">
行 34~39 では、スクリプトの実行時に引数をprotocol
含める場合、および指定したプロトコル値が inet
、 、 inet6
mpls
、 または tnp
、 の場合、intf
そのプロトコル タイプの各インスタンスにテンプレートが適用されていることを指定します。
34 <xsl:choose> 35 <xsl:when test="$protocol='inet' or $protocol='inet6' or $protocol='mpls' or $protocol='tnp'"> 36 <xsl:for-each select="$out/physical-interface/ logical-interface[address-family/address-family-name = $protocol]"> 37 <xsl:call-template name="intf"/> 38 </xsl:for-each> 39 </xsl:when>
40~47 行目では、スクリプトの実行時に引数をprotocol
含める場合、および指定したプロトコル値が inet
、 、 inet6
mpls
、または tnp
、 以外のプロトコル値を生成するかどうかを指定します。
40 <xsl:when test="$protocol"> 41 <xnm:error> 42 <message> 43 <xsl:text>invalid protocol: </xsl:text> 44 <xsl:value-of select="$protocol"/> 45 </message> 46 </xnm:error> 47 </xsl:when>
48~52行目では、スクリプトの実行時に引数を protocol
含まない場合、 intf
テンプレートが出力内の各論理インターフェイスに適用されていることを指定しています。
48 <xsl:otherwise> 49 <xsl:for-each select="$out/physical-interface/logical-interface"> 50 <xsl:call-template name="intf"/> 51 </xsl:for-each> 52 </xsl:otherwise>
53~56行目は終了タグです。
53 </xsl:choose> 54 </interface-information> 55 </op-script-results> 56 </xsl:template>
57行目がテンプレートを intf
開きます。このテンプレートは、 コマンドの出力を show interfaces terse
カスタマイズします。
57 <xsl:template name="intf">
58行目は、 と呼ばれる status
変数を宣言します。その目的は、インターフェイスステータスの報告方法を指定することです。59~78行目には、 <xsl:choose>
考えられるすべての状態を考慮して変数を status
入力する命令が含まれています。XSLT では常に TRUE と評価される最初 <xsl:when>
の命令が実行され、残りの命令は無視されます。各 <xsl:when>
インストラクションは、それぞれ別々に説明されています。
58 <xsl:variable name="status"> 59 <xsl:choose>
60~62行目では、「up」でoper-status
「up」の場合admin-status
、出力は生成されません。この場合、変数はstatus
空のままになります。
60 <xsl:when test="admin-status='up' and oper-status='up'"> 61 <xsl:text> </xsl:text> 62 </xsl:when>
63行目から65行目では、もし'down'の場合 admin-status
、変数には status
テキストが含まれていることを指定します offline
。
63 <xsl:when test="admin-status='down'"> 64 <xsl:text>offline</xsl:text> 65 </xsl:when>
66~68行目では、物理インターフェイスadmin-status
が「ダウン」の場合oper-status
、変数にはstatus
テキストp-offline
が含まれています。(../
物理インターフェイスを選択します)。
66 <xsl:when test="oper-status='down' and ../admin-status='down'"> 67 <xsl:text>p-offline</xsl:text> 68 </xsl:when>
69~71行目では、物理インターフェイスoper-status
が「ダウン」の場合oper-status
、変数にはstatus
テキストp-down
が含まれています。(../
物理インターフェイスを選択します)。
69 <xsl:when test="oper-status='down' and ../oper-status='down'"> 70 <xsl:text>p-down</xsl:text> 71 </xsl:when>
72~74行目は、もし'down'の場合 oper-status
、変数に status
テキストが含まれていることを指定します down
。
72 <xsl:when test="oper-status='down'"> 73 <xsl:text>down</xsl:text> 74 </xsl:when>
75~77行目では、テスト・ケースが真でない場合、 status
変数に区切り記号としてスラッシュが含まれ oper-status
、 admin-status
連結されていることを指定します。
75 <xsl:otherwise> 76 <xsl:value-of select="concat(oper-status, '/', admin-status)"/> 77 </xsl:otherwise>
78行目と79行目は終了タグです。
78 </xsl:choose> 79 </xsl:variable>
80~89行目は、 と呼ばれる desc
変数を定義します。命令は <xsl:choose>
、利用可能な最も具体的なインターフェイス記述を選択して変数を入力します。論理インターフェイス記述が設定に含まれている場合は、 変数を入力 desc
するために使用されます。そうでない場合は、物理インターフェイスの説明が使用されます。設定に物理インターフェイスの説明が含まれていない場合、変数は空のままになります。XSLT では常に TRUE と評価される最初 <xsl:when>
の命令が実行され、残りの命令は無視されます。
80 <xsl:variable name="desc"> 81 <xsl:choose> 82 <xsl:when test="description"> 83 <xsl:value-of select="description"/> 84 </xsl:when> 85 <xsl:when test="../description"> 86 <xsl:value-of select="../description"/> 87 </xsl:when> 88 </xsl:choose> 89 </xsl:variable>
残りのスクリプトは、動作モード出力の表示方法を指定します。
行90および91では、出力で論理インターフェイス名が最初に表示されていることを指定します。
90 <logical-interface> 91 <name><xsl:value-of select="name"/></name>
92~94行目は、変数の desc
文字数が0以外であるかどうかをテストします。文字数がゼロを超える場合、インターフェイス記述はフィールドの標準的な場所に admin-status
表示されます。(標準出力では、 admin-status
フィールドは 2 行目に表示されます。
92 <xsl:if test="string-length($desc)"> 93 <admin-status><xsl:value-of select="$desc"/></admin-status> 94 </xsl:if>
95行目は、 変数で定義されたインターフェイスステータスが status
次に表示されていることを指定します。
95 <admin-status><xsl:value-of select="$status"/></admin-status>
行96~103では、スクリプトの実行時に引数を protocol
含めると、そのプロトコルが設定されたインターフェイスのみが表示されるように指定されています。引数を protocol
含まない場合、すべてのインターフェイスが表示されます。
96 <xsl:choose> 97 <xsl:when test="$protocol"> 98 <xsl:copy-of select="address-family[address-family-name = $protocol]"/> 99 </xsl:when> 100 <xsl:otherwise> 101 <xsl:copy-of select="address-family"/> 102 </xsl:otherwise> 103 </xsl:choose>
104~106行目は終了タグです。
104 </logical-interface> 105 </xsl:template> 106 </xsl:stylesheet>
SLAX 構文
スクリプトの 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 "../import/junos.xsl"; var $arguments = { <argument> { <name> "interface"; <description> "Name of interface to display"; } <argument> { <name> "protocol"; <description> "Protocol to display (inet, inet6)"; } } param $interface; param $protocol; match / { <op-script-results> { var $rpc = { <get-interface-information> { <terse>; if ($interface) { <interface-name> $interface; } } } var $out = jcs:invoke($rpc); <interface-information junos:style="terse"> { if ($protocol='inet' or $protocol='inet6' or $protocol='mpls' or $protocol='tnp') { for-each ($out/physical-interface/ logical-interface[address-family/address-family-name = $protocol]) { call intf(); } } else if ($protocol) { <xnm:error> { <message> { expr "invalid protocol: "; expr $protocol; } } } else { for-each ($out/physical-interface/logical-interface) { call intf(); } } } } } intf () { var $status = { if (admin-status='up' and oper-status='up') { } else if (admin-status='down') { expr "offline"; } else if (oper-status='down' and ../admin-status='down') { expr "p-offline"; } else if (oper-status='down' and ../oper-status='down') { expr "p-down"; } else if (oper-status='down') { expr "down"; } else { expr oper-status _ '/' _ admin-status; } } var $desc = { if (description) { expr description; } else if (../description) { expr ../description; } } <logical-interface> { <name> name; if (string-length($desc)) { <admin-status> $desc; } <admin-status> $status; if ($protocol) { copy-of address-family[address-family-name = $protocol]; } else { copy-of address-family; } } }
構成
手順
手順
スクリプトをダウンロード、有効化、テストするには、以下の手順にしたがっています。
XSLT または SLAX スクリプトをテキスト ファイルにコピーし、必要に応じてファイル interface.xsl または interface.slax に名前を付け、デバイス上の /var/db/scripts/op/ ディレクトリにコピーします。
設定モードでは、必要に応じて、
file
ステートメントを[edit system scripts op]
階層レベルと interface.xsl または interface.slax に含めます。[edit system scripts op] user@host# set file interface.(slax | xsl)
コマンドを
commit and-quit
発行して設定をコミットし、動作モードに戻ります。[edit] user@host# commit and-quit
運用モード コマンドを発行して、op スクリプトを
op interface
実行します。
検証
コミット スクリプト出力の検証
目的
スクリプトが想定どおりに動作していることを確認します。
アクション
および 操作コマンドをshow interfaces terse
op interface
発行し、出力を比較します。コマンドはshow interfaces terse
、標準出力を表示します。コマンドはop interface
、カスタマイズされた出力を表示します。
user@host> show interfaces terse Interface Admin Link Proto Local Remote dsc up up fxp0 up up fxp0.0 up up inet 192.168.71.246/21 fxp1 up up fxp1.0 up up inet 10.0.0.4/8 inet6 fe80::200:ff:fe00:4/64 fc00::10:0:0:4/64 tnp 4 gre up up ipip up up lo0 up up lo0.0 up up inet 127.0.0.1 --> 0/0 lo0.16385 up up inet inet6 fe80::2a0:a5ff:fe12:2f04 lsi up up mtun up up pimd up up pime up up tap up up user@host> op interface Interface Admin Link Proto Local Remote fxp0.0 This is the Ethernet Management interface. inet 192.168.71.246/21 fxp1.0 inet 10.0.0.4/8 inet6 fe80::200:ff:fe00:4/64 fc00::10:0:0:4/64 tnp 4 lo0.0 inet 127.0.0.1 --> 0/0 lo0.16385 inet inet6 fe80::2a0:a5ff:fe12:2f04-->
異なる階層レベルの op interface
操作コマンドを発行し、出力を確認します。例えば:
user@host> op interface interface fxp0 Interface Admin Link Proto Local Remote fxp0.0 This is the Ethernet Management interface. inet 192.168.71.246/21 user@host> op interface protocol inet Interface Admin Link Proto Local Remote fxp0.0 This is the Ethernet Management interface. inet 192.168.71.246/21 fxp1.0 inet 10.0.0.4/8 lo0.0 inet 127.0.0.1 --> 0/0 lo0.16385 inet