接近完善的代码,待生产环境测试。

This commit is contained in:
panjunlan
2026-02-21 14:26:14 +08:00
parent 9024e9c8e4
commit 17e9e0c3bc
11 changed files with 357 additions and 293 deletions

130
core/data_exporter.py Normal file
View File

@@ -0,0 +1,130 @@
import yaml
import pandas as pd
from datetime import datetime, timedelta
from openpyxl.styles import Border, Side, Font, PatternFill
from utils.logger import logger
from config.settings import EXCEL_OUTPUT_PATH, YAML_OUTPUT_PATH, SNAPSHOT_RETENTION_DAYS
from core.get_vm_snapshots import get_all_vms
# 输出数据到 Excel 文件
def create_excel_report(vms):
vm_data, snapshot_data, old_snapshots = [], [], []
for vm in vms:
vm_data.append({
'NodeHost': vm['NodeHost'],
'VMName': vm['name'],
'MOID': vm['moId'],
'PowerState': vm['powerState'],
'System': vm['system'],
'IPAddress': vm['ipAddress'],
'HostName': vm['hostName'],
'CurrentSnapshotID': vm.get('currentSnapshotId'),
'DiskSpace/GB': vm['diskSpaceGB'],
'createDate': vm['createDate'], # 虚拟机的创建时间
'bootTime': vm['bootTime'], # 虚拟机上次启动的时间
'Host': vm['Host'],
'VMPath': vm['vmPath']
})
if vm['snapshots']:
for snapshot in vm['snapshots']:
collect_snapshot_data(snapshot, vm, snapshot_data, old_snapshots)
vm_df = pd.DataFrame(vm_data)
snapshot_df = pd.DataFrame(snapshot_data)
logger.info(f"总共有 {len(snapshot_data)} 个快照")
with pd.ExcelWriter(EXCEL_OUTPUT_PATH, engine='openpyxl') as writer:
vm_df.to_excel(writer, sheet_name='VMs', index=False)
snapshot_df.to_excel(writer, sheet_name='Snapshots', index=False)
workbook = writer.book
style_sheet(workbook['VMs'])
# style_sheet(workbook['Snapshots'], snapshot_df['is_old'].tolist())
# 判断 DataFrame 是否有数据,没有数据则跳过,有数据则写入 excel 文件
if 'is_old' in snapshot_df.columns and snapshot_df['is_old'].tolist():
style_sheet(workbook['Snapshots'], snapshot_df['is_old'].tolist())
logger.debug(f"Excel 文件已生成: {EXCEL_OUTPUT_PATH}")
# 返回旧快照的数据,用于生成 Yaml 数据文件
return old_snapshots
def collect_snapshot_data(snapshot, vm, snapshot_data, old_snapshots):
""" 递归快照数据用于 Excel并收集旧快照 """
create_time = datetime.strptime(snapshot['createTime'], '%Y-%m-%d %H:%M:%S')
is_old = create_time < (datetime.now() - timedelta(days=SNAPSHOT_RETENTION_DAYS))
snapshot_info = {
'NodeHost': vm['NodeHost'],
'VMName': vm['name'],
'Snapshot Name': snapshot['name'],
'Description': snapshot['description'],
'CreateTime': snapshot['createTime'],
'State': snapshot['state'],
'ID': snapshot['id'],
'MOID': snapshot['moId'],
'Quiesced': snapshot['quiesced'],
'is_old': is_old
}
# 如果是旧快照,添加到旧快照列表
if is_old:
old_snapshots.append(snapshot_info)
snapshot_data.append(snapshot_info)
for child in snapshot['children']:
collect_snapshot_data(child, vm, snapshot_data, old_snapshots)
"""设置表格样式"""
def style_sheet(sheet, is_old_data=None):
"""设置工作表样式:列宽、边框、加粗标题、冻结首行和设置背景颜色"""
# 定义边框样式
thin = Side(border_style="thin", color="000000")
border = Border(left=thin, right=thin, top=thin, bottom=thin)
# 设置列宽和边框
for column in sheet.columns:
max_length = 0
column_letter = column[0].column_letter
for cell in column:
try:
if len(str(cell.value)) > max_length:
max_length = len(str(cell.value))
cell.border = border # 为每个单元格添加边框
except Exception as e:
pass
adjusted_width = (max_length + 2)
sheet.column_dimensions[column_letter].width = adjusted_width
# 加粗标题并冻结首行
for cell in sheet[1]: # 加粗标题
cell.font = Font(bold=True)
sheet.freeze_panes = 'A2' # 冻结首行
# 设置背景颜色
if is_old_data is not None:
for row in range(2, len(is_old_data) + 2):
if is_old_data[row - 2]:
for col in range(1, sheet.max_column + 1): # 使用 sheet.max_column
cell = sheet.cell(row=row, column=col)
cell.fill = PatternFill(start_color='ADD8E6', end_color='ADD8E6', fill_type='solid')
# 输出待删除的旧快照到 YAML 文件
def export_yaml(old_snapshots):
logger.info(f"可删除的快照有 {len(old_snapshots)}")
# 将旧快照信息存储到 YAML 文件
with open(YAML_OUTPUT_PATH, 'w', encoding='utf-8') as yaml_file:
# allow_unicode输出 Unicode 字符中文等allow_unicode使用块样式多行缩进sort_keys不按键名排序保留原始插入顺序
yaml.dump(old_snapshots, yaml_file, allow_unicode=True, default_flow_style=False, sort_keys=False)
logger.debug(f"YAML 文件已生成: {YAML_OUTPUT_PATH}")
if __name__ == '__main__':
vms = get_all_vms() # 导出 excel 和 yaml 文件,需要先获取虚拟机信息
old_snapshots = create_excel_report(vms) # 生成 Excel 报告并获取旧快照
export_yaml(old_snapshots)
# print(old_snapshots)