前言:文章附上具体的脚本信息内容略长。
1、CE6851 OPS & 开放系统
产品文档链接:
http://support.huawei.com/enterprise/zh/doc/EDOC1000078659?idPath=7919710%7C21782165%7C21782239%7C22318540%7C7597815
测试环境:HUAWEI CE6851-48S6Q-HI (CE6851HI V100R006C00SPC600)
1.1 TEST OPS
“配置”-“配置指南”-“设备管理”-“OPS配置”
1.1.1 上传API脚本至交换机
Idx Attr Size(Byte) Date Time FileName
17 -rw- 3,779 Aug 22 2018 17:55:46 test.py
1.1.2 测试API脚本
#!/usr/bin/env python
import traceback
import httplib
import string
class OPSConnection(object):
"""Make an OPS connection instance."""
def __init__(self, host, port = 80):
self.host = host
self.port = port
self.headers = {
"Content-type": "text/xml",
"Accept": "text/xml"
}
self.conn = None
def close(self):
"""Close the connection"""
self.conn.close()
def create(self, uri, req_data):
"""Create operation"""
ret = self.rest_call("POST", uri, req_data)
return ret
def delete(self, uri, req_data):
"""Delete operation"""
ret = self.rest_call("DELETE", uri, req_data)
return ret
def get(self, uri, req_data = None):
"""Get operation"""
ret = self.rest_call("GET", uri, req_data)
return ret
def set(self, uri, req_data):
"""Set operation"""
ret = self.rest_call("PUT", uri, req_data)
return ret
def rest_call(self, method, uri, req_data):
"""REST call"""
print('|---------------------------------- request: ----------------------------------|')
print('%s %s HTTP/1.1\n' % (method, uri))
if req_data == None:
body = ""
else:
body = req_data
print(body)
if self.conn:
self.conn.close()
self.conn = httplib.HTTPConnection(self.host, self.port)
self.conn.request(method, uri, body, self.headers)
response = self.conn.getresponse()
response.status = httplib.OK # stub code
ret = (response.status, response.reason, response.read())
print('|---------------------------------- response: ---------------------------------|')
print('HTTP/1.1 %s %s\n\n%s' % ret)
print('|------------------------------------------------------------------------------|')
return ret
def get_startup_info(ops_conn):
"""Get startup info. """
uri = "/cfg/startupInfos/startupInfo"
req_data = \
'''
'''
ret, _, rsp_data = ops_conn.get(uri, req_data)
if ret != httplib.OK:
return None
return rsp_data
def backup_file(ops_conn,cfgFileName):
"""Copy configuration."""
uri = "/ftpc/ftpcTransferFiles/ftpcTransferFile"
str_temp = string.Template(
'''
''')
req_data = str_temp.substitute(srcFileName = cfgFileName,desFileName = cfgFileName.strip('flash:/'))
ret, _, rsp_data = ops_conn.create(uri, req_data)
if ret != httplib.OK:
return None
return rsp_data
def main():
"""The main function."""
host = "localhost"
try:
ops_conn = OPSConnection(host)
print('+-------------------------- Open a OPS connection. ----------------------------+')
rsp_data = get_startup_info(ops_conn)
if rsp_data is not None:
cfgFileName = rsp_data[rsp_data.find("curStartupFile")+15 : rsp_data.find("/curStartupFile")-1]
backup_file(ops_conn,cfgFileName)
ops_conn.close()
print('+-------------------------- Close a OPS connection. ---------------------------+')
return
except:
errinfo = traceback.format_exc()
print(errinfo)
return
if __name__ == "__main__":
main()
斜体加粗为交换机的部分信息
+-------------------------- Open a OPS connection. ----------------------------+
|---------------------------------- request: ----------------------------------|
GET /cfg/startupInfos/startupInfo HTTP/1.1
|---------------------------------- response: ---------------------------------|
HTTP/1.1 200 OK
|------------------------------------------------------------------------------|
|---------------------------------- request: ----------------------------------|
POST /ftpc/ftpcTransferFiles/ftpcTransferFile HTTP/1.1
|---------------------------------- response: ---------------------------------|
HTTP/1.1 200 Internal Server Error
|------------------------------------------------------------------------------|
+-------------------------- Close a OPS connection. ---------------------------+
1.1.3 目前OPS通过维护助手定时上传相应信息,后续内容未继续测试,相关信息详见链接中的文档
1.2 TEST 开放系统
“配置”-“开放系统使用指南”
1.2.1 制作sqfs文件
https://github.com/HuaweiSwitch/LXC_Rootfs
1.2.2 上传sqfs文件
Idx Attr Size(Byte) Date Time FileName
16 -rw- 77,373,440 Aug 22 2018 16:34:26 rootfs_1.sqfs
1.2.3 开启开放系统的容器功能
bash shell rootfs_1.sqfs
1.2.4 进入开放系统
Type
root@CE:~# ip add l
1: lo:
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
10: eth0:
link/ether 3e:bc:24:b7:6e:44 brd ff:ff:ff:ff:ff:ff
inet 192.168.233.233/24 brd 192.168.233.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::3cbc:24ff:feb7:6e44/64 scope link
valid_lft forever preferred_lft forever
root@CE:~#
1.3 小结
无论OPS或者开放系统,功能有限,不够灵活。
2、CISCO DEVNET
参考CSC第39期
实验环境:EVE中的CISCO NX-OSv 9k (Hardware cisco Nexus9000 9000v Chassis , NXOS: version 7.0(3)I7(1))
2.1 交换机内部Python演示
参考链接:https://developer.cisco.com/docs/nx-os/#!getting-started
斜体加粗为输入指令
switch# show run int lo0
^
Invalid range at '^' marker.
switch# python
Python 2.7.5 (default, Nov 5 2016, 04:39:52)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from cli import *
>>> cli('conf t ; int lo0 ; ip add 9.9.9.9/32')
''
>>> exit()
switch# show run int lo0
!Command: show running-config interface loopback0
!Time: Thu Sep 13 03:07:34 2018
version 7.0(3)I7(1)
interface loopback0
ip address 9.9.9.9/32
switch#
switch# python
Python 2.7.5 (default, Nov 5 2016, 04:39:52)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from cli import *
>>> import json
>>> result = json.loads(clid("show int lo0"))
>>> print result
{u'TABLE_interface': {u'ROW_interface': {u'eth_ip_prefix': u'9.9.9.9', u'eth_ip_mask': u'32', u'eth_txload': u'1', u'loop_out_bytes': u'0', u'eth_hw_desc': u'Loopback', u'loop_in_compressed': u'0', u'loop_in_mcast': u'0', u'loop_in_fifo': u'0', u'loop_out_carriers': u'0', u'state': u'up', u'eth_dly': u'5000', u'loop_in_errors': u'0', u'loop_out_collisions': u'0', u'loop_out_pkts': u'0', u'eth_mtu': u'1500', u'eth_rxload': u'1', u'eth_bw': u'8000000', u'loop_in_overrun': u'0', u'admin_state': u'up', u'loop_in_frame': u'0', u'interface': u'loopback0', u'loop_in_bytes': u'0', u'eth_reliability': u'255', u'eth_ip_addr': u'9.9.9.9', u'loop_in_pkts': u'0', u'loop_out_errors': u'0', u'eth_mdix': u'off', u'loop_out_underruns': u'0', u'loop_out_fifo': u'0'}}}
>>>
>>> print (result['TABLE_interface']['ROW_interface']['eth_ip_addr'])
9.9.9.9
>>>
>>> result = json.loads(clid("show vlan"))
>>> print result
{u'TABLE_mtuinfo': {u'ROW_mtuinfo': {u'vlanshowinfo-vlanid': u'1', u'vlanshowinfo-media-type': u'enet', u'vlanshowinfo-vlanmode': u'ce-vlan'}}, u'TABLE_vlanbrief': {u'ROW_vlanbrief': {u'vlanshowbr-vlanstate': u'active', u'vlanshowplist-ifidx': u'Ethernet1/1,Ethernet1/2,Ethernet1/3,Ethernet1/4,Ethernet1/5,Ethernet1/6,Ethernet1/7,Ethernet1/8,Ethernet1/9,Ethernet1/10,Ethernet1/11,Ethernet1/12,Ethernet1/13,Ethernet1/14,Ethernet1/15,Ethernet1/16,Ethernet1/17,Ethernet1/18,Ethernet1/19,Ethernet1/20,Ethernet1/21,Ethernet1/22,Ethernet1/23,Ethernet1/24,Ethernet1/25,Ethernet1/26,Ethernet1/27,Ethernet1/28,Ethernet1/29,Ethernet1/30,Ethernet1/31,Ethernet1/32,Ethernet1/33,Ethernet1/34,Ethernet1/35,Ethernet1/36,Ethernet1/37,Ethernet1/38,Ethernet1/39,Ethernet1/40,Ethernet1/41,Ethernet1/42,Ethernet1/43,Ethernet1/44,Ethernet1/45,Ethernet1/46,Ethernet1/47,Ethernet1/48,Ethernet1/49,Ethernet1/50,Ethernet1/51,Ethernet1/52,Ethernet1/53,Ethernet1/54,Ethernet1/55,Ethernet1/56,Ethernet1/57,Ethernet1/58,Ethernet1/59,Ethernet1/60,Ethernet1/61,Ethernet1/62,Ethernet1/63,Ethernet1/64', u'vlanshowbr-vlanid-utf': u'1', u'vlanshowbr-vlanname': u'default', u'vlanshowbr-vlanid': u'1', u'vlanshowbr-shutstate': u'noshutdown'}}}
>>> from cisco.vlan import *
>>> showvlanojb = ShowVlan()
>>> showvlanojb.get_vlans() #查看vlan
[('1',), ('1',)]
>>>
>>> v = Vlan()
>>> v.create_vlan(333) #添加vlan
True
>>> showvlanojb.get_vlans()
[('1',), ('1',)]
>>> showvlanojb = ShowVlan()
>>> showvlanojb.get_vlans()
[('1',), ('333',), ('1',), ('333',)]
>>>
2.2 交换机Python演示
2.2.1 基于CDP信息自动生成接口描述
脚本文件通过sftp上传至交换机的bootflash,也可以进入交换机底层系统进行创建。
switch# run bash
bash-4.2$ dir
bash-4.2$ sudo su -
root@switch#ls
root@switch#ls
root@switch#cd /
root@switch#pwd
/
root@switch#ls
bin isan_bin_eth.img isan_n9k_lib.img n3k_tor_delete.list sys_block_bootdev vdc_17
boot isan_bin_eth_ro lc nativeboot tmp vdc_2
boot_dev isan_bin.img lcimages nfsroot usbslot1 vdc_3
boot_eth isan_bin_n9k_ro lc_n9k_ro nginx usbslot2 vdc_4
bootflash isan_bin_n9k_rw lc_ro nginx_1_fe usr vdc_5
cgroup isan_bin_ro lc_rw nxos usr.img vdc_6
cmn isan_bin_rw lib opt usr_ro vdc_7
data isanboot lib64 proc usr_rw vdc_8
debug isan_lib_eth.img linuxrc proc_isan var vdc_9
debugfs isan_lib_eth_ro log rd vdc_10 vmachine
dev isan_lib.img logflash root vdc_11 volatile
dklm_lc.tar isan_lib_n9k_ro media rpms vdc_12
etc isan_lib_n9k_rw mgmt sbin vdc_13
home isan_lib_ro mnt slot0 vdc_14
init isan_lib_rw mod-1 smack vdc_15
isan isan_n9k_bin.img modflash sys vdc_16
root@switch#cd bootflash/
root@switch#ls
20180912_021931_poap_27074_init.log nxos.7.0.3.I7.1.bin virtual-instance
config_if_desc.py platform-sdk.cmd virtual-instance.conf
home scripts
int_counter.py virt_strg_pool_bf_vdc_1
root@switch#more config_if_desc.py
from cli import *
import json
import re
def getupintlist():
intflist = json.loads(clid('show interface brief'))
i = 0
upintflist = []
while i < len(intflist['TABLE_interface']['ROW_interface']):
intf = intflist['TABLE_interface']['ROW_interface'][i]
i = i+1
if intf['state'] == 'up':
if re.match('.*Ether.*|.*mgmt.*',intf['interface']):
upintflist.append(intf['interface'])
return upintflist
def getneiname(ifname):
try:
neidetail = json.loads(clid('show cdp neighbors interface %s' % ifname))
return neidetail['TABLE_cdp_neighbor_brief_info']['ROW_cdp_neighbor_brief_info']['device_id']
except:
return None
def config_description(ifname):
enter_inf = 'interface %s' % ifname
description = 'description link_to_%s' % getneiname(ifname)
cli_cmd = 'configure terminal ; ' + enter_inf + ' ; ' +description
cli(cli_cmd)
if __name__ == '__main__':
print getupintlist()
print (getneiname('mgmt 0'))
up_interfaces = getupintlist()
for x in up_interfaces:
if getneiname(x):
config_description(x)
root@switch#
switch(config-if)# python bootflash:///config_if_desc.py
[u'mgmt0', u'Ethernet1/1', u'Ethernet1/2', u'Ethernet1/3', u'Ethernet1/4', u'Ethernet1/5', u'Ethernet1/6', u'Ethernet1/7']
FZ-SVR-01
switch(config-if)# sh run int mgmt0
!Command: show running-config interface mgmt0
!Time: Thu Sep 13 07:16:52 2018
version 7.0(3)I7(1)
interface mgmt0
description link_to_FZ-SVR-01
vrf member management
ip address 10.5.39.252/24
switch(config-if)#
2.2.2 查看接口计数(间隔1s,5次)
root@switch# more int_counter.py
from cli import *
import json
import sys,time
ifName = sys.argv[1]
delay = float(sys.argv[2])
count = int(sys.argv[3])
cmd = 'show interface ' + ifName + ' counters'
out = json.loads(clid(cmd))
rxuc = int(out['TABLE_rx_counters']['ROW_rx_counters']['eth_inucast'])
rxmc = int(out['TABLE_rx_counters']['ROW_rx_counters']['eth_inmcast'])
rxbc = int(out['TABLE_rx_counters']['ROW_rx_counters']['eth_inbcast'])
txuc = int(out['TABLE_tx_counters']['ROW_tx_counters']['eth_outucast'])
txmc = int(out['TABLE_tx_counters']['ROW_tx_counters']['eth_outmcast'])
txbc = int(out['TABLE_tx_counters']['ROW_tx_counters']['eth_outbcast'])
print ' ROW rx_ucast rx_mcast rx_bcast tx_ucast tx_mcast tx
_bcast'
print '===========================================================================================
============='
print ' %8d %8d %8d %8d %8d %8d' % (rxuc,rxmc,rxbc,txuc,txmc,txbc)
print '===========================================================================================
============='
i = 0
while (i < count):
time.sleep(delay)
out = json.loads(clid(cmd))
rxuc_new = int(out['TABLE_rx_counters']['ROW_rx_counters']['eth_inucast'])
rxmc_new = int(out['TABLE_rx_counters']['ROW_rx_counters']['eth_inmcast'])
rxbc_new = int(out['TABLE_rx_counters']['ROW_rx_counters']['eth_inbcast'])
txuc_new = int(out['TABLE_tx_counters']['ROW_tx_counters']['eth_outucast'])
txmc_new = int(out['TABLE_tx_counters']['ROW_tx_counters']['eth_outmcast'])
txbc_new = int(out['TABLE_tx_counters']['ROW_tx_counters']['eth_outbcast'])
i += 1
print '%8d %8d %8d %8d %8d %8d %8d' % (i,rxuc_new,rxmc_new,rxbc_new,txuc_
new,txmc_new,txbc_new)
root@switch#
switch# python bootflash:///int_counter.py mgmt0 1 5
ROW rx_ucast rx_mcast rx_bcast tx_ucast tx_mcast tx_bcast
========================================================================================================
6618 1330741 353961 5339 1723 4
========================================================================================================
1 6619 1330764 353984 5343 1723 4
2 6620 1330768 353986 5344 1723 4
3 6621 1330789 353994 5345 1723 4
4 6622 1330829 354003 5346 1723 4
5 6623 1330881 354010 5347 1723 4
switch#
2.2.3 定时任务执行Python
switch# show cli history | begin 'show clock ' | cut -c 16-
show clock
conf t
feature scheduler
scheduler job name run_python
python bootflash:///config_if_desc.py
exit
scheduler schedule name test_run_python
job name run_python
time start now repeat 0:0:2
end
switch# show scheduler job
Job Name: run_python
--------------------
python bootflash:/config_if_desc.py
==============================================================================
switch# show scheduler schedule
Schedule Name : test_run_python
-------------------------------------
User Name : admin
Schedule Type : Run every 0 Days 0 Hrs 2 Mins
Start Time : Thu Sep 13 08:48:41 2018
Last Execution Time : Thu Sep 13 09:28:41 2018
Last Completion Time: Thu Sep 13 09:28:48 2018
Execution count : 21
-----------------------------------------------
Job Name Last Execution Status
-----------------------------------------------
run_python Success (0)
==============================================================================
switch#
2.3 Netconf
2.3.1 NXOS开启netconf服务
root@switch#service netconf status
xosdsd is stopped
netconf is stopped
root@switch#service netconf start
Starting Netconf Agent: [OK]
root@switch#service netconf status
xosdsd (pid 10268) is running...
netconf (pid 10271) is running...
2.3.2 登入
#ssh -2 [email protected] -s netconf
User Access Verification
Password:
]]>]]>
2.3.2 测试演示
加粗字体为输入指令,其余为输出内容
================================================================================hello交互后才能执行之后的操作
]]>]]>
================================================================================show version
]]>]]>
<__XML__OPT_Cmd_sysmgr_show_version___readonly__>
<__readonly__>
TAC support: http://www.cisco.com/tac
Documents: http://www.cisco.com/en/US/products/ps9372/tsd_products_support_series_home.html
Copyright (c) 2002-2017, Cisco Systems, Inc. All rights reserved.
The copyrights to certain works contained herein are owned by
other third parties and are used and distributed under license.
Some parts of this software are covered under the GNU Public
License. A copy of the license is available at
http://www.gnu.org/licenses/gpl.html.
Nexus 9000v is a demo version of the Nexus Operating System
]]>]]>
================================================================================show run,输出内容未贴出
]]>]]>
================================================================================接口配置
<__XML__MODE_if-ethernet> <__XML__MODE_if-eth-base>
]]>]]>
------------------------------------交换机生成配置
switch(config)# sh run int e1/3
!Command: show running-config interface Ethernet1/3
!Time: Fri Sep 14 02:46:01 2018
version 7.0(3)I7(1)
interface Ethernet1/3
shutdown
switch(config)#
switch(config)#
switch(config)# sh run int e1/3
!Command: show running-config interface Ethernet1/3
!Time: Fri Sep 14 02:46:13 2018
version 7.0(3)I7(1)
interface Ethernet1/3
description Configured by NETCONF
no switchport
ip address 192.168.133.11/24
no shutdown
switch(config)#
------------------------------------
================================================================================show scheduler schedule
]]>]]>
]]>]]>
================================================================================show run int e1/3
]]>]]>
!Command: show running-config interface Ethernet1/3
!Time: Fri Sep 14 03:34:30 2018
version 7.0(3)I7(1)
interface Ethernet1/3
description Configured by NETCONF
no switchport
ip address 192.168.133.11/24
no shutdown
]]>]]>
================================================================================
2.4 NX-API REST SDK
参考链接:https://developer.cisco.com/docs/cisco-nexus-3000-and-9000-series-nx-api-rest-sdk-user-guide-and-api-reference-release-9-x/
2.4.1 交换机开启api feature
switch(config)# feature nxapi
switch(config)# show feature | i api
nxapi 1 enabled
switch(config)#
2.4.2 交换机沙盒进行指令转换
10.5.39.252为交换机的管理地址
2.4.3 脚本信息
[ 15:42:23-root@localhost ]#cat iplist.py
import json
from urllib3 import *
from base64 import b64encode
import certifi
disable_warnings()
http = PoolManager(ca_certs=certifi.where(), cert_reqs='CERT_NONE', assert_hostname=False)
username = "admin"
password = "XXXXXXXXXXXX"
ip = "10.5.39.252"
url = "https://" + ip + "/ins"
my_headers = {'content-type':'application/json-rpc'}
user_pass_str = username + ':' + password
user_pass_str_encode = user_pass_str.encode()
userAndPass = b64encode(user_pass_str_encode).decode("ascii")
my_headers["Authorization"] = 'Basic %s' % userAndPass
[ 15:42:24-root@localhost ]#cat test_json_vlan.py
from iplist import *
def test_json_rpc():
payload = [
{
"jsonrpc": "2.0",
"method": "cli",
"params": {
"cmd": "vlan 222",
"version": 1
},
"id": 1
},
{
"jsonrpc": "2.0",
"method": "cli",
"params": {
"cmd": " name nxapi_config",
"version": 1
},
"id": 2
}
]
r = http.request('POST',url,headers=my_headers,body=json.dumps(payload))
print(r.data)
if __name__ == "__main__":
test_json_rpc()
[ 15:42:26-root@localhost ]#cat test_json_show.py
from iplist import *
import json
def test_json_rpc():
payload = [
{
"jsonrpc": "2.0",
"method": "cli",
"params": {
"cmd": "show version",
"version": 1
},
"id": 1
}
]
r = http.request('POST', url, headers=my_headers, body=json.dumps(payload))
print(r.data)
print((json.loads(r.data)['result']['body']['chassis_id']))
if __name__ == "__main__":
test_json_rpc()
2.4.4 执行 test_json_vlan.py 生成vlan
[ 15:42:36-root@localhost ]#python test_json_vlan.py #下列信息可以设置不打印
[{
"jsonrpc": "2.0",
"result": null,
"id": 1
}, {
"jsonrpc": "2.0",
"result": null,
"id": 2
}]
------------------------------------交换机生成配置
switch(config)# sh run vlan 222
!Command: show running-config vlan 222
!Time: Fri Sep 14 07:44:50 2018
version 7.0(3)I7(1)
vlan 222
vlan 222
name nxapi_config
switch(config)#
------------------------------------
2.4.5 执行 test_json_show.py 查看版本信息
[ 15:42:46-root@localhost ]#python test_json_show.py
{
"jsonrpc": "2.0",
"result": {
"body": {
"header_str": "Cisco Nexus Operating System (NX-OS) Software\nTAC support: http://www.cisco.com/tac\nDocuments: http://www.cisco.com/en/US/products/ps9372/tsd_products_support_series_home.html\nCopyright (c) 2002-2017, Cisco Systems, Inc. All rights reserved.\nThe copyrights to certain works contained herein are owned by\nother third parties and are used and distributed under license.\nSome parts of this software are covered under the GNU Public\nLicense. A copy of the license is available at\nhttp://www.gnu.org/licenses/gpl.html.\n\nNexus 9000v is a demo version of the Nexus Operating System\n",
"bios_ver_str": "",
"kickstart_ver_str": "7.0(3)I7(1)",
"bios_cmpl_time": "",
"kick_file_name": "bootflash:///nxos.7.0.3.I7.1.bin",
"kick_cmpl_time": " 8/31/2017 14:00:00",
"kick_tmstmp": "08/31/2017 22:29:32",
"chassis_id": "Nexus9000 9000v Chassis",
"cpu_name": "",
"memory": 8165044,
"mem_type": "kB",
"proc_board_id": "9Y676KBSI7N",
"host_name": "switch",
"bootflash_size": 3509454,
"kern_uptm_days": 2,
"kern_uptm_hrs": 3,
"kern_uptm_mins": 56,
"kern_uptm_secs": 43,
"rr_reason": "Unknown",
"rr_sys_ver": "",
"rr_service": "",
"manufacturer": "Cisco Systems, Inc.",
"TABLE_package_list": {
"ROW_package_list": {
"package_id": {
}
}
}
}
},
"id": 1
}
3 总结
就当前情况,与华为CE交换机相比,CISCO Nexus交换机提供更丰活灵活的API接口