mistral-dashboard/mistraldashboard/api.py

456 lines
12 KiB
Python

# Copyright 2014 - StackStorm, Inc.
#
# 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 itertools
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from horizon.utils import functions as utils
from horizon.utils import memoized
from mistralclient.api import client as mistral_client
from mistraldashboard.handle_errors import handle_errors
from openstack_dashboard.api import base
SERVICE_TYPE = 'workflowv2'
@memoized.memoized
def mistralclient(request):
return mistral_client.client(
username=request.user.username,
auth_token=request.user.token.id,
project_id=request.user.tenant_id,
# We can't use auth_url param in here if we config
# and use keystone federation
mistral_url=base.url_for(request, 'workflowv2'),
# Todo: add SECONDARY_ENDPOINT_TYPE support
endpoint_type=getattr(
settings,
'OPENSTACK_ENDPOINT_TYPE',
'internalURL'
),
service_type=SERVICE_TYPE,
# We should not treat definition as file path or uri otherwise
# we allow access to contents in internal servers
enforce_raw_definition=False
)
@handle_errors(_("Unable to retrieve list"), [])
def pagination_list(entity, request, marker='', sort_keys='', sort_dirs='asc',
paginate=False, reversed_order=False, selector=None):
"""Retrieve a listing of specific entity and handles pagination.
:param entity: Requested entity (String)
:param request: Request data
:param marker: Pagination marker for large data sets: entity id
:param sort_keys: Columns to sort results by
:param sort_dirs: Sorting Directions (asc/desc). Default:asc
:param paginate: If true will perform pagination based on settings.
Default:False
:param reversed_order: flag to reverse list. Default:False
:param selector: additional selector to allow further server filtering
"""
limit = getattr(settings, 'API_RESULT_LIMIT', 1000)
page_size = utils.get_page_size(request)
if paginate:
request_size = page_size + 1
else:
request_size = limit
if reversed_order:
sort_dirs = 'desc' if sort_dirs == 'asc' else 'asc'
api = mistralclient(request)
entities_iter = (
getattr(api, entity).list(
selector,
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs
) if selector else (
getattr(api, entity).list(
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs
)
)
)
has_prev_data = has_more_data = False
if paginate:
entities = list(itertools.islice(entities_iter, request_size))
# first and middle page condition
if len(entities) > page_size:
entities.pop(-1)
has_more_data = True
# middle page condition
if marker is not None:
has_prev_data = True
# first page condition when reached via prev back
elif reversed_order and marker is not None:
has_more_data = True
# last page condition
elif marker is not None:
has_prev_data = True
# restore the original ordering here
if reversed_order:
entities = sorted(entities,
key=lambda ent:
(getattr(ent, sort_keys) or '').lower(),
reverse=(sort_dirs == 'desc')
)
else:
entities = list(entities_iter)
return entities, has_more_data, has_prev_data
def execution_create(request, **data):
"""Creates new execution."""
return mistralclient(request).executions.create(**data)
def execution_get(request, execution_id):
"""Get specific execution.
:param execution_id: Execution ID
"""
return mistralclient(request).executions.get(execution_id)
def execution_update(request, execution_id, field, value):
"""update specific execution field, either state or description.
:param request: Request data
:param execution_id: Execution ID
:param field: flag - either Execution state or description
:param value: new update value
"""
if field == "state":
return mistralclient(request).\
executions.update(execution_id, value)
elif field == "description":
return mistralclient(request).\
executions.update(execution_id, None, value)
def execution_delete(request, execution_name):
"""Delete execution.
:param execution_name: Execution name
"""
return mistralclient(request).executions.delete(execution_name)
@handle_errors(_("Unable to retrieve tasks."), [])
def task_list(request, execution_id=None):
"""Returns all tasks.
:param execution_id: Workflow execution ID associated with list of tasks
"""
return mistralclient(request).tasks.list(execution_id)
def task_get(request, task_id=None):
"""Get specific task.
:param task_id: Task ID
"""
return mistralclient(request).tasks.get(task_id)
@handle_errors(_("Unable to retrieve workflows"), [])
def workflow_list(request):
"""Returns all workflows."""
return mistralclient(request).workflows.list()
def workflow_get(request, workflow_name):
"""Get specific workflow.
:param workflow_name: Workflow name
"""
return mistralclient(request).workflows.get(workflow_name)
def workflow_create(request, workflows_definition):
"""Create workflow.
:param workflows_definition: Workflows definition
"""
return mistralclient(request).workflows.create(workflows_definition)
def workflow_validate(request, workflow_definition):
"""Validate workflow.
:param workflow_definition: Workflow definition
"""
return mistralclient(request).workflows.validate(workflow_definition)
def workflow_delete(request, workflow_name):
"""Delete workflow.
:param workflow_name: Workflow name
"""
return mistralclient(request).workflows.delete(workflow_name)
def workflow_update(request, workflows_definition):
"""Update workflow.
:param workflows_definition: Workflows definition
"""
return mistralclient(request).workflows.update(workflows_definition)
@handle_errors(_("Unable to retrieve workbooks."), [])
def workbook_list(request):
"""Returns all workbooks."""
return mistralclient(request).workbooks.list()
def workbook_get(request, workbook_name):
"""Get specific workbook.
:param workbook_name: Workbook name
"""
return mistralclient(request).workbooks.get(workbook_name)
def workbook_create(request, workbook_definition):
"""Create workbook.
:param workbook_definition: Workbook definition
"""
return mistralclient(request).workbooks.create(workbook_definition)
def workbook_validate(request, workbook_definition):
"""Validate workbook.
:param workbook_definition: Workbook definition
"""
return mistralclient(request).workbooks.validate(workbook_definition)
def workbook_delete(request, workbook_name):
"""Delete workbook.
:param workbook_name: Workbook name
"""
return mistralclient(request).workbooks.delete(workbook_name)
def workbook_update(request, workbook_definition):
"""Update workbook.
:param workbook_definition: Workbook definition
"""
return mistralclient(request).workbooks.update(workbook_definition)
@handle_errors(_("Unable to retrieve actions."), [])
def action_list(request):
"""Returns all actions."""
return mistralclient(request).actions.list()
def action_get(request, action_name):
"""Get specific action.
:param action_name: Action name
"""
return mistralclient(request).actions.get(action_name)
def action_create(request, action_definition):
"""Create action.
:param action_definition: Action definition
"""
return mistralclient(request).actions.create(action_definition)
def action_update(request, action_definition):
"""Update action.
:param action_definition: Action definition
"""
return mistralclient(request).actions.update(action_definition)
def action_run(request, action_name, input, params):
"""Run specific action execution.
:param action_name: Action name
:param input: input
:param params: params
"""
return mistralclient(request).action_executions.create(
action_name,
input,
**params
)
def action_delete(request, action_name):
"""Delete action.
:param action_name: Action name
"""
return mistralclient(request).actions.delete(action_name)
@handle_errors(_("Unable to retrieve action executions list"), [])
def action_executions_list(request, task_execution_id=None):
"""Returns all actions executions.
:param request: Request data
:param task_execution_id: (Optional) Task Execution ID to filter by
"""
return mistralclient(request).action_executions.list(task_execution_id)
@handle_errors(_("Unable to retrieve action execution"), [])
def action_execution_get(request, action_execution_id):
"""Get specific action execution.
:param action_execution_id: Action Execution ID
"""
return mistralclient(request).action_executions.get(action_execution_id)
@handle_errors(_("Unable to delete action execution/s"), [])
def action_execution_delete(request, action_execution_id):
"""Delete action execution.
:param action_execution_id: Action execution ID
"""
return mistralclient(request).action_executions.delete(action_execution_id)
def action_execution_update(request, id, state=None, output=None):
"""Update action execution output and or state.
:param id: action execution id
:param output: action execution output
:param state: action execution state
"""
return mistralclient(request).action_executions.update(id, state, output)
@handle_errors(_("Unable to retrieve cron trigger list"), [])
def cron_trigger_list(request):
"""Returns all cron triggers.
:param request: Request data
"""
return mistralclient(request).cron_triggers.list()
@handle_errors(_("Unable to retrieve cron trigger"), [])
def cron_trigger_get(request, cron_trigger_name):
"""Get specific cron trigger.
:param request: Request data
:param cron_trigger_name: Cron trigger name
"""
return mistralclient(request).cron_triggers.get(cron_trigger_name)
@handle_errors(_("Unable to delete cron trigger/s"), [])
def cron_trigger_delete(request, cron_trigger_name):
"""Delete Cron Trigger.
:param request: Request data
:param cron_trigger_name: Cron Trigger name
"""
return mistralclient(request).cron_triggers.delete(cron_trigger_name)
def cron_trigger_create(
request,
cron_trigger_name,
workflow_ID,
workflow_input,
workflow_params,
pattern,
first_time,
count
):
"""Create Cron Trigger.
:param request: Request data
:param cron_trigger_name: Cron Trigger name
:param workflow_ID: Workflow ID
:param workflow_input: Workflow input
:param workflow_params: Workflow params <* * * * *>
:param pattern: <* * * * *>
:param first_time:
Date and time of the first execution <YYYY-MM-DD HH:MM>
:param count: Number of wanted executions <integer>
"""
return mistralclient(request).cron_triggers.create(
cron_trigger_name,
workflow_ID,
workflow_input,
workflow_params,
pattern,
first_time,
count
)