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

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

100
core/get_vm_snapshots.py Normal file
View File

@@ -0,0 +1,100 @@
from pyVmomi import vim
from datetime import timedelta
from pyVim.connect import Disconnect
from utils.logger import logger
from core.vm_connector import connect_vcenter
from config.settings import MANAGEMENT_NODES
def get_all_vms():
"""主函数,负责流程控制 """
vm_list = []
for node in MANAGEMENT_NODES:
si, vm_view = None, None # 初始两个变量值
try:
# 1. 连接节点(核心逻辑不变)
si = connect_vcenter(node['host'])
content = si.RetrieveContent()
vm_view = content.viewManager.CreateContainerView(
content.rootFolder, [vim.VirtualMachine], True
)
# 2. 收集VM信息
for vm in vm_view.view:
vm_list.append(build_vm_info(vm, node['host']))
except Exception as e: # 记录错误,跳过当前节点
logger.error(f"处理节点 {node['host']} 失败:{e}")
finally:
# 无论成败,销毁视图+断开连接
if vm_view:
vm_view.Destroy()
if si:
Disconnect(si)
logger.info(f"获取到 {len(vm_list)} 台虚拟机")
return vm_list
def build_vm_info(vm, node_host):
"""构造虚拟机信息字典"""
vm_info = {
'NodeHost': node_host,
'name': vm.name,
'moId': vm._moId,
'powerState': vm.runtime.powerState,
'system': vm.config.guestFullName,
'ipAddress': vm.guest.ipAddress,
'hostName': vm.guest.hostName,
'diskSpaceGB': get_virtual_disk_size(vm),
'createDate': (vm.config.createDate + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S') if vm.runtime.bootTime else None, # 虚拟机的创建时间
'bootTime': (vm.runtime.bootTime + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S') if vm.runtime.bootTime else None, # 虚拟机上次启动的时间
'snapshots': [],
'Host': vm.runtime.host.name,
'vmPath': vm.config.files.vmPathName
}
# 判断虚拟机是否有快照如果有就构造快照结构并记录当前快照ID如果没有就设为 None。
if vm.snapshot:
current_snapshot = vm.snapshot.currentSnapshot
root_snapshots = vm.snapshot.rootSnapshotList
for snapshot in root_snapshots:
vm_info['snapshots'].extend(build_snapshot_dict(snapshot))
vm_info['currentSnapshotId'] = (
current_snapshot._moId if current_snapshot else None
)
else:
vm_info['snapshots'] = None
vm_info['currentSnapshotId'] = None
return vm_info
def build_snapshot_dict(snapshot):
"""递归构造快照结构"""
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,
'quiesced': getattr(snapshot, 'quiesced', None),
'children': []
}
if snapshot.childSnapshotList:
for child in snapshot.childSnapshotList:
snapshot_info['children'].extend(build_snapshot_dict(child))
return [snapshot_info]
"""获取虚拟机的总磁盘大小(仅是虚拟磁盘的分配空间)"""
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
if __name__ == '__main__':
vms = get_all_vms() # 主函数入口,获取虚拟机信息
# print(vms)