Fix API inconsistencies with GET /v2/workflows
Add missing API parameters to Workbooks, Actions, Executions, Cron Triggers, Environments, Action Executions and Tasks: marker, limit, sort_keys, sort_dirs, fields, filters Change-Id: I207bc93e84067f83f926843f0b9895a19b831079 Partial-Bug: #1585646
This commit is contained in:
parent
0ff3627f9e
commit
0e51d26e1c
@ -182,9 +182,9 @@ class ActionsController(rest.RestController, hooks.HookController):
|
|||||||
db_api.delete_action_definition(name)
|
db_api.delete_action_definition(name)
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(Actions, types.uuid, int, types.uniquelist,
|
@wsme_pecan.wsexpose(Actions, types.uuid, int, types.uniquelist,
|
||||||
types.list)
|
types.list, types.uniquelist, types.jsontype)
|
||||||
def get_all(self, marker=None, limit=None, sort_keys='name',
|
def get_all(self, marker=None, limit=None, sort_keys='name',
|
||||||
sort_dirs='asc'):
|
sort_dirs='asc', fields='', **filters):
|
||||||
"""Return all actions.
|
"""Return all actions.
|
||||||
|
|
||||||
:param marker: Optional. Pagination marker for large data sets.
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
@ -196,35 +196,30 @@ class ActionsController(rest.RestController, hooks.HookController):
|
|||||||
:param sort_dirs: Optional. Directions to sort corresponding to
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
sort_keys, "asc" or "desc" can be choosed.
|
sort_keys, "asc" or "desc" can be choosed.
|
||||||
Default: asc.
|
Default: asc.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
|
||||||
Where project_id is the same as the requester or
|
Where project_id is the same as the requester or
|
||||||
project_id is different but the scope is public.
|
project_id is different but the scope is public.
|
||||||
"""
|
"""
|
||||||
acl.enforce('actions:list', context.ctx())
|
acl.enforce('actions:list', context.ctx())
|
||||||
LOG.info("Fetch actions. marker=%s, limit=%s, sort_keys=%s, "
|
LOG.info("Fetch actions. marker=%s, limit=%s, sort_keys=%s, "
|
||||||
"sort_dirs=%s", marker, limit, sort_keys, sort_dirs)
|
"sort_dirs=%s, filters=%s", marker, limit, sort_keys,
|
||||||
|
sort_dirs, filters)
|
||||||
|
|
||||||
rest_utils.validate_query_params(limit, sort_keys, sort_dirs)
|
return rest_utils.get_all(
|
||||||
|
Actions,
|
||||||
marker_obj = None
|
Action,
|
||||||
|
db_api.get_action_definitions,
|
||||||
if marker:
|
db_api.get_action_definition_by_id,
|
||||||
marker_obj = db_api.get_action_definition_by_id(marker)
|
resource_function=None,
|
||||||
|
marker=marker,
|
||||||
db_action_defs = db_api.get_action_definitions(
|
|
||||||
limit=limit,
|
limit=limit,
|
||||||
marker=marker_obj,
|
|
||||||
sort_keys=sort_keys,
|
sort_keys=sort_keys,
|
||||||
sort_dirs=sort_dirs
|
sort_dirs=sort_dirs,
|
||||||
)
|
fields=fields,
|
||||||
|
**filters
|
||||||
actions_list = [Action.from_dict(db_model.to_dict())
|
|
||||||
for db_model in db_action_defs]
|
|
||||||
|
|
||||||
return Actions.convert_with_links(
|
|
||||||
actions_list,
|
|
||||||
limit,
|
|
||||||
pecan.request.host_url,
|
|
||||||
sort_keys=','.join(sort_keys),
|
|
||||||
sort_dirs=','.join(sort_dirs)
|
|
||||||
)
|
)
|
||||||
|
@ -79,11 +79,16 @@ class ActionExecution(resource.Resource):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ActionExecutions(resource.Resource):
|
class ActionExecutions(resource.ResourceList):
|
||||||
"""A collection of action_executions."""
|
"""A collection of action_executions."""
|
||||||
|
|
||||||
action_executions = [ActionExecution]
|
action_executions = [ActionExecution]
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self._type = 'action_executions'
|
||||||
|
|
||||||
|
super(ActionExecutions, self).__init__(**kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def sample(cls):
|
def sample(cls):
|
||||||
return cls(action_executions=[ActionExecution.sample()])
|
return cls(action_executions=[ActionExecution.sample()])
|
||||||
@ -115,18 +120,48 @@ def _get_action_execution_resource(action_ex):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def _get_action_executions(task_execution_id=None):
|
def _get_action_executions(task_execution_id=None, marker=None, limit=None,
|
||||||
kwargs = {'type': 'action_execution'}
|
sort_keys='created_at', sort_dirs='asc',
|
||||||
|
fields='', **filters):
|
||||||
|
"""Return all action executions.
|
||||||
|
|
||||||
|
Where project_id is the same as the requestor or
|
||||||
|
project_id is different but the scope is public.
|
||||||
|
|
||||||
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
|
:param limit: Optional. Maximum number of resources to return in a
|
||||||
|
single result. Default value is None for backward
|
||||||
|
compatibility.
|
||||||
|
:param sort_keys: Optional. Columns to sort results by.
|
||||||
|
Default: created_at, which is backward compatible.
|
||||||
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
|
sort_keys, "asc" or "desc" can be chosen.
|
||||||
|
Default: desc. The length of sort_dirs can be equal
|
||||||
|
or less than that of sort_keys.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
"""
|
||||||
|
filters['type'] = 'action_execution'
|
||||||
|
|
||||||
if task_execution_id:
|
if task_execution_id:
|
||||||
kwargs['task_execution_id'] = task_execution_id
|
filters['task_execution_id'] = task_execution_id
|
||||||
|
|
||||||
action_execs = [
|
return rest_utils.get_all(
|
||||||
_get_action_execution_resource(a_ex)
|
ActionExecutions,
|
||||||
for a_ex in db_api.get_action_executions(**kwargs)
|
ActionExecution,
|
||||||
]
|
db_api.get_action_executions,
|
||||||
|
db_api.get_action_execution,
|
||||||
return ActionExecutions(action_executions=action_execs)
|
resource_function=_get_action_execution_resource,
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ActionExecutionsController(rest.RestController):
|
class ActionExecutionsController(rest.RestController):
|
||||||
@ -194,13 +229,45 @@ class ActionExecutionsController(rest.RestController):
|
|||||||
|
|
||||||
return ActionExecution.from_dict(values)
|
return ActionExecution.from_dict(values)
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(ActionExecutions)
|
@wsme_pecan.wsexpose(ActionExecutions, types.uuid, int, types.uniquelist,
|
||||||
def get_all(self):
|
types.list, types.uniquelist, types.jsontype)
|
||||||
"""Return all action_executions within the execution."""
|
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
||||||
acl.enforce('action_executions:list', context.ctx())
|
sort_dirs='asc', fields='', **filters):
|
||||||
LOG.info("Fetch action_executions")
|
"""Return all tasks within the execution.
|
||||||
|
|
||||||
return _get_action_executions()
|
Where project_id is the same as the requestor or
|
||||||
|
project_id is different but the scope is public.
|
||||||
|
|
||||||
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
|
:param limit: Optional. Maximum number of resources to return in a
|
||||||
|
single result. Default value is None for backward
|
||||||
|
compatibility.
|
||||||
|
:param sort_keys: Optional. Columns to sort results by.
|
||||||
|
Default: created_at, which is backward compatible.
|
||||||
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
|
sort_keys, "asc" or "desc" can be chosen.
|
||||||
|
Default: desc. The length of sort_dirs can be equal
|
||||||
|
or less than that of sort_keys.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
|
||||||
|
"""
|
||||||
|
acl.enforce('action_executions:list', context.ctx())
|
||||||
|
LOG.info("Fetch action_executions. marker=%s, limit=%s, "
|
||||||
|
"sort_keys=%s, sort_dirs=%s, filters=%s",
|
||||||
|
marker, limit, sort_keys, sort_dirs, filters)
|
||||||
|
|
||||||
|
return _get_action_executions(
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
|
||||||
@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)
|
||||||
@ -228,13 +295,46 @@ class ActionExecutionsController(rest.RestController):
|
|||||||
|
|
||||||
|
|
||||||
class TasksActionExecutionController(rest.RestController):
|
class TasksActionExecutionController(rest.RestController):
|
||||||
@wsme_pecan.wsexpose(ActionExecutions, wtypes.text)
|
@wsme_pecan.wsexpose(ActionExecutions, types.uuid, types.uuid, int,
|
||||||
def get_all(self, task_execution_id):
|
types.uniquelist, types.list, types.uniquelist,
|
||||||
"""Return all action executions within the task execution."""
|
types.jsontype)
|
||||||
acl.enforce('action_executions:list', context.ctx())
|
def get_all(self, task_execution_id, marker=None, limit=None,
|
||||||
LOG.info("Fetch action executions")
|
sort_keys='created_at', sort_dirs='asc', fields='', **filters):
|
||||||
|
"""Return all tasks within the execution.
|
||||||
|
|
||||||
return _get_action_executions(task_execution_id=task_execution_id)
|
Where project_id is the same as the requestor or
|
||||||
|
project_id is different but the scope is public.
|
||||||
|
|
||||||
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
|
:param limit: Optional. Maximum number of resources to return in a
|
||||||
|
single result. Default value is None for backward
|
||||||
|
compatibility.
|
||||||
|
:param sort_keys: Optional. Columns to sort results by.
|
||||||
|
Default: created_at, which is backward compatible.
|
||||||
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
|
sort_keys, "asc" or "desc" can be chosen.
|
||||||
|
Default: desc. The length of sort_dirs can be equal
|
||||||
|
or less than that of sort_keys.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
"""
|
||||||
|
acl.enforce('action_executions:list', context.ctx())
|
||||||
|
LOG.info("Fetch action_executions. marker=%s, limit=%s, "
|
||||||
|
"sort_keys=%s, sort_dirs=%s, filters=%s",
|
||||||
|
marker, limit, sort_keys, sort_dirs, filters)
|
||||||
|
|
||||||
|
return _get_action_executions(
|
||||||
|
task_execution_id=task_execution_id,
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
|
||||||
@rest_utils.wrap_wsme_controller_exception
|
@rest_utils.wrap_wsme_controller_exception
|
||||||
@wsme_pecan.wsexpose(ActionExecution, wtypes.text, wtypes.text)
|
@wsme_pecan.wsexpose(ActionExecution, wtypes.text, wtypes.text)
|
||||||
|
@ -64,11 +64,16 @@ class CronTrigger(resource.Resource):
|
|||||||
updated_at='1970-01-01T00:00:00.000000')
|
updated_at='1970-01-01T00:00:00.000000')
|
||||||
|
|
||||||
|
|
||||||
class CronTriggers(resource.Resource):
|
class CronTriggers(resource.ResourceList):
|
||||||
"""A collection of cron triggers."""
|
"""A collection of cron triggers."""
|
||||||
|
|
||||||
cron_triggers = [CronTrigger]
|
cron_triggers = [CronTrigger]
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self._type = 'cron_triggers'
|
||||||
|
|
||||||
|
super(CronTriggers, self).__init__(**kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def sample(cls):
|
def sample(cls):
|
||||||
return cls(cron_triggers=[CronTrigger.sample()])
|
return cls(cron_triggers=[CronTrigger.sample()])
|
||||||
@ -119,16 +124,44 @@ class CronTriggersController(rest.RestController):
|
|||||||
|
|
||||||
db_api.delete_cron_trigger(name)
|
db_api.delete_cron_trigger(name)
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(CronTriggers)
|
@wsme_pecan.wsexpose(CronTriggers, types.uuid, int, types.uniquelist,
|
||||||
def get_all(self):
|
types.list, types.uniquelist, types.jsontype)
|
||||||
"""Return all cron triggers."""
|
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
||||||
|
sort_dirs='asc', fields='', **filters):
|
||||||
|
"""Return all cron triggers.
|
||||||
|
|
||||||
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
|
:param limit: Optional. Maximum number of resources to return in a
|
||||||
|
single result. Default value is None for backward
|
||||||
|
compatibility.
|
||||||
|
:param sort_keys: Optional. Columns to sort results by.
|
||||||
|
Default: created_at, which is backward compatible.
|
||||||
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
|
sort_keys, "asc" or "desc" can be chosen.
|
||||||
|
Default: desc. The length of sort_dirs can be equal
|
||||||
|
or less than that of sort_keys.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
|
||||||
|
"""
|
||||||
acl.enforce('cron_triggers:list', context.ctx())
|
acl.enforce('cron_triggers:list', context.ctx())
|
||||||
LOG.info("Fetch cron triggers.")
|
LOG.info("Fetch cron triggers. marker=%s, limit=%s, sort_keys=%s, "
|
||||||
|
"sort_dirs=%s, filters=%s", marker, limit, sort_keys,
|
||||||
|
sort_dirs, filters)
|
||||||
|
|
||||||
_list = [
|
return rest_utils.get_all(
|
||||||
CronTrigger.from_dict(db_model.to_dict())
|
CronTriggers,
|
||||||
for db_model in db_api.get_cron_triggers()
|
CronTrigger,
|
||||||
]
|
db_api.get_cron_triggers,
|
||||||
|
db_api.get_cron_trigger,
|
||||||
return CronTriggers(cron_triggers=_list)
|
resource_function=None,
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
@ -61,33 +61,66 @@ class Environment(resource.Resource):
|
|||||||
updated_at='1970-01-01T00:00:00.000000')
|
updated_at='1970-01-01T00:00:00.000000')
|
||||||
|
|
||||||
|
|
||||||
class Environments(resource.Resource):
|
class Environments(resource.ResourceList):
|
||||||
"""A collection of Environment resources."""
|
"""A collection of Environment resources."""
|
||||||
|
|
||||||
environments = [Environment]
|
environments = [Environment]
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self._type = 'environments'
|
||||||
|
|
||||||
|
super(Environments, self).__init__(**kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def sample(cls):
|
def sample(cls):
|
||||||
return cls(environments=[Environment.sample()])
|
return cls(environments=[Environment.sample()])
|
||||||
|
|
||||||
|
|
||||||
class EnvironmentController(rest.RestController):
|
class EnvironmentController(rest.RestController):
|
||||||
@wsme_pecan.wsexpose(Environments)
|
@wsme_pecan.wsexpose(Environments, types.uuid, int, types.uniquelist,
|
||||||
def get_all(self):
|
types.list, types.uniquelist, types.jsontype)
|
||||||
|
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
||||||
|
sort_dirs='asc', fields='', **filters):
|
||||||
"""Return all environments.
|
"""Return all environments.
|
||||||
|
|
||||||
Where project_id is the same as the requestor or
|
Where project_id is the same as the requestor or
|
||||||
project_id is different but the scope is public.
|
project_id is different but the scope is public.
|
||||||
|
|
||||||
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
|
:param limit: Optional. Maximum number of resources to return in a
|
||||||
|
single result. Default value is None for backward
|
||||||
|
compatibility.
|
||||||
|
:param sort_keys: Optional. Columns to sort results by.
|
||||||
|
Default: created_at, which is backward compatible.
|
||||||
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
|
sort_keys, "asc" or "desc" can be chosen.
|
||||||
|
Default: desc. The length of sort_dirs can be equal
|
||||||
|
or less than that of sort_keys.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
acl.enforce('environments:list', context.ctx())
|
acl.enforce('environments:list', context.ctx())
|
||||||
LOG.info("Fetch environments.")
|
LOG.info("Fetch environments. marker=%s, limit=%s, sort_keys=%s, "
|
||||||
|
"sort_dirs=%s, filters=%s", marker, limit, sort_keys,
|
||||||
|
sort_dirs, filters)
|
||||||
|
|
||||||
environments = [
|
return rest_utils.get_all(
|
||||||
Environment.from_dict(db_model.to_dict())
|
Environments,
|
||||||
for db_model in db_api.get_environments()
|
Environment,
|
||||||
]
|
db_api.get_environments,
|
||||||
|
db_api.get_environment,
|
||||||
return Environments(environments=environments)
|
resource_function=None,
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
|
||||||
@rest_utils.wrap_wsme_controller_exception
|
@rest_utils.wrap_wsme_controller_exception
|
||||||
@wsme_pecan.wsexpose(Environment, wtypes.text)
|
@wsme_pecan.wsexpose(Environment, wtypes.text)
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
import pecan
|
|
||||||
from pecan import rest
|
from pecan import rest
|
||||||
from wsme import types as wtypes
|
from wsme import types as wtypes
|
||||||
import wsmeext.pecan as wsme_pecan
|
import wsmeext.pecan as wsme_pecan
|
||||||
@ -255,9 +254,9 @@ class ExecutionsController(rest.RestController):
|
|||||||
return db_api.delete_workflow_execution(id)
|
return db_api.delete_workflow_execution(id)
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(Executions, types.uuid, int, types.uniquelist,
|
@wsme_pecan.wsexpose(Executions, types.uuid, int, types.uniquelist,
|
||||||
types.list)
|
types.list, types.uniquelist, types.jsontype)
|
||||||
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
||||||
sort_dirs='asc'):
|
sort_dirs='asc', fields='', **filters):
|
||||||
"""Return all Executions.
|
"""Return all Executions.
|
||||||
|
|
||||||
:param marker: Optional. Pagination marker for large data sets.
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
@ -270,36 +269,30 @@ class ExecutionsController(rest.RestController):
|
|||||||
sort_keys, "asc" or "desc" can be chosen.
|
sort_keys, "asc" or "desc" can be chosen.
|
||||||
Default: desc. The length of sort_dirs can be equal
|
Default: desc. The length of sort_dirs can be equal
|
||||||
or less than that of sort_keys.
|
or less than that of sort_keys.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
acl.enforce('executions:list', context.ctx())
|
acl.enforce('executions:list', context.ctx())
|
||||||
LOG.info(
|
LOG.info(
|
||||||
"Fetch executions. marker=%s, limit=%s, sort_keys=%s, "
|
"Fetch executions. marker=%s, limit=%s, sort_keys=%s, "
|
||||||
"sort_dirs=%s", marker, limit, sort_keys, sort_dirs
|
"sort_dirs=%s, filters=%s", marker, limit, sort_keys, sort_dirs,
|
||||||
|
filters
|
||||||
)
|
)
|
||||||
|
|
||||||
rest_utils.validate_query_params(limit, sort_keys, sort_dirs)
|
return rest_utils.get_all(
|
||||||
|
Executions,
|
||||||
marker_obj = None
|
Execution,
|
||||||
|
db_api.get_workflow_executions,
|
||||||
if marker:
|
db_api.get_workflow_execution,
|
||||||
marker_obj = db_api.get_workflow_execution(marker)
|
resource_function=None,
|
||||||
|
marker=marker,
|
||||||
db_workflow_exs = db_api.get_workflow_executions(
|
|
||||||
limit=limit,
|
limit=limit,
|
||||||
marker=marker_obj,
|
|
||||||
sort_keys=sort_keys,
|
sort_keys=sort_keys,
|
||||||
sort_dirs=sort_dirs
|
sort_dirs=sort_dirs,
|
||||||
)
|
fields=fields,
|
||||||
|
**filters
|
||||||
wf_executions = [
|
|
||||||
Execution.from_dict(db_model.to_dict())
|
|
||||||
for db_model in db_workflow_exs
|
|
||||||
]
|
|
||||||
|
|
||||||
return Executions.convert_with_links(
|
|
||||||
wf_executions,
|
|
||||||
limit,
|
|
||||||
pecan.request.host_url,
|
|
||||||
sort_keys=','.join(sort_keys),
|
|
||||||
sort_dirs=','.join(sort_dirs)
|
|
||||||
)
|
)
|
||||||
|
@ -85,11 +85,16 @@ class Task(resource.Resource):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Tasks(resource.Resource):
|
class Tasks(resource.ResourceList):
|
||||||
"""A collection of tasks."""
|
"""A collection of tasks."""
|
||||||
|
|
||||||
tasks = [Task]
|
tasks = [Task]
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self._type = 'tasks'
|
||||||
|
|
||||||
|
super(Tasks, self).__init__(**kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def sample(cls):
|
def sample(cls):
|
||||||
return cls(tasks=[Task.sample()])
|
return cls(tasks=[Task.sample()])
|
||||||
@ -102,16 +107,46 @@ def _get_task_resource_with_result(task_ex):
|
|||||||
return task
|
return task
|
||||||
|
|
||||||
|
|
||||||
def _get_task_resources_with_results(wf_ex_id=None):
|
def _get_task_resources_with_results(wf_ex_id=None, marker=None, limit=None,
|
||||||
filters = {}
|
sort_keys='created_at', sort_dirs='asc',
|
||||||
|
fields='', **filters):
|
||||||
|
"""Return all tasks within the execution.
|
||||||
|
|
||||||
|
Where project_id is the same as the requestor or
|
||||||
|
project_id is different but the scope is public.
|
||||||
|
|
||||||
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
|
:param limit: Optional. Maximum number of resources to return in a
|
||||||
|
single result. Default value is None for backward
|
||||||
|
compatibility.
|
||||||
|
:param sort_keys: Optional. Columns to sort results by.
|
||||||
|
Default: created_at, which is backward compatible.
|
||||||
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
|
sort_keys, "asc" or "desc" can be chosen.
|
||||||
|
Default: desc. The length of sort_dirs can be equal
|
||||||
|
or less than that of sort_keys.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
"""
|
||||||
if wf_ex_id:
|
if wf_ex_id:
|
||||||
filters['workflow_execution_id'] = wf_ex_id
|
filters['workflow_execution_id'] = wf_ex_id
|
||||||
|
|
||||||
task_exs = db_api.get_task_executions(**filters)
|
return rest_utils.get_all(
|
||||||
tasks = [_get_task_resource_with_result(t_e) for t_e in task_exs]
|
Tasks,
|
||||||
|
Task,
|
||||||
return Tasks(tasks=tasks)
|
db_api.get_task_executions,
|
||||||
|
db_api.get_task_execution,
|
||||||
|
resource_function=_get_task_resource_with_result,
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TasksController(rest.RestController):
|
class TasksController(rest.RestController):
|
||||||
@ -128,13 +163,45 @@ class TasksController(rest.RestController):
|
|||||||
|
|
||||||
return _get_task_resource_with_result(task_ex)
|
return _get_task_resource_with_result(task_ex)
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(Tasks)
|
@wsme_pecan.wsexpose(Tasks, types.uuid, int, types.uniquelist,
|
||||||
def get_all(self):
|
types.list, types.uniquelist, types.jsontype)
|
||||||
"""Return all tasks within the execution."""
|
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
||||||
acl.enforce('tasks:list', context.ctx())
|
sort_dirs='asc', fields='', **filters):
|
||||||
LOG.info("Fetch tasks")
|
"""Return all tasks.
|
||||||
|
|
||||||
return _get_task_resources_with_results()
|
Where project_id is the same as the requestor or
|
||||||
|
project_id is different but the scope is public.
|
||||||
|
|
||||||
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
|
:param limit: Optional. Maximum number of resources to return in a
|
||||||
|
single result. Default value is None for backward
|
||||||
|
compatibility.
|
||||||
|
:param sort_keys: Optional. Columns to sort results by.
|
||||||
|
Default: created_at, which is backward compatible.
|
||||||
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
|
sort_keys, "asc" or "desc" can be chosen.
|
||||||
|
Default: desc. The length of sort_dirs can be equal
|
||||||
|
or less than that of sort_keys.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
|
||||||
|
"""
|
||||||
|
acl.enforce('tasks:list', context.ctx())
|
||||||
|
LOG.info("Fetch tasks. marker=%s, limit=%s, sort_keys=%s, "
|
||||||
|
"sort_dirs=%s, filters=%s", marker, limit, sort_keys,
|
||||||
|
sort_dirs, filters)
|
||||||
|
|
||||||
|
return _get_task_resources_with_results(
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
|
||||||
@rest_utils.wrap_wsme_controller_exception
|
@rest_utils.wrap_wsme_controller_exception
|
||||||
@wsme_pecan.wsexpose(Task, wtypes.text, body=Task)
|
@wsme_pecan.wsexpose(Task, wtypes.text, body=Task)
|
||||||
@ -190,10 +257,44 @@ class TasksController(rest.RestController):
|
|||||||
|
|
||||||
|
|
||||||
class ExecutionTasksController(rest.RestController):
|
class ExecutionTasksController(rest.RestController):
|
||||||
@wsme_pecan.wsexpose(Tasks, wtypes.text)
|
|
||||||
def get_all(self, workflow_execution_id):
|
|
||||||
"""Return all tasks within the workflow execution."""
|
|
||||||
acl.enforce('tasks:list', context.ctx())
|
|
||||||
LOG.info("Fetch tasks.")
|
|
||||||
|
|
||||||
return _get_task_resources_with_results(workflow_execution_id)
|
@wsme_pecan.wsexpose(Tasks, types.uuid, types.uuid, int, types.uniquelist,
|
||||||
|
types.list, types.uniquelist)
|
||||||
|
def get_all(self, workflow_execution_id, marker=None, limit=None,
|
||||||
|
sort_keys='created_at', sort_dirs='asc', fields='', **filters):
|
||||||
|
"""Return all tasks within the execution.
|
||||||
|
|
||||||
|
Where project_id is the same as the requestor or
|
||||||
|
project_id is different but the scope is public.
|
||||||
|
|
||||||
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
|
:param limit: Optional. Maximum number of resources to return in a
|
||||||
|
single result. Default value is None for backward
|
||||||
|
compatibility.
|
||||||
|
:param sort_keys: Optional. Columns to sort results by.
|
||||||
|
Default: created_at, which is backward compatible.
|
||||||
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
|
sort_keys, "asc" or "desc" can be chosen.
|
||||||
|
Default: desc. The length of sort_dirs can be equal
|
||||||
|
or less than that of sort_keys.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
"""
|
||||||
|
acl.enforce('tasks:list', context.ctx())
|
||||||
|
LOG.info("Fetch tasks. workflow_execution_id=%s, marker=%s, limit=%s, "
|
||||||
|
"sort_keys=%s, sort_dirs=%s, filters=%s",
|
||||||
|
workflow_execution_id, marker, limit, sort_keys, sort_dirs,
|
||||||
|
filters)
|
||||||
|
|
||||||
|
return _get_task_resources_with_results(
|
||||||
|
wf_ex_id=workflow_execution_id,
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
@ -22,6 +22,7 @@ import wsmeext.pecan as wsme_pecan
|
|||||||
|
|
||||||
from mistral.api import access_control as acl
|
from mistral.api import access_control as acl
|
||||||
from mistral.api.controllers import resource
|
from mistral.api.controllers import resource
|
||||||
|
from mistral.api.controllers.v2 import types
|
||||||
from mistral.api.controllers.v2 import validation
|
from mistral.api.controllers.v2 import validation
|
||||||
from mistral.api.hooks import content_type as ct_hook
|
from mistral.api.hooks import content_type as ct_hook
|
||||||
from mistral import context
|
from mistral import context
|
||||||
@ -62,11 +63,16 @@ class Workbook(resource.Resource):
|
|||||||
updated_at='1970-01-01T00:00:00.000000')
|
updated_at='1970-01-01T00:00:00.000000')
|
||||||
|
|
||||||
|
|
||||||
class Workbooks(resource.Resource):
|
class Workbooks(resource.ResourceList):
|
||||||
"""A collection of Workbooks."""
|
"""A collection of Workbooks."""
|
||||||
|
|
||||||
workbooks = [Workbook]
|
workbooks = [Workbook]
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self._type = 'workbooks'
|
||||||
|
|
||||||
|
super(Workbooks, self).__init__(**kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def sample(cls):
|
def sample(cls):
|
||||||
return cls(workbooks=[Workbook.sample()])
|
return cls(workbooks=[Workbook.sample()])
|
||||||
@ -123,17 +129,45 @@ class WorkbooksController(rest.RestController, hooks.HookController):
|
|||||||
|
|
||||||
db_api.delete_workbook(name)
|
db_api.delete_workbook(name)
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(Workbooks)
|
@wsme_pecan.wsexpose(Workbooks, types.uuid, int, types.uniquelist,
|
||||||
def get_all(self):
|
types.list, types.uniquelist, types.jsontype)
|
||||||
"""Return all workbooks.
|
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
||||||
|
sort_dirs='asc', fields='', **filters):
|
||||||
|
"""Return a list of workbooks.
|
||||||
|
|
||||||
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
|
:param limit: Optional. Maximum number of resources to return in a
|
||||||
|
single result. Default value is None for backward
|
||||||
|
compatibility.
|
||||||
|
:param sort_keys: Optional. Columns to sort results by.
|
||||||
|
Default: created_at.
|
||||||
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
|
sort_keys, "asc" or "desc" can be choosed.
|
||||||
|
Default: asc.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
|
||||||
Where project_id is the same as the requestor or
|
Where project_id is the same as the requestor or
|
||||||
project_id is different but the scope is public.
|
project_id is different but the scope is public.
|
||||||
"""
|
"""
|
||||||
acl.enforce('workbooks:list', context.ctx())
|
acl.enforce('workbooks:list', context.ctx())
|
||||||
LOG.info("Fetch workbooks.")
|
LOG.info("Fetch workbooks. marker=%s, limit=%s, sort_keys=%s, "
|
||||||
|
"sort_dirs=%s, fields=%s, filters=%s", marker, limit,
|
||||||
|
sort_keys, sort_dirs, fields, filters)
|
||||||
|
|
||||||
workbooks_list = [Workbook.from_dict(db_model.to_dict())
|
return rest_utils.get_all(
|
||||||
for db_model in db_api.get_workbooks()]
|
Workbooks,
|
||||||
|
Workbook,
|
||||||
return Workbooks(workbooks=workbooks_list)
|
db_api.get_workbooks,
|
||||||
|
db_api.get_workbook,
|
||||||
|
resource_function=None,
|
||||||
|
marker=marker,
|
||||||
|
limit=limit,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
@ -236,9 +236,9 @@ class WorkflowsController(rest.RestController, hooks.HookController):
|
|||||||
|
|
||||||
@rest_utils.wrap_wsme_controller_exception
|
@rest_utils.wrap_wsme_controller_exception
|
||||||
@wsme_pecan.wsexpose(Workflows, types.uuid, int, types.uniquelist,
|
@wsme_pecan.wsexpose(Workflows, types.uuid, int, types.uniquelist,
|
||||||
types.list, types.uniquelist)
|
types.list, types.uniquelist, types.jsontype)
|
||||||
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
||||||
sort_dirs='asc', fields=''):
|
sort_dirs='asc', fields='', **filters):
|
||||||
"""Return a list of workflows.
|
"""Return a list of workflows.
|
||||||
|
|
||||||
:param marker: Optional. Pagination marker for large data sets.
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
@ -254,46 +254,26 @@ class WorkflowsController(rest.RestController, hooks.HookController):
|
|||||||
be returned. 'id' will be included automatically in
|
be returned. 'id' will be included automatically in
|
||||||
fields if it's provided, since it will be used when
|
fields if it's provided, since it will be used when
|
||||||
constructing 'next' link.
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A list of filters to apply to the result.
|
||||||
|
|
||||||
Where project_id is the same as the requester or
|
Where project_id is the same as the requester or
|
||||||
project_id is different but the scope is public.
|
project_id is different but the scope is public.
|
||||||
"""
|
"""
|
||||||
acl.enforce('workflows:list', context.ctx())
|
acl.enforce('workflows:list', context.ctx())
|
||||||
LOG.info("Fetch workflows. marker=%s, limit=%s, sort_keys=%s, "
|
LOG.info("Fetch workflows. marker=%s, limit=%s, sort_keys=%s, "
|
||||||
"sort_dirs=%s, fields=%s", marker, limit, sort_keys,
|
"sort_dirs=%s, fields=%s, filters=%s", marker, limit,
|
||||||
sort_dirs, fields)
|
sort_keys, sort_dirs, fields, filters)
|
||||||
|
|
||||||
if fields and 'id' not in fields:
|
return rest_utils.get_all(
|
||||||
fields.insert(0, 'id')
|
Workflows,
|
||||||
|
Workflow,
|
||||||
rest_utils.validate_query_params(limit, sort_keys, sort_dirs)
|
db_api.get_workflow_definitions,
|
||||||
rest_utils.validate_fields(fields, Workflow.get_fields())
|
db_api.get_workflow_definition_by_id,
|
||||||
|
resource_function=None,
|
||||||
marker_obj = None
|
marker=marker,
|
||||||
|
|
||||||
if marker:
|
|
||||||
marker_obj = db_api.get_workflow_definition_by_id(marker)
|
|
||||||
|
|
||||||
db_workflows = db_api.get_workflow_definitions(
|
|
||||||
limit=limit,
|
limit=limit,
|
||||||
marker=marker_obj,
|
|
||||||
sort_keys=sort_keys,
|
sort_keys=sort_keys,
|
||||||
sort_dirs=sort_dirs,
|
sort_dirs=sort_dirs,
|
||||||
fields=fields
|
fields=fields,
|
||||||
)
|
**filters
|
||||||
|
|
||||||
workflows_list = []
|
|
||||||
|
|
||||||
for data in db_workflows:
|
|
||||||
workflow_dict = (dict(zip(fields, data)) if fields else
|
|
||||||
data.to_dict())
|
|
||||||
workflows_list.append(Workflow.from_dict(workflow_dict))
|
|
||||||
|
|
||||||
return Workflows.convert_with_links(
|
|
||||||
workflows_list,
|
|
||||||
limit,
|
|
||||||
pecan.request.host_url,
|
|
||||||
sort_keys=','.join(sort_keys),
|
|
||||||
sort_dirs=','.join(sort_dirs),
|
|
||||||
fields=','.join(fields) if fields else ''
|
|
||||||
)
|
)
|
||||||
|
@ -76,8 +76,16 @@ def load_workbook(name):
|
|||||||
return IMPL.load_workbook(name)
|
return IMPL.load_workbook(name)
|
||||||
|
|
||||||
|
|
||||||
def get_workbooks():
|
def get_workbooks(limit=None, marker=None, sort_keys=None,
|
||||||
return IMPL.get_workbooks()
|
sort_dirs=None, fields=None, **kwargs):
|
||||||
|
return IMPL.get_workbooks(
|
||||||
|
limit=limit,
|
||||||
|
marker=marker,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_workbook(values):
|
def create_workbook(values):
|
||||||
@ -328,8 +336,15 @@ def load_task_execution(name):
|
|||||||
return IMPL.load_task_execution(name)
|
return IMPL.load_task_execution(name)
|
||||||
|
|
||||||
|
|
||||||
def get_task_executions(**kwargs):
|
def get_task_executions(limit=None, marker=None, sort_keys=['created_at'],
|
||||||
return IMPL.get_task_executions(**kwargs)
|
sort_dirs=None, **kwargs):
|
||||||
|
return IMPL.get_task_executions(
|
||||||
|
limit=limit,
|
||||||
|
marker=marker,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_task_execution(values):
|
def create_task_execution(values):
|
||||||
@ -428,8 +443,16 @@ def load_environment(name):
|
|||||||
return IMPL.load_environment(name)
|
return IMPL.load_environment(name)
|
||||||
|
|
||||||
|
|
||||||
def get_environments():
|
def get_environments(limit=None, marker=None, sort_keys=['name'],
|
||||||
return IMPL.get_environments()
|
sort_dirs=None, **kwargs):
|
||||||
|
|
||||||
|
return IMPL.get_environments(
|
||||||
|
limit=limit,
|
||||||
|
marker=marker,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_environment(values):
|
def create_environment(values):
|
||||||
|
@ -153,20 +153,56 @@ def _delete_all(model, session=None, **kwargs):
|
|||||||
_secure_query(model).filter_by(**kwargs).delete(synchronize_session=False)
|
_secure_query(model).filter_by(**kwargs).delete(synchronize_session=False)
|
||||||
|
|
||||||
|
|
||||||
def _get_collection_sorted_by_name(model, **kwargs):
|
def _get_collection(model, limit=None, marker=None, sort_keys=None,
|
||||||
|
sort_dirs=None, fields=None, query=None, **kwargs):
|
||||||
|
columns = (
|
||||||
|
tuple([getattr(model, f) for f in fields if hasattr(model, f)])
|
||||||
|
if fields else ()
|
||||||
|
)
|
||||||
|
|
||||||
|
if query is None:
|
||||||
|
query = _secure_query(model, *columns).filter_by(**kwargs)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return _paginate_query(
|
||||||
|
model,
|
||||||
|
limit,
|
||||||
|
marker,
|
||||||
|
sort_keys,
|
||||||
|
sort_dirs,
|
||||||
|
query
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
raise exc.DBQueryEntryException(
|
||||||
|
"Failed when querying database, error type: %s, "
|
||||||
|
"error message: %s" % (e.__class__.__name__, e.message)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_collection_sorted_by_name(model, fields=None, sort_keys=['name'],
|
||||||
|
**kwargs):
|
||||||
# Note(lane): Sometimes tenant_A needs to get resources of tenant_B,
|
# Note(lane): Sometimes tenant_A needs to get resources of tenant_B,
|
||||||
# especially in resource sharing scenario, the resource owner needs to
|
# especially in resource sharing scenario, the resource owner needs to
|
||||||
# check if the resource is used by a member.
|
# check if the resource is used by a member.
|
||||||
query = (b.model_query(model) if 'project_id' in kwargs
|
columns = (
|
||||||
else _secure_query(model))
|
tuple([getattr(model, f) for f in fields if hasattr(model, f)])
|
||||||
|
if fields else ()
|
||||||
|
)
|
||||||
|
|
||||||
return query.filter_by(**kwargs).order_by(model.name).all()
|
query = (b.model_query(model, *columns) if 'project_id' in kwargs
|
||||||
|
else _secure_query(model, *columns))
|
||||||
|
|
||||||
|
return _get_collection(
|
||||||
|
model=model,
|
||||||
|
query=query,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
fields=fields,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _get_collection_sorted_by_time(model, **kwargs):
|
def _get_collection_sorted_by_time(model, sort_keys=['created_at'], **kwargs):
|
||||||
query = _secure_query(model)
|
return _get_collection(model, sort_keys=sort_keys, **kwargs)
|
||||||
|
|
||||||
return query.filter_by(**kwargs).order_by(model.created_at).all()
|
|
||||||
|
|
||||||
|
|
||||||
def _get_db_object_by_name(model, name):
|
def _get_db_object_by_name(model, name):
|
||||||
@ -259,19 +295,6 @@ def delete_workbooks(**kwargs):
|
|||||||
|
|
||||||
# Workflow definitions.
|
# Workflow definitions.
|
||||||
|
|
||||||
|
|
||||||
WORKFLOW_COL_MAPPING = {
|
|
||||||
'id': models.WorkflowDefinition.id,
|
|
||||||
'name': models.WorkflowDefinition.name,
|
|
||||||
'input': models.WorkflowDefinition.spec,
|
|
||||||
'definition': models.WorkflowDefinition.definition,
|
|
||||||
'tags': models.WorkflowDefinition.tags,
|
|
||||||
'scope': models.WorkflowDefinition.scope,
|
|
||||||
'created_at': models.WorkflowDefinition.created_at,
|
|
||||||
'updated_at': models.WorkflowDefinition.updated_at
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def get_workflow_definition(identifier):
|
def get_workflow_definition(identifier):
|
||||||
"""Gets workflow definition by name or uuid.
|
"""Gets workflow definition by name or uuid.
|
||||||
|
|
||||||
@ -306,29 +329,18 @@ def load_workflow_definition(name):
|
|||||||
return _get_workflow_definition(name)
|
return _get_workflow_definition(name)
|
||||||
|
|
||||||
|
|
||||||
def get_workflow_definitions(limit=None, marker=None, sort_keys=None,
|
def get_workflow_definitions(sort_keys=['created_at'], fields=None, **kwargs):
|
||||||
sort_dirs=None, fields=None, **kwargs):
|
if fields and 'input' in fields:
|
||||||
columns = (
|
fields.remove('input')
|
||||||
tuple(WORKFLOW_COL_MAPPING.get(f) for f in fields) if fields else ()
|
fields.append('spec')
|
||||||
|
|
||||||
|
return _get_collection(
|
||||||
|
model=models.WorkflowDefinition,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
fields=fields,
|
||||||
|
**kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
query = _secure_query(models.WorkflowDefinition, *columns)
|
|
||||||
|
|
||||||
try:
|
|
||||||
return _paginate_query(
|
|
||||||
models.WorkflowDefinition,
|
|
||||||
limit,
|
|
||||||
marker,
|
|
||||||
sort_keys,
|
|
||||||
sort_dirs,
|
|
||||||
query
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
raise exc.DBQueryEntryError(
|
|
||||||
"Failed when querying database, error type: %s, "
|
|
||||||
"error message: %s" % (e.__class__.__name__, e.message)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@b.session_aware()
|
@b.session_aware()
|
||||||
def create_workflow_definition(values, session=None):
|
def create_workflow_definition(values, session=None):
|
||||||
@ -471,24 +483,12 @@ def load_action_definition(name):
|
|||||||
return _get_action_definition(name)
|
return _get_action_definition(name)
|
||||||
|
|
||||||
|
|
||||||
def get_action_definitions(limit=None, marker=None, sort_keys=['name'],
|
def get_action_definitions(sort_keys=['name'], **kwargs):
|
||||||
sort_dirs=None, **kwargs):
|
return _get_collection(
|
||||||
query = _secure_query(models.ActionDefinition).filter_by(**kwargs)
|
model=models.ActionDefinition,
|
||||||
|
sort_keys=sort_keys,
|
||||||
try:
|
**kwargs
|
||||||
return _paginate_query(
|
)
|
||||||
models.ActionDefinition,
|
|
||||||
limit,
|
|
||||||
marker,
|
|
||||||
sort_keys,
|
|
||||||
sort_dirs,
|
|
||||||
query
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
raise exc.DBQueryEntryError(
|
|
||||||
"Failed when querying database, error type: %s, "
|
|
||||||
"error message: %s" % (e.__class__.__name__, e.message)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@b.session_aware()
|
@b.session_aware()
|
||||||
@ -747,24 +747,12 @@ def ensure_workflow_execution_exists(id):
|
|||||||
get_workflow_execution(id)
|
get_workflow_execution(id)
|
||||||
|
|
||||||
|
|
||||||
def get_workflow_executions(limit=None, marker=None, sort_keys=['created_at'],
|
def get_workflow_executions(sort_keys=['created_at'], **kwargs):
|
||||||
sort_dirs=None, **kwargs):
|
return _get_collection(
|
||||||
query = _secure_query(models.WorkflowExecution).filter_by(**kwargs)
|
models.WorkflowExecution,
|
||||||
|
sort_keys=sort_keys,
|
||||||
try:
|
**kwargs
|
||||||
return _paginate_query(
|
)
|
||||||
models.WorkflowExecution,
|
|
||||||
limit,
|
|
||||||
marker,
|
|
||||||
sort_keys,
|
|
||||||
sort_dirs,
|
|
||||||
query
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
raise exc.DBQueryEntryError(
|
|
||||||
"Failed when quering database, error type: %s, "
|
|
||||||
"error message: %s" % (e.__class__.__name__, e.message)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@b.session_aware()
|
@b.session_aware()
|
||||||
@ -1144,10 +1132,15 @@ def _get_cron_trigger(name):
|
|||||||
return _get_db_object_by_name(models.CronTrigger, name)
|
return _get_db_object_by_name(models.CronTrigger, name)
|
||||||
|
|
||||||
|
|
||||||
def _get_cron_triggers(**kwargs):
|
def _get_cron_triggers(*columns, **kwargs):
|
||||||
query = b.model_query(models.CronTrigger)
|
query = b.model_query(models.CronTrigger)
|
||||||
|
|
||||||
return query.filter_by(**kwargs).all()
|
return _get_collection(
|
||||||
|
models.CronTrigger,
|
||||||
|
query=query,
|
||||||
|
*columns,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Environments.
|
# Environments.
|
||||||
|
@ -185,10 +185,10 @@ class TestActionExecutionsController(base.APITest):
|
|||||||
|
|
||||||
self.assertEqual(201, resp.status_int)
|
self.assertEqual(201, resp.status_int)
|
||||||
|
|
||||||
action_exec = ACTION_EX
|
action_exec = copy.deepcopy(ACTION_EX)
|
||||||
del action_exec['task_name']
|
del action_exec['task_name']
|
||||||
|
|
||||||
self.assertDictEqual(ACTION_EX, resp.json)
|
self.assertDictEqual(action_exec, resp.json)
|
||||||
|
|
||||||
f.assert_called_once_with(
|
f.assert_called_once_with(
|
||||||
ACTION_EX['name'],
|
ACTION_EX['name'],
|
||||||
@ -212,10 +212,10 @@ class TestActionExecutionsController(base.APITest):
|
|||||||
|
|
||||||
self.assertEqual(201, resp.status_int)
|
self.assertEqual(201, resp.status_int)
|
||||||
|
|
||||||
action_exec = ACTION_EX
|
action_exec = copy.deepcopy(ACTION_EX)
|
||||||
del action_exec['task_name']
|
del action_exec['task_name']
|
||||||
|
|
||||||
self.assertDictEqual(ACTION_EX, resp.json)
|
self.assertDictEqual(action_exec, resp.json)
|
||||||
|
|
||||||
f.assert_called_once_with(
|
f.assert_called_once_with(
|
||||||
ACTION_EX['name'],
|
ACTION_EX['name'],
|
||||||
|
@ -19,11 +19,15 @@ import json
|
|||||||
|
|
||||||
import pecan
|
import pecan
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from oslo_log import log as logging
|
||||||
from webob import Response
|
from webob import Response
|
||||||
from wsme import exc as wsme_exc
|
from wsme import exc as wsme_exc
|
||||||
|
|
||||||
from mistral import exceptions as exc
|
from mistral import exceptions as exc
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def wrap_wsme_controller_exception(func):
|
def wrap_wsme_controller_exception(func):
|
||||||
"""Decorator for controllers method.
|
"""Decorator for controllers method.
|
||||||
@ -102,3 +106,95 @@ def validate_fields(fields, object_fields):
|
|||||||
raise wsme_exc.ClientSideError(
|
raise wsme_exc.ClientSideError(
|
||||||
'Field(s) %s are invalid.' % ', '.join(invalid_fields)
|
'Field(s) %s are invalid.' % ', '.join(invalid_fields)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_all(list_cls, cls, get_all_function, get_function,
|
||||||
|
resource_function=None, marker=None, limit=None,
|
||||||
|
sort_keys='created_at', sort_dirs='asc', fields='', **filters):
|
||||||
|
"""Return a list of cls.
|
||||||
|
|
||||||
|
:param list_cls: Collection class (e.g.: Actions, Workflows, ...).
|
||||||
|
:param cls: Class (e.g.: Action, Workflow, ...).
|
||||||
|
:param get_all_function: Request function to get all elements with
|
||||||
|
filtering (limit, marker, sort_keys, sort_dirs,
|
||||||
|
fields)
|
||||||
|
:param get_function: Function used to fetch the marker
|
||||||
|
:param resource_function: Optional, function used to fetch additional data
|
||||||
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
|
:param limit: Optional. Maximum number of resources to return in a
|
||||||
|
single result. Default value is None for backward
|
||||||
|
compatibility.
|
||||||
|
:param sort_keys: Optional. Columns to sort results by.
|
||||||
|
Default: created_at.
|
||||||
|
:param sort_dirs: Optional. Directions to sort corresponding to
|
||||||
|
sort_keys, "asc" or "desc" can be choosed.
|
||||||
|
Default: asc.
|
||||||
|
:param fields: Optional. A specified list of fields of the resource to
|
||||||
|
be returned. 'id' will be included automatically in
|
||||||
|
fields if it's provided, since it will be used when
|
||||||
|
constructing 'next' link.
|
||||||
|
:param filters: Optional. A specified dictionary of filters to match.
|
||||||
|
"""
|
||||||
|
if fields and 'id' not in fields:
|
||||||
|
fields.insert(0, 'id')
|
||||||
|
|
||||||
|
validate_query_params(limit, sort_keys, sort_dirs)
|
||||||
|
validate_fields(fields, cls.get_fields())
|
||||||
|
|
||||||
|
marker_obj = None
|
||||||
|
|
||||||
|
if marker:
|
||||||
|
marker_obj = get_function(marker)
|
||||||
|
|
||||||
|
list_to_return = []
|
||||||
|
if resource_function:
|
||||||
|
# do not filter fields yet, resource_function needs the ORM object
|
||||||
|
db_list = get_all_function(
|
||||||
|
limit=limit,
|
||||||
|
marker=marker_obj,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
|
||||||
|
for data in db_list:
|
||||||
|
obj = resource_function(data)
|
||||||
|
|
||||||
|
# filter fields using a loop instead of the ORM
|
||||||
|
if fields:
|
||||||
|
data = []
|
||||||
|
for f in fields:
|
||||||
|
if hasattr(obj, f):
|
||||||
|
data.append(getattr(obj, f))
|
||||||
|
|
||||||
|
dict_data = dict(zip(fields, data))
|
||||||
|
else:
|
||||||
|
dict_data = obj.to_dict()
|
||||||
|
|
||||||
|
list_to_return.append(cls.from_dict(dict_data))
|
||||||
|
|
||||||
|
else:
|
||||||
|
db_list = get_all_function(
|
||||||
|
limit=limit,
|
||||||
|
marker=marker_obj,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
fields=fields,
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
|
||||||
|
for data in db_list:
|
||||||
|
dict_data = (dict(zip(fields, data)) if fields else
|
||||||
|
data.to_dict())
|
||||||
|
|
||||||
|
list_to_return.append(cls.from_dict(dict_data))
|
||||||
|
|
||||||
|
return list_cls.convert_with_links(
|
||||||
|
list_to_return,
|
||||||
|
limit,
|
||||||
|
pecan.request.host_url,
|
||||||
|
sort_keys=','.join(sort_keys),
|
||||||
|
sort_dirs=','.join(sort_dirs),
|
||||||
|
fields=','.join(fields) if fields else '',
|
||||||
|
**filters
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user