Merge "Add support to search resources based on tags or resource type"
This commit is contained in:
commit
05fdc812d5
@ -777,3 +777,38 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
test_client.assert_json_call(
|
||||
'get', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s/allocations' % uuid)
|
||||
|
||||
|
||||
class TestNsxSearch(nsxlib_testcase.NsxClientTestCase):
|
||||
|
||||
def test_nsx_search_tags(self):
|
||||
"""Test search of resources with the specified tag."""
|
||||
with mock.patch.object(self.nsxlib.client, 'url_get') as search:
|
||||
user_tags = [{'scope': 'user', 'tag': 'k8s'}]
|
||||
query = self.nsxlib._build_query(tags=user_tags)
|
||||
self.nsxlib.search_by_tags(tags=user_tags)
|
||||
search.assert_called_with('search?query=%s' % query)
|
||||
|
||||
def test_nsx_search_tags_and_resource_type(self):
|
||||
"""Test search of specified resource with the specified tag."""
|
||||
with mock.patch.object(self.nsxlib.client, 'url_get') as search:
|
||||
user_tags = [{'scope': 'user', 'tag': 'k8s'}]
|
||||
res_type = 'LogicalPort'
|
||||
query = self.nsxlib._build_query(tags=user_tags)
|
||||
# Add resource_type to the query
|
||||
query = "%s AND %s" % (res_type, query)
|
||||
self.nsxlib.search_by_tags(tags=user_tags, resource_type=res_type)
|
||||
search.assert_called_with('search?query=%s' % query)
|
||||
|
||||
def test_nsx_search_invalid_query_fail(self):
|
||||
"""Test search query failure for missing tag argument."""
|
||||
self.assertRaises(exceptions.NsxSearchInvalidQuery,
|
||||
self.nsxlib.search_by_tags,
|
||||
tags=None, resource_type=None)
|
||||
|
||||
def test_nsx_search_invalid_tags_fail(self):
|
||||
"""Test search of resources with the invalid tag."""
|
||||
user_tags = [{'scope': 'user', 'invalid_tag_key': 'k8s'}]
|
||||
self.assertRaises(exceptions.NsxSearchInvalidQuery,
|
||||
self.nsxlib._build_query,
|
||||
tags=user_tags)
|
||||
|
@ -99,6 +99,39 @@ class NsxLib(object):
|
||||
def subscribe(self, callback, event):
|
||||
self.cluster.subscribe(callback, event)
|
||||
|
||||
# TODO(abhiraut): Revisit this method to generate complex boolean
|
||||
# queries to search resources.
|
||||
def search_by_tags(self, tags, resource_type=None):
|
||||
"""Return the list of resources searched based on tags.
|
||||
|
||||
Currently the query only supports AND boolean operator.
|
||||
:param tags: List of dictionaries containing tags. Each
|
||||
NSX tag dictionary is of the form:
|
||||
{'scope': <scope_key>, 'tag': <tag_value>}
|
||||
:param resource_type: Optional string parameter to limit the
|
||||
scope of the search to the given ResourceType.
|
||||
"""
|
||||
if not tags:
|
||||
reason = _("Missing required argument 'tags'")
|
||||
raise exceptions.NsxSearchInvalidQuery(reason=reason)
|
||||
# Query will return nothing if the same scope is repeated.
|
||||
query_tags = self._build_query(tags)
|
||||
query = resource_type
|
||||
if query:
|
||||
query += " AND %s" % query_tags
|
||||
else:
|
||||
query = query_tags
|
||||
url = "search?query=%s" % query
|
||||
return self.client.url_get(url)
|
||||
|
||||
def _build_query(self, tags):
|
||||
try:
|
||||
return " AND ".join(['tags.scope:%(scope)s AND '
|
||||
'tags.tag:%(tag)s' % item for item in tags])
|
||||
except KeyError as e:
|
||||
reason = _('Missing key:%s in tags') % str(e)
|
||||
raise exceptions.NsxSearchInvalidQuery(reason=reason)
|
||||
|
||||
|
||||
class NsxLibPortMirror(utils.NsxLibApiBase):
|
||||
|
||||
|
@ -119,3 +119,7 @@ class NumberOfNsgroupCriteriaTagsReached(ManagerError):
|
||||
class SecurityGroupMaximumCapacityReached(ManagerError):
|
||||
message = _("Security Group %(sg_id)s has reached its maximum capacity, "
|
||||
"no more ports can be associated with this security-group.")
|
||||
|
||||
|
||||
class NsxSearchInvalidQuery(NsxLibException):
|
||||
message = _("Invalid input for NSX search query. Reason: %(reason)s")
|
||||
|
Loading…
x
Reference in New Issue
Block a user