ncclient是一个用于NETCONF客户端的Python库。它旨在体用一个直观的API,将NETCONF的XML编码特性映射到Python构造和习语,并使编写网络管理脚本更容易。
其他主要功能有:
netconf学习笔记: https://cshihong.github.io/2019/12/29/Netconf%E5%8D%8F%E8%AE%AE%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/
ncclient主要使用python实现了netconf的相关操作。
这个模块是周围库的一个抽象层,它公开所有的核心功能。
manager中的操作,都是映射到ncclient.operations.xxx对应的calss。如下:
manager.OPERATIONS
Out[10]:
{'get': ncclient.operations.retrieve.Get,
'get_config': ncclient.operations.retrieve.GetConfig,
'get_schema': ncclient.operations.retrieve.GetSchema,
'dispatch': ncclient.operations.retrieve.Dispatch,
'edit_config': ncclient.operations.edit.EditConfig,
'copy_config': ncclient.operations.edit.CopyConfig,
'validate': ncclient.operations.edit.Validate,
'commit': ncclient.operations.edit.Commit,
'discard_changes': ncclient.operations.edit.DiscardChanges,
'cancel_commit': ncclient.operations.edit.CancelCommit,
'delete_config': ncclient.operations.edit.DeleteConfig,
'lock': ncclient.operations.lock.Lock,
'unlock': ncclient.operations.lock.Unlock,
'create_subscription': ncclient.operations.subscribe.CreateSubscription,
'close_session': ncclient.operations.session.CloseSession,
'kill_session': ncclient.operations.session.KillSession,
'poweroff_machine': ncclient.operations.flowmon.PoweroffMachine,
'reboot_machine': ncclient.operations.flowmon.RebootMachine}
创建一个设备处理对象,该对象提供设备的特殊参数和功能。它在其ncclient的代码中多次调用。
如果device_params
参数没有定义,或者这个参数对应的值在参数字典中不知道,那么会返会一个默认的处理程序。
使用实例:
manager.make_device_handler({'name':'huawei'})
初始化一个连接,通过:class:Manager
over the SSH transport.
通过class:ncclient.transport.SSHSession
实现。
return Manager(session, device_handler, **manager_params)
调用ncclient.thransport.third_party。
return Manager(session, device_handler, **manager_params)
如果host为localhosthe和device_param为junos/local
return connect_ioproc(*args, **kwds)
否则:
return connect_ssh(*args, **kwds)
将RPC操作的API作为方法公开调用。这些方法的返回类型取决于我们是处于异步模式(asynchronous mode)还是同步模式(synchronous mode)。
同步模式下等待应答并返回相应的RPCReply对象。根据异常引发模式的不同,应答中的rpc错误可能会被引发为RPCError异常。
asynchronous mode(异步模式):
异步模式下操作立即返回相应的RPC对象。错误处理和检查是否已收到回复必须手动处理。
注意:在get()和get_config()操作中,reply是GetReply
的一个实例, 它公开的附加属性data
(as Element
)和data_xml
(作为string
),这是这些操作的主要关注点。
在传输层错误的情况下,例如意外的会话关闭,TransportError
将被触发。
有关预期的操作行为和其他参数在:rfc4741中。
Manager实例也是上下文管理器,所以你可以这样使用它:
with manager.connect("host") as m:
# do your stuff
#or like this::
m = manager.connect("host")
try:
# do your stuff
finally:
m.close_session()
检索运行配置和设备状态信息。 查询的是设备当前运行的状态数据,即只能从配置数据库中获取数据。
不需要使用source参数指定配置数据库。
操作成功,Server回复的元素中含有参数,中封装了获取的结果数据。否则在消息中返回。
检索指定配置的全部或部分。
source:指定需要查询的数据库名称。有running
(正在运行的数据库) ,startup
(下次设备启动配置数据库), candidate
(两阶段运行数据库,需要commit提交生效)
fileter: 过滤器。过滤器可以采用如下方式:
这里的type必须是xpath
或者subtree
.
对于“xpath
,criteria
应该是包含XPath表达式的字符串。
对于substree
,criteria
应该是一个XML字符串或一个包含标准的元素对象。
Element
对象。将指定配置的全部或部分加载到目标配置数据存储中。
target:指定要配置的数据库。
config:必须放在元素中, 它可以指定为字符串或Element
default_operation: 如果指定,必须是{ “merge”, “replace”, or “none” } 其中之一。
test_option: { “test_then_set”, “set” } 之一。
error_option: { “stop-on-error”, “continue-on-error”, “rollback-on-error” } 之一。
The “rollback-on-error” error_option :rollback-on-error capability.
源配置数据库替换目标配置数据库。如果目标配置数据库没有创建,则直接创建配置数据库,否则用源配置数据库直接覆盖目标配置数据库。
删除配置数据库。
例如:
dispatch('clear-arp-table')
或者:
xsd_fetch = new_ele('get-xnm-information')
sub_ele(xsd_fetch, 'type').text="xml-schema"
sub_ele(xsd_fetch, 'namespace').text="junos-configuration"
dispatch(xsd_fetch)
允许客户端锁定设备的配置系统。
释放一个配置锁。
返回一个上锁的数据库的上下文件管理器,对应执行操作是:
return operations.LockContext(self._session, self._device_handler, target)
target
: 是要锁定的配置数据存储的名称,
with m.locked("running"):
# do your stuff
# ... instead of::
m.lock("running")
try:
# do your stuff
finally:
m.unlock("running")
尝试从接收的队列中检索一个通知,如果block为True,则调用将等待直到通知收到为止。如果timeout是一个大于0的数字,调用将等待它超时前收到通知的时间
如果在block为False或时没有可用的通知超时后,将不返回任何值。
return self._session.take_notification(block, timeout)
请求优雅地终止NETCONF会话,并关闭传输层会话。
强制去终止一个NETCONF会话。
将数据库配置数据提交,转化为设备的新当运行的配置即。取决于:candidate capability
。
timeout: 操作确认超时时间,单位是秒,缺省值是600秒。设备执行操作后,在确认超时时间内,如果没有执行确认操作,则对数据库中的配置进行回滚,配置数据恢复到执行操作之前的状态,并放弃数据库中的编辑数据。
persist: 使已确认的提交在会话终止后继续执行,并在正在进行的已确认的提交上设置token 。
将候选配置还原为当前正在运行的配置。任何未提交的更改都会被丢弃。
验证指定配置的内容。
返会服务器支持的能力集。
for i in m._session._server_capabilities:
print(i)
urn:ietf:params:netconf:base:1.0
urn:ietf:params:netconf:base:1.1
urn:ietf:params:netconf:capability:writable-running:1.0
....
返会客户端支持的能力集。
for i in m._session._client_capabilities:
print(i)
urn:ietf:params:netconf:base:1.0
urn:ietf:params:netconf:base:1.1
urn:ietf:params:netconf:capability:writable-running:1.0
....
返会一个seesion.id 。
判断seesion是否已经建立。
指定哪些错误引发RPCError
异常。有效值是在RaiseMode
中定义的常量。默认值是ALL
。
指定同步RPC请求的超时。
指定操作是异步执行的(True)还是同步执行的(False)(缺省值)。
表示netconf的能力集。
给定一个具有scheme查询字符串的URI(即:url capability URI),将返回一个受支持的模式列表。
表示NETCONF客户端或服务器可用的能力集。它是由一个capability URI列表初始化的 。
可以通过":cap" in caps
判断一个能力集是否是客户端或者服务器所支持的能力集。cap也能简写。
除了URI之外,对于urn:ietf:params:netconf:capability: n a m e : name: name:version表示的能力,它们的简写可以用作键。例如,对于urn:ietf:params:netconf:capability:candidate:1.0,简写应该是:candidate。如果版本是重要的,使用:candidate:1.0作为键。
返会能力集的迭代对象。
用于创建、解析和处理XML和ElementTree对象的方法。
exception ncclient.xml_.XMLError
, 基于:ncclient.NCClientError
转换并返回具有指定编码的ele(Element)的XML。
转换并返回XML文档x的元素。
有效地解析原始XML文档的根元素,返回其限定名和属性字典的元组。
检查XML文档或元素的根元素是否满足提供的条件。
主要实现了NETCONF传输层连接。
class ncclient.transport.Session(capabilities)
传输协议实现使用的基类。
注册一个监听器,它将收到传入消息和错误的通知。
客户端的能力集。
返回会话的连接状态。
如果注册了指定类型的侦听器,则返回实例 。
表示会话id的字符串。如果没有初始化,为None。
注销一些监听器;如果监听器没有被注册,将被忽略掉。
返回服务器支持的能力集。
会话监听器的基类,当接收到新的NETCONF消息或发生错误时,会通知该类。
收到新的XML文档时调用。 root参数允许回调确定是否要进一步处理文
root:是一个元组(tag, arrtibutes)类型。
tag: 根元素限定名。
attributes:是属性名的字典。
row : 以字符串的形式包含XML文档。
发生错误时调用。
是ssh会话的实现。
如果未知的主机回调发现可接受的密钥,则返回True,否则返回False。
默认返回False,可能导致connet()引发SSHUnknowHost
异常。
如果需要以编程方式验证主机密钥,需要供另一个有效的回调。
host:需要验证的主机名
fingerprint:表示主机指纹的16进制字符串。用冒号分隔。
例如: “4b:69:6c:72:6f:79:20:77:61:73:20:68:65:72:65:21”
实现通过ssh的netconf会话连接。
connect(host[, port=830, timeout=None, unknown_host_cb=default_unknown_host_cb, username=None, password=None, key_filename=None, allow_agent=True, look_for_keys=True, ssh_config=None])
通过SSH连接并初始化NETCONF会话。首先尝试公钥身份验证方法,然后尝试密码身份验证。
若要完全禁用公钥尝试身份验证,设置 allow_agent和look_for_keys作为False调用 。
~/.ssh/config
从指定文件中加载主机密钥。从而可以多次调用。如果未指定文件路径,会使用默认位置:~/.ssh/know_hosts
and ~/ssh/know_hosts
exceptionncclient.transport.TransportError
Bases: ncclient.NCClientError
exceptionncclient.transport.SessionCloseError(in_buf, out_buf=None)
Bases: ncclient.transport.errors.TransportError
exceptionncclient.transport.SSHError
Bases: ncclient.transport.errors.TransportError
exceptionncclient.transport.AuthenticationError
Bases: ncclient.transport.errors.TransportError
exception*ncclient.transport.SSHUnknownHostError(host, fingerprint)
Bases: ncclient.transport.errors.SSHError
该文件夹内主要定义了netconf操作的实现方法。
dir(operations)
Out[3]:
['CancelCommit',
'CloseSession',
'Commit',
'CopyConfig',
'CreateSubscription',
'DeleteConfig',
'DiscardChanges',
'Dispatch',
'EditConfig',
'Get',
'GetConfig',
'GetReply',
'GetSchema',
'KillSession',
'Lock',
'LockContext',
'MissingCapabilityError',
'OperationError',
'PoweroffMachine',
'RPC',
'RPCError',
'RPCReply',
'RaiseMode',
'RebootMachine',
'TimeoutExpiredError',
'Unlock',
'Validate',
'edit',
'errors',
'flowmon',
'lock',
'retrieve',
'rpc',
'session',
'subscribe',
'util']
class RPC是所有操作的基类,直接对应于rpc请求。处理发出请求和接收回复。
classncclient.operations.RPC(session, device_handler, async=False, timeout=30, raise_mode=0)
classncclient.operations.RaiseMode
Operations类异常类型如下:
定义应如何处理RPC指示的错误。
子类可以在发出RPC请求之前,使用此方法来验证NETCONF服务器具有的capability, 如果该capablility不可用,将会引发一个MissingCapabilityError
异常。
request 方法的实现,发送RPC请求和处理回应。
在同步模式下,阻塞直到收到RPCReply。
在异步模式下,立即返会。
op:是RPC请求的实际操作。xml类型的数据。
操作的子类必须实现该方法。通常,将所有请求构建成一个Element元素op,然后传递给_requests(op)去处理。
表示一个rpc-reply,仅仅关注这个RPC请求操作是否成功。
返会一个布尔值,表示RPC回复是否有错误。
表示rpc-error类型。基类是ncclient.operations.errors.OperationError.
实现netconf查询类操作。操作类的基类都是: ncclient.operations.rpc.RPC
class ncclient.operations.Get(session, device_handler, async=False, timeout=30, raise_mode=0)
def requests((self, filter=None, with_defaults=None):
检索运行配置和设备状态信息
class ncclient.operations.GetConfig(session, device_handler, async=False, timeout=30, raise_mode=0)
实现了request(source, filter=None), 检索指定配置的全部或部分。
基类是; ncclient.operations.rpc.RPCReply
将data元素的属性添加到’ RPCReply ’
data_ele
一样。Element
classncclient.operations.Dispatch(session, device_handler, async=False, timeout=30, raise_mode=0)
request(rpc_command, source=None, filter=None)
rpc_command: 指定以纯文本或xml元素格式(取决于命令).
使用示例:
dispatch('clear-arp-table')
or dispatch element like
xsd_fetch = new_ele('get-xnm-information')
sub_ele(xsd_fetch, 'type').text="xml-schema"
sub_ele(xsd_fetch, 'namespace').text="junos-configuration"
dispatch(xsd_fetch)
实现通过netconf对设备进行配置。 将指定配置的全部或部分加载到目标配置数据存储中。
classncclient.operations.EditConfig(session, device_handler, async=False, timeout=30, raise_mode=0)
request(config, format='xml', target='candidate', default_operation=None, test_option=None, error_option=None)
实现删除配置的操作。删除配置数据库。
classncclient.operations.DeleteConfig(session, device_handler, async=False, timeout=30, raise_mode=0)
request(target)
用另一个完整配置数据存储的内容创建或替换整个配置数据存储
classncclient.operations.CopyConfig(session, device_handler, async=False, timeout=30, raise_mode=0)
request(source, target)
验证指定配置的内容。
classncclient.operations.Validate(session, device_handler, async=False, timeout=30, raise_mode=0)
request(source='candidate')
将候选配置提交为设备的新当前配置。取决于: candidate capability.
classncclient.operations.Commit(session, device_handler, async=False, timeout=30, raise_mode=0)
request(confirmed=False, timeout=None, persist=None)
如果在超时间隔内没有后续提交,确认提交(即confiremed is True)将被还原。如果没有指定超时,则确认超时默认为600秒(10分钟)。
将候选配置还原为当前正在运行的配置。任何未提交的更改都会被丢弃。
classncclient.operations.DiscardChanges(session, device_handler, async=False, timeout=30, raise_mode=0)
request()
允许客户端锁定设备的配置系统。
classncclient.operations.Lock(session, device_handler, async=False, timeout=30, raise_mode=0)
request(target='candidate')
释放一个配置锁,这是以前通过锁操作获得的。
classncclient.operations.Unlock(session, device_handler, async=False, timeout=30, raise_mode=0)
request(target='candidate')
请求优雅地终止NETCONF会话,并关闭传输。
classncclient.operations.CloseSession(session, device_handler, async=False, timeout=30, raise_mode=0)
request()
强制终止一个NETCONF会话(不是当前会话!)
classncclient.operations.KillSession(session, device_handler, async=False, timeout=30, raise_mode=0)
request(session_id)
import logging
from string import Template
from ncclient import manager
from ncclient import operations
log = logging.getLogger(__name__)
def huawei_connect(host, port, user, password):
return manager.connect(host=host,
port=port,
username=user,
password=password,
hostkey_verify = False,
device_params={'name': 'huawei'},
allow_agent = False,
look_for_keys = False)
def _check_response(rpc_obj, snippet_name):
print("RPCReply for %s is %s" % (snippet_name, rpc_obj.xml))
xml_str = rpc_obj.xml
print(xml_str)
if " " in xml_str:
print("%s successful" % snippet_name)
else:
print("Cannot successfully execute: %s" % snippet_name)
def test_edit_config_running(host, port, user, password):
#1.Create a NETCONF session
with huawei_connect(host, port=port, user=user, password=password) as m:
acl = '''
3900
'''
get = m.get_config(source='running', filter = ('subtree', acl))
print(get)
if __name__ == '__main__':
host = 'x.x.x.x'
port = 830
user = 'user'
password = 'password'
test_edit_config_running(host, port, user, password)
程序返会内容:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:f6ec534a-0eb1-4aea-a627-de98705cc780">
<data>
<access-lists xmlns="urn:ietf:params:xml:ns:yang:ietf-acl" xmlns:hw-acl="urn:huawei:params:xml:ns:yang:huawei-acl">
<access-list>
<access-control-list-name>3900access-control-list-name>
<hw-acl:vsys>publichw-acl:vsys>
<access-list-entries>
<access-list-entry>
<rule-name>5rule-name>
<matches>
<protocol>0protocol>
<source-ipv4-network>1.1.1.0/24source-ipv4-network>
<destination-ipv4-network>1.1.1.2/32destination-ipv4-network>
matches>
<actions>
<permit/>
actions>
access-list-entry>
access-list-entries>
access-list>
access-lists>
data>
rpc-reply>
附加:
华为Netconf开发指南: https://support.huawei.com/enterprise/zh/doc/EDOC1100109432
华为netconf API : https://support.huawei.com/enterprise/zh/doc/EDOC1100075576
参考资料: https://ncclient.readthedocs.io/en/latest/#
ncclient源码: https://github.com/ncclient/ncclient