接近完善的代码,待生产环境测试。
This commit is contained in:
100
core/get_vm_snapshots.py
Normal file
100
core/get_vm_snapshots.py
Normal 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)
|
||||
Reference in New Issue
Block a user