Vsphere接口调研

参考项目: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)

你可能感兴趣的:(Vsphere接口调研)