From a105ee094333f36d7d000c19d15dba0f1e900c92 Mon Sep 17 00:00:00 2001 From: Mark Goddard Date: Tue, 26 Feb 2019 15:30:26 +0000 Subject: [PATCH] Deploy Templates: add 'extra' field to DB & object The original patch [1] to add DB & object support for deploy templates did not include an 'extra' field for metadata. This patch adds the field, and bumps the object version. Change-Id: I95b4beae217704defc9eab851780fd9c42847c40 Story: 1722275 Task: 29698 --- ironic/common/release_mappings.py | 2 +- ...c9_add_extra_column_to_deploy_templates.py | 31 +++++++++++++++++++ ironic/db/sqlalchemy/models.py | 1 + ironic/objects/deploy_template.py | 4 ++- .../unit/db/sqlalchemy/test_migrations.py | 10 ++++++ ironic/tests/unit/db/test_deploy_templates.py | 6 ++++ ironic/tests/unit/db/utils.py | 1 + .../unit/objects/test_deploy_template.py | 6 ++++ ironic/tests/unit/objects/test_objects.py | 2 +- 9 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 ironic/db/sqlalchemy/alembic/versions/1e15e7122cc9_add_extra_column_to_deploy_templates.py diff --git a/ironic/common/release_mappings.py b/ironic/common/release_mappings.py index 1c55af2d56..6fd6978ab1 100644 --- a/ironic/common/release_mappings.py +++ b/ironic/common/release_mappings.py @@ -138,7 +138,7 @@ RELEASE_MAPPING = { 'Node': ['1.32', '1.31', '1.30', '1.29', '1.28'], 'Conductor': ['1.3'], 'Chassis': ['1.3'], - 'DeployTemplate': ['1.0'], + 'DeployTemplate': ['1.0', '1.1'], 'Port': ['1.9'], 'Portgroup': ['1.4'], 'Trait': ['1.0'], diff --git a/ironic/db/sqlalchemy/alembic/versions/1e15e7122cc9_add_extra_column_to_deploy_templates.py b/ironic/db/sqlalchemy/alembic/versions/1e15e7122cc9_add_extra_column_to_deploy_templates.py new file mode 100644 index 0000000000..854b9c2e7a --- /dev/null +++ b/ironic/db/sqlalchemy/alembic/versions/1e15e7122cc9_add_extra_column_to_deploy_templates.py @@ -0,0 +1,31 @@ +# 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. + +"""add extra column to deploy_templates + +Revision ID: 1e15e7122cc9 +Revises: 2aac7e0872f6 +Create Date: 2019-02-26 15:08:18.419157 + +""" + +# revision identifiers, used by Alembic. +revision = '1e15e7122cc9' +down_revision = '2aac7e0872f6' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.add_column('deploy_templates', + sa.Column('extra', sa.Text(), nullable=True)) diff --git a/ironic/db/sqlalchemy/models.py b/ironic/db/sqlalchemy/models.py index 9d90d9aa35..f9dcf467e4 100644 --- a/ironic/db/sqlalchemy/models.py +++ b/ironic/db/sqlalchemy/models.py @@ -361,6 +361,7 @@ class DeployTemplate(Base): id = Column(Integer, primary_key=True) uuid = Column(String(36)) name = Column(String(255), nullable=False) + extra = Column(db_types.JsonEncodedDict) class DeployTemplateStep(Base): diff --git a/ironic/objects/deploy_template.py b/ironic/objects/deploy_template.py index f6358fae52..7c8238201a 100644 --- a/ironic/objects/deploy_template.py +++ b/ironic/objects/deploy_template.py @@ -20,7 +20,8 @@ from ironic.objects import fields as object_fields @base.IronicObjectRegistry.register class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat): # Version 1.0: Initial version - VERSION = '1.0' + # Version 1.1: Added 'extra' field + VERSION = '1.1' dbapi = db_api.get_instance() @@ -29,6 +30,7 @@ class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat): 'uuid': object_fields.UUIDField(nullable=False), 'name': object_fields.StringField(nullable=False), 'steps': object_fields.ListOfFlexibleDictsField(nullable=False), + 'extra': object_fields.FlexibleDictField(nullable=True), } # NOTE(mgoddard): We don't want to enable RPC on this call just yet. diff --git a/ironic/tests/unit/db/sqlalchemy/test_migrations.py b/ironic/tests/unit/db/sqlalchemy/test_migrations.py index f41eb25278..f54b4f7cf3 100644 --- a/ironic/tests/unit/db/sqlalchemy/test_migrations.py +++ b/ironic/tests/unit/db/sqlalchemy/test_migrations.py @@ -954,6 +954,16 @@ class MigrationCheckersMixin(object): # Insert another step for the same template. deploy_template_steps.insert().execute(step) + def _check_1e15e7122cc9(self, engine, data): + # Deploy template 'extra' field. + deploy_templates = db_utils.get_table(engine, 'deploy_templates') + col_names = [column.name for column in deploy_templates.c] + expected = ['created_at', 'updated_at', 'version', + 'id', 'uuid', 'name', 'extra'] + self.assertEqual(sorted(expected), sorted(col_names)) + self.assertIsInstance(deploy_templates.c.extra.type, + sqlalchemy.types.TEXT) + def test_upgrade_and_version(self): with patch_with_engine(self.engine): self.migration_api.upgrade('head') diff --git a/ironic/tests/unit/db/test_deploy_templates.py b/ironic/tests/unit/db/test_deploy_templates.py index 59fdb447a2..0a7e0cbc53 100644 --- a/ironic/tests/unit/db/test_deploy_templates.py +++ b/ironic/tests/unit/db/test_deploy_templates.py @@ -36,6 +36,7 @@ class DbDeployTemplateTestCase(base.DbTestCase): self.assertEqual('create_configuration', step.step) self.assertEqual({'logical_disks': []}, step.args) self.assertEqual(10, step.priority) + self.assertEqual({}, self.template.extra) def test_create_no_steps(self): uuid = uuidutils.generate_uuid() @@ -104,6 +105,11 @@ class DbDeployTemplateTestCase(base.DbTestCase): template = self.dbapi.update_deploy_template(self.template.id, values) self.assertEqual([], template.steps) + def test_update_extra(self): + values = {'extra': {'foo': 'bar'}} + template = self.dbapi.update_deploy_template(self.template.id, values) + self.assertEqual({'foo': 'bar'}, template.extra) + def test_update_duplicate_name(self): uuid = uuidutils.generate_uuid() template2 = db_utils.create_test_deploy_template(uuid=uuid, diff --git a/ironic/tests/unit/db/utils.py b/ironic/tests/unit/db/utils.py index 7b6be120a5..4b15a31514 100644 --- a/ironic/tests/unit/db/utils.py +++ b/ironic/tests/unit/db/utils.py @@ -633,6 +633,7 @@ def get_test_deploy_template(**kw): 'uuid': kw.get('uuid', 'aa75a317-2929-47d4-b676-fd9bff578bf1'), 'steps': kw.get('steps', [get_test_deploy_template_step( deploy_template_id=kw.get('id', 234))]), + 'extra': kw.get('extra', {}), } diff --git a/ironic/tests/unit/objects/test_deploy_template.py b/ironic/tests/unit/objects/test_deploy_template.py index e32c30f208..b741d1a8e9 100644 --- a/ironic/tests/unit/objects/test_deploy_template.py +++ b/ironic/tests/unit/objects/test_deploy_template.py @@ -42,6 +42,7 @@ class TestDeployTemplateObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn): self.assertEqual(self.fake_template['name'], template.name) self.assertEqual(self.fake_template['steps'], template.steps) + self.assertEqual(self.fake_template['extra'], template.extra) @mock.patch.object(dbapi.IMPL, 'update_deploy_template', autospec=True) def test_save(self, mock_update): @@ -81,6 +82,7 @@ class TestDeployTemplateObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn): self.assertEqual(self.fake_template['name'], template.name) self.assertEqual(self.fake_template['uuid'], template.uuid) self.assertEqual(self.fake_template['steps'], template.steps) + self.assertEqual(self.fake_template['extra'], template.extra) @mock.patch.object(dbapi.IMPL, 'get_deploy_template_by_uuid', autospec=True) @@ -94,6 +96,7 @@ class TestDeployTemplateObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn): self.assertEqual(self.fake_template['name'], template.name) self.assertEqual(self.fake_template['uuid'], template.uuid) self.assertEqual(self.fake_template['steps'], template.steps) + self.assertEqual(self.fake_template['extra'], template.extra) @mock.patch.object(dbapi.IMPL, 'get_deploy_template_by_name', autospec=True) @@ -107,6 +110,7 @@ class TestDeployTemplateObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn): self.assertEqual(self.fake_template['name'], template.name) self.assertEqual(self.fake_template['uuid'], template.uuid) self.assertEqual(self.fake_template['steps'], template.steps) + self.assertEqual(self.fake_template['extra'], template.extra) @mock.patch.object(dbapi.IMPL, 'get_deploy_template_list', autospec=True) def test_list(self, mock_list): @@ -120,6 +124,7 @@ class TestDeployTemplateObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn): self.assertEqual(self.fake_template['name'], templates[0].name) self.assertEqual(self.fake_template['uuid'], templates[0].uuid) self.assertEqual(self.fake_template['steps'], templates[0].steps) + self.assertEqual(self.fake_template['extra'], templates[0].extra) @mock.patch.object(dbapi.IMPL, 'get_deploy_template_list_by_names', autospec=True) @@ -134,6 +139,7 @@ class TestDeployTemplateObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn): self.assertEqual(self.fake_template['name'], templates[0].name) self.assertEqual(self.fake_template['uuid'], templates[0].uuid) self.assertEqual(self.fake_template['steps'], templates[0].steps) + self.assertEqual(self.fake_template['extra'], templates[0].extra) @mock.patch.object(dbapi.IMPL, 'get_deploy_template_by_uuid', autospec=True) diff --git a/ironic/tests/unit/objects/test_objects.py b/ironic/tests/unit/objects/test_objects.py index e1877832ab..0717cc42df 100644 --- a/ironic/tests/unit/objects/test_objects.py +++ b/ironic/tests/unit/objects/test_objects.py @@ -717,7 +717,7 @@ expected_object_fingerprints = { 'Allocation': '1.0-25ebf609743cd3f332a4f80fcb818102', 'AllocationCRUDNotification': '1.0-59acc533c11d306f149846f922739c15', 'AllocationCRUDPayload': '1.0-a82389d019f37cfe54b50049f73911b3', - 'DeployTemplate': '1.0-c20a91a34a5518e13b2a1bf5072eb119', + 'DeployTemplate': '1.1-4e30c8e9098595e359bb907f095bf1a9', }