将请求提交到 Perl 客户端应用程序中的 NETCONF 服务器
在 NETCONF Perl 客户端应用程序中,在与 NETCONF 服务器建立连接后,客户端应用程序可以在运行 Junos OS 的设备上执行操作或配置命令,以请求操作信息或更改配置。NETCONF Perl API 支持一组与 CLI 操作模式命令和 NETCONF 配置操作对应的方法。要执行命令,客户端应用调用与该命令对应的 Perl 方法。
从 Junos OS 16.1 版开始,NETCONF Perl 客户端与版本无关,托管在 GitHub 和 CPAN 上,可以管理运行任何 Junos OS 版本的设备。NETCONF Perl 客户端的不受版本限制,可以调用具有相应 Junos XML 请求标记的任何方法。
在 Junos OS 16.1 版之前,每个 Junos OS 版本都包括与版本相关的 NETCONF Perl 客户端的全新版本。每个版本的软件都支持一组方法,与特定的 CLI 操作模式命令和配置对象操作相对应。您可以查看该客户端版本支持的操作方法列表,方法是检查存储在 NETCONF Perl 发行版的 lib/Netconf/插件/插件/release目录中的文件。与配置对象操作对应的方法集在发行版的 lib/Netconf/Plugins.pm 文件中定义。
有关更多信息,请参阅以下部分:
将 Junos OS 命令和 NETCONF 操作映射到 Perl 方法
Junos XML API 操作开发人员参考中列出了具有 Junos XML 对应项的所有操作命令。您还可以显示 CLI 上具有相应 Junos XML 的任何操作模式命令的 Junos XML 请求标记元素。获取请求标记后,即可将其映射到相应的 Perl 方法名称。
要显示 CLI 中命令的 Junos XML 请求标记,请将 | display xml rpc
选项添加到命令后面。以下示例显示命令的请求标记 show route
:
user@host> show route | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/15.1R1/junos"> <rpc> <get-route-information> </get-route-information> </rpc> </rpc-reply>
您可以将操作命令的请求标记映射到 Perl 方法名称。要派生方法名称,请用下划线替换 request 标记中的任何连字符,并移除括起来的尖括号。例如, <get-route-information>
请求标记会映射到 get_route_information
方法名称。
同样,NETCONF 协议操作以相同的方式映射到 Perl 方法名称。例如,操作 <edit-config>
映射到 edit_config
方法名称。
提供方法选项
Perl 方法可以有一个或多个选项。下一节介绍了应用程序在 NETCONF Perl 客户端应用程序中定义方法选项时使用的说明。
没有选项的方法定义为
$NO_ARGS
,如该方法的以下条目中所述get_autoinstallation_status_information
:## Method : get_autoinstallation_status_information ## Returns: <autoinstallation-status-information> ## Command: "show system autoinstallation status" get_autoinstallation_status_information => $NO_ARGS,
要调用没有选项的方法,客户端应用遵循方法名称,括号内为空,如以下示例所示:
$jnx->get_autoinstallation_status_information();
固定格式选项定义为类型
$TOGGLE
。在以下示例中,get_ancp_neighbor_information
该方法有两个固定形式的选项,brief
以及detail
:## Method : get_ancp_neighbor_information ## Returns: <ancp-neighbor-information> ## Command: "show ancp neighbor" get_ancp_neighbor_information => { brief => $TOGGLE, detail => $TOGGLE, }
要调用方法时包含固定格式选项,请将选项设置为等于字符串
'True'
,如以下示例所示:$jnx->get_ancp_neighbor_information(brief => 'True');
注意:使用与版本相关的 NETCONF Perl 分布时,要包括固定格式选项,在调用方法时,请将选项设置为等于值 1(1)。
具有可变值的选项定义为类型
$STRING
。在以下示例中get_cos_drop_profile_information
,该方法采用参数profile_name
:## Method : get_cos_drop_profile_information ## Returns: <cos-drop-profile-information> ## Command: "show class-of-service drop-profile" get_cos_drop_profile_information => { profile_name => $STRING, },
要调用方法时包含变量值,请将值括在单引号中,如以下示例所示:
$jnx->get_cos_drop_profile_information(profile_name => 'user-drop-profile');
一组配置语句或相应的标记元素定义为类型
$DOM
。在以下示例中,get_config
该方法采用一组配置语句(以及两个属性):'get_config' => { 'source' => $DOM_STRING, 'source_url' => $URL_STRING, 'filter' => $DOM },
DOM 对象是 XML 代码:
my $xml_string = " <filter type=\"subtree\"> <configuration> <protocols> <bgp></bgp> </protocols> </configuration> </filter> "; my %queryargs = ( 'source' => "running", 'filter' => $xml_string, );
这将生成以下 RPC 请求:
<rpc message-id='1'> <get-config> <source> <running/> </source> <filter type="subtree"> <configuration> <protocols> <bgp></bgp> </protocols> </configuration> </filter> </get-config> </rpc>
方法可以将固定形式的选项、具有变量值的选项和一组配置语句组合在一起。例如, get_forwarding_table_information
该方法有四个固定形式的选项和五个带有可变值的选项:
## Method :get_forwarding_table_information
## Returns:<forwarding-table-information>
## Command: "show route forwarding-table" get_forwarding_table_information => { detail => $TOGGLE, extensive => $TOGGLE, multicast => $TOGGLE, family => $STRING, vpn => $STRING, summary => $TOGGLE, matching => $STRING, destination => $STRING, label => $STRING, },
提交请求
以下代码说明了向 NETCONF 服务器发送配置请求的推荐方法,并展示了如何处理错误情况。该$jnx
变量被定义为一个NET::Netconf::Manager
对象。从 edit_configuration.pl 示例脚本中获取的示例代码会锁定候选配置,加载配置更改,提交更改,然后解锁配置数据库,并断开与 NETCONF 服务器的连接。您可以在 https://github.com/Juniper/netconf-perl NETCONF Perl GitHub 存储库的示例/edit_configuration目录中查看完整的 edit_configuration.pl 脚本。
my $res; # Netconf server response # connect to the Netconf server my $jnx = new Net::Netconf::Manager(%deviceinfo); unless (ref $jnx) { croak "ERROR: $deviceinfo{hostname}: failed to connect.\n"; } # Lock the configuration database before making any changes print "Locking configuration database ...\n"; my %queryargs = ( 'target' => 'candidate' ); $res = $jnx->lock_config(%queryargs); # See if you got an error if ($jnx->has_error) { print "ERROR: in processing request \n $jnx->{'request'} \n"; graceful_shutdown($jnx, STATE_CONNECTED, REPORT_FAILURE); } # Load the configuration from the given XML file print "Loading configuration from $xmlfile \n"; if (! -f $xmlfile) { print "ERROR: Cannot load configuration in $xmlfile\n"; graceful_shutdown($jnx, STATE_LOCKED, REPORT_FAILURE); } # Read in the XML file my $config = read_xml_file($xmlfile); print "\n\n$config \n\n"; %queryargs = ( 'target' => 'candidate' ); # If we are in text mode, use config-text arg with wrapped # configuration-text, otherwise use config arg with raw # XML if ($opt{t}) { $queryargs{'config-text'} = '<configuration-text>' . $config . '</configuration-text>'; } else { $queryargs{'config'} = $config; } $res = $jnx->edit_config(%queryargs); # See if you got an error if ($jnx->has_error) { print "ERROR: in processing request \n $jnx->{'request'} \n"; # Get the error my $error = $jnx->get_first_error(); get_error_info(%$error); # Disconnect graceful_shutdown($jnx, STATE_LOCKED, REPORT_FAILURE); } # Commit the changes print "Committing the <edit-config> changes ...\n"; $jnx->commit(); if ($jnx->has_error) { print "ERROR: Failed to commit the configuration.\n"; graceful_shutdown($jnx, STATE_CONFIG_LOADED, REPORT_FAILURE); } # Unlock the configuration database and # disconnect from the Netconf server print "Disconnecting from the Netconf server ...\n"; graceful_shutdown($jnx, STATE_LOCKED, REPORT_SUCCESS);