如何在事件脚本中使用 RPC 和操作模式命令
大多数 Junos OS 操作模式命令具有 XML 等效物。事件脚本可使用 远程过程调用 (RPC) 协议在本地或远程设备上执行这些 XML 命令。 Junos XML API 操作开发人员参考中列出了具有 XML 等效物的所有操作模式命令。
SLAX 和 XSLT 脚本分别使用 jcs:invoke()
或 jcs:execute()
扩展功能在本地或远程设备上执行 RPC。在 Python 脚本中,使用 Junos PyEZ API 可轻松执行 RPC。每个 Junos PyEZ Device
类实例都有一个 rpc
属性,允许您执行通过 Junos XML API 可用的任何 RPC。与本地或远程设备建立会话后,可通过将属性和 RPC 方法名称附加 rpc
到设备实例来执行 RPC。返回值是从标记下 <rpc-reply>
的第一个元素开始的 XML 对象。
在以下章节中更详细地讨论在事件脚本中使用 RPC 和操作模式命令:
在本地设备上执行 RPC
在 SLAX 或 XSLT 事件脚本中,要在本地设备上执行 RPC,请将 RPC 包含在可变声明中,然后将扩展功能称为 jcs:invoke()
RPC 变量作为参数。以下片段在本地设备上调用 RPC:
XSLT 语法
<xsl:variable name="rpc"> <get-interface-information/> # Junos RPC for the show interfaces command </xsl:variable> <xsl:variable name="out" select="jcs:invoke($rpc)"/> ...
SLAX 语法
var $rpc = <get-interface-information>; var $out = jcs:invoke($rpc);
在 Python 事件脚本中,要在本地设备上执行 RPC,请使用空参数列表创建 Device
实例,并将属性和 RPC 方法名称和论证列表附加 rpc
到设备实例。
Python 语法
from jnpr.junos import Device with Device() as jdev: rsp = jdev.rpc.get_interface_information()
使用空参数列表创建 Device
实例以连接到本地设备时,Junos OS 会使用在 [edit event-options event-script file filename python-script-user]
层次结构级别上配置的用户的访问权限。如果省略了该 python-script-user
语句,Junos OS 将使用通用、无特权用户和组 nobody
的访问权限。
在远程设备上执行 RPC
在 SLAX 或 XSLT 事件脚本中,要在远程设备上执行 RPC,请先将 RPC 包含在可变声明中,然后使用 jcs:open()
扩展功能以及连接到远程设备所需的参数创建连接手柄。然后调用 jcs:execute()
扩展功能,将连接手柄和 RPC 变量作为参数。例如:
XSLT 语法
<xsl:variable name="rpc"> <get-interface-information/> </xsl:variable> <xsl:variable name="connection" select="jcs:open('198.51.100.1', 'bsmith', 'test123')"/> <xsl:variable name="out" select="jcs:execute($connection, $rpc)"/> <xsl:value-of select="jcs:close($connection)"/> ...
SLAX 语法
var $rpc = <get-interface-information>; var $connection = jcs:open("198.51.100.1", "bsmith","test123"); var $out = jcs:execute($connection, $rpc); expr jcs:close($connection); ...
在 Python 事件脚本中,要在远程设备上执行 RPC,请先创建一个使用连接到远程设备所需的参数的实例 Device
。然后通过将属性和 RPC 方法名称和论证列表附加 rpc
到设备实例来执行 RPC。
Python 语法
from jnpr.junos import Device with Device(host='198.51.100.1', user='bsmith', passwd='test123') as jdev: rsp = jdev.rpc.get_interface_information()
Junos OS 使用参数列表中 Device()
指定的用户的访问权限连接到远程设备并执行操作,即使在层次结构级别上为 python-script-user
语句 [edit event-options event-script file filename]
配置了其他用户。
为避免将远程连接详细信息直接添加至事件脚本,您可以为在 [edit event-options event-script file filename remote-execution]
层次结构级别的远程设备上执行 RPC 的每个事件脚本指定远程执行详细信息。我们建议将远程执行详细信息添加至配置,而不是直接在事件脚本中添加,因为所有信息都可在单个位置提供,而且在配置中加密直通语。
对于执行 RPC 的每个远程设备,配置设备主机名以及相应的用户名和密码。
[edit event-options event-script file filename] remote-execution { remote-hostname { username username; passphrase passphrase; } }
除了事件详细信息之外,远程主机名及其相应的用户名和传递语在事件策略执行时作为输入传递到事件脚本。有关转发至事件脚本的详细信息,请参阅 在事件脚本中使用事件和远程执行详细信息。
事件脚本引用用于创建与远程主机连接的功能的参数列表中的远程执行详细信息。建立连接后,脚本可在该设备上执行 RPC。
在 Python 事件脚本中,您参考 Junos PyEZ Device()
实例的参数列表中的远程执行详细信息。以下代码会通过为该事件脚本配置的所有主机的远程执行详细信息进行迭代,并连接到每个主机上并执行相同的 RPC。
Python 语法
from junos import Junos_Remote_Execution_Details from jnpr.junos import Device def main() for remote in Junos_Remote_Execution_Details(): hostname = remote.host username = remote.user passphrase = remote.passwd with Device(host=hostname, user=username, passwd=passphrase) as jdev: inv = jdev.rpc.get_interface_information() #process RPC information... if __name__ == "__main__": main()
在 SLAX 或 XSLT 脚本中,使用 jcs:open()
该功能并参考论证列表中的远程执行详细信息,创建与远程主机的连接。例如:
XSLT 语法
<xsl:variable name="rpc"> <get-interface-information/> </xsl:variable> <xsl:for-each select="event-script-input/remote-execution-details"> <xsl:variable name="d" select="remote-execution-detail"/> <xsl:variable name="connection" select="jcs:open($d/remote-hostname,$d/username,$d/passphrase)"/> <xsl:variable name="out" select="jcs:execute($connection, $rpc)"/> <xsl:value-of select="jcs:close($connection)"/> ... </xsl:for-each>
SLAX 语法
var $rpc = <get-interface-information>; for-each (event-script-input/remote-execution-details) { var $d = remote-execution-detail; var $connection = jcs:open($d/remote-hostname,$d/username,$d/passphrase); var $out = jcs:execute($connection, $rpc); expr jcs:close($connection); ... }
要在远程设备上执行 RPC,必须建立 SSH 会话。要使脚本建立连接,您必须为执行脚本的本地设备上的远程设备配置 SSH 主机密钥信息,或者远程设备的 SSH 主机密钥信息必须存在于执行脚本的用户的已知主机文件中。对于执行 RPC 的每个远程设备,请使用以下一种方法配置 SSH 主机密钥信息:
要在本地设备上配置 SSH 已知主机,请包括
host
语句,并在配置的层次结构级别为远程设备[edit security ssh-known-hosts]
指定主机名和主机密钥选项。要手动检索 SSH 主机密钥信息,请发出
set security ssh-known-hosts fetch-from-server hostname
配置模式命令,指示 Junos OS 连接到远程设备并添加密钥。user@host# set security ssh-known-hosts fetch-from-server router2 The authenticity of host 'router2 (198.51.100.1)' can't be established. RSA key fingerprint is 30:18:99:7a:3c:ed:40:04:0f:fd:c1:57:7e:6b:f3:90. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'router2,198.51.100.1' (RSA) to the list of known hosts.
要从文件中手动导入 SSH 主机密钥信息,请使用
set security ssh-known- hosts load-key-file filename
配置模式命令并指定已知主机文件。user@host# set security ssh-known-hosts load-key-file /var/tmp/known_hosts Import SSH host keys from trusted source /var/tmp/known_hosts ? [yes,no] (no) yes
或者,执行脚本的用户可以登录本地设备,将 SSH 登录到远程设备,然后手动接受主机密钥,主机密钥被添加到用户已知的主机文件中。在以下示例中,root 登录到路由器 1。为了在路由器 2 上执行远程 RPC,root 通过发出
ssh router2
操作模式命令并手动接受密钥来添加路由器 2 的主机密钥。root@router1> ssh router2 The authenticity of host 'router2 (198.51.100.1)' can't be established. RSA key fingerprint is 30:18:99:7a:3c:ed:40:04:0f:fd:c1:57:7e:6b:f3:90. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'router2,198.51.100.1' (RSA) to the list of known hosts.
配置所需的 SSH 主机密钥并获取到远程设备的连接手柄后,事件脚本可以执行具有该远程设备扩展功能的 jcs:execute()
RPC。
显示命令的 RPC 标记
您可在设备的 CLI 中显示用于操作模式命令的 RPC XML 标记。要显示用于命令的 RPC XML 标记,请在管道符号 (|) 后输入 display xml rpc
。
以下示例显示命令的 show route
RPC 标记:
user@host> show route | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/10.1I0/junos"> <rpc> <get-route-information> </get-route-information> </rpc> <cli> <banner></banner> </cli> </rpc-reply>
SLAX 和 XSLT 脚本可使用 RPC XML 标记执行 RPC。Python 脚本必须将 RPC 标记和命令选项转换为适合 Python 的格式。有关使用 Junos PyEZ 执行 RPC 以及将 RPC 标记映射到相应的 Python 方法和方法参数的详细信息,请参阅 使用 Junos PyEZ 在运行 Junos OS 的设备上执行 RPC。
在事件脚本中使用操作模式命令
某些操作模式命令没有 XML 等效物。SLAX 和 XSLT 脚本可使用该元素执行没有 XML 等效项的<command>
命令。Python 脚本可使用类中Device
定义的 Junos PyEZ cli()
方法执行这些命令。
如果 Junos XML API 操作开发人员参考中未列出命令,则该命令没有 XML 等效项。确定命令是否有 XML 等效项的另一种方法是发出 命令,然后 | display xml
发出 命令。
user@host> operational-mode-command | display xml
如果输出中仅包含标记元素,如 <output>
, <cli>
和 <banner>
, 命令可能没有 XML 等效项。在以下示例中,输出表示命令 show host
没有 XML 等效项:
user@host> show host hostname | display xml <rpc-reply xmlns:junos="http://xml.juniper.net/junos/10.0R1/junos"> <output> ... </output> <cli> <banner></banner> </cli> </rpc-reply>
对于具有 XML 对应项的某些命令,管道| display xml
命令的输出不包括标记元素,<output>
<cli>
<banner>
而只是因为未配置相关功能。例如,命令show services cos statistics forwarding-class
具有 XML 等效项,用于在响应标记中<service-cos-forwarding-class-statistics>
返回输出,但是如果配置在层次结构级别上[edit class-of-service]
不包含任何语句,则不会显示命令的实际数据show services cos statistics forwarding-class | display xml
。输出与此类似:
user@host> show services cos statistics forwarding-class | display xml <rpc-reply xmlns:junos="http://xml.juniper.net/junos/8.3I0/junos"> <cli> <banner></banner> </cli> </rpc-reply>
因此, Junos XML API 操作开发人员参考 中的信息通常更可靠。
SLAX 和 XSLT 事件脚本可执行无 XML 等效器件的命令。 <command>
使用脚本中的 、 <xsl:value-of>
和 <output>
元素,如以下代码片段所示。此片段在示例中进行了扩展并进行了全面介绍 :使用 Op Script 显示 DNS 主机名信息。
<xsl:variable name="query"> <command> <xsl:value-of select="concat('show host ', $hostname)"/> </command> </xsl:variable> <xsl:variable name="result" select="jcs:invoke($query)"/> <xsl:variable name="host" select="$result"/> <output> <xsl:value-of select="concat('Name: ', $host)"/> </output> ...
Python 事件脚本可使用 Junos PyEZ API 执行没有 XML 等效项的命令。在 cli()
类中 Device
定义的方法执行操作模式命令,并以文本格式返回输出。例如:
from jnpr.junos import Device def main(): with Device() as jdev: res = jdev.cli('show host hostname', warning=False) print (res) if __name__ == "__main__": main()
您也可指定 format='xml'
返回格式化为 Junos OS XML 元素的输出。有关 Junos PyEZ cli
方法的详细信息,请 参阅 http://junos-pyez.readthedocs.org/en/latest/_modules/jnpr/junos/device.html#Device.cli。