示例:使用提交脚本生成持久性和瞬态配置更改
示例:生成持续更改
Junos OS 提交脚本使用户能够根据自己的实践和策略自定义其配置的验证流程,并在提交过程中实施自定义配置规则。此示例演示了一个提交脚本,该脚本会生成 一个永久更改 ,当配置中尚未包含该语句时,该脚本会将该语句添加到 family mpls SONET/SDH 接口的配置中。如果未在接口上显式配置 MPLS 协议家族,则接口不会为 MPLS 应用程序启用。
要求
此示例使用以下硬件和软件组件:
通过一个或多个 SONET/SDH 接口运行 Junos OS 的设备。
Junos OS 16.1R3 或更高版本,使用 Python 脚本时。
概述和提交脚本
此示例中的提交脚本将查找所有配置了逻辑接口但未 family mpls 配置语句的 SONET/SDH 接口。对于这些接口,脚本会将该 family mpls 语句作为层级的 [edit interfaces interface-name unit logical-unit-number] 持久更改添加到接口配置中。该脚本显示在 SLAX、XSLT 和 Python 中。
提交脚本的 SLAX 和 XSLT 版本使用该 jcs:emit-change 模板生成永久更改,该模板是 junos.xsl 导入文件中包含的一个帮助器模板。省 tag 略模板的参数 jcs:emit-change ,这会指示脚本将更改作为永久更改发出。模板 content 参数 jcs:emit-change 包括要添加为永久更改的配置语句。模板 message 参数 jcs:emit-change 包括将在 CLI 中显示的警告消息,通知您配置已更改。
Python 版本的提交脚本使用 jcs.emit_change() 从 jcs 模块导入的功能生成永久更改。Python 脚本通过传递定位参数“change”来表明这是一个永久更改。
XSLT 语法
<?xml version="1.0" standalone="yes"?>
<xsl:stylesheet version="1.0"
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">
<xsl:import href="../import/junos.xsl"/>
<xsl:template match="configuration">
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-')]/unit">
<xsl:if test="not(family/mpls)">
<xsl:call-template name="jcs:emit-change">
<xsl:with-param name="message">
<xsl:text>Adding 'family mpls' to SONET/SDH interface.</xsl:text>
</xsl:with-param>
<xsl:with-param name="content">
<family>
<mpls/>
</family>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
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";
match configuration {
for-each (interfaces/interface[starts-with(name, 'so-')]/unit) {
if (not(family/mpls)) {
call jcs:emit-change() {
with $message = {
expr "Adding 'family mpls' to SONET/SDH interface.";
}
with $content = {
<family> {
<mpls>;
}
}
}
}
}
}
Python 语法
from junos import Junos_Configuration
import jcs
def main():
# Get configuration root object
root = Junos_Configuration
for element in root.xpath("./interfaces/ \
interface[starts-with(name,'so-')]/unit"):
if element.find('family/mpls') is None:
if_name = element.find('../name').text
unit_name = element.find('name').text
change_xml = """
<interfaces>
<interface>
<name>{0}</name>
<unit>
<name>{1}</name>
<family>
<mpls>
</mpls>
</family>
</unit>
</interface>
</interfaces>
""".format(if_name, unit_name).strip()
jcs.emit_change(change_xml, "change", "xml")
jcs.emit_warning("Adding 'family mpls' to SONET/SDH interface: " + if_name)
if __name__ == '__main__':
main()
配置
程序
逐步过程
下载、启用和测试脚本。
将脚本复制到文本文件中,将文件命名为 mpls.xsl、 mpls.slax 或 mpls.py ,并将其复制到设备上的 /var/db/script/commit/ 目录中。
注意:未签名的 Python 脚本必须由 Junos OS
super-user登录类中的 root 或用户所有,并且只有文件所有者才能对该文件拥有写权限。在配置模式下,在
file层次结构级别配置语句和脚本文件名[edit system scripts commit]。[edit] user@host# set system scripts commit file mpls.xsl
如果脚本是用 Python 编写的,请启用执行未签名的 Python 脚本。
[edit] user@host# set system scripts language python
注意:将
language python3语句配置为使用 Python 3 执行 Python 脚本,或将语句配置为language python使用 Python 2.7 执行 Python 脚本。有关更多信息,请参阅 语言。要测试提交脚本是否正确生成永久更改,请确保配置包含引发更改的条件。要测试此脚本,请确保至少
family mpls一个 SONET/SDH 接口的[edit interfaces so-fpc/pic/port unit logical-unit-number]层级不包含该语句。commit check发出命令以预览提交脚本处理的跟踪,以验证脚本是否会向候选配置添加永久更改。命令commit check在提交之前验证配置的语法,但不会提交更改。此示例中的提交脚本会为其所做的每次更改生成一条消息。
commit check使用命令预览这些消息,以确定脚本是否会使用相应接口的family mpls语句更新配置。发出命令以显示
commit check | display xml消息的 XML 格式版本。示例输出指示脚本将在提交操作期间将family mpls语句添加到 so-2/3/4.0 接口配置中。[edit] user@host# commit check | display xml <rpc-reply xmlns:junos="http://xml.juniper.net/junos/11.2R1/junos"> <commit-results> <routing-engine junos:style="normal"> <name>re0</name> <xnm:warning xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm"> <edit-path> [edit interfaces interface so-2/3/4 unit 0] </edit-path> <message> Adding 'family mpls' to SONET/SDH interface. </message> </xnm:warning> <commit-check-success/> </routing-engine> </commit-results> </rpc-reply>要显示提交脚本处理的详细跟踪,请发出
commit check | display detail命令。在示例输出中,有一个持续更改将在提交操作期间加载到配置中。[edit] user@host# commit check | display detail 2011-06-17 14:17:35 PDT: reading commit script configuration 2011-06-17 14:17:35 PDT: testing commit script configuration 2011-06-17 14:17:35 PDT: opening commit script '/var/db/scripts/commit/mpls.xsl' 2011-06-17 14:17:35 PDT: reading commit script 'mpls.xsl' 2011-06-17 14:17:35 PDT: running commit script 'mpls.xsl' 2011-06-17 14:17:35 PDT: processing commit script 'mpls.xsl' 2011-06-17 14:17:35 PDT: no errors from mpls.xsl 2011-06-17 14:17:35 PDT: saving commit script changes for script mpls.xsl 2011-06-17 14:17:35 PDT: summary of script mpls.xsl: changes 1, transients 0, syslog 0 2011-06-17 14:17:35 PDT: start loading commit script changes 2011-06-17 14:17:35 PDT: loading commit script changes into real db 2011-06-17 14:17:35 PDT: finished commit script changes into real db 2011-06-17 14:17:35 PDT: no transient commit script changes 2011-06-17 14:17:35 PDT: finished loading commit script changes 2011-06-17 14:17:35 PDT: copying juniper.db to juniper.data+ 2011-06-17 14:17:35 PDT: finished copying juniper.db to juniper.data+ ... configuration check succeeds
验证脚本是否生成了正确的更改后,发出
commit命令以启动提交操作并执行脚本。user@host# commit
验证
验证配置
目的
验证是否已将正确的更改集成到配置中。
行动
执行提交操作后,通过发出 show interfaces 配置模式命令查看配置。如果在脚本运行之前,在一个或多个 SONET/SDH 接口上未启用 MPLS 协议家族,则输出类似于以下内容:
[edit]
user@host# show interfaces
... other configured interface types ...
so-2/3/4 {
unit 0 {
family mpls; # Added by persistent change
}
}
... other configured interface types ...
示例:生成瞬时更改
此示例使用提交脚本在所有启用 IPv4 协议家族的 SONET/SDH 接口上设置 PPP 封装。这些更改会作为瞬时更改添加。
要求
此示例使用以下硬件和软件组件:
通过一个或多个 SONET/SDH 接口运行 Junos OS 的设备。
Junos OS 16.1R3 或更高版本,使用 Python 脚本时。
概述和提交脚本
此示例中的 commit 脚本会查找配置中启用了 IPv4 协议家族的所有 SONET/SDH 接口,并将语句 encapsulation ppp 添加到接口配置中。提交脚本会生成一个瞬时更改,这会将更改添加到检出配置中,但不会添加到候选配置中。该脚本显示在 SLAX、XSLT 和 Python 中。
提交脚本的 SLAX 和 XSLT 版本使用该 jcs:emit-change 模板生成瞬时更改,该模板是 junos.xsl 导入文件中包含的一个帮助器模板。模板 tag 的参数 jcs:emit-change 有值 transient-change,该值指示脚本将更改作为 瞬时更改 发出,而不是 作为永久更改。模板 content 参数 jcs:emit-change 包括要添加为瞬态更改的配置语句。
Python 版本的提交脚本使用 jcs.emit_change() 从 jcs 模块导入的功能生成瞬态更改。Python 脚本通过传递位置参数“瞬时更改”来表明这是一个瞬时更改。
XSLT 语法
<?xml version="1.0" standalone="yes"?>
<xsl:stylesheet version="1.0"
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">
<xsl:import href="../import/junos.xsl"/>
<xsl:template match="configuration">
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-')
and unit/family/inet]">
<xsl:call-template name="jcs:emit-change">
<xsl:with-param name="tag" select="'transient-change'"/>
<xsl:with-param name="content">
<encapsulation>ppp</encapsulation>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
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";
match configuration {
for-each (interfaces/interface[starts-with(name, 'so-') and unit/family/inet]) {
call jcs:emit-change($tag = 'transient-change') {
with $content = {
<encapsulation> "ppp";
}
}
}
}
Python 语法
from junos import Junos_Configuration
import jcs
def main():
# Get configuration root object
root = Junos_Configuration
for element in root.xpath("./interfaces/ \
interface[starts-with(name,'so-') and unit/family/inet]"):
if_name = element.find('name').text
change_xml = """
<interfaces>
<interface>
<name>{0}</name>
<encapsulation>ppp</encapsulation>
</interface>
</interfaces>
""".format(if_name).strip()
jcs.emit_change(change_xml, "transient-change", "xml")
jcs.emit_warning("Adding 'ppp' encapsulation to SONET interface: " + if_name)
jcs.emit_warning(change_xml)
if __name__ == '__main__':
main()
配置
程序
逐步过程
下载、启用和测试脚本。
将脚本复制到文本文件中,将文件命名 为 encap-ppp.xsl、 encap-ppp.slax 或 encap-ppp.py ,并将其复制到设备上的 /var/db/script/commit/ 目录中。
注意:未签名的 Python 脚本必须由 Junos OS
super-user登录类中的 root 或用户所有,并且只有文件所有者才能对该文件拥有写权限。在配置模式下,在
file层次结构级别配置语句和脚本文件名[edit system scripts commit]。[edit] user@host# set system scripts commit file encap-ppp.xsl
配置语句,
allow-transients使提交脚本能够将瞬时更改加载到结账配置中。[edit] user@host# set system scripts commit allow-transients
如果脚本是用 Python 编写的,请启用执行未签名的 Python 脚本。
[edit] user@host# set system scripts language python
注意:将
language python3语句配置为使用 Python 3 执行 Python 脚本,或将语句配置为language python使用 Python 2.7 执行 Python 脚本。有关更多信息,请参阅 语言。要测试提交脚本是否能够正确生成瞬时更改,请确保配置包含引发更改的条件。确保
encapsulation ppp至少一个 SONET/SDH 接口的[edit interfaces so-fpc/pic/port]层级不包含该语句。commit check发出命令以预览提交脚本处理的跟踪,以验证脚本是否会向结账配置添加瞬时更改。命令commit check在提交之前验证配置的语法,但不会提交更改。发出命令以显示
commit check | display detail提交脚本处理的详细跟踪。在示例输出中,有两个瞬态更改加载到结账配置中。[edit] user@host# commit check | display detail 2011-06-15 12:07:30 PDT: reading commit script configuration 2011-06-15 12:07:30 PDT: testing commit script configuration 2011-06-15 12:07:30 PDT: opening commit script '/var/db/scripts/commit/encap-ppp.xsl' 2011-06-15 12:07:30 PDT: reading commit script 'encap-ppp.xsl' 2011-06-15 12:07:30 PDT: running commit script 'encap-ppp.xsl' 2011-06-15 12:07:30 PDT: processing commit script 'encap-ppp.xsl' 2011-06-15 12:07:30 PDT: no errors from encap-ppp.xsl 2011-06-15 12:07:30 PDT: saving commit script changes for script encap-ppp.xsl 2011-06-15 12:07:30 PDT: summary of script encap-ppp.xsl: changes 0, transients 2 (allowed), syslog 0 2011-06-15 12:07:30 PDT: start loading commit script changes 2011-06-15 12:07:30 PDT: no commit script changes 2011-06-15 12:07:30 PDT: updating transient changes into transient tree 2011-06-15 12:07:30 PDT: finished loading commit script changes 2011-06-15 12:07:30 PDT: copying juniper.db to juniper.data+ 2011-06-15 12:07:30 PDT: finished copying juniper.db to juniper.data+ 2011-06-15 12:07:30 PDT: exporting juniper.conf 2011-06-15 12:07:30 PDT: merging transient changes ... configuration check succeeds
验证脚本是否生成了正确的更改后,发出
commit命令以启动提交操作并执行脚本。user@host# commit
验证
验证配置
目的
验证是否已将正确的更改集成到结账配置中。如果启用了一个或多个 SONET/SDH 接口并启用了 IPv4 协议家族,您应该会看到该 encapsulation ppp 语句添加为对接口层次结构的 瞬时更改 。
行动
要查看具有瞬时更改的配置,请发出 show interfaces | display commit-scripts 配置模式命令。命令 show interfaces | display commit-scripts 将显示配置中的所有语句,包括由瞬时更改生成的语句。如果启用了一个或多个 SONET/SDH 接口并启用了 IPv4 协议系列,则输出类似于以下内容:
[edit]
user@host# show interfaces | display commit-scripts
...
so-1/2/3 {
mtu 576;
encapsulation ppp; /* Added by transient change. */
unit 0 {
family inet {
address 10.0.0.3/32;
}
}
}
so-1/2/4 {
encapsulation ppp; /* Added by transient change. */
unit 0 {
family inet {
address 10.0.0.4/32;
}
}
}
so-2/3/4 {
encapsulation cisco-hdlc; # Not affected by the script, because IPv4 protocol
# family is not configured on this interface.
unit 0 {
family mpls;
}
}
故障 排除
提交错误的故障排除
问题
CLI 会生成无效的瞬时更改错误,提交失败。
user@host# commit check error: invalid transient change generated by commit script: encap-ppp.xsl warning: 1 transient change was generated without [system scripts commit allow-transients] error: 1 error reported by commit scripts error: commit script failure
解决 方案
您必须在[edit system scripts commit]层次结构级别配置语句allow-transients,以便提交脚本将瞬时更改加载到检出配置中。
配置以下语句以允许瞬时更改:
[edit] user@host# set system scripts commit allow-transients