【vmware sdk】003、示例代码介绍

针对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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值