summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwanghao <sxmatch1986@gmail.com>2017-10-27 12:35:27 +0800
committerwanghao <sxmatch1986@gmail.com>2018-02-05 14:17:03 +0800
commitbdbf3f81e718168465f37f40d121f1e139b317e4 (patch)
tree135006f9781557bc32b034531700aad8d634ef3e
parent063a6d9d9a492019cf2355bc3d4bd1bc46085af9 (diff)
Add manageable server information into system metadata
Now when Mogan manage the baremetal node from driver, Mogan didn't know it is a managed server. We need add this information "managed_server=True" to system metadata for internal use. So this patch will finish two jobs: 1. Implements the system metadata in Mogan 2. Add manageable server information into system metadata Co-Authored-By: Xinran WANG <xin-ran.wang@intel.com> Change-Id: I89947796e120d89ec56f8f5daeb9774cf15b6bd0 Implements: blueprint system-metadata Closes-Bug: #1727913
Notes
Notes (review): Code-Review+2: Tao Li <litao3721@126.com> Workflow+1: Tao Li <litao3721@126.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Thu, 08 Feb 2018 06:56:00 +0000 Reviewed-on: https://review.openstack.org/515585 Project: openstack/mogan Branch: refs/heads/master
-rw-r--r--mogan/api/controllers/v1/servers.py11
-rw-r--r--mogan/db/sqlalchemy/alembic/versions/91941bf1ebc9_initial_migration.py1
-rw-r--r--mogan/db/sqlalchemy/models.py1
-rw-r--r--mogan/engine/manager.py1
-rw-r--r--mogan/objects/server.py1
-rw-r--r--mogan/tests/unit/api/v1/test_server.py17
-rw-r--r--mogan/tests/unit/db/utils.py3
-rw-r--r--mogan/tests/unit/objects/test_objects.py2
8 files changed, 32 insertions, 5 deletions
diff --git a/mogan/api/controllers/v1/servers.py b/mogan/api/controllers/v1/servers.py
index 0d015bd..246bb58 100644
--- a/mogan/api/controllers/v1/servers.py
+++ b/mogan/api/controllers/v1/servers.py
@@ -46,7 +46,8 @@ import re
46_DEFAULT_SERVER_RETURN_FIELDS = ('uuid', 'name', 'description', 46_DEFAULT_SERVER_RETURN_FIELDS = ('uuid', 'name', 'description',
47 'status', 'power_state') 47 'status', 'power_state')
48 48
49_ONLY_ADMIN_VISIBLE_SEVER_FIELDS = ('node', 'affinity_zone',) 49_ONLY_ADMIN_VISIBLE_SERVER_FIELDS = ('node', 'affinity_zone',
50 'system_metadata')
50 51
51LOG = log.getLogger(__name__) 52LOG = log.getLogger(__name__)
52 53
@@ -433,6 +434,9 @@ class Server(base.APIBase):
433 locked = types.boolean 434 locked = types.boolean
434 """Represent the current lock state of the server""" 435 """Represent the current lock state of the server"""
435 436
437 system_metadata = {wtypes.text: types.jsontype}
438 """The system meta data of the server"""
439
436 def __init__(self, **kwargs): 440 def __init__(self, **kwargs):
437 super(Server, self).__init__(**kwargs) 441 super(Server, self).__init__(**kwargs)
438 self.fields = [] 442 self.fields = []
@@ -445,7 +449,7 @@ class Server(base.APIBase):
445 if kwargs.get('status') != 'error': 449 if kwargs.get('status') != 'error':
446 setattr(self, field, wtypes.Unset) 450 setattr(self, field, wtypes.Unset)
447 continue 451 continue
448 if field in _ONLY_ADMIN_VISIBLE_SEVER_FIELDS: 452 if field in _ONLY_ADMIN_VISIBLE_SERVER_FIELDS:
449 if not pecan.request.context.is_admin: 453 if not pecan.request.context.is_admin:
450 setattr(self, field, wtypes.Unset) 454 setattr(self, field, wtypes.Unset)
451 continue 455 continue
@@ -487,7 +491,8 @@ class ServerPatchType(types.JsonPatchType):
487 '/power_state', '/availability_zone', 491 '/power_state', '/availability_zone',
488 '/flavor_uuid', '/image_uuid', '/addresses', 492 '/flavor_uuid', '/image_uuid', '/addresses',
489 '/launched_at', '/affinity_zone', '/key_name', 493 '/launched_at', '/affinity_zone', '/key_name',
490 '/partitions', '/fault', '/node', '/locked'] 494 '/partitions', '/fault', '/node', '/locked',
495 '/system_metadata']
491 496
492 497
493class ServerCollection(base.APIBase): 498class ServerCollection(base.APIBase):
diff --git a/mogan/db/sqlalchemy/alembic/versions/91941bf1ebc9_initial_migration.py b/mogan/db/sqlalchemy/alembic/versions/91941bf1ebc9_initial_migration.py
index f5d0b22..c56276b 100644
--- a/mogan/db/sqlalchemy/alembic/versions/91941bf1ebc9_initial_migration.py
+++ b/mogan/db/sqlalchemy/alembic/versions/91941bf1ebc9_initial_migration.py
@@ -85,6 +85,7 @@ def upgrade():
85 sa.Column('affinity_zone', sa.String(length=255), nullable=True), 85 sa.Column('affinity_zone', sa.String(length=255), nullable=True),
86 sa.Column('locked_by', sa.Enum('admin', 'owner'), nullable=True), 86 sa.Column('locked_by', sa.Enum('admin', 'owner'), nullable=True),
87 sa.Column('key_name', sa.String(length=255), nullable=True), 87 sa.Column('key_name', sa.String(length=255), nullable=True),
88 sa.Column('system_metadata', sa.Text(), nullable=True),
88 sa.PrimaryKeyConstraint('id'), 89 sa.PrimaryKeyConstraint('id'),
89 sa.UniqueConstraint('uuid', name='uniq_servers0uuid'), 90 sa.UniqueConstraint('uuid', name='uniq_servers0uuid'),
90 sa.Index('servers_project_id_idx', 'project_id'), 91 sa.Index('servers_project_id_idx', 'project_id'),
diff --git a/mogan/db/sqlalchemy/models.py b/mogan/db/sqlalchemy/models.py
index f70ab72..7eb1145 100644
--- a/mogan/db/sqlalchemy/models.py
+++ b/mogan/db/sqlalchemy/models.py
@@ -93,6 +93,7 @@ class Server(Base):
93 locked_by = Column(Enum('owner', 'admin')) 93 locked_by = Column(Enum('owner', 'admin'))
94 affinity_zone = Column(String(255), nullable=True) 94 affinity_zone = Column(String(255), nullable=True)
95 key_name = Column(String(255), nullable=True) 95 key_name = Column(String(255), nullable=True)
96 system_metadata = Column(db_types.JsonEncodedDict, nullable=True)
96 97
97 98
98class ServerNic(Base): 99class ServerNic(Base):
diff --git a/mogan/engine/manager.py b/mogan/engine/manager.py
index 047f5b6..884a440 100644
--- a/mogan/engine/manager.py
+++ b/mogan/engine/manager.py
@@ -785,6 +785,7 @@ class EngineManager(base_manager.BaseEngineManager):
785 server.power_state = node['power_state'] 785 server.power_state = node['power_state']
786 server.launched_at = timeutils.utcnow() 786 server.launched_at = timeutils.utcnow()
787 server.status = states.ACTIVE 787 server.status = states.ACTIVE
788 server.system_metadata = {"managed_server": "True"}
788 if server.power_state == states.POWER_OFF: 789 if server.power_state == states.POWER_OFF:
789 server.status = states.STOPPED 790 server.status = states.STOPPED
790 791
diff --git a/mogan/objects/server.py b/mogan/objects/server.py
index 9a801c7..700ae6c 100644
--- a/mogan/objects/server.py
+++ b/mogan/objects/server.py
@@ -57,6 +57,7 @@ class Server(base.MoganObject, object_base.VersionedObjectDictCompat):
57 'locked_by': object_fields.StringField(nullable=True), 57 'locked_by': object_fields.StringField(nullable=True),
58 'affinity_zone': object_fields.StringField(nullable=True), 58 'affinity_zone': object_fields.StringField(nullable=True),
59 'key_name': object_fields.StringField(nullable=True), 59 'key_name': object_fields.StringField(nullable=True),
60 'system_metadata': object_fields.FlexibleDictField(nullable=True),
60 } 61 }
61 62
62 def __init__(self, context=None, **kwargs): 63 def __init__(self, context=None, **kwargs):
diff --git a/mogan/tests/unit/api/v1/test_server.py b/mogan/tests/unit/api/v1/test_server.py
index 0e7be9f..6e1d305 100644
--- a/mogan/tests/unit/api/v1/test_server.py
+++ b/mogan/tests/unit/api/v1/test_server.py
@@ -185,6 +185,23 @@ class TestServerAuthorization(v1_test.APITestV1):
185 headers = self.gen_headers(self.context) 185 headers = self.gen_headers(self.context)
186 self.post_json('/servers', body, headers=headers, status=403) 186 self.post_json('/servers', body, headers=headers, status=403)
187 187
188 def test_server_get_one_by_owner_without_system_metadata(self):
189 # not admin but the owner
190 self.context.tenant = self.server1.project_id
191 headers = self.gen_headers(self.context, roles="no-admin")
192 resp = self.get_json('/servers/%s' % self.server1.uuid,
193 headers=headers)
194 self.assertNotIn('system_metadata', resp)
195
196 def test_server_get_one_by_admin_without_system_metadata(self):
197 # when the evil tenant is admin, he can do everything.
198 self.context.tenant = self.evil_project
199 headers = self.gen_headers(self.context, roles="admin")
200 resp = self.get_json('/servers/%s' % self.server1.uuid,
201 headers=headers)
202 self.assertIn('system_metadata', resp)
203 self.assertEqual(resp['system_metadata'], {})
204
188 205
189class TestPatch(v1_test.APITestV1): 206class TestPatch(v1_test.APITestV1):
190 207
diff --git a/mogan/tests/unit/db/utils.py b/mogan/tests/unit/db/utils.py
index c50158c..f505134 100644
--- a/mogan/tests/unit/db/utils.py
+++ b/mogan/tests/unit/db/utils.py
@@ -66,7 +66,8 @@ def get_test_server(**kw):
66 'created_at': kw.get('created_at'), 66 'created_at': kw.get('created_at'),
67 'locked_by': kw.get('locked_by', None), 67 'locked_by': kw.get('locked_by', None),
68 'affinity_zone': kw.get('affinity_zone', 'ZON1'), 68 'affinity_zone': kw.get('affinity_zone', 'ZON1'),
69 'key_name': kw.get('key_name', 'test_key') 69 'key_name': kw.get('key_name', 'test_key'),
70 'system_metadata': kw.get('system_metadata', {})
70 } 71 }
71 72
72 73
diff --git a/mogan/tests/unit/objects/test_objects.py b/mogan/tests/unit/objects/test_objects.py
index a106039..9c0ecaa 100644
--- a/mogan/tests/unit/objects/test_objects.py
+++ b/mogan/tests/unit/objects/test_objects.py
@@ -382,7 +382,7 @@ class _TestObject(object):
382# version bump. It is md5 hash of object fields and remotable methods. 382# version bump. It is md5 hash of object fields and remotable methods.
383# The fingerprint values should only be changed if there is a version bump. 383# The fingerprint values should only be changed if there is a version bump.
384expected_object_fingerprints = { 384expected_object_fingerprints = {
385 'Server': '1.0-1480ee88a244bf44492f61f20a022a6f', 385 'Server': '1.0-3e78c39d5ddb7b08ecdb7dad3a579b49',
386 'ServerFault': '1.0-74349ff701259e4834b4e9dc2dac1b12', 386 'ServerFault': '1.0-74349ff701259e4834b4e9dc2dac1b12',
387 'ServerFaultList': '1.0-43e8aad0258652921f929934e9e048fd', 387 'ServerFaultList': '1.0-43e8aad0258652921f929934e9e048fd',
388 'Flavor': '1.0-9f7166aa387d89ec40cd699019d0c9a9', 388 'Flavor': '1.0-9f7166aa387d89ec40cd699019d0c9a9',