netmiko概述:
netmiko作为paramiko的高级封装,目的是简化各种网络供应商和平台之间的比较低效SSH(也支持telnet)管理。
netmiko基础代码和支持的设备可以参考:
https://blog.csdn.net/tushanpeipei/article/details/113704076?spm=1001.2014.3001.5501
textfsm概述:
textfsm作为开源python库,可以通过自定义模板的方式,将网络设备输出的格式按照给定的模板输出,例如使用netmiko在cisco交换机上使用命令:show ip interfcae brief,可以得到如下的字符串信息:
CSR1000v#show ip interface brief
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 192.168.0.66 YES NVRAM up up
GigabitEthernet2 10.1.1.1 YES NVRAM up up
GigabitEthernet3 unassigned YES NVRAM administratively down down
Loopback0 1.1.1.1 YES NVRAM up up
VirtualPortGroup0 30.1.1.254 YES NVRAM up up
处理字符串中的相关信息,我们第一时间可以想到的是使用正则表达式。但是正则表达式常常令人头疼,面对复杂的匹配要求时对使用人的熟练度要求较高。
使用textfsm的模板分析输出信息后,可以将回显信息整理为json的格式,方便python进行处理:
{
"intf": "GigabitEthernet1",
"ipaddr": "192.168.0.77",
"status": "up",
"proto": "up"
},
{
"intf": "GigabitEthernet2",
"ipaddr": "10.1.1.2",
"status": "up",
"proto": "up"
},
{
"intf": "GigabitEthernet3",
"ipaddr": "unassigned",
"status": "administratively down",
"proto": "down"
},
{
"intf": "Loopback0",
"ipaddr": "2.2.2.2",
"status": "up",
"proto": "up"
}
但是,仅仅使用textfsm,面对不同厂商,不同操作系统的回显信息,如果都由我们手工编写模板,则显得过于笨重和浪费时间。这时候就需要一个模板集来帮助我们将各种设备的回显信息转换为python容易处理的数据格式(XML、JSON、YAML)。这三种数据格式介绍可以参考:
https://blog.csdn.net/tushanpeipei/article/details/116883378?spm=1001.2014.3001.5501
ntc-templates概述:
ntc-templates作为一个textfsm的模板集,对绝大多数主流厂商(非国内)都有这比较好的支持性,特别是对于Cisco的设备。目前ntc-templates模板如下:
比较可怜的是,ntc-templates目前仅支持4个华为设备的模板。
测试实验:
实验目的:
通过netmiko&textfsm&ntc-templates获取设备接口为UP的信息和获取OSPF路由信息。
实验环境:
两台已经配置完成SSH的CSR1000v,IP地址分别为192.168.0.66、192.168.0.77。
步骤一: 安装netmiko、textfsm和ntc-templates
netmiko和textfsm直接使用pip3安装即可。
ntc-templates安装步骤如下:
-
在根目录下创建ntc-template目录,移动到创建好的ntc-template文件夹下,执行如下命令下载ntc-template.git文件。
git clone https://github.com/networktocode/ntc-templates.git
-
设置环境变量,方便netmiko调用模板:
export NET_TEXTFSM='/ntc-template/ntc-templates/templates'
注意:ntc-templates不能直接在windows下使用。
步骤二: 使用netmiko&textfsm&ntc-templates将路由器show相关信息转换为json字符串格式,方便后续分析:
from netmiko import ConnectHandler
import json
CSR1 = {
'device_type': 'cisco_ios',
'ip': '192.168.0.66',
'username': 'prin',
'password': 'Cisc0123',
}
CSR2 = {
'device_type': 'cisco_ios',
'ip': '192.168.0.77',
'username': 'prin',
'password': 'Cisc0123',
}
CSR_Group = [CSR1, CSR2]
for device in CSR_Group:
# 避免有连接不上的设备,使用异常处理机制
try:
# 依次连接每一个设备
connect = ConnectHandler(**device)
# 通过textfsm模板对接口信息进行分析
interfaces = connect.send_command('show ip int brief', use_textfsm=True)
print(json.dumps(interfaces, indent=2))
# 通过textfsm模板对路由条目进行分析
route = connect.send_command('show ip route', use_textfsm=True)
print(json.dumps(route, indent=2))
except Exception as e:
print(e)
测试结果如下(部分截图):
步骤三: 根据打印出的json字符串,组织分析字典信息,得到需要的接口和路由信息:
from netmiko import ConnectHandler
import json
CSR1 = {
'device_type': 'cisco_ios',
'ip': '192.168.0.66',
'username': 'prin',
'password': 'Cisc0123',
}
CSR2 = {
'device_type': 'cisco_ios',
'ip': '192.168.0.77',
'username': 'prin',
'password': 'Cisc0123',
}
CSR_Group = [CSR1, CSR2]
for device in CSR_Group:
# 避免有连接不上的设备,使用异常处理机制
try:
# 依次连接每一个设备
connect = ConnectHandler(**device)
print('*' * 50, f"{device['ip']}状态为UP的接口", '*' * 50)
# 通过textfsm模板对接口信息进行分析
interfaces = connect.send_command('show ip int brief', use_textfsm=True)
# print(json.dumps(interfaces, indent=2))
# 根据打印出的json格式信息,输出状态是UP的接口。每个interface是一个字典。
for interface in interfaces:
if interface["status"] == 'up':
print(f'{interface["intf"]} is up! IP address: {interface["ipaddr"]}')
# 通过textfsm模板对路由条目进行分析
print('*' * 50, f"{device['ip']}OSPF的路由信息", '*' * 50)
route = connect.send_command('show ip route', use_textfsm=True)
# print(json.dumps(route, indent=2))
# 根据打印出的json格式信息,输出是OSPF的路由信息
for ospf_route in route:
if ospf_route['protocol'] == ('O' or 'IA' or 'N1' or 'N2' or 'E1' or 'E2'):
print(
f"OSPF路由:network {ospf_route['network']}/mask {ospf_route['mask']} nexthop_ip {ospf_route['nexthop_ip']}")
except Exception as e:
print(e)
测试结果:
参考资料来源:
《网络工程师的python之路》:https://www.zhihu.com/people/wang-yin-31-84/posts?page=2
NetDevOps加油站:https://zhuanlan.zhihu.com/p/163534748