从 ZStack 获取物理机与云主机信息并导出 Excel 文件

文章目录

  • 从 ZStack 获取物理机与云主机信息并导出 Excel 文件
  • 环境
  • zstack 官网
  • 客户端封装
    • 讲解
  • 获取物理机信息
    • 讲解
  • 获取云主机信息并关联物理机
    • 讲解
  • 导出数据到 Excel 文件
    • 讲解
  • 运行主程序
    • 讲解
  • 总结
  • 最终文档效果
  • 完整代码


从 ZStack 获取物理机与云主机信息并导出 Excel 文件

在云计算环境中,物理机和云主机的信息管理非常重要。ZStack 作为一款开源云平台,提供了丰富的 API 来获取相关数据。本文将通过一个 Python 脚本,展示如何从 ZStack 获取物理机和云主机的基本信息,并将这些信息整理成 Excel 文件,方便进行分析和报告。

环境

  • python 3.9
  • zstack 5.3.0

zstack 官网

用户手册
开发手册

客户端封装

为了与 ZStack 进行交互,我们首先需要封装一个 API 客户端。这个客户端提供了登录、请求数据和获取物理机、云主机信息的功能。

class ZstackInstancesApi:def __init__(self, host, user, passwd, port):self.zstack_api_url = f"http://{host}:{port}/zstack/"self.session_id = self._login(user, passwd)self.headers = {"Content-Type": "application/json;charset=UTF-8","Authorization": f"OAuth {self.session_id}" if self.session_id else ""}def _login(self, user, passwd):login_data = {"logInByAccount": {"accountName": user,"password": hashlib.sha512(passwd.encode()).hexdigest(),}}try:res = requests.put(f"{self.zstack_api_url}v1/accounts/login",data=json.dumps(login_data),headers={"Content-Type": "application/json"},)res.raise_for_status()return res.json().get("inventory", {}).get("uuid")except requests.RequestException as e:print(f"Login failed: {e}")return None

讲解

  • ZstackInstancesApi 类封装了与 ZStack API 交互的基本操作。
  • __init__ 方法接收 ZStack 服务器的地址、用户名、密码和端口,初始化客户端并进行登录。
  • _login 方法使用 SHA-512 加密密码并发起登录请求,获取会话 ID。

获取物理机信息

接下来,我们通过 get_queryhost 方法获取物理机的基本信息。每台物理机的信息包括 UUID、名称、状态、管理 IP、CPU 核心数、内存容量等。

def get_queryhost(self):data = self._request("GET", "v1/hosts")if not data:return []instances = []for instance in data.get("inventories", []):instances.append({"uuid": instance.get("uuid"),"state": instance.get("state"),"status": instance.get("status"),"cpuNum": instance.get("cpuNum"),"name": instance.get("name"),"managementIp": instance.get("managementIp"),"cpuSockets": instance.get("cpuSockets"),"totalMemoryCapacity": round(instance.get("totalMemoryCapacity", 0) / (1024 * 1024 * 1024), 2)})return instances

讲解

  • get_queryhost 方法发送请求获取所有物理机的信息,并对返回的数据进行解析,将相关字段整理成一个易于使用的列表。
  • 物理机信息包括 UUID、状态、CPU 核心数、内存等数据,内存被转换为 GB 单位,保留两位小数。

获取云主机信息并关联物理机

通过 get_instances_info 方法,我们可以获取所有云主机的信息,并通过云主机的 hostUuid 与物理机的信息进行关联。每个云主机的详细信息包括名称、状态、CPU 核心数、内存、IP 地址、存储信息等。

def get_instances_info(self):data = self._request("GET", "v1/vm-instances")if not data:return []physical_machines = self.get_queryhost()physical_machine_dict = {pm["uuid"]: pm["managementIp"] for pm in physical_machines}instances = []for instance in data.get("inventories", []):vm_nics = instance.get("vmNics", [])nic_ip = vm_nics[0].get("ip") if vm_nics else Nonevm_allVolumes = instance.get("allVolumes", [])volumes = []for volume in vm_allVolumes:if volume.get("type") != "Root":continuevolume_info = {"size": round(volume.get("size") / (1024 * 1024 * 1024), 2),}volumes.append(volume_info)host_uuid = instance.get("hostUuid")physical_ip = physical_machine_dict.get(host_uuid)instances.append({"uuid": instance.get("uuid"),"name": instance.get("name"),"state": instance.get("state"),"platform": instance.get("platform"),"cpuNum": instance.get("cpuNum"),"memorySize": round(instance.get("memorySize", 0) / (1024 * 1024 * 1024), 2),"ip": nic_ip,"volumes": volumes[0].get("size") if volumes else None,"hostIp": physical_ip})return instances

讲解

  • get_instances_info 方法首先获取云主机信息,并通过物理机的 uuid 从物理机列表中查找对应的 IP。
  • 云主机的存储信息会被提取并转换为 GB 单位。关联物理机信息后,云主机信息中将包含物理机的 IP。

导出数据到 Excel 文件

在获取完物理机和云主机的所有信息后,我们将其导出到 Excel 文件中,分别保存在两个工作表里:一个存储物理机信息,另一个存储云主机信息。

def export_to_excel(physical_machines, instances):wb = openpyxl.Workbook()# 创建物理机 Sheetws1 = wb.activews1.title = "物理机信息"ws1.append(["物理机名称", "物理机IP", "物理机状态", "CPU", "内存", "磁盘"])for machine in physical_machines:total_capacity = f"{machine['totalCapacity']} GB" if "totalCapacity" in machine else "N/A"ws1.append([machine["name"],machine["managementIp"],machine["state"],machine["cpuNum"],f"{machine['totalMemoryCapacity']} GB",total_capacity])# 创建云主机 Sheetws2 = wb.create_sheet(title="虚拟机信息")ws2.append(["云主机名称", "云主机IP", "云主机状态", "CPU", "内存", "云主机磁盘", "物理机IP"])for instance in instances:ws2.append([instance["name"],instance["ip"],instance["state"],instance["cpuNum"],f"{instance['memorySize']} GB",f"{instance['volumes']} GB" if instance.get("volumes") else "N/A",instance.get("hostIp"),])# 保存文件wb.save("cloud_and_physical_machines.xlsx")

讲解

  • export_to_excel 方法使用 openpyxl 库创建一个 Excel 文件,分两个工作表导出物理机和云主机的信息。
  • 物理机的磁盘容量(总容量)和云主机的磁盘信息(根卷大小)会分别输出到对应的工作表中。

运行主程序

最后,在 __main__ 代码块中,我们初始化 API 客户端,获取物理机和云主机信息,并导出到 Excel 文件。

if __name__ == "__main__":api = ZstackInstancesApi(host="192.168.1.1", user="admin", passwd="password", port=8080)physical_machines = api.get_queryhost()uuid = api.get_primary_storage_info()[0].get("uuid")physical_storage_info = api.get_physical_storage_info(uuid)for machine in physical_machines:for storage in physical_storage_info:if machine["uuid"] == storage["hostUuid"]:machine["totalCapacity"] = storage["totalCapacity"]breakinstances = api.get_instances_info()export_to_excel(physical_machines, instances)

讲解

  • 通过 ZstackInstancesApi 客户端获取物理机和云主机的信息。
  • 获取主存储信息并将磁盘容量添加到物理机信息中。
  • 最后将数据导出到 cloud_and_physical_machines.xlsx 文件。

总结

通过上述代码,我们能够从 ZStack 获取物理机和云主机的相关信息,并将这些信息以结构化的方式导出到 Excel 文件中。这样,管理员可以方便地查看和分析云环境中的各类资源。此方法不仅简化了信息提取的流程,也为进一步的资源管理和优化提供了有力支持。

最终文档效果

在这里插入图片描述
在这里插入图片描述

完整代码

"""
导出物理机信息以及关联云主机信息生成excel表格
物理机名称 物理机IP 物理机状态 物理机CPU 物理机内存 物理机磁盘
云主机名称 云主机IP 云主机状态 云主机CPU 云主机内存 云主机磁盘
"""
import requests
import json
import hashlib
import openpyxlclass ZstackInstancesApi:"""ZStack API 客户端封装,用于管理云主机实例。"""def __init__(self, host, user, passwd, port):"""初始化 API 客户端,并尝试登录。:param host: ZStack 服务器地址:param user: 登录用户名:param passwd: 登录密码:param port: 服务器端口,默认为 8080"""self.zstack_api_url = f"http://{host}:{port}/zstack/"self.session_id = self._login(user, passwd)self.headers = {"Content-Type": "application/json;charset=UTF-8","Authorization": f"OAuth {self.session_id}" if self.session_id else ""}def _login(self, user, passwd):"""登录 ZStack 并获取会话 ID。:param user: 账户名:param passwd: 密码:return: 会话 ID 或 None(登录失败时)"""login_data = {"logInByAccount": {"accountName": user,"password": hashlib.sha512(passwd.encode()).hexdigest(),}}try:res = requests.put(f"{self.zstack_api_url}v1/accounts/login",data=json.dumps(login_data),headers={"Content-Type": "application/json"},)res.raise_for_status()return res.json().get("inventory", {}).get("uuid")except requests.RequestException as e:print(f"Login failed: {e}")return Nonedef _request(self, method, endpoint, params=None):"""统一封装 HTTP 请求方法。:param method: HTTP 方法(GET、POST、DELETE等):param endpoint: API 端点:param params: 请求参数:return: JSON 响应数据或 None(请求失败时)"""url = f"{self.zstack_api_url}{endpoint}"try:res = requests.request(method, url, headers=self.headers, params=params)res.raise_for_status()return res.json()except requests.RequestException as e:print(f"Request failed: {e}")return Nonedef get_queryhost(self):"""获取所有物理机的基本信息。:return: 包含物理机信息的列表"""data = self._request("GET", "v1/hosts")# return data.get("inventories", []) if data else []if not data:return []instances = []for instance in data.get("inventories", []):instances.append({"uuid": instance.get("uuid"),"state": instance.get("state"),"status": instance.get("status"),"cpuNum": instance.get("cpuNum"),"name": instance.get("name"),"managementIp": instance.get("managementIp"),"cpuSockets": instance.get("cpuSockets"),"totalMemoryCapacity": round(instance.get("totalMemoryCapacity", 0) / (1024 * 1024 * 1024), 2)  # 转换为 GB,保留两位小数})return instancesdef get_primary_storage_info(self):"""获取主存储信息。:return: 主存储信息列表"""data = self._request("GET", "v1/primary-storage")if not data:return []storages = []for storage in data.get("inventories", []):storages.append({"uuid": storage.get("uuid"),"name": storage.get("name"),"state": storage.get("state"),"status": storage.get("status"),"totalCapacity": round(storage.get("totalCapacity", 0) / (1024 * 1024 * 1024), 2),  # 转换为 GB"availableCapacity": round(storage.get("availableCapacity", 0) / (1024 * 1024 * 1024), 2)})return storagesdef get_physical_storage_info(self, uuid):"""获取指定主存储的物理存储信息。:param uuid: 主存储 UUID:return: 物理存储信息列表"""data = self._request("GET", f"v1/primary-storage/local-storage/{uuid}/capacities")if not data:return []physical_storages = []for storage in data.get("inventories", []):physical_storages.append({"hostUuid": storage.get("hostUuid"),"totalCapacity": round(storage.get("totalCapacity", 0) / (1024 * 1024 * 1024), 2),# "availableCapacity": round(storage.get("availableCapacity", 0) / (1024 * 1024 * 1024), 2),# "totalPhysicalCapacity": round(storage.get("totalPhysicalCapacity", 0) / (1024 * 1024 * 1024), 2),# "availablePhysicalCapacity": round(storage.get("availablePhysicalCapacity", 0) / (1024 * 1024 * 1024), 2)})return physical_storagesdef get_instance_vm(self, uuid):"""获取指定云主机的控制台地址。:param uuid: 云主机 UUID:return: JSON 格式的控制台地址信息"""return self._request("GET", f"v1/vm-instances/{uuid}/console-addresses")# def get_instances_info(self):#     """#     获取所有云主机的基本信息。#     :return: 包含云主机信息的列表#     """#     data = self._request("GET", "v1/vm-instances")#     # return data.get("inventories", []) if data else []#     if not data:#         return []#     # for instance in instances:#     #     print(f"云主机名称: {instance['name']},memorySize: {instance['memorySize']}, cpuNum: {instance['cpuNum']}, state: {instance['state']}, vmNics: {instance['vmNics'][0].get('uuid')}, ")#     instances = []#     for instance in data.get("inventories", []):#         # 获取云主机的 IP 地址#         vm_nics = instance.get("vmNics", [])#         nic_ip = vm_nics[0].get("ip") if vm_nics else None#         # 获取云主机的存储信息#         vm_allVolumes = instance.get("allVolumes", [])#         volumes = []#         # 遍历所有卷并提取信息#         for volume in vm_allVolumes:#             # 只处理根卷#             if volume.get("type") != "Root":#                 continue#             volume_info = {#                 # "uuid": volume.get("uuid"),#                 # "name": volume.get("name"),#                 "size": round(volume.get("size") / (1024 * 1024 * 1024),2),  # 转换为 GB#             }#             volumes.append(volume_info)#         instances.append({#             "uuid": instance.get("uuid"),#             "hostUuid": instance.get("hostUuid"),#             "name": instance.get("name"),#             "state": instance.get("state"),#             "platform": instance.get("platform"),#             "cpuNum": instance.get("cpuNum"),#             "memorySize": round(instance.get("memorySize", 0) / (1024 * 1024 * 1024), 2),  # 转换为 GB#             "ip": nic_ip,#             "volumes": volumes[0].get("size") if volumes else None,  # 获取第一个卷的大小#         })#     return instancesdef get_instances_info(self):"""获取所有云主机的基本信息,并与物理机信息关联。:return: 包含云主机信息的列表"""data = self._request("GET", "v1/vm-instances")if not data:return []# 获取所有物理机信息physical_machines = self.get_queryhost()# 创建一个字典,快速查找物理机信息physical_machine_dict = {pm["uuid"]: pm["managementIp"] for pm in physical_machines}instances = []for instance in data.get("inventories", []):# 获取云主机的 IP 地址vm_nics = instance.get("vmNics", [])nic_ip = vm_nics[0].get("ip") if vm_nics else None# 获取云主机的存储信息vm_allVolumes = instance.get("allVolumes", [])volumes = []for volume in vm_allVolumes:if volume.get("type") != "Root":continuevolume_info = {"size": round(volume.get("size") / (1024 * 1024 * 1024), 2),  # 转换为 GB}volumes.append(volume_info)# 查找对应的物理机信息(只获取物理机的 IP)host_uuid = instance.get("hostUuid")physical_ip = physical_machine_dict.get(host_uuid)instances.append({"uuid": instance.get("uuid"),"name": instance.get("name"),"state": instance.get("state"),"platform": instance.get("platform"),"cpuNum": instance.get("cpuNum"),"memorySize": round(instance.get("memorySize", 0) / (1024 * 1024 * 1024), 2),  # 转换为 GB"ip": nic_ip,"volumes": volumes[0].get("size") if volumes else None,"hostIp": physical_ip  # 只输出物理机的 IP})return instancesdef get_query_address_pool(self, uuid):"""获取指定地址池的详细信息。:param uuid: 地址池 UUID:return: JSON 格式的地址池信息"""return self._request("GET", f"v1/l3-networks/address-pools/{uuid}")def logout(self):"""退出当前 ZStack 会话。"""if not self.session_id:print("No active session to log out.")returnself._request("DELETE", f"api/v2/session/{self.session_id}")def export_to_excel(physical_machines, instances):wb = openpyxl.Workbook()# 创建物理机 Sheetws1 = wb.activews1.title = "物理机信息"ws1.append(["物理机名称", "物理机IP", "物理机状态", "CPU", "内存", "磁盘"])for machine in physical_machines:total_capacity = f"{machine['totalCapacity']} GB" if "totalCapacity" in machine else "N/A"ws1.append([machine["name"],machine["managementIp"],machine["state"],machine["cpuNum"],f"{machine['totalMemoryCapacity']} GB",total_capacity  # 添加磁盘总容量])# 创建云主机 Sheetws2 = wb.create_sheet(title="虚拟机信息")ws2.append(["云主机名称", "云主机IP", "云主机状态", "CPU", "内存", "云主机磁盘", "物理机IP"])for instance in instances:ws2.append([instance["name"],instance["ip"],instance["state"],instance["cpuNum"],f"{instance['memorySize']} GB",f"{instance['volumes']} GB" if instance.get("volumes") else "N/A",instance.get("hostIp"),  # 输出物理机的 IP])# 保存文件wb.save("cloud_and_physical_machines.xlsx")if __name__ == "__main__":# 示例: 初始化 API 客户端并获取云主机信息api = ZstackInstancesApi(host="192.168.1.1", user="admin", passwd="password", port=8080)# 获取所有物理机信息physical_machines = api.get_queryhost()# 获取主存储信息并根据物理机 UUID 进行匹配uuid = api.get_primary_storage_info()[0].get("uuid")physical_storage_info = api.get_physical_storage_info(uuid)# 遍历物理机信息并添加 totalCapacity 信息for machine in physical_machines:for storage in physical_storage_info:if machine["uuid"] == storage["hostUuid"]:# 在物理机信息中添加 totalCapacitymachine["totalCapacity"] = storage["totalCapacity"]break  # 一旦找到对应的物理存储,跳出循环# 获取所有云主机信息instances = api.get_instances_info()# 导出数据到 Excel 文件export_to_excel(physical_machines, instances)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/900445.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

5.好事多磨 -- TCP网络连接Ⅱ

前言 第4章节通过回声服务示例讲解了TCP服务器端/客户端的实现方法。但这仅是从编程角度的学习,我们尚未详细讨论TCP的工作原理。因此,将详细讲解TCP中必要的理论知识,还将给出第4章节客户端问题的解决方案。 一、回声客户端完美实现 第4章…

sql server数据库可疑修复

sql server数据库可疑修复 从上图可以看到数据库nchrdb显示可疑,导致原因为NC系统在增加公共薪资项目的时候,扩展字段报错了,第一次遇到这种情况,折腾了很久终于解决,记下解决方案: 1,将SQL数据…

Flutter之页面布局二

目录: 1、列表布局1.1、基础列表1.2、水平滑动的列表1.3、网格列表1.3、不同列表项的列表1.4、包含间隔的列表1.6、长列表 2、滚动2.1、浮动的顶栏2.2、平衡错位滚动 1、列表布局 1.1、基础列表 import package:flutter/material.dart;void main() > runApp(con…

ARM------硬件程序开发

硬件程序开发流程 相关硬件的工作原理 理解硬件的工作原理,明确硬件的功能和用途。 硬件连接 将硬件设备正确连接到开发板上。 编写程序 根据硬件功能编写相应的程序代码。 调试验证 通过调试工具验证程序的正确性,确保硬件功能正常。 控制LED的…

《QT从基础到进阶·七十四》Qt+C++开发一个python编译器,能够编写,运行python程序改进版

1、概述 源码放在文章末尾 根据上一篇文章回顾下利用QtC实现了一个简易的python编译器,类似pycharm或vsCode这样的编译器,该python编译器目前实现了如下功能: (1)支持编写python程序 (2)编写代…

Winform MQTT客户端连接方式

项目中使用到Winform的数据转发服务,所以记录下使用到的方法。 一.创建单例模板 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ConsoleApp.Scripts {public class SingleTon&…

Windows强制删除任何你想删除的文件和文件夹

Windows强制删除任何你想删除的文件和文件夹 本教程适用于 Windows 10/11 系统,工具和命令均经过验证。 为什么删除会失败? 权限不足:文件或文件夹可能需要管理员权限才能删除。文件被占用:某个程序正在使用目标文件&#xff0c…

Jmeter如何使用MD5进行加密?

在软件测试中,使用 JMeter 对数据进行 MD5 加密是一项常见需求,尤其是在模拟用户登录等涉及密码加密的场景时。下面详细介绍在 JMeter 里运用 MD5 加密的具体步骤。 1. 添加 BeanShell 预处理器 JMeter 本身没有直接的 MD5 加密功能,但可以…

4-c语言中的数据类型

一.C 语⾔中的常量 1.生活中的数据 整数: 100,200,300,400,500 小数: 11.11 22.22 33.33 字母: a,b,c,d A,B,C,D 在 C 语⾔中我们把字⺟叫做字符. 字符⽤单引号引⽤。例如A’ 单词…

中钧科技通过数字赋能,编织“数字互联网”助力数字化进程!

时间飞逝转眼间2025年已过去四分之一,作为一名95后回顾当下的生活,忍不住感慨10年和现在的对比。发现现在的手机支付、网上挂号、APP打车、在线学习、网络订餐、线上协同办公都以逐渐成为人们生活、工作的常态。也正是在这样的常态背景下,加快…

AI重塑云基础设施,亚马逊云科技打造AI定制版IaaS“样板房”

AI正在彻底重塑云基础设施。 IDC最新《2025年IDC MarketScape:全球公有云基础设施即服务(IaaS)报告》显示,AI正在通过多种方式重塑云基础设施,公有云IaaS有望继续保持快速增长,预计2025年全球IaaS的整体规…

高效深度学习lecture01

lecture01 零样本学习(Zero-Shot Learning, ZSL): 模型可以在没有见过某种特定任务或类别的训练样本的情况下,直接完成对应的任务 利用知识迁移 模型在一个任务上训练时学到的知识,能够迁移到其他任务上比如,模型知道“狗”和“…

使用 iPerf 测试内网两台机器之间的传输速度

在现代网络管理中,确保内部网络(内网)的高效运行是至关重要的。为了评估和优化网络性能,我们需要一种可靠的方法来测试内网中不同设备间的传输速率。iPerf 作为一款广泛使用的工具,能够帮助我们准确测量两个节点之间的…

视频设备轨迹回放平台EasyCVR如何搭建公共娱乐场所远程视频监控系统

一、背景介绍 由于KTV、酒吧、足疗店等服务场所人员流动频繁、环境复杂,一直是治安管理的重点区域。为有效打击 “黄赌毒”、打架斗殴、寻衅滋事等违法犯罪的活动,打造安全有序的娱乐消费环境,我国相关部门将加大对这类场所的清查与管控力度…

vue进度条组件

<div class"global-mask" v-if"isProgress"><div class"contentBox"><div class"progresstitie">数据加载中请稍后</div><el-progress class"progressStyle" :color"customColor" tex…

Css:如何解决绝对定位子元素内容被父级元素overflow:hidden属性剪裁

一、问题描述 今天小伙伴提了一个bug&#xff0c;在点击列表项的“…”按钮应该出现的悬浮菜单显示不完整&#xff1a; 二、问题排查 一般这种问题&#xff0c;是由于悬浮菜单采用的是绝对定位&#xff0c;而父级采用了overflow:hidden属性。但需要注意的是&#xff0c;这里的…

JavaScript基础--01-JS简介

字面量&#xff1a;数字、字符串、布尔值 前言JavaScript背景Web前端有三层&#xff1a;发展历史JavaScript的发展&#xff1a;蒸蒸日上 JavaScript介绍JavaScript入门易学性JavaScript是脚本语言JavaScript的组成 JavaScript 的特点特点1&#xff1a;解释型语言特点2&#xff…

[leetcode] 面试经典 150 题——篇9:二叉树(番外:二叉树的遍历方式)

二叉树的遍历是指按照某种顺序访问二叉树中的每个节点。常见的遍历方式有四种&#xff1a;前序遍历&#xff08;Pre-order Traversal&#xff09;、中序遍历&#xff08;In-order Traversal&#xff09;、后序遍历&#xff08;Post-order Traversal&#xff09;以及层序遍历&am…

es基本概念

Elasticsearch 的架构与基本概念 Elasticsearch&#xff08;简称 ES&#xff09;是一个开源的分布式搜索和分析引擎&#xff0c;基于 Apache Lucene 构建。它被广泛用于全文搜索、日志分析、实时数据分析等场景。以下是其架构概述及其基本概念的详细解释。 Elasticsearch 的架…

《星环之城:量子迷雾下的网络安全战记》

点击下面图片带您领略全新的嵌入式学习路线 &#x1f525;爆款热榜 88万阅读 1.6万收藏 序章&#xff1a;星环之陨 公元2145年&#xff0c;人类在火星轨道上建造了“星环之城”——一座由量子网络连接的太空城邦。它的中枢AI“盖娅”掌控着地球与殖民地的数据洪流&#xff…