Initial version - Webhook DB APIs
Change-Id: I4e91f0d5f211935d518a35254b665e9e682f2e2b
This commit is contained in:
parent
80b0834384
commit
4c9fc5163b
|
@ -103,6 +103,13 @@ CLUSTER_POLICY_ATTRS = (
|
|||
'policy_id', 'priority', 'level', 'cooldown', 'enabled',
|
||||
)
|
||||
|
||||
WEBHOOK_ATTRS = (
|
||||
WEBHOOK_NAME, WEBHOOK_OBJ_ID, WEBHOOK_OBJ_TYPE,
|
||||
WEBHOOK_CREATED_TIME, WEBHOOK_DELETED_TIME,
|
||||
) = (
|
||||
'name', 'obj_id', 'obj_type', 'created_time', 'deleted_time',
|
||||
)
|
||||
|
||||
EVENT_ATTRS = (
|
||||
EVENT_TIMESTAMP, EVENT_OBJ_ID, EVENT_OBJ_NAME, EVENT_OBJ_TYPE,
|
||||
EVENT_USER, EVENT_ACTION, EVENT_STATUS, EVENT_STATUS_REASON,
|
||||
|
|
|
@ -291,6 +291,40 @@ def event_get_all_by_cluster(context, cluster_id, limit=None, marker=None,
|
|||
filters=filters)
|
||||
|
||||
|
||||
# Webhooks
|
||||
def webhook_create(context, values):
|
||||
return IMPL.webhook_create(context, values)
|
||||
|
||||
|
||||
def webhook_get(context, webhook_id, show_deleted=False):
|
||||
return IMPL.webhook_get(context, webhook_id, show_deleted=show_deleted)
|
||||
|
||||
|
||||
def webhook_get_by_name(context, name, show_deleted=False):
|
||||
return IMPL.webhook_get_by_name(context, name, show_deleted=show_deleted)
|
||||
|
||||
|
||||
def webhook_get_all(context, show_deleted=False, limit=None,
|
||||
marker=None, sort_keys=None, sort_dir=None,
|
||||
filters=None, tenant_safe=True):
|
||||
return IMPL.webhook_get_all(context, show_deleted=show_deleted,
|
||||
limit=limit, marker=marker,
|
||||
sort_keys=sort_keys, sort_dir=sort_dir,
|
||||
filters=filters, tenant_safe=tenant_safe)
|
||||
|
||||
|
||||
def webhook_get_all_by_obj_id(context, obj_id):
|
||||
return IMPL.webhook_get_all_by_obj_id(context, obj_id)
|
||||
|
||||
|
||||
def webhook_get_all_by_obj_type(context, obj_type):
|
||||
return IMPL.webhook_get_all_by_obj_type(context, obj_type)
|
||||
|
||||
|
||||
def webhook_delete(context, webhook_id, force=False):
|
||||
return IMPL.webhook_delete(context, webhook_id, force)
|
||||
|
||||
|
||||
# Actions
|
||||
def action_create(context, values):
|
||||
return IMPL.action_create(context, values)
|
||||
|
|
|
@ -472,6 +472,79 @@ def node_delete(context, node_id, force=False):
|
|||
session.flush()
|
||||
|
||||
|
||||
# Webhooks
|
||||
def webhook_create(context, values):
|
||||
webhook = models.Webhook()
|
||||
webhook.update(values)
|
||||
webhook.save(_session(context))
|
||||
return webhook
|
||||
|
||||
|
||||
def webhook_get(context, webhook_id, show_deleted=False):
|
||||
webhook = model_query(context, models.Webhook).get(webhook_id)
|
||||
if not webhook:
|
||||
return None
|
||||
|
||||
if not show_deleted and webhook.deleted_time is not None:
|
||||
return None
|
||||
|
||||
return webhook
|
||||
|
||||
|
||||
def webhook_get_by_name(context, name, show_deleted=False):
|
||||
return query_by_name(context, models.Webhook, name,
|
||||
show_deleted=show_deleted)
|
||||
|
||||
|
||||
def webhook_get_all(context, show_deleted=False, limit=None,
|
||||
marker=None, sort_keys=None, sort_dir=None,
|
||||
filters=None, tenant_safe=True):
|
||||
query = soft_delete_aware_query(context, models.Webhook,
|
||||
show_deleted=show_deleted)
|
||||
|
||||
if tenant_safe:
|
||||
query = query.filter_by(project=context.tenant_id)
|
||||
|
||||
if filters is None:
|
||||
filters = {}
|
||||
|
||||
sort_key_map = {
|
||||
consts.WEBHOOK_NAME: models.Webhook.name.key,
|
||||
consts.WEBHOOK_OBJ_ID: models.Webhook.obj_id.key,
|
||||
consts.WEBHOOK_OBJ_TYPE: models.Webhook.obj_type.key,
|
||||
consts.WEBHOOK_CREATED_TIME: models.Webhook.created_time.key,
|
||||
consts.WEBHOOK_DELETED_TIME: models.Webhook.deleted_time.key,
|
||||
}
|
||||
keys = _get_sort_keys(sort_keys, sort_key_map)
|
||||
query = db_filters.exact_filter(query, models.Webhook, filters)
|
||||
return _paginate_query(context, query, models.Webhook,
|
||||
limit=limit, marker=marker,
|
||||
sort_keys=keys, sort_dir=sort_dir,
|
||||
default_sort_keys=['obj_id']).all()
|
||||
|
||||
|
||||
def webhook_get_all_by_obj_id(context, obj_id):
|
||||
query = model_query(context, models.Webhook).filter_by(obj_id=obj_id)
|
||||
webhooks = query.all()
|
||||
return webhooks
|
||||
|
||||
|
||||
def webhook_get_all_by_obj_type(context, obj_type):
|
||||
query = model_query(context, models.Webhook).filter_by(obj_type=obj_type)
|
||||
webhooks = query.all()
|
||||
return webhooks
|
||||
|
||||
|
||||
def webhook_delete(context, webhook_id, force=False):
|
||||
session = _session(context)
|
||||
webhook = session.query(models.Webhook).get(webhook_id)
|
||||
if not webhook:
|
||||
return
|
||||
|
||||
webhook.soft_delete(session=session)
|
||||
session.flush()
|
||||
|
||||
|
||||
# Locks
|
||||
def cluster_lock_acquire(cluster_id, action_id, scope):
|
||||
'''Acquire lock on a cluster.
|
||||
|
|
|
@ -100,6 +100,24 @@ def create_node(ctx, cluster, profile, **kwargs):
|
|||
return db_api.node_create(ctx, values)
|
||||
|
||||
|
||||
def create_webhook(ctx, obj_id, obj_type, action, **kwargs):
|
||||
values = {
|
||||
'name': 'test_webhook_name',
|
||||
'user': ctx.user,
|
||||
'project': ctx.tenant_id,
|
||||
'domain': ctx.domain,
|
||||
'created_time': None,
|
||||
'deleted_time': None,
|
||||
'obj_id': obj_id,
|
||||
'obj_type': obj_type,
|
||||
'action': action,
|
||||
'credential': None,
|
||||
'params': None,
|
||||
}
|
||||
values.update(kwargs)
|
||||
return db_api.webhook_create(ctx, values)
|
||||
|
||||
|
||||
def create_action(ctx, **kwargs):
|
||||
values = {
|
||||
'context': kwargs.get('context'),
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
# 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.
|
||||
|
||||
import datetime
|
||||
|
||||
from senlin.db.sqlalchemy import api as db_api
|
||||
from senlin.tests.common import base
|
||||
from senlin.tests.common import utils
|
||||
from senlin.tests.db import shared
|
||||
|
||||
UUID1 = shared.UUID1
|
||||
UUID2 = shared.UUID2
|
||||
UUID3 = shared.UUID3
|
||||
|
||||
|
||||
class DBAPIWebhookTest(base.SenlinTestCase):
|
||||
def setUp(self):
|
||||
super(DBAPIWebhookTest, self).setUp()
|
||||
self.ctx = utils.dummy_context()
|
||||
self.obj_id = UUID1
|
||||
self.obj_type = 'test_obj_type'
|
||||
self.action = 'test_action'
|
||||
|
||||
def test_webhook_create(self):
|
||||
res = shared.create_webhook(self.ctx, self.obj_id,
|
||||
self.obj_type, self.action)
|
||||
webhook = db_api.webhook_get(self.ctx, res.id)
|
||||
self.assertIsNotNone(webhook)
|
||||
self.assertEqual(UUID1, webhook.obj_id)
|
||||
self.assertEqual('test_webhook_name', webhook.name)
|
||||
self.assertEqual(self.ctx.user, webhook.user)
|
||||
self.assertEqual(self.ctx.domain, webhook.domain)
|
||||
self.assertEqual(self.ctx.tenant_id, webhook.project)
|
||||
self.assertIsNone(webhook.created_time)
|
||||
self.assertIsNone(webhook.deleted_time)
|
||||
self.assertEqual('test_obj_type', webhook.obj_type)
|
||||
self.assertEqual('test_action', webhook.action)
|
||||
|
||||
def test_webhook_get(self):
|
||||
res = shared.create_webhook(self.ctx, self.obj_id,
|
||||
self.obj_type, self.action)
|
||||
webhook = db_api.webhook_get(self.ctx, res.id)
|
||||
self.assertIsNotNone(webhook)
|
||||
|
||||
def test_webhook_get_show_deleted(self):
|
||||
res = shared.create_webhook(self.ctx, self.obj_id,
|
||||
self.obj_type, self.action)
|
||||
webhook_id = res.id
|
||||
webhook = db_api.webhook_get(self.ctx, webhook_id)
|
||||
self.assertIsNotNone(webhook)
|
||||
|
||||
db_api.webhook_delete(self.ctx, webhook_id)
|
||||
|
||||
webhook = db_api.webhook_get(self.ctx, webhook_id)
|
||||
self.assertIsNone(webhook)
|
||||
|
||||
webhook = db_api.webhook_get(self.ctx, webhook_id, show_deleted=False)
|
||||
self.assertIsNone(webhook)
|
||||
|
||||
webhook = db_api.webhook_get(self.ctx, webhook_id, show_deleted=True)
|
||||
self.assertEqual(webhook_id, webhook.id)
|
||||
|
||||
def test_webhook_get_by_name(self):
|
||||
webhook_name = 'fake_webhook_name'
|
||||
shared.create_webhook(self.ctx, self.obj_id, self.obj_type,
|
||||
self.action, name=webhook_name)
|
||||
webhook = db_api.webhook_get_by_name(self.ctx, webhook_name)
|
||||
self.assertIsNotNone(webhook)
|
||||
self.assertEqual(webhook_name, webhook.name)
|
||||
|
||||
res = db_api.webhook_get_by_name(self.ctx, 'BogusName')
|
||||
self.assertIsNone(res)
|
||||
|
||||
def test_webhook_get_by_name_show_deleted(self):
|
||||
webhook_name = 'fake_webhook_name'
|
||||
shared.create_webhook(self.ctx, self.obj_id, self.obj_type,
|
||||
self.action, name=webhook_name)
|
||||
webhook = db_api.webhook_get_by_name(self.ctx, webhook_name)
|
||||
self.assertIsNotNone(webhook)
|
||||
self.assertEqual(webhook_name, webhook.name)
|
||||
|
||||
webhook_id = webhook.id
|
||||
db_api.webhook_delete(self.ctx, webhook_id)
|
||||
|
||||
res = db_api.webhook_get_by_name(self.ctx, webhook_name)
|
||||
self.assertIsNone(res)
|
||||
|
||||
res = db_api.webhook_get_by_name(self.ctx, webhook_name,
|
||||
show_deleted=False)
|
||||
self.assertIsNone(res)
|
||||
|
||||
res = db_api.webhook_get_by_name(self.ctx, webhook_name,
|
||||
show_deleted=True)
|
||||
self.assertEqual(webhook_id, res.id)
|
||||
|
||||
def test_webhook_get_all(self):
|
||||
values = [{'name': 'webhook1'},
|
||||
{'name': 'webhook2'},
|
||||
{'name': 'webhook3'}]
|
||||
[shared.create_webhook(
|
||||
self.ctx, self.obj_id, self.obj_type,
|
||||
self.action, **v) for v in values]
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx)
|
||||
self.assertEqual(3, len(webhooks))
|
||||
|
||||
names = [webhook.name for webhook in webhooks]
|
||||
[self.assertIn(val['name'], names) for val in values]
|
||||
|
||||
def test_webhook_get_all_show_deleted(self):
|
||||
values = [{'id': 'webhook1'}, {'id': 'webhook2'}, {'id': 'webhook3'}]
|
||||
for v in values:
|
||||
shared.create_webhook(self.ctx, self.obj_id, self.obj_type,
|
||||
self.action, **v)
|
||||
|
||||
db_api.webhook_delete(self.ctx, 'webhook2')
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx)
|
||||
self.assertEqual(2, len(webhooks))
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx, show_deleted=False)
|
||||
self.assertEqual(2, len(webhooks))
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx, show_deleted=True)
|
||||
self.assertEqual(3, len(webhooks))
|
||||
|
||||
def test_webhook_get_all_with_limit_marker(self):
|
||||
webhook_ids = ['webhook1', 'webhook2', 'webhook3']
|
||||
for v in webhook_ids:
|
||||
shared.create_webhook(self.ctx, self.obj_id, self.obj_type,
|
||||
self.action, id=v,
|
||||
created_time=datetime.datetime.utcnow())
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx, limit=1)
|
||||
self.assertEqual(1, len(webhooks))
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx, limit=2)
|
||||
self.assertEqual(2, len(webhooks))
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx, limit=5)
|
||||
self.assertEqual(3, len(webhooks))
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx, marker='webhook1')
|
||||
self.assertEqual(2, len(webhooks))
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx, marker='webhook2')
|
||||
self.assertEqual(1, len(webhooks))
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx, marker='webhook3')
|
||||
self.assertEqual(0, len(webhooks))
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx, limit=1, marker='webhook1')
|
||||
self.assertEqual(1, len(webhooks))
|
||||
|
||||
def test_webhook_get_all_used_sort_keys(self):
|
||||
webhook_ids = ['webhook1', 'webhook2', 'webhook3']
|
||||
for v in webhook_ids:
|
||||
shared.create_webhook(self.ctx, self.obj_id, self.obj_type,
|
||||
self.action, id=v)
|
||||
|
||||
mock_paginate = self.patchobject(db_api.utils, 'paginate_query')
|
||||
sort_keys = ['name', 'created_time', 'deleted_time',
|
||||
'obj_id', 'obj_type']
|
||||
|
||||
db_api.webhook_get_all(self.ctx, sort_keys=sort_keys)
|
||||
args = mock_paginate.call_args[0]
|
||||
used_sort_keys = set(args[3])
|
||||
expected_keys = set(['name', 'created_time', 'deleted_time',
|
||||
'obj_id', 'obj_type', 'id'])
|
||||
self.assertEqual(expected_keys, used_sort_keys)
|
||||
|
||||
def test_webhook_get_all_sort_keys_wont_change(self):
|
||||
sort_keys = ['id']
|
||||
db_api.webhook_get_all(self.ctx, sort_keys=sort_keys)
|
||||
self.assertEqual(['id'], sort_keys)
|
||||
|
||||
def test_webhook_get_all_sort_keys_and_dir(self):
|
||||
values = [{'id': '001', 'name': 'webhook1'},
|
||||
{'id': '002', 'name': 'webhook3'},
|
||||
{'id': '003', 'name': 'webhook2'}]
|
||||
obj_ids = {'webhook1': 'id3',
|
||||
'webhook2': 'id2',
|
||||
'webhook3': 'id1'}
|
||||
for v in values:
|
||||
shared.create_webhook(self.ctx, obj_ids[v['name']],
|
||||
self.obj_type,
|
||||
self.action, **v)
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx,
|
||||
sort_keys=['name', 'obj_id'],
|
||||
sort_dir='asc')
|
||||
self.assertEqual(3, len(webhooks))
|
||||
# Sorted by name (ascending)
|
||||
self.assertEqual('001', webhooks[0].id)
|
||||
self.assertEqual('003', webhooks[1].id)
|
||||
self.assertEqual('002', webhooks[2].id)
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx,
|
||||
sort_keys=['obj_id', 'name'],
|
||||
sort_dir='asc')
|
||||
self.assertEqual(3, len(webhooks))
|
||||
# Sorted by obj_id (ascending)
|
||||
self.assertEqual('002', webhooks[0].id)
|
||||
self.assertEqual('003', webhooks[1].id)
|
||||
self.assertEqual('001', webhooks[2].id)
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx,
|
||||
sort_keys=['obj_id', 'name'],
|
||||
sort_dir='desc')
|
||||
self.assertEqual(3, len(webhooks))
|
||||
# Sorted by obj_id (descending)
|
||||
self.assertEqual('001', webhooks[0].id)
|
||||
self.assertEqual('003', webhooks[1].id)
|
||||
self.assertEqual('002', webhooks[2].id)
|
||||
|
||||
def test_webhook_get_all_default_sort_dir(self):
|
||||
values = [{'id': '001', 'name': 'webhook1'},
|
||||
{'id': '002', 'name': 'webhook2'},
|
||||
{'id': '003', 'name': 'webhook3'}]
|
||||
obj_ids = {'webhook1': 'id3',
|
||||
'webhook2': 'id2',
|
||||
'webhook3': 'id1'}
|
||||
for v in values:
|
||||
shared.create_webhook(self.ctx, obj_ids[v['name']],
|
||||
self.obj_type,
|
||||
self.action, **v)
|
||||
|
||||
webhooks = db_api.webhook_get_all(self.ctx, sort_dir='asc')
|
||||
self.assertEqual(3, len(webhooks))
|
||||
self.assertEqual(values[2]['id'], webhooks[0].id)
|
||||
self.assertEqual(values[1]['id'], webhooks[1].id)
|
||||
self.assertEqual(values[0]['id'], webhooks[2].id)
|
||||
|
||||
def test_webhook_get_all_with_filters(self):
|
||||
shared.create_webhook(self.ctx, self.obj_id,
|
||||
self.obj_type, self.action, name='webhook1')
|
||||
shared.create_webhook(self.ctx, self.obj_id,
|
||||
self.obj_type, self.action, name='webhook2')
|
||||
|
||||
filters = {'name': ['webhook1', 'webhookx']}
|
||||
results = db_api.webhook_get_all(self.ctx, filters=filters)
|
||||
self.assertEqual(1, len(results))
|
||||
self.assertEqual('webhook1', results[0]['name'])
|
||||
|
||||
filters = {'name': 'webhook1'}
|
||||
results = db_api.webhook_get_all(self.ctx, filters=filters)
|
||||
self.assertEqual(1, len(results))
|
||||
self.assertEqual('webhook1', results[0]['name'])
|
||||
|
||||
def test_webhook_get_all_with_empty_filters(self):
|
||||
shared.create_webhook(self.ctx, self.obj_id,
|
||||
self.obj_type, self.action, name='webhook1')
|
||||
shared.create_webhook(self.ctx, self.obj_id,
|
||||
self.obj_type, self.action, name='webhook2')
|
||||
|
||||
filters = None
|
||||
results = db_api.webhook_get_all(self.ctx, filters=filters)
|
||||
self.assertEqual(2, len(results))
|
||||
|
||||
def test_webhook_get_all_with_tenant_safe(self):
|
||||
shared.create_webhook(self.ctx, self.obj_id,
|
||||
self.obj_type, self.action, name='webhook1')
|
||||
shared.create_webhook(self.ctx, self.obj_id,
|
||||
self.obj_type, self.action, name='webhook2')
|
||||
|
||||
self.ctx.tenant_id = 'a-different-tenant'
|
||||
results = db_api.webhook_get_all(self.ctx, tenant_safe=False)
|
||||
self.assertEqual(2, len(results))
|
||||
|
||||
self.ctx.tenant_id = 'a-different-tenant'
|
||||
results = db_api.webhook_get_all(self.ctx)
|
||||
self.assertEqual(0, len(results))
|
||||
|
||||
results = db_api.webhook_get_all(self.ctx, tenant_safe=True)
|
||||
self.assertEqual(0, len(results))
|
||||
|
||||
def test_webhook_get_by_obj_id(self):
|
||||
obj_ids = [UUID1, UUID2]
|
||||
for obj_id in obj_ids:
|
||||
shared.create_webhook(self.ctx, obj_id,
|
||||
self.obj_type,
|
||||
self.action)
|
||||
|
||||
webhooks = db_api.webhook_get_all_by_obj_id(self.ctx, obj_ids[0])
|
||||
|
||||
self.assertEqual(1, len(webhooks))
|
||||
self.assertEqual(obj_ids[0], webhooks[0].obj_id)
|
||||
|
||||
webhooks = db_api.webhook_get_all_by_obj_id(self.ctx, None)
|
||||
self.assertEqual(0, len(webhooks))
|
||||
|
||||
def test_webhook_get_by_obj_type(self):
|
||||
obj_types = ['type1', 'type2']
|
||||
for obj_type in obj_types:
|
||||
shared.create_webhook(self.ctx, self.obj_id,
|
||||
obj_type,
|
||||
self.action)
|
||||
|
||||
webhooks = db_api.webhook_get_all_by_obj_type(self.ctx, obj_types[0])
|
||||
|
||||
self.assertEqual(1, len(webhooks))
|
||||
self.assertEqual(obj_types[0], webhooks[0].obj_type)
|
||||
|
||||
webhooks = db_api.webhook_get_all_by_obj_type(self.ctx, None)
|
||||
self.assertEqual(0, len(webhooks))
|
||||
|
||||
def test_webhook_delete(self):
|
||||
res = shared.create_webhook(self.ctx, self.obj_id,
|
||||
self.obj_type, self.action)
|
||||
webhook_id = res.id
|
||||
webhook = db_api.webhook_get(self.ctx, webhook_id)
|
||||
self.assertIsNotNone(webhook)
|
||||
|
||||
db_api.webhook_delete(self.ctx, webhook_id)
|
||||
res = db_api.webhook_get(self.ctx, webhook_id)
|
||||
self.assertIsNone(res)
|
||||
|
||||
def test_webhook_delete_not_found(self):
|
||||
webhook_id = 'BogusWebhookID'
|
||||
res = db_api.webhook_delete(self.ctx, webhook_id)
|
||||
self.assertIsNone(res)
|
||||
|
||||
res = db_api.webhook_get(self.ctx, webhook_id)
|
||||
self.assertIsNone(res)
|
Loading…
Reference in New Issue