Ejemplo n.º 1
0
    def instantiate_vapp(self,
                         name,
                         catalog,
                         template,
                         network=None,
                         fence_mode='bridged',
                         ip_allocation_mode='dhcp',
                         deploy=True,
                         power_on=True,
                         accept_all_eulas=True,
                         memory=None,
                         cpu=None,
                         password=None,
                         cust_script=None,
                         identical=False):
        """
        Instantiate a vApp from a vApp template.
        :param name: (str): The name of the new vApp.
        :param catalog: (str): The name of the catalog.
        :param template: (str): The name of the vApp template.
        :param identical: (bool): If True, no guest customization or VM name update is performed
        :return:  A :class:`lxml.objectify.StringElement` object describing the new vApp.
        """  # NOQA
        if self.resource is None:
            self.resource = self.client.get_resource(self.href)
        network_href = None
        if hasattr(self.resource, 'AvailableNetworks') and \
           hasattr(self.resource.AvailableNetworks, 'Network'):
            for n in self.resource.AvailableNetworks.Network:
                if network is None or network == n.get('name'):
                    network_href = n.get('href')
                    network_name = n.get('name')
        if network_href is None:
            raise Exception('Network not found in the Virtual Datacenter.')
        org_href = find_link(self.resource, RelationType.UP,
                             EntityType.ORG.value).href
        org = Org(self.client, href=org_href)
        template_resource = org.get_catalog_item(catalog, template)
        v = self.client.get_resource(template_resource.Entity.get('href'))
        n = v.xpath(
            '//ovf:NetworkSection/ovf:Network',
            namespaces={'ovf': 'http://schemas.dmtf.org/ovf/envelope/1'})
        assert len(n) > 0
        network_name_from_template = n[0].get(
            '{http://schemas.dmtf.org/ovf/envelope/1}name')
        deploy_param = 'true' if deploy else 'false'
        power_on_param = 'true' if power_on else 'false'
        network_configuration = E.Configuration(
            E.ParentNetwork(href=network_href), E.FenceMode(fence_mode))
        # if fence_mode == 'natRouted':
        #     network_configuration.append(
        #         E.Features(
        #             E.NatService(
        #                 E.IsEnabled('true'),
        #                 E.NatType('ipTranslation'),
        #                 E.Policy('allowTraffic'),
        #                 E.NatRule(
        #                     E.OneToOneVmRule(
        #                         E.MappingMode('automatic'),
        #                         E.VAppScopedVmId(vm_id),
        #                         E.VmNicId(0)
        #                     )
        #                 )
        #             )
        #         )
        #     )
        vapp_network_name = network_name_from_template
        if vapp_network_name == 'none':
            vapp_network_name = network_name
        vapp_template_params = E.InstantiateVAppTemplateParams(
            name=name, deploy=deploy_param, powerOn=power_on_param)
        if network_name is not None:
            vapp_template_params.append(
                E.InstantiationParams(
                    E.NetworkConfigSection(
                        E_OVF.Info('Configuration for logical networks'),
                        E.NetworkConfig(network_configuration,
                                        networkName=vapp_network_name))))
        vapp_template_params.append(
            E.Source(href=template_resource.Entity.get('href')))
        vm = v.xpath('//vcloud:VAppTemplate/vcloud:Children/vcloud:Vm',
                     namespaces=NSMAP)
        assert len(vm) > 0
        ip = E.InstantiationParams()
        if not identical:
            gc = E.GuestCustomizationSection(
                E_OVF.Info('Specifies Guest OS Customization Settings'),
                E.Enabled('false'),
            )
            if password is not None:
                gc.append(E.AdminPasswordEnabled('true'))
                gc.append(E.AdminPasswordAuto('false'))
                gc.append(E.AdminPassword(password))
                gc.append(E.ResetPasswordRequired('false'))
            else:
                gc.append(E.AdminPasswordEnabled('false'))
            if cust_script is not None:
                gc.append(E.CustomizationScript(cust_script))
            gc.Enabled = E.Enabled('true')
            gc.append(E.ComputerName(name))
            ip.append(gc)
        primary_index = int(
            vm[0].NetworkConnectionSection.PrimaryNetworkConnectionIndex.text)
        ip.append(
            E.NetworkConnectionSection(
                E_OVF.Info('Specifies the available VM network connections'),
                E.NetworkConnection(E.NetworkConnectionIndex(primary_index),
                                    E.IsConnected('true'),
                                    E.IpAddressAllocationMode(
                                        ip_allocation_mode.upper()),
                                    network=vapp_network_name)))
        if memory is not None:
            items = v.Children[0].Vm.xpath(
                '//ovf:VirtualHardwareSection/ovf:Item',
                namespaces={'ovf': 'http://schemas.dmtf.org/ovf/envelope/1'})
            for item in items:
                if item['{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ResourceType'] == 4:  # NOQA
                    item[
                        '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ElementName'] = '%s MB of memory' % memory  # NOQA
                    item[
                        '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}VirtualQuantity'] = memory  # NOQA
                    memory_params = item
                    break
        if cpu is not None:
            items = v.Children[0].Vm.xpath(
                '//ovf:VirtualHardwareSection/ovf:Item',
                namespaces={'ovf': 'http://schemas.dmtf.org/ovf/envelope/1'})
            for item in items:
                if item['{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ResourceType'] == 3:  # NOQA
                    item[
                        '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ElementName'] = '%s virtual CPU(s)' % cpu  # NOQA
                    item[
                        '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}VirtualQuantity'] = cpu  # NOQA
                    cpu_params = item
                    break

        if memory is not None or cpu is not None:
            vhs = E_OVF.VirtualHardwareSection(
                E_OVF.Info('Virtual hardware requirements'))
            if memory is not None:
                vhs.append(memory_params)
            if cpu is not None:
                vhs.append(cpu_params)
            ip.append(vhs)

        if identical or (password is None and cust_script is None):
            needs_customization = 'false'
        else:
            needs_customization = 'true'
        si = E.SourcedItem(
            E.Source(href=vm[0].get('href'),
                     id=vm[0].get('id'),
                     name=vm[0].get('name'),
                     type=vm[0].get('type')))
        if not identical:
            si.append(
                E.VmGeneralParams(E.Name(name),
                                  E.NeedsCustomization(needs_customization)))
        si.append(ip)
        # if network_name != network_name_from_template:
        #     si.append(E.NetworkAssignment(
        #         innerNetwork=network_name_from_template,
        #         containerNetwork=network_name))
        vapp_template_params.append(si)
        all_eulas_accepted = 'true' if accept_all_eulas else 'false'
        vapp_template_params.append(E.AllEULAsAccepted(all_eulas_accepted))
        return self.client.post_resource(
            self.href + '/action/instantiateVAppTemplate',
            vapp_template_params,
            EntityType.INSTANTIATE_VAPP_TEMPLATE_PARAMS.value)
Ejemplo n.º 2
0
    def to_sourced_item(self, spec):
        """Creates a VM SourcedItem from a VM specification.

        :param spec: (dict) containing:
            vapp: (resource): (required) source vApp or vAppTemplate resource
            source_vm_name: (str): (required) source VM name
            target_vm_name: (str): (optional) target VM name
            hostname: (str): (optional) target guest hostname
            password: (str): (optional) set the administrator password of this
                machine to this value
            password_auto: (bool): (optional) autogenerate administrator
                password
            password_reset: (bool): (optional) True if the administrator
                password for this virtual machine must be reset after first use
            cust_script: (str): (optional) script to run on guest customization
            network: (str): (optional) Name of the vApp network to connect.
                If omitted, the VM won't be connected to any network
            storage_profile: (str): (optional) the name of the storage profile
                to be used for this VM

        :return: SourcedItem: (:class:`lxml.objectify.StringElement`): object
            representing the 'SourcedItem' xml object created from the
            specification.
        """
        source_vapp = VApp(self.client, resource=spec['vapp'])
        source_vm_resource = source_vapp.get_vm(spec['source_vm_name'])

        sourced_item = E.SourcedItem(
            E.Source(href=source_vm_resource.get('href'),
                     id=source_vm_resource.get('id'),
                     name=source_vm_resource.get('name'),
                     type=source_vm_resource.get('type')))

        vm_general_params = E.VmGeneralParams()
        if 'target_vm_name' in spec:
            vm_general_params.append(E.Name(spec['target_vm_name']))

        vm_instantiation_param = E.InstantiationParams()
        if 'network' in spec:
            primary_index = int(source_vm_resource.NetworkConnectionSection.
                                PrimaryNetworkConnectionIndex.text)
            if 'ip_allocation_mode' in spec:
                ip_allocation_mode = spec['ip_allocation_mode']
            else:
                ip_allocation_mode = 'DHCP'
            vm_instantiation_param.append(
                E.NetworkConnectionSection(
                    E_OVF.Info(),
                    E.NetworkConnection(
                        E.NetworkConnectionIndex(primary_index),
                        E.IsConnected(True),
                        E.IpAddressAllocationMode(ip_allocation_mode.upper()),
                        network=spec['network'])))

        needs_customization = 'disk_size' in spec or 'password' in spec or \
            'cust_script' in spec or 'hostname' in spec
        if needs_customization:
            guest_customization_param = E.GuestCustomizationSection(
                E_OVF.Info(),
                E.Enabled(True),
            )
            if 'password' in spec:
                guest_customization_param.append(E.AdminPasswordEnabled(True))
                guest_customization_param.append(E.AdminPasswordAuto(False))
                guest_customization_param.append(
                    E.AdminPassword(spec['password']))
            else:
                if 'password_auto' in spec:
                    guest_customization_param.append(
                        E.AdminPasswordEnabled(True))
                    guest_customization_param.append(E.AdminPasswordAuto(True))
                else:
                    guest_customization_param.append(
                        E.AdminPasswordEnabled(False))
            if 'password_reset' in spec:
                guest_customization_param.append(
                    E.ResetPasswordRequired(spec['password_reset']))
            if 'cust_script' in spec:
                guest_customization_param.append(
                    E.CustomizationScript(spec['cust_script']))
            if 'hostname' in spec:
                guest_customization_param.append(
                    E.ComputerName(spec['hostname']))
            vm_instantiation_param.append(guest_customization_param)

        vm_general_params.append(E.NeedsCustomization(needs_customization))
        sourced_item.append(vm_general_params)
        sourced_item.append(vm_instantiation_param)

        if 'storage_profile' in spec:
            sp = spec['storage_profile']
            storage_profile = E.StorageProfile(
                href=sp.get('href'),
                id=sp.get('href').split('/')[-1],
                type=sp.get('type'),
                name=sp.get('name'))
            sourced_item.append(storage_profile)

        return sourced_item
Ejemplo n.º 3
0
    def instantiate_vapp(self,
                         name,
                         catalog,
                         template,
                         network=None,
                         fence_mode=FenceMode.BRIDGED.value,
                         ip_allocation_mode='dhcp',
                         deploy=True,
                         power_on=True,
                         accept_all_eulas=False,
                         memory=None,
                         cpu=None,
                         disk_size=None,
                         password=None,
                         cust_script=None,
                         vm_name=None,
                         hostname=None,
                         storage_profile=None):
        """Instantiate a vApp from a vApp template in a catalog.

        If customization parameters are provided, it will customize the VM and
        guest OS, taking some assumptions.
        See each parameter for details.

        :param name: (str): The name of the new vApp.
        :param catalog: (str): The name of the catalog.
        :param template: (str): The name of the vApp template.
        :param network: (str): The name of a vdc network.
            When provided, connects the VM to the network.
            It assumes one VM in the vApp and one NIC in the VM.
        :param fence_mode: (str): Fence mode.
            Possible values are `bridged` and `natRouted`
        :param ip_allocation_mode: (str): IP allocation mode.
            Possible values are `pool`, `dhcp` and `static`
        :param deploy: (bool):
        :param power_on: (bool):
        :param accept_all_eulas: (bool): True confirms acceptance of all EULAs
            in a vApp template.
        :param memory: (int):
        :param cpu: (int):
        :param disk_size: (int):
        :param password: (str):
        :param cust_script: (str):
        :param vm_name: (str): When provided, set the name of the VM.
            It assumes one VM in the vApp.
        :param hostname: (str): When provided, set the hostname of the guest
            OS. It assumes one VM in the vApp.
        :param storage_profile: (str):

        :return:  A :class:`lxml.objectify.StringElement` object describing the
            new vApp.
        """
        if self.resource is None:
            self.resource = self.client.get_resource(self.href)

        # Get hold of the template
        org_href = find_link(self.resource, RelationType.UP,
                             EntityType.ORG.value).href
        org = Org(self.client, href=org_href)
        catalog_item = org.get_catalog_item(catalog, template)
        template_resource = self.client.get_resource(
            catalog_item.Entity.get('href'))

        # If network is not specified by user then default to
        # vApp network name specified in the template
        template_networks = template_resource.xpath(
            '//ovf:NetworkSection/ovf:Network',
            namespaces={'ovf': NSMAP['ovf']})
        assert len(template_networks) > 0
        network_name_from_template = template_networks[0].get('{' +
                                                              NSMAP['ovf'] +
                                                              '}name')
        if ((network is None) and (network_name_from_template != 'none')):
            network = network_name_from_template

        # Find the network in vdc referred to by user, using
        # name of the network
        network_href = network_name = None
        if network is not None:
            if hasattr(self.resource, 'AvailableNetworks') and \
               hasattr(self.resource.AvailableNetworks, 'Network'):
                for n in self.resource.AvailableNetworks.Network:
                    if network == n.get('name'):
                        network_href = n.get('href')
                        network_name = n.get('name')
                        break
            if network_href is None:
                raise Exception(
                    'Network \'%s\' not found in the Virtual Datacenter.' %
                    network)

        # Configure the network of the vApp
        vapp_instantiation_param = None
        if network_name is not None:
            network_configuration = E.Configuration(
                E.ParentNetwork(href=network_href), E.FenceMode(fence_mode))

            if fence_mode == 'natRouted':
                # TODO(need to find the vm_id)
                vm_id = None
                network_configuration.append(
                    E.Features(
                        E.NatService(
                            E.IsEnabled('true'), E.NatType('ipTranslation'),
                            E.Policy('allowTraffic'),
                            E.NatRule(
                                E.OneToOneVmRule(E.MappingMode('automatic'),
                                                 E.VAppScopedVmId(vm_id),
                                                 E.VmNicId(0))))))

            vapp_instantiation_param = E.InstantiationParams(
                E.NetworkConfigSection(
                    E_OVF.Info('Configuration for logical networks'),
                    E.NetworkConfig(network_configuration,
                                    networkName=network_name)))

        # Get all vms in the vapp template
        vms = template_resource.xpath(
            '//vcloud:VAppTemplate/vcloud:Children/vcloud:Vm',
            namespaces=NSMAP)
        assert len(vms) > 0

        vm_instantiation_param = E.InstantiationParams()

        # Configure network of the first vm
        if network_name is not None:
            primary_index = int(vms[0].NetworkConnectionSection.
                                PrimaryNetworkConnectionIndex.text)
            vm_instantiation_param.append(
                E.NetworkConnectionSection(
                    E_OVF.Info(
                        'Specifies the available VM network connections'),
                    E.NetworkConnection(
                        E.NetworkConnectionIndex(primary_index),
                        E.IsConnected('true'),
                        E.IpAddressAllocationMode(ip_allocation_mode.upper()),
                        network=network_name)))

        # Configure cpu, memory, disk of the first vm
        cpu_params = memory_params = disk_params = None
        if memory is not None or cpu is not None or disk_size is not None:
            virtual_hardware_section = E_OVF.VirtualHardwareSection(
                E_OVF.Info('Virtual hardware requirements'))
            items = vms[0].xpath('//ovf:VirtualHardwareSection/ovf:Item',
                                 namespaces={'ovf': NSMAP['ovf']})
            for item in items:
                if memory is not None and memory_params is None:
                    if item['{' + NSMAP['rasd'] + '}ResourceType'] == 4:
                        item['{' + NSMAP['rasd'] +
                             '}ElementName'] = '%s MB of memory' % memory
                        item['{' + NSMAP['rasd'] + '}VirtualQuantity'] = memory
                        memory_params = item
                        virtual_hardware_section.append(memory_params)

                if cpu is not None and cpu_params is None:
                    if item['{' + NSMAP['rasd'] + '}ResourceType'] == 3:
                        item['{' + NSMAP['rasd'] +
                             '}ElementName'] = '%s virtual CPU(s)' % cpu
                        item['{' + NSMAP['rasd'] + '}VirtualQuantity'] = cpu
                        cpu_params = item
                        virtual_hardware_section.append(cpu_params)

                if disk_size is not None and disk_params is None:
                    if item['{' + NSMAP['rasd'] + '}ResourceType'] == 17:
                        item['{' + NSMAP['rasd'] + '}Parent'] = None
                        item['{' + NSMAP['rasd'] + '}HostResource'].attrib[
                            '{' + NSMAP['vcloud'] +
                            '}capacity'] = '%s' % disk_size
                        item['{' + NSMAP['rasd'] +
                             '}VirtualQuantity'] = disk_size * 1024 * 1024
                        disk_params = item
                        virtual_hardware_section.append(disk_params)
            vm_instantiation_param.append(virtual_hardware_section)

        # Configure guest customization for the vm
        if password is not None or cust_script is not None or \
           hostname is not None:
            guest_customization_param = E.GuestCustomizationSection(
                E_OVF.Info('Specifies Guest OS Customization Settings'),
                E.Enabled('true'),
            )
            if password is None:
                guest_customization_param.append(
                    E.AdminPasswordEnabled('false'))
            else:
                guest_customization_param.append(
                    E.AdminPasswordEnabled('true'))
                guest_customization_param.append(E.AdminPasswordAuto('false'))
                guest_customization_param.append(E.AdminPassword(password))
                guest_customization_param.append(
                    E.ResetPasswordRequired('false'))
            if cust_script is not None:
                guest_customization_param.append(
                    E.CustomizationScript(cust_script))
            if hostname is not None:
                guest_customization_param.append(E.ComputerName(hostname))
            vm_instantiation_param.append(guest_customization_param)

        # Craft the <SourcedItem> element for the first VM
        sourced_item = E.SourcedItem(
            E.Source(href=vms[0].get('href'),
                     id=vms[0].get('id'),
                     name=vms[0].get('name'),
                     type=vms[0].get('type')))

        vm_general_params = E.VmGeneralParams()
        if vm_name is not None:
            vm_general_params.append(E.Name(vm_name))

        # TODO(check if it needs customization if network, cpu or memory...)
        if disk_size is None and \
           password is None and \
           cust_script is None and \
           hostname is None:
            needs_customization = 'false'
        else:
            needs_customization = 'true'
        vm_general_params.append(E.NeedsCustomization(needs_customization))
        sourced_item.append(vm_general_params)
        sourced_item.append(vm_instantiation_param)

        if storage_profile is not None:
            sp = self.get_storage_profile(storage_profile)
            vapp_storage_profile = E.StorageProfile(
                href=sp.get('href'),
                id=sp.get('href').split('/')[-1],
                type=sp.get('type'),
                name=sp.get('name'))
            sourced_item.append(vapp_storage_profile)

        # Cook the entire vApp Template instantiation element
        deploy_param = 'true' if deploy else 'false'
        power_on_param = 'true' if power_on else 'false'
        all_eulas_accepted = 'true' if accept_all_eulas else 'false'

        vapp_template_params = E.InstantiateVAppTemplateParams(
            name=name, deploy=deploy_param, powerOn=power_on_param)

        if vapp_instantiation_param is not None:
            vapp_template_params.append(vapp_instantiation_param)

        vapp_template_params.append(
            E.Source(href=catalog_item.Entity.get('href')))

        vapp_template_params.append(sourced_item)

        vapp_template_params.append(E.AllEULAsAccepted(all_eulas_accepted))

        # TODO(use post_linked_resource?)
        return self.client.post_resource(
            self.href + '/action/instantiateVAppTemplate',
            vapp_template_params,
            EntityType.INSTANTIATE_VAPP_TEMPLATE_PARAMS.value)
Ejemplo n.º 4
0
    def to_sourced_item(self, spec):
        """Creates a vm SourcedItem from a vm specification.

        :param dict spec: a dictionary containing

            - vapp: (resource): (required) source vApp or vAppTemplate
                resource.
            - source_vm_name: (str): (required) source vm name.
            - target_vm_name: (str): (optional) target vm name.
            - hostname: (str): (optional) target guest hostname.
            - password: (str): (optional) the administrator password of the vm.
            - password_auto: (bool): (optional) auto generate administrator
                password.
            - password_reset: (bool): (optional) True, if the administrator
                password for this vm must be reset after first use.
            - cust_script: (str): (optional) script to run on guest
                customization.
            - network: (str): (optional) name of the vApp network to connect.
                If omitted, the vm won't be connected to any network.
            - storage_profile: (str): (optional) the name of the storage
                profile to be used for this vm.

        :return: an object containing SourcedItem XML element.

        :rtype: lxml.objectify.ObjectifiedElement
        """
        source_vapp = VApp(self.client, resource=spec['vapp'])
        source_vapp.reload()
        source_vm_resource = source_vapp.get_vm(spec['source_vm_name'])

        sourced_item = E.SourcedItem(
            E.Source(href=source_vm_resource.get('href'),
                     id=source_vm_resource.get('id'),
                     name=source_vm_resource.get('name'),
                     type=source_vm_resource.get('type')))

        vm_general_params = E.VmGeneralParams()
        if 'target_vm_name' in spec:
            vm_general_params.append(E.Name(spec['target_vm_name']))

        vm_instantiation_param = E.InstantiationParams()
        if 'network' in spec:
            primary_index = int(source_vm_resource.NetworkConnectionSection.
                                PrimaryNetworkConnectionIndex.text)
            if 'ip_allocation_mode' in spec:
                ip_allocation_mode = spec['ip_allocation_mode']
            else:
                ip_allocation_mode = 'DHCP'

            new_connection = E.NetworkConnection(
                E.NetworkConnectionIndex(primary_index),
                network=spec['network'])

            if spec['ip_address'] and ip_allocation_mode == 'MANUAL':
                new_connection.append(E.IpAddress(spec['ip_address']))

            new_connection.append(E.IsConnected(True))
            new_connection.append(
                E.IpAddressAllocationMode(ip_allocation_mode.upper()))

            vm_instantiation_param.append(
                E.NetworkConnectionSection(
                    E_OVF.Info("Something"),
                    E.PrimaryNetworkConnectionIndex(primary_index),
                    new_connection))

        needs_customization = 'disk_size' in spec or 'password' in spec or \
            'cust_script' in spec or 'hostname' in spec
        if needs_customization:
            guest_customization_param = E.GuestCustomizationSection(
                E_OVF.Info(),
                E.Enabled(True),
            )
            if 'password' in spec:
                guest_customization_param.append(E.AdminPasswordEnabled(True))
                guest_customization_param.append(E.AdminPasswordAuto(False))
                guest_customization_param.append(
                    E.AdminPassword(spec['password']))
            else:
                if 'password_auto' in spec:
                    guest_customization_param.append(
                        E.AdminPasswordEnabled(True))
                    guest_customization_param.append(E.AdminPasswordAuto(True))
                else:
                    guest_customization_param.append(
                        E.AdminPasswordEnabled(False))
            if 'password_reset' in spec:
                guest_customization_param.append(
                    E.ResetPasswordRequired(spec['password_reset']))
            if 'cust_script' in spec:
                guest_customization_param.append(
                    E.CustomizationScript(spec['cust_script']))
            if 'hostname' in spec:
                guest_customization_param.append(
                    E.ComputerName(spec['hostname']))
            vm_instantiation_param.append(guest_customization_param)

        vm_general_params.append(E.NeedsCustomization(needs_customization))
        sourced_item.append(vm_general_params)
        sourced_item.append(vm_instantiation_param)

        if 'storage_profile' in spec:
            sp = spec['storage_profile']
            storage_profile = E.StorageProfile(
                href=sp.get('href'),
                id=sp.get('href').split('/')[-1],
                type=sp.get('type'),
                name=sp.get('name'))
            sourced_item.append(storage_profile)

        return sourced_item
Ejemplo n.º 5
0
    def to_instantiate_vm_template_params(self, spec):
        source_vapp = VApp(self.client, resource=spec['vapp'])
        vm_template = source_vapp.get_vm(spec['source_vm_name'])

        params = E.InstantiateVmTemplateParams(
            E.SourcedVmTemplateItem(
                E.Source(
                    href=vm_template.get('href'),
                    id=vm_template.get('id'),
                    type=vm_template.get('type'),
                    name=vm_template.get('name'),
                )),
            name=spec['target_vm_name'],
            powerOn='true' if spec['power_on'] else 'false')

        vm_general_params = E.VmGeneralParams()
        vm_instantiation_param = E.VmTemplateInstantiationParams()

        if spec.get('network'):
            primary_index = int(vm_template.NetworkConnectionSection.
                                PrimaryNetworkConnectionIndex.text)
            vm_instantiation_param.append(
                E.NetworkConnectionSection(
                    E_OVF.Info(),
                    E.NetworkConnection(
                        E.NetworkConnectionIndex(primary_index),
                        E.IsConnected(True),
                        E.IpAddressAllocationMode(
                            spec['ip_allocation_mode'].upper()),
                        network=spec['network'])))

        needs_customization = 'disk_size' in spec or 'password' in spec or \
            'cust_script' in spec or 'hostname' in spec
        if needs_customization:
            guest_customization_param = E.GuestCustomizationSection(
                E_OVF.Info(),
                E.Enabled(True),
            )
            if spec.get('password'):
                guest_customization_param.append(E.AdminPasswordEnabled(True))
                guest_customization_param.append(E.AdminPasswordAuto(False))
                guest_customization_param.append(
                    E.AdminPassword(spec['password']))
            else:
                if spec.get('password_auto'):
                    guest_customization_param.append(
                        E.AdminPasswordEnabled(True))
                    guest_customization_param.append(E.AdminPasswordAuto(True))
                else:
                    guest_customization_param.append(
                        E.AdminPasswordEnabled(False))
            if spec.get('password_reset'):
                guest_customization_param.append(
                    E.ResetPasswordRequired(spec['password_reset']))
            if spec.get('cust_script'):
                guest_customization_param.append(
                    E.CustomizationScript(spec['cust_script']))
            if spec.get('hostname'):
                guest_customization_param.append(
                    E.ComputerName(spec['hostname']))
            vm_instantiation_param.append(guest_customization_param)

        vm_general_params.append(E.NeedsCustomization(needs_customization))

        params.SourcedVmTemplateItem.append(vm_general_params)
        params.SourcedVmTemplateItem.append(vm_instantiation_param)

        if spec.get('storage_profile'):
            sp = spec['storage_profile']
            storage_profile = E.StorageProfile(
                href=sp.get('href'),
                id=sp.get('href').split('/')[-1],
                type=sp.get('type'),
                name=sp.get('name'))
            params.SourcedVmTemplateItem.append(storage_profile)

        return params