def test_get_req_path_uuid_and_is_instance_path(self): # Fail: no '/' path = dummyuuid1 self.assertIsNone(util.get_req_path_uuid(path)) self.assertRaises(IndexError, util.is_instance_path, path) path = '/' + dummyuuid1 self.assertEqual(dummyuuid1, util.get_req_path_uuid(path)) self.assertTrue(util.is_instance_path(path)) path = 'https://server:1234/rest/api/uom/Obj/' + dummyuuid1 self.assertEqual(dummyuuid1, util.get_req_path_uuid(path)) self.assertTrue(util.is_instance_path(path)) # Fail: last path element is not a UUID path = 'https://server:1234/rest/api/uom/Obj/' + dummyuuid1 + '/Child' self.assertIsNone(util.get_req_path_uuid(path)) self.assertFalse(util.is_instance_path(path)) # Fail: last path element is not quiiiite a UUID path = 'https://server:1234/rest/api/uom/Obj/' + dummyuuid1[1:] self.assertIsNone(util.get_req_path_uuid(path)) self.assertFalse(util.is_instance_path(path)) # Ignore query/fragment path = ('https://server:1234/rest/api/uom/Obj/' + dummyuuid1 + '?group=One,Two#frag') self.assertEqual(dummyuuid1, util.get_req_path_uuid(path)) self.assertTrue(util.is_instance_path(path)) # Fail: last path element (having removed query/fragment) is not a UUID path = ('https://server:1234/rest/api/uom/Obj/' + dummyuuid1 + '/Child?group=One,Two#frag') self.assertIsNone(util.get_req_path_uuid(path)) self.assertFalse(util.is_instance_path(path)) # Default case conversion path = 'https://server:1234/rest/api/uom/Obj/' + dummyuuid1.upper() self.assertEqual(dummyuuid1, util.get_req_path_uuid(path)) self.assertEqual(dummyuuid1, util.get_req_path_uuid(path, preserve_case=False)) self.assertTrue(util.is_instance_path(path)) # Force no case conversion self.assertEqual(dummyuuid1.upper(), util.get_req_path_uuid(path, preserve_case=True)) # Child URI gets child UUID by default path = ('https://server:1234/rest/api/uom/Obj/' + dummyuuid1 + '/Child/' + dummyuuid2) self.assertEqual(dummyuuid2, util.get_req_path_uuid(path)) self.assertTrue(util.is_instance_path(path)) # Get root UUID from child URI path = ('https://server:1234/rest/api/uom/Obj/' + dummyuuid1 + '/Child/' + dummyuuid2) self.assertEqual(dummyuuid1, util.get_req_path_uuid(path, root=True)) self.assertTrue(util.is_instance_path(path)) # root=True redundant on a root path path = '/' + dummyuuid1 self.assertEqual(dummyuuid1, util.get_req_path_uuid(path, root=True)) path = 'https://server:1234/rest/api/uom/Obj/' + dummyuuid1 self.assertEqual(dummyuuid1, util.get_req_path_uuid(path, root=True))
def test_get_req_path_uuid_and_is_instance_path(self): # Fail: no '/' path = dummyuuid1 self.assertIsNone(util.get_req_path_uuid(path)) self.assertRaises(IndexError, util.is_instance_path, path) path = '/' + dummyuuid1 self.assertEqual(dummyuuid1, util.get_req_path_uuid(path)) self.assertTrue(util.is_instance_path(path)) path = 'https://server:1234/rest/api/uom/Obj/' + dummyuuid1 self.assertEqual(dummyuuid1, util.get_req_path_uuid(path)) self.assertTrue(util.is_instance_path(path)) # Fail: last path element is not a UUID path = 'https://server:1234/rest/api/uom/Obj/' + dummyuuid1 + '/Child' self.assertIsNone(util.get_req_path_uuid(path)) self.assertFalse(util.is_instance_path(path)) # Fail: last path element is not quiiiite a UUID path = 'https://server:1234/rest/api/uom/Obj/' + dummyuuid1[1:] self.assertIsNone(util.get_req_path_uuid(path)) self.assertFalse(util.is_instance_path(path)) # Ignore query/fragment path = ('https://server:1234/rest/api/uom/Obj/' + dummyuuid1 + '?group=One,Two#frag') self.assertEqual(dummyuuid1, util.get_req_path_uuid(path)) self.assertTrue(util.is_instance_path(path)) # Fail: last path element (having removed query/fragment) is not a UUID path = ('https://server:1234/rest/api/uom/Obj/' + dummyuuid1 + '/Child?group=One,Two#frag') self.assertIsNone(util.get_req_path_uuid(path)) self.assertFalse(util.is_instance_path(path)) # Default case conversion path = 'https://server:1234/rest/api/uom/Obj/' + dummyuuid1.upper() self.assertEqual(dummyuuid1, util.get_req_path_uuid(path)) self.assertEqual(dummyuuid1, util.get_req_path_uuid( path, preserve_case=False)) self.assertTrue(util.is_instance_path(path)) # Force no case conversion self.assertEqual(dummyuuid1.upper(), util.get_req_path_uuid( path, preserve_case=True)) # Child URI gets child UUID by default path = ('https://server:1234/rest/api/uom/Obj/' + dummyuuid1 + '/Child/' + dummyuuid2) self.assertEqual(dummyuuid2, util.get_req_path_uuid(path)) self.assertTrue(util.is_instance_path(path)) # Get root UUID from child URI path = ('https://server:1234/rest/api/uom/Obj/' + dummyuuid1 + '/Child/' + dummyuuid2) self.assertEqual(dummyuuid1, util.get_req_path_uuid(path, root=True)) self.assertTrue(util.is_instance_path(path)) # root=True redundant on a root path path = '/' + dummyuuid1 self.assertEqual(dummyuuid1, util.get_req_path_uuid(path, root=True)) path = 'https://server:1234/rest/api/uom/Obj/' + dummyuuid1 self.assertEqual(dummyuuid1, util.get_req_path_uuid(path, root=True))
def _handle_event(self, pvm_event, details, inst=None): """Handle an individual event. :param pvm_event: PowerVM Event Wrapper :param details: Parsed Details from the event :param inst: (Optional, Default: None) The pypowervm wrapper object that represents the VM instance. If None we try to look it up based on UUID. :return: returns the instance object or None (when it's not an instance event or action is not partition state change or NVRAM change) """ # See if this uri (from data) ends with a PowerVM UUID. if not pvm_util.is_instance_path(pvm_event.data): return None # If a vm event and one we handle, call the inst handler. pvm_uuid = pvm_util.get_req_path_uuid(pvm_event.data, preserve_case=True) if (pvm_event.data.endswith('LogicalPartition/' + pvm_uuid) and (self.inst_actions_handled & set(details))): if not inst: LOG.debug( 'PowerVM Nova Event Handler: Getting inst ' 'for id %s', pvm_uuid) inst = vm.get_instance(ctx.get_admin_context(), pvm_uuid) if inst: LOG.debug( 'Handle action "%(action)s" event for instance: ' '%(inst)s', dict(action=details, inst=inst.name)) self._handle_inst_event(inst, pvm_uuid, details) return inst return None
def _prov_reqs_for_uri(self, uri): """Returns set of ProvisionRequests for a URI. When the API indicates that a URI is invalid, it will return a List of ProvisionRequests for a given URI. If the URI is not valid for a ClientNetworkAdapter (CNA) then an empty list will be returned. """ try: if not pvm_util.is_instance_path(uri): return [] except Exception: LOG.warn(_LW('Unable to parse URI %s for provision request ' 'assessment.'), uri) return [] # The event queue will only return URI's for 'root like' objects. # This is essentially just the LogicalPartition, you can't get the # ClientNetworkAdapter. So if we find an add/invalidate for the # LogicalPartition, we'll get all the CNAs. # # This check will throw out everything that doesn't include the # LogicalPartition's uuid = pvm_util.get_req_path_uuid(uri, preserve_case=True) if not uri.endswith('LogicalPartition/' + uuid): return [] # For the LPAR, get the CNAs. cna_wraps = utils.list_cnas(self.adapter, self.host_uuid, uuid) resp = [] for cna_w in cna_wraps: # Build a provision request for each type device_mac = utils.norm_mac(cna_w.mac) device_detail = self.agent.get_device_details(device_mac) # A device detail will always come back...even if neutron has # no idea what the port is. This WILL happen for PowerVM, maybe # an event for the mgmt partition or the secure RMC VIF. We can # detect if Neutron has full device details by simply querying for # the mac from the device_detail if not device_detail.get('mac_address'): continue # Must be good! resp.append(agent_base.ProvisionRequest(device_detail, uuid)) return resp