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:
parent
f7bc040a92
commit
67d3448136
|
@ -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)
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue