From 87666c501439c4f7cf2863d06660d90fffc16870 Mon Sep 17 00:00:00 2001 From: ghanshyam Date: Thu, 28 Jun 2018 10:17:16 +0300 Subject: [PATCH] Merge server create for user data extension 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 server_create for user data extensions. Partially implements: blueprint api-extensions-merge-rocky Change-Id: I138b1ec4d14275b45922f6542e5f942d4615b916 --- nova/api/openstack/compute/servers.py | 3 +- nova/api/openstack/compute/user_data.py | 21 --- .../api/openstack/compute/test_serversV21.py | 24 +++ .../api/openstack/compute/test_user_data.py | 157 ------------------ 4 files changed, 25 insertions(+), 180 deletions(-) delete mode 100644 nova/api/openstack/compute/user_data.py delete mode 100644 nova/tests/unit/api/openstack/compute/test_user_data.py diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index c165d86d16dd..7e4e3f8cf88a 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -36,7 +36,6 @@ from nova.api.openstack.compute import multiple_create from nova.api.openstack.compute import scheduler_hints from nova.api.openstack.compute.schemas import servers as schema_servers from nova.api.openstack.compute import security_groups -from nova.api.openstack.compute import user_data from nova.api.openstack.compute.views import servers as views_servers from nova.api.openstack import wsgi from nova.api import validation @@ -76,7 +75,6 @@ class ServersController(wsgi.Controller): multiple_create.server_create, scheduler_hints.server_create, security_groups.server_create, - user_data.server_create, ] @staticmethod @@ -436,6 +434,7 @@ class ServersController(wsgi.Controller): # extension interface. But the final goal is that merging # all of extended code into ServersController. self._create_by_func_list(server_dict, create_kwargs, body) + create_kwargs['user_data'] = server_dict.get('user_data') availability_zone = server_dict.pop("availability_zone", None) diff --git a/nova/api/openstack/compute/user_data.py b/nova/api/openstack/compute/user_data.py deleted file mode 100644 index f9890bbbfcaa..000000000000 --- a/nova/api/openstack/compute/user_data.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# 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. - -ATTRIBUTE_NAME = 'user_data' - - -# NOTE(gmann): This function is not supposed to use 'body_deprecated_param' -# parameter as this is placed to handle scheduler_hint extension for V2.1. -def server_create(server_dict, create_kwargs, body_deprecated_param): - create_kwargs['user_data'] = server_dict.get(ATTRIBUTE_NAME) diff --git a/nova/tests/unit/api/openstack/compute/test_serversV21.py b/nova/tests/unit/api/openstack/compute/test_serversV21.py index a17e34caadd7..556982389ba2 100644 --- a/nova/tests/unit/api/openstack/compute/test_serversV21.py +++ b/nova/tests/unit/api/openstack/compute/test_serversV21.py @@ -4011,6 +4011,30 @@ class ServersControllerCreateTest(test.TestCase): self.assertRaises(webob.exc.HTTPBadRequest, self._test_create_extra, {}) + def test_create_instance_with_user_data(self): + value = base64.encode_as_text("A random string") + params = {'user_data': value} + self._test_create_extra(params) + + def test_create_instance_with_bad_user_data(self): + value = "A random string" + params = {'user_data': value} + self.assertRaises(exception.ValidationError, + self._test_create_extra, params) + + @mock.patch('nova.compute.api.API.create') + def test_create_instance_with_none_allowd_for_v20_compat_mode(self, + mock_create): + + def create(context, *args, **kwargs): + self.assertIsNone(kwargs['user_data']) + return ([fakes.stub_instance_obj(context)], None) + + mock_create.side_effect = create + self.req.set_legacy_v2() + params = {'user_data': None} + self._test_create_extra(params) + class ServersControllerCreateTestV219(ServersControllerCreateTest): def _create_instance_req(self, set_desc, desc=None): diff --git a/nova/tests/unit/api/openstack/compute/test_user_data.py b/nova/tests/unit/api/openstack/compute/test_user_data.py deleted file mode 100644 index c78edd22e39b..000000000000 --- a/nova/tests/unit/api/openstack/compute/test_user_data.py +++ /dev/null @@ -1,157 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# Copyright 2013 IBM Corp. -# 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 datetime - -import mock -from oslo_serialization import base64 -from oslo_serialization import jsonutils - -from nova.api.openstack.compute import servers -from nova.api.openstack.compute import user_data -from nova.compute import flavors -from nova import exception -from nova import test -from nova.tests.unit.api.openstack import fakes -from nova.tests.unit import fake_instance -from nova.tests.unit.image import fake - - -FAKE_UUID = fakes.FAKE_UUID - - -class ServersControllerCreateTest(test.TestCase): - - def setUp(self): - """Shared implementation for tests below that create instance.""" - super(ServersControllerCreateTest, self).setUp() - - self.flags(enable_instance_password=True, group='api') - self.instance_cache_num = 0 - self.instance_cache_by_id = {} - self.instance_cache_by_uuid = {} - - # Network API needs to be stubbed out before creating the controllers. - fakes.stub_out_nw_api(self) - - self.controller = servers.ServersController() - - def instance_create(context, inst): - inst_type = flavors.get_flavor_by_flavor_id(3) - image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' - def_image_ref = 'http://localhost/images/%s' % image_uuid - self.instance_cache_num += 1 - instance = fake_instance.fake_db_instance(**{ - 'id': self.instance_cache_num, - 'display_name': inst['display_name'] or 'test', - 'uuid': FAKE_UUID, - 'instance_type': inst_type, - 'access_ip_v4': '1.2.3.4', - 'access_ip_v6': 'fead::1234', - 'image_ref': inst.get('image_ref', def_image_ref), - 'user_id': 'fake', - 'project_id': 'fake', - 'reservation_id': inst['reservation_id'], - "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), - "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), - user_data.ATTRIBUTE_NAME: None, - "progress": 0, - "fixed_ips": [], - "task_state": "", - "vm_state": "", - "root_device_name": inst.get('root_device_name', 'vda'), - }) - - self.instance_cache_by_id[instance['id']] = instance - self.instance_cache_by_uuid[instance['uuid']] = instance - return instance - - def instance_get(context, instance_id): - """Stub for compute/api create() pulling in instance after - scheduling - """ - return self.instance_cache_by_id[instance_id] - - def instance_update(context, uuid, values): - instance = self.instance_cache_by_uuid[uuid] - instance.update(values) - return instance - - def server_update(context, instance_uuid, params): - inst = self.instance_cache_by_uuid[instance_uuid] - inst.update(params) - return (inst, inst) - - def project_get_networks(context, user_id): - return dict(id='1', host='localhost') - - fakes.stub_out_key_pair_funcs(self) - fake.stub_out_image_service(self) - - self.stub_out('uuid.uuid4', lambda: FAKE_UUID) - self.stub_out('nova.db.instance_add_security_group', - lambda c, i, s: None) - self.stub_out('nova.db.project_get_networks', project_get_networks) - self.stub_out('nova.db.instance_create', instance_create) - self.stub_out('nova.db.instance_system_metadata_update', - lambda c, i, m, d: None) - self.stub_out('nova.db.instance_get', instance_get) - self.stub_out('nova.db.instance_update', instance_update) - self.stub_out('nova.db.instance_update_and_get_original', - server_update) - self.stub_out('nova.network.manager.VlanManager.allocate_fixed_ip', - lambda self, c, i, n, **k: None) - - def _test_create_extra(self, params, no_image=False, - legacy_v2=False): - image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77' - server = dict(name='server_test', imageRef=image_uuid, flavorRef=2) - if no_image: - server.pop('imageRef', None) - server.update(params) - body = dict(server=server) - req = fakes.HTTPRequestV21.blank('/servers') - req.method = 'POST' - req.body = jsonutils.dump_as_bytes(body) - req.headers["content-type"] = "application/json" - if legacy_v2: - req.set_legacy_v2() - server = self.controller.create(req, body=body).obj['server'] - return server - - def test_create_instance_with_user_data(self): - value = base64.encode_as_text("A random string") - params = {user_data.ATTRIBUTE_NAME: value} - server = self._test_create_extra(params) - self.assertEqual(FAKE_UUID, server['id']) - - def test_create_instance_with_bad_user_data(self): - value = "A random string" - params = {user_data.ATTRIBUTE_NAME: value} - self.assertRaises(exception.ValidationError, - self._test_create_extra, params) - - @mock.patch('nova.compute.api.API.create') - def test_create_instance_with_none_allowd_for_v20_compat_mode(self, - mock_create): - - def create(context, *args, **kwargs): - self.assertIsNone(kwargs['user_data']) - return ([fakes.stub_instance_obj(context)], None) - - mock_create.side_effect = create - params = {user_data.ATTRIBUTE_NAME: None} - self._test_create_extra(params, legacy_v2=True)