Python pyvmomi operation VMware (7): According to the template clone virtual machine (type is Windows), specify IP, host name and other information

Background : When the virtual machine cloned by the customer is of the Windows type, and information such as IP and host name must be specified.
Question : According to the previous cloning method, when the template is found to be of the Windows type, how to specify the host name fails, and an error message: The specified parameter is incorrect: spec.identity
process : After studying the official document, I found a more interesting thing, which is Clone specifies some configuration information. Windows and Linux are distinguished. When the template is Windows, the identity uses the Sysprep configuration; when the template is Linux and other systems, the identity uses the LinuxPrep configuration.
Insert picture description here
The configuration information of Sysprep is as follows: Insert picture description here
here the previous clone IP configuration information function is modified:
selective cloning is performed according to the system type of the template

    def get_customspec(self, template, vm_ip=None, vm_subnetmask=None, vm_gateway=None, vm_dns=None,
                       vm_domain=None, vm_hostname=None):
        """
        IP等信息的配置函数
        :param template: 模板对象
        :param vm_ip:
        :param vm_subnetmask:
        :param vm_gateway:
        :param vm_dns:
        :param vm_domain:
        :param vm_hostname:
        :return:
        """
        adaptermaps = []
        guest_map = vim.vm.customization.AdapterMapping()
        guest_map.adapter = vim.vm.customization.IPSettings()
        guest_map.adapter.ip = vim.vm.customization.FixedIp()
        guest_map.adapter.ip.ipAddress = vm_ip
        guest_map.adapter.subnetMask = vm_subnetmask
        guest_map.adapter.gateway = vm_gateway
        if vm_domain:
            guest_map.adapter.dnsDomain = vm_domain
        adaptermaps.append(guest_map)

        # DNS settings
        globalip = vim.vm.customization.GlobalIPSettings()
        if vm_dns:
            if vm_dns.find(',') > -1:
                globalip.dnsServerList = vm_dns.split(',')
            else:
                globalip.dnsServerList = [vm_dns]
            globalip.dnsSuffixList = vm_domain

        # Hostname settings
        # 如果模板是windows
        if 'windows' in template.config.guestId:
            ident = vim.vm.customization.Sysprep()
            ident.userData = vim.vm.customization.UserData()
            ident.userData.computerName = vim.vm.customization.FixedName()
            if vm_hostname:
                ident.userData.computerName.name = vm_hostname
                ident.userData.fullName = 'Administrator'
                ident.userData.orgName = 'Administrators'

            ident.guiUnattended = vim.vm.customization.GuiUnattended()
            ident.identification = vim.vm.customization.Identification()
            if vm_domain:
                ident.identification.domainAdmin = vm_domain

        else:
            # 如果模板不是windows
            ident = vim.vm.customization.LinuxPrep()
            if vm_domain:
                ident.domain = vm_domain
            ident.hostName = vim.vm.customization.FixedName()
            if vm_hostname:
                ident.hostName.name = vm_hostname

        customspec = vim.vm.customization.Specification()
        customspec.nicSettingMap = adaptermaps
        customspec.globalIPSettings = globalip
        customspec.identity = ident
        return customspec

    def clone(self, template_name, vm_name, datacenter_name,
              datastore_name, vm_exi_ip, vm_folder=None,
              cup_num=None, memory=None, vm_disk=None, vm_ip=None,
              vm_subnetmask=None, vm_gateway=None, vm_dns=None,
              vm_domain=None, vm_hostname=None,
              vm_vlan=None, switch_type=None):
        # 获取模版
        template = self._get_obj([vim.VirtualMachine], template_name)
        # 模版不存在
        if template is None:
            return {'message': u'克隆失败: 模版不存在', 'result': False}
        # 选择克隆的虚拟机存放位置,通过数据中心获取对象
        datacenter = self._get_obj([vim.Datacenter], datacenter_name)
        # 数据中心不存在
        if datacenter is None:
            return {'message': u'克隆失败: 数据中心不存在', 'result': False}
        # vm创建路径
        if vm_folder:
            vmfolder = self._get_obj([vim.Folder], vm_folder)
        else:
            vmfolder = datacenter.vmFolder

        # 获取存储
        if datastore_name:
            datastore = self.get_datastore_by_name(datastore_name, datacenter)
            if datastore is None:
                return {'message': u'克隆失败: 该数据中心下%s存储不存在' % datastore_name, 'result': False}
        else:
            datastore = self.get_datastore_by_name(template.datastore[0].info.name, datacenter)
            if datastore is None:
                return {'message': u'克隆失败: 该数据中心下%s模版不存在' % template_name, 'result': False}
        # 获取宿主机
        host = self.get_host_by_name(vm_exi_ip, datastore)
        if host is None:
            return {'message': u'克隆失败: 该存储下%s主机不存在' % vm_exi_ip, 'result': False}
        # 获取宿主机下的vm
        vms = host.vm
        for vm in vms:
            config = vm.summary.config
            if vm_name == config.name:
                return {'message': u'克隆失败: 虚拟机%s已经存在' % vm_name, 'result': False}
        # 获取资源池
        resourcepool = host.parent.resourcePool
        relospec = vim.vm.RelocateSpec()
        relospec.datastore = datastore
        relospec.pool = resourcepool
        relospec.host = host
        # 配置Clone属性
        clonespec = vim.vm.CloneSpec()
        clonespec.location = relospec
        clonespec.powerOn = True
        device_change = []
        # 设置网卡
        if len(template.network) == 0:
            logger.info(u'设置网卡')
            nic_change = self.add_nic('VM Network')
            device_change.extend(nic_change)
        # 指定网络段配置
        if vm_vlan:
            device_nic_change = self.device_nic(
                vm=template,
                network_name=vm_vlan,
                switch_type=switch_type
            )
            device_change.extend(device_nic_change)
        # 修改硬盘大小
        if vm_disk:
            logger.info(u'追加硬盘')
            # disk_change = self.add_disk(template, vm_disk)
            # if type(disk_change) is list:
            #     device_change.extend(disk_change)
            # else:
            #     return {'message': disk_change, 'result': False}

            disk_change = self.change_disk_size(template, vm_disk)
            if type(disk_change) is list:
                device_change.extend(disk_change)
            else:
                return {'message': disk_change, 'result': False}

        # 更新配置
        vmconf = vim.vm.ConfigSpec(deviceChange=device_change)
        logger.info(u'更新网卡网卡的配置')
        # 设置IP
        if all([vm_ip, vm_subnetmask, vm_gateway]):
            clonespec.customization = self.get_customspec(template, vm_ip, vm_subnetmask, vm_gateway, vm_dns, vm_domain,
                                                          vm_hostname)
            logger.info(u'设置IP')
        # 更改cpu和内存
        if cup_num:
            vmconf.numCPUs = cup_num
        if memory:
            vmconf.memoryMB = memory * 1024
        if vmconf is not None:
            clonespec.config = vmconf
        # 开始克隆
        task = template.Clone(folder=vmfolder, name=vm_name, spec=clonespec)

Guess you like

Origin blog.csdn.net/qq_42631707/article/details/108243646