Allow searching for hypervisors and getting back details

The 2.53 microversion allows listing hypervisors with
details and filtering on a hypervisor_hostname substring
pattern match.

This makes the python API binding HypervisorManager.search
method allow that as well by adding a new 'detailed' boolean
kwarg which defaults to False for backward compatibility for
the /search and /servers routes before 2.53, but allows
searching and getting detailed results back as well.

Change-Id: I81fa4520af3cc7f1298c262f4fdc4e15fbc6d7ba
This commit is contained in:
Matt Riedemann 2019-05-17 18:07:38 -04:00
parent dfb84228a2
commit 0dc6b96ec8
4 changed files with 56 additions and 3 deletions

View File

@ -26,3 +26,16 @@ class TestHypervisorsV2_53(TestHypervisorsV28):
def test_list(self): def test_list(self):
self._test_list(cpu_info_type=dict, uuid_as_id=True) self._test_list(cpu_info_type=dict, uuid_as_id=True)
def test_search_with_details(self):
# First find a hypervisor from the list to search on.
hypervisors = self.client.hypervisors.list()
# Now search for that hypervisor with details.
hypervisor = hypervisors[0]
hypervisors = self.client.hypervisors.search(
hypervisor.hypervisor_hostname, detailed=True)
self.assertEqual(1, len(hypervisors))
hypervisor = hypervisors[0]
# We know we got details if service is in the response.
self.assertIsNotNone(hypervisor.service,
'Expected service in hypervisor: %s' % hypervisor)

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import six
from novaclient import api_versions from novaclient import api_versions
from novaclient import exceptions from novaclient import exceptions
from novaclient.tests.unit.fixture_data import client from novaclient.tests.unit.fixture_data import client
@ -119,6 +121,14 @@ class HypervisorsTest(utils.FixturedTestCase):
self.cs.hypervisors.search, self.cs.hypervisors.search,
hypervisor_match) hypervisor_match)
def test_hypervisor_search_detailed(self):
# detailed=True is not supported before 2.53
ex = self.assertRaises(exceptions.UnsupportedVersion,
self.cs.hypervisors.search, 'hyper',
detailed=True)
self.assertIn('Parameter "detailed" requires API version 2.53 or '
'greater.', six.text_type(ex))
def test_hypervisor_servers(self): def test_hypervisor_servers(self):
expected = [ expected = [
dict(id=self.data_fixture.hyper_id_1, dict(id=self.data_fixture.hyper_id_1,
@ -236,3 +246,16 @@ class HypervisorsV2_53Test(HypervisorsV233Test):
def setUp(self): def setUp(self):
super(HypervisorsV2_53Test, self).setUp() super(HypervisorsV2_53Test, self).setUp()
self.cs.api_version = api_versions.APIVersion("2.53") self.cs.api_version = api_versions.APIVersion("2.53")
def test_hypervisor_search_detailed(self):
expected = [
dict(id=self.data_fixture.hyper_id_1,
hypervisor_hostname='hyper1'),
dict(id=self.data_fixture.hyper_id_2,
hypervisor_hostname='hyper2')]
result = self.cs.hypervisors.search('hyper', detailed=True)
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called(
'GET', '/os-hypervisors/detail?hypervisor_hostname_pattern=hyper')
for idx, hyper in enumerate(result):
self.compare_to_expected(expected[idx], hyper)

View File

@ -23,6 +23,8 @@ from six.moves.urllib import parse
from novaclient import api_versions from novaclient import api_versions
from novaclient import base from novaclient import base
from novaclient import exceptions
from novaclient.i18n import _
from novaclient import utils from novaclient import utils
@ -76,7 +78,7 @@ class HypervisorManager(base.ManagerWithFind):
""" """
return self._list_base(detailed=detailed, marker=marker, limit=limit) return self._list_base(detailed=detailed, marker=marker, limit=limit)
def search(self, hypervisor_match, servers=False): def search(self, hypervisor_match, servers=False, detailed=False):
""" """
Get a list of matching hypervisors. Get a list of matching hypervisors.
@ -84,6 +86,8 @@ class HypervisorManager(base.ManagerWithFind):
The hypervisor hosts are selected with the host name matching The hypervisor hosts are selected with the host name matching
this pattern. this pattern.
:param servers: If True, server information is also retrieved. :param servers: If True, server information is also retrieved.
:param detailed: If True, detailed hypervisor information is returned.
This requires API version 2.53 or greater.
""" """
# Starting with microversion 2.53, the /servers and /search routes are # Starting with microversion 2.53, the /servers and /search routes are
# deprecated and we get the same results using GET /os-hypervisors # deprecated and we get the same results using GET /os-hypervisors
@ -91,11 +95,16 @@ class HypervisorManager(base.ManagerWithFind):
if six.PY2: if six.PY2:
hypervisor_match = encodeutils.safe_encode(hypervisor_match) hypervisor_match = encodeutils.safe_encode(hypervisor_match)
if self.api_version >= api_versions.APIVersion('2.53'): if self.api_version >= api_versions.APIVersion('2.53'):
url = ('/os-hypervisors?hypervisor_hostname_pattern=%s' % url = ('/os-hypervisors%s?hypervisor_hostname_pattern=%s' %
parse.quote(hypervisor_match, safe='')) ('/detail' if detailed else '',
parse.quote(hypervisor_match, safe='')))
if servers: if servers:
url += '&with_servers=True' url += '&with_servers=True'
else: else:
if detailed:
raise exceptions.UnsupportedVersion(
_('Parameter "detailed" requires API version 2.53 or '
'greater.'))
target = 'servers' if servers else 'search' target = 'servers' if servers else 'search'
url = ('/os-hypervisors/%s/%s' % url = ('/os-hypervisors/%s/%s' %
(parse.quote(hypervisor_match, safe=''), target)) (parse.quote(hypervisor_match, safe=''), target))

View File

@ -0,0 +1,8 @@
---
features:
- |
The ``novaclient.v2.hypervisors.HypervisorManager.search`` method now
accepts a ``detailed`` boolean kwarg which defaults to False but when
True will search for the given hypervisor hostname match and return
details about any matching hypervisors. Specifying ``detailed=True``
requires compute API version 2.53 or greater.