def add_resource_pools_to_provider_vdc(self, pvdc_name, resource_pool_names): """Add Resource Pools to a Provider Virtual Datacenter. :param str pvdc_name: name of the Provider Virtual Datacenter. :param list resource_pool_names: list or resource pool names. :return: an object containing EntityType.TASK XML data which represents the asynchronous task that is adding Resource Pools to the PVDC. :rtype: lxml.objectify.ObjectifiedElement """ provider_vdc = self.get_res_by_name(ResourceType.PROVIDER_VDC, pvdc_name) pvdc_resource = self.client.get_resource(provider_vdc.get('href')) pvdc_ext_href = get_admin_extension_href(pvdc_resource.get('href')) pvdc_ext_resource = self.client.get_resource(pvdc_ext_href) vc_name = pvdc_ext_resource.VimServer.get('name') vc_href = pvdc_ext_resource.VimServer.get('href') rp_morefs = self.get_resource_pool_morefs(vc_name, vc_href, resource_pool_names) payload = E_VMEXT.UpdateResourcePoolSetParams() for rp_moref in rp_morefs: add_item = E_VMEXT.AddItem() add_item.append( E_VMEXT.VimServerRef(type=EntityType.VIRTUAL_CENTER.value, href=vc_href)) add_item.append(E_VMEXT.MoRef(rp_moref)) add_item.append(E_VMEXT.VimObjectType('RESOURCE_POOL')) payload.append(add_item) return self.client.post_linked_resource( resource=pvdc_ext_resource, rel=RelationType.UPDATE_RESOURCE_POOLS, media_type=EntityType.RES_POOL_SET_UPDATE_PARAMS.value, contents=payload)
def create_directly_connected_vdc_network(self, network_name, description, parent_network_name, is_shared=None): """Create a new directly connected OrgVdc network in this VDC. :param network_name: (str): Name of the new network :param description: (str): Description of the new network :param parent_network_name: (str): Name of the external network that the new network will be directly connected to :param is_shared: (bool): True, is the network is shared with \ other VDC(s) in the organization else False :return: A :class:`lxml.objectify.StringElement` object representing a sparsely populated OrgVdcNetwork element. """ resource_admin = self.client.get_resource(self.href_admin) parent_network_href = None if hasattr(resource_admin, 'ProviderVdcReference'): pvdc_admin_href = resource_admin.ProviderVdcReference.get('href') pvdc_admin_ext_href = get_admin_extension_href(pvdc_admin_href) pvdc_resource = self.client.get_resource(pvdc_admin_ext_href) available_network_tag = '{' + NSMAP['vcloud'] + \ '}AvailableNetworks' if hasattr(pvdc_resource, available_network_tag) and \ hasattr(pvdc_resource[available_network_tag], 'Network'): for ext_net in pvdc_resource[available_network_tag].Network: if parent_network_name == ext_net.get('name'): parent_network_href = ext_net.get('href') break else: raise Exception('User doesn\'t have enough permission to view ' 'Provider Virtual Datacenter backing Virtual ' 'Datacenter %s' % self.name) if parent_network_href is None: raise Exception('Network \'%s\' not found in the Provider ' 'Virtual Datacenter.' % parent_network_name) request_payload = E.OrgVdcNetwork(name=network_name) request_payload.append(E.Description(description)) vdc_network_configuration = E.Configuration() vdc_network_configuration.append( E.ParentNetwork(href=parent_network_href)) vdc_network_configuration.append(E.FenceMode('bridged')) request_payload.append(vdc_network_configuration) if is_shared is not None: request_payload.append(E.IsShared(is_shared)) return self.client.post_linked_resource( resource_admin, RelationType.ADD, EntityType.ORG_VDC_NETWORK.value, request_payload)
def get_pvdc(self, pvdc_name): """Fetch pvdc reference, href, and extension resource. :param str pvdc_name: name of pvdc. :return: PVDC reference, href, and extension resource. :rtype: list """ provider_vdc = self.get_ref_by_name(ResourceType.PROVIDER_VDC, pvdc_name) pvdc_ext_href = get_admin_extension_href(provider_vdc.get('href')) pvdc_ext_resource = self.client.get_resource(pvdc_ext_href) return provider_vdc, pvdc_ext_href, pvdc_ext_resource
def attach_resource_pools_to_provider_vdc(self, pvdc_name, resource_pool_names): """Attach Resource Pools to a Provider Virtual Datacenter. This function attaches one or more resource pools (RPs) to a Provider Virtual Datacenter (PVDC). Caveat: The current implementation of this function takes a list of RP "basenames" as input. A basename is the last element of a full pathname. For example, given a pathname /a/b/c, the basename of that pathname is "c". Since RP names are only required to have unique pathnames but not unique basenames, this function may not work correctly if there are non-unique RP basenames. Therefore, in order to use this function, all RP basenames must be unique. It is therefore up to the user of this function to be aware of this limitation and name their RPs appropriately. This limitation will be fixed in a future version of this function. :param str pvdc_name: name of the Provider Virtual Datacenter. :param list resource_pool_names: list or resource pool names. :return: an object containing EntityType.TASK XML data which represents the asynchronous task that is adding Resource Pools to the PVDC. :rtype: lxml.objectify.ObjectifiedElement """ provider_vdc = self.get_res_by_name(ResourceType.PROVIDER_VDC, pvdc_name) pvdc_resource = self.client.get_resource(provider_vdc.get('href')) pvdc_ext_href = get_admin_extension_href(pvdc_resource.get('href')) pvdc_ext_resource = self.client.get_resource(pvdc_ext_href) vc_name = pvdc_ext_resource.VimServer.get('name') vc_href = pvdc_ext_resource.VimServer.get('href') rp_morefs = self.get_resource_pool_morefs(vc_name, vc_href, resource_pool_names) payload = E_VMEXT.UpdateResourcePoolSetParams() for rp_moref in rp_morefs: add_item = E_VMEXT.AddItem() add_item.append( E_VMEXT.VimServerRef(type=EntityType.VIRTUAL_CENTER.value, href=vc_href)) add_item.append(E_VMEXT.MoRef(rp_moref)) add_item.append(E_VMEXT.VimObjectType('RESOURCE_POOL')) payload.append(add_item) return self.client.post_linked_resource( resource=pvdc_ext_resource, rel=RelationType.UPDATE_RESOURCE_POOLS, media_type=EntityType.RES_POOL_SET_UPDATE_PARAMS.value, contents=payload)
def get_pvdc(self, pvdc_name): """Fetch pvdc reference, href, and extension resource. :param str pvdc_name: name of pvdc. :return: PVDC reference, href, and extension resource. :rtype: list """ provider_vdc = self.get_ref_by_name(ResourceType.PROVIDER_VDC, pvdc_name) pvdc_ext_href = get_admin_extension_href(provider_vdc.get('href')) pvdc_ext_resource = self.client.get_resource(pvdc_ext_href) return provider_vdc, pvdc_ext_href, pvdc_ext_resource
def pvdc_migrate_vms(self, pvdc_name, vms_to_migrate, src_resource_pool, target_resource_pool=None): """Migrate VMs to (an optionally) specified ResourcePool. :param str pvdc_name: name of the Provider Virtual Datacenter. :param list(str) vms_to_migrate: list of VMs to migrate. :param str src_resource_pool: source resource pool name. :param str target_resource_pool: target resource pool name (optional). This function migrates the specified VMs to (an optionally) specified target resource pool. If no target resource pool is specified, the system will automatically choose a target resource pool and migrate the VMs to it. If any of the vms_to_migrate are not found on the source resource pool, an exception will be thrown. :return: an object containing EntityType.TASK XML data which represents the async task that is migrating VMs. :rtype: lxml.objectify.ObjectifiedElement :raises: EntityNotFoundException: if source or target resource pool cannot be found, or if any of the vms_to_migrate are not found on the source resource pool. """ provider_vdc = self.get_ref_by_name(ResourceType.PROVIDER_VDC, pvdc_name) pvdc_ext_href = get_admin_extension_href(provider_vdc.get('href')) pvdc_ext_resource = self.client.get_resource(pvdc_ext_href) vc_name = pvdc_ext_resource.VimServer.get('name') vc_href = pvdc_ext_resource.VimServer.get('href') # find the src_respool_resource to get href and link to migrate VMs query_filter = 'vcName==%s' % urllib.parse.quote(vc_name) query = self.client.get_typed_query( ResourceType.RESOURCE_POOL.value, query_result_format=QueryResultFormat.RECORDS, qfilter=query_filter) res_pools_in_use = {} for res_pool in list(query.execute()): res_pools_in_use[res_pool.get('name')] = res_pool.get('moref') if src_resource_pool not in res_pools_in_use.keys(): raise EntityNotFoundException( 'source resource pool: \'%s\' not found' % src_resource_pool) else: src_rp_moref = res_pools_in_use[src_resource_pool] if target_resource_pool is not None: if target_resource_pool not in res_pools_in_use.keys(): raise EntityNotFoundException( 'target resource pool: \'%s\' not found' % target_resource_pool) else: target_rp_moref = res_pools_in_use[target_resource_pool] res_pools_in_pvdc = self.client.get_linked_resource( resource=pvdc_ext_resource, rel=RelationType.DOWN, media_type=EntityType.VMW_PROVIDER_VDC_RESOURCE_POOL_SET.value) pvdc_res_pools = {} if hasattr(res_pools_in_pvdc, '{' + NSMAP['vmext'] + '}VMWProviderVdcResourcePool'): for res_pool in res_pools_in_pvdc.VMWProviderVdcResourcePool: pvdc_res_pools[res_pool.ResourcePoolVimObjectRef.MoRef] = \ res_pool src_respool_resource = pvdc_res_pools[src_rp_moref] # create map of VM names to VM hrefs (in source respool) vms_in_respool = self.client.get_linked_resource( resource=src_respool_resource, rel=RelationType.RESOURCE_POOL_VM_LIST, media_type=None) vm_hrefs_in_respool = {} if hasattr(vms_in_respool, 'ResourcePoolVMRecord'): for vm in vms_in_respool.ResourcePoolVMRecord: vm_hrefs_in_respool[vm.get('name')] = vm.get('href') # check that vms_to_migrate are contained in vms in respool # and build the vms to migrate list payload = E_VMEXT.MigrateParams() for vm_to_migrate in vms_to_migrate: if vm_to_migrate in vm_hrefs_in_respool.keys(): payload.append( E_VMEXT.VmRef(href=vm_hrefs_in_respool[vm_to_migrate])) else: raise EntityNotFoundException( 'virtual machine \'%s\' not Found' % vm_to_migrate) # if target respool specified, add target RP <vc, moref> to payload if target_resource_pool is not None: res_pool_ref = E_VMEXT.ResourcePoolRef() vc_ref = E_VMEXT.VimServerRef(href=vc_href) moref = E_VMEXT.MoRef(target_rp_moref) obj_type = E_VMEXT.VimObjectType('RESOURCE_POOL') res_pool_ref.append(vc_ref) res_pool_ref.append(moref) res_pool_ref.append(obj_type) payload.append(res_pool_ref) # do the migrate, return task return self.client.post_linked_resource(resource=src_respool_resource, rel=RelationType.MIGRATE_VMS, media_type=None, contents=payload)
def detach_resource_pools_from_provider_vdc(self, pvdc_name, resource_pool_names): """Disable & Detach Resource Pools from a Provider Virtual Datacenter. This function deletes resource pools (RPs) from a Provider Virtual Datacenter (PVDC). In order to do this, the input "user-friendly" RP names must be translated into RP hrefs. This is a multi-step process. 1) create a dictionary that maps RP names associated w/ this PVDC's backing VC to morefs. 2) create a list of morefs_to_delete, using the dictionary created in step 1 -- filtered by the input set of RP names. 3) create a dictionary that maps RP morefs associated w/ this PVDC to RP hrefs. 4) Use the list of morefs_to_delete (created in step 2) to filter the list of RP hrefs created as a dictionary in step 3 to create the final payload. Note that in order to delete a RP, it must first be disabled. This is done for each RP to be deleted if the disable link is present (which indicates that the RP is enabled). Caveat: The current implementation of this function takes a list of RP "basenames" as input. A basename is the last element of a full pathname. For example, given a pathname /a/b/c, the basename of that pathname is "c". Since RP names are only required to have unique pathnames but not unique basenames, this function may not work correctly if there are non-unique RP basenames. Therefore, in order to use this function, all RP basenames must be unique. It is therefore up to the user of this function to be aware of this limitation and name their RPs appropriately. This limitation will be fixed in a future version of this function. :param str pvdc_name: name of the Provider Virtual Datacenter. :param list resource_pool_names: list or resource pool names. :return: an object containing EntityType.TASK XML data which represents the async task that is deleting Resource Pools from the PVDC. :rtype: lxml.objectify.ObjectifiedElement :raises: EntityNotFoundException: if any resource_pool_name cannot be found. :raises: ValidationError: if primary resource pool is input for deletion. """ provider_vdc = self.get_ref_by_name(ResourceType.PROVIDER_VDC, pvdc_name) pvdc_ext_href = get_admin_extension_href(provider_vdc.get('href')) pvdc_ext_resource = self.client.get_resource(pvdc_ext_href) vc_name = pvdc_ext_resource.VimServer.get('name') # find the RPs in use that are associated with the backing VC name_filter = ('vcName', vc_name) query = self.client.get_typed_query( ResourceType.RESOURCE_POOL.value, query_result_format=QueryResultFormat.RECORDS, equality_filter=name_filter) res_pools_in_use = {} for res_pool in list(query.execute()): res_pools_in_use[res_pool.get('name')] = res_pool.get('moref') morefs_to_delete = [] for resource_pool_name in resource_pool_names: if resource_pool_name in res_pools_in_use.keys(): morefs_to_delete.append(res_pools_in_use[resource_pool_name]) else: raise EntityNotFoundException( 'resource pool \'%s\' not Found' % resource_pool_name) res_pools_in_pvdc = self.client.get_linked_resource( resource=pvdc_ext_resource, rel=RelationType.DOWN, media_type=EntityType.VMW_PROVIDER_VDC_RESOURCE_POOL_SET.value) pvdc_res_pools = {} if hasattr(res_pools_in_pvdc, '{' + NSMAP['vmext'] + '}VMWProviderVdcResourcePool'): for res_pool in res_pools_in_pvdc.VMWProviderVdcResourcePool: pvdc_res_pools[res_pool.ResourcePoolVimObjectRef.MoRef] = \ res_pool res_pool_to_delete_refs = [] for moref in morefs_to_delete: if moref not in pvdc_res_pools.keys(): raise EntityNotFoundException( 'resource pool with moref \'%s\' not Found' % moref) else: res_pool = pvdc_res_pools[moref] if res_pool.get('primary') == 'true': raise ValidationError( 'cannot delete primary respool with moref \'%s\' ' % res_pool.ResourcePoolVimObjectRef.MoRef) else: # disable the RP if it is enabled links = get_links(resource=res_pool, rel=RelationType.DISABLE) num_links = len(links) if num_links == 1: self.client.\ post_linked_resource(resource=res_pool, rel=RelationType.DISABLE, media_type=None, contents=None) res_pool_to_delete_refs.append(res_pool) payload = E_VMEXT.UpdateResourcePoolSetParams() for res_pool_ref in res_pool_to_delete_refs: del_item = E_VMEXT.DeleteItem( href=res_pool_ref.ResourcePoolRef.get('href'), type=EntityType.VMW_PROVIDER_VDC_RESOURCE_POOL.value) payload.append(del_item) return self.client.post_linked_resource( resource=pvdc_ext_resource, rel=RelationType.UPDATE_RESOURCE_POOLS, media_type=EntityType.RES_POOL_SET_UPDATE_PARAMS.value, contents=payload)
def test_0000_setup(self): """Setup the org vdc required for the other tests in this module. Create one org vdc as per the configuration stated above. Test the method Org.create_org_vdc(). This test passes if the vdc href is not None. """ logger = Environment.get_default_logger() TestPVDC._sys_admin_client = Environment.get_sys_admin_client() org = Environment.get_test_org(TestPVDC._sys_admin_client) platform = Platform(TestPVDC._sys_admin_client) vdc_name = TestPVDC._new_vdc_name pvdc_name = Environment.get_test_pvdc_name() provider_vdc = platform.get_ref_by_name(ResourceType.PROVIDER_VDC, pvdc_name) pvdc_ext_href = get_admin_extension_href(provider_vdc.get('href')) pvdc_ext_resource = TestPVDC._sys_admin_client.get_resource( pvdc_ext_href) vc_name = pvdc_ext_resource.VimServer.get('name') res_pools_in_pvdc = TestPVDC._sys_admin_client.get_linked_resource( resource=pvdc_ext_resource, rel=RelationType.DOWN, media_type=EntityType.VMW_PROVIDER_VDC_RESOURCE_POOL_SET.value) if hasattr(res_pools_in_pvdc, '{' + NSMAP['vmext'] + '}VMWProviderVdcResourcePool'): src_respool = res_pools_in_pvdc.VMWProviderVdcResourcePool[0] name_filter = ('vcName', vc_name) query = TestPVDC._sys_admin_client.get_typed_query( ResourceType.RESOURCE_POOL.value, query_result_format=QueryResultFormat.RECORDS, equality_filter=name_filter) res_pools_in_use = {} for res_pool in list(query.execute()): res_pools_in_use[res_pool.get('moref')] = res_pool.get('name') source_respool_name = res_pools_in_use[ src_respool.ResourcePoolVimObjectRef.MoRef] TestPVDC._source_resource_pool = source_respool_name storage_profiles = [{ 'name': '*', 'enabled': True, 'units': 'MB', 'limit': 0, 'default': True }] vdc_resource = org.create_org_vdc(vdc_name, pvdc_name, storage_profiles=storage_profiles, uses_fast_provisioning=True, is_thin_provision=True) TestPVDC._sys_admin_client.get_task_monitor().wait_for_success( task=vdc_resource.Tasks.Task[0]) logger.debug('Created ovdc ' + vdc_name + '.') # The following contraption is required to get the non admin href of # the ovdc. vdc_resource contains the admin version of the href since # we created the ovdc as a sys admin. org.reload() for vdc in org.list_vdcs(): if vdc.get('name').lower() == vdc_name.lower(): TestPVDC._new_vdc_href = vdc.get('href') self.assertIsNotNone(TestPVDC._new_vdc_href)
def test_0000_setup(self): """Setup the org vdc required for the other tests in this module. Create one org vdc as per the configuration stated above. Test the method Org.create_org_vdc(). This test passes if the vdc href is not None. """ logger = Environment.get_default_logger() TestPVDC._sys_admin_client = Environment.get_sys_admin_client() org = Environment.get_test_org(TestPVDC._sys_admin_client) platform = Platform(TestPVDC._sys_admin_client) vdc_name = TestPVDC._new_vdc_name pvdc_name = Environment.get_test_pvdc_name() provider_vdc = platform.get_ref_by_name(ResourceType.PROVIDER_VDC, pvdc_name) pvdc_ext_href = get_admin_extension_href(provider_vdc.get('href')) pvdc_ext_resource = TestPVDC._sys_admin_client.get_resource( pvdc_ext_href) vc_name = pvdc_ext_resource.VimServer.get('name') res_pools_in_pvdc = TestPVDC._sys_admin_client.get_linked_resource( resource=pvdc_ext_resource, rel=RelationType.DOWN, media_type=EntityType.VMW_PROVIDER_VDC_RESOURCE_POOL_SET.value) if hasattr(res_pools_in_pvdc, '{' + NSMAP['vmext'] + '}VMWProviderVdcResourcePool'): src_respool = res_pools_in_pvdc.VMWProviderVdcResourcePool[0] name_filter = ('vcName', vc_name) query = TestPVDC._sys_admin_client.get_typed_query( ResourceType.RESOURCE_POOL.value, query_result_format=QueryResultFormat.RECORDS, equality_filter=name_filter) res_pools_in_use = {} for res_pool in list(query.execute()): res_pools_in_use[res_pool.get('moref')] = res_pool.get('name') source_respool_name = res_pools_in_use[ src_respool.ResourcePoolVimObjectRef.MoRef] TestPVDC._source_resource_pool = source_respool_name storage_profiles = [{ 'name': '*', 'enabled': True, 'units': 'MB', 'limit': 0, 'default': True }] vdc_resource = org.create_org_vdc( vdc_name, pvdc_name, storage_profiles=storage_profiles, uses_fast_provisioning=True, is_thin_provision=True) TestPVDC._sys_admin_client.get_task_monitor().wait_for_success( task=vdc_resource.Tasks.Task[0]) logger.debug('Created ovdc ' + vdc_name + '.') # The following contraption is required to get the non admin href of # the ovdc. vdc_resource contains the admin version of the href since # we created the ovdc as a sys admin. org.reload() for vdc in org.list_vdcs(): if vdc.get('name').lower() == vdc_name.lower(): TestPVDC._new_vdc_href = vdc.get('href') self.assertIsNotNone(TestPVDC._new_vdc_href)