思科PY(Python Package Index,通常指PyPI)中支持Python的用法和配置方法,核心是通过`pip`工具安装和管理专为思科网络设备自动化运维设计的Python包,其中Netmiko和Paramiko是两个最关键的库。下面通过具体的代码示例和配置步骤进行详细说明。
### 1. Netmiko库的安装与基本配置
Netmiko是一个多厂商网络设备SSH连接库,支持思科IOS、NX-OS等多种操作系统。安装与基本配置步骤如下:
```python
# 安装Netmiko库
# pip install netmiko
from netmiko import ConnectHandler
# 定义思科设备连接参数
cisco_device = {
'device_type': 'cisco_ios', # 设备类型,思科IOS
'host': '192.168.1.1', # 设备IP地址
'username': 'admin', # SSH用户名
'password': 'cisco123', # SSH密码
'secret': 'enable123', # 特权模式密码(可选)
'port': 22, # SSH端口,默认22
'verbose': False, # 是否显示详细日志
}
# 建立SSH连接
connection = ConnectHandler(**cisco_device)
# 进入特权模式(如果需要执行show running-config等特权命令)
if cisco_device.get('secret'):
connection.enable()
# 发送命令并获取输出
output = connection.send_command('show version')
print(output)
# 发送配置命令(可接受列表形式的多条命令)
config_commands = ['interface GigabitEthernet0/1', 'description To-Core-Switch', 'no shutdown']
output = connection.send_config_set(config_commands)
print(output)
# 断开连接
connection.disconnect()
```
*代码说明:首先通过`pip install netmiko`安装库,然后使用`ConnectHandler`类建立与思科设备的SSH连接。`device_type`参数必须指定为`cisco_ios`(对于IOS设备)或`cisco_nxos`(对于NX-OS设备)等。`send_command`用于执行查询命令,`send_config_set`用于执行配置命令[ref_1][ref_2][ref_4]。*
### 2. Paramiko库的安装与基本用法
Paramiko是一个纯Python实现的SSHv2协议库,提供了更底层的SSH连接控制,适用于需要自定义交互逻辑的场景。
```python
# 安装Paramiko库
# pip install paramiko
import paramiko
import time
# 创建SSH客户端实例
ssh_client = paramiko.SSHClient()
# 自动添加主机密钥(生产环境应使用更安全的方式)
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接思科设备
ssh_client.connect(
hostname='192.168.1.1',
port=22,
username='admin',
password='cisco123',
look_for_keys=False, # 不查找本地密钥
allow_agent=False, # 不使用SSH代理
)
# 获取交互式shell
remote_conn = ssh_client.invoke_shell()
# 等待设备响应
time.sleep(1)
# 读取初始输出
output = remote_conn.recv(65535).decode('utf-8')
print(output)
# 发送命令(注意需要添加回车符\n)
remote_conn.send('enable\n')
time.sleep(0.5)
remote_conn.send('enable123\n') # 特权模式密码
time.sleep(0.5)
remote_conn.send('show running-config\n')
time.sleep(2) # 等待命令执行
# 获取命令输出
output = remote_conn.recv(65535).decode('utf-8')
print(output)
# 关闭连接
remote_conn.close()
ssh_client.close()
```
*代码说明:Paramiko提供了更灵活的SSH连接控制,但需要手动处理命令交互和等待时间。`invoke_shell()`方法获取交互式shell,`send()`方法发送命令,`recv()`方法接收输出[ref_3]。*
### 3. 批量配置与备份的完整示例
结合Netmiko和文件操作,可以实现对多台思科设备的批量配置和配置备份。
```python
from netmiko import ConnectHandler
from datetime import datetime
import yaml # 需要安装PyYAML: pip install pyyaml
# 从YAML文件读取设备列表(推荐方式)
def load_devices_from_yaml(file_path):
with open(file_path, 'r') as f:
devices = yaml.safe_load(f)
return devices
# 设备列表YAML示例内容(devices.yaml):
# ---
# - device_type: cisco_ios
# host: 192.168.1.1
# username: admin
# password: cisco123
# secret: enable123
# - device_type: cisco_ios
# host: 192.168.1.2
# username: admin
# password: cisco123
# secret: enable123
# 批量备份配置函数
def backup_configs(devices):
backup_dir = 'backups/'
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
for device in devices:
try:
# 连接设备
connection = ConnectHandler(**device)
if device.get('secret'):
connection.enable()
# 获取主机名用于生成文件名
hostname_output = connection.send_command('show run | include hostname')
hostname = hostname_output.split()[-1] if 'hostname' in hostname_output else device['host']
# 获取运行配置
running_config = connection.send_command('show running-config')
# 保存到文件
filename = f"{backup_dir}{hostname}_{timestamp}.cfg"
with open(filename, 'w') as f:
f.write(running_config)
print(f"成功备份 {device['host']} 配置到 {filename}")
connection.disconnect()
except Exception as e:
print(f"备份 {device['host']} 失败: {str(e)}")
# 批量配置函数
def configure_devices(devices, config_commands):
for device in devices:
try:
connection = ConnectHandler(**device)
if device.get('secret'):
connection.enable()
# 发送配置命令
output = connection.send_config_set(config_commands)
print(f"设备 {device['host']} 配置输出:\n{output}")
# 保存配置(思科设备)
connection.send_command('write memory')
connection.disconnect()
print(f"设备 {device['host']} 配置完成并已保存")
except Exception as e:
print(f"配置 {device['host']} 失败: {str(e)}")
# 主程序
if __name__ == "__main__":
# 加载设备列表
devices = load_devices_from_yaml('devices.yaml')
# 示例1:批量备份配置
backup_configs(devices)
# 示例2:批量配置VLAN
vlan_commands = [
'vlan 100',
'name IT_Department',
'vlan 200',
'name HR_Department',
]
configure_devices(devices, vlan_commands)
```
*代码说明:此示例展示了完整的批量操作流程。使用YAML文件管理设备信息提高了可维护性。`backup_configs`函数备份每台设备的配置并以时间戳命名文件,`configure_devices`函数批量执行配置命令并保存配置到启动文件[ref_5][ref_6]。*
### 4. 高级功能与最佳实践
#### 4.1 使用TextFSM/Genie解析命令输出
Netmiko可以配合TextFSM或Genie解析半结构化的命令输出为结构化数据(如JSON)。
```python
from netmiko import ConnectHandler
import json
cisco_device = {
'device_type': 'cisco_ios',
'host': '192.168.1.1',
'username': 'admin',
'password': 'cisco123',
}
connection = ConnectHandler(**cisco_device)
# 使用TextFSM模板解析'show interface status'输出
output = connection.send_command('show interface status', use_textfsm=True)
# output现在是Python列表,每个元素是字典
print(json.dumps(output[:2], indent=2)) # 打印前两个接口的信息
# 使用Genie解析(需要安装genie库)
try:
from genie.conf.base import Device
import genie.parsers
# 创建Genie设备对象
genie_device = Device(name='router1', os='ios')
genie_device.custom.setdefault('abstraction', {})['order'] = ['os']
# 获取解析后的输出
parsed_output = genie_device.parse('show interface brief')
print(json.dumps(parsed_output, indent=2))
except ImportError:
print("Genie库未安装,请使用: pip install genie")
connection.disconnect()
```
*代码说明:`use_textfsm=True`参数让Netmiko使用TextFSM模板解析命令输出,返回结构化数据。Genie是思科官方开发的解析库,提供更强大的解析能力[ref_4]。*
#### 4.2 错误处理与日志记录
完善的错误处理和日志记录对生产环境至关重要。
```python
import logging
from netmiko import ConnectHandler, NetmikoTimeoutException, NetmikoAuthenticationException
# 配置日志
logging.basicConfig(
filename='netmiko_operations.log',
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def safe_connect_and_execute(device, commands):
"""安全的连接和执行函数"""
try:
connection = ConnectHandler(**device)
logging.info(f"成功连接到 {device['host']}")
if device.get('secret'):
try:
connection.enable()
except Exception as e:
logging.warning(f"设备 {device['host']} 进入特权模式失败: {str(e)}")
# 执行命令
results = []
for cmd in commands:
try:
output = connection.send_command(cmd, delay_factor=2) # 增加延迟因子
results.append({'command': cmd, 'output': output})
logging.info(f"设备 {device['host']} 执行命令 '{cmd}' 成功")
except Exception as e:
logging.error(f"设备 {device['host']} 执行命令 '{cmd}' 失败: {str(e)}")
results.append({'command': cmd, 'error': str(e)})
connection.disconnect()
return {'success': True, 'results': results}
except NetmikoTimeoutException:
error_msg = f"连接 {device['host']} 超时"
logging.error(error_msg)
return {'success': False, 'error': error_msg}
except NetmikoAuthenticationException:
error_msg = f"连接 {device['host']} 认证失败"
logging.error(error_msg)
return {'success': False, 'error': error_msg}
except Exception as e:
error_msg = f"连接 {device['host']} 发生未知错误: {str(e)}"
logging.error(error_msg)
return {'success': False, 'error': error_msg}
# 使用示例
device = {
'device_type': 'cisco_ios',
'host': '192.168.1.1',
'username': 'admin',
'password': 'cisco123',
'timeout': 30, # 连接超时时间(秒)
'session_timeout': 60, # 会话超时时间
}
commands = ['show version', 'show ip interface brief', 'show running-config']
result = safe_connect_and_execute(device, commands)
if result['success']:
for item in result['results']:
if 'output' in item:
print(f"命令: {item['command']}\n输出长度: {len(item['output'])} 字符")
else:
print(f"操作失败: {result['error']}")
```
*代码说明:此代码展示了完整的错误处理机制,包括连接超时、认证失败等异常处理,并配置了详细的日志记录。`delay_factor`参数可以调整命令执行间的延迟,对于响应慢的设备特别有用[ref_3][ref_4]。*
#### 4.3 与定时任务集成
结合APScheduler或操作系统的crontab,可以实现定时自动备份。
```python
# 使用APScheduler实现定时备份(需要安装:pip install apscheduler)
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime
def scheduled_backup():
"""定时备份任务"""
print(f"{datetime.now()} 开始执行定时备份")
devices = load_devices_from_yaml('devices.yaml')
backup_configs(devices)
print(f"{datetime.now()} 备份任务完成")
# 创建调度器
scheduler = BlockingScheduler()
# 每天凌晨2点执行备份
scheduler.add_job(scheduled_backup, 'cron', hour=2, minute=0)
# 每30分钟执行一次(测试用)
# scheduler.add_job(scheduled_backup, 'interval', minutes=30)
print("定时备份服务已启动,按Ctrl+C退出")
try:
scheduler.start()
except (KeyboardInterrupt, SystemExit):
print("定时备份服务已停止")
```
*代码说明:APScheduler提供了灵活的定时任务调度功能,可以替代操作系统的crontab,特别是在Windows环境下或需要更复杂调度逻辑时[ref_5]。*
### 5. 环境配置与依赖管理
为了确保代码的可移植性和一致性,建议使用虚拟环境和依赖文件。
```bash
# 创建虚拟环境(Linux/Mac)
python3 -m venv cisco_automation_env
source cisco_automation_env/bin/activate
# 创建虚拟环境(Windows)
python -m venv cisco_automation_env
cisco_automation_env\Scripts\activate
# 安装核心依赖
pip install netmiko paramiko pyyaml
# 可选:安装解析库
pip install textfsm genie
# 生成requirements.txt文件
pip freeze > requirements.txt
# requirements.txt示例内容:
# netmiko==4.1.0
# paramiko==3.3.1
# pyyaml==6.0
# apscheduler==3.10.4
# textfsm==1.1.3
```
*代码说明:使用虚拟环境可以隔离项目依赖,避免版本冲突。`requirements.txt`文件记录了所有依赖包及其版本,方便在其他环境重现[ref_1][ref_2]。*
### 6. 不同思科设备类型的配置差异
不同系列的思科设备在Netmiko中的`device_type`参数有所不同:
| 设备系列 | 操作系统 | device_type值 | 备注 |
|---------|---------|--------------|------|
| Cisco IOS | IOS | `cisco_ios` | 大多数传统交换机路由器 |
| Cisco NX-OS | NX-OS | `cisco_nxos` | Nexus系列数据中心交换机 |
| Cisco IOS-XE | IOS-XE | `cisco_xe` | ASR/ISR/CSR系列设备 |
| Cisco IOS-XR | IOS-XR | `cisco_xr` | CRS/ASR9k系列核心路由器 |
| Cisco ASA | ASA OS | `cisco_asa` | 自适应安全设备 |
```python
# 不同设备类型的连接示例
devices = [
{
'device_type': 'cisco_ios',
'host': '192.168.1.10',
'username': 'admin',
'password': 'cisco123',
'secret': 'enable123',
},
{
'device_type': 'cisco_nxos',
'host': '192.168.1.20',
'username': 'admin',
'password': 'cisco123',
# NX-OS通常不需要secret参数
},
{
'device_type': 'cisco_asa',
'host': '192.168.1.30',
'username': 'admin',
'password': 'cisco123',
'secret': '', # ASA通常不需要enable密码
'port': 22,
}
]
for device in devices:
try:
connection = ConnectHandler(**device)
# 对于ASA,show命令通常不需要enable模式
if device['device_type'] != 'cisco_asa' and device.get('secret'):
connection.enable()
output = connection.send_command('show version')
print(f"{device['host']} 版本信息获取成功")
connection.disconnect()
except Exception as e:
print(f"{device['host']} 连接失败: {str(e)}")
```
*代码说明:不同系列的思科设备在Netmiko中对应不同的`device_type`值,连接参数和行为也略有差异。例如,NX-OS设备通常不需要`secret`参数,而ASA设备的命令语法与其他IOS设备不同[ref_2][ref_4]。*
通过上述详细的代码示例和配置方法,可以全面掌握在Python环境中对思科设备进行自动化运维的技术。关键点包括:正确安装Netmiko/Paramiko库、准确配置设备连接参数、实现批量操作和错误处理、使用结构化数据解析以及集成定时任务。这些方法显著提高了网络运维的效率和可靠性[ref_1][ref_2][ref_5]。