示例:使用 NETCONF Perl 客户端应用程序更改配置
NETCONF Perl 分配包含多个示例 Perl 脚本,用于在运行 Junos OS 的设备上执行各种功能。 edit_configuration.pl 脚本在设备上锁定、修改、上传和提交配置。它使用基本结构发送请求,还定义了一个 graceful_shutdown 处理错误的子程序。以下部分介绍了脚本执行的不同功能:
处理错误状况
graceful_shutdown edit_configuration.pl 脚本中的子路由可处理 NETCONF 会话中遇到的错误。它使用以下附加常量:
# query execution status constants use constant REPORT_SUCCESS => 1; use constant REPORT_FAILURE => 0; use constant STATE_CONNECTED => 1; use constant STATE_LOCKED => 2; use constant STATE_CONFIG_LOADED => 3;
子路由中的前两 if 个语句指的是 STATE_CONFIG_LOADED 和 STATE_LOCKED 条件,这些语句特别适用于在 edit_configuration.pl 脚本中加载配置。
sub graceful_shutdown
{
my ($jnx, $state, $success) = @_;
if ($state >= STATE_CONFIG_LOADED) {
# We have already done an <edit-config> operation
# - Discard the changes
print "Discarding the changes made ...\n";
$jnx->discard_changes();
if ($jnx->has_error) {
print "Unable to discard <edit-config> changes\n";
}
}
if ($state >= STATE_LOCKED) {
# Unlock the configuration database
$jnx->unlock_config();
if ($jnx->has_error) {
print "Unable to unlock the candidate configuration\n";
}
}
if ($state >= STATE_CONNECTED) {
# Disconnect from the Netconf server
$jnx->disconnect();
}
if ($success) {
print "REQUEST succeeded !!\n";
} else {
print "REQUEST failed !!\n";
}
exit;
}
锁定配置
edit_configuration.pl 脚本的主要部分是从建立与 NETCONF 服务器的连接开始。然后,它会调用lock_configuration该方法来锁定配置数据库。如果发生错误,脚本将graceful_shutdown调用处理错误状况中描述的子程序。
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);
}
阅读配置数据
在以下代码示例中, edit_configuration.pl 脚本会读取并解析包含 Junos XML 配置标记元素或 ASCII 格式语句的文件。完整的示例遵循有关功能小节的详细讨论。
# 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;
上述代码示例的第一个子部分用于验证包含配置数据的文件是否存在。之前从命令行获取文件的名称并分配给变量 $xmlfile 。如果文件不存在,脚本将调用子 graceful_shutdown 程序。
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_xml_file 程序,该子程序可打开文件进行读取,并将其内容分配给变量 $config 。将 queryargs 键 target 设置为值 candidate。当脚本调用该方法时 edit_configuration ,将编辑候选配置。
# Read in the XML file
my $config = read_xml_file($xmlfile);
print "\n\n$config \n\n";
%queryargs = (
'target' => 'candidate'
);
-t如果在调用 edit_configuration.pl 脚本时包含命令行选项,则变量引用$xmlfile的文件应包含 ASCII 格式的配置语句,如 CLI 配置模式show命令返回的配置语句。如果配置语句采用 ASCII 格式的文本,则脚本将存储在标记元素中的变量中的$config配置括起来,并将结果存储在与queryargs散列键config-text关联的值configuration-text中。
-t如果在调用 edit_configuration.pl 脚本时未包含命令行选项,则变量引用$xmlfile的文件将包含 Junos XML 配置标记元素。在这种情况下,脚本仅将$config变量存储为与queryargs散列密钥config关联的值。
if ($opt{t}) {
$queryargs{'config-text'} = '<configuration text> . $config . </configuration-text>';
} else {
$queryargs{'config'} = $config;
编辑配置数据
脚本会调用该方法, edit_config 将配置更改加载到设备上。如果来自 NETCONF 服务器的响应有错误,它会调用 graceful_shutdown 子路由器。
$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 调用该方法,在设备上提交配置并将其配置为活动配置。
# 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);
}