Change to use server metadata instead of extra
Use server metadata to be user friendly. Change-Id: Ib396fba305d6138c2436a40559c267de5bb4e7f9 Closes-Bug: #1696899
This commit is contained in:
parent
6cf1af411b
commit
ed5993efce
@ -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``.
|
||||
|
@ -13,7 +13,7 @@
|
||||
"port_type": "10GE"
|
||||
}
|
||||
],
|
||||
"extra" : {
|
||||
"metadata" : {
|
||||
"My Server Name" : "Apache1"
|
||||
},
|
||||
"personality": [
|
||||
|
@ -23,7 +23,7 @@
|
||||
"project_id": "2f15c3524826465a9afbd150478b3b76",
|
||||
"user_id": "a6205fcab03d4a289251f420456b1289",
|
||||
"nics": [],
|
||||
"extra": {
|
||||
"metadata": {
|
||||
"My Server Name" : "Apache1"
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@
|
||||
"launched_at": null,
|
||||
"user_id": "cdbf77d47f1d4d04ad9b7ff62b672467",
|
||||
"uuid": "f978ef48-d4af-4dad-beec-e6174309bc71",
|
||||
"extra": {
|
||||
"metadata": {
|
||||
"My Server Name" : "Apache1"
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/extra/k1",
|
||||
"path": "/metadata/k1",
|
||||
"value": "v1"
|
||||
},
|
||||
{
|
||||
"op": "add",
|
||||
"path": "/extra/k2",
|
||||
"path": "/metadata/k2",
|
||||
"value": "v2"
|
||||
}
|
||||
]
|
||||
|
@ -41,7 +41,7 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"extra": {
|
||||
"metadata": {
|
||||
"k1": "v1",
|
||||
"k2": "v2"
|
||||
}
|
||||
|
@ -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**
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -58,7 +58,7 @@ flavor_id = {
|
||||
}
|
||||
|
||||
|
||||
extra = {
|
||||
metadata = {
|
||||
'type': 'object',
|
||||
'patternProperties': {
|
||||
'^[a-zA-Z0-9-_:. ]{1,255}$': {
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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'])
|
||||
|
Loading…
Reference in New Issue
Block a user