このページの目次
例: スクリプト内の接続のセッションプロトコルを指定する
次の例は、リモート デバイスとの接続を作成するときに、Junos 自動化スクリプト内でセッション プロトコルを指定する方法を示しています。具体的には、 サンプル op スクリプト は、Junos OS を実行しているリモート デバイスとの NETCONF セッションを確立し、NETCONF サーバーの機能を取得して印刷し、そのデバイスの設定を更新してコミットします。
要件
Junos OS リリース 11.4 以降を実行するルーティング、スイッチング、またはセキュリティ デバイス。
クライアントアプリケーションは、NETCONFサーバーが存在するデバイスにログインできます。
SSH経由のNETCONFサービスが、NETCONFサーバが存在するデバイスで有効になっている。
概要とスクリプト
jcs:open()
拡張機能には、Junos OSが動作するデバイス上のJunos XMLプロトコルサーバー、またはSSH経由のNETCONFサービスが有効になっているデバイス上のNETCONFサーバーとのセッションを作成するオプションが含まれています。次の例では、スクリプトが接続を作成し、Junos OS を実行しているリモート デバイスとの NETCONF セッションを確立します。接続とセッションが正常に確立されると、スクリプトはリモートデバイスの設定を更新し、 ステートメントをftp
階層レベルに追加します[edit system services]
。また、このスクリプトは、セッションプロトコルとNETCONFサーバーの機能を取得して出力します。
スクリプトは、 remote-host
リモート デバイスの IP アドレスまたはホスト名である 1 つの引数 を取ります。変数は arguments
スクリプトのグローバル レベルで宣言されるため、ユーザーが 状況依存のヘルプを必要とするときに、引数の名前と説明がコマンド ライン インターフェイス (CLI) に表示されます。
この変数 netconf
は、リモートデバイスのセッションプロトコルと接続パラメータを指定するノードセットです。要素の値は <method>
「netconf」に設定され、SSHv2 接続を介して NETCONF サーバーとのセッションを確立します。要素は <username>
、接続のユーザー名を指定します。ユーザー名を指定せず、接続に必要な場合、スクリプトはスクリプトを実行するユーザーのローカル名を使用します。この例では、パスフレーズとポートは指定されていません。認証にパスフレーズが必要な場合、リモートデバイスはスクリプトの実行中にパスフレーズの入力を求める必要があります。スクリプトは、デフォルトのNETCONFポート830を使用してセッションを確立します。
NETCONF セッションの接続と確立が成功すると、スクリプトはリモート プロシージャ コール(RPC)を実行します。RPCには、候補の設定をロック、編集、コミット、ロック解除するためのNETCONF操作であるタグ要素<lock>
、 <edit-config>
<commit>
、 、および <unlock>
が含まれています。このスクリプトは、各タスクの RPC を個別の変数に格納します。各 RPC の結果も個別に保存され、エラーがないか解析されます。スクリプトは、前のステップが成功した場合にのみ、後続の各ステップを実行します。たとえば、スクリプトが設定をロックできない場合、設定の編集、コミット、ロック解除を行う RPC は実行されません。
変数 rpc-edit-config
には、設定を変更するためのNETCONF操作であるtag要素 <edit-config>
が含まれています。子要素である には、 <config>
デバイス上の候補コンフィギュレーションとマージされたコンフィギュレーションの変更された部分が含まれます。エラーが発生した場合、スクリプトは ステートメントを呼び出して copy-of
結果ツリーフラグメント変数を結果ツリーにコピーし、スクリプト実行中にエラーメッセージが CLI に出力されるようにします。
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"; ns ext = "http://xmlsoft.org/XSLT/namespace"; var $arguments = { <argument> { <name> "remote-host"; <description> "device hostname or IP address to which to connect"; } } param $remote-host; match / { <op-script-results> { var $netconf := { <method> "netconf"; <username> "bsmith"; } var $rpc-lock-config = { <lock> { <target> { <candidate>; } } } var $rpc-unlock-config = { <unlock> { <target> { <candidate>; } } } var $rpc-commit = { <commit>; } var $rpc-edit-config = { <edit-config> { <target> { <candidate>; } <default-operation> "merge"; <config> { <configuration> { <system> { <services> { <ftp>; } } } } } } if ($remote-host = '') { <xnm:error> { <message> "missing mandatory argument 'remote-host'"; } } else { var $connection = jcs:open($remote-host, $netconf); if ($connection) { /* request protocol and capabilities */ var $protocol = jcs:get-protocol($connection); var $capabilities = jcs:get-hello($connection); <output> "\nSession protocol: " _ $protocol _ "\n"; copy-of $capabilities; /* execute rpcs to lock, edit, commit, and unlock config */ var $lock-reply = jcs:execute($connection, $rpc-lock-config); if ($lock-reply/..//rpc-error) { copy-of $lock-reply; } else { var $edit-config-reply = jcs:execute($connection, $rpc-edit-config); if ($edit-config-reply/..//rpc-error) { <output>"Configuration error: "_ $edit-config-reply/..//error-message/. _ "\nConfiguration not committed.\n" ; copy-of $edit-config-reply; } else { var $commit-reply = jcs:execute($connection, $rpc-commit); if ($commit-reply/..//rpc-error) { <output>"Commit error or warning: " _ $commit-reply/..//error-message/.; copy-of $commit-reply; } } var $unlock-reply = jcs:execute($connection, $rpc-unlock-config); } expr jcs:close($connection); } else { <output>"\nNo connection - exiting script"; } } } }
XSLT 構文
<?xml version="1.0" standalone="yes"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:junos="http://xml.juniper.net/junos/*/junos" xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm" xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0" xmlns:ext="http://xmlsoft.org/XSLT/namespace" version="1.0"> <xsl:variable name="arguments"> <argument> <name>remote-host</name> <description>device hostname or IP address to which to connect</description> </argument> </xsl:variable> <xsl:param name="remote-host"/> <xsl:template match="/"> <op-script-results> <xsl:variable name="netconf-temp-1"> <method>netconf</method> <username>bsmith</username> </xsl:variable> <xsl:variable xmlns:ext="http://xmlsoft.org/XSLT/namespace" name="netconf" select="ext:node-set($netconf-temp-1)"/> <xsl:variable name="rpc-lock-config"> <lock> <target> <candidate/> </target> </lock> </xsl:variable> <xsl:variable name="rpc-unlock-config"> <unlock> <target> <candidate/> </target> </unlock> </xsl:variable> <xsl:variable name="rpc-commit"> <commit/> </xsl:variable> <xsl:variable name="rpc-edit-config"> <edit-config> <target> <candidate/> </target> <default-operation>merge</default-operation> <config> <configuration> <system> <services> <ftp/> </services> </system> </configuration> </config> </edit-config> </xsl:variable> <xsl:choose> <xsl:when test="$remote-host = ''"> <xnm:error> <message>missing mandatory argument 'remote-host'</message> </xnm:error> </xsl:when> <xsl:otherwise> <xsl:variable name="connection" select="jcs:open($remote-host, $netconf)"/> <xsl:choose> <xsl:when test="$connection"> <!-- request protocol and capabilities --> <xsl:variable name="protocol" select="jcs:get-protocol($connection)"/> <xsl:variable name="capabilities" select="jcs:get-hello($connection)"/> <output> <xsl:value-of select="concat(' Session protocol: ', $protocol, ' ')"/> </output> <xsl:copy-of select="$capabilities"/> <!-- execute rpcs --> <xsl:variable name="lock-reply" select="jcs:execute($connection, $rpc-lock-config)"/> <xsl:choose> <xsl:when test="$lock-reply/..//rpc-error"> <xsl:copy-of select="$lock-reply"/> </xsl:when> <xsl:otherwise> <xsl:variable name="edit-config-reply" select="jcs:execute($connection, $rpc-edit-config)"/> <xsl:choose> <xsl:when test="$edit-config-reply/..//rpc-error"> <output> <xsl:value-of select="concat('Configuration error: ', $edit-config-reply/..//error-message/., ' Configuration not committed. ')"/> </output> <xsl:copy-of select="$edit-config-reply"/> </xsl:when> <xsl:otherwise> <xsl:variable name="commit-reply" select="jcs:execute($connection, $rpc-commit)"/> <xsl:if test="$commit-reply/..//rpc-error"> <output> <xsl:value-of select="concat('Commit error or warning: ', $commit-reply/..//error-message/.)"/> </output> <xsl:copy-of select="$commit-reply"/> </xsl:if> </xsl:otherwise> </xsl:choose> <xsl:variable name="unlock-reply" select="jcs:execute($connection, $rpc-unlock-config)"/> </xsl:otherwise> </xsl:choose> <xsl:value-of select="jcs:close($connection)"/> </xsl:when> <xsl:otherwise> <output>No connection - exiting script</output> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </op-script-results> </xsl:template> </xsl:stylesheet>
構成
手順
手順
スクリプトをダウンロード、有効化、およびテストするには:
XSLT または SLAX スクリプトをテキスト ファイルにコピーし、必要に応じてファイルに netconf-session.xsl または netconf-session.slax という名前を付けて、デバイスの /var/db/scripts/op/ ディレクトリにコピーします。
設定モードでは、 階層レベルに
[edit system scripts op]
ステートメントを含めfile
、必要に応じて netconf-session.xsl または netconf-session.slax を含めます。[edit system scripts op] bsmith@local-host# set file netconf-session.(slax | xsl)
コマンドを発行します
commit and-quit
。[edit] bsmith@local-host# commit and-quit
op モード コマンドを発行
op netconf-session
してローカル デバイスで op スクリプトを実行し、必要な引数を含めます。この例では、ユーザー bsmith はリモート デバイスである fivestar に接続しています。リモート デバイスにはデュアル ルーティング エンジンがあるため、
commit
この操作は、両方のルーティング エンジンに新しい候補構成をコミットするために コマンドを使用する必要があるという警告commit synchronize
を返します。bsmith@local-host> op netconf-session remote-host fivestar bsmith@fivestar's password: Session protocol: netconf Commit error or warning: graceful-switchover is enabled, commit synchronize should be used
検証
デバイスが正常に動作していることを確認します。
Op スクリプトの実行の検証
目的
スクリプトが期待どおりに動作することを確認します。
アクション
CLI と op スクリプト ログ ファイルでスクリプトの出力を確認します。実行中に発生したエラーに特に注意してください。デフォルトの op スクリプト ログ ファイルは /var/log/op-script.log です。ログファイルが非常に長い場合は、 コマンドに show log
オプションを追加して| last number-of-lines
表示を制限し、CLI に出力する行数を指定します。要素内の<op-script-results>
出力は、スクリプトの実行に関連しています。
bsmith@local-host> show log op-script.log | last 100 ...output omitted for brevity... <op-script-results xmlns:junos="http://xml.juniper.net/junos/*/junos" xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm" xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0" xmlns:ext="http://xmlsoft.org/XSLT/namespace"> <output> Session protocol: netconf </output> <hello> <capabilities> <capability>urn:ietf:params:xml:ns:netconf:base:1.0</capability> <capability>urn:ietf:params:xml:ns:netconf:capability:candidate:1.0 </capability> <capability>urn:ietf:params:xml:ns:netconf:capability:confirmed-commit:1.0 </capability> <capability>urn:ietf:params:xml:ns:netconf:capability:validate:1.0</capability> <capability> urn:ietf:params:xml:ns:netconf:capability:url:1.0?protocol=http,ftp,file </capability> <capability>http://xml.juniper.net/netconf/junos/1.0</capability> <capability>http://xml.juniper.net/dmi/system/1.0</capability> </capabilities> <session-id>29087</session-id> </hello> <output>Commit error or warning: graceful-switchover is enabled, commit synchronize should be used </output> <rpc-error> <error-severity>warning</error-severity> <error-message> graceful-switchover is enabled, commit synchronize should be used </error-message> </rpc-error> <ok/> </op-script-results>
また、opスクリプトの実行時に オプションを含める | display xml
ことで、Junos OSを実行しているデバイスでより説明的なスクリプト出力を得ることができます。
bsmith@local-host> op netconf-session remote-host fivestar | display xml <rpc-reply xmlns:junos="http://xml.juniper.net/junos/11.4D0/junos"> <output> Session protocol: netconf </output> <hello> <capabilities> <capability> urn:ietf:params:xml:ns:netconf:base:1.0 </capability> <capability> urn:ietf:params:xml:ns:netconf:capability:candidate:1.0 </capability> <capability> urn:ietf:params:xml:ns:netconf:capability:confirmed-commit:1.0 </capability> <capability> urn:ietf:params:xml:ns:netconf:capability:validate:1.0 </capability> <capability> urn:ietf:params:xml:ns:netconf:capability:url:1.0?protocol=http,ftp,file </capability> <capability> http://xml.juniper.net/netconf/junos/1.0 </capability> <capability> http://xml.juniper.net/dmi/system/1.0 </capability> </capabilities> <session-id> 29087 </session-id> </hello> <output> Commit error or warning: graceful-switchover is enabled, commit synchronize should be used </output> <rpc-error> <error-severity> warning </error-severity> <error-message> graceful-switchover is enabled, commit synchronize should be used </error-message> </rpc-error> <ok/> </op-script-results> <cli> <banner></banner> </cli> </rpc-reply>
意味
この例では、Junos OS を実行しているリモート デバイス上に NETCONF セッションを作成します。NETCONF サーバーの機能には、標準の NETCONF 操作と、 と で定義されているhttp://xml.juniper.net/netconf/junos/1.0
http://xml.juniper.net/dmi/system/1.0
ジュニパーネットワークス独自の拡張機能の両方が含まれます。操作の commit
RPC 結果には 1 つの警告が含まれていますが、コミット操作は成功しています。
設定変更の確認
目的
リモート デバイスで設定変更とコミット ログを表示して、コミットが成功したことを確認します。
アクション
リモート デバイスで、 show configuration system services
運用モード コマンドを実行して、設定の階層レベルを表示します [edit system services]
。スクリプトが成功した場合、設定には ステートメントが含まれます ftp
。
bsmith@fivestar> show configuration system services ftp; netconf { ssh; }
また、コミットログを確認することもできます。リモート デバイスで、 show system commit
運用モード コマンドを実行してコミット ログを表示します。この例では、指定された日時に bsmith が NETCONF セッションで候補コンフィギュレーションをコミットしたことがログから確認されています。
bsmith@fivestar> show system commit 0 2011-07-11 12:04:01 PDT by bsmith via netconf 1 2011-07-08 15:16:33 PDT by root via cli
トラブルシューティング
接続エラーのトラブルシューティング
問題
スクリプトは、次のエラー メッセージを生成します。
hello packet:1:(0) Document is empty hello packet:1:(0) Start tag expected, '<' not found error: netconf: could not read hello error: did not receive hello packet from server error: Error in creating the session with "fivestar" server No connection - exiting script
接続エラーの考えられる原因は次のとおりです。
接続しているデバイスまたはインターフェイスがダウンしているか、使用できません。
リモート デバイスの IP アドレスまたは DNS 名のスクリプト引数が正しくありません。
接続を確立する前に、接続タイムアウト値を超えました。
リモート デバイスのユーザー認証が無効であるか、正しく入力されていません。
NETCONF セッションを確立しようとしていますが、NETCONF サーバが存在するデバイスで SSH 経由の NETCONF が有効になっていないか、別のポートで有効になっています。
ソリューション
リモート デバイスが起動して実行中であり、ユーザーがデバイスにアクセスできることを確認します。また、スクリプトの実行時に、リモート デバイスの IP アドレスまたは DNS 名に正しい引数を指定したことも確認します。
NETCONF セッションの場合、NETCONF サーバが存在するデバイスで SSH 経由の NETCONF が有効になっていることを確認します。サンプルプログラムはNETCONFセッションの特定のポート番号を指定していないため、セッションはデフォルトのNETCONF-over-SSHポート830で確立されます。Junos OSを実行しているデバイスのデフォルトポートでSSH経由のNETCONFが有効になっているかどうかを確認するには、リモートデバイスで次の動作モードコマンドを入力します。
bsmith@fivestar> show configuration system services netconf { ssh; }
netconf
設定階層がリモートデバイスに存在しない場合、設定モードで以下のステートメントを発行し、デフォルトポートでSSH経由のNETCONFを有効にします。
[edit] bsmith@fivestar# set system services netconf ssh bsmith@fivestar# commit
構成階層で netconf
既定のポート以外のポートが指定されている場合は、関数に渡す XML ノード セットにポート番号を含めます jcs:open()
。例えば、以下のデバイスはポート12345でSSH経由のNETCONF用に設定されています。
bsmith@fivestar> show configuration system services netconf { ssh { port 12345; } }
代替ポートで NETCONF セッションを作成するには、XML ノード セットに新しいポート番号を含めます。
var $netconf := { <method> "netconf"; <username> "bsmith"; <port> "12345"; } var $connection = jcs:open($remote-host, $netconf); ...
設定ロックエラーのトラブルシューティング
問題
スクリプトは、次のいずれかのエラー メッセージを生成します。
configuration database locked by: root terminal p0 (pid 24113) on since 2011-07-11 11:48:06 PDT, idle 00:07:59
Users currently editing the configuration: root terminal p1 (pid 24279) on since 2011-07-11 12:28:30 PDT {master}[edit]
configuration database modified
ソリューション
別のユーザーが現在候補コンフィギュレーションをロックしているか、候補コンフィギュレーションを変更したが、まだコンフィギュレーションをコミットしていません。ロックが解除されるまで待ってから、プログラムを実行します。
設定構文エラーのトラブルシューティング
問題
次のエラー メッセージが CLI に出力されます。
Configuration error: syntax error Configuration not committed.
追加情報については、結果ツリーを調べます。この場合、結果ツリーには次のエラー メッセージが表示されます。
<rpc-error> <error-severity> error </error-severity> <error-info> <bad-element> ftp2 </bad-element> </error-info> <error-message> syntax error </error-message> </rpc-error>
ソリューション
<bad-element>
tag 要素は、設定ステートメントが無効であることを示しています。構成階層を修正し、スクリプトを実行します。この例のエラーでは、ユーザーが の代わりに <ftp>
タグ<ftp2>
を入力しました。これは設定で許容できる要素ではないため、NETCONFサーバーはエラーを返します。