def resolve_uri(self, query): try: # Slight hack here -- relies on the "name" field usually being # first in a reverse-sort in order to optimize for the most # common query. for field, expressions in (sorted( self.schema['filtering'].iteritems(), key=lambda x: x[0], reverse=True)): for expression in expressions: filter = "%s__%s" % (field, expression) try: candidates = self.list(**{filter: query}) except BadRequest: continue if len(candidates) > 1: if expression in ["startswith", "endswith"]: raise TooManyMatches( "The query %s/%s matches more than one resource: %s" % (self.name, query, candidates)) else: continue try: ''' We may have search on a filter with a reference such as host__fqdn. In this case the attribute will not exist a so we have to search the nested dictionaries. lc = { "id": 1, "host": {"fqdn": "myserver"} } Will have it's value in candidates[0]['host']['fqdn'] ''' search_value = candidates[0].all_attributes for sub_field in field.split('__'): if type( search_value ) != dict: # We didn't get the keys correct so it is a KeyError raise KeyError search_value = search_value[sub_field] if query in str(search_value): return candidates[0]['resource_uri'] except (IndexError, KeyError): continue except KeyError: # No filtering possible? pass raise NotFound("Unable to resolve URI for %s/%s" % (self.name, query))
def _resolve_volume_node(self, spec): try: hostname, path = spec.split(":") host = self.api.endpoints["host"].show(hostname) kwargs = {"host": host["id"], "path": path} vn_set = self.api.endpoints["volume_node"].list(**kwargs) if len(vn_set) > 1: raise TooManyMatches() else: return vn_set[0] except (ValueError, IndexError): raise InvalidVolumeNode(spec)