Merge keypair extension response into server view builder

As nova extensions has been deprecated already and goal is to
merge all scattered code into main controller side.
Currently schema and request/response extended code are there
among all extensions.

This commit merge the keypair extension resposne into server
view builder.

Partially implements: blueprint api-extensions-merge-stein

Change-Id: I606c5e9cf7a57b4054e91540f2801885527225fc
This commit is contained in:
ghanshyam 2018-08-15 12:45:53 +00:00 committed by Matt Riedemann
parent 82b98ad951
commit 5dd8622f92
6 changed files with 24 additions and 74 deletions

View File

@ -288,28 +288,3 @@ class KeypairController(wsgi.Controller):
keypairs_dict['keypairs_links'] = keypairs_links
return keypairs_dict
class Controller(wsgi.Controller):
def _add_key_name(self, req, servers):
for server in servers:
db_server = req.get_db_instance(server['id'])
# server['id'] is guaranteed to be in the cache due to
# the core API adding it in its 'show'/'detail' methods.
server['key_name'] = db_server['key_name']
def _show(self, req, resp_obj):
if 'server' in resp_obj.obj:
server = resp_obj.obj['server']
self._add_key_name(req, [server])
@wsgi.extends
def show(self, req, resp_obj, id):
self._show(req, resp_obj)
@wsgi.extends
def detail(self, req, resp_obj):
if 'servers' in resp_obj.obj:
servers = resp_obj.obj['servers']
self._add_key_name(req, servers)

View File

@ -269,7 +269,6 @@ server_controller = functools.partial(_create_controller,
extended_status.ExtendedStatusController,
extended_volumes.ExtendedVolumesController,
hide_server_addresses.Controller,
keypairs.Controller,
security_groups.SecurityGroupsOutputController,
server_usage.ServerUsageController,
],

View File

@ -721,7 +721,8 @@ class ServersController(wsgi.Controller):
show_AZ=False,
show_config_drive=False,
show_extended_attr=False,
show_host_status=False)
show_host_status=False,
show_keypair=False)
except exception.InstanceNotFound:
msg = _("Instance could not be found")
raise exc.HTTPNotFound(explanation=msg)
@ -985,21 +986,22 @@ class ServersController(wsgi.Controller):
instance = self._get_server(context, req, id, is_detail=True)
# NOTE(liuyulong): set the new key_name for the API response.
# from microversion 2.54 onwards.
show_keypair = api_version_request.is_supported(
req, min_version='2.54')
view = self._view_builder.show(req, instance, extend_address=False,
show_AZ=False,
show_config_drive=False,
show_extended_attr=False,
show_host_status=False)
show_host_status=False,
show_keypair=show_keypair)
# Add on the admin_password attribute since the view doesn't do it
# unless instance passwords are disabled
if CONF.api.enable_instance_password:
view['server']['adminPass'] = password
if api_version_request.is_supported(req, min_version='2.54'):
# NOTE(liuyulong): set the new key_name for the API response.
view['server']['key_name'] = instance.key_name
if include_user_data:
view['server']['user_data'] = instance.user_data

View File

@ -117,7 +117,8 @@ class ViewBuilder(common.ViewBuilder):
def show(self, request, instance, extend_address=True,
show_extra_specs=None, show_AZ=True, show_config_drive=True,
show_extended_attr=None, show_host_status=None):
show_extended_attr=None, show_host_status=None,
show_keypair=True):
"""Detailed view of a single instance."""
ip_v4 = instance.get('access_ip_v4')
ip_v6 = instance.get('access_ip_v6')
@ -178,6 +179,9 @@ class ViewBuilder(common.ViewBuilder):
if show_config_drive:
server["server"]["config_drive"] = instance["config_drive"]
if show_keypair:
server["server"]["key_name"] = instance["key_name"]
if show_extended_attr is None:
show_extended_attr = context.can(
esa_policies.BASE_POLICY_NAME, fatal=False)

View File

@ -15,7 +15,6 @@
import mock
from oslo_policy import policy as oslo_policy
from oslo_serialization import jsonutils
import webob
from nova.api.openstack.compute import keypairs as keypairs_v21
@ -29,7 +28,6 @@ from nova import quota
from nova import test
from nova.tests.unit.api.openstack import fakes
from nova.tests.unit.objects import test_keypair
from nova.tests import uuidsentinel as uuids
QUOTAS = quota.QUOTAS
@ -317,44 +315,6 @@ class KeypairsTestV21(test.TestCase):
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.show, self.req, 'FAKE')
def test_show_server(self):
self.stub_out('nova.db.api.instance_get',
fakes.fake_instance_get())
self.stub_out('nova.db.api.instance_get_by_uuid',
fakes.fake_instance_get())
# NOTE(sdague): because of the way extensions work, we have to
# also stub out the Request compute cache with a real compute
# object. Delete this once we remove all the gorp of
# extensions modifying the server objects.
self.stub_out('nova.api.openstack.wsgi.Request.get_db_instance',
fakes.fake_compute_get())
req = fakes.HTTPRequest.blank(
self.base_url + '/servers/' + uuids.server)
req.headers['Content-Type'] = 'application/json'
response = req.get_response(self.app_server)
self.assertEqual(response.status_int, 200)
res_dict = jsonutils.loads(response.body)
self.assertIn('key_name', res_dict['server'])
self.assertEqual(res_dict['server']['key_name'], '')
@mock.patch('nova.compute.api.API.get_all')
def test_detail_servers(self, mock_get_all):
# NOTE(danms): Orphan these fakes (no context) so that we
# are sure that the API is requesting what it needs without
# having to lazy-load.
mock_get_all.return_value = objects.InstanceList(
objects=[fakes.stub_instance_obj(ctxt=None, id=1),
fakes.stub_instance_obj(ctxt=None, id=2)])
req = fakes.HTTPRequest.blank(self.base_url + '/servers/detail')
res = req.get_response(self.app_server)
server_dicts = jsonutils.loads(res.body)['servers']
self.assertEqual(len(server_dicts), 2)
for server_dict in server_dicts:
self.assertIn('key_name', server_dict)
self.assertEqual(server_dict['key_name'], '')
def _assert_keypair_type(self, res_dict):
self.assertNotIn('type', res_dict['keypair'])

View File

@ -385,6 +385,7 @@ class ServersControllerTest(ControllerTest):
"OS-EXT-SRV-ATTR:host": None,
"OS-EXT-SRV-ATTR:hypervisor_hostname": None,
"OS-EXT-SRV-ATTR:instance_name": "instance-00000002",
"key_name": ''
}
}
@ -2065,6 +2066,7 @@ class ServersControllerDeleteTest(ControllerTest):
class ServersControllerRebuildInstanceTest(ControllerTest):
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
expected_key_name = False
def setUp(self):
super(ServersControllerRebuildInstanceTest, self).setUp()
@ -2334,6 +2336,8 @@ class ServersControllerRebuildInstanceTest(ControllerTest):
'OS-EXT-SRV-ATTR:reservation_id',
'OS-EXT-SRV-ATTR:root_device_name',
'OS-EXT-SRV-ATTR:user_data', 'host_status']
if not self.expected_key_name:
get_only_fields.append('key_name')
for field in get_only_fields:
self.assertNotIn(field, body['server'])
@ -2415,6 +2419,7 @@ class ServersControllerRebuildInstanceTest(ControllerTest):
class ServersControllerRebuildTestV254(ServersControllerRebuildInstanceTest):
expected_key_name = True
def setUp(self):
super(ServersControllerRebuildTestV254, self).setUp()
@ -2940,7 +2945,8 @@ class ServersControllerUpdateTest(ControllerTest):
'OS-EXT-SRV-ATTR:ramdisk_id',
'OS-EXT-SRV-ATTR:reservation_id',
'OS-EXT-SRV-ATTR:root_device_name',
'OS-EXT-SRV-ATTR:user_data', 'host_status']
'OS-EXT-SRV-ATTR:user_data', 'host_status',
'key_name']
for field in get_only_fields:
self.assertNotIn(field, res_dict['server'])
@ -6256,6 +6262,7 @@ class ServersViewBuilderTest(test.TestCase):
"OS-EXT-SRV-ATTR:host": None,
"OS-EXT-SRV-ATTR:hypervisor_hostname": None,
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
"key_name": ''
}
}
@ -6340,6 +6347,7 @@ class ServersViewBuilderTest(test.TestCase):
"OS-EXT-SRV-ATTR:host": None,
"OS-EXT-SRV-ATTR:hypervisor_hostname": None,
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
"key_name": ''
}
}
@ -6523,6 +6531,7 @@ class ServersViewBuilderTest(test.TestCase):
"OS-EXT-SRV-ATTR:host": None,
"OS-EXT-SRV-ATTR:hypervisor_hostname": None,
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
"key_name": ''
}
}
@ -6604,6 +6613,7 @@ class ServersViewBuilderTest(test.TestCase):
"OS-EXT-SRV-ATTR:host": None,
"OS-EXT-SRV-ATTR:hypervisor_hostname": None,
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
"key_name": ''
}
}