Merge "Implementing run-action command in client"
This commit is contained in:
commit
58bbf1a839
@ -12,6 +12,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
|
|
||||||
|
|
||||||
@ -22,6 +24,27 @@ class ActionExecution(base.Resource):
|
|||||||
class ActionExecutionManager(base.ResourceManager):
|
class ActionExecutionManager(base.ResourceManager):
|
||||||
resource_class = ActionExecution
|
resource_class = ActionExecution
|
||||||
|
|
||||||
|
def create(self, name, input=None, **params):
|
||||||
|
self._ensure_not_empty(name=name)
|
||||||
|
|
||||||
|
data = {'name': name}
|
||||||
|
|
||||||
|
if input:
|
||||||
|
data['input'] = json.dumps(input)
|
||||||
|
|
||||||
|
if params:
|
||||||
|
data['params'] = params
|
||||||
|
|
||||||
|
resp = self.client.http_client.post(
|
||||||
|
'/action_executions',
|
||||||
|
json.dumps(data)
|
||||||
|
)
|
||||||
|
|
||||||
|
if resp.status_code != 201:
|
||||||
|
self._raise_api_exception(resp)
|
||||||
|
|
||||||
|
return self.resource_class(self, base.get_json(resp))
|
||||||
|
|
||||||
def update(self, id, state=None, output=None):
|
def update(self, id, state=None, output=None):
|
||||||
self._ensure_not_empty(id=id)
|
self._ensure_not_empty(id=id)
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ def format(action_ex=None, lister=False):
|
|||||||
action_ex.id,
|
action_ex.id,
|
||||||
action_ex.name,
|
action_ex.name,
|
||||||
action_ex.workflow_name,
|
action_ex.workflow_name,
|
||||||
action_ex.task_name,
|
action_ex.task_name if hasattr(action_ex, 'task_name') else None,
|
||||||
action_ex.state,
|
action_ex.state,
|
||||||
state_info,
|
state_info,
|
||||||
action_ex.accepted,
|
action_ex.accepted,
|
||||||
@ -60,6 +60,80 @@ def format(action_ex=None, lister=False):
|
|||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
|
class Create(show.ShowOne):
|
||||||
|
"""Create new Action execution or just run specific action."""
|
||||||
|
|
||||||
|
def produce_output(self, parsed_args, column_names, data):
|
||||||
|
if not column_names:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return super(Create, self).produce_output(
|
||||||
|
parsed_args,
|
||||||
|
column_names,
|
||||||
|
data
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(Create, self).get_parser(prog_name)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'name',
|
||||||
|
help='Action name to execute.'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
dest='input',
|
||||||
|
nargs='?',
|
||||||
|
help='Action input.'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-s',
|
||||||
|
'--save-result',
|
||||||
|
dest='save_result',
|
||||||
|
action='store_true',
|
||||||
|
help='Save the result into DB.'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-t',
|
||||||
|
'--target',
|
||||||
|
dest='target',
|
||||||
|
help='Action will be executed on <target> executor.'
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
if parsed_args.save_result:
|
||||||
|
params['save_result'] = parsed_args.save_result
|
||||||
|
|
||||||
|
if parsed_args.target:
|
||||||
|
params['target'] = parsed_args.target
|
||||||
|
|
||||||
|
action_input = None
|
||||||
|
|
||||||
|
if parsed_args.input:
|
||||||
|
try:
|
||||||
|
action_input = json.loads(parsed_args.input)
|
||||||
|
except:
|
||||||
|
action_input = json.load(open(parsed_args.input))
|
||||||
|
|
||||||
|
action_ex = action_executions.ActionExecutionManager(
|
||||||
|
self.app.client
|
||||||
|
).create(
|
||||||
|
parsed_args.name,
|
||||||
|
action_input,
|
||||||
|
**params
|
||||||
|
)
|
||||||
|
|
||||||
|
if parsed_args.save_result:
|
||||||
|
return format(action_ex)
|
||||||
|
else:
|
||||||
|
self.app.stdout.write("%s\n" % action_ex.output)
|
||||||
|
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
class List(base.MistralLister):
|
class List(base.MistralLister):
|
||||||
"""List all Action executions."""
|
"""List all Action executions."""
|
||||||
|
|
||||||
|
@ -324,6 +324,7 @@ class MistralShell(app.App):
|
|||||||
mistralclient.commands.v2.environments.Update,
|
mistralclient.commands.v2.environments.Update,
|
||||||
'environment-list': mistralclient.commands.v2.environments.List,
|
'environment-list': mistralclient.commands.v2.environments.List,
|
||||||
'environment-get': mistralclient.commands.v2.environments.Get,
|
'environment-get': mistralclient.commands.v2.environments.Get,
|
||||||
|
'run-action': mistralclient.commands.v2.action_executions.Create,
|
||||||
'action-execution-list':
|
'action-execution-list':
|
||||||
mistralclient.commands.v2.action_executions.List,
|
mistralclient.commands.v2.action_executions.List,
|
||||||
'action-execution-get':
|
'action-execution-get':
|
||||||
|
@ -32,6 +32,25 @@ URL_TEMPLATE_ID = '/action_executions/%s'
|
|||||||
|
|
||||||
|
|
||||||
class TestActionExecutions(base.BaseClientV2Test):
|
class TestActionExecutions(base.BaseClientV2Test):
|
||||||
|
def test_create(self):
|
||||||
|
mock = self.mock_http_post(content=ACTION_EXEC)
|
||||||
|
body = {
|
||||||
|
'name': ACTION_EXEC['name']
|
||||||
|
}
|
||||||
|
|
||||||
|
action_execution = self.action_executions.create(
|
||||||
|
'my_action_execution',
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertIsNotNone(action_execution)
|
||||||
|
self.assertEqual(action_executions.ActionExecution(
|
||||||
|
self.action_executions, ACTION_EXEC
|
||||||
|
).__dict__, action_execution.__dict__)
|
||||||
|
|
||||||
|
mock.assert_called_once_with(
|
||||||
|
URL_TEMPLATE, json.dumps(body))
|
||||||
|
|
||||||
def test_update(self):
|
def test_update(self):
|
||||||
mock = self.mock_http_put(content=ACTION_EXEC)
|
mock = self.mock_http_put(content=ACTION_EXEC)
|
||||||
body = {
|
body = {
|
||||||
|
@ -50,6 +50,38 @@ ACTION_EX_WITH_INPUT = action_ex.ActionExecution(
|
|||||||
|
|
||||||
|
|
||||||
class TestCLIActionExecutions(base.BaseCommandTest):
|
class TestCLIActionExecutions(base.BaseCommandTest):
|
||||||
|
@mock.patch(
|
||||||
|
'mistralclient.api.v2.action_executions.ActionExecutionManager.create'
|
||||||
|
)
|
||||||
|
def test_create(self, mock):
|
||||||
|
mock.return_value = ACTION_EX_WITH_OUTPUT
|
||||||
|
|
||||||
|
self.call(
|
||||||
|
action_ex_cmd.Create,
|
||||||
|
app_args=['some', '{"output": "Hello!"}']
|
||||||
|
)
|
||||||
|
|
||||||
|
self.app.stdout.write.assert_called_with(
|
||||||
|
json.dumps(ACTION_EX_RESULT) + "\n")
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
'mistralclient.api.v2.action_executions.ActionExecutionManager.create'
|
||||||
|
)
|
||||||
|
def test_create_save_result(self, mock):
|
||||||
|
mock.return_value = ACTION_EX_WITH_OUTPUT
|
||||||
|
|
||||||
|
result = self.call(
|
||||||
|
action_ex_cmd.Create,
|
||||||
|
app_args=[
|
||||||
|
'some', '{"output": "Hello!"}', '--save-result'
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
('123', 'some', 'thing', 'task1', 'RUNNING',
|
||||||
|
'RUNNING somehow.', True), result[1]
|
||||||
|
)
|
||||||
|
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
'mistralclient.api.v2.action_executions.ActionExecutionManager.update'
|
'mistralclient.api.v2.action_executions.ActionExecutionManager.update'
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user