Merge "Allow to use both name and id to access action definitions"
This commit is contained in:
commit
e0741669b2
@ -102,12 +102,16 @@ class ActionsController(rest.RestController, hooks.HookController):
|
|||||||
|
|
||||||
@rest_utils.wrap_wsme_controller_exception
|
@rest_utils.wrap_wsme_controller_exception
|
||||||
@wsme_pecan.wsexpose(Action, wtypes.text)
|
@wsme_pecan.wsexpose(Action, wtypes.text)
|
||||||
def get(self, name):
|
def get(self, identifier):
|
||||||
"""Return the named action."""
|
"""Return the named action.
|
||||||
acl.enforce('actions:get', context.ctx())
|
|
||||||
LOG.info("Fetch action [name=%s]" % name)
|
|
||||||
|
|
||||||
db_model = db_api.get_action_definition(name)
|
:param identifier: ID or name of the Action to get.
|
||||||
|
"""
|
||||||
|
|
||||||
|
acl.enforce('actions:get', context.ctx())
|
||||||
|
LOG.info("Fetch action [identifier=%s]" % identifier)
|
||||||
|
|
||||||
|
db_model = db_api.get_action_definition(identifier)
|
||||||
|
|
||||||
return Action.from_dict(db_model.to_dict())
|
return Action.from_dict(db_model.to_dict())
|
||||||
|
|
||||||
@ -169,19 +173,19 @@ class ActionsController(rest.RestController, hooks.HookController):
|
|||||||
|
|
||||||
@rest_utils.wrap_wsme_controller_exception
|
@rest_utils.wrap_wsme_controller_exception
|
||||||
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
|
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
|
||||||
def delete(self, name):
|
def delete(self, identifier):
|
||||||
"""Delete the named action."""
|
"""Delete the named action."""
|
||||||
acl.enforce('actions:delete', context.ctx())
|
acl.enforce('actions:delete', context.ctx())
|
||||||
LOG.info("Delete action [name=%s]" % name)
|
LOG.info("Delete action [identifier=%s]" % identifier)
|
||||||
|
|
||||||
with db_api.transaction():
|
with db_api.transaction():
|
||||||
db_model = db_api.get_action_definition(name)
|
db_model = db_api.get_action_definition(identifier)
|
||||||
|
|
||||||
if db_model.is_system:
|
if db_model.is_system:
|
||||||
msg = "Attempt to delete a system action: %s" % name
|
msg = "Attempt to delete a system action: %s" % identifier
|
||||||
raise exc.DataAccessException(msg)
|
raise exc.DataAccessException(msg)
|
||||||
|
|
||||||
db_api.delete_action_definition(name)
|
db_api.delete_action_definition(identifier)
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(Actions, types.uuid, int, types.uniquelist,
|
@wsme_pecan.wsexpose(Actions, types.uuid, int, types.uniquelist,
|
||||||
types.list, types.uniquelist, wtypes.text,
|
types.list, types.uniquelist, wtypes.text,
|
||||||
|
@ -21,7 +21,7 @@ from oslo_db import exception as db_exc
|
|||||||
from oslo_db import sqlalchemy as oslo_sqlalchemy
|
from oslo_db import sqlalchemy as oslo_sqlalchemy
|
||||||
from oslo_db.sqlalchemy import utils as db_utils
|
from oslo_db.sqlalchemy import utils as db_utils
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils # noqa
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
|
||||||
from mistral.db.sqlalchemy import base as b
|
from mistral.db.sqlalchemy import base as b
|
||||||
@ -232,6 +232,18 @@ def _get_db_object_by_id(model, id):
|
|||||||
return _secure_query(model).filter_by(id=id).first()
|
return _secure_query(model).filter_by(id=id).first()
|
||||||
|
|
||||||
|
|
||||||
|
def _get_db_object_by_name_or_id(model, identifier):
|
||||||
|
query = _secure_query(model)
|
||||||
|
query = query.filter(
|
||||||
|
sa.or_(
|
||||||
|
model.id == identifier,
|
||||||
|
model.name == identifier
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return query.first()
|
||||||
|
|
||||||
|
|
||||||
# Workbook definitions.
|
# Workbook definitions.
|
||||||
|
|
||||||
def get_workbook(name):
|
def get_workbook(name):
|
||||||
@ -321,9 +333,10 @@ def get_workflow_definition(identifier):
|
|||||||
uuid.
|
uuid.
|
||||||
:return: Workflow definition.
|
:return: Workflow definition.
|
||||||
"""
|
"""
|
||||||
wf_def = (_get_workflow_definition_by_id(identifier)
|
wf_def = _get_db_object_by_name_or_id(
|
||||||
if uuidutils.is_uuid_like(identifier)
|
models.WorkflowDefinition,
|
||||||
else _get_workflow_definition(identifier))
|
identifier
|
||||||
|
)
|
||||||
|
|
||||||
if not wf_def:
|
if not wf_def:
|
||||||
raise exc.DBEntityNotFoundError(
|
raise exc.DBEntityNotFoundError(
|
||||||
@ -334,7 +347,7 @@ def get_workflow_definition(identifier):
|
|||||||
|
|
||||||
|
|
||||||
def get_workflow_definition_by_id(id):
|
def get_workflow_definition_by_id(id):
|
||||||
wf_def = _get_workflow_definition_by_id(id)
|
wf_def = _get_db_object_by_id(models.WorkflowDefinition, id)
|
||||||
|
|
||||||
if not wf_def:
|
if not wf_def:
|
||||||
raise exc.DBEntityNotFoundError(
|
raise exc.DBEntityNotFoundError(
|
||||||
@ -345,7 +358,7 @@ def get_workflow_definition_by_id(id):
|
|||||||
|
|
||||||
|
|
||||||
def load_workflow_definition(name):
|
def load_workflow_definition(name):
|
||||||
return _get_workflow_definition(name)
|
return _get_db_object_by_name(models.WorkflowDefinition, name)
|
||||||
|
|
||||||
|
|
||||||
def get_workflow_definitions(sort_keys=['created_at'], fields=None, **kwargs):
|
def get_workflow_definitions(sort_keys=['created_at'], fields=None, **kwargs):
|
||||||
@ -424,7 +437,7 @@ def update_workflow_definition(identifier, values, session=None):
|
|||||||
|
|
||||||
@b.session_aware()
|
@b.session_aware()
|
||||||
def create_or_update_workflow_definition(name, values, session=None):
|
def create_or_update_workflow_definition(name, values, session=None):
|
||||||
if not _get_workflow_definition(name):
|
if not _get_db_object_by_name(models.WorkflowDefinition, name):
|
||||||
return create_workflow_definition(values)
|
return create_workflow_definition(values)
|
||||||
else:
|
else:
|
||||||
return update_workflow_definition(name, values)
|
return update_workflow_definition(name, values)
|
||||||
@ -472,14 +485,6 @@ def delete_workflow_definitions(**kwargs):
|
|||||||
return _delete_all(models.WorkflowDefinition, **kwargs)
|
return _delete_all(models.WorkflowDefinition, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def _get_workflow_definition(name):
|
|
||||||
return _get_db_object_by_name(models.WorkflowDefinition, name)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_workflow_definition_by_id(id):
|
|
||||||
return _get_db_object_by_id(models.WorkflowDefinition, id)
|
|
||||||
|
|
||||||
|
|
||||||
# Action definitions.
|
# Action definitions.
|
||||||
|
|
||||||
def get_action_definition_by_id(id):
|
def get_action_definition_by_id(id):
|
||||||
@ -493,19 +498,22 @@ def get_action_definition_by_id(id):
|
|||||||
return action_def
|
return action_def
|
||||||
|
|
||||||
|
|
||||||
def get_action_definition(name):
|
def get_action_definition(identifier):
|
||||||
a_def = _get_action_definition(name)
|
a_def = _get_db_object_by_name_or_id(
|
||||||
|
models.ActionDefinition,
|
||||||
|
identifier
|
||||||
|
)
|
||||||
|
|
||||||
if not a_def:
|
if not a_def:
|
||||||
raise exc.DBEntityNotFoundError(
|
raise exc.DBEntityNotFoundError(
|
||||||
"Action definition not found [action_name=%s]" % name
|
"Action definition not found [action_name=%s]" % identifier
|
||||||
)
|
)
|
||||||
|
|
||||||
return a_def
|
return a_def
|
||||||
|
|
||||||
|
|
||||||
def load_action_definition(name):
|
def load_action_definition(name):
|
||||||
return _get_action_definition(name)
|
return _get_db_object_by_name(models.ActionDefinition, name)
|
||||||
|
|
||||||
|
|
||||||
def get_action_definitions(**kwargs):
|
def get_action_definitions(**kwargs):
|
||||||
@ -533,7 +541,7 @@ def create_action_definition(values, session=None):
|
|||||||
|
|
||||||
@b.session_aware()
|
@b.session_aware()
|
||||||
def update_action_definition(name, values, session=None):
|
def update_action_definition(name, values, session=None):
|
||||||
a_def = _get_action_definition(name)
|
a_def = _get_db_object_by_name(models.ActionDefinition, name)
|
||||||
|
|
||||||
if not a_def:
|
if not a_def:
|
||||||
raise exc.DBEntityNotFoundError(
|
raise exc.DBEntityNotFoundError(
|
||||||
@ -547,20 +555,15 @@ def update_action_definition(name, values, session=None):
|
|||||||
|
|
||||||
@b.session_aware()
|
@b.session_aware()
|
||||||
def create_or_update_action_definition(name, values, session=None):
|
def create_or_update_action_definition(name, values, session=None):
|
||||||
if not _get_action_definition(name):
|
if not _get_db_object_by_name(models.ActionDefinition, name):
|
||||||
return create_action_definition(values)
|
return create_action_definition(values)
|
||||||
else:
|
else:
|
||||||
return update_action_definition(name, values)
|
return update_action_definition(name, values)
|
||||||
|
|
||||||
|
|
||||||
@b.session_aware()
|
@b.session_aware()
|
||||||
def delete_action_definition(name, session=None):
|
def delete_action_definition(identifier, session=None):
|
||||||
a_def = _get_action_definition(name)
|
a_def = get_action_definition(identifier)
|
||||||
|
|
||||||
if not a_def:
|
|
||||||
raise exc.DBEntityNotFoundError(
|
|
||||||
"Action definition not found [action_name=%s]" % name
|
|
||||||
)
|
|
||||||
|
|
||||||
session.delete(a_def)
|
session.delete(a_def)
|
||||||
|
|
||||||
@ -570,10 +573,6 @@ def delete_action_definitions(**kwargs):
|
|||||||
return _delete_all(models.ActionDefinition, **kwargs)
|
return _delete_all(models.ActionDefinition, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def _get_action_definition(name):
|
|
||||||
return _get_db_object_by_name(models.ActionDefinition, name)
|
|
||||||
|
|
||||||
|
|
||||||
# Common executions.
|
# Common executions.
|
||||||
|
|
||||||
def get_execution(id):
|
def get_execution(id):
|
||||||
|
@ -124,21 +124,44 @@ MOCK_DUPLICATE = mock.MagicMock(side_effect=exc.DBDuplicateEntryError())
|
|||||||
|
|
||||||
|
|
||||||
class TestActionsController(base.APITest):
|
class TestActionsController(base.APITest):
|
||||||
@mock.patch.object(db_api, "get_action_definition", MOCK_ACTION)
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definition", MOCK_ACTION)
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
resp = self.app.get('/v2/actions/my_action')
|
resp = self.app.get('/v2/actions/my_action')
|
||||||
|
|
||||||
self.assertEqual(200, resp.status_int)
|
self.assertEqual(200, resp.status_int)
|
||||||
self.assertDictEqual(ACTION, resp.json)
|
self.assertDictEqual(ACTION, resp.json)
|
||||||
|
|
||||||
@mock.patch.object(db_api, "get_action_definition", MOCK_NOT_FOUND)
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definition", MOCK_NOT_FOUND)
|
||||||
def test_get_not_found(self):
|
def test_get_not_found(self):
|
||||||
resp = self.app.get('/v2/actions/my_action', expect_errors=True)
|
resp = self.app.get('/v2/actions/my_action', expect_errors=True)
|
||||||
|
|
||||||
self.assertEqual(404, resp.status_int)
|
self.assertEqual(404, resp.status_int)
|
||||||
|
|
||||||
@mock.patch.object(db_api, "get_action_definition", MOCK_ACTION)
|
|
||||||
@mock.patch.object(db_api, "update_action_definition", MOCK_UPDATED_ACTION)
|
@mock.patch.object(db_api, "update_action_definition", MOCK_UPDATED_ACTION)
|
||||||
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definition", MOCK_ACTION)
|
||||||
|
def test_get_by_id(self):
|
||||||
|
url = '/v2/actions/{0}'.format(ACTION['id'])
|
||||||
|
resp = self.app.get(url)
|
||||||
|
|
||||||
|
self.assertEqual(200, resp.status_int)
|
||||||
|
self.assertEqual(ACTION['id'], resp.json['id'])
|
||||||
|
|
||||||
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definition", MOCK_NOT_FOUND)
|
||||||
|
def test_get_by_id_not_found(self):
|
||||||
|
url = '/v2/actions/1234'
|
||||||
|
resp = self.app.get(url, expect_errors=True)
|
||||||
|
|
||||||
|
self.assertEqual(404, resp.status_int)
|
||||||
|
|
||||||
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definition", MOCK_ACTION)
|
||||||
|
@mock.patch.object(
|
||||||
|
db_api, "update_action_definition", MOCK_UPDATED_ACTION
|
||||||
|
)
|
||||||
def test_put(self):
|
def test_put(self):
|
||||||
resp = self.app.put(
|
resp = self.app.put(
|
||||||
'/v2/actions',
|
'/v2/actions',
|
||||||
@ -178,7 +201,8 @@ class TestActionsController(base.APITest):
|
|||||||
|
|
||||||
self.assertEqual(404, resp.status_int)
|
self.assertEqual(404, resp.status_int)
|
||||||
|
|
||||||
@mock.patch.object(db_api, "get_action_definition", MOCK_SYSTEM_ACTION)
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definition", MOCK_SYSTEM_ACTION)
|
||||||
def test_put_system(self):
|
def test_put_system(self):
|
||||||
resp = self.app.put(
|
resp = self.app.put(
|
||||||
'/v2/actions',
|
'/v2/actions',
|
||||||
@ -257,7 +281,8 @@ class TestActionsController(base.APITest):
|
|||||||
|
|
||||||
self.assertEqual(409, resp.status_int)
|
self.assertEqual(409, resp.status_int)
|
||||||
|
|
||||||
@mock.patch.object(db_api, "get_action_definition", MOCK_ACTION)
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definition", MOCK_ACTION)
|
||||||
@mock.patch.object(db_api, "delete_action_definition", MOCK_DELETE)
|
@mock.patch.object(db_api, "delete_action_definition", MOCK_DELETE)
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
resp = self.app.delete('/v2/actions/my_action')
|
resp = self.app.delete('/v2/actions/my_action')
|
||||||
@ -270,7 +295,8 @@ class TestActionsController(base.APITest):
|
|||||||
|
|
||||||
self.assertEqual(404, resp.status_int)
|
self.assertEqual(404, resp.status_int)
|
||||||
|
|
||||||
@mock.patch.object(db_api, "get_action_definition", MOCK_SYSTEM_ACTION)
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definition", MOCK_SYSTEM_ACTION)
|
||||||
def test_delete_system(self):
|
def test_delete_system(self):
|
||||||
resp = self.app.delete('/v2/actions/std.echo', expect_errors=True)
|
resp = self.app.delete('/v2/actions/std.echo', expect_errors=True)
|
||||||
|
|
||||||
@ -278,7 +304,8 @@ class TestActionsController(base.APITest):
|
|||||||
self.assertIn('Attempt to delete a system action: std.echo',
|
self.assertIn('Attempt to delete a system action: std.echo',
|
||||||
resp.json['faultstring'])
|
resp.json['faultstring'])
|
||||||
|
|
||||||
@mock.patch.object(db_api, "get_action_definitions", MOCK_ACTIONS)
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definitions", MOCK_ACTIONS)
|
||||||
def test_get_all(self):
|
def test_get_all(self):
|
||||||
resp = self.app.get('/v2/actions')
|
resp = self.app.get('/v2/actions')
|
||||||
|
|
||||||
@ -287,7 +314,8 @@ class TestActionsController(base.APITest):
|
|||||||
self.assertEqual(1, len(resp.json['actions']))
|
self.assertEqual(1, len(resp.json['actions']))
|
||||||
self.assertDictEqual(ACTION, resp.json['actions'][0])
|
self.assertDictEqual(ACTION, resp.json['actions'][0])
|
||||||
|
|
||||||
@mock.patch.object(db_api, "get_action_definitions", MOCK_EMPTY)
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definitions", MOCK_EMPTY)
|
||||||
def test_get_all_empty(self):
|
def test_get_all_empty(self):
|
||||||
resp = self.app.get('/v2/actions')
|
resp = self.app.get('/v2/actions')
|
||||||
|
|
||||||
@ -295,7 +323,8 @@ class TestActionsController(base.APITest):
|
|||||||
|
|
||||||
self.assertEqual(0, len(resp.json['actions']))
|
self.assertEqual(0, len(resp.json['actions']))
|
||||||
|
|
||||||
@mock.patch.object(db_api, "get_action_definitions", MOCK_ACTIONS)
|
@mock.patch.object(
|
||||||
|
db_api, "get_action_definitions", MOCK_ACTIONS)
|
||||||
def test_get_all_pagination(self):
|
def test_get_all_pagination(self):
|
||||||
resp = self.app.get(
|
resp = self.app.get(
|
||||||
'/v2/actions?limit=1&sort_keys=id,name')
|
'/v2/actions?limit=1&sort_keys=id,name')
|
||||||
|
Loading…
Reference in New Issue
Block a user