针对python,vmware提供了很多示例脚本,可以从https://github.com/vmware/pyvmomi-community-samples下载,里面的脚本有的用python2,有的用python3版本实现,而且对于vcenter的版本也没有说明,所以只能作为参考,使用之前还是要理清楚相关操作思路。
下面整理一些基本的需求,并进行代码示例说明。
自动化基本需求
1、列出所有资源类下的对象,比如看看所有的datacenter
2、找到指定的元素,比如一个虚拟机。
3、从某一个模板中创建一个虚拟机。
列出指定元素类的所有对象
说明: 使用viewManager从rootFolder向下遍历,取出所有的对象。
from pyVim import connect
from pyVmomi import vim
import atexit
# 获取service instance
service_instance = connect.SmartConnectNoSSL(host="xxx",
user="xxx",
pwd="xxx",
port=443)
# 退出执行销毁
atexit.register(connect.Disconnect, service_instance)
# 获取object data
content = service_instance.RetrieveContent()
# 资源类,只支持列表,可以写多个
obj_type_list = [vim.Datacenter]
"""
总结的受管对象种类有:
VirtualMachine
Datacenter
Folder
Datastore
Network
HostSystem
ResourcePool
ComputeResource
"""
# 获取指定类型的 managed object
objview = content.viewManager.CreateContainerView(content.rootFolder, obj_type_list, True)
# 打印所有资源的名字
for obj in objview.view:
print(obj.name)
执行结果:
办公生产
测试环境,禁止安装UAT机器
测试UAT
航科留守服务器
找到指定的对象
说明: 找到名为wjf_test的虚拟机。
方法1:
写循环遍历整个目录树。
from pyVim import connect
from pyVmomi import vim
import atexit
# 获取service instance
service_instance = connect.SmartConnectNoSSL(host="xxx",
user="xxx",
pwd="xxx",
port=443)
# 退出执行销毁
atexit.register(connect.Disconnect, service_instance)
# 获取object data
content = service_instance.RetrieveContent()
obj_type = vim.VirtualMachine
obj_name = 'wjf_test'
"""
总结的受管对象种类有:
VirtualMachine
Datacenter
Folder
Datastore
Network
HostSystem
ResourcePool
ComputeResource
"""
# 获取指定类型的 managed object
objview = content.viewManager.CreateContainerView(content.rootFolder, [obj_type], True)
# 遍历所有对象
for obj in objview.view:
# 设置过滤条件,满足条件的就是要找的对象
if obj.name == obj_name:
print('====', obj.parent.name)
print(obj.name)
break
执行结果:
==== vm
wjf_test
示例仅仅是通过对象的name就行查找,对于在全局命名可以重复的对象,if语句的过滤条件要多设置写,以保证得到的对象就是你要找到的对象,因为对于虚拟机命名是全局唯一的,因此可以唯一确定一个对象。
方法2:
service instance content 有一个search index的对象,可以根据一些维度在清单中快速搜索对象。
官方说明:https://code.vmware.com/apis/42/vsphere/doc/vim.SearchIndex.html
from pyVim import connect
from pyVmomi import vim
import atexit
# 获取service instance
service_instance = connect.SmartConnectNoSSL(host="99.48.210.219",
user="administrator@vsphere.local",
pwd="P@ss1234",
port=443)
# 退出执行销毁
atexit.register(connect.Disconnect, service_instance)
# 获取object data
content = service_instance.RetrieveContent()
# 获取所有的datacenter对象
dc_all = content.viewManager.CreateContainerView(content.rootFolder, [vim.Datacenter], True)
# 在每一个datacenter中寻找
for dc_one in dc_all.view:
vm = content.searchIndex.FindByIp(dc_one, '99.48.212.50', True)
if vm:
print(vm.name)
"""
content.searchIndex服务提供了在几个在一个datacenter中检索对象的方法:
FindByIp
FindAllByaIp
等
"""
执行结果:
Public-Uat-Centos7.2-Rundeck-99.48.212.50
从某一个模板中创建一个虚拟机
示例代码:
from pyVmomi import vim
from pyVim.connect import SmartConnectNoSSL, Disconnect
import atexit
def wait_for_task(task):
""" wait for a vCenter task to finish """
task_done = False
while not task_done:
if task.info.state == 'success':
return task.info.result
if task.info.state == 'error':
print("there was an error")
print(task.info.error.msg)
task_done = True
# 获取一个受管对象
# 该函数若取全局名称不唯一的对象,则默认规则是取第一个符合规则的对象,可能会出问题,生产使用需要修复
def get_obj(content, vimtype, name):
"""
Return an object by name, if name is None the
first found object is returned
"""
obj = None
container = content.viewManager.CreateContainerView(
content.rootFolder, vimtype, True)
for c in container.view:
if name:
if c.name == name:
obj = c
break
else:
obj = c
break
return obj
def clone_vm(content, template, vm_name, datacenter_name, vm_folder, datastore_name, resource_pool, power_on):
"""
Clone a VM from a template/VM, datacenter_name, vm_folder, datastore_name
cluster_name, resource_pool, and power_on are all optional.
"""
# if none git the first one
datacenter = get_obj(content, [vim.Datacenter], datacenter_name)
if vm_folder:
destfolder = get_obj(content, [vim.Folder], vm_folder)
else:
destfolder = datacenter.vmFolder
if datastore_name:
datastore = get_obj(content, [vim.Datastore], datastore_name)
else:
datastore = get_obj(
content, [vim.Datastore], template.datastore[0].info.name)
if resource_pool:
resource_pool = get_obj(content, [vim.ResourcePool], resource_pool)
# set relospec
relospec = vim.vm.RelocateSpec()
relospec.datastore = datastore
relospec.pool = resource_pool
clonespec = vim.vm.CloneSpec()
clonespec.location = relospec
clonespec.powerOn = power_on
print("cloning VM...")
task = template.CloneVM_Task(folder=destfolder, name=vm_name, spec=clonespec)
wait_for_task(task)
# 临时使用的参数定义类
class Args():
def __init__(self):
self.no_ssl = True
# 连接信息
self.host = 'xxxx'
self.user = 'xxxx'
self.password = 'xxxx'
self.port = 443
# 新建虚机名称
self.vm_name = 'wjf_test_03'
# 新建虚机的datacenter位置
self.datacenter_name = '测试UAT'
# 新建虚机的folder位置
self.vm_folder = ''
# 新建虚机的datastore的位置
self.datastore_name = 'datastore232'
# 新建虚机的资源池位置
self.resource_pool = '210.63'
# 新建虚机是否开机启动
self.power_on = False
# 模板名称
self.template = 'temp-centos7.2--optimization-v8'
# 主函数
if __name__ == "__main__":
# 初始化参数
args = Args()
# 获取service instance
si = SmartConnectNoSSL(
host=args.host,
user=args.user,
pwd=args.password,
port=args.port)
atexit.register(Disconnect, si)
# 获取service instance content
content = si.RetrieveContent()
# 根据模板名称获取模板对象
template = get_obj(content, [vim.VirtualMachine], args.template)
# 如果模板存在,则开始从模板克隆虚拟机
if template:
clone_vm(content, template, args.vm_name, args.datacenter_name, args.vm_folder,
args.datastore_name, args.resource_pool, args.power_on)
对于创建虚拟机这样一个任务,如何从官方文档中查找出相关的操作步骤:
1、先通过API文档,在all methods中找到自己要用的task:
https://code.vmware.com/apis/42/vsphere/doc/index-methods.html
比如,先找到clonVM_Task的定义。
2、查看具体task的调用参数:
对于比如spec这类参数,依次级联进去,查看里面嵌套的data object即可。
比如clonVm_task---->virtualMachineClonSpec------>VirtualMachineRelocateSpec。
3、编程序阶段
# 摘抄自上面的代码
# 实例化一个空的RelocateSpec对象
relospec = vim.vm.RelocateSpec()
# 根据需要,设置里面的个别属性值,从文档中可知,datastore需要使用MOR赋值
relospec.datastore = datastore
relospec.pool = resource_pool
# 实例化一个空的CloneSpec配置对象
clonespec = vim.vm.CloneSpec()
# 对其中的属性就行赋值
clonespec.location = relospec
clonespec.powerOn = power_on
print("cloning VM...")
# 调用task任务,将上面准备的参数对象传入任务即可
task = template.CloneVM_Task(folder=destfolder, name=vm_name, spec=clonespec)
# task都是异步执行的,此时可以在vsphere中看到任务执行状态了,代码层可以等待也可以不等待。
wait_for_task(task)
SSL connect
以上都是使用nossl方式连接,如果用ssl方式,改写如下
import ssl
# ssl
ssl_context = None
if hasattr(ssl, "_create_unverified_context"):
ssl_context = ssl._create_unverified_context()
# 获取service instance
service_instance = connect.SmartConnect(host="xxx",
user="xxx",
pwd="xxx",
port=443,
sslContext=ssl_context)
######或者
import ssl
# ssl
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
# 获取service instance
service_instance = connect.SmartConnect(host="xxx",
user="xxxx",
pwd="xxxx",
port=443,
sslContext=ssl_context)
from pyVim import connect
from pyVmomi import vim
import atexit
class vmHandler:
def __init__(self):
self.__host = "xxxx"
self.__port = 443
self.__user = "xxxx"
self.__pwd = "xxxx"
self.__si = self.get_si()
self.__conent = self.__si.RetrieveContent()
self.all_resouce_type = {
"vm": vim.VirtualMachine,
"dc": vim.Datacenter,
"ds": vim.Datastore,
"rp": vim.ResourcePool
}
def get_si(self):
# 获取service instance
service_instance = connect.SmartConnectNoSSL(host=self.__host,
user=self.__user,
pwd=self.__pwd,
port=self.__port)
return service_instance
def get_all_resource_type(self, resource_type):
if resource_type not in self.all_resouce_type.keys():
return {}
obj_type_list = [self.all_resouce_type.get(resource_type)]
objview = self.__conent.viewManager.CreateContainerView(self.__conent.rootFolder, obj_type_list, True)
return objview.view
def get_object_by_name(self, resource_type, object_name):
if resource_type not in self.all_resouce_type.keys():
return {}
obj_type_list = [self.all_resouce_type.get(resource_type)]
objview = self.__conent.viewManager.CreateContainerView(self.__conent.rootFolder, obj_type_list, True)
for obj in objview.view:
if obj.name == object_name:
return obj
return {}
def clone_vm_from_template(self, template_name, vm_name, customization_spec=None):
template_vm = self.get_object_by_name("vm", template_name)
# 获取目录
datacenter = self.get_object_by_name("dc", "dc_name")
destfolder = datacenter.vmFolder
resource_pool = self.get_object_by_name("rp", "Resources")
# set relospec
relospec = vim.vm.RelocateSpec()
relospec.pool = resource_pool
clonespec = vim.vm.CloneSpec()
clonespec.location = relospec
# 自定义规范
if customization_spec:
clonespec.customization = customization_spec
print("cloning VM...")
task = template_vm.CloneVM_Task(folder=destfolder, name=vm_name, spec=clonespec)
return task
def vm_custormization(self):
pass
def modify_cpu(self, vm_name, cpu_num):
vm = self.get_object_by_name("vm", vm_name)
configSpec = vim.vm.ConfigSpec()
configSpec.numCPUs = cpu_num
task = vm.ReconfigVM_Task(spec=configSpec)
return task
def modify_memorysize(self, vm_name, memory_zie):
vm = self.get_object_by_name("vm", vm_name)
configSpec = vim.vm.ConfigSpec()
configSpec.memoryMB = memory_zie
task = vm.ReconfigVM_Task(spec=configSpec)
return task
def power_ctl(self, vm_name, ctl="on"):
vm = self.get_object_by_name("vm", vm_name)
if ctl == "off":
task = vm.PowerOffVM_Task()
else:
task = vm.PowerOnVM_Task()
return task
def destory_vm(self, vm_name):
vm = self.get_object_by_name("vm", vm_name)
task = vm.Destroy_Task()
return task
def get_customization_setting(self, customization_name, ip, hostname):
customization_manager = self.__conent.customizationSpecManager
custom_spec = None
try:
customization_item = customization_manager.GetCustomizationSpec(customization_name)
custom_spec = customization_item.spec
# 设置ip
custom_fixip = vim.vm.customization.FixedIp()
custom_fixip.ipAddress = ip
# 设置主机名
custom_hostname = vim.vm.customization.FixedName()
custom_hostname.name = hostname
# 修改配置
custom_spec.identity.hostName = custom_hostname
custom_spec.nicSettingMap[0].adapter.ip = custom_fixip
except Exception as e:
print(str(e))
return custom_spec
def add_new_raw_disk(self, vm_name, size_gb):
vm = self.get_object_by_name("vm", vm_name)
# 获取当前控制器号码,以及生成新的unit_number
for dev in vm.config.hardware.device:
if hasattr(dev.backing, 'fileName'):
unit_number = int(dev.unitNumber) + 1
# unit_number 7 reserved for scsi controller
if unit_number == 7:
unit_number += 1
if unit_number >= 16:
print("we don't support this many disks")
return
if isinstance(dev, vim.vm.device.VirtualSCSIController):
controller = dev
spec = vim.vm.ConfigSpec()
# 虚拟设备配置
device_spec = vim.vm.device.VirtualDeviceSpec()
device_spec.fileOperation = "create"
device_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
# 磁盘配置
disk_spec = vim.vm.device.VirtualDisk()
disk_spec.capacityInKB = 1024 * 1024 * int(size_gb)
device_spec.device = disk_spec
# 设置控制器相关
device_spec.device.unitNumber = unit_number
device_spec.device.controllerKey = controller.key
# 后台文件相关
backing_file = vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
device_spec.device.backing = backing_file
device_spec.device.backing.diskMode = "persistent"
device_spec.device.backing.thinProvisioned = True
device_spec.device.backing.writeThrough = True
# 应用更改
spec.deviceChange = [device_spec]
task = vm.ReconfigVM_Task(spec=spec)
return task
if __name__ == "__main__":
pass