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)