python3 脚本通过pyvim 调用 vshphere,进行一些操作,可以对接自己的运维管理平台
import atexit
import datetime
from itertools import count
import ssl
import time
from pyVim.connect import Disconnect, SmartConnect
from pyVmomi import vim, vmodl
import json
# 磁盘大小来显示不同的单位(例如字节、千字节、兆字节、吉字节等
def format_disk_size(bytes):
if bytes < 1024:
return f"{bytes} 字节"
elif bytes < 1024 * 1024:
kilobytes = bytes / 1024
return f"{kilobytes:.2f} KB"
elif bytes < 1024 * 1024 * 1024:
megabytes = bytes / (1024 * 1024)
return f"{megabytes:.2f} MB"
elif bytes < 1024 * 1024 * 1024 * 1024:
gigabytes = bytes / (1024 * 1024 * 1024)
return f"{gigabytes:.2f} GB"
else:
terabytes = bytes / (1024 * 1024 * 1024 * 1024)
return f"{terabytes:.2f} TB"
# 时间
def format_time(seconds):
if seconds < 60:
return f"{seconds}秒"
elif seconds < 3600:
minutes = seconds // 60
return f"{minutes}分钟"
elif seconds < 86400:
hours = seconds // 3600
return f"{hours}小时"
else:
days = seconds // 86400
return f"{days}天"
# 根据 CPU 大小来显示不同的单位(例如赫兹、千赫兹、兆赫兹等)
def format_cpu_speed(hertz):
if hertz < 1000:
return f"{hertz} Hz"
elif hertz < 1000000:
kilohertz = hertz / 1000
return f"{kilohertz:.2f} kHz"
elif hertz < 1000000000:
megahertz = hertz / 1000000
return f"{megahertz:.2f} MHz"
else:
gigahertz = hertz / 1000000000
return f"{gigahertz:.2f} GHz"
# 根据内存大小来显示不同的单位(例如字节、千字节、兆字节、吉字节等)
def format_memory_size(bytes):
if bytes < 1024:
return f"{bytes} 字节"
elif bytes < 1024 * 1024:
kilobytes = bytes / 1024
return f"{kilobytes:.2f} KB"
elif bytes < 1024 * 1024 * 1024:
megabytes = bytes / (1024 * 1024)
return f"{megabytes:.2f} MB"
else:
gigabytes = bytes / (1024 * 1024 * 1024)
return f"{gigabytes:.2f} GB"
# 虚拟机开关机需要的一个方法
def WaitForTasks(service_instance, tasks):
"""
Given the service instance si and tasks, it returns after all the
tasks are complete
"""
pc = service_instance.content.propertyCollector
task_list = [str(task) for task in tasks]
# Create filter
obj_specs = [vmodl.query.PropertyCollector.ObjectSpec(obj=task)
for task in tasks]
property_spec = vmodl.query.PropertyCollector.PropertySpec(type=vim.Task,
pathSet=[],
all=True)
filter_spec = vmodl.query.PropertyCollector.FilterSpec()
filter_spec.objectSet = obj_specs
filter_spec.propSet = [property_spec]
pcfilter = pc.CreateFilter(filter_spec, True)
try:
version, state = None, None
# Loop looking for updates till the state moves to a completed state.
while True:
update = pc.WaitForUpdates(version)
for filter_set in update.filterSet:
for obj_set in filter_set.objectSet:
task = obj_set.obj
for change in obj_set.changeSet:
if change.name == 'info':
state = change.val.state
elif change.name == 'info.state':
state = change.val
else:
continue
# Check if the state moved to a completed state.
if state == vim.TaskInfo.State.success:
return task.info.result
elif state == vim.TaskInfo.State.error:
raise task.info.error
finally:
if pcfilter:
pcfilter.Destroy()
class test(object):
# 与vsphere建立连接
def connect_vsphere(host,user,password,port):
context = None
# 建立与vSphere的连接
if hasattr(ssl, '_create_unverified_context'):
context = ssl._create_unverified_context()
si = SmartConnect(host=host,user=user,pwd=password,port=port,sslContext=context)
if not si:
print("帐号密码有问题")
# else:
# print('成功')
atexit.register(Disconnect, si)
return si
# 获取物理机详情
def get_host_template(si):
content = si.RetrieveContent()
# 物理机名称
host_name = "10.252.100.100"
# 使用 content.searchIndex 执行查找
search_index = content.searchIndex
host = search_index.FindByDnsName(dnsName=host_name, vmSearch=False)
host_information = {}
if host:
# 获取物理机电源状态
power_state = host.runtime.powerState
if power_state == "poweredOn":
host_information['status'] = "开机"
# 获取物理机信息
cpu_usage = host.summary.quickStats.overallCpuUsage
total_cpu_resource = host.summary.hardware.numCpuCores * host.summary.hardware.cpuMhz
total_memory = host.hardware.memorySize
memory_usage = host.summary.quickStats.overallMemoryUsage
uptime = host.summary.quickStats.uptime
# 获取存储信息
total_storage_size = 0
# 获取存储已用信息
used_storage_size = 0
for datastore in host.datastore:
total_storage_size += datastore.summary.capacity
# 检查每个存储设备的已用容量
used_storage_size += datastore.summary.capacity - datastore.summary.freeSpace
# 转换存储大小为 GB 或 TB,视情况而定
total_storage_size_in_gb = total_storage_size # 转换为 GB
used_storage_size_in_gb = used_storage_size # 转换为 TB
# 内存可用
memAvailable = total_memory - (memory_usage * 1024 * 1024)
# print(format_memory_size(memAvailable))
# 磁盘可用
storageAvailable = total_storage_size_in_gb - used_storage_size_in_gb
# cpu可用
cpuAvailable = total_cpu_resource - cpu_usage
host_information.update({
"name": host.name,
"hardware_model": host.hardware.systemInfo.model,
"cpu_model": host.hardware.cpuPkg[0].description,
"cpu_cores": host.hardware.cpuInfo.numCpuCores,
"cpu_sockets": host.hardware.cpuInfo.numCpuPackages,
"cpu_available":format_cpu_speed(cpuAvailable * 1000000),
"物理机逻辑处理器数量": host.summary.hardware.numCpuThreads,
"物理机 CPU 使用情况": format_cpu_speed(cpu_usage * 1000000 ),
"物理机总 CPU 资源": format_cpu_speed(total_cpu_resource * 1000000 ),
"物理机总内存": format_memory_size(total_memory),
"物理机内存使用情况": format_memory_size(memory_usage * (1024 * 1024) ),
"mem_available":format_memory_size(memAvailable),
"物理机总运行时长": format_time(uptime),
"物理机总存储空间大小": format_disk_size(total_storage_size_in_gb),
"物理机存储已用大小": format_disk_size(used_storage_size_in_gb),
"storage_available":format_disk_size(storageAvailable),
})
else:
host_information['status'] = "关机"
# return {
# "name": host.name,
# "hardware_model":host.hardware.systemInfo.model,
# "cpu_model":host.hardware.cpuPkg[0].description,
# "cpu_cores":host.hardware.cpuInfo.numCpuCores,
# "cpu_sockets":host.hardware.cpuInfo.numCpuPackages,
# "物理机逻辑处理器数量":host.summary.hardware.numCpuThreads,
# "物理机 CPU 使用情况":cpu_usage,
# "物理机总 CPU 资源":total_cpu_resource,
# "物理机总内存":format_memory_size(total_memory),
# "物理机内存使用情况":format_memory_size(memory_usage),
# "物理机总运行时长":format_time(uptime),
# "物理机总存储空间大小":format_disk_size(total_storage_size_in_gb),
# "物理机存储已用大小":format_disk_size(used_storage_size_in_gb),
# }
return host_information
# 虚拟机简略信息
def get_vm_template(si):
# 名称
# IP
# 操作系统
# CPU
# 内存
# 状态
# 所属物理机
content = si.RetrieveContent()
container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
vms = container.view
for vm in vms:
if vm.name == "Pro_10.252.100.102_2022-05-06_文件转码服务器":
print('VMname:', vm.name)
print('IP :{}'.format(vm.guest.ipAddress))
# print('操作系统:{}'.format(vm.guest.guestFullName))
# print("CPU:{}".format(vm.config.hardware.numCPU))
# print("内存大小: {:.0f} GB".format(vm.config.hardware.memoryMB / (1024)))
# print('虚拟机状态:{}'.format(vm.runtime.powerState))
# "poweredOn": 虚拟机已经开机并正在运行。"poweredOff": 虚拟机已经关机。"suspended": 虚拟机处于挂起状态
print('关联物理机:{}'.format(vm.runtime.host.name))
# 虚拟机开机
def power_on_vm(si,vm_name):
# 从已建立的连接中获取内容
content = si.RetrieveContent()
# 查找虚拟机
vm = None
container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
vms = container.view
for v in vms:
if v.name == vm_name:
vm = v
break
if vm:
# 检查虚拟机当前状态
if vm.runtime.powerState == "poweredOff":
# if vm.runtime.powerState == "poweredOn":
# 开机虚拟机
task = vm.PowerOnVM_Task()
# task = vm.PowerOffVM_Task()
# 等待操作完成
WaitForTasks(si, [task])
return f"虚拟机 '{vm_name}' 已开机"
else:
return f"虚拟机 '{vm_name}' 已处于开机状态"
else:
return f"找不到虚拟机 '{vm_name}'"
# 虚拟机关机
def power_off_vm(si,vm_name):
# 从已建立的连接中获取内容
content = si.RetrieveContent()
# 查找虚拟机
vm = None
container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
vms = container.view
for v in vms:
if v.name == vm_name:
vm = v
break
if vm:
# 检查虚拟机当前状态
if vm.runtime.powerState == "poweredOn":
# 开机虚拟机
task = vm.PowerOffVM_Task()
# 等待操作完成
WaitForTasks(si, [task])
return f"虚拟机 '{vm_name}' 已开机"
else:
return f"虚拟机 '{vm_name}' 已处于开机状态"
else:
return f"找不到虚拟机 '{vm_name}'"
# 虚拟机详细信息
def get_vm_details(si, vm_name):
content = si.RetrieveContent()
container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
vms = container.view
total_disk_capacity_gb = 0
total_disk_free_gb = 0
disk_block = 0
vm_information = {}
disk_data = {}
disk_data2 = []
for vm in vms:
if vm.name == vm_name:
vm_state = vm.runtime.powerState
if vm_state == "poweredOn":
vm_information['status'] = "开机"
else:
vm_information['status'] = "关机"
vm_information.update({
"name" : vm.name,
"IP" : vm.guest.ipAddress,
"system" : vm.config.guestFullName,
"cpu核数" : vm.config.hardware.numCPU,
"mem": format_memory_size(vm.config.hardware.memoryMB * 1024 * 1024),
"host":vm.runtime.host.name,
"cpu 使用":format_cpu_speed(vm.summary.quickStats.overallCpuUsage * 1000000),
"mem使用": format_memory_size(vm.summary.quickStats.guestMemoryUsage * 1024 * 1024 ),
})
# 磁盘类型
for device in vm.config.hardware.device:
if isinstance(device, vim.vm.device.VirtualDisk):
disk_capacity_kb = device.capacityInKB
total_disk_capacity_gb += disk_capacity_kb
# 硬盘块数统计
disk_block += 1
vm_information['硬盘块'] = disk_block
vm_information['总储存'] = format_disk_size(total_disk_capacity_gb * 1024)
# 硬盘详细情况
if isinstance(device.backing, vim.vm.device.VirtualDisk.FlatVer2BackingInfo):
if device.backing.thinProvisioned == True:
disk_data2.append({"disk名称" : device.deviceInfo.label,'disk大小':format_disk_size(disk_capacity_kb * 1024),"disk类型": "精简置备"})
else:
if device.backing.eagerlyScrub == None:
disk_data2.append({"disk名称" : device.deviceInfo.label,'disk大小':format_disk_size(disk_capacity_kb * 1024),"disk类型": "厚置备延迟置零"})
elif device.backing.eagerlyScrub == True:
disk_data2.append({"disk名称" : device.deviceInfo.label,'disk大小':format_disk_size(disk_capacity_kb * 1024),"disk类型": "厚置备快速置零"})
vm_information['disk'] = disk_data2
return vm_information
# 虚拟机删除
def delete_vms(si, vm_name):
content = si.RetrieveContent()
container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
vms = container.view
for vm in vms:
if vm.name == vm_name:
try:
if vm.runtime.powerState == "poweredOn":
# 如果虚拟机正在运行,首先关闭它
task = vm.PowerOff()
task_info = task.info
task_info.state = vim.TaskInfo.State.success
task_info.result = None
# print(f"等待虚拟机 {vm_name} 关机...")
WaitForTasks(si, [task])
# 删除虚拟机
task = vm.Destroy()
task_info = task.info
task_info.state = vim.TaskInfo.State.success
task_info.result = None
start_time = time.time()
while task_info.state != vim.TaskInfo.State.success:
if time.time() - start_time > 300: # 设置超时时间,单位秒
# raise Exception(f"删除虚拟机 {vm_name} 超时")
print({'code': 404, 'message': '虚拟机 %s 已超时5分钟' %vm_name})
time.sleep(5) # 每5秒检查一次任务状态
task_info = task.info
print({'code': 200, 'message': '虚拟机 %s 已成功删除' %vm_name})
except Exception as e:
print({'code': 404, 'message': ' %s' %e})
if __name__ == "__main__":
host='192.168.1.1'
user='administrator'
password='password'
port=443
si=test.connect_vsphere(host,user,password,port)
# 物理机详情
# print(test.get_host_template(si))
# 虚拟机简略信息
# print(test.get_vm_template(si))
# 虚拟机开机
# print(test.power_on_vm(si=si,vm_name="test-2"))
# 虚拟机关机
# print(test.power_off_vm(si=si,vm_name="test-2"))
# 虚拟机详细信息
# print(test.get_vm_details(si,'test-2'))
# 虚拟机删除
print(test.delete_vms(si,'test-2'))
# 断开与vCenter服务器的连接
Disconnect(si)