diff --git a/mistralclient/api/base.py b/mistralclient/api/base.py index d33b6c7c..231a9676 100644 --- a/mistralclient/api/base.py +++ b/mistralclient/api/base.py @@ -107,12 +107,12 @@ class ResourceManager(object): def _list(self, url, response_key=None): resp = self.client.http_client.get(url) - if resp.status_code == 200: - return [self.resource_class(self, resource_data) - for resource_data in extract_json(resp, response_key)] - else: + if resp.status_code != 200: self._raise_api_exception(resp) + return [self.resource_class(self, resource_data) + for resource_data in extract_json(resp, response_key)] + def _get(self, url, response_key=None): resp = self.client.http_client.get(url) diff --git a/mistralclient/api/v2/workflows.py b/mistralclient/api/v2/workflows.py index 3d2bdff1..6ec89773 100644 --- a/mistralclient/api/v2/workflows.py +++ b/mistralclient/api/v2/workflows.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json + from mistralclient.api import base @@ -22,29 +24,33 @@ class Workflow(base.Resource): class WorkflowManager(base.ResourceManager): resource_class = Workflow - def create(self, name, definition, tags=None): - self._ensure_not_empty(name=name, definition=definition) + def create(self, definition): + self._ensure_not_empty(definition=definition) - data = { - 'name': name, - 'definition': definition, - 'tags': tags, - } + resp = self.client.http_client.post( + '/workflows', + json.dumps({'definition': definition}) + ) - return self._create('/workflows', data) + if resp.status_code != 201: + self._raise_api_exception(resp) - def update(self, name, definition=None, tags=None): - self._ensure_not_empty(name=name) + return [self.resource_class(self, resource_data) + for resource_data in base.extract_json(resp, 'workflows')] - data = { - 'name': name, - 'tags': tags, - } + def update(self, definition): + self._ensure_not_empty(definition=definition) - if definition: - data.update({'definition': definition}) + resp = self.client.http_client.put( + '/workflows', + json.dumps({'definition': definition}) + ) - return self._update('/workflows/%s' % name, data) + if resp.status_code != 200: + self._raise_api_exception(resp) + + return [self.resource_class(self, resource_data) + for resource_data in base.extract_json(resp, 'workflows')] def list(self): return self._list('/workflows', response_key='workflows') diff --git a/mistralclient/commands/v2/workflows.py b/mistralclient/commands/v2/workflows.py index 6514fdd1..ffd498db 100644 --- a/mistralclient/commands/v2/workflows.py +++ b/mistralclient/commands/v2/workflows.py @@ -35,10 +35,12 @@ def format(workflow=None): ) if workflow: + tags = getattr(workflow, 'tags', None) or [] + data = ( workflow.name, - ', '.join(workflow.tags or '') or '', - workflow.created_at, + ', '.join(tags) or '', + workflow.created_at ) if hasattr(workflow, 'updated_at'): @@ -55,10 +57,9 @@ 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() - ] + wf_list = workflows.WorkflowManager(self.app.client).list() + + data = [format(wf)[1] for wf in wf_list] if data: return format()[0], data @@ -77,27 +78,19 @@ class Get(show.ShowOne): return parser def take_action(self, parsed_args): - workflow = workflows.WorkflowManager(self.app.client).get( - parsed_args.name) + wf = workflows.WorkflowManager(self.app.client).get(parsed_args.name) - return format(workflow) + return format(wf) -class Create(show.ShowOne): +class Create(lister.Lister): """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' ) @@ -109,12 +102,15 @@ class Create(show.ShowOne): 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(',')) + wf_list = workflows.WorkflowManager(self.app.client)\ + .create(parsed_args.definition.read()) - return format(workflow) + data = [format(wf)[1] for wf in wf_list] + + if data: + return format()[0], data + else: + return format() class Delete(command.Command): @@ -131,62 +127,30 @@ class Delete(command.Command): workflows.WorkflowManager(self.app.client).delete(parsed_args.name) -class Update(show.ShowOne): +class Update(lister.Lister): """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='?', + type=argparse.FileType('r'), 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, - open(parsed_args.definition).read(), - str(parsed_args.tags).split(',')) + wf_list = workflows.WorkflowManager(self.app.client)\ + .update(parsed_args.definition.read()) + + data = [format(wf)[1] for wf in wf_list] + + if data: + return format()[0], data 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") + return format() class GetDefinition(command.Command): diff --git a/mistralclient/shell.py b/mistralclient/shell.py index 9c4816b2..86b4b285 100644 --- a/mistralclient/shell.py +++ b/mistralclient/shell.py @@ -268,8 +268,6 @@ class MistralShell(app.App): '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 } diff --git a/mistralclient/tests/unit/v2/test_cli_workflows.py b/mistralclient/tests/unit/v2/test_cli_workflows.py index f89faf2e..b8ed9703 100644 --- a/mistralclient/tests/unit/v2/test_cli_workflows.py +++ b/mistralclient/tests/unit/v2/test_cli_workflows.py @@ -30,9 +30,12 @@ WORKFLOW_DICT = { } WF_DEF = """ -tasks: - task1: - action: nova.servers_get server="1" +version: '2.0' + +flow: + tasks: + task1: + action: nova.servers_get server="1" """ WF_WITH_DEF_DICT = WORKFLOW_DICT.copy() @@ -45,21 +48,22 @@ class TestCLIWorkflowsV2(base.BaseCommandTest): @mock.patch('argparse.open', create=True) @mock.patch('mistralclient.api.v2.workflows.WorkflowManager.create') def test_create(self, mock, mock_open): - mock.return_value = WORKFLOW + mock.return_value = (WORKFLOW,) mock_open.return_value = mock.MagicMock(spec=file) - result = self.call(workflow_cmd.Create, - app_args=['name', 'tag', '1.txt']) + result = self.call(workflow_cmd.Create, app_args=['1.txt']) - self.assertEqual(('a', 'a, b', '1', '1'), result[1]) + self.assertEqual([('a', 'a, b', '1', '1')], result[1]) + @mock.patch('argparse.open', create=True) @mock.patch('mistralclient.api.v2.workflows.WorkflowManager.update') - def test_update(self, mock): - mock.return_value = WORKFLOW + def test_update(self, mock, mock_open): + mock.return_value = (WORKFLOW,) + mock_open.return_value = mock.MagicMock(spec=file) - result = self.call(workflow_cmd.Update, app_args=['name']) + result = self.call(workflow_cmd.Update, app_args=['1.txt']) - self.assertEqual(('a', 'a, b', '1', '1'), result[1]) + self.assertEqual([('a', 'a, b', '1', '1')], result[1]) @mock.patch('mistralclient.api.v2.workflows.WorkflowManager.list') def test_list(self, mock): @@ -81,20 +85,6 @@ class TestCLIWorkflowsV2(base.BaseCommandTest): def test_delete(self, mock): self.assertIsNone(self.call(workflow_cmd.Delete, app_args=['name'])) - @mock.patch('argparse.open', create=True) - @mock.patch( - 'mistralclient.api.v2.workflows.WorkflowManager.update' - ) - def test_upload_definition(self, mock, mock_open): - mock.return_value = WORKFLOW_WITH_DEF - mock_open.return_value = mock.MagicMock(spec=file) - - result = self.call(workflow_cmd.UploadDefinition, - app_args=['name', '1.txt']) - - self.assertIsNone(result) - self.app.stdout.write.assert_called_with(WF_DEF) - @mock.patch('mistralclient.api.v2.workflows.' 'WorkflowManager.get') def test_get_definition(self, mock):