diff options
author | He Jie Xu <hejie.xu@intel.com> | 2016-05-19 11:04:10 +0800 |
---|---|---|
committer | Matt Riedemann <mriedem@us.ibm.com> | 2016-06-01 11:29:16 -0400 |
commit | c29ea41ba0706cd1421d127d79b18e0c4fa58da4 (patch) | |
tree | 37c5f0402bc129a0b2a7b5923c9f95b16819a81a | |
parent | 38d8b7ca7e8292d3c237c8d4aee2bde4842d964a (diff) | |
download | nova-c29ea41ba0706cd1421d127d79b18e0c4fa58da4.tar.gz |
Enable 'null' value for user_data in V2.1 API
The legacy v2 API allow the 'null' value for user_data. Unfortunately
the v2.1 API didn't match that in the input validation. This patch
enables 'null' value, at sametime, it enables for v2.1 compat mode
also.
Change-Id: Iae614035efd4b37c214754ad12b17ca224b8fd92
Closes-Bug: #1582911
(cherry picked from commit 22c87390a33300b93f0913d4e787662b119a00b9)
(cherry picked from commit 2024387ecc0922abe97863c349cf94df1d4462d0)
-rw-r--r-- | nova/api/openstack/compute/schemas/user_data.py | 10 | ||||
-rw-r--r-- | nova/api/openstack/compute/user_data.py | 2 | ||||
-rw-r--r-- | nova/api/validation/validators.py | 4 | ||||
-rw-r--r-- | nova/tests/unit/api/openstack/compute/test_user_data.py | 17 |
4 files changed, 32 insertions, 1 deletions
diff --git a/nova/api/openstack/compute/schemas/user_data.py b/nova/api/openstack/compute/schemas/user_data.py index dd4f9ad244..6ffc4aaab3 100644 --- a/nova/api/openstack/compute/schemas/user_data.py +++ b/nova/api/openstack/compute/schemas/user_data.py @@ -18,3 +18,13 @@ server_create = { 'format': 'base64' }, } + + +server_create_v20 = { + 'user_data': { + 'oneOf': [ + {'type': 'string', 'format': 'base64'}, + {'type': 'null'}, + ], + }, +} diff --git a/nova/api/openstack/compute/user_data.py b/nova/api/openstack/compute/user_data.py index fdcb1c0f7a..7e46ee78ee 100644 --- a/nova/api/openstack/compute/user_data.py +++ b/nova/api/openstack/compute/user_data.py @@ -39,4 +39,6 @@ class UserData(extensions.V21APIExtensionBase): create_kwargs['user_data'] = server_dict.get(ATTRIBUTE_NAME) def get_server_create_schema(self, version): + if version == '2.0': + return schema_user_data.server_create_v20 return schema_user_data.server_create diff --git a/nova/api/validation/validators.py b/nova/api/validation/validators.py index 2ae5dfe907..8b79f03a21 100644 --- a/nova/api/validation/validators.py +++ b/nova/api/validation/validators.py @@ -47,6 +47,10 @@ def _validate_base64_format(instance): base64.decodestring(instance) except base64.binascii.Error: return False + except TypeError: + # The name must be string type. If instance isn't string type, the + # TypeError will be raised at here. + return False return True diff --git a/nova/tests/unit/api/openstack/compute/test_user_data.py b/nova/tests/unit/api/openstack/compute/test_user_data.py index 3be774df60..8cd27d23d7 100644 --- a/nova/tests/unit/api/openstack/compute/test_user_data.py +++ b/nova/tests/unit/api/openstack/compute/test_user_data.py @@ -16,6 +16,7 @@ import base64 import datetime +import mock import uuid from oslo_config import cfg @@ -138,7 +139,7 @@ class ServersControllerCreateTest(test.TestCase): fake_method) def _test_create_extra(self, params, no_image=False, - override_controller=None): + override_controller=None, legacy_v2=False): image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77' server = dict(name='server_test', imageRef=image_uuid, flavorRef=2) if no_image: @@ -149,6 +150,8 @@ class ServersControllerCreateTest(test.TestCase): req.method = 'POST' req.body = jsonutils.dumps(body) req.headers["content-type"] = "application/json" + if legacy_v2: + req.set_legacy_v2() if override_controller: server = override_controller.create(req, body=body).obj['server'] else: @@ -190,3 +193,15 @@ class ServersControllerCreateTest(test.TestCase): 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) |