From 2616494f139322a32eca558d63f9a9c0e806c57c Mon Sep 17 00:00:00 2001 From: Dong Ma Date: Mon, 23 Jul 2018 11:32:13 +0000 Subject: [PATCH] Support alias for webhook creation This commit to support alias for webhook creation, to create webhook use function_alias pramater, and get function_id and function_version from function_alias. Also add function tests for webhook creation. Change-Id: Ia5db0b446b6b0e0980da596ed073fa6e2d66d7cc Story: #2002143 Task: #19988 --- qinling/api/controllers/v1/resources.py | 1 + qinling/api/controllers/v1/webhook.py | 14 ++++++++-- .../unit/api/controllers/v1/test_webhook.py | 28 +++++++++++++++++++ .../services/qinling_client.py | 18 ++++++++++-- .../tests/api/test_webhooks.py | 28 +++++++++++++++++++ qinling_tempest_plugin/tests/base.py | 18 ++++++++---- 6 files changed, 97 insertions(+), 10 deletions(-) diff --git a/qinling/api/controllers/v1/resources.py b/qinling/api/controllers/v1/resources.py index 2c60353f..6c731e18 100644 --- a/qinling/api/controllers/v1/resources.py +++ b/qinling/api/controllers/v1/resources.py @@ -365,6 +365,7 @@ class ScaleInfo(Resource): class Webhook(Resource): id = types.uuid function_id = types.uuid + function_alias = wtypes.text function_version = wsme.wsattr(int) description = wtypes.text project_id = wsme.wsattr(wtypes.text, readonly=True) diff --git a/qinling/api/controllers/v1/webhook.py b/qinling/api/controllers/v1/webhook.py index 85ba1486..d0569b65 100644 --- a/qinling/api/controllers/v1/webhook.py +++ b/qinling/api/controllers/v1/webhook.py @@ -34,7 +34,6 @@ from qinling.utils import rest_utils LOG = logging.getLogger(__name__) -POST_REQUIRED = set(['function_id']) UPDATE_ALLOWED = set(['function_id', 'function_version', 'description']) @@ -104,11 +103,20 @@ class WebhooksController(rest.RestController): acl.enforce('webhook:create', context.get_ctx()) params = webhook.to_dict() - if not POST_REQUIRED.issubset(set(params.keys())): + if not (params.get("function_id") or params.get("function_alias")): raise exc.InputException( - 'Required param is missing. Required: %s' % POST_REQUIRED + 'Either function_alias or function_id must be provided.' ) + # if function_alias provided + function_alias = params.get('function_alias') + if function_alias: + alias_db = db_api.get_function_alias(function_alias) + function_id = alias_db.function_id + version = alias_db.function_version + params.update({'function_id': function_id, + 'function_version': version}) + LOG.info("Creating %s, params: %s", self.type, params) # Even admin user can not expose normal user's function diff --git a/qinling/tests/unit/api/controllers/v1/test_webhook.py b/qinling/tests/unit/api/controllers/v1/test_webhook.py index 60d0f603..1b1d43c0 100644 --- a/qinling/tests/unit/api/controllers/v1/test_webhook.py +++ b/qinling/tests/unit/api/controllers/v1/test_webhook.py @@ -80,6 +80,34 @@ class TestWebhookController(base.APITest): self.assertEqual(201, resp.status_int) self.assertEqual(1, resp.json.get("function_version")) + def test_post_with_alias(self): + db_api.increase_function_version(self.func_id, 0) + 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) + + webhook_body = { + 'function_alias': name, + 'description': 'webhook test' + } + resp = self.app.post_json('/v1/webhooks', webhook_body) + + self.assertEqual(201, resp.status_int) + self.assertEqual(1, resp.json.get("function_version")) + + def test_post_without_required_params(self): + resp = self.app.post( + '/v1/webhooks', + params={}, + expect_errors=True + ) + + self.assertEqual(400, resp.status_int) + def test_put_with_version(self): db_api.increase_function_version(self.func_id, 0) webhook = self.create_webhook(self.func_id) diff --git a/qinling_tempest_plugin/services/qinling_client.py b/qinling_tempest_plugin/services/qinling_client.py index 567e6ac8..87f33d47 100644 --- a/qinling_tempest_plugin/services/qinling_client.py +++ b/qinling_tempest_plugin/services/qinling_client.py @@ -169,8 +169,22 @@ class QinlingClient(client_base.QinlingClientBase): return self.get_resources(url) - def create_webhook(self, function_id, version=0): - req_body = {"function_id": function_id, "function_version": version} + def create_webhook(self, function_id=None, function_alias=None, + version=0): + """Create webhook. + + function_alias takes precedence over function_id. + """ + if function_alias: + req_body = {'function_alias': function_alias} + elif function_id: + req_body = { + 'function_id': function_id, + 'function_version': version + } + else: + raise Exception("Either function_alias or function_id must be " + "provided.") resp, body = self.post_json('webhooks', req_body) return resp, body diff --git a/qinling_tempest_plugin/tests/api/test_webhooks.py b/qinling_tempest_plugin/tests/api/test_webhooks.py index f067b5ab..25bdd050 100644 --- a/qinling_tempest_plugin/tests/api/test_webhooks.py +++ b/qinling_tempest_plugin/tests/api/test_webhooks.py @@ -76,6 +76,34 @@ class WebhooksTest(base.BaseQinlingTest): self.assertEqual(200, resp.status) self.assertIn('version_test', body) + @decorators.idempotent_id('a5b5eed3-82ee-4ab1-b9ca-9898e4da6b5a') + def test_webhook_with_function_alias(self): + version = self.create_function_version(self.function_id) + function_alias = self.create_function_alias(self.function_id, version) + webhook_id, url = self.create_webhook(function_alias=function_alias) + resp = requests.post(url, data={'name': 'alias_test'}, verify=False) + + self.assertEqual(202, resp.status_code) + + resp_exec_id = resp.json().get('execution_id') + self.addCleanup(self.client.delete_resource, 'executions', + resp_exec_id, ignore_notfound=True) + + resp, body = self.client.get_resources( + 'executions', + {'description': 'has:%s' % webhook_id} + ) + + self.assertEqual(200, resp.status) + self.assertEqual(1, len(body['executions'])) + exec_id = body['executions'][0]['id'] + self.assertEqual(resp_exec_id, exec_id) + self.wait_execution_success(exec_id) + + resp, body = self.client.get_execution_log(exec_id) + self.assertEqual(200, resp.status) + self.assertIn('alias_test', body) + @decorators.idempotent_id('8e6e4f76-f748-11e7-8ec3-00224d6b7bc1') def test_get_all_admin(self): """Admin user can get webhooks of other projects""" diff --git a/qinling_tempest_plugin/tests/base.py b/qinling_tempest_plugin/tests/base.py index a95db597..7d14707f 100644 --- a/qinling_tempest_plugin/tests/base.py +++ b/qinling_tempest_plugin/tests/base.py @@ -169,11 +169,19 @@ class BaseQinlingTest(test.BaseTestCase): self.assertEqual(200, resp.status_code) - def create_webhook(self, function_id=None, version=0): - if not function_id: - function_id = self.create_function() - - resp, body = self.client.create_webhook(function_id, version=version) + def create_webhook(self, function_id=None, function_alias=None, + version=0): + if function_alias: + resp, body = self.client.create_webhook( + function_alias=function_alias + ) + else: + if not function_id: + function_id = self.create_function() + resp, body = self.client.create_webhook( + function_id, + version=version + ) self.assertEqual(201, resp.status) webhook_id = body['id']