使用 Junos PyEZ 检索配置
总结 您可以创建 Junos PyEZ 应用程序,以便从 Junos 设备上的指定配置数据库中检索配置数据。
Junos PyEZ 应用程序可以在 Junos 设备上按需执行远程过程调用 (RPC)。创建类的 Device 实例后,应用程序可以将 RPC 作为实例的属性 Device 执行。Junos PyEZ 应用程序可以使用 get_config() RPC 请求本机 Junos OS 配置以及与已添加到设备的标准(IETF、OpenConfig)或自定义 YANG 数据模型对应的配置数据的完整配置或配置的选定部分。
Junos PyEZ get_config RPC 调用 Junos XML 协议 <get-configuration> 操作。有关操作 <get-configuration> 及其选项的详细信息,请参阅 <get-configuration>。
本主题讨论如何使用 Junos PyEZ get_config() RPC 检索配置。有关使用表和视图检索配置数据的信息,请参阅 定义 Junos PyEZ 配置表 和使用 Junos PyEZ 配置表检索配置数据。
检索完整的候选配置
要从 Junos 设备检索完整的候选配置,请执行 get_config() RPC。默认输出格式为 XML。例如:
from jnpr.junos import Device
from lxml import etree
with Device(host='router1.example.net') as dev:
data = dev.rpc.get_config()
print (etree.tostring(data, encoding='unicode', pretty_print=True))
指定配置数据的源数据库
当 Junos PyEZ 应用程序使用 RPC 从 get_config() Junos 设备检索配置信息时,默认情况下,服务器会从候选配置数据库中返回数据。Junos PyEZ 应用程序还可以从提交的配置数据库或临时配置数据库中检索配置数据。
候选配置数据库
若要从候选配置数据库中检索数据,请执行 get_config() RPC,并选择性地包含任何其他参数。
from jnpr.junos import Device
from lxml import etree
with Device(host='router1.example.net') as dev:
data = dev.rpc.get_config()
print (etree.tostring(data, encoding='unicode', pretty_print=True))
提交的配置数据库
若要从提交的配置数据库中检索数据,请在 options RPC 调用中包含get_config()参数'database':'committed'。
from jnpr.junos import Device
from lxml import etree
with Device(host='router1.example.net') as dev:
data = dev.rpc.get_config(options={'database' : 'committed'})
print (etree.tostring(data, encoding='unicode', pretty_print=True))
临时配置数据库
Junos PyEZ 支持对支持此数据库的设备上的 临时配置数据库 执行操作。从共享配置数据库中检索配置数据时,默认情况下,结果不包括临时配置数据库中的数据。
临时数据库是一种备用配置数据库,提供用于在 Junos 设备上执行配置更新的快速编程接口。临时配置数据库是一项高级功能,如果使用不当,可能会对设备的操作产生严重的负面影响。有关更多信息,请参阅 了解临时配置数据库。
若要从临时配置数据库的默认实例中检索数据,请先打开默认临时实例,然后请求数据。要打开默认实例,请使用上下文管理器创建 Config 实例,并包含 mode='ephemeral' 参数。例如:
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
from jnpr.junos.exception import ConnectError
from lxml import etree
dev = Device(host='router1.example.net')
try:
dev.open()
with Config(dev, mode='ephemeral') as cu:
data = dev.rpc.get_config(options={'format':'text'})
print(etree.tostring(data, encoding='unicode'))
dev.close()
except ConnectError as err:
print ("Cannot connect to device: {0}".format(err))
except Exception as err:
print (err)
若要从临时配置数据库的特定实例中检索数据,请先打开临时实例,然后请求数据。要打开临时配置数据库的用户定义实例,请使用上下文管理器创建 Config 实例,包括 mode='ephemeral' 参数,并将参数设置为 ephemeral_instance 临时实例的名称。
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
from jnpr.junos.exception import ConnectError
from lxml import etree
dev = Device(host='router1.example.net')
try:
dev.open()
with Config(dev, mode='ephemeral', ephemeral_instance='eph1') as cu:
data = dev.rpc.get_config(options={'format':'text'})
print(etree.tostring(data, encoding='unicode'))
dev.close()
except ConnectError as err:
print ("Cannot connect to device: {0}".format(err))
except Exception as err:
print (err)
指定要返回的配置数据的范围
除了检索完整的 Junos OS 配置之外,Junos PyEZ 应用程序还可以通过使用参数调用 get_config() filter_xml RPC 来检索配置的特定部分。该 filter_xml 参数采用一个字符串,其中包含子树筛选器,该子树筛选器选择要返回的配置语句。子树筛选器返回与选择条件匹配的配置数据。
若要请求多个层次结构, filter_xml 字符串必须包含 <configuration> 根元素。否则,的值 filter_xml 必须表示配置层次结构的所有级别,从根 <configuration> 元素下方开始,一直到要显示的层次结构。若要选择子树,请包含该层次结构级别的空标记。若要返回特定对象,请包含一个内容匹配节点,该节点定义要匹配的元素和值。
以下 Junos PyEZ 应用程序检索并打印候选配置中 和 [edit interfaces] [edit protocols] 层次结构级别的配置:
from jnpr.junos import Device
from lxml import etree
with Device(host='router1.example.net') as dev:
filter = '<configuration><interfaces/><protocols/></configuration>'
data = dev.rpc.get_config(filter_xml=filter)
print (etree.tostring(data, encoding='unicode', pretty_print=True))
以下示例使用不同但等效的参数值filter_xml在层次结构级别检索[edit system services]和打印配置:
from jnpr.junos import Device
from lxml import etree
with Device(host='router1.example.net') as dev:
data = dev.rpc.get_config(filter_xml='<system><services/></system>')
print (etree.tostring(data, encoding='unicode', pretty_print=True))
data = dev.rpc.get_config(filter_xml='system/services')
print (etree.tostring(data, encoding='unicode', pretty_print=True))
filter = etree.XML('<system><services/></system>')
data = dev.rpc.get_config(filter_xml=filter)
print (etree.tostring(data, encoding='unicode', pretty_print=True))
以下示例检索<name>继承后候选配置中层次结构下<interfaces>每个<interface>元素的元素:
from jnpr.junos import Device
from lxml import etree
with Device(host='router1.example.net') as dev:
filter = '<interfaces><interface><name/></interface></interfaces>'
data = dev.rpc.get_config(filter_xml=filter, options={'inherit':'inherit'})
print (etree.tostring(data, encoding='unicode', pretty_print=True))
user@server:~$ python3 junos-pyez-get-interface-names.py
<configuration changed-seconds="1544032801" changed-localtime="2018-12-05 10:00:01 PST">
<interfaces>
<interface>
<name>ge-1/0/0</name>
</interface>
<interface>
<name>ge-1/0/1</name>
</interface>
<interface>
<name>lo0</name>
</interface>
<interface>
<name>fxp0</name>
</interface>
</interfaces>
</configuration>
以下示例检索 ge-1/0/1 接口的子树:
from jnpr.junos import Device
from lxml import etree
with Device(host='router1.example.net') as dev:
filter = '<interfaces><interface><name>ge-1/0/1</name></interface></interfaces>'
data = dev.rpc.get_config(filter_xml=filter, options={'inherit':'inherit'})
print (etree.tostring(data, encoding='unicode', pretty_print=True))
user@server:~$ python3 junos-pyez-get-single-interface.py
<configuration changed-seconds="1544032801" changed-localtime="2018-12-05 10:00:01 PST">
<interfaces>
<interface>
<name>ge-1/0/1</name>
<description>customerA</description>
<disable/>
<unit>
<name>0</name>
<family>
<inet>
<address>
<name>198.51.100.1/24</name>
</address>
</inet>
</family>
</unit>
</interface>
</interfaces>
</configuration>
指定要返回的配置数据的格式
Junos PyEZ get_config() RPC 调用 Junos XML 协议 <get-configuration> 操作,该操作可以将 Junos OS 配置数据作为 Junos XML 元素、CLI 配置语句、Junos OS set 命令或 JavaScript 对象表示法 (JSON) 返回。默认情况下,RPC 以 get_config() XML 形式返回配置数据。
要指定返回配置数据的格式,Junos PyEZ 应用程序在参数列表中包含options字典'format':'format'get_config()。要请求 CLI 配置语句、Junos OS set 命令或 JSON 格式,请分别将值text设置为 format 、 set或 json。
与在 NETCONF 和 Junos XML 协议会话中一样,Junos PyEZ 以预期格式返回配置数据,该格式包含在该格式的相应 XML 元素中。RPC 回复将 XML、文本或set命令格式的配置数据分别括在 、 <configuration-text>和<configuration-set>元素中<configuration>。
from jnpr.junos import Device
from lxml import etree
from pprint import pprint
with Device(host='router1.example.net') as dev:
# XML format (default)
data = dev.rpc.get_config()
print (etree.tostring(data, encoding='unicode', pretty_print=True))
# Text format
data = dev.rpc.get_config(options={'format':'text'})
print (etree.tostring(data, encoding='unicode', pretty_print=True))
# Junos OS set format
data = dev.rpc.get_config(options={'format':'set'})
print (etree.tostring(data, encoding='unicode', pretty_print=True))
# JSON format
data = dev.rpc.get_config(options={'format':'json'})
pprint (data)
根据 Python 的版本和输出的格式,您可能需要修改 print 语句以显示更易读的输出。
检索标准或自定义 YANG 数据模型的配置数据
您可以将标准化或自定义 YANG 模块加载到 Junos 设备上,以添加 Junos OS 本身不支持但可通过转换支持的数据模型。您可以使用为这些模型定义的语法在候选配置中配置非本机数据模型。提交配置时,数据模型的转换脚本会转换该数据,并将相应的 Junos OS 配置作为检出配置中的瞬时更改提交。
候选配置和活动配置按照这些模型定义的语法包含非本机 YANG 数据模型的配置数据。除了通过在 RPC 中包含 get_config() 适当的参数来检索本机 Junos OS 配置之外,Junos PyEZ 应用程序还可以检索标准和自定义 YANG 数据模型的配置数据。默认情况下,RPC 回复中 get_config() 不包含非本机配置数据。
除了检索 Junos OS 配置之外,还要检索由非本机 YANG 数据模型定义的配置数据,请使用参数执行 get_config() model RPC,并在适当时包含 namespace 参数。该 model 参数采用以下值之一:
custom- 检索由自定义 YANG 数据模型定义的配置数据。检索自定义 YANG 数据模型的数据时,必须包含namespace参数。ietf— 检索由 IETF YANG 数据模型定义的配置数据。openconfig—检索由 OpenConfig YANG 数据模型定义的配置数据。True—检索所有配置数据,包括完整的 Junos OS 配置和来自任何 YANG 数据模型的数据。
如果为model参数指定ietf或openconfig值,Junos PyEZ 将自动使用相应的命名空间。如果使用 检索model='custom'自定义 YANG 数据模型的数据,还必须将namespace参数包含在相应的命名空间中。
如果将参数与值 custom、 一起ietf包含model,或者openconfig还包括filter_xml用于返回特定 XML 子树的参数,则 Junos OS 仅返回来自非本机数据模型的匹配层次结构。如果 Junos OS 配置包含同名的层次结构(例如“接口”),则不会包含在回复中。使用 model=True时不支持该filter_xml选项。
在以下示例中, get_config() RPC 从设备上的候选配置中检索 OpenConfig bgp 配置层次结构。如果省略该 filter_xml 参数,RPC 将返回完整的 Junos OS 和 OpenConfig 候选配置。
from jnpr.junos import Device
from lxml import etree
with Device(host='router1.example.net') as dev:
data = dev.rpc.get_config(filter_xml='bgp', model='openconfig')
print (etree.tostring(data, encoding='unicode', pretty_print=True))
以下 RPC 从 IETF YANG 数据模型的候选配置中检索 interfaces 配置层次结构:
data = dev.rpc.get_config(filter_xml='interfaces', model='ietf')
print (etree.tostring(data, encoding='unicode', pretty_print=True))
以下 RPC 从具有给定命名空间的自定义 YANG 数据模型的候选配置中检索 l2vpn 配置层次结构:
data = dev.rpc.get_config(filter_xml='l2vpn', model='custom', namespace='http://yang.juniper.net/customyang/demo/l2vpn')
print (etree.tostring(data, encoding='unicode', pretty_print=True))
以下 RPC 检索完整的 Junos OS 候选配置以及已添加到设备的其他 YANG 数据模型的配置数据:
data = dev.rpc.get_config(model=True)
print (etree.tostring(data, encoding='unicode', pretty_print=True))
指定其他 RPC 选项
使用 Junos PyEZ get_config() RPC 检索配置时,它会调用 Junos XML 协议 <get-configuration> 操作。RPC 支持该 options 参数,该参数使您能够包含操作支持 <get-configuration> 的任何属性的键/值对的字典。有关 Junos XML 协议 <get-configuration> 操作支持的属性的完整列表,请参阅 <get-configuration>。
例如,get_config()RPC 从预继承配置中检索数据,其中 <groups>、 <apply-groups>、 <apply-groups-except>和 <interface-range> 标记是配置输出中的单独元素。要从继承后配置中检索数据(该配置将从用户定义的组和范围继承的语句显示为继承语句的子级),可以将参数包含在 中'inherit':'inherit'。options
例如,以下代码从继承后候选配置中检索层次结构级别的配置 [edit system services] 。在这种情况下,如果配置还包含在层次结构级别配置 [edit groups global system services] 的语句,则这些语句将在继承后配置的层次结构下 [edit system services] 继承,并在检索到的配置数据中返回。
from jnpr.junos import Device
from lxml import etree
with Device(host='router1.example.net') as dev:
data = dev.rpc.get_config(filter_xml='system/services', options={'inherit':'inherit'})
print (etree.tostring(data, encoding='unicode', pretty_print=True))
如何处理配置数据中的命名空间
默认情况下,Junos PyEZ get_config() RPC 会去除返回的配置数据中的所有命名空间。Junos PyEZ 应用程序可以在返回的配置数据中保留命名空间,这使您能够将数据加载回设备上,例如当您想要快速修改现有配置时。
若要在配置数据中保留命名空间,请在参数列表中包含 remove_ns=False 参数 get_config() 。例如:
from jnpr.junos import Device
from lxml import etree
with Device(host='router1.example.net') as dev:
data = dev.rpc.get_config(filter_xml='bgp', model='openconfig', remove_ns=False)
print (etree.tostring(data, encoding='unicode', pretty_print=True))
在以下截断输出中,元素 <bgp> 保留 xmlns 定义命名空间的属性:
<bgp xmlns="http://openconfig.net/yang/bgp">
<neighbors>
<neighbor>
<neighbor-address>198.51.100.1</neighbor-address>
<config>
<peer-group>OC</peer-group>
<neighbor-address>198.51.100.1</neighbor-address>
<enabled>true</enabled>
<peer-as>64496</peer-as>
</config>
</neighbor>
</neighbors>
...
get_config() remove_ns=False如果省略该参数,则命名空间不包含在输出中。
<bgp>
<neighbors>
<neighbor>
<neighbor-address>198.51.100.1</neighbor-address>
<config>
<peer-group>OC</peer-group>
<neighbor-address>198.51.100.1</neighbor-address>
<enabled>true</enabled>
<peer-as>64496</peer-as>
</config>
</neighbor>
</neighbors>
...