from pyVmomi import vim from config.settings import MANAGEMENT_NODES from core.vcenter_connector import VCenterManager # 使用管理器类 from utils.logger import logger from typing import List, Dict def get_all_vms_from_node(si, node_name: str) -> List[Dict]: """ 从单个vCenter/ESXi获取所有虚拟机 :param si: ServiceInstance :param node_name: 节点名称(用于标识来源) :return: VM列表 """ try: content = si.RetrieveContent() vm_view = content.viewManager.CreateContainerView( content.rootFolder, [vim.VirtualMachine], True ) vms = vm_view.view vm_view.Destroy() vm_list = [] for vm in vms: # 安全获取快照数量 num_snapshots = 0 if vm.snapshot and vm.snapshot.rootSnapshotList: num_snapshots = len(vm.snapshot.rootSnapshotList) vm_info = { 'vcenter_node': node_name, # 来自哪个vCenter/ESXi 'vcenter_host': si._stub.host, # vCenter主机地址 'vm_name': vm.name, 'vm_moid': vm._moId, 'power_state': str(vm.runtime.powerState), # 转字符串 'num_snapshots': num_snapshots, 'guest_os': vm.config.guestFullName if vm.config else 'Unknown' } vm_list.append(vm_info) logger.info(f"📥 [{node_name}] 获取到 {len(vm_list)} 台VM") return vm_list except Exception as e: logger.error(f"❌ [{node_name}] 获取VM列表失败: {str(e)}") return [] def get_all_vms_from_all_nodes() -> List[Dict]: """ 从所有配置的vCenter/ESXi节点获取虚拟机 :return: 合并后的VM列表 """ all_vms = [] # 使用VCenterManager连接所有节点 with VCenterManager() as manager: connections = manager.connect_all() if not connections: logger.error("没有可用的vCenter/ESXi连接") return [] # 遍历每个连接获取VM for conn in connections: vms = get_all_vms_from_node(conn.si, conn.name) all_vms.extend(vms) # 合并列表 logger.info(f"📊 总计获取 {len(all_vms)} 台VM(来自 {len(connections)} 个节点)") return all_vms def print_vm_table(vm_list: List[Dict]): """打印VM列表表格(调试用)""" if not vm_list: print("没有获取到VM数据") return print(f"\n{'=' * 100}") print(f"{'节点':<15} {'VM名称':<30} {'状态':<12} {'快照数':<8} {'操作系统':<20}") print(f"{'-' * 100}") for vm in vm_list: print(f"{vm['vcenter_node']:<15} {vm['vm_name']:<30} " f"{vm['power_state']:<12} {vm['num_snapshots']:<8} " f"{vm['guest_os'][:20]:<20}") print(f"{'=' * 100}") print(f"总计: {len(vm_list)} 台VM") # ==================== 主程序入口 ==================== if __name__ == '__main__': # 获取所有VM vm_list = get_all_vms_from_all_nodes() # 打印结果 print_vm_table(vm_list) # 示例:筛选有快照的VM vms_with_snapshots = [vm for vm in vm_list if vm['num_snapshots'] > 0] print(f"\n有快照的VM: {len(vms_with_snapshots)} 台") for vm in vms_with_snapshots: print(f" - {vm['vm_name']}: {vm['num_snapshots']} 个快照")