为确保网络设备发生故障或者配置错误需要回滚,能够快速恢复之前的工作状态,需定时对网络设备进行配置备份。
可以通过使用python脚本及定时任务,执行自动备份工作。
Python代码如下,备份华为交换机、华为防火墙,在CentOS 7.9, python 3.8.7 测试通过。
import paramiko
import os
from datetime import datetime
import time
import chardet # 导入chardet库用于检测编码
backup_dir = "/data/configBackup"
# 多台设备的连接信息
devices = [
{'hostname': 'IP地址1', 'port': 22, 'username': '用户名1', 'password': '密码1'},
{'hostname': 'IP地址2', 'port': 22, 'username': '用户名2', 'password': '密码2'},
# 添加更多设备信息
]
# 创建SSH对象
def create_ssh_client(hostname, port, username, password):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=hostname, port=port, username=username, password=password)
return client
def get_switch_configuration(client, hostname):
remote_conn = client.invoke_shell()
# 关闭分页功能,确保输出完整
remote_conn.send("screen-length 0 temporary\n")
time.sleep(1)
remote_conn.send("\n")
time.sleep(1)
remote_conn.send("display current-configuration\n")
time.sleep(20) # 确保设备有足够时间返回数据
output = b"" # 使用字节串来接收数据
# end_marker = ""
while remote_conn.recv_ready():
output += remote_conn.recv(65535) # 以字节方式接收数据
if output:
# 使用chardet检测编码
detected = chardet.detect(output)
encoding = detected['encoding']
#encoding = "GB2312"
confidence = detected['confidence']
print(f"Detected encoding for {hostname}: {encoding} with confidence {confidence}")
try:
decoded_output = output.decode(encoding,errors="replace") # 使用检测到的编码进行解码
print("Configuration output received.")
return decoded_output
except (UnicodeDecodeError, TypeError) as e:
print(f"Failed to decode using detected encoding {encoding} for {hostname}: {e}")
return ""
else:
print("No configuration output received.")
return ""
def save_configuration(config, backup_dir, hostname):
device_backup_dir = os.path.join(backup_dir, hostname)
if not os.path.exists(device_backup_dir):
os.makedirs(device_backup_dir)
filename = os.path.join(device_backup_dir, f'config_backup_{datetime.now().strftime("%Y%m%d_%H%M%S")}.txt')
with open(filename, 'w', encoding='utf-8') as file: # 确保保存时使用UTF-8编码
file.write(config)
print(f'Configuration saved to {filename}')
def backup_device(device):
try:
client = create_ssh_client(device['hostname'], device['port'], device['username'], device['password'])
config = get_switch_configuration(client, device['hostname'])
if config:
save_configuration(config, backup_dir, device['hostname'])
except paramiko.AuthenticationException:
print(f'Authentication failed for {device["hostname"]}, please verify your credentials.')
except paramiko.SSHException as sshException:
print(f'Unable to establish SSH connection to {device["hostname"]}: {sshException}')
except Exception as e:
print(f'An error occurred with {device["hostname"]}: {e}')
finally:
client.close()
def main():
for device in devices:
backup_device(device)
if __name__ == '__main__':
main()
部分代码解释:
detected = chardet.detect(output)
encoding = detected['encoding']
confidence = detected['confidence']
chardet.detect(output) 是 chardet 库的一个方法,用于检测给定字节数据的可能编码。这个方法返回一个字典对象,其中包含了以下信息:
encoding: 检测到的最可能的编码类型,例如 ‘utf-8’、’gbk’、’iso-8859-1’ 等。
confidence: 检测结果的置信度,表示 chardet 对这个编码检测的准确性的信心,值在 0 到 1 之间,1 表示最高的置信度。
language: 与编码相关的自然语言信息(有时可能为空或不适用)。
假设 output 是一些字节数据,执行 chardet.detect(output) 可能会返回如下结果:
detected = {
'encoding': 'utf-8',
'confidence': 0.99,
'language': ''
}
那么,encoding 将会是 ‘utf-8’,而 confidence 将会是 0.99。
encoding = detected['encoding'] # 'utf-8'
confidence = detected['confidence'] # 0.99
使用 encoding: 你可以使用这个编码值来解码字节数据。例如:
decoded_output = output.decode(encoding)
检查 confidence: 如果置信度很高(接近 1),你可以更有信心地使用这个编码来解码数据。如果置信度较低,可能需要考虑其他编码或检查数据的完整性。
配置定时任务,每天凌晨1点执行
(py387) [python@localhost bkconfig]$crontab -e
0 1 * * * /usr/bin/python3 /path/to/backup_huawei_switch.py