diff --git a/doc/api_samples/os-hypervisors/v2.28/hypervisors-detail-resp.json b/doc/api_samples/os-hypervisors/v2.28/hypervisors-detail-resp.json new file mode 100644 index 000000000000..db5934bfb76c --- /dev/null +++ b/doc/api_samples/os-hypervisors/v2.28/hypervisors-detail-resp.json @@ -0,0 +1,43 @@ +{ + "hypervisors": [ + { + "cpu_info": { + "arch": "x86_64", + "model": "Nehalem", + "vendor": "Intel", + "features": [ + "pge", + "clflush" + ], + "topology": { + "cores": 1, + "threads": 1, + "sockets": 4 + } + }, + "current_workload": 0, + "status": "enabled", + "state": "up", + "disk_available_least": 0, + "host_ip": "1.1.1.1", + "free_disk_gb": 1028, + "free_ram_mb": 7680, + "hypervisor_hostname": "fake-mini", + "hypervisor_type": "fake", + "hypervisor_version": 1000, + "id": 1, + "local_gb": 1028, + "local_gb_used": 0, + "memory_mb": 8192, + "memory_mb_used": 512, + "running_vms": 0, + "service": { + "host": "e6a37ee802d74863ab8b91ade8f12a67", + "id": 2, + "disabled_reason": null + }, + "vcpus": 1, + "vcpus_used": 0 + } + ] +} diff --git a/doc/api_samples/os-hypervisors/v2.28/hypervisors-list-resp.json b/doc/api_samples/os-hypervisors/v2.28/hypervisors-list-resp.json new file mode 100644 index 000000000000..375627499df6 --- /dev/null +++ b/doc/api_samples/os-hypervisors/v2.28/hypervisors-list-resp.json @@ -0,0 +1,10 @@ +{ + "hypervisors": [ + { + "hypervisor_hostname": "fake-mini", + "id": 1, + "state": "up", + "status": "enabled" + } + ] +} diff --git a/doc/api_samples/os-hypervisors/v2.28/hypervisors-search-resp.json b/doc/api_samples/os-hypervisors/v2.28/hypervisors-search-resp.json new file mode 100644 index 000000000000..375627499df6 --- /dev/null +++ b/doc/api_samples/os-hypervisors/v2.28/hypervisors-search-resp.json @@ -0,0 +1,10 @@ +{ + "hypervisors": [ + { + "hypervisor_hostname": "fake-mini", + "id": 1, + "state": "up", + "status": "enabled" + } + ] +} diff --git a/doc/api_samples/os-hypervisors/v2.28/hypervisors-show-resp.json b/doc/api_samples/os-hypervisors/v2.28/hypervisors-show-resp.json new file mode 100644 index 000000000000..03c9a5d2492e --- /dev/null +++ b/doc/api_samples/os-hypervisors/v2.28/hypervisors-show-resp.json @@ -0,0 +1,41 @@ +{ + "hypervisor": { + "cpu_info": { + "arch": "x86_64", + "model": "Nehalem", + "vendor": "Intel", + "features": [ + "pge", + "clflush" + ], + "topology": { + "cores": 1, + "threads": 1, + "sockets": 4 + } + }, + "state": "up", + "status": "enabled", + "current_workload": 0, + "disk_available_least": 0, + "host_ip": "1.1.1.1", + "free_disk_gb": 1028, + "free_ram_mb": 7680, + "hypervisor_hostname": "fake-mini", + "hypervisor_type": "fake", + "hypervisor_version": 1000, + "id": 1, + "local_gb": 1028, + "local_gb_used": 0, + "memory_mb": 8192, + "memory_mb_used": 512, + "running_vms": 0, + "service": { + "host": "043b3cacf6f34c90a7245151fc8ebcda", + "id": 2, + "disabled_reason": null + }, + "vcpus": 1, + "vcpus_used": 0 + } +} diff --git a/doc/api_samples/os-hypervisors/v2.28/hypervisors-statistics-resp.json b/doc/api_samples/os-hypervisors/v2.28/hypervisors-statistics-resp.json new file mode 100644 index 000000000000..2cfb51e7030a --- /dev/null +++ b/doc/api_samples/os-hypervisors/v2.28/hypervisors-statistics-resp.json @@ -0,0 +1,16 @@ +{ + "hypervisor_statistics": { + "count": 1, + "current_workload": 0, + "disk_available_least": 0, + "free_disk_gb": 1028, + "free_ram_mb": 7680, + "local_gb": 1028, + "local_gb_used": 0, + "memory_mb": 8192, + "memory_mb_used": 512, + "running_vms": 0, + "vcpus": 1, + "vcpus_used": 0 + } +} \ No newline at end of file diff --git a/doc/api_samples/os-hypervisors/v2.28/hypervisors-uptime-resp.json b/doc/api_samples/os-hypervisors/v2.28/hypervisors-uptime-resp.json new file mode 100644 index 000000000000..78521b373112 --- /dev/null +++ b/doc/api_samples/os-hypervisors/v2.28/hypervisors-uptime-resp.json @@ -0,0 +1,9 @@ +{ + "hypervisor": { + "hypervisor_hostname": "fake-mini", + "id": 1, + "state": "up", + "status": "enabled", + "uptime": " 08:32:11 up 93 days, 18:25, 12 users, load average: 0.20, 0.12, 0.14" + } +} diff --git a/doc/api_samples/os-hypervisors/v2.28/hypervisors-with-servers-resp.json b/doc/api_samples/os-hypervisors/v2.28/hypervisors-with-servers-resp.json new file mode 100644 index 000000000000..61ccaa7dd79e --- /dev/null +++ b/doc/api_samples/os-hypervisors/v2.28/hypervisors-with-servers-resp.json @@ -0,0 +1,20 @@ +{ + "hypervisors": [ + { + "hypervisor_hostname": "fake-mini", + "id": 1, + "state": "up", + "status": "enabled", + "servers": [ + { + "name": "test_server1", + "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "name": "test_server2", + "uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + } + ] + } + ] +} diff --git a/doc/api_samples/os-hypervisors/v2.28/hypervisors-without-servers-resp.json b/doc/api_samples/os-hypervisors/v2.28/hypervisors-without-servers-resp.json new file mode 100644 index 000000000000..375627499df6 --- /dev/null +++ b/doc/api_samples/os-hypervisors/v2.28/hypervisors-without-servers-resp.json @@ -0,0 +1,10 @@ +{ + "hypervisors": [ + { + "hypervisor_hostname": "fake-mini", + "id": 1, + "state": "up", + "status": "enabled" + } + ] +} diff --git a/doc/api_samples/versions/v21-version-get-resp.json b/doc/api_samples/versions/v21-version-get-resp.json index 4fa05093fbc7..fd39e1faa39b 100644 --- a/doc/api_samples/versions/v21-version-get-resp.json +++ b/doc/api_samples/versions/v21-version-get-resp.json @@ -19,7 +19,7 @@ } ], "status": "CURRENT", - "version": "2.27", + "version": "2.28", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" } diff --git a/doc/api_samples/versions/versions-get-resp.json b/doc/api_samples/versions/versions-get-resp.json index e11ae184db78..432ff2f87ad0 100644 --- a/doc/api_samples/versions/versions-get-resp.json +++ b/doc/api_samples/versions/versions-get-resp.json @@ -22,7 +22,7 @@ } ], "status": "CURRENT", - "version": "2.27", + "version": "2.28", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" } diff --git a/nova/api/openstack/api_version_request.py b/nova/api/openstack/api_version_request.py index 074ce92bb828..889a5e8b5c9d 100644 --- a/nova/api/openstack/api_version_request.py +++ b/nova/api/openstack/api_version_request.py @@ -74,6 +74,7 @@ REST_API_VERSION_HISTORY = """REST API Version History: * 2.26 - Adds support of server tags * 2.27 - Adds support for new-style microversion headers while keeping support for the original style. + * 2.28 - Changes compute_node.cpu_info from string to object """ # The minimum and maximum versions of the API supported @@ -82,7 +83,7 @@ REST_API_VERSION_HISTORY = """REST API Version History: # Note(cyeoh): This only applies for the v2.1 API once microversions # support is fully merged. It does not affect the V2 API. _MIN_API_VERSION = "2.1" -_MAX_API_VERSION = "2.27" +_MAX_API_VERSION = "2.28" DEFAULT_API_VERSION = _MIN_API_VERSION diff --git a/nova/api/openstack/compute/hypervisors.py b/nova/api/openstack/compute/hypervisors.py index 8d2168a66bbb..e7e315528c2e 100644 --- a/nova/api/openstack/compute/hypervisors.py +++ b/nova/api/openstack/compute/hypervisors.py @@ -15,8 +15,10 @@ """The hypervisors admin extension.""" +from oslo_serialization import jsonutils import webob.exc +from nova.api.openstack import api_version_request from nova.api.openstack import common from nova.api.openstack import extensions from nova.api.openstack import wsgi @@ -38,7 +40,7 @@ class HypervisorsController(wsgi.Controller): self.servicegroup_api = servicegroup.API() super(HypervisorsController, self).__init__() - def _view_hypervisor(self, hypervisor, service, detail, servers=None, + def _view_hypervisor(self, hypervisor, service, detail, req, servers=None, **kwargs): alive = self.servicegroup_api.service_is_up(service) hyp_dict = { @@ -54,8 +56,7 @@ class HypervisorsController(wsgi.Controller): 'memory_mb_used', 'local_gb_used', 'hypervisor_type', 'hypervisor_version', 'free_ram_mb', 'free_disk_gb', 'current_workload', - 'running_vms', 'cpu_info', 'disk_available_least', - 'host_ip'): + 'running_vms', 'disk_available_least', 'host_ip'): hyp_dict[field] = getattr(hypervisor, field) hyp_dict['service'] = { @@ -64,6 +65,11 @@ class HypervisorsController(wsgi.Controller): 'disabled_reason': service.disabled_reason, } + if api_version_request.is_supported(req, min_version='2.28'): + hyp_dict['cpu_info'] = jsonutils.loads(hypervisor.cpu_info) + else: + hyp_dict['cpu_info'] = hypervisor.cpu_info + if servers: hyp_dict['servers'] = [dict(name=serv['name'], uuid=serv['uuid']) for serv in servers] @@ -84,7 +90,7 @@ class HypervisorsController(wsgi.Controller): hyp, self.host_api.service_get_by_compute_host( context, hyp.host), - False) + False, req) for hyp in compute_nodes]) @extensions.expected_errors(()) @@ -94,11 +100,8 @@ class HypervisorsController(wsgi.Controller): compute_nodes = self.host_api.compute_node_get_all(context) req.cache_db_compute_nodes(compute_nodes) return dict(hypervisors=[self._view_hypervisor( - hyp, - self.host_api.service_get_by_compute_host( - context, hyp.host), - True) - for hyp in compute_nodes]) + hyp, self.host_api.service_get_by_compute_host(context, hyp.host), + True, req) for hyp in compute_nodes]) @extensions.expected_errors(404) def show(self, req, id): @@ -112,7 +115,8 @@ class HypervisorsController(wsgi.Controller): raise webob.exc.HTTPNotFound(explanation=msg) service = self.host_api.service_get_by_compute_host( context, hyp.host) - return dict(hypervisor=self._view_hypervisor(hyp, service, True)) + return dict(hypervisor=self._view_hypervisor( + hyp, service, True, req)) @extensions.expected_errors((400, 404, 501)) def uptime(self, req, id): @@ -135,7 +139,7 @@ class HypervisorsController(wsgi.Controller): raise webob.exc.HTTPBadRequest(explanation=e.format_message()) service = self.host_api.service_get_by_compute_host(context, host) - return dict(hypervisor=self._view_hypervisor(hyp, service, False, + return dict(hypervisor=self._view_hypervisor(hyp, service, False, req, uptime=uptime)) @extensions.expected_errors(404) @@ -149,7 +153,7 @@ class HypervisorsController(wsgi.Controller): hyp, self.host_api.service_get_by_compute_host( context, hyp.host), - False) + False, req) for hyp in hypervisors]) else: msg = _("No hypervisor matching '%s' could be found.") % id @@ -170,7 +174,7 @@ class HypervisorsController(wsgi.Controller): compute_node.host) service = self.host_api.service_get_by_compute_host( context, compute_node.host) - hyp = self._view_hypervisor(compute_node, service, False, + hyp = self._view_hypervisor(compute_node, service, False, req, instances) hypervisors.append(hyp) return dict(hypervisors=hypervisors) diff --git a/nova/api/openstack/rest_api_version_history.rst b/nova/api/openstack/rest_api_version_history.rst index 36697c47e1a0..df792fa26c43 100644 --- a/nova/api/openstack/rest_api_version_history.rst +++ b/nova/api/openstack/rest_api_version_history.rst @@ -291,3 +291,12 @@ user documentation. `Microversion Specification `_. Both the original form of header and the new form is supported. + +2.28 +---- + + Nova API hypervisor.cpu_info change from string to JSON object. + + From this version of the API the hypervisor's 'cpu_info' field will be + will returned as JSON object (not string) by sending GET request + to the /v2.1/os-hypervisors/{hypervisor_id}. diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-detail-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-detail-resp.json.tpl new file mode 100644 index 000000000000..6d51132137f3 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-detail-resp.json.tpl @@ -0,0 +1,43 @@ +{ + "hypervisors": [ + { + "cpu_info": { + "arch": "x86_64", + "model": "Nehalem", + "vendor": "Intel", + "features": [ + "pge", + "clflush" + ], + "topology": { + "cores": 1, + "threads": 1, + "sockets": 4 + } + }, + "current_workload": 0, + "state": "up", + "status": "enabled", + "disk_available_least": 0, + "host_ip": "%(ip)s", + "free_disk_gb": 1028, + "free_ram_mb": 7680, + "hypervisor_hostname": "fake-mini", + "hypervisor_type": "fake", + "hypervisor_version": 1000, + "id": %(hypervisor_id)s, + "local_gb": 1028, + "local_gb_used": 0, + "memory_mb": 8192, + "memory_mb_used": 512, + "running_vms": 0, + "service": { + "host": "%(host_name)s", + "id": 2, + "disabled_reason": null + }, + "vcpus": 1, + "vcpus_used": 0 + } + ] +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-list-resp.json.tpl new file mode 100644 index 000000000000..710cdfcf9cb0 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-list-resp.json.tpl @@ -0,0 +1,10 @@ +{ + "hypervisors": [ + { + "hypervisor_hostname": "fake-mini", + "state": "up", + "status": "enabled", + "id": 1 + } + ] +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-search-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-search-resp.json.tpl new file mode 100644 index 000000000000..375627499df6 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-search-resp.json.tpl @@ -0,0 +1,10 @@ +{ + "hypervisors": [ + { + "hypervisor_hostname": "fake-mini", + "id": 1, + "state": "up", + "status": "enabled" + } + ] +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-show-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-show-resp.json.tpl new file mode 100644 index 000000000000..3bcf0b449ef2 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-show-resp.json.tpl @@ -0,0 +1,41 @@ +{ + "hypervisor": { + "cpu_info": { + "arch": "x86_64", + "model": "Nehalem", + "vendor": "Intel", + "features": [ + "pge", + "clflush" + ], + "topology": { + "cores": 1, + "threads": 1, + "sockets": 4 + } + }, + "current_workload": 0, + "disk_available_least": 0, + "state": "up", + "status": "enabled", + "host_ip": "%(ip)s", + "free_disk_gb": 1028, + "free_ram_mb": 7680, + "hypervisor_hostname": "fake-mini", + "hypervisor_type": "fake", + "hypervisor_version": 1000, + "id": %(hypervisor_id)s, + "local_gb": 1028, + "local_gb_used": 0, + "memory_mb": 8192, + "memory_mb_used": 512, + "running_vms": 0, + "service": { + "host": "%(host_name)s", + "id": 2, + "disabled_reason": null + }, + "vcpus": 1, + "vcpus_used": 0 + } +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-statistics-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-statistics-resp.json.tpl new file mode 100644 index 000000000000..2cfb51e7030a --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-statistics-resp.json.tpl @@ -0,0 +1,16 @@ +{ + "hypervisor_statistics": { + "count": 1, + "current_workload": 0, + "disk_available_least": 0, + "free_disk_gb": 1028, + "free_ram_mb": 7680, + "local_gb": 1028, + "local_gb_used": 0, + "memory_mb": 8192, + "memory_mb_used": 512, + "running_vms": 0, + "vcpus": 1, + "vcpus_used": 0 + } +} \ No newline at end of file diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-uptime-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-uptime-resp.json.tpl new file mode 100644 index 000000000000..e2f6d2e47e74 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-uptime-resp.json.tpl @@ -0,0 +1,9 @@ +{ + "hypervisor": { + "hypervisor_hostname": "fake-mini", + "id": %(hypervisor_id)s, + "state": "up", + "status": "enabled", + "uptime": " 08:32:11 up 93 days, 18:25, 12 users, load average: 0.20, 0.12, 0.14" + } +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-with-servers-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-with-servers-resp.json.tpl new file mode 100644 index 000000000000..61ccaa7dd79e --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-with-servers-resp.json.tpl @@ -0,0 +1,20 @@ +{ + "hypervisors": [ + { + "hypervisor_hostname": "fake-mini", + "id": 1, + "state": "up", + "status": "enabled", + "servers": [ + { + "name": "test_server1", + "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + }, + { + "name": "test_server2", + "uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" + } + ] + } + ] +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-without-servers-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-without-servers-resp.json.tpl new file mode 100644 index 000000000000..375627499df6 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/os-hypervisors/v2.28/hypervisors-without-servers-resp.json.tpl @@ -0,0 +1,10 @@ +{ + "hypervisors": [ + { + "hypervisor_hostname": "fake-mini", + "id": 1, + "state": "up", + "status": "enabled" + } + ] +} diff --git a/nova/tests/functional/api_sample_tests/test_hypervisors.py b/nova/tests/functional/api_sample_tests/test_hypervisors.py index dedbcb210010..7a7d4554ee13 100644 --- a/nova/tests/functional/api_sample_tests/test_hypervisors.py +++ b/nova/tests/functional/api_sample_tests/test_hypervisors.py @@ -157,3 +157,12 @@ class HypervisorsCellsSampleJsonTests(api_sample_base.ApiSampleTestBaseV21): response = self._do_get('os-hypervisors/%s/uptime' % hypervisor_id) subs = {'hypervisor_id': str(hypervisor_id)} self._verify_response('hypervisors-uptime-resp', subs, response, 200) + + +class HypervisorsSampleJson228Tests(HypervisorsSampleJsonTests): + microversion = '2.28' + scenarios = [('v2_28', {'api_major_version': 'v2.1'})] + + def setUp(self): + super(HypervisorsSampleJson228Tests, self).setUp() + self.api.microversion = self.microversion diff --git a/nova/tests/unit/api/openstack/compute/test_extended_hypervisors.py b/nova/tests/unit/api/openstack/compute/test_extended_hypervisors.py index d9238e05a385..e9ad74cb29a8 100644 --- a/nova/tests/unit/api/openstack/compute/test_extended_hypervisors.py +++ b/nova/tests/unit/api/openstack/compute/test_extended_hypervisors.py @@ -79,9 +79,10 @@ class ExtendedHypervisorsTestV21(test.NoDBTestCase): fake_service_get_by_compute_host) def test_view_hypervisor_detail_noservers(self): + req = self._get_request() result = self.controller._view_hypervisor( test_hypervisors.TEST_HYPERS_OBJ[0], - test_hypervisors.TEST_SERVICES[0], True) + test_hypervisors.TEST_SERVICES[0], True, req) self.assertEqual(result, self.DETAIL_HYPERS_DICTS[0]) diff --git a/nova/tests/unit/api/openstack/compute/test_hypervisor_status.py b/nova/tests/unit/api/openstack/compute/test_hypervisor_status.py index 5fe40f0fe464..cb976f528e7c 100644 --- a/nova/tests/unit/api/openstack/compute/test_hypervisor_status.py +++ b/nova/tests/unit/api/openstack/compute/test_hypervisor_status.py @@ -21,6 +21,7 @@ from nova.api.openstack.compute import hypervisors \ from nova import objects from nova import test from nova.tests.unit.api.openstack.compute import test_hypervisors +from nova.tests.unit.api.openstack import fakes TEST_HYPER = test_hypervisors.TEST_HYPERS_OBJ[0].obj_clone() TEST_SERVICE = objects.Service(id=1, @@ -39,31 +40,37 @@ class HypervisorStatusTestV21(test.NoDBTestCase): self.controller.servicegroup_api.service_is_up = mock.MagicMock( return_value=True) + def _get_request(self): + return fakes.HTTPRequest.blank('/v2/fake/os-hypervisors/detail', + use_admin_context=True) + def test_view_hypervisor_service_status(self): self._prepare_extension() + req = self._get_request() result = self.controller._view_hypervisor( - TEST_HYPER, TEST_SERVICE, False) + TEST_HYPER, TEST_SERVICE, False, req) self.assertEqual('enabled', result['status']) self.assertEqual('up', result['state']) self.assertEqual('enabled', result['status']) self.controller.servicegroup_api.service_is_up.return_value = False result = self.controller._view_hypervisor( - TEST_HYPER, TEST_SERVICE, False) + TEST_HYPER, TEST_SERVICE, False, req) self.assertEqual('down', result['state']) hyper = copy.deepcopy(TEST_HYPER) service = copy.deepcopy(TEST_SERVICE) service.disabled = True - result = self.controller._view_hypervisor(hyper, service, False) + result = self.controller._view_hypervisor(hyper, service, False, req) self.assertEqual('disabled', result['status']) def test_view_hypervisor_detail_status(self): self._prepare_extension() + req = self._get_request() result = self.controller._view_hypervisor( - TEST_HYPER, TEST_SERVICE, True) + TEST_HYPER, TEST_SERVICE, True, req) self.assertEqual('enabled', result['status']) self.assertEqual('up', result['state']) @@ -71,13 +78,13 @@ class HypervisorStatusTestV21(test.NoDBTestCase): self.controller.servicegroup_api.service_is_up.return_value = False result = self.controller._view_hypervisor( - TEST_HYPER, TEST_SERVICE, True) + TEST_HYPER, TEST_SERVICE, True, req) self.assertEqual('down', result['state']) hyper = copy.deepcopy(TEST_HYPER) service = copy.deepcopy(TEST_SERVICE) service.disabled = True service.disabled_reason = "fake" - result = self.controller._view_hypervisor(hyper, service, True) + result = self.controller._view_hypervisor(hyper, service, True, req) self.assertEqual('disabled', result['status'],) self.assertEqual('fake', result['service']['disabled_reason']) diff --git a/nova/tests/unit/api/openstack/compute/test_hypervisors.py b/nova/tests/unit/api/openstack/compute/test_hypervisors.py index 6be2584574f9..ae11e74ac152 100644 --- a/nova/tests/unit/api/openstack/compute/test_hypervisors.py +++ b/nova/tests/unit/api/openstack/compute/test_hypervisors.py @@ -16,6 +16,7 @@ import copy import mock import netaddr +from oslo_serialization import jsonutils from webob import exc from nova.api.openstack.compute import hypervisors \ @@ -28,6 +29,12 @@ from nova.tests.unit.api.openstack import fakes from nova.tests.unit import fake_instance from nova.tests import uuidsentinel as uuids +CPU_INFO = """ +{"arch": "x86_64", +"vendor": "fake", +"topology": {"cores": 1, "threads": 1, "sockets": 1}, +"features": [], +"model": ""}""" TEST_HYPERS = [ dict(id=1, @@ -46,7 +53,7 @@ TEST_HYPERS = [ free_disk_gb=125, current_workload=2, running_vms=2, - cpu_info='cpu_info', + cpu_info=CPU_INFO, disk_available_least=100, host_ip=netaddr.IPAddress('1.1.1.1')), dict(id=2, @@ -65,7 +72,7 @@ TEST_HYPERS = [ free_disk_gb=125, current_workload=2, running_vms=2, - cpu_info='cpu_info', + cpu_info=CPU_INFO, disk_available_least=100, host_ip=netaddr.IPAddress('2.2.2.2'))] @@ -158,6 +165,8 @@ def fake_instance_get_all_by_host(context, host): class HypervisorsTestV21(test.NoDBTestCase): + api_version = '2.1' + # copying the objects locally so the cells testcases can provide their own TEST_HYPERS_OBJ = copy.deepcopy(TEST_HYPERS_OBJ) TEST_SERVICES = copy.deepcopy(TEST_SERVICES) @@ -176,7 +185,6 @@ class HypervisorsTestV21(test.NoDBTestCase): 'status': 'enabled', 'service': dict(id=2, host='compute2', disabled_reason=None)}) - INDEX_HYPER_DICTS = [ dict(id=1, hypervisor_hostname="hyper1", state='up', status='enabled'), @@ -184,7 +192,8 @@ class HypervisorsTestV21(test.NoDBTestCase): state='up', status='enabled')] def _get_request(self, use_admin_context): - return fakes.HTTPRequest.blank('', use_admin_context=use_admin_context) + return fakes.HTTPRequest.blank('', use_admin_context=use_admin_context, + version=self.api_version) def _set_up_controller(self): self.controller = hypervisors_v21.HypervisorsController() @@ -208,21 +217,25 @@ class HypervisorsTestV21(test.NoDBTestCase): fake_compute_node_statistics) def test_view_hypervisor_nodetail_noservers(self): + req = self._get_request(True) result = self.controller._view_hypervisor( - self.TEST_HYPERS_OBJ[0], self.TEST_SERVICES[0], False) + self.TEST_HYPERS_OBJ[0], self.TEST_SERVICES[0], False, req) self.assertEqual(result, self.INDEX_HYPER_DICTS[0]) def test_view_hypervisor_detail_noservers(self): + req = self._get_request(True) result = self.controller._view_hypervisor( - self.TEST_HYPERS_OBJ[0], self.TEST_SERVICES[0], True) + self.TEST_HYPERS_OBJ[0], self.TEST_SERVICES[0], True, req) self.assertEqual(result, self.DETAIL_HYPERS_DICTS[0]) def test_view_hypervisor_servers(self): + req = self._get_request(True) result = self.controller._view_hypervisor(self.TEST_HYPERS_OBJ[0], self.TEST_SERVICES[0], - False, self.TEST_SERVERS) + False, req, + self.TEST_SERVERS) expected_dict = copy.deepcopy(self.INDEX_HYPER_DICTS[0]) expected_dict.update({'servers': [ dict(name="inst1", uuid=uuids.instance_1), @@ -511,3 +524,11 @@ class CellHypervisorsTestV21(HypervisorsTestV21): fake_compute_node_statistics) self.stubs.Set(self.controller.host_api, 'instance_get_all_by_host', self.fake_instance_get_all_by_host) + + +class HypervisorsTestV228(HypervisorsTestV21): + api_version = '2.28' + + DETAIL_HYPERS_DICTS = copy.deepcopy(HypervisorsTestV21.DETAIL_HYPERS_DICTS) + DETAIL_HYPERS_DICTS[0]['cpu_info'] = jsonutils.loads(CPU_INFO) + DETAIL_HYPERS_DICTS[1]['cpu_info'] = jsonutils.loads(CPU_INFO) diff --git a/releasenotes/notes/bp-nova-api-hypervsor-cpu-info-b84cddf8b70b88d2.yaml b/releasenotes/notes/bp-nova-api-hypervsor-cpu-info-b84cddf8b70b88d2.yaml new file mode 100644 index 000000000000..f0dd7570e9ed --- /dev/null +++ b/releasenotes/notes/bp-nova-api-hypervsor-cpu-info-b84cddf8b70b88d2.yaml @@ -0,0 +1,4 @@ +--- +features: + - Added microversion v2.28 from which hypervisor's 'cpu_info' field returned + as JSON object by sending GET /v2.1/os-hypervisors/{hypervisor_id} request.