def test_validate_runner_type_happy_case(self): action_api_dict = fixture.ARTIFACTS['actions']['local'] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) except: self.fail('Exception validating action: %s' % json.dumps(action_api_dict))
def _register_action(self, pack, action): content = self._meta_loader.load(action) pack_field = content.get('pack', None) if not pack_field: content['pack'] = pack pack_field = pack if pack_field != pack: raise Exception('Model is in pack "%s" but field "pack" is different: %s' % (pack, pack_field)) action_api = ActionAPI(**content) action_api.validate() action_validator.validate_action(action_api) model = ActionAPI.to_model(action_api) action_ref = ResourceReference.to_string_reference(pack=pack, name=str(content['name'])) existing = action_utils.get_action_by_ref(action_ref) if not existing: LOG.debug('Action %s not found. Creating new one with: %s', action_ref, content) else: LOG.debug('Action %s found. Will be updated from: %s to: %s', action_ref, existing, model) model.id = existing.id try: model = Action.add_or_update(model) extra = {'action_db': model} LOG.audit('Action updated. Action %s from %s.', model, action, extra=extra) except Exception: LOG.exception('Failed to write action to db %s.', model.name) raise
def put(self, action_ref_or_id, action): 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)) if not getattr(action, 'pack', None): action.pack = action_db.pack try: action_validator.validate_action(action) except ValueValidationException as e: abort(http_client.BAD_REQUEST, str(e)) return try: action_db = ActionAPI.to_model(action) action_db.id = action_id action_db = Action.add_or_update(action_db) except (ValidationError, ValueError) as e: LOG.exception('Unable to update action data=%s', action) abort(http_client.BAD_REQUEST, str(e)) return action_api = ActionAPI.from_model(action_db) LOG.debug('PUT /actions/ client_result=%s', action_api) return action_api
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 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
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 test_validate_runner_type_invalid_runner(self): action_api_dict = fixture.ARTIFACTS['actions']['action-with-invalid-runner'] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) self.fail('Action validation should not have passed. %s' % json.dumps(action_api_dict)) except ValueValidationException: pass
def test_validate_override_immutable_runner_param(self): action_api_dict = fixture.ARTIFACTS['actions']['local-override-runner-immutable'] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) self.fail('Action validation should not have passed. %s' % json.dumps(action_api_dict)) except ValueValidationException as e: self.assertTrue('Cannot override in action.' in e.message)
def test_validate_action_param_immutable(self): action_api_dict = fixture.ARTIFACTS['actions']['action-immutable-param-no-default'] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) self.fail('Action validation should not have passed. %s' % json.dumps(action_api_dict)) except ValueValidationException as e: self.assertTrue('requires a default value.' in e.message)
def post(self, action): """ Create a new action. Handles requests: POST /actions/ """ LOG.info('POST /actions/ with action data=%s', action) if not hasattr(action, 'enabled'): LOG.debug( 'POST /actions/ incoming action data has enabled field unset. ' 'Defaulting enabled to True.') setattr(action, 'enabled', True) else: action.enabled = bool(action.enabled) 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) try: action_db = Action.add_or_update(action_model) except StackStormDBObjectConflictError as e: # If an existing DB object conflicts with new object then raise error. LOG.warn( '/actions/ POST unable to save ActionDB object "%s" due to uniqueness ' 'conflict. %s', action_model, str(e)) abort(http_client.CONFLICT, str(e), body={'conflict-id': e.conflict_id}) return except Exception as e: LOG.exception( '/actions/ POST unable to save ActionDB object "%s". %s', action_model, e) abort(http_client.INTERNAL_SERVER_ERROR, str(e)) return LOG.debug('/actions/ POST saved ActionDB object=%s', action_db) LOG.audit('Action created. Action=%s', action_db) action_api = ActionAPI.from_model(action_db) LOG.debug('POST /actions/ client_result=%s', action_api) return action_api
def _register_action(self, pack, action): content = self._meta_loader.load(action) pack_field = content.get('pack', None) if not pack_field: content['pack'] = pack pack_field = pack if pack_field != pack: raise Exception( 'Model is in pack "%s" but field "pack" is different: %s' % (pack, pack_field)) action_api = ActionAPI(**content) try: action_api.validate() except jsonschema.ValidationError as e: # We throw a more user-friendly exception on invalid parameter name msg = str(e) is_invalid_parameter_name = 'Additional properties are not allowed' in msg is_invalid_parameter_name &= 'in schema[\'properties\'][\'parameters\']' in msg if is_invalid_parameter_name: parameter_name = re.search('\'(.+?)\' was unexpected', msg).groups()[0] new_msg = ( 'Parameter name "%s" is invalid. Valid characters for parameter name ' 'are [a-zA-Z0-0_].' % (parameter_name)) new_msg += '\n\n' + msg raise jsonschema.ValidationError(new_msg) raise e action_validator.validate_action(action_api) model = ActionAPI.to_model(action_api) action_ref = ResourceReference.to_string_reference( pack=pack, name=str(content['name'])) existing = action_utils.get_action_by_ref(action_ref) if not existing: LOG.debug('Action %s not found. Creating new one with: %s', action_ref, content) else: LOG.debug('Action %s found. Will be updated from: %s to: %s', action_ref, existing, model) model.id = existing.id try: model = Action.add_or_update(model) extra = {'action_db': model} LOG.audit('Action updated. Action %s from %s.', model, action, extra=extra) except Exception: LOG.exception('Failed to write action to db %s.', model.name) raise
def test_validate_action_param_position_values_unique(self): action_api_dict = fixture.ARTIFACTS['actions']['action-with-non-unique-positions'] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) self.fail('Action validation should have failed ' + 'because position values are not unique.' % json.dumps(action_api_dict)) except ValueValidationException as e: self.assertTrue('have same position' in str(e))
def test_validate_action_param_position_values_contiguous(self): action_api_dict = fixture.ARTIFACTS['actions']['action-with-non-contiguous-positions'] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) self.fail('Action validation should have failed ' + 'because position values are not contiguous.' % json.dumps(action_api_dict)) except ValueValidationException as e: self.assertTrue('are not contiguous' in six.text_type(e))
def test_validate_action_param_immutable(self): action_api_dict = fixture.ARTIFACTS["actions"][ "action-immutable-param-no-default"] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) self.fail("Action validation should not have passed. %s" % json.dumps(action_api_dict)) except ValueValidationException as e: self.assertIn("requires a default value.", six.text_type(e))
def test_validate_override_immutable_runner_param(self): action_api_dict = fixture.ARTIFACTS["actions"][ "remote-override-runner-immutable"] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) self.fail("Action validation should not have passed. %s" % json.dumps(action_api_dict)) except ValueValidationException as e: self.assertIn("Cannot override in action.", six.text_type(e))
def test_validate_action_param_immutable_no_default(self): action_api_dict = fixture.ARTIFACTS['actions']['action-immutable-runner-param-no-default'] action_api = ActionAPI(**action_api_dict) # Runner param sudo is decalred immutable in action but no defualt value # supplied in action. We should pick up default value from runner. try: action_validator.validate_action(action_api) except ValueValidationException as e: print(e) self.fail('Action validation should have passed. %s' % json.dumps(action_api_dict))
def post(self, action, requester_user): """ Create a new action. Handles requests: POST /actions/ """ permission_type = PermissionType.ACTION_CREATE rbac_utils = get_rbac_backend().get_utils_class() rbac_utils.assert_user_has_resource_api_permission( user_db=requester_user, resource_api=action, permission_type=permission_type) try: # Perform validation validate_not_part_of_system_pack(action) action_validator.validate_action(action) except ( ValidationError, ValueError, ValueValidationException, InvalidActionParameterException, ) as e: LOG.exception("Unable to create action data=%s", action) abort(http_client.BAD_REQUEST, six.text_type(e)) return # 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_ref=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 Response(json=action_api, status=http_client.CREATED)
def test_validate_action_param_position_values_unique(self): action_api_dict = fixture.ARTIFACTS["actions"][ "action-with-non-unique-positions"] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) self.fail("Action validation should have failed " + "because position values are not unique." % json.dumps(action_api_dict)) except ValueValidationException as e: self.assertIn("have same position", six.text_type(e))
def test_validate_action_param_position_values_unique(self): action_api_dict = fixture.ARTIFACTS['actions'][ 'action-with-non-unique-positions'] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) self.fail('Action validation should have failed ' + 'because position values are not unique.' % json.dumps(action_api_dict)) except ValueValidationException as e: self.assertTrue('have same position' in e.message)
def _register_action(self, pack, action): content = self._meta_loader.load(action) pack_field = content.get('pack', None) if not pack_field: content['pack'] = pack pack_field = pack if pack_field != pack: raise Exception('Model is in pack "%s" but field "pack" is different: %s' % (pack, pack_field)) action_api = ActionAPI(**content) try: action_api.validate() except jsonschema.ValidationError as e: # We throw a more user-friendly exception on invalid parameter name msg = str(e) is_invalid_parameter_name = 'does not match any of the regexes: ' in msg if is_invalid_parameter_name: match = re.search('\'(.+?)\' does not match any of the regexes', msg) if match: parameter_name = match.groups()[0] else: parameter_name = 'unknown' new_msg = ('Parameter name "%s" is invalid. Valid characters for parameter name ' 'are [a-zA-Z0-0_].' % (parameter_name)) new_msg += '\n\n' + msg raise jsonschema.ValidationError(new_msg) raise e action_validator.validate_action(action_api) model = ActionAPI.to_model(action_api) action_ref = ResourceReference.to_string_reference(pack=pack, name=str(content['name'])) existing = action_utils.get_action_by_ref(action_ref) if not existing: LOG.debug('Action %s not found. Creating new one with: %s', action_ref, content) else: LOG.debug('Action %s found. Will be updated from: %s to: %s', action_ref, existing, model) model.id = existing.id try: model = Action.add_or_update(model) extra = {'action_db': model} LOG.audit('Action updated. Action %s from %s.', model, action, extra=extra) except Exception: LOG.exception('Failed to write action to db %s.', model.name) raise
def test_validate_action_param_position_values_contiguous(self): action_api_dict = fixture.ARTIFACTS['actions'][ 'action-with-non-contiguous-positions'] action_api = ActionAPI(**action_api_dict) try: action_validator.validate_action(action_api) self.fail('Action validation should have failed ' + 'because position values are not contiguous.' % json.dumps(action_api_dict)) except ValueValidationException as e: self.assertIn('are not contiguous', six.text_type(e))
def test_validate_action_param_immutable_no_default(self): action_api_dict = fixture.ARTIFACTS['actions'][ 'action-immutable-runner-param-no-default'] action_api = ActionAPI(**action_api_dict) # Runner param sudo is decalred immutable in action but no defualt value # supplied in action. We should pick up default value from runner. try: action_validator.validate_action(action_api) except ValueValidationException as e: print(e) self.fail('Action validation should have passed. %s' % json.dumps(action_api_dict))
def post(self, action): """ Create a new action. Handles requests: POST /actions/ """ LOG.info('POST /actions/ with action data=%s', action) if not hasattr(action, 'enabled'): LOG.debug('POST /actions/ incoming action data has enabled field unset. ' 'Defaulting enabled to True.') setattr(action, 'enabled', True) else: action.enabled = bool(action.enabled) if not hasattr(action, 'pack'): setattr(action, 'pack', 'default') 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) try: action_db = Action.add_or_update(action_model) except NotUniqueError as e: # If an existing DB object conflicts with new object then raise error. LOG.warn('/actions/ POST unable to save ActionDB object "%s" due to uniqueness ' 'conflict. %s', action_model, str(e)) abort(http_client.CONFLICT, str(e)) return except Exception as e: LOG.exception('/actions/ POST unable to save ActionDB object "%s". %s', action_model, e) abort(http_client.INTERNAL_SERVER_ERROR, str(e)) return LOG.debug('/actions/ POST saved ActionDB object=%s', action_db) LOG.audit('Action created. Action=%s', action_db) action_api = ActionAPI.from_model(action_db) LOG.debug('POST /actions/ client_result=%s', action_api) return action_api
def put(self, action, ref_or_id, requester_user): action_db = self._get_by_ref_or_id(ref_or_id=ref_or_id) # Assert permissions permission_type = PermissionType.ACTION_MODIFY rbac_utils = get_rbac_backend().get_utils_class() rbac_utils.assert_user_has_resource_db_permission( user_db=requester_user, resource_db=action_db, permission_type=permission_type, ) action_id = action_db.id if not getattr(action, "pack", None): action.pack = action_db.pack # 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_ref=action.pack, data_files=data_files) try: action_db = ActionAPI.to_model(action) LOG.debug("/actions/ PUT incoming action: %s", action_db) action_db.id = action_id action_db = Action.add_or_update(action_db) LOG.debug("/actions/ PUT after add_or_update: %s", action_db) except (ValidationError, ValueError) as e: LOG.exception("Unable to update action data=%s", action) abort(http_client.BAD_REQUEST, six.text_type(e)) return # Dispatch an internal trigger for each written data file. This way user # automate committing 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) action_api = ActionAPI.from_model(action_db) LOG.debug("PUT /actions/ client_result=%s", action_api) return action_api
def post(self, action, requester_user): """ Create a new action. Handles requests: POST /actions/ """ permission_type = PermissionType.ACTION_CREATE rbac_utils = get_rbac_backend().get_utils_class() rbac_utils.assert_user_has_resource_api_permission(user_db=requester_user, resource_api=action, permission_type=permission_type) try: # Perform validation validate_not_part_of_system_pack(action) action_validator.validate_action(action) except (ValidationError, ValueError, ValueValidationException, InvalidActionParameterException) as e: LOG.exception('Unable to create action data=%s', action) abort(http_client.BAD_REQUEST, six.text_type(e)) return # 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_ref=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 Response(json=action_api, status=http_client.CREATED)
def put(self, action, ref_or_id, requester_user): action_db = self._get_by_ref_or_id(ref_or_id=ref_or_id) # Assert permissions permission_type = PermissionType.ACTION_MODIFY rbac_utils = get_rbac_backend().get_utils_class() rbac_utils.assert_user_has_resource_db_permission(user_db=requester_user, resource_db=action_db, permission_type=permission_type) action_id = action_db.id if not getattr(action, 'pack', None): action.pack = action_db.pack # 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_ref=action.pack, data_files=data_files) try: action_db = ActionAPI.to_model(action) LOG.debug('/actions/ PUT incoming action: %s', action_db) action_db.id = action_id action_db = Action.add_or_update(action_db) LOG.debug('/actions/ PUT after add_or_update: %s', action_db) except (ValidationError, ValueError) as e: LOG.exception('Unable to update action data=%s', action) abort(http_client.BAD_REQUEST, six.text_type(e)) return # Dispatch an internal trigger for each written data file. This way user # automate committing 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) action_api = ActionAPI.from_model(action_db) LOG.debug('PUT /actions/ client_result=%s', action_api) return action_api
def put(self, action_ref_or_id, action): action_db = self._get_by_ref_or_id(ref_or_id=action_ref_or_id) # Assert permissions action_id = action_db.id if not getattr(action, 'pack', None): action.pack = action_db.pack # 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) try: action_db = ActionAPI.to_model(action) LOG.debug('/actions/ PUT incoming action: %s', action_db) action_db.id = action_id action_db = Action.add_or_update(action_db) LOG.debug('/actions/ PUT after add_or_update: %s', action_db) except (ValidationError, ValueError) as e: LOG.exception('Unable to update action data=%s', action) abort(http_client.BAD_REQUEST, str(e)) return # 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) action_api = ActionAPI.from_model(action_db) LOG.debug('PUT /actions/ client_result=%s', action_api) return action_api
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) try: action_db = Action.add_or_update(action_model) except StackStormDBObjectConflictError as e: # If an existing DB object conflicts with new object then raise error. LOG.warn('/actions/ POST unable to save ActionDB object "%s" due to uniqueness ' 'conflict. %s', action_model, str(e)) abort(http_client.CONFLICT, str(e), body={'conflict-id': e.conflict_id}) return except Exception as e: LOG.exception('/actions/ POST unable to save ActionDB object "%s". %s', action_model, e) abort(http_client.INTERNAL_SERVER_ERROR, str(e)) return 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
def put(self, action_ref_or_id, action): action_db = self._get_by_ref_or_id(ref_or_id=action_ref_or_id) # Assert permissions action_id = action_db.id if not getattr(action, 'pack', None): action.pack = action_db.pack # 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) try: action_db = ActionAPI.to_model(action) action_db.id = action_id action_db = Action.add_or_update(action_db) except (ValidationError, ValueError) as e: LOG.exception('Unable to update action data=%s', action) abort(http_client.BAD_REQUEST, str(e)) return # 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) action_api = ActionAPI.from_model(action_db) LOG.debug('PUT /actions/ client_result=%s', action_api) return action_api
def put(self, action_ref_or_id, action): try: action_db = self._get_by_ref_or_id(ref_or_id=action_ref_or_id) except Exception as e: LOG.exception(e.message) abort(http_client.NOT_FOUND, e.message) return 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)) if not getattr(action, 'pack', None): action.pack = action_db.pack try: action_validator.validate_action(action) except ValueValidationException as e: abort(http_client.BAD_REQUEST, str(e)) return try: action_db = ActionAPI.to_model(action) action_db.id = action_id action_db = Action.add_or_update(action_db) except (ValidationError, ValueError) as e: LOG.exception('Unable to update action data=%s', action) abort(http_client.BAD_REQUEST, str(e)) return action_api = ActionAPI.from_model(action_db) LOG.debug('PUT /actions/ client_result=%s', action_api) return action_api
def _register_action(self, pack, action): content = self._meta_loader.load(action) pack_field = content.get('pack', None) if not pack_field: content['pack'] = pack pack_field = pack if pack_field != pack: raise Exception( 'Model is in pack "%s" but field "pack" is different: %s' % (pack, pack_field)) # Add in "metadata_file" attribute which stores path to the pack metadata file relative to # the pack directory metadata_file = content_utils.get_relative_path_to_pack_file( pack_ref=pack, file_path=action, use_pack_cache=True) content['metadata_file'] = metadata_file action_api = ActionAPI(**content) try: action_api.validate() except jsonschema.ValidationError as e: # We throw a more user-friendly exception on invalid parameter name msg = six.text_type(e) is_invalid_parameter_name = 'does not match any of the regexes: ' in msg if is_invalid_parameter_name: match = re.search( '\'(.+?)\' does not match any of the regexes', msg) if match: parameter_name = match.groups()[0] else: parameter_name = 'unknown' new_msg = ( 'Parameter name "%s" is invalid. Valid characters for parameter name ' 'are [a-zA-Z0-0_].' % (parameter_name)) new_msg += '\n\n' + msg raise jsonschema.ValidationError(new_msg) raise e # Use in-memory cached RunnerTypeDB objects to reduce load on the database if self._use_runners_cache: runner_type_db = self._runner_type_db_cache.get( action_api.runner_type, None) if not runner_type_db: runner_type_db = action_validator.get_runner_model(action_api) self._runner_type_db_cache[ action_api.runner_type] = runner_type_db else: runner_type_db = None action_validator.validate_action(action_api, runner_type_db=runner_type_db) model = ActionAPI.to_model(action_api) action_ref = ResourceReference.to_string_reference( pack=pack, name=str(content['name'])) existing = action_utils.get_action_by_ref(action_ref) if not existing: LOG.debug('Action %s not found. Creating new one with: %s', action_ref, content) else: LOG.debug('Action %s found. Will be updated from: %s to: %s', action_ref, existing, model) model.id = existing.id try: model = Action.add_or_update(model) extra = {'action_db': model} LOG.audit('Action updated. Action %s from %s.', model, action, extra=extra) except Exception: LOG.exception('Failed to write action to db %s.', model.name) raise
def _register_action(self, pack, action): content = self._meta_loader.load(action) pack_field = content.get("pack", None) if not pack_field: content["pack"] = pack pack_field = pack if pack_field != pack: raise Exception( 'Model is in pack "%s" but field "pack" is different: %s' % (pack, pack_field)) # Add in "metadata_file" attribute which stores path to the pack metadata file relative to # the pack directory metadata_file = content_utils.get_relative_path_to_pack_file( pack_ref=pack, file_path=action, use_pack_cache=True) content["metadata_file"] = metadata_file action_api = ActionAPI(**content) try: action_api.validate() except jsonschema.ValidationError as e: # We throw a more user-friendly exception on invalid parameter name msg = six.text_type(e) is_invalid_parameter_name = "does not match any of the regexes: " in msg if is_invalid_parameter_name: match = re.search("'(.+?)' does not match any of the regexes", msg) if match: parameter_name = match.groups()[0] else: parameter_name = "unknown" new_msg = ( 'Parameter name "%s" is invalid. Valid characters for parameter name ' "are [a-zA-Z0-0_]." % (parameter_name)) new_msg += "\n\n" + msg raise jsonschema.ValidationError(new_msg) raise e # Use in-memory cached RunnerTypeDB objects to reduce load on the database if self._use_runners_cache: runner_type_db = self._runner_type_db_cache.get( action_api.runner_type, None) if not runner_type_db: runner_type_db = action_validator.get_runner_model(action_api) self._runner_type_db_cache[ action_api.runner_type] = runner_type_db else: runner_type_db = None action_validator.validate_action(action_api, runner_type_db=runner_type_db) model = ActionAPI.to_model(action_api) action_ref = ResourceReference.to_string_reference( pack=pack, name=str(content["name"])) # NOTE: Here we only retrieve existing object to perform an upsert if it already exists in # the database. To do that, we only need access to the "id" attribute (and ref and pack # for our ActionDB abstraction). Retrieving only those fields is fast and much efficient # especially for actions like aws pack ones which contain a lot of parameters. existing = action_utils.get_action_by_ref( action_ref, only_fields=["id", "ref", "pack"]) if not existing: LOG.debug("Action %s not found. Creating new one with: %s", action_ref, content) else: LOG.debug( "Action %s found. Will be updated from: %s to: %s", action_ref, existing, model, ) model.id = existing.id try: model = Action.add_or_update(model) extra = {"action_db": model} LOG.audit("Action updated. Action %s from %s.", model, action, extra=extra) except Exception: LOG.exception("Failed to write action to db %s.", model.name) raise
def _register_action(self, pack, action): content = self._meta_loader.load(action) pack_field = content.get('pack', None) if not pack_field: content['pack'] = pack pack_field = pack if pack_field != pack: raise Exception('Model is in pack "%s" but field "pack" is different: %s' % (pack, pack_field)) # Add in "metadata_file" attribute which stores path to the pack metadata file relative to # the pack directory metadata_file = content_utils.get_relative_path_to_pack_file(pack_ref=pack, file_path=action, use_pack_cache=True) content['metadata_file'] = metadata_file action_api = ActionAPI(**content) try: action_api.validate() except jsonschema.ValidationError as e: # We throw a more user-friendly exception on invalid parameter name msg = six.text_type(e) is_invalid_parameter_name = 'does not match any of the regexes: ' in msg if is_invalid_parameter_name: match = re.search('\'(.+?)\' does not match any of the regexes', msg) if match: parameter_name = match.groups()[0] else: parameter_name = 'unknown' new_msg = ('Parameter name "%s" is invalid. Valid characters for parameter name ' 'are [a-zA-Z0-0_].' % (parameter_name)) new_msg += '\n\n' + msg raise jsonschema.ValidationError(new_msg) raise e # Use in-memory cached RunnerTypeDB objects to reduce load on the database if self._use_runners_cache: runner_type_db = self._runner_type_db_cache.get(action_api.runner_type, None) if not runner_type_db: runner_type_db = action_validator.get_runner_model(action_api) self._runner_type_db_cache[action_api.runner_type] = runner_type_db else: runner_type_db = None action_validator.validate_action(action_api, runner_type_db=runner_type_db) model = ActionAPI.to_model(action_api) action_ref = ResourceReference.to_string_reference(pack=pack, name=str(content['name'])) existing = action_utils.get_action_by_ref(action_ref) if not existing: LOG.debug('Action %s not found. Creating new one with: %s', action_ref, content) else: LOG.debug('Action %s found. Will be updated from: %s to: %s', action_ref, existing, model) model.id = existing.id try: model = Action.add_or_update(model) extra = {'action_db': model} LOG.audit('Action updated. Action %s from %s.', model, action, extra=extra) except Exception: LOG.exception('Failed to write action to db %s.', model.name) raise