def test_action_with_notify_crud(self): runnertype = self._create_save_runnertype(metadata=False) saved = self._create_save_action(runnertype, metadata=False) # Update action with notification settings on_complete = NotificationSubSchema(message='Action complete.') saved.notify = NotificationSchema(on_complete=on_complete) saved = Action.add_or_update(saved) # Check if notification settings were set correctly. retrieved = Action.get_by_id(saved.id) self.assertEqual(retrieved.notify.on_complete.message, on_complete.message) # Now reset notify in action to empty and validate it's gone. retrieved.notify = NotificationSchema(on_complete=None) saved = Action.add_or_update(retrieved) retrieved = Action.get_by_id(saved.id) self.assertEqual(retrieved.notify.on_complete, None) # cleanup self._delete([retrieved]) try: retrieved = Action.get_by_id(saved.id) except ValueError: retrieved = None self.assertIsNone(retrieved, 'managed to retrieve after failure.')
def test_parameter_schema(self): runnertype = self._create_save_runnertype(metadata=True) saved = self._create_save_action(runnertype, metadata=True) retrieved = Action.get_by_id(saved.id) # validate generated schema schema = util_schema.get_schema_for_action_parameters(retrieved) self.assertDictEqual(schema, PARAM_SCHEMA) validator = util_schema.get_validator() validator.check_schema(schema) # use schema to validate parameters jsonschema.validate({"r2": "abc", "p1": "def"}, schema, validator) jsonschema.validate({"r2": "abc", "p1": "def", "r1": {"r1a": "ghi"}}, schema, validator) self.assertRaises(jsonschema.ValidationError, jsonschema.validate, '{"r2": "abc", "p1": "def"}', schema, validator) self.assertRaises(jsonschema.ValidationError, jsonschema.validate, {"r2": "abc"}, schema, validator) self.assertRaises(jsonschema.ValidationError, jsonschema.validate, {"r2": "abc", "p1": "def", "r1": 123}, schema, validator) # cleanup self._delete([retrieved]) try: retrieved = Action.get_by_id(saved.id) except ValueError: retrieved = None self.assertIsNone(retrieved, 'managed to retrieve after failure.')
def setup_action_models(cls): action_db = ActionDB() action_db.name = 'action-1' action_db.description = 'awesomeness' action_db.enabled = True action_db.pack = 'wolfpack' action_db.entry_point = '' action_db.runner_type = {'name': 'test-runner'} action_db.parameters = { 'actionstr': {'type': 'string', 'required': True}, 'actionint': {'type': 'number', 'default': 10}, 'runnerdummy': {'type': 'string', 'default': 'actiondummy'}, 'runnerimmutable': {'type': 'string', 'default': 'failed_override'}, 'actionimmutable': {'type': 'string', 'default': 'actionimmutable', 'immutable': True} } RunnerContainerTest.action_db = Action.add_or_update(action_db) action_db = ActionDB() action_db.name = 'action-2' action_db.description = 'awesomeness' action_db.enabled = True action_db.pack = 'wolfpack' action_db.entry_point = '' action_db.runner_type = {'name': 'test-failingrunner'} action_db.parameters = {} RunnerContainerTest.failingaction_db = Action.add_or_update(action_db)
def setUpClass(cls): super(ExecutionCancellationTestCase, cls).setUpClass() for _, fixture in six.iteritems(FIXTURES['actions']): instance = ActionAPI(**fixture) Action.add_or_update(ActionAPI.to_model(instance)) runners_registrar.register_runners()
def delete(self, action_ref_or_id): """ Delete an action. Handles requests: POST /actions/1?_method=delete DELETE /actions/1 DELETE /actions/mypack.myaction """ action_db = self._get_by_ref_or_id(ref_or_id=action_ref_or_id) action_id = action_db.id try: validate_not_part_of_system_pack(action_db) except ValueValidationException as e: abort(http_client.BAD_REQUEST, str(e)) LOG.debug('DELETE /actions/ lookup with ref_or_id=%s found object: %s', action_ref_or_id, action_db) try: Action.delete(action_db) except Exception as e: LOG.error('Database delete encountered exception during delete of id="%s". ' 'Exception was %s', action_id, e) abort(http_client.INTERNAL_SERVER_ERROR, str(e)) return extra = {'action_db': action_db} LOG.audit('Action deleted. Action.id=%s' % (action_db.id), extra=extra) return None
def tearDownClass(cls): for actiondb in cls.actiondbs.values(): Action.delete(actiondb) RunnerType.delete(cls.runnerdb) super(TestActionExecutionService, cls).tearDownClass()
def setUpClass(cls): super(TestMistralRunner, cls).setUpClass() runners_registrar.register_runner_types() for _, fixture in six.iteritems(FIXTURES['actions']): instance = ActionAPI(**fixture) Action.add_or_update(ActionAPI.to_model(instance))
def _register_action(self, pack, action): with open(action, 'r') as fd: try: content = json.load(fd) except ValueError: LOG.exception('Failed loading action json from %s.', action) raise try: model = Action.get_by_name(str(content['name'])) except ValueError: model = ActionDB() model.name = content['name'] model.description = content['description'] model.enabled = content['enabled'] model.pack = pack model.entry_point = content['entry_point'] model.parameters = content.get('parameters', {}) runner_type = str(content['runner_type']) valid_runner_type, runner_type_db = self._has_valid_runner_type(runner_type) if valid_runner_type: model.runner_type = {'name': runner_type_db.name} else: LOG.exception('Runner type %s doesn\'t exist.') raise try: model = Action.add_or_update(model) LOG.audit('Action created. Action %s from %s.', model, action) except Exception: LOG.exception('Failed to write action to db %s.', model.name) raise
def setUpClass(cls): super(TestMistralRunner, cls).setUpClass() runners_registrar.register_runner_types() metadata = fixture.ARTIFACTS['metadata'] action_local = ActionAPI(**copy.deepcopy(metadata['actions']['local'])) Action.add_or_update(ActionAPI.to_model(action_local)) action_wkflow = ActionAPI(**copy.deepcopy(metadata['actions']['workflow-v2'])) Action.add_or_update(ActionAPI.to_model(action_wkflow))
def test_request_disabled_action(self): self.actiondb.enabled = False Action.add_or_update(self.actiondb) parameters = {'hosts': 'localhost', 'cmd': 'uname -a'} execution = LiveActionDB(action=ACTION_REF, parameters=parameters) self.assertRaises(ValueError, action_service.request, execution) self.actiondb.enabled = True Action.add_or_update(self.actiondb)
def setUp(self): RUNNER_TYPE.id = None RunnerType.add_or_update(RUNNER_TYPE) ACTION.id = None ACTION.runner_type = {'name': RUNNER_TYPE.name} Action.add_or_update(ACTION) TRIGGER.id = None Trigger.add_or_update(TRIGGER)
def setUpClass(cls): super(TestActionExecutionHistoryWorker, cls).setUpClass() runners_registrar.register_runners() action_local = ActionAPI(**copy.deepcopy(fixture.ARTIFACTS["actions"]["local"])) Action.add_or_update(ActionAPI.to_model(action_local)) action_chain = ActionAPI(**copy.deepcopy(fixture.ARTIFACTS["actions"]["chain"])) action_chain.entry_point = fixture.PATH + "/chain.yaml" Action.add_or_update(ActionAPI.to_model(action_chain))
def setUpClass(cls): super(TestActionExecutionHistoryWorker, cls).setUpClass() runners_registrar.register_runner_types() action_local = ActionAPI(**copy.deepcopy(fixture.ARTIFACTS['actions']['local'])) Action.add_or_update(ActionAPI.to_model(action_local)) action_chain = ActionAPI(**copy.deepcopy(fixture.ARTIFACTS['actions']['chain'])) action_chain.entry_point = fixture.PATH + '/chain.yaml' Action.add_or_update(ActionAPI.to_model(action_chain))
def setUpClass(cls): super(TestStreamController, cls).setUpClass() instance = RunnerTypeAPI(**RUNNER_TYPE_1) RunnerType.add_or_update(RunnerTypeAPI.to_model(instance)) instance = ActionAPI(**ACTION_1) Action.add_or_update(ActionAPI.to_model(instance))
def setUpClass(cls): super(DSLTransformTestCase, cls).setUpClass() for _, fixture in six.iteritems(FIXTURES['runners']): instance = RunnerTypeAPI(**fixture) RunnerType.add_or_update(RunnerTypeAPI.to_model(instance)) for _, fixture in six.iteritems(FIXTURES['actions']): instance = ActionAPI(**fixture) Action.add_or_update(ActionAPI.to_model(instance))
def test_register_all_actions(self): try: packs_base_path = os.path.join(tests_base.get_fixtures_path()) all_actions_in_db = Action.get_all() actions_registrar.register_actions(packs_base_path=packs_base_path) all_actions_in_db = Action.get_all() self.assertTrue(len(all_actions_in_db) > 0) except Exception as e: print(str(e)) self.fail('All actions must be registered without exceptions.')
def setUpClass(cls): super(MistralValidationControllerTest, cls).setUpClass() for _, fixture in six.iteritems(FIXTURES['runners']): instance = RunnerTypeAPI(**fixture) RunnerType.add_or_update(RunnerTypeAPI.to_model(instance)) for _, fixture in six.iteritems(FIXTURES['actions']): instance = ActionAPI(**fixture) Action.add_or_update(ActionAPI.to_model(instance))
def test_register_all_actions(self): try: packs_base_path = fixtures_loader.get_fixtures_base_path() all_actions_in_db = Action.get_all() actions_registrar.register_actions(packs_base_paths=[packs_base_path]) except Exception as e: print(str(e)) self.fail('All actions must be registered without exceptions.') else: all_actions_in_db = Action.get_all() self.assertTrue(len(all_actions_in_db) > 0)
def setUpClass(cls): super(MistralValidationTest, cls).setUpClass() for _, fixture in six.iteritems(FIXTURES["runners"]): instance = RunnerTypeAPI(**fixture) RunnerType.add_or_update(RunnerTypeAPI.to_model(instance)) for _, fixture in six.iteritems(FIXTURES["actions"]): instance = ActionAPI(**fixture) Action.add_or_update(ActionAPI.to_model(instance)) cls.validator = wf_validation_utils.get_validator()
def test_run(self): pack = 'dummy_pack_1' # Verify all the resources are there pack_dbs = Pack.query(ref=pack) action_dbs = Action.query(pack=pack) alias_dbs = ActionAlias.query(pack=pack) rule_dbs = Rule.query(pack=pack) sensor_dbs = Sensor.query(pack=pack) trigger_type_dbs = TriggerType.query(pack=pack) policy_dbs = Policy.query(pack=pack) config_schema_dbs = ConfigSchema.query(pack=pack) config_dbs = Config.query(pack=pack) self.assertEqual(len(pack_dbs), 1) self.assertEqual(len(action_dbs), 1) self.assertEqual(len(alias_dbs), 2) self.assertEqual(len(rule_dbs), 1) self.assertEqual(len(sensor_dbs), 3) self.assertEqual(len(trigger_type_dbs), 4) self.assertEqual(len(policy_dbs), 2) self.assertEqual(len(config_schema_dbs), 1) self.assertEqual(len(config_dbs), 1) # Run action action = self.get_action_instance() action.run(packs=[pack]) # Make sure all resources have been removed from the db pack_dbs = Pack.query(ref=pack) action_dbs = Action.query(pack=pack) alias_dbs = ActionAlias.query(pack=pack) rule_dbs = Rule.query(pack=pack) sensor_dbs = Sensor.query(pack=pack) trigger_type_dbs = TriggerType.query(pack=pack) policy_dbs = Policy.query(pack=pack) config_schema_dbs = ConfigSchema.query(pack=pack) config_dbs = Config.query(pack=pack) self.assertEqual(len(pack_dbs), 0) self.assertEqual(len(action_dbs), 0) self.assertEqual(len(alias_dbs), 0) self.assertEqual(len(rule_dbs), 0) self.assertEqual(len(sensor_dbs), 0) self.assertEqual(len(trigger_type_dbs), 0) self.assertEqual(len(policy_dbs), 0) self.assertEqual(len(config_schema_dbs), 0) self.assertEqual(len(config_dbs), 0)
def setUpClass(cls): super(DSLTransformTestCase, cls).setUpClass() runners_registrar.register_runner_types() action_local = ActionAPI(**copy.deepcopy(FIXTURES['actions']['local.yaml'])) Action.add_or_update(ActionAPI.to_model(action_local)) for action_name in ['action1', 'action2', 'action3']: metadata = copy.deepcopy(FIXTURES['actions']['local.yaml']) metadata['name'] = action_name metadata['pack'] = 'demo' action = ActionAPI(**metadata) Action.add_or_update(ActionAPI.to_model(action))
def test_pack_name_missing(self): registrar = actions_registrar.ActionsRegistrar() action_file = os.path.join(tests_base.get_fixtures_path(), 'wolfpack/actions/action_3_pack_missing.json') registrar._register_action('dummy', action_file) action_name = None with open(action_file, 'r') as fd: content = json.load(fd) action_name = str(content['name']) action_db = Action.get_by_name(action_name) self.assertEqual(action_db.pack, 'dummy', 'Content pack must be ' + 'set to dummy') Action.delete(action_db)
def test_request_disabled_action(self): actiondb = self.actiondbs[ACTION['name']] actiondb.enabled = False Action.add_or_update(actiondb) try: parameters = {'hosts': 'localhost', 'cmd': 'uname -a'} execution = LiveActionDB(action=ACTION_REF, parameters=parameters) self.assertRaises(ValueError, action_service.request, execution) except Exception as e: raise e finally: actiondb.enabled = True Action.add_or_update(actiondb)
def test_pack_name_missing(self): registrar = actions_registrar.ActionsRegistrar() loader = fixtures_loader.FixturesLoader() action_file = loader.get_fixture_file_path_abs( 'generic', 'actions', 'action_3_pack_missing.yaml') registrar._register_action('dummy', action_file) action_name = None with open(action_file, 'r') as fd: content = yaml.safe_load(fd) action_name = str(content['name']) action_db = Action.get_by_name(action_name) self.assertEqual(action_db.pack, 'dummy', 'Content pack must be ' + 'set to dummy') Action.delete(action_db)
def test_register_all_actions(self): try: packs_base_path = fixtures_loader.get_fixtures_base_path() all_actions_in_db = Action.get_all() actions_registrar.register_actions(packs_base_paths=[packs_base_path]) except Exception as e: print(six.text_type(e)) self.fail('All actions must be registered without exceptions.') else: all_actions_in_db = Action.get_all() self.assertTrue(len(all_actions_in_db) > 0) # Assert metadata_file field is populated expected_path = 'actions/action-with-no-parameters.yaml' self.assertEqual(all_actions_in_db[0].metadata_file, expected_path)
def setUpClass(cls): super(TestActionExecutionService, cls).setUpClass() cls.runner = RunnerTypeAPI(**RUNNER) cls.runnerdb = RunnerType.add_or_update(RunnerTypeAPI.to_model(cls.runner)) cls.action = ActionAPI(**ACTION) cls.actiondb = Action.add_or_update(ActionAPI.to_model(cls.action)) cls.container = RunnerContainer()
def post(self, action): """ Create a new action. Handles requests: POST /actions/ """ # Perform validation validate_not_part_of_system_pack(action) action_validator.validate_action(action) # Write pack data files to disk (if any are provided) data_files = getattr(action, 'data_files', []) written_data_files = [] if data_files: written_data_files = self._handle_data_files(pack_name=action.pack, data_files=data_files) action_model = ActionAPI.to_model(action) LOG.debug('/actions/ POST verified ActionAPI object=%s', action) action_db = Action.add_or_update(action_model) LOG.debug('/actions/ POST saved ActionDB object=%s', action_db) # Dispatch an internal trigger for each written data file. This way user # automate comitting this files to git using StackStorm rule if written_data_files: self._dispatch_trigger_for_written_data_files(action_db=action_db, written_data_files=written_data_files) extra = {'acion_db': action_db} LOG.audit('Action created. Action.id=%s' % (action_db.id), extra=extra) action_api = ActionAPI.from_model(action_db) return action_api
def _register_action(self, pack, action): content = self._meta_loader.load(action) action_ref = ResourceReference(pack=pack, name=str(content['name'])) model = action_utils.get_action_by_ref(action_ref) if not model: model = ActionDB() model.name = content['name'] model.description = content['description'] model.enabled = content['enabled'] model.pack = pack model.entry_point = content['entry_point'] model.parameters = content.get('parameters', {}) runner_type = str(content['runner_type']) valid_runner_type, runner_type_db = self._has_valid_runner_type(runner_type) if valid_runner_type: model.runner_type = {'name': runner_type_db.name} else: LOG.exception('Runner type %s doesn\'t exist.', runner_type) raise try: model = Action.add_or_update(model) LOG.audit('Action created. Action %s from %s.', model, action) except Exception: LOG.exception('Failed to write action to db %s.', model.name) raise
def test_action_update(self): registrar = actions_registrar.ActionsRegistrar() loader = fixtures_loader.FixturesLoader() action_file = loader.get_fixture_file_path_abs( 'generic', 'actions', 'action1.yaml') registrar._register_action('wolfpack', action_file) # try registering again. this should not throw errors. registrar._register_action('wolfpack', action_file) action_name = None with open(action_file, 'r') as fd: content = yaml.safe_load(fd) action_name = str(content['name']) action_db = Action.get_by_name(action_name) self.assertEqual(action_db.pack, 'wolfpack', 'Content pack must be ' + 'set to wolfpack') Action.delete(action_db)
def post(self, action): """ Create a new action. Handles requests: POST /actions/ """ if not hasattr(action, 'pack'): setattr(action, 'pack', DEFAULT_PACK_NAME) try: action_validator.validate_action(action) except ValueValidationException as e: abort(http_client.BAD_REQUEST, str(e)) return # ActionsController._validate_action_parameters(action, runnertype_db) action_model = ActionAPI.to_model(action) LOG.debug('/actions/ POST verified ActionAPI object=%s', action) action_db = Action.add_or_update(action_model) LOG.debug('/actions/ POST saved ActionDB object=%s', action_db) extra = {'action_db': action_db} LOG.audit('Action created. Action.id=%s' % (action_db.id), extra=extra) action_api = ActionAPI.from_model(action_db) return action_api