def test_model_transformations(self): notify = {} notify_model = NotificationsHelper.to_model(notify) self.assertEqual(notify_model.on_success, None) self.assertEqual(notify_model.on_failure, None) self.assertEqual(notify_model.on_complete, None) notify_api = NotificationsHelper.from_model(notify_model) self.assertEqual(notify_api, {}) notify["on-complete"] = { "message": "Action completed.", "routes": ["66"], "data": { "foo": "{{foo}}", "bar": 1, "baz": [1, 2, 3] }, } notify["on-success"] = { "message": "Action succeeded.", "routes": ["100"], "data": { "foo": "{{foo}}", "bar": 1, }, } notify_model = NotificationsHelper.to_model(notify) self.assertEqual(notify["on-complete"]["message"], notify_model.on_complete.message) self.assertDictEqual(notify["on-complete"]["data"], notify_model.on_complete.data) self.assertListEqual(notify["on-complete"]["routes"], notify_model.on_complete.routes) self.assertEqual(notify["on-success"]["message"], notify_model.on_success.message) self.assertDictEqual(notify["on-success"]["data"], notify_model.on_success.data) self.assertListEqual(notify["on-success"]["routes"], notify_model.on_success.routes) notify_api = NotificationsHelper.from_model(notify_model) self.assertEqual(notify["on-complete"]["message"], notify_api["on-complete"]["message"]) self.assertDictEqual(notify["on-complete"]["data"], notify_api["on-complete"]["data"]) self.assertListEqual(notify["on-complete"]["routes"], notify_api["on-complete"]["routes"]) self.assertEqual(notify["on-success"]["message"], notify_api["on-success"]["message"]) self.assertDictEqual(notify["on-success"]["data"], notify_api["on-success"]["data"]) self.assertListEqual(notify["on-success"]["routes"], notify_api["on-success"]["routes"])
def test_model_transformations(self): notify = {} notify_model = NotificationsHelper.to_model(notify) self.assertEqual(notify_model.on_success, None) self.assertEqual(notify_model.on_failure, None) self.assertEqual(notify_model.on_complete, None) notify_api = NotificationsHelper.from_model(notify_model) self.assertEqual(notify_api, {}) notify['on-complete'] = { 'message': 'Action completed.', 'routes': ['66'], 'data': { 'foo': '{{foo}}', 'bar': 1, 'baz': [1, 2, 3] } } notify['on-success'] = { 'message': 'Action succeeded.', 'routes': ['100'], 'data': { 'foo': '{{foo}}', 'bar': 1, } } notify_model = NotificationsHelper.to_model(notify) self.assertEqual(notify['on-complete']['message'], notify_model.on_complete.message) self.assertDictEqual(notify['on-complete']['data'], notify_model.on_complete.data) self.assertListEqual(notify['on-complete']['routes'], notify_model.on_complete.routes) self.assertEqual(notify['on-success']['message'], notify_model.on_success.message) self.assertDictEqual(notify['on-success']['data'], notify_model.on_success.data) self.assertListEqual(notify['on-success']['routes'], notify_model.on_success.routes) notify_api = NotificationsHelper.from_model(notify_model) self.assertEqual(notify['on-complete']['message'], notify_api['on-complete']['message']) self.assertDictEqual(notify['on-complete']['data'], notify_api['on-complete']['data']) self.assertListEqual(notify['on-complete']['routes'], notify_api['on-complete']['routes']) self.assertEqual(notify['on-success']['message'], notify_api['on-success']['message']) self.assertDictEqual(notify['on-success']['data'], notify_api['on-success']['data']) self.assertListEqual(notify['on-success']['routes'], notify_api['on-success']['routes'])
def test_launch_workflow_with_notifications(self): notify_data = {'on_complete': {'channels': ['slack'], 'message': '"@channel: Action succeeded."', 'data': {}}} MistralRunner.entry_point = mock.PropertyMock(return_value=WF1_YAML_FILE_PATH) liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, notify=notify_data) liveaction, execution = action_service.request(liveaction) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, action_constants.LIVEACTION_STATUS_RUNNING) mistral_context = liveaction.context.get('mistral', None) self.assertIsNotNone(mistral_context) self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) workflow_input = copy.deepcopy(ACTION_PARAMS) workflow_input.update({'count': '3'}) env = { 'st2_execution_id': str(execution.id), 'st2_liveaction_id': str(liveaction.id), '__actions': { 'st2.action': { 'st2_context': { 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', 'parent': str(liveaction.id), 'notify': NotificationsHelper.from_model(liveaction.notify), 'skip_notify_tasks': [] } } } } executions.ExecutionManager.create.assert_called_with( WF1_NAME, workflow_input=workflow_input, env=env)
def test_launch_workflow_with_notifications(self): notify_data = {'on_complete': {'channels': ['slack'], 'message': '"@channel: Action succeeded."', 'data': {}}} MistralRunner.entry_point = mock.PropertyMock(return_value=WF1_YAML_FILE_PATH) execution = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, notify=notify_data) liveaction, _ = action_service.request(execution) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, action_constants.LIVEACTION_STATUS_RUNNING) mistral_context = liveaction.context.get('mistral', None) self.assertIsNotNone(mistral_context) self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) workflow_input = copy.deepcopy(ACTION_PARAMS) workflow_input.update({'count': '3'}) env = { '__actions': { 'st2.action': { 'st2_context': { 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', 'parent': str(liveaction.id), 'notify': NotificationsHelper.from_model(liveaction.notify), 'skip_notify_tasks': [] } } } } executions.ExecutionManager.create.assert_called_with( WF1_NAME, workflow_input=workflow_input, env=env)
def test_model_transformations(self): notify = {} notify['on_complete'] = { 'message': 'Action completed.', 'data': { 'foo': '{{foo}}', 'bar': 1, 'baz': [1, 2, 3] } } notify['on_success'] = { 'message': 'Action succeeded.', 'data': { 'foo': '{{foo}}', 'bar': 1, } } notify_model = NotificationsHelper.to_model(notify) self.assertEqual(notify['on_complete']['message'], notify_model.on_complete.message) self.assertDictEqual(notify['on_complete']['data'], notify_model.on_complete.data) self.assertEqual(notify['on_success']['message'], notify_model.on_success.message) self.assertDictEqual(notify['on_success']['data'], notify_model.on_success.data) notify_api = NotificationsHelper.from_model(notify_model) self.assertEqual(notify['on_complete']['message'], notify_api['on_complete']['message']) self.assertDictEqual(notify['on_complete']['data'], notify_api['on_complete']['data']) self.assertEqual(notify['on_success']['message'], notify_api['on_success']['message']) self.assertDictEqual(notify['on_success']['data'], notify_api['on_success']['data'])
def _construct_workflow_execution_options(self): # This URL is used by Mistral to talk back to the API api_url = get_mistral_api_url() endpoint = api_url + '/actionexecutions' # This URL is available in the context and can be used by the users inside a workflow, # similar to "ST2_ACTION_API_URL" environment variable available to actions public_api_url = get_full_public_api_url() # Build context with additional information parent_context = {'execution_id': self.execution_id} if getattr(self.liveaction, 'context', None): parent_context.update(self.liveaction.context) # Convert jinja expressions in the params of Action Chain under the parent context # into raw block. If there is any jinja expressions, Mistral will try to evaulate # the expression. If there is a local context reference, the evaluation will fail # because the local context reference is out of scope. chain_ctx = parent_context.get('chain') or {} for attr in ['params', 'parameters']: chain_params_ctx = chain_ctx.get(attr) or {} for k, v in six.iteritems(chain_params_ctx): parent_context['chain'][attr][ k] = jinja.convert_jinja_to_raw_block(v) st2_execution_context = { 'api_url': api_url, 'endpoint': endpoint, 'parent': parent_context, 'notify': {}, 'skip_notify_tasks': self._skip_notify_tasks } # Include notification information if self._notify: notify_dict = NotificationsHelper.from_model( notify_model=self._notify) st2_execution_context['notify'] = notify_dict if self.auth_token: st2_execution_context['auth_token'] = self.auth_token.token options = { 'env': { 'st2_execution_id': self.execution_id, 'st2_liveaction_id': self.liveaction_id, 'st2_action_api_url': public_api_url, '__actions': { 'st2.action': { 'st2_context': st2_execution_context } } } } return options
def test_model_transformations(self): notify = {} notify_model = NotificationsHelper.to_model(notify) self.assertEqual(notify_model.on_success, None) self.assertEqual(notify_model.on_failure, None) self.assertEqual(notify_model.on_complete, None) notify_api = NotificationsHelper.from_model(notify_model) self.assertEqual(notify_api, {}) notify['on-complete'] = { 'message': 'Action completed.', 'routes': [ '66' ], 'data': { 'foo': '{{foo}}', 'bar': 1, 'baz': [1, 2, 3] } } notify['on-success'] = { 'message': 'Action succeeded.', 'routes': [ '100' ], 'data': { 'foo': '{{foo}}', 'bar': 1, } } notify_model = NotificationsHelper.to_model(notify) self.assertEqual(notify['on-complete']['message'], notify_model.on_complete.message) self.assertDictEqual(notify['on-complete']['data'], notify_model.on_complete.data) self.assertListEqual(notify['on-complete']['routes'], notify_model.on_complete.routes) self.assertEqual(notify['on-success']['message'], notify_model.on_success.message) self.assertDictEqual(notify['on-success']['data'], notify_model.on_success.data) self.assertListEqual(notify['on-success']['routes'], notify_model.on_success.routes) notify_api = NotificationsHelper.from_model(notify_model) self.assertEqual(notify['on-complete']['message'], notify_api['on-complete']['message']) self.assertDictEqual(notify['on-complete']['data'], notify_api['on-complete']['data']) self.assertListEqual(notify['on-complete']['routes'], notify_api['on-complete']['routes']) self.assertEqual(notify['on-success']['message'], notify_api['on-success']['message']) self.assertDictEqual(notify['on-success']['data'], notify_api['on-success']['data']) self.assertListEqual(notify['on-success']['routes'], notify_api['on-success']['routes'])
def from_model(cls, model): action = cls._from_model(model) action['runner_type'] = action['runner_type']['name'] action['tags'] = TagsHelper.from_model(model.tags) if getattr(model, 'notify', None): action['notify'] = NotificationsHelper.from_model(model.notify) return cls(**action)
def from_model(cls, model, mask_secrets=False): action = cls._from_model(model) action["runner_type"] = action["runner_type"]["name"] action["tags"] = TagsHelper.from_model(model.tags) if getattr(model, "notify", None): action["notify"] = NotificationsHelper.from_model(model.notify) return cls(**action)
def from_model(cls, model, mask_secrets=False): action = cls._from_model(model) action["runner_type"] = action.get("runner_type", {}).get("name", None) action["tags"] = TagsHelper.from_model(model.tags) if getattr(model, "notify", None): action["notify"] = NotificationsHelper.from_model(model.notify) return cls(**action)
def from_model(cls, model, mask_secrets=False): action = cls._from_model(model) action['runner_type'] = action.get('runner_type', {}).get('name', None) action['tags'] = TagsHelper.from_model(model.tags) if getattr(model, 'notify', None): action['notify'] = NotificationsHelper.from_model(model.notify) return cls(**action)
def from_model(cls, model, mask_secrets=False): action = cls._from_model(model) action['runner_type'] = action['runner_type']['name'] action['tags'] = TagsHelper.from_model(model.tags) if getattr(model, 'notify', None): action['notify'] = NotificationsHelper.from_model(model.notify) return cls(**action)
def from_model(cls, model): doc = super(cls, cls)._from_model(model) if model.start_timestamp: doc['start_timestamp'] = isotime.format(model.start_timestamp, offset=False) if model.end_timestamp: doc['end_timestamp'] = isotime.format(model.end_timestamp, offset=False) if getattr(model, 'notify', None): doc['notify'] = NotificationsHelper.from_model(model.notify) return cls(**doc)
def from_model(cls, model, mask_secrets=False): doc = super(cls, cls)._from_model(model, mask_secrets=mask_secrets) if model.start_timestamp: doc["start_timestamp"] = isotime.format(model.start_timestamp, offset=False) if model.end_timestamp: doc["end_timestamp"] = isotime.format(model.end_timestamp, offset=False) if getattr(model, "notify", None): doc["notify"] = NotificationsHelper.from_model(model.notify) return cls(**doc)
def from_model(cls, model, mask_secrets=False): doc = super(cls, cls)._from_model(model, mask_secrets=mask_secrets) if model.start_timestamp: doc['start_timestamp'] = isotime.format(model.start_timestamp, offset=False) if model.end_timestamp: doc['end_timestamp'] = isotime.format(model.end_timestamp, offset=False) if getattr(model, 'notify', None): doc['notify'] = NotificationsHelper.from_model(model.notify) return cls(**doc)
def test_model_transformations(self): notify = {} notify_model = NotificationsHelper.to_model(notify) self.assertEqual(notify_model.on_success, None) self.assertEqual(notify_model.on_failure, None) self.assertEqual(notify_model.on_complete, None) notify_api = NotificationsHelper.from_model(notify_model) self.assertEqual(notify_api, {}) notify["on-complete"] = {"message": "Action completed.", "data": {"foo": "{{foo}}", "bar": 1, "baz": [1, 2, 3]}} notify["on-success"] = {"message": "Action succeeded.", "data": {"foo": "{{foo}}", "bar": 1}} notify_model = NotificationsHelper.to_model(notify) self.assertEqual(notify["on-complete"]["message"], notify_model.on_complete.message) self.assertDictEqual(notify["on-complete"]["data"], notify_model.on_complete.data) self.assertEqual(notify["on-success"]["message"], notify_model.on_success.message) self.assertDictEqual(notify["on-success"]["data"], notify_model.on_success.data) notify_api = NotificationsHelper.from_model(notify_model) self.assertEqual(notify["on-complete"]["message"], notify_api["on-complete"]["message"]) self.assertDictEqual(notify["on-complete"]["data"], notify_api["on-complete"]["data"]) self.assertEqual(notify["on-success"]["message"], notify_api["on-success"]["message"]) self.assertDictEqual(notify["on-success"]["data"], notify_api["on-success"]["data"])
def test_launch_workflow_with_notifications(self): notify_data = { 'on_complete': { 'routes': ['slack'], 'message': '"@channel: Action succeeded."', 'data': {} } } liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, notify=notify_data) liveaction, execution = action_service.request(liveaction) liveaction = self._wait_on_status( liveaction, action_constants.LIVEACTION_STATUS_RUNNING) mistral_context = liveaction.context.get('mistral', None) self.assertIsNotNone(mistral_context) self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) workflow_input = copy.deepcopy(ACTION_PARAMS) workflow_input.update({'count': '3'}) env = { 'st2_execution_id': str(execution.id), 'st2_liveaction_id': str(liveaction.id), 'st2_action_api_url': 'http://0.0.0.0:9101/v1', '__actions': { 'st2.action': { 'st2_context': { 'api_url': 'http://0.0.0.0:9101/v1', 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', 'parent': { 'pack': 'mistral_tests', 'execution_id': str(execution.id) }, 'notify': NotificationsHelper.from_model(liveaction.notify), 'skip_notify_tasks': [] } } } } executions.ExecutionManager.create.assert_called_with( WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY)
def _construct_workflow_execution_options(self): # This URL is used by Mistral to talk back to the API api_url = get_mistral_api_url() endpoint = api_url + '/actionexecutions' # This URL is available in the context and can be used by the users inside a workflow, # similar to "ST2_ACTION_API_URL" environment variable available to actions public_api_url = get_full_public_api_url() # Build context with additional information parent_context = { 'execution_id': self.execution_id } if getattr(self.liveaction, 'context', None): parent_context.update(self.liveaction.context) st2_execution_context = { 'api_url': api_url, 'endpoint': endpoint, 'parent': parent_context, 'notify': {}, 'skip_notify_tasks': self._skip_notify_tasks } # Include notification information if self._notify: notify_dict = NotificationsHelper.from_model(notify_model=self._notify) st2_execution_context['notify'] = notify_dict if self.auth_token: st2_execution_context['auth_token'] = self.auth_token.token options = { 'env': { 'st2_execution_id': self.execution_id, 'st2_liveaction_id': self.liveaction_id, 'st2_action_api_url': public_api_url, '__actions': { 'st2.action': { 'st2_context': st2_execution_context } } } } return options
def _construct_workflow_execution_options(self): # This URL is used by Mistral to talk back to the API api_url = get_mistral_api_url() endpoint = api_url + '/actionexecutions' # This URL is available in the context and can be used by the users inside a workflow, # similar to "ST2_ACTION_API_URL" environment variable available to actions public_api_url = get_full_public_api_url() # Build context with additional information parent_context = {'execution_id': self.execution_id} if getattr(self.liveaction, 'context', None): parent_context.update(self.liveaction.context) st2_execution_context = { 'api_url': api_url, 'endpoint': endpoint, 'parent': parent_context, 'notify': {}, 'skip_notify_tasks': self._skip_notify_tasks } # Include notification information if self._notify: notify_dict = NotificationsHelper.from_model( notify_model=self._notify) st2_execution_context['notify'] = notify_dict if self.auth_token: st2_execution_context['auth_token'] = self.auth_token.token options = { 'env': { 'st2_execution_id': self.execution_id, 'st2_liveaction_id': self.liveaction_id, 'st2_action_api_url': public_api_url, '__actions': { 'st2.action': { 'st2_context': st2_execution_context } } } } return options
def _construct_workflow_execution_options(self): # This URL is used by Mistral to talk back to the API api_url = get_mistral_api_url() endpoint = api_url + "/actionexecutions" # This URL is available in the context and can be used by the users inside a workflow, # similar to "ST2_ACTION_API_URL" environment variable available to actions public_api_url = get_full_public_api_url() # Build context with additional information parent_context = {"execution_id": self.execution_id} if getattr(self.liveaction, "context", None): parent_context.update(self.liveaction.context) st2_execution_context = { "endpoint": endpoint, "parent": parent_context, "notify": {}, "skip_notify_tasks": self._skip_notify_tasks, } # Include notification information if self._notify: notify_dict = NotificationsHelper.from_model(notify_model=self._notify) st2_execution_context["notify"] = notify_dict if self.auth_token: st2_execution_context["auth_token"] = self.auth_token.token options = { "env": { "st2_execution_id": self.execution_id, "st2_liveaction_id": self.liveaction_id, "st2_action_api_url": public_api_url, "__actions": {"st2.action": {"st2_context": st2_execution_context}}, } } return options
def test_launch_workflow_with_notifications(self): notify_data = {'on_complete': {'routes': ['slack'], 'message': '"@channel: Action succeeded."', 'data': {}}} liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, notify=notify_data) liveaction, execution = action_service.request(liveaction) liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) mistral_context = liveaction.context.get('mistral', None) self.assertIsNotNone(mistral_context) self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) workflow_input = copy.deepcopy(ACTION_PARAMS) workflow_input.update({'count': '3'}) env = { 'st2_execution_id': str(execution.id), 'st2_liveaction_id': str(liveaction.id), 'st2_action_api_url': 'http://0.0.0.0:9101/v1', '__actions': { 'st2.action': { 'st2_context': { 'api_url': 'http://0.0.0.0:9101/v1', 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', 'parent': { 'pack': 'mistral_tests', 'execution_id': str(execution.id) }, 'notify': NotificationsHelper.from_model(liveaction.notify), 'skip_notify_tasks': [] } } } } executions.ExecutionManager.create.assert_called_with( WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY)
def try_run(self, action_parameters): # Test connection self._client.workflows.list() # Setup inputs for the workflow execution. inputs = self.runner_parameters.get("context", dict()) inputs.update(action_parameters) endpoint = "http://%s:%s/v1/actionexecutions" % (cfg.CONF.api.host, cfg.CONF.api.port) # Build context with additional information parent_context = {"execution_id": self.execution_id} if getattr(self.liveaction, "context", None): parent_context.update(self.liveaction.context) st2_execution_context = { "endpoint": endpoint, "parent": parent_context, "notify": {}, "skip_notify_tasks": self._skip_notify_tasks, } # Include notification information if self._notify: notify_dict = NotificationsHelper.from_model(notify_model=self._notify) st2_execution_context["notify"] = notify_dict if self.auth_token: st2_execution_context["auth_token"] = self.auth_token.token options = { "env": { "st2_execution_id": self.execution_id, "st2_liveaction_id": self.liveaction_id, "__actions": {"st2.action": {"st2_context": st2_execution_context}}, } } # Get workbook/workflow definition from file. with open(self.entry_point, "r") as def_file: def_yaml = def_file.read() def_dict = yaml.safe_load(def_yaml) is_workbook = "workflows" in def_dict if not is_workbook: # Non-workbook definition containing multiple workflows is not supported. if len([k for k, _ in six.iteritems(def_dict) if k != "version"]) != 1: raise Exception( "Workflow (not workbook) definition is detected. " "Multiple workflows is not supported." ) action_ref = "%s.%s" % (self.action.pack, self.action.name) self._check_name(action_ref, is_workbook, def_dict) def_dict_xformed = utils.transform_definition(def_dict) def_yaml_xformed = yaml.safe_dump(def_dict_xformed, default_flow_style=False) # Save workbook/workflow definition. if is_workbook: self._save_workbook(action_ref, def_yaml_xformed) default_workflow = self._find_default_workflow(def_dict_xformed) execution = self._client.executions.create(default_workflow, workflow_input=inputs, **options) else: self._save_workflow(action_ref, def_yaml_xformed) execution = self._client.executions.create(action_ref, workflow_input=inputs, **options) status = LIVEACTION_STATUS_RUNNING partial_results = {"tasks": []} # pylint: disable=no-member current_context = {"execution_id": str(execution.id), "workflow_name": execution.workflow_name} exec_context = self.context exec_context = self._build_mistral_context(exec_context, current_context) LOG.info("Mistral query context is %s" % exec_context) return (status, partial_results, exec_context)
def _construct_workflow_execution_options(self): # This URL is used by Mistral to talk back to the API api_url = get_mistral_api_url() endpoint = api_url + '/actionexecutions' # This URL is available in the context and can be used by the users inside a workflow, # similar to "ST2_ACTION_API_URL" environment variable available to actions public_api_url = get_full_public_api_url() # Build context with additional information parent_context = { 'execution_id': self.execution_id } if getattr(self.liveaction, 'context', None): parent_context.update(self.liveaction.context) # Convert jinja expressions in the params of Action Chain under the parent context # into raw block. If there is any jinja expressions, Mistral will try to evaulate # the expression. If there is a local context reference, the evaluation will fail # because the local context reference is out of scope. chain_ctx = parent_context.get('chain') or {} for attr in ['params', 'parameters']: chain_params_ctx = chain_ctx.get(attr) or {} for k, v in six.iteritems(chain_params_ctx): parent_context['chain'][attr][k] = jinja.convert_jinja_to_raw_block(v) st2_execution_context = { 'api_url': api_url, 'endpoint': endpoint, 'parent': parent_context, 'notify': {}, 'skip_notify_tasks': self._skip_notify_tasks } # Include notification information if self._notify: notify_dict = NotificationsHelper.from_model(notify_model=self._notify) st2_execution_context['notify'] = notify_dict if self.auth_token: st2_execution_context['auth_token'] = self.auth_token.token options = { 'env': { 'st2_execution_id': self.execution_id, 'st2_liveaction_id': self.liveaction_id, 'st2_action_api_url': public_api_url, '__actions': { 'st2.action': { 'st2_context': st2_execution_context } } } } if not self.is_polling_enabled(): options['notify'] = [{'type': 'st2'}] # Only used on reverse type workflows task_name = self.runner_parameters.get('task_name', None) if task_name is not None: options['task_name'] = task_name return options
def try_run(self, action_parameters): # Test connection self._client.workflows.list() # Setup inputs for the workflow execution. inputs = self.runner_parameters.get('context', dict()) inputs.update(action_parameters) endpoint = 'http://%s:%s/v1/actionexecutions' % (cfg.CONF.api.host, cfg.CONF.api.port) # Build context with additional information parent_context = {'execution_id': self.execution_id} if getattr(self.liveaction, 'context', None): parent_context.update(self.liveaction.context) st2_execution_context = { 'endpoint': endpoint, 'parent': parent_context, 'notify': {}, 'skip_notify_tasks': self._skip_notify_tasks } # Include notification information if self._notify: notify_dict = NotificationsHelper.from_model( notify_model=self._notify) st2_execution_context['notify'] = notify_dict if self.auth_token: st2_execution_context['auth_token'] = self.auth_token.token options = { 'env': { 'st2_execution_id': self.execution_id, 'st2_liveaction_id': self.liveaction_id, '__actions': { 'st2.action': { 'st2_context': st2_execution_context } } } } # Get workbook/workflow definition from file. with open(self.entry_point, 'r') as def_file: def_yaml = def_file.read() def_dict = yaml.safe_load(def_yaml) is_workbook = ('workflows' in def_dict) if not is_workbook: # Non-workbook definition containing multiple workflows is not supported. if len([k for k, _ in six.iteritems(def_dict) if k != 'version' ]) != 1: raise Exception( 'Workflow (not workbook) definition is detected. ' 'Multiple workflows is not supported.') action_ref = '%s.%s' % (self.action.pack, self.action.name) self._check_name(action_ref, is_workbook, def_dict) def_dict_xformed = utils.transform_definition(def_dict) def_yaml_xformed = yaml.safe_dump(def_dict_xformed, default_flow_style=False) # Save workbook/workflow definition. if is_workbook: self._save_workbook(action_ref, def_yaml_xformed) default_workflow = self._find_default_workflow(def_dict_xformed) execution = self._client.executions.create(default_workflow, workflow_input=inputs, **options) else: self._save_workflow(action_ref, def_yaml_xformed) execution = self._client.executions.create(action_ref, workflow_input=inputs, **options) status = LIVEACTION_STATUS_RUNNING partial_results = {'tasks': []} # pylint: disable=no-member current_context = { 'execution_id': str(execution.id), 'workflow_name': execution.workflow_name } exec_context = self.context exec_context = self._build_mistral_context(exec_context, current_context) LOG.info('Mistral query context is %s' % exec_context) return (status, partial_results, exec_context)
def run(self, action_parameters): # Test connection self._client.workflows.list() # Setup inputs for the workflow execution. inputs = self.runner_parameters.get('context', dict()) inputs.update(action_parameters) # This URL is used by Mistral to talk back to the API api_url = get_mistral_api_url() endpoint = api_url + '/actionexecutions' # This URL is available in the context and can be used by the users inside a workflow, # similar to "ST2_ACTION_API_URL" environment variable available to actions public_api_url = get_full_public_api_url() # Build context with additional information parent_context = { 'execution_id': self.execution_id } if getattr(self.liveaction, 'context', None): parent_context.update(self.liveaction.context) st2_execution_context = { 'endpoint': endpoint, 'parent': parent_context, 'notify': {}, 'skip_notify_tasks': self._skip_notify_tasks } # Include notification information if self._notify: notify_dict = NotificationsHelper.from_model(notify_model=self._notify) st2_execution_context['notify'] = notify_dict if self.auth_token: st2_execution_context['auth_token'] = self.auth_token.token options = { 'env': { 'st2_execution_id': self.execution_id, 'st2_liveaction_id': self.liveaction_id, 'st2_action_api_url': public_api_url, '__actions': { 'st2.action': { 'st2_context': st2_execution_context } } } } # Get workbook/workflow definition from file. with open(self.entry_point, 'r') as def_file: def_yaml = def_file.read() def_dict = yaml.safe_load(def_yaml) is_workbook = ('workflows' in def_dict) if not is_workbook: # Non-workbook definition containing multiple workflows is not supported. if len([k for k, _ in six.iteritems(def_dict) if k != 'version']) != 1: raise Exception('Workflow (not workbook) definition is detected. ' 'Multiple workflows is not supported.') action_ref = '%s.%s' % (self.action.pack, self.action.name) self._check_name(action_ref, is_workbook, def_dict) def_dict_xformed = utils.transform_definition(def_dict) def_yaml_xformed = yaml.safe_dump(def_dict_xformed, default_flow_style=False) # Save workbook/workflow definition. if is_workbook: self._save_workbook(action_ref, def_yaml_xformed) default_workflow = self._find_default_workflow(def_dict_xformed) execution = self._client.executions.create(default_workflow, workflow_input=inputs, **options) else: self._save_workflow(action_ref, def_yaml_xformed) execution = self._client.executions.create(action_ref, workflow_input=inputs, **options) status = LIVEACTION_STATUS_RUNNING partial_results = {'tasks': []} # pylint: disable=no-member current_context = { 'execution_id': str(execution.id), 'workflow_name': execution.workflow_name } exec_context = self.context exec_context = self._build_mistral_context(exec_context, current_context) LOG.info('Mistral query context is %s' % exec_context) return (status, partial_results, exec_context)
def try_run(self, action_parameters): # Test connection self._client.workflows.list() # Setup inputs for the workflow execution. inputs = self.runner_parameters.get('context', dict()) inputs.update(action_parameters) endpoint = 'http://%s:%s/v1/actionexecutions' % (cfg.CONF.api.host, cfg.CONF.api.port) # Build context with additional information st2_execution_context = { 'endpoint': endpoint, 'parent': self.liveaction_id, 'notify': {}, 'skip_notify_tasks': self._skip_notify_tasks } # Include notification information if self._notify: notify_dict = NotificationsHelper.from_model(notify_model=self._notify) st2_execution_context['notify'] = notify_dict if self.auth_token: st2_execution_context['auth_token'] = self.auth_token.token options = { 'env': { 'st2_execution_id': self.execution_id, 'st2_liveaction_id': self.liveaction_id, '__actions': { 'st2.action': { 'st2_context': st2_execution_context } } } } # Get workbook/workflow definition from file. with open(self.entry_point, 'r') as def_file: def_yaml = def_file.read() def_dict = yaml.safe_load(def_yaml) is_workbook = ('workflows' in def_dict) if not is_workbook: # Non-workbook definition containing multiple workflows is not supported. if len([k for k, _ in six.iteritems(def_dict) if k != 'version']) != 1: raise Exception('Workflow (not workbook) definition is detected. ' 'Multiple workflows is not supported.') action_ref = '%s.%s' % (self.action.pack, self.action.name) self._check_name(action_ref, is_workbook, def_dict) def_dict_xformed = utils.transform_definition(def_dict) def_yaml_xformed = yaml.safe_dump(def_dict_xformed, default_flow_style=False) # Save workbook/workflow definition. if is_workbook: self._save_workbook(action_ref, def_yaml_xformed) default_workflow = self._find_default_workflow(def_dict_xformed) execution = self._client.executions.create(default_workflow, workflow_input=inputs, **options) else: self._save_workflow(action_ref, def_yaml_xformed) execution = self._client.executions.create(action_ref, workflow_input=inputs, **options) status = LIVEACTION_STATUS_RUNNING partial_results = {'tasks': []} # pylint: disable=no-member current_context = { 'execution_id': str(execution.id), 'workflow_name': execution.workflow_name } exec_context = self.context exec_context = self._build_mistral_context(exec_context, current_context) LOG.info('Mistral query context is %s' % exec_context) return (status, partial_results, exec_context)