Merge config drive extension response into server controller

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 config drive extension resposne into server controller.

Partially implements: blueprint api-extensions-merge-stein

Change-Id: I5725e37b5640b91f388af9b12ac1b3dad4d438a7
This commit is contained in:
ghanshyam 2018-08-15 12:01:28 +00:00 committed by Matt Riedemann
parent f7bc040a92
commit 67d3448136
6 changed files with 15 additions and 120 deletions

View File

@ -1,45 +0,0 @@
# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Config Drive extension."""
from nova.api.openstack import wsgi
ATTRIBUTE_NAME = "config_drive"
class ConfigDriveController(wsgi.Controller):
def _add_config_drive(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[ATTRIBUTE_NAME] = db_server['config_drive']
def _show(self, req, resp_obj):
if 'server' in resp_obj.obj:
server = resp_obj.obj['server']
self._add_config_drive(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_config_drive(req, servers)

View File

@ -28,7 +28,6 @@ from nova.api.openstack.compute import baremetal_nodes
from nova.api.openstack.compute import cells
from nova.api.openstack.compute import certificates
from nova.api.openstack.compute import cloudpipe
from nova.api.openstack.compute import config_drive
from nova.api.openstack.compute import console_auth_tokens
from nova.api.openstack.compute import console_output
from nova.api.openstack.compute import consoles
@ -268,7 +267,6 @@ security_group_rules_controller = functools.partial(_create_controller,
server_controller = functools.partial(_create_controller,
servers.ServersController,
[
config_drive.ConfigDriveController,
extended_server_attributes.ExtendedServerAttributesController,
extended_status.ExtendedStatusController,
extended_volumes.ExtendedVolumesController,

View File

@ -718,7 +718,8 @@ class ServersController(wsgi.Controller):
update_dict)
return self._view_builder.show(req, instance,
extend_address=False,
show_AZ=False)
show_AZ=False,
show_config_drive=False)
except exception.InstanceNotFound:
msg = _("Instance could not be found")
raise exc.HTTPNotFound(explanation=msg)
@ -983,7 +984,8 @@ class ServersController(wsgi.Controller):
instance = self._get_server(context, req, id, is_detail=True)
view = self._view_builder.show(req, instance, extend_address=False,
show_AZ=False)
show_AZ=False,
show_config_drive=False)
# Add on the admin_password attribute since the view doesn't do it
# unless instance passwords are disabled

View File

@ -111,7 +111,7 @@ class ViewBuilder(common.ViewBuilder):
return sorted(list(set(self._show_expected_attrs + expected_attrs)))
def show(self, request, instance, extend_address=True,
show_extra_specs=None, show_AZ=True):
show_extra_specs=None, show_AZ=True, show_config_drive=True):
"""Detailed view of a single instance."""
ip_v4 = instance.get('access_ip_v4')
ip_v6 = instance.get('access_ip_v6')
@ -169,6 +169,9 @@ class ViewBuilder(common.ViewBuilder):
# with v2.0.
server["server"]["OS-EXT-AZ:availability_zone"] = az or ''
if show_config_drive:
server["server"]["config_drive"] = instance["config_drive"]
if api_version_request.is_supported(request, min_version="2.9"):
server["server"]["locked"] = (True if instance["locked_by"]
else False)

View File

@ -1,70 +0,0 @@
# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from oslo_serialization import jsonutils
from nova import objects
from nova import test
from nova.tests.unit.api.openstack import fakes
from nova.tests.unit.image import fake
from nova.tests import uuidsentinel as uuids
class ConfigDriveTestV21(test.TestCase):
base_url = '/v2/fake/servers/'
def _setup_wsgi(self):
self.app = fakes.wsgi_app_v21()
def setUp(self):
super(ConfigDriveTestV21, self).setUp()
fakes.stub_out_networking(self)
fake.stub_out_image_service(self)
fakes.stub_out_secgroup_api(self)
self._setup_wsgi()
def test_show(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 + uuids.sentinel)
req.headers['Content-Type'] = 'application/json'
response = req.get_response(self.app)
self.assertEqual(response.status_int, 200)
res_dict = jsonutils.loads(response.body)
self.assertIn('config_drive', res_dict['server'])
@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 + 'detail')
res = req.get_response(self.app)
server_dicts = jsonutils.loads(res.body)['servers']
self.assertNotEqual(len(server_dicts), 0)
for server_dict in server_dicts:
self.assertIn('config_drive', server_dict)

View File

@ -378,6 +378,7 @@ class ServersControllerTest(ControllerTest):
"accessIPv4": '',
"accessIPv6": '',
"OS-EXT-AZ:availability_zone": "nova",
"config_drive": None,
}
}
@ -2088,6 +2089,7 @@ class ServersControllerRebuildInstanceTest(ControllerTest):
body=body).obj
self.assertNotIn('OS-EXT-AZ:availability_zone', body['server'])
self.assertNotIn('config_drive', body['server'])
@mock.patch.object(compute_api.API, 'start')
def test_start(self, mock_start):
@ -2683,6 +2685,7 @@ class ServersControllerUpdateTest(ControllerTest):
req = self._get_request(body)
res_dict = self.controller.update(req, FAKE_UUID, body=body)
self.assertNotIn('OS-EXT-AZ:availability_zone', res_dict['server'])
self.assertNotIn('config_drive', res_dict['server'])
def test_update_server_name_too_long(self):
body = {'server': {'name': 'x' * 256}}
@ -5992,6 +5995,7 @@ class ServersViewBuilderTest(test.TestCase):
"accessIPv4": '',
"accessIPv6": '',
"OS-EXT-AZ:availability_zone": "nova",
"config_drive": None,
}
}
@ -6072,6 +6076,7 @@ class ServersViewBuilderTest(test.TestCase):
"accessIPv4": '',
"accessIPv6": '',
"OS-EXT-AZ:availability_zone": "nova",
"config_drive": None,
}
}
@ -6251,6 +6256,7 @@ class ServersViewBuilderTest(test.TestCase):
"accessIPv4": '',
"accessIPv6": '',
"OS-EXT-AZ:availability_zone": "nova",
"config_drive": None,
}
}
@ -6328,6 +6334,7 @@ class ServersViewBuilderTest(test.TestCase):
"accessIPv4": '',
"accessIPv6": '',
"OS-EXT-AZ:availability_zone": "nova",
"config_drive": None,
}
}