From 766a64a41a8afe6b86137a78651f8dcbcc5f56d4 Mon Sep 17 00:00:00 2001 From: Feilong Wang Date: Wed, 10 Oct 2018 14:12:52 +1300 Subject: [PATCH] Allow cluster template being renamed To get a better cluster template versioning and relieve the pain of maintaining public cluster template, the patch is proposing that the name of cluster template can be changed. A folllowing patch/spec will be proposed to add a new field 'deprecated' to allow ops to hide old/deprecated templates. Task: 26889 Story: 2003960 Change-Id: Id1db81d35bc3dccff0fac481be7801de200d52de --- magnum/db/sqlalchemy/api.py | 7 +++++-- .../unit/api/controllers/v1/test_baymodel.py | 20 ++++++++++++++---- .../controllers/v1/test_cluster_template.py | 21 +++++++++++++++---- ...mplate-being-renamed-82f7d5d1f33a7957.yaml | 7 +++++++ 4 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 releasenotes/notes/allow-cluster-template-being-renamed-82f7d5d1f33a7957.yaml diff --git a/magnum/db/sqlalchemy/api.py b/magnum/db/sqlalchemy/api.py index 1c4823a2bf..559c00e255 100644 --- a/magnum/db/sqlalchemy/api.py +++ b/magnum/db/sqlalchemy/api.py @@ -13,6 +13,7 @@ # under the License. """SQLAlchemy storage backend.""" +import six from oslo_db import exception as db_exc from oslo_db.sqlalchemy import session as db_session @@ -405,8 +406,10 @@ class Connection(api.Connection): clustertemplate=cluster_template_id) if self._is_cluster_template_referenced(session, ref['uuid']): - # we only allow to update ClusterTemplate to be public - if not self._is_publishing_cluster_template(values): + # NOTE(flwang): We only allow to update ClusterTemplate to be + # public and rename + if (not self._is_publishing_cluster_template(values) and + list(six.viewkeys(values)) != ["name"]): raise exception.ClusterTemplateReferenced( clustertemplate=cluster_template_id) diff --git a/magnum/tests/unit/api/controllers/v1/test_baymodel.py b/magnum/tests/unit/api/controllers/v1/test_baymodel.py index a1e208b84b..9ae756563b 100644 --- a/magnum/tests/unit/api/controllers/v1/test_baymodel.py +++ b/magnum/tests/unit/api/controllers/v1/test_baymodel.py @@ -225,8 +225,8 @@ class TestPatch(api_base.FunctionalTest): cluster_template_id=baymodel.uuid) response = self.patch_json('/baymodels/%s' % baymodel.uuid, - [{'path': '/name', - 'value': 'bay_model_example_B', + [{'path': '/network_driver', + 'value': 'flannel', 'op': 'replace'}], expect_errors=True) self.assertEqual(400, response.status_int) @@ -234,6 +234,18 @@ class TestPatch(api_base.FunctionalTest): self.assertTrue(response.json['errors']) self.assertIn(baymodel.uuid, response.json['errors'][0]['detail']) + def test_update_baymodel_name_with_bay(self): + baymodel = obj_utils.create_test_cluster_template(self.context) + obj_utils.create_test_cluster(self.context, + cluster_template_id=baymodel.uuid) + + response = self.patch_json('/baymodels/%s' % baymodel.uuid, + [{'path': '/name', + 'value': 'bay_model_example_B', + 'op': 'replace'}], + expect_errors=True) + self.assertEqual(200, response.status_int) + @mock.patch.object(magnum_policy, 'enforce') def test_update_public_baymodel_success(self, mock_policy): mock_policy.return_value = True @@ -274,8 +286,8 @@ class TestPatch(api_base.FunctionalTest): obj_utils.create_test_cluster(self.context, cluster_template_id=baymodel.uuid) response = self.patch_json('/baymodels/%s' % baymodel.uuid, - [{'path': '/name', - 'value': 'new_name', + [{'path': '/network_driver', + 'value': 'calico', 'op': 'replace'}], expect_errors=True) self.assertEqual(400, response.status_code) diff --git a/magnum/tests/unit/api/controllers/v1/test_cluster_template.py b/magnum/tests/unit/api/controllers/v1/test_cluster_template.py index 584ed994ed..1e1359a457 100644 --- a/magnum/tests/unit/api/controllers/v1/test_cluster_template.py +++ b/magnum/tests/unit/api/controllers/v1/test_cluster_template.py @@ -284,8 +284,8 @@ class TestPatch(api_base.FunctionalTest): response = self.patch_json('/clustertemplates/%s' % cluster_template.uuid, - [{'path': '/name', - 'value': 'cluster_model_example_B', + [{'path': '/network_driver', + 'value': 'flannel', 'op': 'replace'}], expect_errors=True) self.assertEqual(400, response.status_int) @@ -294,6 +294,19 @@ class TestPatch(api_base.FunctionalTest): self.assertIn(cluster_template.uuid, response.json['errors'][0]['detail']) + def test_update_cluster_template_name_with_cluster(self): + cluster_template = obj_utils.create_test_cluster_template(self.context) + obj_utils.create_test_cluster( + self.context, cluster_template_id=cluster_template.uuid) + + response = self.patch_json('/clustertemplates/%s' % + cluster_template.uuid, + [{'path': '/name', + 'value': 'cluster_model_example_B', + 'op': 'replace'}], + expect_errors=True) + self.assertEqual(200, response.status_int) + @mock.patch.object(magnum_policy, 'enforce') def test_update_public_cluster_template_success(self, mock_policy): mock_policy.return_value = True @@ -353,8 +366,8 @@ class TestPatch(api_base.FunctionalTest): self.context, cluster_template_id=cluster_template.uuid) response = self.patch_json('/clustertemplates/%s' % cluster_template.uuid, - [{'path': '/name', - 'value': 'new_name', + [{'path': '/network_driver', + 'value': 'calico', 'op': 'replace'}], expect_errors=True) self.assertEqual(400, response.status_code) diff --git a/releasenotes/notes/allow-cluster-template-being-renamed-82f7d5d1f33a7957.yaml b/releasenotes/notes/allow-cluster-template-being-renamed-82f7d5d1f33a7957.yaml new file mode 100644 index 0000000000..75754255d1 --- /dev/null +++ b/releasenotes/notes/allow-cluster-template-being-renamed-82f7d5d1f33a7957.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + To get a better cluster template versioning and relieve the pain + of maintaining public cluster template, now the name of cluster template + can be changed. +