From 12fa9199d474a89cfb06acbfec6d8da88928ea15 Mon Sep 17 00:00:00 2001 From: Dong Ma Date: Wed, 25 Jul 2018 17:13:28 +0000 Subject: [PATCH] Delete check of function alias This commit add function alias check of delete function and delete function version, if there is alias associated with the function or function version, the function or function version deletion will fail. Change-Id: Ic45f5e0bcf30266fccd7b1ed649e79f94eaccdc3 Story: #2002143 Task: 23265 --- qinling/api/controllers/v1/function.py | 4 ++++ qinling/api/controllers/v1/function_version.py | 12 +++++++++++- qinling/db/sqlalchemy/models.py | 4 ++++ .../unit/api/controllers/v1/test_function.py | 17 +++++++++++++++++ .../controllers/v1/test_function_version.py | 18 ++++++++++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) diff --git a/qinling/api/controllers/v1/function.py b/qinling/api/controllers/v1/function.py index 5aa6549f..a80b351a 100644 --- a/qinling/api/controllers/v1/function.py +++ b/qinling/api/controllers/v1/function.py @@ -281,6 +281,10 @@ class FunctionsController(rest.RestController): raise exc.NotAllowedException( 'The function is still associated with webhook(s).' ) + if len(func_db.aliases) > 0: + raise exc.NotAllowedException( + 'The function is still associated with function alias(es).' + ) # Even admin user can not delete other project's function because # the trust associated can only be removed by function owner. diff --git a/qinling/api/controllers/v1/function_version.py b/qinling/api/controllers/v1/function_version.py index 25847d28..a4077366 100644 --- a/qinling/api/controllers/v1/function_version.py +++ b/qinling/api/controllers/v1/function_version.py @@ -243,7 +243,17 @@ class FunctionVersionsController(rest.RestController): ) if len(version_webhook) > 0: raise exc.NotAllowedException( - 'The function versioin is still associated with webhook.' + 'The function version is still associated with webhook.' + ) + + filters = rest_utils.get_filters( + function_id=version_db.function_id, + function_version=version_db.version_number + ) + version_aliases = db_api.get_function_aliases(**filters) + if len(version_aliases) > 0: + raise exc.NotAllowedException( + 'The function version is still associated with alias.' ) # Delete resources for function version diff --git a/qinling/db/sqlalchemy/models.py b/qinling/db/sqlalchemy/models.py index d7764532..a7f2d7d1 100644 --- a/qinling/db/sqlalchemy/models.py +++ b/qinling/db/sqlalchemy/models.py @@ -164,3 +164,7 @@ Function.versions = relationship( lazy='select', cascade="all, delete-orphan" ) +Function.aliases = relationship( + "FunctionAlias", + uselist=True +) diff --git a/qinling/tests/unit/api/controllers/v1/test_function.py b/qinling/tests/unit/api/controllers/v1/test_function.py index a3c70dba..9966b43d 100644 --- a/qinling/tests/unit/api/controllers/v1/test_function.py +++ b/qinling/tests/unit/api/controllers/v1/test_function.py @@ -377,6 +377,23 @@ class TestFunctionController(base.APITest): self.assertEqual(403, resp.status_int) + def test_delete_with_alias(self): + db_func = self.create_function(runtime_id=self.runtime_id) + func_id = db_func.id + name = self.rand_name(name="alias", prefix=self.prefix) + body = { + 'function_id': func_id, + 'name': name + } + db_api.create_function_alias(**body) + + resp = self.app.delete( + '/v1/functions/%s' % func_id, + expect_errors=True + ) + + self.assertEqual(403, resp.status_int) + @mock.patch('qinling.rpc.EngineClient.scaleup_function') def test_scale_up(self, scaleup_function_mock): db_func = self.create_function(runtime_id=self.runtime_id) diff --git a/qinling/tests/unit/api/controllers/v1/test_function_version.py b/qinling/tests/unit/api/controllers/v1/test_function_version.py index 048920f9..337c2db5 100644 --- a/qinling/tests/unit/api/controllers/v1/test_function_version.py +++ b/qinling/tests/unit/api/controllers/v1/test_function_version.py @@ -190,6 +190,24 @@ class TestFunctionVersionController(base.APITest): self.assertEqual(403, resp.status_int) + def test_delete_with_alias(self): + db_api.increase_function_version(self.func_id, 0, + description="version 1") + name = self.rand_name(name="alias", prefix=self.prefix) + body = { + 'function_id': self.func_id, + 'function_version': 1, + 'name': name + } + db_api.create_function_alias(**body) + + resp = self.app.delete( + '/v1/functions/%s/versions/1' % self.func_id, + expect_errors=True + ) + + self.assertEqual(403, resp.status_int) + @mock.patch('qinling.rpc.EngineClient.scaleup_function') def test_scale_up(self, scaleup_function_mock): db_api.increase_function_version(self.func_id, 0)