python网络自动化ncclient模块,netconf协议检索与下发交换机配置
以juniper和华为设备为例
交换机必要配置,配置简单,使用ssh模式传输
#juniper
set system services netconf ssh
#华为
local-user netconf-dark password irreversible-cipher $1c$16[R/:A_aG$sG-KWmUb!SCz=R9y[P%KE&9.'P"+:XJ=-`<S76p.$
local-user netconf-dark privilege level 15
local-user netconf-dark service-type api
netconf
source ip 10.0.3.105
netconf使用XML格式来请求和接收数据,使用简单举例
使用ssh连接交换机
C:\Users\86185>ssh 10.0.3.101 -s netconf
Password:
<!-- No zombies were killed during the creation of this user interface -->
<!-- user dark, class j-super-user -->
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<capabilities>
<capability>urn:ietf:params:netconf:base:1.0</capability>
<capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
<capability>urn:ietf:params:netconf:capability:confirmed-commit:1.0</capability>
<capability>urn:ietf:params:netconf:capability:validate:1.0</capability>
<capability>urn:ietf:params:netconf:capability:url:1.0?scheme=http,ftp,file</capability>
<capability>urn:ietf:params:xml:ns:netconf:base:1.0</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:candidate:1.0</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:confirmed-commit:1.0</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:validate:1.0</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:url:1.0?protocol=http,ftp,file</capability>
<capability>http://xml.juniper.net/netconf/junos/1.0</capability>
<capability>http://xml.juniper.net/dmi/system/1.0</capability>
</capabilities>
<session-id>65770</session-id>
</hello>
]]>]]>
juniper请求端口信息
<rpc>
<get-interface-information>
<interface-name>xe-0/0/1</interface-name>
<detail/>
</get-interface-information>
</rpc>
juniper提交配置
<rpc>
<commit/>
</rpc>
华为请求trunk接口信息
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1024">
<get>
<filter type="subtree">
<ifmtrunk xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<TrunkIfs>
<TrunkIf>
<ifName></ifName>
<minUpNum></minUpNum>
<trunkType></trunkType>
</TrunkIf>
</TrunkIfs>
</ifmtrunk>
</filter>
</get>
</rpc>
以上是netconf的简单原生操作,如果我们要在python环境中使用netconf,首先需要下载读取YANG文件,封装get get-config commit edit_config lock unlock等功能,根据不同厂商选择不同的YANG API,其次还需要创建sock连接,通过ssh交互netconf报文,设备厂商繁多,各家功能对应的TAG名称也不一致,自己一步一步写起来太过复杂,好在python中有较为成熟的库可供我们使用
ncclient
ncclient是一个用于NETCONF客户端的Python库,可以在python环境中使用netconf协议检索下发交换机配置
host = '10.0.3.105'
username = 'username'
passwd = 'password'
#connect()返回一个连接对象
netconf_connection = manager.connect(host=host,
username=username,
password=passwd,
port=830,
hostkey_verify=False
) #获取交换机端口简要信息XML语句
interface_index = """
<device-state xmlns="urn:huawei:params:xml:ns:yang:huawei-device">
<optical-module-infos>
<interface-list>
</interface-list>
</optical-module-infos>
</device-state>
""" rpc_conf = netconf_connection.get(filter =('subtree',interface_info)) print(rpc)
得到如下信息

<?xml version="1.0" encoding="UTF-8"?><data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><device-state xmlns="urn:huawei:params:xml:ns:yang:huawei-device"><optical-module-infos><interface-list><interface-name>XGigabitEthernet0/0/1</interface-name><physical-index>1</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/2</interface-name><physical-index>2</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/3</interface-name><physical-index>3</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/4</interface-name><physical-index>4</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/5</interface-name><physical-index>5</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/6</interface-name><physical-index>6</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/7</interface-name><physical-index>7</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/8</interface-name><physical-index>8</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/9</interface-name><physical-index>9</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/10</interface-name><physical-index>10</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/11</interface-name><physical-index>11</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/12</interface-name><physical-index>12</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/13</interface-name><physical-index>13</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/14</interface-name><physical-index>14</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/15</interface-name><physical-index>15</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/16</interface-name><physical-index>16</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/17</interface-name><physical-index>17</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/18</interface-name><physical-index>18</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/19</interface-name><physical-index>19</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/20</interface-name><physical-index>20</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/21</interface-name><physical-index>21</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/22</interface-name><physical-index>22</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/23</interface-name><physical-index>23</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/24</interface-name><physical-index>24</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/25</interface-name><physical-index>25</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/26</interface-name><physical-index>26</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/27</interface-name><physical-index>27</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/28</interface-name><physical-index>28</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/29</interface-name><physical-index>29</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/30</interface-name><physical-index>30</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/31</interface-name><physical-index>31</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/32</interface-name><physical-index>32</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/33</interface-name><physical-index>33</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/34</interface-name><physical-index>34</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/35</interface-name><physical-index>35</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/36</interface-name><physical-index>36</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/37</interface-name><physical-index>37</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/38</interface-name><physical-index>38</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/39</interface-name><physical-index>39</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/40</interface-name><physical-index>40</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/41</interface-name><physical-index>41</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/42</interface-name><physical-index>42</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/43</interface-name><physical-index>43</physical-index><present>false</present></interface-list><interface-list><interface-name>XGigabitEthernet0/0/44</interface-name><physical-index>44</physical-index><present>false</present></interface-list><interface-list><interface-name>100GE0/0/1</interface-name><physical-index>1</physical-index><present>false</present></interface-list><interface-list><interface-name>100GE0/0/2</interface-name><physical-index>2</physical-index><present>false</present></interface-list><interface-list><interface-name>40GE0/0/3</interface-name><physical-index>3</physical-index><present>false</present></interface-list><interface-list><interface-name>40GE0/0/4</interface-name><physical-index>4</physical-index><present>false</present></interface-list><interface-list><interface-name>40GE0/0/5</interface-name><physical-index>5</physical-index><present>false</present></interface-list><interface-list><interface-name>40GE0/0/6</interface-name><physical-index>6</physical-index><present>false</present></interface-list></optical-module-infos></device-state></data>
请问这一堆乱糟糟的是什么东西,也没个换行符-_-!
别急,我们需要封装一些功能进去
1 #首先自己写一个类
2 class Netconf:
3 #封装一些connect必要的参数
4 def __init__(self,*args,**kwargs):
5 self.host = kwargs['host']
6 self.port = kwargs.get('port',830)
7 self.username = kwargs['username']
8 self.passwd = kwargs['passwd']
9 self.hostkey_verify=kwargs.get('hostkey_verify',False)
10 #connect方法
11 def conn(self):
12 try:
13 netconf_conn = manager.connect(host=self.host,port=self.port,username=self.username,password=self.passwd,hostkey_verify=self.hostkey_verify)
14 return netconf_conn
15 except Exception as a:
16 print(a)
17 print("""
18 ---------------------------------------------------------------------------------------
19 sample: Netconf(host='10.0.3.105',username='netconf-dark',passwd='1234567',port=830)
20 """
21 )
22 #get_config方法,获取的交换机的所有配置
23 def get_conf(self):
24 netconf_conn = self.conn()
25 return netconf_conn.get_config(source='running').data_xml
26 #写个方法处理下得到的数据,以xml树形格式进行返回
27 def get_xml(self,command=None):
28 netconf_conn = self.conn()
29 rpc_replay = netconf_conn.get(filter=('subtree',command)).data_xml
30 rpc_xml = xml.dom.minidom.parseString(rpc_replay).toprettyxml()
31 return rpc_replay
32 #以字典形式进行返回,方便做数据处理
33 def get_dic(self,command=None):
34 netconf_conn = self.conn()
35 rpc_replay = netconf_conn.get(filter=('subtree',command)).data_xml
36 rpc_dict = xmltodict.parse(rpc_replay)
37 return rpc_dict
38 #以json方式进行返回
39 def get_json(self,command=None):
40 rpc_replay = self.get_dic(command)
41 rpc_json = json.dumps(rpc_replay, indent=1)
42 return rpc_json
43 def server_capabilities(self):
44 netconf_conn = self.conn()
45 return netconf_conn.server_capabilities
我们来用下好不好使
interface_info = """
<interfaces-state xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name></name>
<ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
<address></address>
</ipv4>
</interface>
</interfaces-state>
"""
conn = Netconf(host='10.0.3.105',username='netconf',passwd='netconf123456')
rpc_json = conn.get_json(interface_index)
rpc_xml = conn.get_xml(interface_index)
with open('/home/dark/interface_info.json') as a:
a.write(rpc_json)
with open('/home/dark/interface_info.xml') as a:
a.write(rpc_xml)
运行以上代码

#json格式,输出太长,截取一小段
{
"data": {
"@xmlns": "urn:ietf:params:xml:ns:netconf:base:1.0",
"@xmlns:nc": "urn:ietf:params:xml:ns:netconf:base:1.0",
"interfaces-state": {
"@xmlns": "urn:ietf:params:xml:ns:yang:ietf-interfaces",
"interface": [
{
"name": "NULL0"
},
{
"name": "MEth0/0/1"
},
{
"name": "Vlanif1"
},
{
"name": "XGigabitEthernet0/0/1"
},
{
"name": "XGigabitEthernet0/0/2"
},
{
"name": "XGigabitEthernet0/0/3"
},
{
"name": "XGigabitEthernet0/0/4"
},
{
"name": "40GE0/0/3"
},
{
"name": "40GE0/0/4"
},
{
"name": "40GE0/0/5"
},
{
"name": "40GE0/0/6"
},
{
"name": "LoopBack0",
"ipv4": {
"@xmlns": "urn:ietf:params:xml:ns:yang:ietf-ip",
"address": {
"ip": "192.168.35.60",
"netmask": "255.255.255.255",
"origin": "static"
}
}
},
{
"name": "Vlanif48",
"ipv4": {
"@xmlns": "urn:ietf:params:xml:ns:yang:ietf-ip",
"address": {
"ip": "10.40.0.70",
"netmask": "255.255.255.252",
"origin": "static"
}
}
},
{
"name": "LoopBack1",
"ipv4": {
"@xmlns": "urn:ietf:params:xml:ns:yang:ietf-ip",
"address": {
"ip": "192.168.39.17",
"netmask": "255.255.255.252",
"origin": "static"
}
}
},
{
"name": "MEth0/0/2"
}
]
}
}
}
json格式

#XML格式,输出太长,截取一小段
<?xml version="1.0" ?>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
<interfaces-state xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>NULL0</name>
</interface>
<interface>
<name>MEth0/0/1</name>
</interface>
<interface>
<name>Vlanif1</name>
</interface>
<interface>
<name>XGigabitEthernet0/0/1</name>
</interface>
<interface>
<name>XGigabitEthernet0/0/2</name>
</interface>
<interface>
<name>XGigabitEthernet0/0/3</name>
</interface>
<interface>
<name>40GE0/0/3</name>
</interface>
<interface>
<name>40GE0/0/4</name>
</interface>
<interface>
<name>40GE0/0/5</name>
</interface>
<interface>
<name>40GE0/0/6</name>
</interface>
<interface>
<name>LoopBack0</name>
<ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
<address>
<ip>192.168.35.60</ip>
<netmask>255.255.255.255</netmask>
<origin>static</origin>
</address>
</ipv4>
</interface>
<interface>
<name>Nve1</name>
</interface>
<interface>
<name>Vlanif48</name>
<ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
<address>
<ip>10.40.0.70</ip>
<netmask>255.255.255.252</netmask>
<origin>static</origin>
</address>
</ipv4>
</interface>
<interface>
<name>LoopBack1</name>
<ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
<address>
<ip>192.168.39.17</ip>
<netmask>255.255.255.252</netmask>
<origin>static</origin>
</address>
</ipv4>
</interface>
<interface>
<name>MEth0/0/2</name>
</interface>
</interfaces-state>
</data>
XML格式
代码中的interfac_info的XML字符串来自哪里?这就需要用到YANG API,有公共的YANG,各家厂商也有自己的YANG
例如华为CE系列的https://support.huawei.com/hedex/hdx.do?docid=EDOC1000179511&lang=zh&id=library_change_preview&from=HedExLite
也可以通过get请求格式化成XML文档树,如下

juniper还可以通过命令行输出XML格式,华为没找类似功能,可能是我手里的交换机太垃圾

如果是通过YANG API文件检索的字符串,我们用ncclient执行操作时只需要content部分,如下黑色框区域

如果是get到的XML文档树,需要哪个模块就点开哪个模块复制就行,例如我们需要获取每个端口的ipaddress,如下
先找到interfaces-state这一层,展开

我们可以获取关于接口的N多信息,如果我们只需要其中的一部分可以进行如下操作
interface_info = """
<interfaces-state xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name></name>
<ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
<address></address>
</ipv4>
</interface>
</interfaces-state>
"""
#根层必须有,子层的父层也必须有,到子层后需要哪些标签就写对应的标签
rpc_xml = conn.get_xml(interface_info)
print(rpc_xml)
输出如下,截取部分

同样的,juniper通过GET到XML结构树,这里不得不感叹下juniper的便捷,灵活性,从以下输出可以看到juniper的XML树形结构与配置命令的层次结构极其相似

来get一下接口信息,这次输出json格式
rpc_json = conn.get_json('<configuration><interfaces></interfaces></configuration>')
print(rpc_json)
运行以上代码,截取一小部分

以上是ncclient的GET操作,ncclient的manager模块还有许多其他方法,如下
、
接着说edit_config和commit,discard_changss,这些方法用于对交换机配置的变更,我们需要封装进我们自己的类,改变如下
1 class Netconf:
2 #封装一些connect必要的参数
3 def __init__(self,*args,**kwargs):
4 self.host = kwargs['host']
5 self.port = kwargs.get('port',830)
6 self.username = kwargs['username']
7 self.passwd = kwargs['passwd']
8 self.hostkey_verify=kwargs.get('hostkey_verify',False)
9 self.device_params=kwargs.get('device_params',None)
10 #connect方法
11 def conn(self):
12 try:
13 netconf_conn = manager.connect(host=self.host,port=self.port,username=self.username,\
14 password=self.passwd,hostkey_verify=self.hostkey_verify,device_params=self.device_params)
15 return netconf_conn
16 except Exception as a:
17 print(a)
18 print("""
19 ---------------------------------------------------------------------------------------
20 sample: Netconf(host='10.0.3.105',username='netconf-dark',passwd='1234567',port=830)
21 """
22 )
23 #get_config方法,获取的交换机的所有配置
24 def get_conf(self):
25 netconf_conn = self.conn()
26 return netconf_conn.get_config(source='running').data_xml
27 #写个方法处理下得到的数据,以xml树形格式进行返回
28 def get_xml(self,command=None):
29 netconf_conn = self.conn()
30 rpc_replay = netconf_conn.get(filter=('subtree',command)).data_xml
31 rpc_xml = xml.dom.minidom.parseString(rpc_replay).toprettyxml()
32
33 return rpc_xml.strip()
34 #以字典形式进行返回,方便做数据处理
35 def get_dic(self,command=None):
36 netconf_conn = self.conn()
37 rpc_replay = netconf_conn.get(filter=('subtree',command)).data_xml
38 rpc_dict = xmltodict.parse(rpc_replay)
39 return rpc_dict
40 #以json方式进行返回
41 def get_json(self,command=None):
42 rpc_replay = self.get_dic(command)
43 rpc_json = json.dumps(rpc_replay, indent=1)
44 return rpc_json
45 #server端所支持的能力,返回迭代器
46 def server_capabilities(self):
47 netconf_conn = self.conn()
48 return netconf_conn.server_capabilities
49 #edit_config方法,target可使用candidate或running
50 def edit(self,command=None,target='candidate'):
51 netconf_conn = self.conn()
52 reply = netconf_conn.edit_config(target=target,config=command)
53 return reply
54 #清除未提交配置
55 def rollback(self):
56 netconf_conn = self.conn()
57 # netconf_conn.rpc('<discard-changes/>')
58 return netconf_conn.discard_changes()
59
60 #提交配置,confirmed代表是否进行回滚,timout表示多久回滚
61 def commit(self,confirmed=False,timeout=None):
62 netconf_conn = self.conn()
63 return netconf_conn.commit(confirmed=confirmed,timeout=timeout)
edit_config方法有一个必要的参数,config,XML格式,target参数需要注意,值可为candidate或running,对于juniper必须使用candidate,因为juniper配置完设备后需要commit提交配置

首先我们使用 server_capabilities方法看下设备是否支持edit_config
jun_conn = Netconf(host='10.0.3.101',username='username',passwd='passwd',port=1211,device_params={'name':'junos'})
hw_conn = Netconf(host='10.0.3.105',username='netconf',passwd='passwd')
for cap in hw_conn.server_capabilities():
print(cap)
for cap in jun_conn.server_capabilities():
print(cap)
输出如下,juniper对网络可编程支持性较好,操作舒服,以下案例均使用juniper设备
#HW rn:ietf:params:netconf:base:1.0
urn:ietf:params:netconf:base:1.1
urn:ietf:params:netconf:capability:writable-running:1.0
urn:ietf:params:netconf:capability:candidate:1.0
urn:ietf:params:netconf:capability:startup:1.0
urn:ietf:params:netconf:capability:rollback-on-error:1.0
urn:ietf:params:netconf:capability:with-defaults:1.0
urn:ietf:params:netconf:capability:notification:1.0
urn:ietf:params:xml:ns:yang:1?revision=2017-02-20&module=yang
urn:ietf:params:xml:ns:yang:ietf-inet-types?revision=2013-07-15&module=ietf-inet-types
urn:ietf:params:xml:ns:yang:ietf-yang-types?revision=2013-07-15&module=ietf-yang-types
urn:ietf:params:xml:ns:yang:ietf-yang-library?revision=2018-01-17&module=ietf-yang-library
urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08&module=ietf-interfaces&feature=arbitrary-names,pre-provisioning,if-mib
#输出太多,截取一部分,如上支持的module,测试交换机是s6720,xml固定格式是<huawei-vlan:vlans xmlns:huawei-vlan="urn:huawei:params:xml:ns:yang:huawei-vlan" >
#最后的yang:后面跟交换机支持的模块,操作对应的模块
#<huawei-vlan:vlan xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0" xc:operation="delete"> 操作类型前需要跟前面一长串
#juniper
urn:ietf:params:netconf:base:1.0
urn:ietf:params:netconf:capability:candidate:1.0
urn:ietf:params:netconf:capability:confirmed-commit:1.0
urn:ietf:params:netconf:capability:validate:1.0
urn:ietf:params:netconf:capability:url:1.0?scheme=http,ftp,file
urn:ietf:params:xml:ns:netconf:base:1.0
urn:ietf:params:xml:ns:netconf:capability:candidate:1.0
urn:ietf:params:xml:ns:netconf:capability:confirmed-commit:1.0
urn:ietf:params:xml:ns:netconf:capability:validate:1.0
urn:ietf:params:xml:ns:netconf:capability:url:1.0?protocol=http,ftp,file
http://xml.juniper.net/netconf/junos/1.0
http://xml.juniper.net/dmi/system/1.0
来使用下我们新增的方法,通用YANG API edit_config方法使用的tag是<config>,内层标签则需要查找设备厂商所提供的API
jun_conn = Netconf(host='10.0.3.101',username='usernam',passwd='password',port=1211,device_params={'name':'junos'})
snmp = '''
<config>
<configuration>
<snmp>
<community>
<name>dark123456</name>
<authorization>read-only</authorization>
</community>
</snmp>
</configuration>
</config>
'''
jun_conn.edit(snmp)
运行以上代码后在设备上可以看到配置已经下发,但未提交,需要注意的是对于华为设备如果candidate数据库中有未提交配置时不可操作running数据库
dark@Test-Route# show | compare
[edit snmp]
community 000123a { ... }
+ community dark123456 {
+ authorization read-only;
+ } [edit]
dark@Test-Route> show configuration snmp | display set
set snmp community test authorization read-only
运行以下代码进行配置回滚
jun_conn.rollback()
执行后在设备上查看未提交配置为空

让我们回到下发配置未提交时,执行以下方法,commit并在1分钟后回滚配置
jun_conn.edit(snmp)
jun_conn.commit(confirmed=True,timeout=60)

可以看到配置将在1分钟内回滚
执行jun_conn.commit(),查看设备配置,配置已经下发并提交

然后我们进行配置删除
执行以下代码
del_snmp = '''
<config>
<configuration>
<snmp>
<community operation="delete">
<name>dark123456</name>
<authorization>read-only</authorization>
</community>
</snmp>
</configuration>
</config>''' jun_conn.edit(del_snmp)
jun_conn.commit()

配置已删除
再试下华为设备,添加vlan 671

执行以下代码
vlan = '''
<config>
<huawei-vlan:vlans xmlns:huawei-vlan="urn:huawei:params:xml:ns:yang:huawei-vlan" >
<huawei-vlan:vlan>
<huawei-vlan:id >671</huawei-vlan:id>
</huawei-vlan:vlan>
</huawei-vlan:vlans>
</config>
'''
hw_conn.edit(command=vlan,target='running')

删除vlan执行以下代码
del_vlan = '''
<config>
<huawei-vlan:vlans xmlns:huawei-vlan="urn:huawei:params:xml:ns:yang:huawei-vlan" >
<huawei-vlan:vlan xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0" xc:operation="delete">
<huawei-vlan:id >671</huawei-vlan:id>
</huawei-vlan:vlan>
</huawei-vlan:vlans>
</config>
'''
hw_conn.edit(del_vlan)
至此ncclient基本增删改查方法与格式化输出封装完毕
出门溜娃,下周继续.................
python网络自动化ncclient模块,netconf协议检索与下发交换机配置的更多相关文章
- Python+Selenium自动化-安装模块和浏览器驱动操作方法
Python+Selenium自动化-安装模块和浏览器驱动操作方法 1.安装模块文件 pip install selenium 2.安装浏览器驱动 我们主要用的浏览器驱动有chrome浏览器.fire ...
- python 网络爬虫requests模块
一.requests模块 requests模块是python中原生的基于网络请求的模块,其主要作用是用来模拟浏览器发起请求.功能强大,用法简洁高效. 1.1 模块介绍及请求过程 requests模块模 ...
- Python网络爬虫-requests模块
requests模块 requests模块是python中原生的基于网络请求的模块,其主要作用是用来模拟浏览器发起请求.功能强大,用法简洁高效.在爬虫领域中占据着半壁江山的地位. 如何使用reques ...
- python 网络编程--socket模块/struct模块
socket模块: 客户端:CS架构, client -> server 浏览器:BS架构, browser -> server 网络通信本质:传输字节 doc命令查看ip地址:ipc ...
- python网络自动化运维之环境搭建(EVE-NG+pycharm)
参考了很多资料,发现现在很多环境用的都是GNS3加linux下的python,几乎没有是用EVE-NG加上pycharm的教程,EVE的功能如此强大,存在的教程却较少,这里我出一篇教程供使用EVE作为 ...
- Python网络爬虫-requests模块(II)
有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取张三“人人网”个人主页数据)时,如果使用之前requests模块常规操作时,往往达不到我们想要的目的,例如: #!/usr/bin/env ...
- python网络编程socketserver模块(实现TCP客户端/服务器)
摘录python核心编程 socketserver(python3.x版本重新命名)是标准库中的网络编程的高级模块.通过将创建网络客户端和服务器所必须的代码封装起来,简化了模板,为你提供了各种各样的类 ...
- python网络自动化运维paramiko实验
运行环境: 物理机:win10 1903 网络设备:EVE-NG模拟器上运行思科三层路由器 网络设备OS版本:cisco ios(versions 15.6) python环境:pycharm 3.5 ...
- python网络自动化运维之telnetlib实验(EVE-NG+pycharm)
运行环境: 物理机:win10 1903 网络设备:EVE-NG模拟器上运行思科三层路由器 网络设备OS版本:cisco ios(versions 15.6) python环境:pycharm 3.3 ...
随机推荐
- matlab拟合函数的三种方法
方法一:多项式拟合polyfit 1 x=[1 2 3 4 5 6 7 8 9]; 2 3 y=[9 7 6 3 -1 2 5 7 20]; 4 P= polyfit(x, y, 3) %三阶多项式拟 ...
- jQ模拟打字效果插件typetype
typetype是一个jquery插件,可以模拟人类的打字效果. 效果图如下所示: 查看演示 http://weber.pub/demo/160828/jQuery.Type/jQuery.type. ...
- 【每日日报】第五十三天---安装My SQL
1 2今天安装了My SQL并学习了一些基础的命令 mysql下载及安装教程 2 没有成功安装SQL Server,误删了一些文件 3 明天继续看视频 ------------------------ ...
- Mybatis的简介+简单实现增删改查案例
@ 目录 总结内容 1. 基本概念 2. Mybatis的使用 需求 配置文件简介 总结 总结内容 1. 基本概念 Mybatis是一款优秀的持久层框架,它支持定制化SQL.存储过程以及高级映射.My ...
- vscode代码格式化快捷键及保存时自动格式化
一.实现vs code中代码格式化快捷键:[Shift]+[Alt]+ F 二.实现保存时自动代码格式化: 1)文件 ------.>[首选项]---------->[设置]: 2)搜索 ...
- Python简单文件读写
''' 用文件存储账户信息 使用列表存储多个账户信息,每个账户为一个字典对象 ''' users=[] #创建一个空列表 users.append({'id':'admin','pwd':'1235@ ...
- 虚拟机上 安装 CentoOS 7.5 1804 过程记录
1.准备安装镜像 在开始安装CentOS之前,必须下载安装ISO映像.镜像可从CentOS网站https://www.centos.org/download/.提供以下基本类型的镜像: DVD ISO ...
- css3,css的基础全局运用
浮动 1.浮动起来的盒子不占用位置,浮动了一个盒子下面的标准流的盒子会顶上来 可用清除浮动的方法来解决标准流会顶替位置的问题 清除浮动给父盒子加overflow: hidden; 鼠标经过事件 : ...
- 深入理解nodejs的异步IO与事件模块机制
node为什么要使用异步I/O 异步I/O的技术方案:轮询技术 node的异步I/O nodejs事件环 一.node为什么要使用异步I/O 异步最先诞生于操作系统的底层,在底层系统中,异步通过信号量 ...
- (ICONIP2021)On the Unreasonable Effectiveness of Centroids in Image
目录 摘要 1.引言 2.提出的方法 2.1 CentroidTripletloss 2.2 聚合表示 3.实验 3.1 数据集 3.2 应用细节 3.3 Fashion检索结果 3.4 行人再识别结 ...