netmiko運維網絡設備
netmiko自動化配置網絡設備
一、環境搭建
1.1 安裝Python
Linux下自帶python環境,但是Linux自帶的python一般是比較老的版本,我們可以通過命令來查看Linux中python的版本
[root@localhost ~]# python --version
Python 2.7.5
建議大家在保留python2的基礎上安裝一個python3,因為python2和python3還是有一些區別的,同時安裝python2和python3的環境,以便不時之需或者對比學習。
鏈接:https://www.python.org/downloads/source/

1.2 安裝python3
3.1首先解壓源碼包
tar -zxvf Python-3.10.13.tgz
3.2安裝依賴包
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel
3.3進入解壓路徑執行編譯三部曲
cd Python-3.10.13
./configure --prefix=安裝路徑
make
make install
1.3 安裝依賴模塊netmiko
[root@backup backup]# pip3 install --trusted-host mirrors.huaweicloud.com -i https://mirrors.huaweicloud.com/repository/pypi/simple netmiko
[root@backup backup]# pip freeze | grep netmiko #查看是否安裝成功,如果是windows就是pip freeze | findstr netmiko
二、VRP配置自動存檔
2.1 環境準備
配置腳本以及備份存檔路徑
[root@backup ~]# mkdir -p /backup/{script,data}
2.2 備份設備列表
準備號需要備份的設備,將設備ssh登錄的ip、用戶名、密碼羅列準備再設備列表當中。
[root@backup ~]# cd /backup/script/
[root@backup script]# cat devices.txt
IP地址 用戶名 密碼
192.168.10.1 user1 passwd1
192.168.20.1 user2 passwd2
192.168.30.1 user3 passwd3
192.168.40.1 user4 passwd4
2.3 編寫備份腳本
編寫備份腳本,腳本會自動登錄設備執行display current-configuration查看設備配置,添加到備份溫江當中。
[root@backup script]# cat HuaWeiVRP_backup.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import argparse
import time
from datetime import datetime
from netmiko import ConnectHandler
def load_devices_from_txt(file_path):
"""
從文本文件中讀取設備信息(字段以空格或 Tab 分隔):
IP地址 用戶名 密碼
空行及以 "#" 開頭的行會被自動跳過。
"""
devices = []
try:
with open(file_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
parts = line.split()
if len(parts) != 3:
print(f"格式錯誤,跳過該行:{line}")
continue
device = {
"device_type": "huawei", # 默認設備類型為華為
"ip": parts[0].strip(),
"username": parts[1].strip(),
"password": parts[2].strip()
}
devices.append(device)
except Exception as e:
print(f"加載設備列表文件失敗:{e}")
return devices
def backup_configuration(dev, backup_path):
"""
針對單臺華為設備進行配置備份:
1. 連接設備;
2. 執行 "display current-configuration" 命令獲取配置;
3. 將配置保存到備份目錄中,生成的文件名格式為:[IP]_backup_[時間戳].txt
"""
try:
print(f"正在連接到設備 {dev['ip']} ...")
net_connect = ConnectHandler(**dev, conn_timeout=20)
except Exception as e:
print(f"連接 {dev['ip']} 失敗: {e}")
return
config_command = "display current-configuration"
try:
print(f"[{dev['ip']}] 正在執行命令:{config_command}")
config_output = net_connect.send_command(config_command)
except Exception as e:
print(f"[{dev['ip']}] 獲取配置失敗: {e}")
net_connect.disconnect()
return
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = os.path.join(backup_path, f"{dev['ip']}_backup_{timestamp}.txt")
try:
with open(filename, "w", encoding="utf-8") as f:
f.write(config_output)
print(f"[{dev['ip']}] 配置備份已保存到:{filename}")
except Exception as e:
print(f"[{dev['ip']}] 保存備份文件失敗: {e}")
net_connect.disconnect()
print(f"[{dev['ip']}] 設備連接已關閉。\n")
def cleanup_old_backups(backup_path, retention_days=7):
"""
清理備份目錄內超過 retention_days 天的備份文件
"""
now = time.time()
retention_seconds = retention_days * 24 * 3600
try:
for fname in os.listdir(backup_path):
file_path = os.path.join(backup_path, fname)
if os.path.isfile(file_path):
file_mtime = os.path.getmtime(file_path)
if (now - file_mtime) > retention_seconds:
os.remove(file_path)
print(f"刪除超過 {retention_days} 天的備份文件:{file_path}")
except Exception as e:
print(f"清理備份文件時出錯:{e}")
def main():
parser = argparse.ArgumentParser(
description="備份華為設備配置(設備文件格式:IP 用戶名 密碼),每天執行一次,并保留最近7天的數據"
)
parser.add_argument("--backup-path", default="backup", help="備份文件存放目錄(默認為 backup)")
parser.add_argument("--devices-file", default="devices.txt", help="設備信息文本文件路徑(默認為 devices.txt)")
parser.add_argument("--retention-days", type=int, default=7, help="保留備份的天數(默認為 7 天)")
args = parser.parse_args()
# 確保備份目錄存在
if not os.path.exists(args.backup_path):
os.makedirs(args.backup_path)
print(f"創建備份目錄:{args.backup_path}")
devices = load_devices_from_txt(args.devices_file)
if not devices:
print("未加載到任何設備信息,請檢查設備文件格式。")
return
for dev in devices:
backup_configuration(dev, args.backup_path)
cleanup_old_backups(args.backup_path, args.retention_days)
if __name__ == "__main__":
main()
執行測試
注意運行之前修改devices.txt當中的設備登錄信息。
[root@backup script]# python3 /backup/script/HuaWeiVRP_backup.py --backup-path /backup/data/ --devices-file /backup/script/devices.txt

2.4 結合crontab實現每天存檔
加入定時任務每天2點執行:
[root@backup data]# chmod +x /backup/script/HuaWeiVRP_backup.py
[root@backup data]# whereis python3
python3: /usr/local/bin/python3.9 /usr/local/bin/python3.9-config /usr/local/bin/python3 /usr/local/lib/python3.9
[root@backup script]# crontab -l
0 2 * * * /usr/local/bin/python3 /backup/script/HuaWeiVRP_backup.py --backup-path /backup/data/ --retention-days 30 --devices-file /backup/script/devices.txt >> /backup/script/backup.log 2>&1
注:--retention-days 30 是存檔30天的意思。
ok!!!
這里把備份cisio的腳本也給出,同樣的使用方法。
[root@kvm script]# cat cisio_backup.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import argparse
import time
from datetime import datetime
from netmiko import ConnectHandler
def load_devices(file_path):
"""
從文本文件中加載設備信息,每一行的格式為:
IP地址 用戶名 密碼
空行或以 "#" 開頭的行會被跳過。
"""
devices = []
try:
with open(file_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
parts = line.split()
if len(parts) != 3:
print(f"格式錯誤,跳過該行:{line}")
continue
device = {
"device_type": "cisco_ios",
"ip": parts[0].strip(),
"username": parts[1].strip(),
"password": parts[2].strip()
}
devices.append(device)
except Exception as e:
print(f"加載設備文件失敗:{e}")
return devices
def backup_device(dev, backup_path):
"""
針對單臺 Cisco 設備進行配置備份:
1. 連接設備;
2. 執行 "show running-config" 命令獲取配置;
3. 將配置保存到備份目錄,文件名格式為:[IP]_backup_[時間戳].txt
"""
try:
print(f"正在連接到設備 {dev['ip']} ...")
net_connect = ConnectHandler(**dev, conn_timeout=20)
except Exception as e:
print(f"連接 {dev['ip']} 失敗: {e}")
return
config_command = "show running-config"
try:
print(f"[{dev['ip']}] 正在執行命令:{config_command}")
config_output = net_connect.send_command(config_command)
except Exception as e:
print(f"[{dev['ip']}] 獲取配置失敗: {e}")
net_connect.disconnect()
return
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = os.path.join(backup_path, f"{dev['ip']}_backup_{timestamp}.txt")
try:
with open(filename, "w", encoding="utf-8") as f:
f.write(config_output)
print(f"[{dev['ip']}] 配置備份已保存到:{filename}")
except Exception as e:
print(f"[{dev['ip']}] 保存備份文件失敗: {e}")
net_connect.disconnect()
print(f"[{dev['ip']}] 設備連接已關閉。\n")
def cleanup_backups(backup_path, retention_days):
"""
清理備份目錄中超過指定保留天數的備份文件
"""
now = time.time()
retention_seconds = retention_days * 24 * 3600
try:
for fname in os.listdir(backup_path):
file_path = os.path.join(backup_path, fname)
if os.path.isfile(file_path):
file_mtime = os.path.getmtime(file_path)
if (now - file_mtime) > retention_seconds:
os.remove(file_path)
print(f"刪除超過 {retention_days} 天的備份文件:{file_path}")
except Exception as e:
print(f"清理備份文件時出錯:{e}")
def main():
parser = argparse.ArgumentParser(
description="備份 Cisco 設備配置,每天執行一次,并保留指定天數的備份文件"
)
parser.add_argument("--backup-path", default="backup", help="備份文件存放目錄(默認為 backup)")
parser.add_argument("--devices-file", default="devices.txt", help="設備信息文件路徑(默認為 devices.txt)")
parser.add_argument("--retention-days", type=int, default=7, help="保留備份的天數(默認為 7 天)")
args = parser.parse_args()
if not os.path.exists(args.backup_path):
os.makedirs(args.backup_path)
print(f"創建備份目錄:{args.backup-path}")
devices = load_devices(args.devices_file)
if not devices:
print("未加載到任何設備信息,請檢查設備文件格式。")
return
for dev in devices:
backup_device(dev, args.backup_path)
cleanup_backups(args.backup_path, args.retention_days)
if __name__ == "__main__":
main()

浙公網安備 33010602011771號