diff --git a/novaclient/tests/functional/v2/test_hypervisors.py b/novaclient/tests/functional/v2/test_hypervisors.py index ca66a44a2..bb58648b9 100644 --- a/novaclient/tests/functional/v2/test_hypervisors.py +++ b/novaclient/tests/functional/v2/test_hypervisors.py @@ -26,3 +26,16 @@ class TestHypervisorsV2_53(TestHypervisorsV28): def test_list(self): 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) diff --git a/novaclient/tests/unit/v2/test_hypervisors.py b/novaclient/tests/unit/v2/test_hypervisors.py index 0c24209bc..3eaeb576f 100644 --- a/novaclient/tests/unit/v2/test_hypervisors.py +++ b/novaclient/tests/unit/v2/test_hypervisors.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +import six + from novaclient import api_versions from novaclient import exceptions from novaclient.tests.unit.fixture_data import client @@ -119,6 +121,14 @@ class HypervisorsTest(utils.FixturedTestCase): self.cs.hypervisors.search, 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): expected = [ dict(id=self.data_fixture.hyper_id_1, @@ -236,3 +246,16 @@ class HypervisorsV2_53Test(HypervisorsV233Test): def setUp(self): super(HypervisorsV2_53Test, self).setUp() 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) diff --git a/novaclient/v2/hypervisors.py b/novaclient/v2/hypervisors.py index 4b26bfc59..e6f5038c8 100644 --- a/novaclient/v2/hypervisors.py +++ b/novaclient/v2/hypervisors.py @@ -23,6 +23,8 @@ from six.moves.urllib import parse from novaclient import api_versions from novaclient import base +from novaclient import exceptions +from novaclient.i18n import _ from novaclient import utils @@ -76,7 +78,7 @@ class HypervisorManager(base.ManagerWithFind): """ 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. @@ -84,6 +86,8 @@ class HypervisorManager(base.ManagerWithFind): The hypervisor hosts are selected with the host name matching this pattern. :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 # deprecated and we get the same results using GET /os-hypervisors @@ -91,11 +95,16 @@ class HypervisorManager(base.ManagerWithFind): if six.PY2: hypervisor_match = encodeutils.safe_encode(hypervisor_match) if self.api_version >= api_versions.APIVersion('2.53'): - url = ('/os-hypervisors?hypervisor_hostname_pattern=%s' % - parse.quote(hypervisor_match, safe='')) + url = ('/os-hypervisors%s?hypervisor_hostname_pattern=%s' % + ('/detail' if detailed else '', + parse.quote(hypervisor_match, safe=''))) if servers: url += '&with_servers=True' else: + if detailed: + raise exceptions.UnsupportedVersion( + _('Parameter "detailed" requires API version 2.53 or ' + 'greater.')) target = 'servers' if servers else 'search' url = ('/os-hypervisors/%s/%s' % (parse.quote(hypervisor_match, safe=''), target)) diff --git a/releasenotes/notes/search-hypervisor-detailed-352f3ac70d42fe6e.yaml b/releasenotes/notes/search-hypervisor-detailed-352f3ac70d42fe6e.yaml new file mode 100644 index 000000000..026e1a283 --- /dev/null +++ b/releasenotes/notes/search-hypervisor-detailed-352f3ac70d42fe6e.yaml @@ -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.