参考项目:https://github.com/vmware/pyvmomi-community-samples
参考链接:https://code.vmware.com/web/dp/explorer-apis?id=197
准备开发环境
1. Installed python
2. Installed pip
3. Install pyvmomi using pip
$ pip install pyvmomi
现在已经可以使用vsphere提供的api,进行基本的操作了。
# 创建虚拟机流程
1. 跨过认证
from pyVim import connect
import atexit
#获取连接对象
si = connect.SmartConnectNoSSL(host=args.host,
user=args.user,
pwd=args.password,
port=int(args.port))
#断开连接
atexit.register(connect.Disconnect, si)
2. 创建虚拟机(只包含内存,cpu,网卡)
from pyVmomi import vim
from tools import tasks
def get_obj(content, vimtype, name):
obj = None
container = content.viewManager.CreateContainerView(
content.rootFolder, vimtype, True)
for c in container.view:
if c.name == name:
obj = c
break
return obj
#添加网卡配置
def add_nic_spec(si, config_spec, network):
nic_changes = []
nic_spec = vim.vm.device.VirtualDeviceSpec()
nic_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
nic_spec.device = vim.vm.device.VirtualE1000()
nic_spec.device.deviceInfo = vim.Description()
nic_spec.device.deviceInfo.summary = 'vCenter API test'
nic_spec.device.backing = \
vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()
nic_spec.device.backing.useAutoDetect = False
content = si.RetrieveContent()
nic_spec.device.backing.network = get_obj(content, [vim.Network], network)
nic_spec.device.backing.deviceName = network
nic_spec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
nic_spec.device.connectable.startConnected = True
nic_spec.device.connectable.startConnected = True
nic_spec.device.connectable.allowGuestControl = True
nic_spec.device.connectable.connected = True
nic_spec.device.connectable.status = 'untried'
nic_spec.device.wakeOnLanEnabled = True
nic_spec.device.addressType = 'generated'
nic_changes.append(nic_spec)
config_spec.deviceChange = nic_changes
return config_spec
def create_dummy_vm(name, si, vm_folder, resource_pool, datastore):
#定义vm存储目录
datastore_path = '[' + datastore + '] ' + vm_name
# bare minimum VM shell, no disks. Feel free to edit
vmx_file = vim.vm.FileInfo(logDirectory=None,
snapshotDirectory=None,
suspendDirectory=None,
vmPathName=datastore_path)
#配置vm boot配置
config = vim.vm.ConfigSpec(name=name, memoryMB=1048, numCPUs=1, files=vmx_file, guestId='centos7_64Guest',
version='vmx-13')
config = add_nic_spec(si, config, network='Ceph_Net')
#创建虚拟机
task = vm_folder.CreateVM_Task(config=config, pool=resource_pool)
tasks.wait_for_tasks(si, [task])
content = si.RetrieveContent()
datacenter = content.rootFolder.childEntity[0]
vmfolder = datacenter.vmFolder
hosts = datacenter.hostFolder.childEntity
resource_pool = hosts[0].resourcePool
name = "test_vm02"
create_dummy_vm(name, service_instance, vmfolder, resource_pool,
args.datastore)
3. 挂载磁盘到虚拟机
from pyVmomi import vim
from tools import tasks
from pyVim.task import WaitForTask
def get_obj(content, vimtype, name):
obj = None
container = content.viewManager.CreateContainerView(
content.rootFolder, vimtype, True)
for c in container.view:
if c.name == name:
obj = c
break
return obj
def add_scsi_device_to_vm(vm):
"""
add scsi device to a virtual machine
:param vm: virtual machine object
:return: scsi configuration
:TBD
"""
spec = vim.vm.ConfigSpec()
scsi_ctr = vim.vm.device.VirtualDeviceSpec()
scsi_ctr.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
scsi_ctr.device = vim.vm.device.VirtualLsiLogicController()
scsi_ctr.device.deviceInfo = vim.Description()
scsi_ctr.device.unitNumber = 3
scsi_ctr.device.busNumber = 0
scsi_ctr.device.hotAddRemove = True
scsi_ctr.device.sharedBus = 'noSharing'
scsi_ctr.device.scsiCtlrUnitNumber = 7
spec.deviceChange = [scsi_ctr]
LOGGER.info("SCSI device added to %s", vm.config.name)
return scsi_ctr
def add_disk(vm, si, disk_size, disk_type):
spec = vim.vm.ConfigSpec()
scsi_ctr = add_scsi_device_to_vm(vm)
controller = scsi_ctr.device
# get all disks on a VM, set unit_number to the next available
unit_number = 0
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
# add disk here
dev_changes = []
new_disk_kb = int(disk_size) * 1024 * 1024
disk_spec = vim.vm.device.VirtualDeviceSpec()
disk_spec.fileOperation = "create"
disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
disk_spec.device = vim.vm.device.VirtualDisk()
disk_spec.device.backing = \
vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
if disk_type == 'thin':
disk_spec.device.backing.thinProvisioned = True
disk_spec.device.backing.diskMode = 'persistent'
disk_spec.device.unitNumber = unit_number
disk_spec.device.capacityInKB = new_disk_kb
disk_spec.device.controllerKey = controller.key
dev_changes.append(disk_spec)
spec.deviceChange = dev_changes
task = vm.ReconfigVM_Task(spec=spec)
tasks.wait_for_tasks(si, [task])
#通过vm uuid过滤虚拟机
search_index = si.content.searchIndex
vm = search_index.FindByUuid(None, args.uuid, True, True)
#挂载磁盘(磁盘大小单位GB,类型可选项:thin,thick)
# thin:虚拟硬盘实际大小随着使用量而浮动,直到使用到硬盘分配上限
# thick:创建虚拟硬盘是一次性分配完全
add_disk(vm, si, args.disk_size, args.disk_type)
4. 挂载CD_ROM到虚拟机
#判断vm是否已经挂载CD-Rom
def check_vm_cdrom(vm):
for device in vm.config.hardware.device:
if isinstance(device, vim.vm.device.VirtualCdrom):
return device
return None
#查找设备控制器
def find_free_ide_controller(vm):
for dev in vm.config.hardware.device:
if isinstance(dev, vim.vm.device.VirtualIDEController):
# If there are less than 2 devices attached, we can use it.
if len(dev.device) < 2:
return dev
return None
#生成CD-Rom配置
def new_cdrom_spec(controller_key, backing):
connectable = vim.vm.device.VirtualDevice.ConnectInfo()
connectable.allowGuestControl = True
connectable.startConnected = True
cdrom = vim.vm.device.VirtualCdrom()
cdrom.controllerKey = controller_key
cdrom.key = -1
cdrom.connectable = connectable
cdrom.backing = backing
return cdrom
search_index = si.content.searchIndex
#获取vm_obj,需要传入参数vm_uuid
vm = search_index.FindByUuid(None, uuid, True ,True)
if vm is None:
raise Exception('Failed to find VM %s in datacenter %s' %
(dc.name, args.name))
controller = find_free_ide_controller(vm)
if controller is None:
raise Exception('Failed to find a free slot on the IDE controller')
cdrom = check_vm_cdrom(vm)
op = vim.vm.device.VirtualDeviceSpec.Operation
iso = args.iso
if iso is not None:
deviceSpec = vim.vm.device.VirtualDeviceSpec()
if cdrom is None: # add a cdrom
print("Adding a new cd-Rom......")
backing = vim.vm.device.VirtualCdrom.IsoBackingInfo(fileName=iso)
cdrom = new_cdrom_spec(controller.key, backing)
deviceSpec.operation = op.add
else: # edit an existing cdrom
print("Updating a old cd-Rom......")
backing = vim.vm.device.VirtualCdrom.IsoBackingInfo(fileName=iso)
cdrom.backing = backing
deviceSpec.operation = op.edit
deviceSpec.device = cdrom
configSpec = vim.vm.ConfigSpec(deviceChange=[deviceSpec])
WaitForTask(vm.Reconfigure(configSpec))
cdroms = find_device(vm, vim.vm.device.VirtualCdrom)
cdrom = filter(lambda x: type(x.backing) == type(backing) and
x.backing.fileName == iso, cdroms)[0]
else:
print('Skipping ISO test as no iso provided.')
# 获取虚拟机列表及详情
from pyVmomi import vim
#打印虚拟机详情
def print_vm_info(virtual_machine):
"""
Print information for a particular virtual machine or recurse into a
folder with depth protection
"""
summary = virtual_machine.summary
print("Name : ", summary.config.name)
print("Template : ", summary.config.template)
print("Path : ", summary.config.vmPathName)
print("Guest : ", summary.config.guestFullName)
print("Instance UUID : ", summary.config.instanceUuid)
print("Bios UUID : ", summary.config.uuid)
annotation = summary.config.annotation
if annotation:
print("Annotation : ", annotation)
print("State : ", summary.runtime.powerState)
if summary.guest is not None:
ip_address = summary.guest.ipAddress
tools_version = summary.guest.toolsStatus
if tools_version is not None:
print("VMware-tools: ", tools_version)
else:
print("Vmware-tools: None")
if ip_address:
print("IP : ", ip_address)
else:
print("IP : None")
if summary.runtime.question is not None:
print("Question : ", summary.runtime.question.text)
print("")
#获取所有虚拟机对象
content = si.RetrieveContent()
container = content.rootFolder # starting point to look into
viewType = [vim.VirtualMachine] # object types to look for
recursive = True # whether we should look into it recursively
containerView = content.viewManager.CreateContainerView(container, viewType, recursive)
#遍历虚拟机列表打印虚拟机详情
children = containerView.view
for child in children:
print_vm_info(child)