diff --git a/api-ref/source/v1/parameters.yaml b/api-ref/source/v1/parameters.yaml index 78b90b75..09e25107 100644 --- a/api-ref/source/v1/parameters.yaml +++ b/api-ref/source/v1/parameters.yaml @@ -130,13 +130,6 @@ created_at: in: body required: true type: string -extra: - description: | - Metadata key and value pairs. The maximum size of the metadata key and value is - 255 bytes each. - in: body - required: false - type: object fixed_address: description: | The fixed IP address with which you want to associate the floating IP address. @@ -303,6 +296,13 @@ lock_state: in: body required: true type: boolean +metadata: + description: | + Metadata key and value pairs. The maximum size of the metadata key and value is + 255 bytes each. + in: body + required: false + type: object max_count_body: description: | The max number of servers to be created. Defaults to the value of ``min_count``. diff --git a/api-ref/source/v1/samples/servers/server-create-req.json b/api-ref/source/v1/samples/servers/server-create-req.json index 66680c6e..facabdfb 100644 --- a/api-ref/source/v1/samples/servers/server-create-req.json +++ b/api-ref/source/v1/samples/servers/server-create-req.json @@ -13,7 +13,7 @@ "port_type": "10GE" } ], - "extra" : { + "metadata" : { "My Server Name" : "Apache1" }, "personality": [ diff --git a/api-ref/source/v1/samples/servers/server-create-resp.json b/api-ref/source/v1/samples/servers/server-create-resp.json index a073fd82..ef4b5091 100644 --- a/api-ref/source/v1/samples/servers/server-create-resp.json +++ b/api-ref/source/v1/samples/servers/server-create-resp.json @@ -23,7 +23,7 @@ "project_id": "2f15c3524826465a9afbd150478b3b76", "user_id": "a6205fcab03d4a289251f420456b1289", "nics": [], - "extra": { + "metadata": { "My Server Name" : "Apache1" } } diff --git a/api-ref/source/v1/samples/servers/server-detail-resp-when-error.json b/api-ref/source/v1/samples/servers/server-detail-resp-when-error.json index f4818dfa..a8f1c67a 100644 --- a/api-ref/source/v1/samples/servers/server-detail-resp-when-error.json +++ b/api-ref/source/v1/samples/servers/server-detail-resp-when-error.json @@ -33,7 +33,7 @@ "updated_at": "2016-10-17T04:12:44+00:00", "user_id": "cdbf77d47f1d4d04ad9b7ff62b672467", "uuid": "f978ef48-d4af-4dad-beec-e6174309bc71", - "extra": { + "metadata": { "My Server Name" : "Apache1" } } diff --git a/api-ref/source/v1/samples/servers/server-detail-resp.json b/api-ref/source/v1/samples/servers/server-detail-resp.json index 8222338c..fec103d8 100644 --- a/api-ref/source/v1/samples/servers/server-detail-resp.json +++ b/api-ref/source/v1/samples/servers/server-detail-resp.json @@ -41,7 +41,7 @@ "updated_at": "2016-10-17T04:12:44+00:00", "user_id": "cdbf77d47f1d4d04ad9b7ff62b672467", "uuid": "f978ef48-d4af-4dad-beec-e6174309bc71", - "extra": { + "metadata": { "My Server Name" : "Apache1" } } diff --git a/api-ref/source/v1/samples/servers/server-list-detail-resp.json b/api-ref/source/v1/samples/servers/server-list-detail-resp.json index 7f3c0641..8fc6e6d0 100644 --- a/api-ref/source/v1/samples/servers/server-list-detail-resp.json +++ b/api-ref/source/v1/samples/servers/server-list-detail-resp.json @@ -43,7 +43,7 @@ "launched_at": null, "user_id": "cdbf77d47f1d4d04ad9b7ff62b672467", "uuid": "f978ef48-d4af-4dad-beec-e6174309bc71", - "extra": { + "metadata": { "My Server Name" : "Apache1" } } diff --git a/api-ref/source/v1/samples/servers/server-update-req.json b/api-ref/source/v1/samples/servers/server-update-req.json index 6c028e97..05b7795e 100644 --- a/api-ref/source/v1/samples/servers/server-update-req.json +++ b/api-ref/source/v1/samples/servers/server-update-req.json @@ -1,12 +1,12 @@ [ { "op": "replace", - "path": "/extra/k1", + "path": "/metadata/k1", "value": "v1" }, { "op": "add", - "path": "/extra/k2", + "path": "/metadata/k2", "value": "v2" } ] diff --git a/api-ref/source/v1/samples/servers/server-update-resp.json b/api-ref/source/v1/samples/servers/server-update-resp.json index f6ddf4d4..32b5c01c 100644 --- a/api-ref/source/v1/samples/servers/server-update-resp.json +++ b/api-ref/source/v1/samples/servers/server-update-resp.json @@ -41,7 +41,7 @@ ] } ], - "extra": { + "metadata": { "k1": "v1", "k2": "v2" } diff --git a/api-ref/source/v1/servers.inc b/api-ref/source/v1/servers.inc index a674a399..6642e89b 100644 --- a/api-ref/source/v1/servers.inc +++ b/api-ref/source/v1/servers.inc @@ -66,7 +66,7 @@ Response - user_id: user_id_body - updated_at: updated_at - created_at: created_at - - extra: extra + - metadata: metadata **Example Create Server: JSON response** @@ -202,7 +202,7 @@ Response - updated_at: updated_at - created_at: created_at - launched_at: launched_at - - extra: extra + - metadata: metadata **Example Detailed list of Servers: JSON response** @@ -253,7 +253,7 @@ Response - updated_at: updated_at - created_at: created_at - launched_at: launched_at - - extra: extra + - metadata: metadata **Example Server Details: JSON response** @@ -312,7 +312,7 @@ Response - user_id: user_id_body - updated_at: updated_at - created_at: created_at - - extra: extra + - metadata: metadata **Example Update Server: JSON response** diff --git a/mogan/api/controllers/v1/schemas/servers.py b/mogan/api/controllers/v1/schemas/servers.py index 930a32c7..1e9fb948 100644 --- a/mogan/api/controllers/v1/schemas/servers.py +++ b/mogan/api/controllers/v1/schemas/servers.py @@ -42,7 +42,7 @@ create_server = { 'key_name': parameter_types.name, 'min_count': {'type': 'integer', 'minimum': 1}, 'max_count': {'type': 'integer', 'minimum': 1}, - 'extra': parameter_types.extra, + 'metadata': parameter_types.metadata, }, 'required': ['name', 'image_uuid', 'flavor_uuid', 'networks'], 'additionalProperties': False, diff --git a/mogan/api/controllers/v1/servers.py b/mogan/api/controllers/v1/servers.py index b4ceb126..5505bcad 100644 --- a/mogan/api/controllers/v1/servers.py +++ b/mogan/api/controllers/v1/servers.py @@ -446,7 +446,7 @@ class Server(base.APIBase): launched_at = datetime.datetime """The UTC date and time of the server launched""" - extra = {wtypes.text: types.jsontype} + metadata = {wtypes.text: types.jsontype} """The meta data of the server""" fault_info = {wtypes.text: types.jsontype} @@ -669,7 +669,7 @@ class ServerController(ServerControllerBase): name=server.get('name'), description=server.get('description'), availability_zone=server.get('availability_zone'), - extra=server.get('extra'), + metadata=server.get('metadata'), requested_networks=requested_networks, user_data=user_data, injected_files=injected_files, diff --git a/mogan/api/validation/parameter_types.py b/mogan/api/validation/parameter_types.py index 0839b478..fabcab99 100644 --- a/mogan/api/validation/parameter_types.py +++ b/mogan/api/validation/parameter_types.py @@ -58,7 +58,7 @@ flavor_id = { } -extra = { +metadata = { 'type': 'object', 'patternProperties': { '^[a-zA-Z0-9-_:. ]{1,255}$': { diff --git a/mogan/engine/api.py b/mogan/engine/api.py index 96c13951..f8030c98 100644 --- a/mogan/engine/api.py +++ b/mogan/engine/api.py @@ -77,7 +77,7 @@ class API(object): def _validate_and_build_base_options(self, context, flavor, image_uuid, name, description, - availability_zone, extra, + availability_zone, metadata, requested_networks, user_data, key_name, max_count): """Verify all the input parameters""" @@ -117,7 +117,7 @@ class API(object): 'name': name, 'description': description, 'locked': False, - 'extra': extra or {}, + 'metadata': metadata or {}, 'availability_zone': availability_zone} # return the validated options @@ -247,7 +247,7 @@ class API(object): max_count) def _create_server(self, context, flavor, image_uuid, - name, description, availability_zone, extra, + name, description, availability_zone, metadata, requested_networks, user_data, injected_files, key_name, min_count, max_count): """Verify all the input parameters""" @@ -262,7 +262,7 @@ class API(object): base_options, max_net_count, key_pair = \ self._validate_and_build_base_options( context, flavor, image_uuid, name, description, - availability_zone, extra, requested_networks, user_data, + availability_zone, metadata, requested_networks, user_data, key_name, max_count) # max_net_count is the maximum number of servers requested by the @@ -304,7 +304,7 @@ class API(object): def create(self, context, flavor, image_uuid, name=None, description=None, availability_zone=None, - extra=None, requested_networks=None, user_data=None, + metadata=None, requested_networks=None, user_data=None, injected_files=None, key_name=None, min_count=None, max_count=None): """Provision servers @@ -323,7 +323,7 @@ class API(object): return self._create_server(context, flavor, image_uuid, name, description, - availability_zone, extra, + availability_zone, metadata, requested_networks, user_data, injected_files, key_name, min_count, max_count) diff --git a/mogan/objects/server.py b/mogan/objects/server.py index 006b0221..7f27ac74 100644 --- a/mogan/objects/server.py +++ b/mogan/objects/server.py @@ -51,7 +51,7 @@ class Server(base.MoganObject, object_base.VersionedObjectDictCompat): 'fault': object_fields.ObjectField('ServerFault', nullable=True), 'node_uuid': object_fields.UUIDField(nullable=True), 'launched_at': object_fields.DateTimeField(nullable=True), - 'extra': object_fields.FlexibleDictField(nullable=True), + 'metadata': object_fields.FlexibleDictField(nullable=True), 'locked': object_fields.BooleanField(default=False), 'locked_by': object_fields.StringField(nullable=True), } @@ -78,7 +78,10 @@ class Server(base.MoganObject, object_base.VersionedObjectDictCompat): :return: The object of the class with the database entity added """ for field in set(server.fields) - set(OPTIONAL_ATTRS): - server[field] = db_server[field] + if field == 'metadata': + server[field] = db_server['extra'] + else: + server[field] = db_server[field] if expected_attrs is None: expected_attrs = [] @@ -139,6 +142,9 @@ class Server(base.MoganObject, object_base.VersionedObjectDictCompat): def create(self, context=None): """Create a Server record in the DB.""" values = self.obj_get_changes() + metadata = values.pop('metadata', None) + if metadata is not None: + values['extra'] = metadata server_nics = values.pop('nics', None) if server_nics: values['nics'] = server_nics.as_list_of_dict() @@ -170,6 +176,9 @@ class Server(base.MoganObject, object_base.VersionedObjectDictCompat): raise updates.pop(field) + metadata = updates.pop('metadata', None) + if metadata is not None: + updates['extra'] = metadata self.dbapi.server_update(context, self.uuid, updates) self.obj_reset_changes() diff --git a/mogan/tests/functional/api/v1/test_servers.py b/mogan/tests/functional/api/v1/test_servers.py index 65fd68a7..e1e843d9 100644 --- a/mogan/tests/functional/api/v1/test_servers.py +++ b/mogan/tests/functional/api/v1/test_servers.py @@ -136,7 +136,7 @@ class TestServers(v1_test.APITestV1): 'networks': [ {'net_id': 'c1940655-8b8e-4370-b8f9-03ba1daeca31', 'port_type': 'Ethernet'}], - 'extra': {'fake_key': 'fake_value'} + 'metadata': {'fake_key': 'fake_value'} } responses.append( self.post_json('/servers', test_body, headers=headers, @@ -154,7 +154,7 @@ class TestServers(v1_test.APITestV1): resp['image_uuid']) self.assertEqual('mogan', resp['availability_zone']) self.assertEqual([], resp['nics']) - self.assertEqual({'fake_key': 'fake_value'}, resp['extra']) + self.assertEqual({'fake_key': 'fake_value'}, resp['metadata']) self.assertIn('links', resp) self.assertIn('created_at', resp) self.assertIn('updated_at', resp) @@ -176,7 +176,7 @@ class TestServers(v1_test.APITestV1): resp['image_uuid']) self.assertEqual('mogan', resp['availability_zone']) self.assertEqual([], resp['nics']) - self.assertEqual({'fake_key': 'fake_value'}, resp['extra']) + self.assertEqual({'fake_key': 'fake_value'}, resp['metadata']) self.assertIn('links', resp) self.assertIn('created_at', resp) self.assertIn('updated_at', resp) diff --git a/mogan/tests/tempest/api/test_servers.py b/mogan/tests/tempest/api/test_servers.py index d55f8284..2de95ebd 100644 --- a/mogan/tests/tempest/api/test_servers.py +++ b/mogan/tests/tempest/api/test_servers.py @@ -36,7 +36,7 @@ class BaremetalComputeAPIServersTest(base.BaseBaremetalComputeTest): self.assertEqual(self.image_id, resp['image_uuid']) self.assertIn('launched_at', resp) self.assertIn('updated_at', resp) - self.assertIn('extra', resp) + self.assertIn('metadata', resp) self.assertIn('links', resp) self.assertIn('project_id', resp) self.assertIn('user_id', resp) @@ -54,7 +54,7 @@ class BaremetalComputeAPIServersTest(base.BaseBaremetalComputeTest): self.assertEqual('power on', resp['power_state']) self.assertIn('launched_at', resp) self.assertIn('updated_at', resp) - self.assertIn('extra', resp) + self.assertIn('metadata', resp) self.assertIn('links', resp) self.assertIn('project_id', resp) self.assertIn('user_id', resp) diff --git a/mogan/tests/unit/api/v1/test_server.py b/mogan/tests/unit/api/v1/test_server.py index db2598fa..78597a03 100644 --- a/mogan/tests/unit/api/v1/test_server.py +++ b/mogan/tests/unit/api/v1/test_server.py @@ -135,7 +135,7 @@ class TestPatch(v1_test.APITestV1): def test_update_not_found(self): uuid = uuidutils.generate_uuid() response = self.patch_json('/servers/%s' % uuid, - [{'path': '/extra/a', 'value': 'b', + [{'path': '/metadata/a', 'value': 'b', 'op': 'add'}], headers=self.headers, expect_errors=True) @@ -169,7 +169,7 @@ class TestPatch(v1_test.APITestV1): extra=extra) new_value = 'new value' response = self.patch_json('/servers/%s' % server.uuid, - [{'path': '/extra/foo2', + [{'path': '/metadata/foo2', 'value': new_value, 'op': 'replace'}], headers=self.headers) self.assertEqual('application/json', response.content_type) @@ -178,7 +178,7 @@ class TestPatch(v1_test.APITestV1): headers=self.headers) extra["foo2"] = new_value - self.assertEqual(extra, result['extra']) + self.assertEqual(extra, result['metadata']) def test_remove_singular(self): uuid = uuidutils.generate_uuid() @@ -195,7 +195,7 @@ class TestPatch(v1_test.APITestV1): # Assert nothing else was changed self.assertEqual(server.uuid, result['uuid']) - self.assertEqual(server.extra, result['extra']) + self.assertEqual(server.extra, result['metadata']) def test_remove_multi(self): extra = {"foo1": "bar1", "foo2": "bar2", "foo3": "bar3"} @@ -204,24 +204,25 @@ class TestPatch(v1_test.APITestV1): uuid=uuid, description="foobar") # Removing one item from the collection - response = self.patch_json('/servers/%s' % server.uuid, - [{'path': '/extra/foo2', 'op': 'remove'}], - headers=self.headers) + response = self.patch_json( + '/servers/%s' % server.uuid, + [{'path': '/metadata/foo2', 'op': 'remove'}], + headers=self.headers) self.assertEqual('application/json', response.content_type) self.assertEqual(http_client.OK, response.status_code) result = self.get_json('/servers/%s' % server.uuid, headers=self.headers) extra.pop("foo2") - self.assertEqual(extra, result['extra']) + self.assertEqual(extra, result['metadata']) # Removing the collection response = self.patch_json('/servers/%s' % server.uuid, - [{'path': '/extra', 'op': 'remove'}], + [{'path': '/metadata', 'op': 'remove'}], headers=self.headers) self.assertEqual(http_client.OK, response.status_code) result = self.get_json('/servers/%s' % server.uuid, headers=self.headers) - self.assertEqual({}, result['extra']) + self.assertEqual({}, result['metadata']) # Assert nothing else was changed self.assertEqual(server.uuid, result['uuid']) @@ -230,7 +231,7 @@ class TestPatch(v1_test.APITestV1): def test_remove_non_existent_property_fail(self): response = self.patch_json( '/servers/%s' % self.server.uuid, - [{'path': '/extra/non-existent', 'op': 'remove'}], + [{'path': '/metadata/non-existent', 'op': 'remove'}], headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_code) @@ -256,9 +257,9 @@ class TestPatch(v1_test.APITestV1): def test_add_multi(self): response = self.patch_json('/servers/%s' % self.server.uuid, - [{'path': '/extra/foo1', 'value': 'bar1', + [{'path': '/metadata/foo1', 'value': 'bar1', 'op': 'add'}, - {'path': '/extra/foo2', 'value': 'bar2', + {'path': '/metadata/foo2', 'value': 'bar2', 'op': 'add'}], headers=self.headers) self.assertEqual('application/json', response.content_type) @@ -266,7 +267,7 @@ class TestPatch(v1_test.APITestV1): result = self.get_json('/servers/%s' % self.server.uuid, headers=self.headers) expected = {"foo1": "bar1", "foo2": "bar2"} - self.assertEqual(expected, result['extra']) + self.assertEqual(expected, result['metadata']) def test_remove_uuid(self): response = self.patch_json('/servers/%s' % self.server.uuid, diff --git a/mogan/tests/unit/engine/test_engine_api.py b/mogan/tests/unit/engine/test_engine_api.py index 2b16a45e..eb099e6a 100644 --- a/mogan/tests/unit/engine/test_engine_api.py +++ b/mogan/tests/unit/engine/test_engine_api.py @@ -58,7 +58,7 @@ class ComputeAPIUnitTest(base.DbTestCase): name='fake-name', description='fake-descritpion', availability_zone='test_az', - extra={'k1', 'v1'}, + metadata={'k1', 'v1'}, requested_networks=None, user_data=None, key_name=None, @@ -68,7 +68,7 @@ class ComputeAPIUnitTest(base.DbTestCase): self.assertEqual('fake-project', base_opts['project_id']) self.assertEqual(states.BUILDING, base_opts['status']) self.assertEqual(flavor.uuid, base_opts['flavor_uuid']) - self.assertEqual({'k1', 'v1'}, base_opts['extra']) + self.assertEqual({'k1', 'v1'}, base_opts['metadata']) self.assertEqual('test_az', base_opts['availability_zone']) self.assertIsNone(key_pair) @@ -107,7 +107,7 @@ class ComputeAPIUnitTest(base.DbTestCase): 'flavor_uuid': 'fake-type-uuid', 'name': 'fake-name', 'description': 'fake-description', - 'extra': {'k1', 'v1'}, + 'metadata': {'k1', 'v1'}, 'availability_zone': 'test_az'} min_count = 1 max_count = 2 @@ -131,7 +131,7 @@ class ComputeAPIUnitTest(base.DbTestCase): name='fake-name', description='fake-descritpion', availability_zone='test_az', - extra={'k1', 'v1'}, + metadata={'k1', 'v1'}, requested_networks=requested_networks, min_count=min_count, max_count=max_count) @@ -180,7 +180,7 @@ class ComputeAPIUnitTest(base.DbTestCase): 'flavor_uuid': 'fake-type-uuid', 'name': 'fake-name', 'description': 'fake-description', - 'extra': {'k1', 'v1'}, + 'metadata': {'k1', 'v1'}, 'availability_zone': 'test_az'} min_count = 11 max_count = 20 diff --git a/mogan/tests/unit/objects/test_objects.py b/mogan/tests/unit/objects/test_objects.py index 2f929660..cfe8bbbf 100644 --- a/mogan/tests/unit/objects/test_objects.py +++ b/mogan/tests/unit/objects/test_objects.py @@ -382,7 +382,7 @@ class _TestObject(object): # version bump. It is md5 hash of object fields and remotable methods. # The fingerprint values should only be changed if there is a version bump. expected_object_fingerprints = { - 'Server': '1.0-f3ef6866ef8072b063014a2c49060c6d', + 'Server': '1.0-dc54162c0cc91fac43fed5304cd2c968', 'ComputeNode': '1.0-586e7eaadd4ec88a0506c4238ebdd7a5', 'ComputeNodeList': '1.0-33a2e1bb91ad4082f9f63429b77c1244', 'ComputePort': '1.0-ca4c1817ad7324286813f2cfcdcf802e', diff --git a/mogan/tests/unit/objects/test_server.py b/mogan/tests/unit/objects/test_server.py index a4c4eb32..5abcd107 100644 --- a/mogan/tests/unit/objects/test_server.py +++ b/mogan/tests/unit/objects/test_server.py @@ -61,11 +61,11 @@ class TestServerObject(base.DbTestCase): autospec=True) as mock_server_create: mock_server_create.return_value = self.fake_server server = objects.Server(self.context, **self.fake_server) - server.obj_get_changes() server.create(self.context) expected_called = copy.deepcopy(self.fake_server) expected_called['nics'][0].update( server_uuid=self.fake_server['uuid']) + expected_called.pop('extra', None) mock_server_create.assert_called_once_with(self.context, expected_called) self.assertEqual(self.fake_server['uuid'], server['uuid'])