Add CLI for client v2

* Added CLI for workbooks, executions,
   workflows and tasks.
 * v2 commands are set by default

TODO:
  * Unit tests for CLI v2
  * Add ActionManager and Actions CLI

Change-Id: Ie564cd77d816ab7ff939f4bec9fa14ae04130435
This commit is contained in:
Nikolay Mahotkin 2014-08-29 16:11:36 +04:00
parent 413019b6d8
commit 37606f99ac
18 changed files with 896 additions and 70 deletions

View File

@ -22,12 +22,11 @@ class Workbook(base.Resource):
class WorkbookManager(base.ResourceManager):
resource_class = Workbook
def create(self, name, definition=None, description=None, tags=None):
def create(self, name, tags=None, definition=None):
self._ensure_not_empty(name=name)
data = {
'name': name,
'description': description,
'tags': tags,
}
@ -36,12 +35,11 @@ class WorkbookManager(base.ResourceManager):
return self._create('/workbooks', data)
def update(self, name, definition=None, description=None, tags=None):
def update(self, name, tags=None, definition=None):
self._ensure_not_empty(name=name)
data = {
'name': name,
'description': description,
'tags': tags,
}

View File

@ -22,24 +22,22 @@ class Workflow(base.Resource):
class WorkflowManager(base.ResourceManager):
resource_class = Workflow
def create(self, name, definition, description=None, tags=None):
def create(self, name, definition, tags=None):
self._ensure_not_empty(name=name, definition=definition)
data = {
'name': name,
'definition': definition,
'description': description,
'tags': tags,
}
return self._create('/workflows', data)
def update(self, name, definition=None, description=None, tags=None):
def update(self, name, definition=None, tags=None):
self._ensure_not_empty(name=name)
data = {
'name': name,
'description': description,
'tags': tags,
}

View File

View File

View File

@ -0,0 +1,214 @@
# Copyright 2014 - Mirantis, Inc.
# All Rights Reserved
#
# 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 json
import logging
from cliff import command
from cliff import lister
from cliff import show
from mistralclient.api.v2 import executions
LOG = logging.getLogger(__name__)
def format(execution=None):
columns = (
'ID',
'Workflow',
'State',
'Created at',
'Updated at'
)
# TODO(nmakhotkin) Add parent task id when it's implemented in API.
if execution:
data = (
execution.id,
execution.workflow_name,
execution.state,
execution.created_at,
execution.updated_at or '<none>'
)
else:
data = (tuple('<none>' for _ in range(len(columns))),)
return columns, data
class List(lister.Lister):
"""List all executions."""
def take_action(self, parsed_args):
data = [format(execution)[1] for execution
in executions.ExecutionManager(self.app.client).list()]
if data:
return format()[0], data
else:
return format()
class Get(show.ShowOne):
"""Show specific execution."""
def get_parser(self, prog_name):
parser = super(Get, self).get_parser(prog_name)
parser.add_argument(
'id',
help='Execution identifier')
return parser
def take_action(self, parsed_args):
execution = executions.ExecutionManager(self.app.client)\
.get(parsed_args.id)
return format(execution)
class Create(show.ShowOne):
"""Create new execution."""
def get_parser(self, prog_name):
parser = super(Create, self).get_parser(prog_name)
parser.add_argument(
'workflow_name',
help='Execution workflow')
parser.add_argument(
'workflow_input',
nargs='?',
help='Workflow input')
parser.add_argument(
'params',
nargs='?',
help='Workflow additional parameters')
return parser
def take_action(self, parsed_args):
if parsed_args.workflow_input:
try:
wf_input = json.loads(parsed_args.workflow_input)
except:
wf_input = json.load(open(parsed_args.workflow_input))
else:
wf_input = {}
if parsed_args.params:
try:
params = json.loads(parsed_args.params)
except:
params = json.load(open(parsed_args.params))
else:
params = {}
execution = executions.ExecutionManager(self.app.client)\
.create(parsed_args.workflow_name,
wf_input,
**params)
return format(execution)
class Delete(command.Command):
"""Delete execution."""
def get_parser(self, prog_name):
parser = super(Delete, self).get_parser(prog_name)
parser.add_argument(
'id',
help='Execution identifier')
return parser
def take_action(self, parsed_args):
executions.ExecutionManager(self.app.client).delete(parsed_args.id)
class Update(show.ShowOne):
"""Update execution."""
def get_parser(self, prog_name):
parser = super(Update, self).get_parser(prog_name)
parser.add_argument(
'id',
help='Execution identifier')
parser.add_argument(
'state',
choices=['RUNNING', 'SUSPENDED', 'STOPPED', 'SUCCESS', 'ERROR'],
help='Execution state')
return parser
def take_action(self, parsed_args):
execution = executions.ExecutionManager(self.app.client)\
.update(parsed_args.id,
parsed_args.state)
return format(execution)
class GetInput(command.Command):
"""Show execution input data."""
def get_parser(self, prog_name):
parser = super(GetInput, self).get_parser(prog_name)
parser.add_argument(
'id',
help='Execution ID')
return parser
def take_action(self, parsed_args):
ex_input = executions.ExecutionManager(self.app.client)\
.get(parsed_args.id).input
try:
ex_input = json.loads(ex_input)
ex_input = json.dumps(ex_input, indent=4) + "\n"
except:
LOG.debug("Execution input is not JSON.")
self.app.stdout.write(ex_input or "\n")
class GetOutput(command.Command):
"""Show execution output data."""
def get_parser(self, prog_name):
parser = super(GetOutput, self).get_parser(prog_name)
parser.add_argument(
'id',
help='Execution ID')
return parser
def take_action(self, parsed_args):
output = executions.ExecutionManager(self.app.client)\
.get(parsed_args.id).output
try:
output = json.loads(output)
output = json.dumps(output, indent=4) + "\n"
except:
LOG.debug("Execution output is not JSON.")
self.app.stdout.write(output or "\n")

View File

@ -0,0 +1,154 @@
# Copyright 2014 - Mirantis, Inc.
# All Rights Reserved
#
# 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 json
import logging
from cliff import command
from cliff import lister
from cliff import show
from mistralclient.api.v2 import tasks
LOG = logging.getLogger(__name__)
def format(task=None):
columns = (
'ID',
'Name',
'Workflow name',
'Execution ID',
'State',
'Parameters',
)
if task:
data = (
task.id,
task.name,
task.wf_name,
task.execution_id,
task.state,
task.parameters,
)
else:
data = (tuple('<none>' for _ in range(len(columns))),)
return columns, data
class List(lister.Lister):
"""List all tasks."""
def take_action(self, parsed_args):
data = [format(task)[1] for task
in tasks.TaskManager(self.app.client).list()]
if data:
return format()[0], data
else:
return format()
class Get(show.ShowOne):
"""Show specific task."""
def get_parser(self, prog_name):
parser = super(Get, self).get_parser(prog_name)
parser.add_argument(
'id',
help='Task identifier')
return parser
def take_action(self, parsed_args):
execution = tasks.TaskManager(self.app.client)\
.get(parsed_args.id)
return format(execution)
class Update(show.ShowOne):
"""Update task."""
def get_parser(self, prog_name):
parser = super(Update, self).get_parser(prog_name)
parser.add_argument(
'id',
help='Task identifier')
parser.add_argument(
'state',
choices=['IDLE', 'RUNNING', 'SUCCESS', 'ERROR'],
help='Task state')
return parser
def take_action(self, parsed_args):
execution = tasks.TaskManager(self.app.client).update(
parsed_args.id,
parsed_args.state)
return format(execution)
class GetOutput(command.Command):
"""Show task output data."""
def get_parser(self, prog_name):
parser = super(GetOutput, self).get_parser(prog_name)
parser.add_argument(
'id',
help='Task ID')
return parser
def take_action(self, parsed_args):
output = tasks.TaskManager(self.app.client)\
.get(parsed_args.id).output
try:
output = json.loads(output)
output = json.dumps(output, indent=4) + "\n"
except:
LOG.debug("Task output is not JSON.")
self.app.stdout.write(output or "\n")
class GetResult(command.Command):
"""Show task output data."""
def get_parser(self, prog_name):
parser = super(GetResult, self).get_parser(prog_name)
parser.add_argument(
'id',
help='Task ID')
return parser
def take_action(self, parsed_args):
result = tasks.TaskManager(self.app.client)\
.get(parsed_args.id).result
try:
result = json.loads(result)
result = json.dumps(result, indent=4) + "\n"
except:
LOG.debug("Task result is not JSON.")
self.app.stdout.write(result or "\n")

View File

@ -0,0 +1,208 @@
# Copyright 2014 - Mirantis, Inc.
# All Rights Reserved
#
# 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 argparse
import logging
from cliff import command
from cliff import lister
from cliff import show
from mistralclient.api.v2 import workbooks
LOG = logging.getLogger(__name__)
def format(workbook=None):
columns = (
'Name',
'Tags',
'Created at',
'Updated at'
)
if workbook:
data = (
workbook.name,
', '.join(workbook.tags or '') or '<none>',
workbook.created_at,
)
if hasattr(workbook, 'updated_at'):
data += (workbook.updated_at or '<none>',)
else:
data += (None,)
else:
data = (tuple('<none>' for _ in range(len(columns))),)
return columns, data
class List(lister.Lister):
"""List all workbooks."""
def take_action(self, parsed_args):
data = [format(workbook)[1] for workbook
in workbooks.WorkbookManager(self.app.client).list()]
if data:
return format()[0], data
else:
return format()
class Get(show.ShowOne):
"""Show specific workbook."""
def get_parser(self, prog_name):
parser = super(Get, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workbook name')
return parser
def take_action(self, parsed_args):
workbook = workbooks.WorkbookManager(self.app.client).get(
parsed_args.name)
return format(workbook)
class Create(show.ShowOne):
"""Create new workbook."""
def get_parser(self, prog_name):
parser = super(Create, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workbook name')
parser.add_argument(
'tags',
nargs='?',
help='Workbook tags separated by ","')
parser.add_argument(
'definition',
nargs='?',
type=argparse.FileType('r'),
help='Workbook definition file'
)
return parser
def take_action(self, parsed_args):
if parsed_args.definition:
workbook = workbooks.WorkbookManager(self.app.client)\
.create(parsed_args.name,
str(parsed_args.tags).split(','),
parsed_args.definition.read())
else:
workbook = workbooks.WorkbookManager(self.app.client)\
.create(parsed_args.name,
str(parsed_args.tags).split(','), None)
return format(workbook)
class Delete(command.Command):
"""Delete workbook."""
def get_parser(self, prog_name):
parser = super(Delete, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workbook name')
return parser
def take_action(self, parsed_args):
workbooks.WorkbookManager(self.app.client).delete(parsed_args.name)
class Update(show.ShowOne):
"""Update workbook."""
def get_parser(self, prog_name):
parser = super(Update, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workbook name')
parser.add_argument(
'tags',
nargs='?',
help='Workbook tags separated by ","')
parser.add_argument(
'definition',
nargs='?',
type=argparse.FileType('r'),
help='Workbook definition file'
)
return parser
def take_action(self, parsed_args):
if parsed_args.definition:
workbook = workbooks.WorkbookManager(self.app.client)\
.update(parsed_args.name,
str(parsed_args.tags).split(','),
parsed_args.definition.read())
return format(workbook)
else:
workbook = workbooks.WorkbookManager(self.app.client)\
.update(parsed_args.name,
tags=str(parsed_args.tags).split(','))
return format(workbook)
class UploadDefinition(command.Command):
"""Upload workbook definition."""
def get_parser(self, prog_name):
parser = super(UploadDefinition, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workbook name')
parser.add_argument(
'path',
type=argparse.FileType('r'),
help='Workbook definition file')
return parser
def take_action(self, parsed_args):
workbook = workbooks.WorkbookManager(self.app.client)\
.update(parsed_args.name,
definition=parsed_args.path.read())
self.app.stdout.write(workbook.definition or "\n")
class GetDefinition(command.Command):
"""Show workbook definition."""
def get_parser(self, prog_name):
parser = super(GetDefinition, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workbook name')
return parser
def take_action(self, parsed_args):
definition = workbooks.WorkbookManager(self.app.client)\
.get(parsed_args.name).definition
self.app.stdout.write(definition or "\n")

View File

@ -0,0 +1,206 @@
# Copyright 2014 - Mirantis, Inc.
# All Rights Reserved
#
# 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 argparse
import logging
from cliff import command
from cliff import lister
from cliff import show
from mistralclient.api.v2 import workflows
LOG = logging.getLogger(__name__)
def format(workflow=None):
columns = (
'Name',
'Tags',
'Created at',
'Updated at'
)
if workflow:
data = (
workflow.name,
', '.join(workflow.tags or '') or '<none>',
workflow.created_at,
)
if hasattr(workflow, 'updated_at'):
data += (workflow.updated_at,)
else:
data += (None,)
else:
data = (tuple('<none>' for _ in range(len(columns))),)
return columns, data
class List(lister.Lister):
"""List all workflows."""
def take_action(self, parsed_args):
data = [format(workflow)[1] for workflow
in workflows.WorkflowManager(self.app.client).list()]
if data:
return format()[0], data
else:
return format()
class Get(show.ShowOne):
"""Show specific workflow."""
def get_parser(self, prog_name):
parser = super(Get, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workflow name')
return parser
def take_action(self, parsed_args):
workflow = workflows.WorkflowManager(self.app.client).get(
parsed_args.name)
return format(workflow)
class Create(show.ShowOne):
"""Create new workflow."""
def get_parser(self, prog_name):
parser = super(Create, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workflow name')
parser.add_argument(
'tags',
nargs='?',
help='Workflow tags separated by ","')
parser.add_argument(
'definition',
nargs='?',
type=argparse.FileType('r'),
help='Workflow definition file'
)
return parser
def take_action(self, parsed_args):
if not parsed_args.definition:
raise RuntimeError("You must provide path to workflow "
"definition file.")
workflow = workflows.WorkflowManager(self.app.client)\
.create(parsed_args.name,
parsed_args.definition.read(),
str(parsed_args.tags).split(','))
return format(workflow)
class Delete(command.Command):
"""Delete workflow."""
def get_parser(self, prog_name):
parser = super(Delete, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workflow name')
return parser
def take_action(self, parsed_args):
workflows.WorkflowManager(self.app.client).delete(parsed_args.name)
class Update(show.ShowOne):
"""Update workflow."""
def get_parser(self, prog_name):
parser = super(Update, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workflow name')
parser.add_argument(
'tags',
nargs='?',
help='Workflow tags separated by ","')
parser.add_argument(
'definition',
nargs='?',
help='Workflow definition')
return parser
def take_action(self, parsed_args):
if parsed_args.definition:
workflow = workflows.WorkflowManager(self.app.client)\
.update(parsed_args.name,
parsed_args.definition.read(),
str(parsed_args.tags).split(','))
else:
workflow = workflows.WorkflowManager(self.app.client)\
.update(parsed_args.name,
None,
str(parsed_args.tags).split(','))
return format(workflow)
class UploadDefinition(command.Command):
"""Upload workflow definition."""
def get_parser(self, prog_name):
parser = super(UploadDefinition, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workflow name')
parser.add_argument(
'path',
type=argparse.FileType('r'),
help='Workflow definition file')
return parser
def take_action(self, parsed_args):
workflow = workflows.WorkflowManager(self.app.client)\
.update(parsed_args.name,
definition=parsed_args.path.read())
self.app.stdout.write(workflow.definition or "\n")
class GetDefinition(command.Command):
"""Show workflow definition."""
def get_parser(self, prog_name):
parser = super(GetDefinition, self).get_parser(prog_name)
parser.add_argument(
'name',
help='Workflow name')
return parser
def take_action(self, parsed_args):
definition = workflows.WorkflowManager(self.app.client)\
.get(parsed_args.name).definition
self.app.stdout.write(definition or "\n")

View File

@ -25,50 +25,34 @@ from mistralclient.openstack.common.cliutils import env
from mistralclient.api import client
import mistralclient.commands.workbooks
import mistralclient.commands.executions
import mistralclient.commands.tasks
import mistralclient.commands.v1.workbooks
import mistralclient.commands.v1.executions
import mistralclient.commands.v1.tasks
import mistralclient.commands.v2.workbooks
import mistralclient.commands.v2.workflows
import mistralclient.commands.v2.executions
import mistralclient.commands.v2.tasks
from cliff.app import App
from cliff.help import HelpAction
from cliff.commandmanager import CommandManager
from cliff import app
from cliff import help
from cliff import commandmanager
import argparse
LOG = logging.getLogger(__name__)
class MistralShell(App):
class MistralShell(app.App):
def __init__(self):
super(MistralShell, self).__init__(
description=__doc__.strip(),
version='0.1',
command_manager=CommandManager('mistral.cli'),
command_manager=commandmanager.CommandManager('mistral.cli'),
)
self.commands = {
'workbook-list': mistralclient.commands.workbooks.List,
'workbook-get': mistralclient.commands.workbooks.Get,
'workbook-create': mistralclient.commands.workbooks.Create,
'workbook-delete': mistralclient.commands.workbooks.Delete,
'workbook-update': mistralclient.commands.workbooks.Update,
'workbook-upload-definition':
mistralclient.commands.workbooks.UploadDefinition,
'workbook-get-definition':
mistralclient.commands.workbooks.GetDefinition,
'execution-list': mistralclient.commands.executions.List,
'execution-get': mistralclient.commands.executions.Get,
'execution-create': mistralclient.commands.executions.Create,
'execution-delete': mistralclient.commands.executions.Delete,
'execution-update': mistralclient.commands.executions.Update,
'task-list': mistralclient.commands.tasks.List,
'task-get': mistralclient.commands.tasks.Get,
'task-update': mistralclient.commands.tasks.Update,
}
for k, v in self.commands.items():
self.command_manager.add_command(k, v)
# Set v2 commands by default
self._set_shell_commands(self._get_commands_v2())
def configure_logging(self):
super(MistralShell, self).configure_logging()
@ -125,7 +109,7 @@ class MistralShell(App):
)
parser.add_argument(
'-h', '--help',
action=HelpAction,
action=help.HelpAction,
nargs=0,
default=self, # tricky
help="Show this help message and exit.",
@ -140,7 +124,7 @@ class MistralShell(App):
'--os-mistral-url',
action='store',
dest='mistral_url',
default=env('OS_MISTRAL_URL', default='http://localhost:8989/v1'),
default=env('OS_MISTRAL_URL', default='http://localhost:8989/v2'),
help='Mistral API host (Env: OS_MISTRAL_URL)'
)
parser.add_argument(
@ -188,6 +172,10 @@ class MistralShell(App):
return parser
def initialize_app(self, argv):
self._clear_shell_commands()
self._set_shell_commands(self._get_commands(
client.determine_client_version(self.options.mistral_url)))
self.client = client.client(mistral_url=self.options.mistral_url,
username=self.options.username,
api_key=self.options.password,
@ -198,6 +186,81 @@ class MistralShell(App):
service_type='workflow',
auth_token=self.options.token)
def _set_shell_commands(self, cmds_dict):
for k, v in cmds_dict.items():
self.command_manager.add_command(k, v)
def _clear_shell_commands(self):
exclude_cmds = ['help', 'complete']
cmds = self.command_manager.commands.copy()
for k, v in cmds.items():
if k not in exclude_cmds:
self.command_manager.commands.pop(k)
def _get_commands(self, version):
if version == 1:
return self._get_commands_v1()
else:
return self._get_commands_v2()
def _get_commands_v1(self):
return {
'workbook-list': mistralclient.commands.v1.workbooks.List,
'workbook-get': mistralclient.commands.v1.workbooks.Get,
'workbook-create': mistralclient.commands.v1.workbooks.Create,
'workbook-delete': mistralclient.commands.v1.workbooks.Delete,
'workbook-update': mistralclient.commands.v1.workbooks.Update,
'workbook-upload-definition':
mistralclient.commands.v1.workbooks.UploadDefinition,
'workbook-get-definition':
mistralclient.commands.v1.workbooks.GetDefinition,
'execution-list': mistralclient.commands.v1.executions.List,
'execution-get': mistralclient.commands.v1.executions.Get,
'execution-create': mistralclient.commands.v1.executions.Create,
'execution-delete': mistralclient.commands.v1.executions.Delete,
'execution-update': mistralclient.commands.v1.executions.Update,
'task-list': mistralclient.commands.v1.tasks.List,
'task-get': mistralclient.commands.v1.tasks.Get,
'task-update': mistralclient.commands.v1.tasks.Update,
}
def _get_commands_v2(self):
return {
'workbook-list': mistralclient.commands.v2.workbooks.List,
'workbook-get': mistralclient.commands.v2.workbooks.Get,
'workbook-create': mistralclient.commands.v2.workbooks.Create,
'workbook-delete': mistralclient.commands.v2.workbooks.Delete,
'workbook-update': mistralclient.commands.v2.workbooks.Update,
'workbook-upload-definition':
mistralclient.commands.v2.workbooks.UploadDefinition,
'workbook-get-definition':
mistralclient.commands.v2.workbooks.GetDefinition,
'execution-list': mistralclient.commands.v2.executions.List,
'execution-get': mistralclient.commands.v2.executions.Get,
'execution-get-input':
mistralclient.commands.v2.executions.GetInput,
'execution-get-output':
mistralclient.commands.v2.executions.GetOutput,
'execution-create': mistralclient.commands.v2.executions.Create,
'execution-delete': mistralclient.commands.v2.executions.Delete,
'execution-update': mistralclient.commands.v2.executions.Update,
'task-list': mistralclient.commands.v2.tasks.List,
'task-get': mistralclient.commands.v2.tasks.Get,
'task-get-output': mistralclient.commands.v2.tasks.GetOutput,
'task-get-result': mistralclient.commands.v2.tasks.GetResult,
'task-update': mistralclient.commands.v2.tasks.Update,
'workflow-list': mistralclient.commands.v2.workflows.List,
'workflow-get': mistralclient.commands.v2.workflows.Get,
'workflow-create': mistralclient.commands.v2.workflows.Create,
'workflow-delete': mistralclient.commands.v2.workflows.Delete,
'workflow-update': mistralclient.commands.v2.workflows.Update,
'workflow-upload-definition':
mistralclient.commands.v2.workflows.UploadDefinition,
'workflow-get-definition':
mistralclient.commands.v2.workflows.GetDefinition
}
def main(argv=sys.argv[1:]):
return MistralShell().run(argv)

View File

@ -18,13 +18,18 @@ from tempest import cli
from tempest import exceptions
MISTRAL_URL = "http://localhost:8989/v1"
class MistralCLIAuth(cli.ClientTestBase):
def mistral(self, action, flags='', params='', admin=True, fail_ok=False,
keystone_version=3):
"""Executes Mistral command."""
mistral_url_op = "--os-mistral-url %s" % MISTRAL_URL
return self.cmd_with_auth(
'mistral', action, flags, params, admin, fail_ok, keystone_version)
'mistral %s' % mistral_url_op, action, flags, params, admin,
fail_ok, keystone_version)
class SimpleMistralCLITests(MistralCLIAuth):
@ -34,24 +39,6 @@ class SimpleMistralCLITests(MistralCLIAuth):
def setUpClass(cls):
super(SimpleMistralCLITests, cls).setUpClass()
def test_command_help(self):
mistral_help = self.mistral('--help')
self.assertIn('Command-line interface to the Mistral APIs',
mistral_help)
self.assertIn('Commands:', mistral_help)
expected_commands = ('complete', 'execution-create',
'execution-delete', 'execution-get',
'execution-list', 'execution-update',
'help', 'task-get', 'task-list',
'task-update', 'workbook-create',
'workbook-delete', 'workbook-get',
'workbook-get-definition', 'workbook-list',
'workbook-update', 'workbook-upload-definition')
for command in expected_commands:
self.assertIn(command, mistral_help)
def test_workbooks_list(self):
workbooks = self.parser.listing(self.mistral('workbook-list'))
self.assertTableStruct(workbooks,

View File

@ -13,7 +13,8 @@ class ClientAuth(rest_client.RestClient):
super(ClientAuth, self).__init__(auth_provider)
self.mistral_client = mclient.Client(
auth_token=self.auth_provider.get_token())
auth_token=self.auth_provider.get_token(),
mistral_url="http://localhost:8989/v1")
class MistralBase(testtools.TestCase):

View File

@ -19,7 +19,7 @@ import pkg_resources as pkg
import mock
from mistralclient.tests.unit import base
from mistralclient.commands import executions
from mistralclient.commands.v1 import executions
from mistralclient.api.v1.executions import Execution
EXECUTION = Execution(mock, {

View File

@ -18,7 +18,7 @@ import mock
from mistralclient.tests.unit import base
from mistralclient.commands import tasks
from mistralclient.commands.v1 import tasks
from mistralclient.api.v1.tasks import Task
TASK = Task(mock, {

View File

@ -18,7 +18,7 @@ import mock
from mistralclient.tests.unit import base
from mistralclient.commands import workbooks
from mistralclient.commands.v1 import workbooks
from mistralclient.api.v1.workbooks import Workbook
WORKBOOK = Workbook(mock, {

View File

@ -45,7 +45,6 @@ Workflows:
WORKBOOK = {
'name': "my_workbook",
'description': "My cool Mistral workbook",
'tags': ['deployment', 'demo'],
'definition': WB_DEF
}
@ -61,9 +60,8 @@ class TestWorkbooksV2(base.BaseClientV2Test):
mock = self.mock_http_post(content=WORKBOOK)
wb = self.workbooks.create(WORKBOOK['name'],
WORKBOOK['definition'],
WORKBOOK['description'],
WORKBOOK['tags'])
WORKBOOK['tags'],
WORKBOOK['definition'])
self.assertIsNotNone(wb)
self.assertEqual(workbooks.Workbook(self.workbooks,
@ -74,9 +72,8 @@ class TestWorkbooksV2(base.BaseClientV2Test):
mock = self.mock_http_put(content=WORKBOOK)
wb = self.workbooks.update(WORKBOOK['name'],
WORKBOOK['definition'],
description=WORKBOOK['description'],
tags=WORKBOOK['tags'])
WORKBOOK['tags'],
WORKBOOK['definition'])
self.assertIsNotNone(wb)
self.assertEqual(workbooks.Workbook(self.workbooks,