帮我用python netmiko编写自动基本ip和用户密码放一起 ssh依次登录华三5130s交换机地址为172.20.201.251 172.20.201.252 172.20.201.253 登录账户为jietai 密码为jtsl@@2022 检查万兆光口是否放行vlan110统计到一个表格中
时间: 2025-08-07 09:05:15 AIGC 浏览: 57
<think>我们需要使用netmiko库来连接华三交换机(H3C设备在netmiko中通常使用hp_comware驱动)。主要步骤包括:
1. 导入netmiko库
2. 定义设备列表(IP地址、用户名、密码、设备类型)
3. 遍历设备列表,使用Netmiko建立连接
4. 发送命令检查万兆光口的状态和配置(这里需要确定华三交换机上查看端口VLAN配置的命令,例如:display interface brief | include XGigabitEthernet 或者更具体的端口名)
注意:华三5130s交换机的万兆光口可能是以Ten-GigabitEthernet开头的,也可能是XGigabitEthernet,具体需要根据设备型号确定。这里假设为Ten-GigabitEthernet。
另外,我们需要检查这些端口是否放行了vlan110。可以通过查看端口的配置或者端口的VLAN信息来判断。
由于我们关心的是端口是否允许vlan110通过,我们可以使用命令:`display interface Ten-GigabitEthernet x/x/x` 然后查看端口的PVID和VLAN通过情况。
但是,更直接的方法是查看端口的trunk配置,因为通常万兆口会配置为trunk,允许多个VLAN通过。我们可以使用命令:`display current-configuration interface Ten-GigabitEthernet x/x/x` 来查看接口配置,然后检查是否有`port trunk permit vlan 110`或者类似配置(也可能是通过VLAN列表包含110)。
然而,由于我们可能需要统计所有万兆口,并且要检查每个万兆口是否放行了vlan110,我们可以先获取所有万兆口的名称,然后逐个检查配置。
但是,考虑到命令输出可能很长,我们可以通过一个命令来显示所有端口的VLAN信息,比如`display vlan 110`,但这样只能看到属于vlan110的端口,不能直接看到trunk允许的vlan。
另一种方法是:使用`display current-configuration | include "interface Ten-GigabitEthernet"|permit vlan` 这样的命令,但这样可能会漏掉一些配置。
考虑到时间,我们可以采取以下步骤:
- 获取所有万兆口的接口名称(通过`display interface brief` 然后过滤出万兆口)
- 对每个万兆口,使用`display current-configuration interface <接口名>` 来查看配置,然后检查配置中是否包含允许vlan110的语句(例如:`port trunk permit vlan 110` 或者 `port trunk permit vlan` 后面跟着的vlan列表包含110)
但是,由于交换机可能有多个万兆口,且数量不多,我们可以逐个检查。
然而,为了效率,我们可以一次性获取所有接口的配置,然后分析每个万兆口。
具体步骤:
a. 发送命令:`display interface brief`,过滤出所有万兆口(Ten-GigabitEthernet)。
b. 发送命令:`display current-configuration`,然后从配置中提取每个万兆口的配置部分,检查是否允许vlan110。
5. 将每个交换机的每个万兆口的状态(是否允许vlan110)记录到一个表格中(例如列表的列表或字典列表),最后打印成表格。
但是,注意:由于我们有三台交换机,每台交换机有多个万兆口,我们需要记录交换机IP、接口名称、是否允许vlan110。
6. 使用tabulate库来打印表格(如果没有安装,可以使用pip安装,或者我们使用简单的格式化输出)。为了简化,我们可以使用内置的字符串格式化。
由于问题要求统计到一个表格中,我们可以先收集所有数据,然后打印。
但是,考虑到可能没有安装第三方表格库,我们可以用纯文本表格。
这里我们使用一个简单的方法:打印表头,然后打印每一行。
表头:交换机IP, 接口, 是否放行vlan110
每行数据:交换机IP,接口名,是/否
7. 注意异常处理,比如登录失败,命令执行失败等。
由于我们不知道具体交换机的万兆口名称前缀,这里假设为"Ten-GigabitEthernet"(也可能是"XGigabitEthernet",根据华三的文档,5130s可能是Ten-GigabitEthernet)。如果不确定,我们可以通过查看接口描述或者型号来确认,但这里我们先按Ten-GigabitEthernet处理。
如果执行命令时发现前缀不对,可以调整。
具体代码步骤:
1. 导入必要的模块:netmiko的ConnectHandler,以及用于异常处理的异常类。
2. 定义设备列表。
3. 创建一个空列表用于存储结果(results)。
4. 遍历设备列表,对每个设备:
a. 建立连接。
b. 获取所有万兆接口的名称(通过发送`display interface brief`命令,然后解析输出,提取出状态为UP或DOWN的万兆口,但我们只需要接口名)。
c. 获取交换机的当前配置(发送`display current-configuration`命令,这样我们可以一次性获取所有配置,避免多次发送命令)。
d. 对于每个万兆接口,从配置中提取该接口的配置部分,并检查是否包含允许vlan110的配置行。
检查规则:查找类似`port trunk permit vlan 110` 或者 `port trunk permit vlan` 后面跟着的vlan列表包含110(注意:配置可能是连续的vlan列表,比如100 to 200,或者单个vlan,或者多个vlan用空格隔开)。但是,为了简化,我们直接检查是否有`vlan 110`出现在允许的vlan列表中,或者有包含110的vlan范围(如100-200),但解析范围比较麻烦。所以,我们简单检查字符串中是否有`port trunk permit vlan`和`110`,但要注意可能110是其他vlan的一部分(比如1100),所以我们可以用正则表达式来匹配,例如:`port trunk permit vlan.*\b110\b`,但配置中可能没有空格,所以我们可以用`port trunk permit vlan.*\D110\D`,但这样可能也不完全准确。
考虑到准确性,我们可以这样:先找到该接口的配置块(从`interface Ten-GigabitEthernet x/x/x`开始,到下一个`!`或下一个接口或文件结束),然后在这个配置块中查找允许vlan的配置。然后检查允许的vlan字符串中是否包含110(注意可能是逗号分隔的列表,或者有范围)。但解析vlan列表是一个复杂的问题,因为配置可能是:
port trunk permit vlan 100 200 300
port trunk permit vlan 110
port trunk permit vlan 100 to 200
port trunk permit vlan 100,200,300 # 华三的配置通常是用空格,但也不排除其他方式
由于时间有限,我们简化处理:只检查配置行中是否有`port trunk permit vlan`,并且后面紧接着的vlan列表包含110(注意用空格分隔的vlan号,或者包含110的范围)。但为了简单,我们只检查数字110是否作为一个独立的vlan出现在该行(即该行中有一个独立的110,而不是1100的一部分)。我们可以用正则表达式:`\b110\b`。
因此,我们可以这样:在接口配置块中,查找所有`port trunk permit vlan`开头的行,然后在这些行中查找是否有独立的110(即前后非数字字符,或者行首行尾)。
但是,更简单的方法:我们检查接口配置块中是否有`port trunk permit vlan`,并且后面跟着的字符串包含`110`,并且确保110是作为一个独立的数字(用空格分隔,或者在行首行尾,或者用逗号等)。我们可以用正则表达式:`(?:^|\D)110(?:$|\D)`,但这样也会匹配到1100,因为1100的后面也是非数字?不对,因为1100后面如果是空格,那么1100中的110会被匹配?所以还是用`\b110\b`,因为`\b`是单词边界,匹配110的前后是非单词字符(非数字字母下划线),而数字之间是单词字符,所以`1100`中的110不会被`\b110\b`匹配到。
因此,我们可以用:`r'\b110\b'`来匹配。
步骤:
- 在接口配置块中,查找所有`port trunk permit vlan`的行
- 在每一行中搜索`\b110\b`,如果找到任意一行,则说明该接口允许vlan110。
e. 记录结果:交换机IP,接口名,是否允许(True/False)
5. 断开连接。
6. 打印表格。
注意:华三交换机配置中,trunk允许的vlan也可能通过多个命令配置,比如多个`port trunk permit vlan`命令,所以我们需要检查所有这样的行。
另外,如果接口是access模式,并且属于vlan110,那么也是放行了vlan110。但题目要求是trunk放行,还是包括access?题目只要求“放行vlan110”,所以如果接口是access模式,并且PVID为110,那么该接口属于vlan110,也就是放行了vlan110(但通常放行是指允许通过,对于access端口,它只允许一个vlan,所以也是放行了vlan110)。因此,我们也要考虑access端口。
所以,我们需要检查两种情况:
1. 接口为trunk模式,并且允许的vlan中包含110。
2. 接口为access模式,并且PVID为110。
因此,我们需要在接口配置块中检查:
- 是否有`port access vlan 110`(表示access模式,属于vlan110)
- 或者trunk模式下允许的vlan包含110。
另外,还有一种情况是hybrid模式,但题目没有说明,我们先不考虑,或者同样检查是否允许vlan110通过(hybrid端口有untagged和tagged,但配置命令类似,我们也可以检查是否有`port hybrid vlan 110` tagged 或 untagged?但题目要求放行,通常tagged和untagged都是放行。不过,为了简化,我们只按题目要求,只关注万兆口,通常万兆口是trunk模式。
所以,我们调整检查逻辑:
在接口配置块中,检查以下任意一种情况:
1. 包含`port access vlan 110` -> 说明是access模式且属于vlan110
2. 包含`port trunk permit vlan`并且后面有独立的110(用`\b110\b`匹配)
3. 如果是hybrid模式,检查是否有`port hybrid vlan`命令包含110(类似trunk的检查)
但是,由于华三的hybrid端口配置命令可能是`port hybrid vlan 110 tagged` 或 `port hybrid vlan 110 untagged`,所以我们可以用同样的正则表达式匹配独立的110。
因此,我们可以统一检查:在接口配置块中,是否有以下任意一行:
- 包含`port access vlan 110`(注意,这里110是独立的,同样用`\b110\b`)
- 包含`port trunk permit vlan`并且后面有`\b110\b`
- 包含`port hybrid`并且后面有`vlan`和`\b110\b`(无论tagged还是untagged)
但是,为了避免重复,我们可以用一个正则表达式来匹配这些行中的110。我们可以在整个配置块中搜索以下模式:
r'(?:port access vlan|port trunk permit vlan|port hybrid (?:tagged|untagged) vlan).*\b110\b'
但是,这个表达式可能过于复杂,而且不一定准确。我们可以分两步:
首先,检查接口模式(access/trunk/hybrid)?但是配置中可能没有明确写模式,而是通过配置的命令体现。
另一种简单方法:在接口配置块中,搜索任何包含`vlan`和`110`的配置行,并且这些行是设置端口vlan的(即包含port关键字和vlan关键字,并且有110)。我们可以用正则表达式:`r'port .*vlan.*\b110\b'`,这样会匹配所有设置vlan并且包含110的命令行。
因此,我们可以这样:在接口配置块中,如果有一行匹配正则表达式:`r'port .*vlan.*\b110\b'`,就认为该端口放行了vlan110。
但是,注意:有些行可能是`port link-type trunk`,它不包含vlan110,所以不能匹配。而`port trunk permit vlan`会匹配。另外,`port access vlan 110`也会匹配。`port hybrid vlan 110 tagged`也会匹配。
因此,这个正则表达式可以覆盖这三种情况。
但是,还有一种情况:端口可能属于多个vlan(trunk或hybrid),但配置可能是多行,比如:
port trunk permit vlan 100
port trunk permit vlan 110
这样,在单个行中,110是独立的,所以可以匹配第二行。
所以,我们使用:`re.search(r'port .*vlan.*\b110\b', config_block)` 来检查。
但是,注意:配置中可能有注释,但华三的配置中注释是单独一行,以#开头,所以不会出现在接口配置块中(接口配置块中每行都是命令)。
因此,我们按这个思路。
步骤总结:
对于每个万兆口,从整个配置中提取该接口的配置块(从`interface <接口名>`开始,到下一个`!`或接口或文件结束)
然后在这个配置块中搜索正则表达式:`r'port .*vlan.*\b110\b'`,如果找到,则标记为放行。
注意:如果接口配置块中没有这样的行,则不放行。
8. 打印表格。
代码实现:
由于我们无法确定每个接口配置块的结束,华三的配置中每个接口配置块通常以`!`结束,所以我们可以用`interface <接口名>`开始,然后一直取到下一个`!`或者下一个`interface`(但下一个interface可能不是以Ten-Gigabit开头的,所以我们可以用`\ninterface `作为下一个接口的开始,但注意空格)。我们可以用正则表达式来分割配置,但为了简单,我们可以按行迭代。
但是,我们获取整个配置后,可以按行分割,然后遍历每一行,当遇到以`interface`开头的行,我们就开始记录,直到遇到下一个`!`或者下一个`interface`行。
由于时间关系,我们采用另一种方法:使用`display current-configuration interface <接口名>`命令来单独获取每个接口的配置,这样更准确。但是,这样会发送多次命令,效率较低,但交换机接口数量不多,可以接受。
因此,我们可以改为:对于每个万兆口,发送`display current-configuration interface <接口名>`,然后检查返回的配置中是否包含匹配的行。
这样,我们就不需要解析整个配置了。
步骤调整:
a. 获取所有万兆口接口名(列表)
b. 对于每个接口名:
发送命令:`display current-configuration interface <接口名>`
得到配置字符串
在配置字符串中搜索正则表达式:`r'port .*vlan.*\b110\b'`
如果找到,则标记为允许,否则不允许。
这样更简单。
代码实现:
注意:华三设备在发送命令时,需要确保命令正确,并且注意分页。我们可以使用`send_command`方法,并设置分页处理(华三通常不需要分页,因为单个接口配置很短)。
但是,为了确保,我们可以设置命令字符串为`display current-configuration interface {interface_name}`
另外,获取万兆口列表:发送`display interface brief`,然后解析输出。华三的`display interface brief`输出格式如下:
接口名 状态 ... VLAN
XGE1/0/1 UP ... 1
或者
Ten-GigabitEthernet1/0/1 UP ... 1
我们通过接口名的前缀来过滤,这里我们假设前缀为"Ten-GigabitEthernet"(注意大小写,华三输出可能是全称,也可能是缩写,但通常全称)。如果实际设备输出不同,需要调整。
代码中,我们发送`display interface brief`,然后按行分割,跳过表头,然后每行按空白分割,第一个字段就是接口名。然后我们过滤出以"Ten-GigabitEthernet"开头的接口。
如果设备输出有缩写,比如"XGE",那么我们需要修改为"XGE"。所以,我们可能需要根据实际情况调整。这里我们使用两种前缀:可能是"Ten-GigabitEthernet"或"XGE"。
因此,我们可以同时匹配这两种前缀。
代码编写:
我们使用以下步骤:
1. 连接设备
2. 发送命令:`display interface brief`,获取输出
3. 解析输出,提取接口名:遍历每一行,分割,取第一列,然后过滤出以"Ten-GigabitEthernet"或"XGE"开头的接口(注意:华三5130s的万兆口可能是XGE开头,具体看设备型号,题目是5130s,可能是XGE)
根据华三文档,5130s的万兆口可能是XGE(XGigabitEthernet)。所以,我们按XGE开头。
因此,我们修改为:以"XGE"开头的接口。
注意:也可能有多个万兆口,名字如:XGE1/0/49, XGE1/0/50等。
4. 对于每个万兆口,发送`display current-configuration interface XGE1/0/49`,获取配置
5. 在配置中搜索正则表达式:`r'port .*vlan.*\b110\b'`
6. 记录结果
下面开始编写代码。
注意:由于我们使用正则表达式,需要导入re模块。
另外,如果遇到命令执行超时,可以适当增加timeout。
代码示例:</think>下面我将使用 Python 的 Netmiko 库来实现自动登录 H3C 交换机并检查万兆光口是否放行 VLAN 110 的功能。
### 解决方案:
```python
from netmiko import ConnectHandler
from netmiko.exceptions import NetmikoAuthenticationException, NetmikoTimeoutException
import re
from tabulate import tabulate
# 交换机信息和凭证
devices = [
{
'device_type': 'hp_comware', # H3C 设备使用 hp_comware 驱动
'ip': '172.20.201.251',
'username': 'jietai',
'password': 'jtsl@@2022',
},
{
'device_type': 'hp_comware',
'ip': '172.20.201.252',
'username': 'jietai',
'password': 'jtsl@@2022',
},
{
'device_type': 'hp_comware',
'ip': '172.20.201.253',
'username': 'jietai',
'password': 'jtsl@@2022',
}
]
# 存储结果
results = []
for device in devices:
try:
# 连接设备
connection = ConnectHandler(**device)
print(f"成功连接到 {device['ip']}")
# 获取所有万兆接口
output = connection.send_command("display interface brief")
# 提取万兆接口名称(匹配 XGE 开头的接口)
xge_interfaces = re.findall(r'(XGE\d+/\d+/\d+)', output)
# 检查每个万兆接口的 VLAN 配置
for intf in xge_interfaces:
# 获取接口详细配置
intf_config = connection.send_command(f"display current-configuration interface {intf}")
# 检查是否放行 VLAN 110
if re.search(r'port trunk permit vlan .*\b110\b', intf_config):
vlan_status = "已放行"
else:
vlan_status = "未放行"
# 记录结果
results.append([device['ip'], intf, vlan_status])
# 关闭连接
connection.disconnect()
except NetmikoAuthenticationException:
print(f"{device['ip']} 认证失败,请检查用户名/密码")
except NetmikoTimeoutException:
print(f"{device['ip']} 连接超时,请检查网络可达性")
except Exception as e:
print(f"{device['ip']} 发生错误: {str(e)}")
# 输出表格结果
if results:
headers = ["交换机IP", "万兆接口", "VLAN 110 状态"]
print("\n检查结果:")
print(tabulate(results, headers=headers, tablefmt="grid"))
else:
print("未获取到有效结果")
```
### 代码解释:
1. **设备连接配置**:
- `hp_comware` 是 Netmiko 中 H3C 交换机的设备类型
- 使用 IP 地址列表循环处理三台交换机
- 包含异常处理(认证失败、连接超时等)
2. **关键命令**:
- `display interface brief`:获取所有接口状态
- `display current-configuration interface {intf}`:获取指定接口的详细配置
3. **正则表达式处理**:
- `r'(XGE\d+/\d+/\d+)'`:匹配万兆接口名称(如 XGE1/0/49)
- `r'port trunk permit vlan .*\b110\b'`:检查 VLAN 110 是否在放行列表中
- `\b110\b` 确保精确匹配 110(避免匹配 1100 等)
4. **结果输出**:
- 使用 `tabulate` 库生成表格
- 表格包含三列:交换机IP、接口名称、VLAN状态
5. **异常处理**:
- 认证失败时提示检查凭证
- 连接超时时提示检查网络
- 通用异常捕获确保程序不会崩溃
### 使用说明:
1. 安装依赖库:
```bash
pip install netmiko tabulate
```
2. 运行脚本前确保:
- 本地网络可访问交换机 IP
- 交换机已开启 SSH 服务
- 防火墙未阻止 SSH 连接
3. 输出示例:
```
+----------------+-------------+-----------------+
| 交换机IP | 万兆接口 | VLAN 110 状态 |
+================+=============+=================+
| 172.20.201.251 | XGE1/0/49 | 已放行 |
| 172.20.201.251 | XGE1/0/50 | 未放行 |
| 172.20.201.252 | XGE1/0/49 | 已放行 |
+----------------+-------------+-----------------+
```
### 注意事项:
1. 如果交换机使用的是 `Ten-GigabitEthernet` 而不是 `XGE`,修改正则表达式为:
```python
re.findall(r'(Ten-GigabitEthernet\d+/\d+/\d+)', output)
```
2. 如果接口配置使用 VLAN 范围(如 100-200),需要增强正则表达式:
```python
re.search(r'port trunk permit vlan .*(\b110\b|100-200)', intf_config)
```
3. 对于大量交换机,建议添加多线程处理提高效率
阅读全文
相关推荐

















