105 lines
3.3 KiB
Python
105 lines
3.3 KiB
Python
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']} 个快照") |