Ejemplo n.º 1
0
    def create_vapp(self,
                    name,
                    description=None,
                    network=None,
                    fence_mode=FenceMode.BRIDGED.value,
                    accept_all_eulas=None):
        """Create a new vApp in this vdc.

        :param name: (str) Name of the new vApp.
        :param description: (str) Description of the new vApp.
        :param network: (str) Name of the OrgVDC network the vApp will
            connect to.
        :param fence_mode: (str): Network fence mode.
            Possible values are `bridged` and `natRouted`
        :param accept_all_eulas: (bool): True confirms acceptance of all EULAs
            in a vApp template.
        :return:  A :class:`lxml.objectify.StringElement` object representing a
            sparsely populated vApp element in the target vdc.
        """
        if self.resource is None:
            self.resource = self.client.get_resource(self.href)

        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)

        vapp_instantiation_param = None
        if network_name is not None:
            network_configuration = E.Configuration(
                E.ParentNetwork(href=network_href), E.FenceMode(fence_mode))

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

        params = E.ComposeVAppParams(name=name)
        if description is not None:
            params.append(E.Description(description))
        if vapp_instantiation_param is not None:
            params.append(vapp_instantiation_param)
        if accept_all_eulas is not None:
            params.append(E.AllEULAsAccepted(accept_all_eulas))

        return self.client.post_linked_resource(
            self.resource, RelationType.ADD,
            EntityType.COMPOSE_VAPP_PARAMS.value, params)
Ejemplo n.º 2
0
    def capture_vapp(self,
                     catalog_resource,
                     vapp_href,
                     catalog_item_name,
                     description,
                     customize_on_instantiate=False,
                     overwrite=False):
        """Capture vApp as a catalog item template.

        :param catalog_resource: (`lxml.objectify.StringElement`): The
            catalog.
        :param vapp_href: (str): The href of the vApp to capture.
        :param catalog_item_name: (str): The name of the target catalog item.
        :param description: (str): The description of the catalog item.
        :param customize_on_instantiate: (bool): A flag indicating if the
            vApp to be instantiated from this vApp template can be customized.
        :param overwrite: (bool): A flag indicating if the item in the catalog
            has to be overwritten if it already exists. If it doesn't exists,
            this flag is not used.
        :return:  A :class:`lxml.objectify.StringElement` object describing
            the updated catalog item.
        """
        contents = E.CaptureVAppParams(
            E.Description(description),
            E.Source(href=vapp_href),
            name=catalog_item_name)
        if customize_on_instantiate:
            contents.append(
                E.CustomizationSection(
                    E_OVF.Info('VApp template customization section'),
                    E.CustomizeOnInstantiate('true')))
        if overwrite:
            try:
                item = self.get_catalog_item(
                    catalog_resource.get('name'), catalog_item_name)
                contents.append(
                    E.TargetCatalogItem(
                        href=item.get('href'),
                        id=item.get('id'),
                        type=item.get('type'),
                        name=item.get('name')))
            except Exception:
                pass
        return self.client.post_linked_resource(
            catalog_resource,
            rel=RelationType.ADD,
            media_type=EntityType.CAPTURE_VAPP_PARAMS.value,
            contents=contents)
Ejemplo n.º 3
0
 def capture_vapp(self,
                  catalog_resource,
                  vapp_href,
                  catalog_item_name,
                  description,
                  customize_on_instantiate=False):
     contents = E.CaptureVAppParams(E.Description(description),
                                    E.Source(href=vapp_href),
                                    name=catalog_item_name)
     if customize_on_instantiate:
         contents.append(
             E.CustomizationSection(
                 E_OVF.Info('VApp template customization section'),
                 E.CustomizeOnInstantiate('true')))
     return self.client.post_linked_resource(
         catalog_resource,
         rel=RelationType.ADD,
         media_type=EntityType.CAPTURE_VAPP_PARAMS.value,
         contents=contents)
Ejemplo n.º 4
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.º 5
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
    def add_vm(self):
        params = self.params
        source_vapp_resource = self.get_source_resource()
        target_vm_name = params.get('target_vm_name')
        source_vm_name = params.get('source_vm_name')
        hostname = params.get('hostname')
        vmpassword = params.get('vmpassword')
        vmpassword_auto = params.get('vmpassword_auto')
        vmpassword_reset = params.get('vmpassword_reset')
        network = params.get('network')
        all_eulas_accepted = params.get('all_eulas_accepted')
        power_on = params.get('power_on')
        ip_allocation_mode = params.get('ip_allocation_mode')
        cust_script = params.get('cust_script')
        storage_profile = params.get('storage_profile')
        properties = params.get('properties')
        response = dict()
        response['changed'] = False

        try:
            self.get_vm()
        except EntityNotFoundException:
            spec = {
                'source_vm_name': source_vm_name,
                'vapp': source_vapp_resource,
                'target_vm_name': target_vm_name,
                'hostname': hostname,
                'password': vmpassword,
                'password_auto': vmpassword_auto,
                'password_reset': vmpassword_reset,
                'ip_allocation_mode': ip_allocation_mode,
                'network': network,
                'cust_script': cust_script
            }
            if storage_profile!='':
                spec['storage_profile'] = self.get_storage_profile(storage_profile)
            spec = {k: v for k, v in spec.items() if v}
            source_vm = self.vapp.to_sourced_item(spec)

            # Check the source vm if we need to inject OVF properties.
            source_vapp = VApp(self.client, resource=source_vapp_resource)
            vm = source_vapp.get_vm(source_vm_name)
            productsection = vm.find('ovf:ProductSection', NSMAP)
            if productsection is not None:
                for prop in productsection.iterfind('ovf:Property', NSMAP):
                    if properties and prop.get('{'+NSMAP['ovf']+'}key') in properties:
                        val = prop.find('ovf:Value', NSMAP)
                        if val:
                            prop.remove(val)
                        val = E_OVF.Value()
                        val.set('{'+NSMAP['ovf']+'}value', properties[prop.get('{'+NSMAP['ovf']+'}key')])
                        prop.append(val)
                source_vm.InstantiationParams.append(productsection)
                source_vm.VmGeneralParams.NeedsCustomization = E.NeedsCustomization('true')

            params = E.RecomposeVAppParams(deploy='true', powerOn='true' if power_on else 'false')
            params.append(source_vm)
            if all_eulas_accepted is not None:
                params.append(E.AllEULAsAccepted(all_eulas_accepted))

            add_vms_task = self.client.post_linked_resource(
                self.get_target_resource(), RelationType.RECOMPOSE,
                EntityType.RECOMPOSE_VAPP_PARAMS.value, params)
            self.execute_task(add_vms_task)
            response['msg'] = 'Vapp VM {} has been created.'.format(
                target_vm_name)
            response['changed'] = True
        else:
            response['warnings'] = 'Vapp VM {} is already present.'.format(
                target_vm_name)

        return response
Ejemplo n.º 7
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.º 8
0
    def attach_network_to_vm(self,
                             vm_name,
                             network_name,
                             connection_index,
                             connections_primary_index=None,
                             ip_allocation_mode='DHCP',
                             mac_address=None,
                             ip_address=None):
        """Attach a single vm to a virtual network.

        :param vm_name: (str): The name of the vm that the network will be
                               attached to.
        :param network_name: (str): The network name to connect the VM to.
        :param connection_index: (str): Virtual slot number associated with
                                        this NIC. First slot number is 0.
        :param connections_primary_index: (str): Virtual slot number associated
                                                 with the NIC that should be
                                                 considered this virtual
                                                 machine's primary network
                                                 connection. Default slot 0.
        :param ip_allocation_mode: (str, optional): IP address allocation
                                                    mode for this connection.

            * One of:
             - POOL (A static IP address is allocated automatically from a
                     pool of addresses.)
             - DHCP (The IP address is obtained from a DHCP service.)
             - MANUAL (The IP address is assigned manually in the IpAddress
                       element.)
             - NONE (No IP addressing mode specified.)

        :param mac_address: (str):    the MAC address associated with the NIC.
        :param ip_address: (str):     the IP address assigned to this NIC.
        :return:  A :class:`lxml.objectify.StringElement` object representing
            the asynchronous task that is connecting the vm to the network.
        :raises: Exception: If the named VM cannot be located or another error
                            occured.
        """
        if self.resource is None:
            self.resource = self.client.get_resource(self.href)

        vm = self.get_vm(vm_name)

        new_connection = E.NetworkConnection(
            E.NetworkConnectionIndex(connection_index), network=network_name)
        if ip_address and ip_allocation_mode == 'MANUAL':
            new_connection.append(E.IpAddress(ip_address))
        new_connection.append(E.IsConnected('true'))
        new_connection.append(
            E.IpAddressAllocationMode(ip_allocation_mode.upper()))

        if mac_address:
            new_connection.append(E.MACAddress(mac_address))

        new_connection_section = E.NetworkConnectionSection(
            E_OVF.Info(), E.PrimaryNetworkConnectionIndex(connection_index),
            new_connection)

        return self.client.put_linked_resource(
            vm.NetworkConnectionSection, RelationType.EDIT,
            EntityType.NETWORK_CONNECTION_SECTION.value,
            new_connection_section)
Ejemplo n.º 9
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.º 10
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
Ejemplo n.º 11
0
    def update_vm_ng(self):
        source_vapp_resource = self.get_source_resource()
        source_vapp_name = self.params.get('vapp')
        target_vapp_name = self.params.get('vapp')
        vapp = self.params.get('vapp')
        source_vm_name = self.params.get('vm_name')
        target_vm_name = self.params.get('vm_name')
        vm_name = self.params.get('vm_name')
        force_customization = self.params.get('force_customization')
        hostname = self.params.get('hostname')
        vmpassword = self.params.get('vmpassword')
        vmpassword_auto = self.params.get('vmpassword_auto')
        vmpassword_reset = self.params.get('vmpassword_reset')
        network = self.params.get('network')
        all_eulas_accepted = self.params.get('all_eulas_accepted')
        power_on = self.params.get('power_on')
        deploy = self.params.get('deploy')
        ip_allocation_mode = self.params.get('ip_allocation_mode')
        cust_script = self.params.get('cust_script')
        storage_profile = self.params.get('storage_profile')
        properties = self.params.get('properties')
        response = dict()
        response['changed'] = False
        self.vapp = vapp
        self.target_vm_name = target_vm_name
        self.source_vm_name = source_vm_name
        self.source_vapp_name = vapp
        self.target_vapp_name = vapp
        self.vm_name = vm_name
        self.hostname = hostname
        self.vmpassword = vmpassword
        self.vmpassword_auto = vmpassword_auto
        self.vmpassword_reset = vmpassword_reset
        self.network = network
        self.force_customization = force_customization
        self.all_eulas_accepted = all_eulas_accepted
        self.power_on = power_on
        self.ip_allocation_mode = ip_allocation_mode
        self.cust_script = cust_script
        self.storage_profile = storage_profile
        # self.params =
        vm = self.get_vm()
        self.vm = vm
        source_vm = vm
        target_vm = vm
        self.source_vm = source_vm
        self.target_vm = target_vm
        spec = {
            'source_vm_name': source_vm,
            'target_vm_name': target_vm,
            'vapp': vapp,
            'vm_name': vm_name,
            'hostname': hostname,
            'password': vmpassword,
            'password_auto': vmpassword_auto,
            'password_reset': vmpassword_reset,
            'ip_allocation_mode': ip_allocation_mode,
            'network': network,
            'cust_script': cust_script,
            'force_customization': force_customization
        }

        spec = {k: v for k, v in spec.items() if v}
        if storage_profile != '':
            spec['storage_profile'] = self.get_storage_profile(storage_profile)
        # source_vm = self.vapp.to_sourced_item(spec)

        # # Check the source vm if we need to inject OVF properties.
        # source_vapp = VApp(self.client, resource=source_vapp_resource)
        # vm = source_vapp.get_vm(source_vm_name)
        productsection = vm.find('ovf:ProductSection', NSMAP)
        if productsection is not None:
            for prop in productsection.iterfind('ovf:Property', NSMAP):
                if properties and prop.get('{' + NSMAP['ovf'] +
                                           '}key') in properties:
                    val = prop.find('ovf:Value', NSMAP)
                    if val:
                        prop.remove(val)
                    val = E_OVF.Value()
                    val.set('{' + NSMAP['ovf'] + '}value',
                            properties[prop.get('{' + NSMAP['ovf'] + '}key')])
                    prop.append(val)
            source_vm.InstantiationParams.append(productsection)
            source_vm.VmGeneralParams.NeedsCustomization = E.NeedsCustomization(
                'true')

        params = E.RecomposeVAppParams(state='update' if state else 'false',
                                       deploy='true' if deploy else 'false',
                                       powerOn='true' if power_on else 'false')
        params.append(source_vm)
        if all_eulas_accepted is not None:
            params.update(E.AllEULAsAccepted(all_eulas_accepted))

        update_vm_ngs_task = self.client.post_linked_resource(
            self.get_target_resource(), RelationType.RECOMPOSE,
            EntityType.RECOMPOSE_VAPP_PARAMS.value, params)
        self.execute_task(update_vm_ngs_task)
        response['msg'] = 'VM {} has been created.'.format(target_vm_name)
        response['changed'] = True

        return response