Get Vms Snapshots and Export Excel has completed.
This commit is contained in:
237
core/get_vms.py
Normal file
237
core/get_vms.py
Normal file
@@ -0,0 +1,237 @@
|
||||
from pyVmomi import vim
|
||||
from pyVim.connect import SmartConnect, Disconnect
|
||||
from config.settings import MANAGEMENT_NODES
|
||||
from datetime import timedelta
|
||||
import pandas as pd
|
||||
import openpyxl
|
||||
from openpyxl.styles import Border, Side, Font, PatternFill
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
"""计算虚拟机的总磁盘大小(仅是虚拟磁盘的分配空间)"""
|
||||
def get_virtual_disk_size(vm):
|
||||
total_size = 0
|
||||
for device in vm.config.hardware.device:
|
||||
if isinstance(device, vim.vm.device.VirtualDisk):
|
||||
# 获取每个虚拟磁盘的容量
|
||||
total_size += device.capacityInKB / (1024 * 1024) # 转换为GB
|
||||
return total_size
|
||||
|
||||
|
||||
"""获取所有虚拟机"""
|
||||
def get_all_vms():
|
||||
# 取第一个节点
|
||||
node = MANAGEMENT_NODES[0]
|
||||
|
||||
# 连接vCenter
|
||||
si = SmartConnect(
|
||||
host=node['host'],
|
||||
user=node['user'],
|
||||
pwd=node['password'],
|
||||
disableSslCertValidation=True
|
||||
)
|
||||
|
||||
# 获取所有VM
|
||||
content = si.RetrieveContent()
|
||||
vm_view = content.viewManager.CreateContainerView(
|
||||
content.rootFolder, [vim.VirtualMachine], True
|
||||
)
|
||||
|
||||
vm_list = []
|
||||
for vm in vm_view.view:
|
||||
# 初始化VM信息字典
|
||||
vm_info = {
|
||||
'name': vm.name,
|
||||
'moId': vm._moId,
|
||||
'powerState': str(vm.runtime.powerState),
|
||||
'system': vm.config.guestFullName,
|
||||
'ipAddress': vm.guest.ipAddress,
|
||||
'hostName': vm.guest.hostName,
|
||||
'vmPath': vm.config.files.vmPathName,
|
||||
'Host': vm.runtime.host.name, # 拿到 Host 主机名
|
||||
'snapshots': [], # 添加快照信息
|
||||
'diskSpaceGB': get_virtual_disk_size(vm) # 添加虚拟机占用的磁盘空间
|
||||
}
|
||||
|
||||
# 获取快照信息
|
||||
if vm.snapshot is not None:
|
||||
current_snapshot = vm.snapshot.currentSnapshot
|
||||
root_snapshots = vm.snapshot.rootSnapshotList
|
||||
|
||||
# 处理根快照列表
|
||||
for snapshot in root_snapshots:
|
||||
snapshot_info = get_snapshot_info(snapshot)
|
||||
vm_info['snapshots'].extend(snapshot_info)
|
||||
|
||||
# 添加当前快照ID(如果有)
|
||||
if current_snapshot:
|
||||
vm_info['currentSnapshotId'] = current_snapshot._moId
|
||||
else:
|
||||
vm_info['snapshots'] = None
|
||||
vm_info['currentSnapshotId'] = None
|
||||
|
||||
vm_list.append(vm_info)
|
||||
|
||||
vm_view.Destroy()
|
||||
Disconnect(si)
|
||||
|
||||
print(f"获取到 {len(vm_list)} 台VM")
|
||||
return vm_list
|
||||
|
||||
|
||||
"""递归获取快照信息"""
|
||||
def get_snapshot_info(snapshot):
|
||||
|
||||
snapshot_list = []
|
||||
# 当前快照信息
|
||||
snapshot_info = {
|
||||
'name': snapshot.name,
|
||||
'description': snapshot.description,
|
||||
'createTime': (snapshot.createTime + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'state': str(snapshot.state),
|
||||
'id': snapshot.id,
|
||||
'moId': snapshot.snapshot._moId, # 快照的Managed Object ID
|
||||
'sizeMB': snapshot.diskSizeMB if hasattr(snapshot, 'diskSizeMB') else None, # 快照大小
|
||||
'quiesced': snapshot.quiesced if hasattr(snapshot, 'quiesced') else None, # 是否静默快照
|
||||
'children': [] # 子快照
|
||||
}
|
||||
|
||||
# 递归处理子快照
|
||||
if snapshot.childSnapshotList:
|
||||
for child in snapshot.childSnapshotList:
|
||||
snapshot_info['children'].extend(get_snapshot_info(child))
|
||||
|
||||
snapshot_list.append(snapshot_info)
|
||||
return snapshot_list
|
||||
|
||||
|
||||
def print_snapshot_tree(snapshot_info, level=0):
|
||||
"""递归打印快照树(辅助函数)"""
|
||||
indent = " " * level
|
||||
print(f"{indent}├─ {snapshot_info['name']}")
|
||||
print(f"{indent}│ ├─ 创建时间: {snapshot_info['createTime']}")
|
||||
print(f"{indent}│ ├─ 描述: {snapshot_info['description']}")
|
||||
print(f"{indent}│ ├─ 状态: {snapshot_info['state']}")
|
||||
if snapshot_info['sizeMB']:
|
||||
print(f"{indent}│ ├─ 大小: {snapshot_info['sizeMB']} MB")
|
||||
|
||||
for child in snapshot_info['children']:
|
||||
print_snapshot_tree(child, level + 1)
|
||||
|
||||
|
||||
"""表格样式"""
|
||||
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')
|
||||
|
||||
|
||||
"""将虚拟机和快照信息写入Excel文件,并标记创建时间在15天前的快照"""
|
||||
def create_excel_report(vms):
|
||||
vm_data = []
|
||||
snapshot_data = []
|
||||
|
||||
def add_snapshots_to_report(snapshot, vm_name):
|
||||
"""递归将快照信息加入报告"""
|
||||
create_time = datetime.strptime(snapshot['createTime'], '%Y-%m-%d %H:%M:%S')
|
||||
is_old = create_time < (datetime.now() - timedelta(days=1))
|
||||
|
||||
snapshot_data.append({
|
||||
'VM Name': vm_name,
|
||||
'Snapshot Name': snapshot['name'],
|
||||
'Description': snapshot['description'],
|
||||
'Create Time': snapshot['createTime'],
|
||||
'State': snapshot['state'],
|
||||
'ID': snapshot['id'],
|
||||
'MO ID': snapshot['moId'],
|
||||
'Size (MB)': snapshot['sizeMB'],
|
||||
'Quiesced': snapshot['quiesced'],
|
||||
'is_old': is_old
|
||||
})
|
||||
|
||||
for child in snapshot['children']:
|
||||
add_snapshots_to_report(child, vm_name)
|
||||
|
||||
for vm in vms:
|
||||
vm_data.append({
|
||||
'VM Name': vm['name'],
|
||||
'MO ID': vm['moId'],
|
||||
'Power State': vm['powerState'],
|
||||
'System': vm['system'],
|
||||
'IP Address': vm['ipAddress'],
|
||||
'Host Name': vm['hostName'],
|
||||
'VM Path': vm['vmPath'],
|
||||
'Host': vm['Host'],
|
||||
'Current Snapshot ID': vm.get('currentSnapshotId', None),
|
||||
'DiskSpace/GB': vm['diskSpaceGB']
|
||||
})
|
||||
|
||||
if vm['snapshots']:
|
||||
for snapshot in vm['snapshots']:
|
||||
add_snapshots_to_report(snapshot, vm['name'])
|
||||
|
||||
vm_df = pd.DataFrame(vm_data)
|
||||
snapshot_df = pd.DataFrame(snapshot_data)
|
||||
|
||||
with pd.ExcelWriter('vm_and_snapshots_report.xlsx', 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
|
||||
vm_sheet = workbook['VMs']
|
||||
snapshot_sheet = workbook['Snapshots']
|
||||
|
||||
# 调用样式设置函数,传入 is_old_data
|
||||
style_sheet(vm_sheet) # 设置 VMs 工作表样式
|
||||
style_sheet(snapshot_sheet, snapshot_df['is_old'].tolist()) # 设置 Snapshots 工作表样式并传入旧数据标识列表
|
||||
|
||||
print("报告已生成: vm_and_snapshots_report.xlsx")
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
vms = get_all_vms()
|
||||
|
||||
# # 打印示例:显示每个VM的快照信息
|
||||
# for vm in vms:
|
||||
# print(f"\nVM: {vm['name']}")
|
||||
# if vm['snapshots']:
|
||||
# print(f"快照数量: {len(vm['snapshots'])}")
|
||||
# for snapshot in vm['snapshots']:
|
||||
# print_snapshot_tree(snapshot)
|
||||
# else:
|
||||
# print("无快照")
|
||||
|
||||
# 生成Excel报告
|
||||
create_excel_report(vms)
|
||||
Reference in New Issue
Block a user