Huawei_Netconf_Ncclient
Huawei_Netconf_Ncclient
官网介绍
- ncclient 是一个用于 NETCONF 客户端的 Python 库。
- 它旨在提供一个直观的 API
- 将 NETCONF 的 XML 编码特性明智地映射到 Python 结构和习惯用法,并使编写网络管理脚本变得更加容易。
- 异步RPC
- 正常情况下我们只需要导入ncclient当中的manager就可以了
from ncclient import manager
with manager.connect(host=host, port=830, username=user, hostkey_verify=False, device_params={'name':'junos'}) as m:
c = m.get_config(source='running').data_xml
with open("%s.xml" % host, 'w') as f:
f.write(c)o invoke Juniper’s functions and params one has to re-write the above with device_params={‘name’:’junos’}:
For example to invoke Juniper’s functions and params one has to re-write the above with device_params={‘name’:’junos’}:例如,要调用 Juniper 的函数和参数,必须使用 device_params={‘name’:’junos’} 重写上面的代码:
from ncclient import manager
with manager.connect(host=host, port=830, username=user, hostkey_verify=False, device_params={'name':'junos'}) as m:
c = m.get_config(source='running').data_xml
with open("%s.xml" % host, 'w') as f:
f.write(c)
复习一下上面的get_config是什么意思?Netconf的基本操作方法之一
根据官网介绍攒一攒代码
# 导入库当中的功能
from ncclient import manager
# 发起连接
manager.connect(
host="192.168.80.100",
port=830,
username="zhangsan",
hostkey_verify=False,
device_params={'name':'huawei'})
# 将xml文件发送到设备并取加返回值
get_config(source='running').data_xml
明智地映射
明智地映射是什么意思?
明智的映射就是ncclient就是能够帮你把Message层和Operations层的内容写好,我们只需要关注content内容层的东西。
其实我们会发现上图当中有几个关键词意思是有点重叠的,比如说有两个merge,还有一个edit-conf,这三个单词其实都有重叠的含义,那就是修改,所以当我们只需要把content层当中的merge写出来就可以了,操作层和消息层的有关修改的信息都是自动由ncclient填充的。
再重复一遍呀!操作层和消息层我们都不用写,我们只需要想办法把content层里面的内容写出来就可以了,而content层里面的东西取决于你在device_params选择的哪个厂商,你如果选择的是华为那你就找找华为关于Netconf的文档,把内容复制出来放到Content当中即可。
我们下面这一章节就告诉大家:
- 如何写华为的content层?其实是去华为的开发者文档里面复制?
- 如何下载华为关于netconf的开发者文档呢?
- 下载了之后又如何查看呢?
内容层
前言
通过在ncclient官网上的了解,我们发现nclient对思科的支持是最好的,对华为只支持两种device_params,一种是比较新的大部分厂商都在使用的YANG模型,另一种则是华为在没有YANG模型之前的Schema,所以说华为在模型语言有两种,也就是说有起码会有两个开发者文档。
我们就拿Schema开发者文件来看一下,到底如何查看这个文档,我们应该复制哪些内容?
NETCONF协议介绍那一章值得一看!比华为HCIE官方PPT介绍的详细很多!
这个文档的目录与普通的用户手册并没有特别什么不同,所有的功能都分类编写,我们想看啥就直接去点就可以了,比如我们想查看某个接口的状态或是配置某个接口,就直接到“接口”管理那一章节里面去查看就好了,而且它里面有一些现成的配置,就是开头那个典型应用,有很多地方我们可以直接抄,比较方便。
所以可以通过两种途经查看想要的配置:
- 直接看典型配置
- 根据分类找
典型配置
上面两个图都是从典型配置当中直接拿出来来的,把代码当中的接口号修改成你想的,立马就能使用,ctrl+c和ctrl+v得心应手!
分类查看
同样的,我们还是想看接口状态和想把接口从二层接口修改成三层模式。
我没有找到怎么将二层修改成三层怎么办?那就把接口所有属性都get下来,这样就能看到了,然后我们再修改。
规律
我们在网络设备做的操作,大多数都是查询,然后根据需求修改,不经常用的操作是保存和备份,我们可以总结一下我们使用网络设备的周期:
- 连接-ssh
- 查看状态-get或get-config
- 修改配置-merge
- 保存配置
- 备份配置-sftp
配置思路
基本信息
关于NetConf的理论性信息我们已经总结过来,链接在此,本文档只讨论如何编写NetConf文件。
编写Netconf的思路:
- 编写netconf连接
- 填写数据或过滤器
- 编写操作
第一步:编写netconf连接,这一步最容易理解就是类似ssh,你要准备好连接Nnetconf用到的IP、用户之类的信息;
第二步:netconf即可以通过edit这种操作方法去修改设备的配置信息,那你要修改什么内容呢?比如你要修改g0/0/1接口的IP地址,那好,那你得明确指明我要修改的“具体对象”是g0/0/1接口,那这个对象你要在第二步当中填写的数据。那怎么还要有过滤器呢?是因为你通过Netconf不仅仅是去修改设备的配置信息,你还可以进行查询呀,那查询的话,你也得指明你想查询哪些信息?就像在linux当中我们去grep root /etc/passwd,那root就是我们要grep当中要使用的过滤器,过滤器可以理解为我们想要的信息。也就是说,如果你是要查询配置,那就得通过过滤器告诉Netconf想看哪些信息;如果你想编辑配置,那就得通过“数据”指明你想修改的对象。
第三步:编写操作,当你在第二步指定了某个对象之后,接下来就要把你的操作写上了,是edit还是get。第二步和第三步的的关系可以理解为:先找到对象,然后再决定对它采取什么措施。
想要使用Netconf,得先安装支持Netconf客户端的模块ncclient
关于建模语言的选择,华为在本身支持YANG这种编码要求的建模语言,同时也支持Schema这种建模语言,我们可以选择一种使用,建议选择YANG,因为YANG是使用厂商最多的,具有较好的兼容性,不仅仅能在华为设备上使用。在接下来实验当中我们先用Schema,然后再用YANG。
代码编写思路
- 我们对网络设备常用的操作无非是查询和修改,那我们就打算编写两个函数,分别用于查询和修改。
- 在编写之前确定我们要查询和编辑的数据和过滤器,我们就是我们将要要操作的“对象”
- 将要查询的内容放到查询,即get相关联的函数当中;将要编辑的放到编辑,即edit相关联的函数当中。
我们将要做的任务是:查询某个并没上电的接口,通过Netconf查询并返回其状态,然后,将此接口的的打开,并最终再次返回接口状态用以确认。
通用代码解释
# 查看ncclient是否已经正确安装
import ncclient
print(ncclient.__version__)
"C:\Program Files\Python311\python.exe" G:\python2\第十章\text_files\netconf.py
0.6.13
预先配置
配置解释
# 启用netconf功能,并且调用ssh并侦听830端口
[HUAWEI]netconf
[HUAWEI-netconf]protocol inbound ssh port 830
Info: Succeeded in starting the ssh port 830 service.
[HUAWEI-netconf]dis tcp status
-----------------------------------------------------------------------------------
Cid SocketID Local-Addr:Port Foreign-Addr:Port State VPNName
-----------------------------------------------------------------------------------
0x8093271F 2 0.0.0.0:22 0.0.0.0:0 LISTEN --
0x8093271F 15 192.168.80.101:22 192.168.80.1:5109 ESTABLISHED --
0x8093271F 16 0.0.0.0:830 0.0.0.0:0 LISTEN --
Netconf为什么要于ssh扯上关系呢?如果你前面看了理论部分就不会有此疑问了,ssh本来就包括在Netconf的协议集当中,可以看做是Netconf的一部分,就像SSL之于HTTP一样的关系。
# 在aaa数据库里面新建一个专门用于Netconf的用户
[HUAWEI]aaa
[HUAWEI-aaa]local-user ncuser password cipher Passworda1!aaa
Info: A new user is added.
[HUAWEI-aaa]local-user ncuser level 3
[HUAWEI-aaa]local-user ncuser service-type ssh
Info: The user ncuser's password has been changed to be irreversible.
快速配置
system-view immediately
telnet server disable
stelnet server enable
user-interface vty 0 4
authentication-mode aaa
quit
aaa
local-user ncuser password cipher Passworda1!
local-user ncuser level 3
local-user ncuser service-type ssh
quit
netconf
protocol inbound ssh port 830
int GE 1/0/1
undo portswitch
undo shutdown
ip add 192.168.80.101 24
Schema
代码片段--编写连接
from ncclient import manager
nc_port = 830
nc_user = "ncuser"
ip = "192.168.80.101"
nc_pass = "Passworda1!"
nc_proc = manager.connect(
host=ip,
port=nc_port,
password=nc_pass,
username=nc_user,
hostkey_verify=False,
device_params={'name':"huawei"}
)
- 上面这段代码其实就是我们思路的第一步,即通过ssh与设备建立链接。
- 第一行代码当中我们仅仅引入了一个方法,并不用把整个nclient全部分引入的
- 为什么端口使用830?因为Netconf的公认端口号就是830,已经被netconf注册了的。
- hostkey_verify=False这一行其实挺简单,这一行其实就调用了ssh当中的ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
- device_params={'name':"huawei"}这是个字典,是关于建模语言的的选择,name是键,这是固定的,后面的huawei的意思就是代表Schema这种建模语言,我们这么写,其实就是声明后续的代码我将使用Schema这种建模语言的格式要求进行编写。
注意,由于ncclient模块写的很烂,你会发现在写参数,比如说password这些参数时不会自动联想并补全,这是因为模块的原因,这其实也是导致现在人们普遍不愿意使用ncclient的原因,转而使用resetconf相关的模块。
调用了ssh,但没有完整调用,你会发现看不出来协议,只能看到TCP,里面的数据全都加密了。
代码片段-编写数据或过滤器
完整的XML代码包括了:
- Message消息层,用来确定发起哪个系统调用,无法也就是类似get、edit之类的。
- Operations操作层,其实也是你想对“对象”做什么动作,无非也就是get、edit之类的。
以上两层我们都不用管,为什么呢?因为我们会在第三步的时候编写
这一步不用我们管,ncclient会根据我们在第三步编写操作,ncclient模块会根据我们写的具体操作,将具体的操作转换成为Message的系统调用和Operations层当中的动作,这一步很好理解呀,我们在搞NFS的时候,就直接把远程目录的文件双击打开了,NFS程序自动会把我们双击这个动作转换为read相关的RPC调用传给服务器的。
所以我们主要的关注点其实是在内容层,内容层里面你要把你要操作的对象和对象的操作方法写上,我们把这两点明确之后,也就是第二步和第三步我们做完之后,Message和Operations会自动生成,我们会在复习华为API参考手册的时候,Message和Operations部分不用复制,我们只复制内容层当中的内容,即Content当中的内容即可,上图当中的格式是YHANG格式,我们接下来要操作是Schama格式的,但原理是差不多,我们只需要复习上图当中红框标出来的部分到Pycharm当中即可。
Filter = '''
<filter type="subtree">
<ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<interfaces>
<interface>
<ifName>Eth-Trunk1</ifName>
<ifDynamicInfo>
<ifOperStatus></ifOperStatus>
<ifPhyStatus></ifPhyStatus>
<ifLinkStatus></ifLinkStatus>
<ifOpertMTU></ifOpertMTU>
<ifOperSpeed></ifOperSpeed>
<ifV4State></ifV4State>
<ifV6State></ifV6State>
<ifCtrlFlapDamp></ifCtrlFlapDamp>
<ifOperMac></ifOperMac>
</ifDynamicInfo>
</interface>
</interfaces>
</ifm>
</filter>
'''
就是把图中的内容层的要操作的对象部分复制了一下赋值给变量Filter而已,注意哈,这里面的要操作的对象还挺多的,ifDynamicInfo当中包括起来的就是要查询的对象,你看哈,里面有关于ipv4的状态,ipv6的状态,物理接口的状态,mtu等等,太多了,如果我们要这么查询会导致返回一大堆内容,所以我们想看什么,你就保留什么即可,我们说我们就想看接口的状态,那就可以把其它的全都删除掉,这样返回来的内容会非常的精简.还有一个地方要修改,那就是接口,上面的接口对象是eth-trunk1接口,我们不看这个接口,我们就要看看一下g1/0/1接口的状态,所以要在ifName>Eth-Trunk1</ifName当中把接口也修改一下,修改之后的内容如下:
Filter = '''
<filter type="subtree">
<ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<interfaces>
<interface>
<ifName>GE1/0/1</ifName>
<isL2SwitchPort></isL2SwitchPort>
<ifAdminStatus></ifAdminStatus>
</interface>
</interfaces>
</ifm>
</filter>
'''
isL2SwitchPort></isL2SwitchPort和ifAdminStatus></ifAdminStatus怎么来的?其实很简单,假如说我们只想看到接口是不是二层的,和接口的管理状态,我们也不知道这个对象怎么写,我们干脆可以什么都不写,只写一个接口信息,然后直接get或get_config把接口所有的信息都获取下来,然后我们看一下获取到的信息里面有哪些过滤器是我们想要的,就把它复制出来放到ifName>GE1/0/1</ifName下面,注意,不要忘记把值删除掉,如上述所示;
代码片段-编写查询操作
# 编写操作,get就是我们的动作,get就是获取信息
# 通过get方法将过滤器当中的内容传到设备上,并将结果赋值给result
result = nc_proc.get(filter=Filter)
print(result)
nc_proc.close_seesion
我们上述是使用get方法,还有一个比get更厉害一点的方法是get_config此方法可以指定我们数据库,这样我们查询的信息更准备,也更具有针对性,如下所示:
# 编写操作
result = nc_proc.get_config(source="running",filter=Filter)
print(result)
nc_proc.close_seesion
# 最终的结果如下所示:
"C:\Program Files\Python311\python.exe" G:\python2\第十章\text_files\netconf.py
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="urn:uuid:89e0aadf-b918-41d4-9d02-b111d574412f" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<data>
<ifm xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0">
<interfaces>
<interface>
<ifName>GE1/0/1</ifName>
<isL2SwitchPort>false</isL2SwitchPort> # 不是二层接口
<ifAdminStatus>up</ifAdminStatus> # 管理状态是UP的
</interface>
</interfaces>
</ifm>
</data>
</rpc-reply>
Process finished with exit code 0
取想要的值
我们看到了,上述代码尽管我们已经精简过了,但还是返回了大量的内容,对我们来说有价值的内容就那两行而已,我们让它只显示我们想要的那两行呢?其实很简单,把返回的内容搞成列表,然后通过列表的方法进行取值即可。
# 编写操作
result = nc_proc.get_config(source="running",filter=Filter)
result_1 = str(result)
## 取管理状态
admin_port = result_1.split('<ifAdminStatus>')[1].split("</ifAdminStatus>")[0]
## 取二层的状态
sw_port = result_1.split('<isL2SwitchPort>')[1].split("</isL2SwitchPort>")[0]
print((admin_port,sw_port))
"C:\Program Files\Python311\python.exe" G:\python2\第十章\text_files\netconf.py
('down', 'true')
查询操作完整代码
from ncclient import manager
nc_port = 830
nc_user = "ncuser"
ip = "192.168.80.101"
nc_pass = "Passworda1!"
nc_proc = manager.connect(
host=ip,
port=nc_port,
password=nc_pass,
username=nc_user,
hostkey_verify=False,
device_params={'name':"huawei"}
)
def if_get_config():
Filter = '''
<filter type="subtree">
<ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<interfaces>
<interface>
<ifName>GE1/0/2</ifName>
<isL2SwitchPort></isL2SwitchPort>
<ifAdminStatus></ifAdminStatus>
</interface>
</interfaces>
</ifm>
</filter>
'''
# 编写操作
result = nc_proc.get_config(source="running",filter=Filter)
result_1 = str(result)
## 取管理状态
admin_port = result_1.split('<ifAdminStatus>')[1].split("</ifAdminStatus>")[0]
## 取二层的状态
sw_port = result_1.split('<isL2SwitchPort>')[1].split("</isL2SwitchPort>")[0]
print(f'接口GE1/0/1当前二层的状态是{sw_port},管理状态是{sw_port}')
if_get_config()
编辑操作完整代码
ip = "192.168.80.101"
nc_pass = "Passworda1!aaa"
nc_proc = manager.connect(
host=ip,
port=nc_port,
password=nc_pass,
username=nc_user,
hostkey_verify=False,
device_params={'name':"huawei"}
)
def if_edit():
config = '''
<config>
<ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<interfaces>
<interface>
<ifName>GE1/0/2</ifName>
<ipv4Config>
<am4CfgAddrs>
<am4CfgAddr operation="merge">
<ifIpAddr>192.168.2.1</ifIpAddr>
<subnetMask>255.255.255.0</subnetMask>
<addrType>main</addrType>
</am4CfgAddr>
</am4CfgAddrs>
</ipv4Config>
</interface>
</interfaces>
</ifm>
</config>
'''
nc_proc.edit_config(target='running',config=config)
a = print("接口的IP地址已经设置成功")
return a
if_edit()
完整第一版
from ncclient import manager
nc_port = 830
nc_user = "ncuser"
ip = "192.168.80.101"
nc_pass = "Passworda1!aaa"
nc_proc = manager.connect(
host=ip,
port=nc_port,
password=nc_pass,
username=nc_user,
hostkey_verify=False,
device_params={'name':"huawei"}
)
def if_get_config():
Filter = '''
<filter type="subtree">
<ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<interfaces>
<interface>
<ifName>GE1/0/2</ifName>
<isL2SwitchPort></isL2SwitchPort>
<ifAdminStatus></ifAdminStatus>
</interface>
</interfaces>
</ifm>
</filter>
'''
# 编写操作
result = nc_proc.get_config(source="running",filter=Filter)
result_1 = str(result)
## 取管理状态
admin_port = result_1.split('<ifAdminStatus>')[1].split("</ifAdminStatus>")[0]
## 取二层的状态
sw_port = result_1.split('<isL2SwitchPort>')[1].split("</isL2SwitchPort>")[0]
print(f'接口GE1/0/2当前二层的状态是{sw_port},管理状态是{sw_port}')
#######################################################
def l2_l3_chagne():
config = '''
<config>
<ethernet xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<ethernetIfs>
<ethernetIf operation="merge">
<ifName>GE1/0/2</ifName>
<l2Enable>disable</l2Enable>
</ethernetIf>
</ethernetIfs>
</ethernet>
</config>
'''
nc_proc.edit_config(target='running', config=config)
print("已经成功将接口配置为三层接口,可以进行IP地址的配置和管理!")
def if_ip_change():
config = '''
<config>
<ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<interfaces>
<interface>
<ifName>GE1/0/2</ifName>
<ipv4Config>
<am4CfgAddrs>
<am4CfgAddr operation="merge">
<ifIpAddr>192.168.2.1</ifIpAddr>
<subnetMask>255.255.255.0</subnetMask>
<addrType>main</addrType>
</am4CfgAddr>
</am4CfgAddrs>
</ipv4Config>
</interface>
</interfaces>
</ifm>
</config>
'''
nc_proc.edit_config(target='running',config=config)
a = print("接口的IP地址已经设置成功")
return a
if_get_config()
l2_l3_chagne()
if_ip_change()
完整第二版
from ncclient import manager
nc_port = 830
nc_user = "ncuser"
ip = "192.168.80.101"
nc_pass = "Passworda1!aaa"
nc_proc = manager.connect(
host=ip,
port=nc_port,
password=nc_pass,
username=nc_user,
hostkey_verify=False,
device_params={'name':"huawei"}
)
def if_get_config():
Filter = '''
<filter type="subtree">
<ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<interfaces>
<interface>
<ifName>GE1/0/2</ifName>
<isL2SwitchPort></isL2SwitchPort>
<ifAdminStatus></ifAdminStatus>
</interface>
</interfaces>
</ifm>
</filter>
'''
# 编写操作
result = nc_proc.get_config(source="running",filter=Filter)
result_1 = str(result)
## 取管理状态
admin_port = result_1.split('<ifAdminStatus>')[1].split("</ifAdminStatus>")[0]
## 取二层的状态
sw_port = result_1.split('<isL2SwitchPort>')[1].split("</isL2SwitchPort>")[0]
print(f'接口GE1/0/2当前二层的状态是{sw_port},管理状态是{sw_port}')
#######################################################
def changeup():
config='''
<config>
<ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<interfaces>
<interface operation="merge">
<ifName>GE1/0/2</ifName>
<ifAdminStatus>up</ifAdminStatus>
</interface>
</interfaces>
</ifm>
</config>
'''
nc_proc.edit_config(target='running', config=config)
print("已经启用端口!")
def l2_l3_chagne():
config = '''
<config>
<ethernet xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<ethernetIfs>
<ethernetIf operation="merge">
<ifName>GE1/0/2</ifName>
<l2Enable>disable</l2Enable>
</ethernetIf>
</ethernetIfs>
</ethernet>
</config>
'''
nc_proc.edit_config(target='running', config=config)
print("已经成功将接口配置为三层接口,可以进行IP地址的配置和管理!")
def if_ip_change():
config = '''
<config>
<ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<interfaces>
<interface>
<ifName>GE1/0/2</ifName>
<ipv4Config>
<am4CfgAddrs>
<am4CfgAddr operation="merge">
<ifIpAddr>192.168.2.1</ifIpAddr>
<subnetMask>255.255.255.0</subnetMask>
<addrType>main</addrType>
</am4CfgAddr>
</am4CfgAddrs>
</ipv4Config>
</interface>
</interfaces>
</ifm>
</config>
'''
nc_proc.edit_config(target='running',config=config)
a = print("接口的IP地址已经设置成功")
return a
if_get_config()
changeup()
l2_l3_chagne()
if_ip_change()
"C:\Program Files\Python311\python.exe" G:\python2\第十章\text_files\netconf.py
接口GE1/0/2当前二层的状态是true,管理状态是true
已经启用端口!
已经成功将接口配置为三层接口,可以进行IP地址的配置和管理!
接口的IP地址已经设置成功
YANG
有了上述的基础,根据文档把上面的内容层替换一下即可。华为YANG与schema的格式非常相似,替换无压力。但华为的schema是比较成熟的,建议用schame。
第一步:先获取状态
from ncclient import manager
nc_port = 830
nc_user = "ncuser"
ip = "192.168.80.101"
nc_pass = "Passworda1!aaa"
nc_proc = manager.connect(
host=ip,
port=nc_port,
password=nc_pass,
username=nc_user,
hostkey_verify=False,
device_params={'name':"huaweiyang"})
def status():
Filter = '''
<filter type="subtree">
<ifm xmlns="http://www.huawei.com/netconf/vrp/huawei-ifm">
<interfaces>
<interface>
<ifName>GE1/0/2</ifName>
<ifAdminStatus></ifAdminStatus>
</interface>
</interfaces>
</ifm>
<ethernet xmlns="http://www.huawei.com/netconf/vrp/huawei-ethernet">
<ethernetIfs>
<ethernetIf>
<ifName>GE1/0/2</ifName>
<l2Enable></l2Enable>
</ethernetIf>
</ethernetIfs>
</ethernet>
</filter>
'''
# 编写操作
result = nc_proc.get_config(source="running",filter=Filter)
print(result)
status()
第二步:修改配置
# 修改配置
def change1():
config = '''
<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
<ethernet xmlns="http://www.huawei.com/netconf/vrp/huawei-ethernet">
<ethernetIfs>
<ethernetIf xc:operation="merge">
<ifName>GE1/0/2</ifName>
<l2Enable>disable</l2Enable>
</ethernetIf>
</ethernetIfs>
</ethernet>
</config>
'''
nc_proc.edit_config(target='running', config=config)
def change2():
config='''
<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
<ifm xmlns="http://www.huawei.com/netconf/vrp/huawei-ifm">
<interfaces>
<interface>
<ifName>GE1/0/2</ifName>
<ipv4Config>
<am4CfgAddrs>
<am4CfgAddr xc:operation="merge">
<ifIpAddr>192.168.2.1</ifIpAddr>
<subnetMask>255.255.255.0</subnetMask>
<addrType>main</addrType>
</am4CfgAddr>
</am4CfgAddrs>
</ipv4Config>
</interface>
</interfaces>
</ifm>
</config>
'''
nc_proc.edit_config(target='running', config=config)
print("已经配置好IP地址")
change1()
change2()