Example #1
0
    def put(self,
            pack_config_content,
            pack_ref,
            requester_user,
            show_secrets=False):
        """
        Create a new config for a pack.

        Handles requests:
            POST /configs/<pack_ref>
        """

        try:
            config_api = ConfigAPI(pack=pack_ref,
                                   values=vars(pack_config_content))
            config_api.validate(validate_against_schema=True)
        except jsonschema.ValidationError as e:
            raise ValueValidationException(six.text_type(e))
        except ValueValidationException as e:
            raise ValueValidationException(six.text_type(e))

        self._dump_config_to_disk(config_api)

        config_db = ConfigsRegistrar.save_model(config_api)

        mask_secrets = self._get_mask_secrets(requester_user,
                                              show_secrets=show_secrets)
        return ConfigAPI.from_model(config_db, mask_secrets=mask_secrets)
Example #2
0
def _validate_parameters(action_params=None, runner_params=None):
    for param, action_param_meta in six.iteritems(action_params):
        if 'immutable' in action_param_meta:
            if param in runner_params:
                runner_param_meta = runner_params[param]
                if 'immutable' in runner_param_meta:
                    msg = 'Param %s is declared immutable in runner. ' % param + \
                          'Cannot override in action.'
                    raise ValueValidationException(msg)
            if 'default' not in action_param_meta:
                msg = 'Immutable param %s requires a default value.' % param
                raise ValueValidationException(msg)
Example #3
0
def _validate_parameters(action_ref, action_params=None, runner_params=None):
    position_params = {}
    for action_param, action_param_meta in six.iteritems(action_params):
        # Check if overridden runner parameters are permitted.
        if action_param in runner_params:
            for action_param_attr, value in six.iteritems(action_param_meta):
                util_schema.validate_runner_parameter_attribute_override(
                    action_ref,
                    action_param,
                    action_param_attr,
                    value,
                    runner_params[action_param].get(action_param_attr),
                )

        if "position" in action_param_meta:
            pos = action_param_meta["position"]
            param = position_params.get(pos, None)
            if param:
                msg = (
                    "Parameters %s and %s have same position %d."
                    % (action_param, param, pos)
                    + " Position values have to be unique."
                )
                raise ValueValidationException(msg)
            else:
                position_params[pos] = action_param

        if "immutable" in action_param_meta:
            if action_param in runner_params:
                runner_param_meta = runner_params[action_param]
                if "immutable" in runner_param_meta:
                    msg = (
                        "Param %s is declared immutable in runner. " % action_param
                        + "Cannot override in action."
                    )
                    raise ValueValidationException(msg)
                if (
                    "default" not in action_param_meta
                    and "default" not in runner_param_meta
                ):
                    msg = "Immutable param %s requires a default value." % action_param
                    raise ValueValidationException(msg)
            else:
                if "default" not in action_param_meta:
                    msg = "Immutable param %s requires a default value." % action_param
                    raise ValueValidationException(msg)

    return _validate_position_values_contiguous(position_params)
Example #4
0
def validate_criteria(criteria):
    if not isinstance(criteria, dict):
        raise ValueValidationException('Criteria should be a dict.')

    for key, value in six.iteritems(criteria):
        operator = value.get('type', None)
        if operator is None:
            raise ValueValidationException('Operator not specified for field: ' + key)
        if operator not in allowed_operators:
            raise ValueValidationException('For field: ' + key + ', operator ' + operator +
                                           ' not in list of allowed operators: ' +
                                           str(allowed_operators.keys()))
        pattern = value.get('pattern', None)
        if pattern is None:
            raise ValueValidationException('For field: ' + key + ', no pattern specified ' +
                                           'for operator ' + operator)
Example #5
0
    def put(self, pack_uninstall_request, pack_ref):
        """
            Create a new config for a pack.

            Handles requests:
                POST /configs/<pack_ref>
        """

        try:
            config_api = ConfigAPI(pack=pack_ref,
                                   values=vars(pack_uninstall_request))
            config_api.validate(validate_against_schema=True)
        except jsonschema.ValidationError as e:
            raise ValueValidationException(str(e))

        config_content = yaml.safe_dump(config_api.values,
                                        default_flow_style=False)

        configs_path = os.path.join(cfg.CONF.system.base_path, 'configs/')
        config_path = os.path.join(configs_path, '%s.yaml' % config_api.pack)
        with open(config_path, 'w') as f:
            f.write(config_content)

        ConfigsRegistrar.save_model(config_api)

        return config_api
Example #6
0
def validate_action(action_api, runner_type_db=None):
    """
    :param runner_type_db: RunnerTypeDB object belonging to this action. If not provided, it's
                           retrieved from the database.
    :type runner_type_db: :class:`RunnerTypeDB`
    """
    if not runner_type_db:
        runner_db = get_runner_model(action_api)
    else:
        runner_db = runner_type_db

    # Check if pack is valid.
    if not _is_valid_pack(action_api.pack):
        packs_base_paths = get_packs_base_paths()
        packs_base_paths = ",".join(packs_base_paths)
        msg = (
            'Content pack "%s" is not found or doesn\'t contain actions directory. '
            "Searched in: %s" % (action_api.pack, packs_base_paths)
        )
        raise ValueValidationException(msg)

    # Check if parameters defined are valid.
    action_ref = ResourceReference.to_string_reference(
        pack=action_api.pack, name=action_api.name
    )
    _validate_parameters(action_ref, action_api.parameters, runner_db.runner_parameters)
Example #7
0
def validate_action(action_api):
    runner_db = None
    # Check if runner exists.
    try:
        runner_db = get_runnertype_by_name(action_api.runner_type)
    except StackStormDBObjectNotFoundError:
        msg = 'RunnerType %s is not found.' % action_api.runner_type
        raise ValueValidationException(msg)

    # Check if pack is valid.
    if not _is_valid_pack(action_api.pack):
        msg = 'Content pack %s does not exist in %s.' % (
            action_api.pack, cfg.CONF.content.packs_base_path)
        raise ValueValidationException(msg)

    # Check if parameters defined are valid.
    _validate_parameters(action_api.parameters, runner_db.runner_parameters)
Example #8
0
    def _schedule_execution(self,
                            liveaction,
                            user=None,
                            context_string=None,
                            show_secrets=False):
        # Initialize execution context if it does not exist.
        if not hasattr(liveaction, 'context'):
            liveaction.context = dict()

        liveaction.context['user'] = user
        LOG.debug('User is: %s' % liveaction.context['user'])

        # Retrieve other st2 context from request header.
        if context_string:
            context = try_loads(context_string)
            if not isinstance(context, dict):
                raise ValueError(
                    'Unable to convert st2-context from the headers into JSON.'
                )
            liveaction.context.update(context)

        # Schedule the action execution.
        liveaction_db = LiveActionAPI.to_model(liveaction)
        liveaction_db, actionexecution_db = action_service.create_request(
            liveaction_db)

        action_db = action_utils.get_action_by_ref(liveaction_db.action)
        runnertype_db = action_utils.get_runnertype_by_name(
            action_db.runner_type['name'])

        try:
            liveaction_db.parameters = param_utils.render_live_params(
                runnertype_db.runner_parameters, action_db.parameters,
                liveaction_db.parameters, liveaction_db.context)
        except ParamException:
            # By this point the execution is already in the DB therefore need to mark it failed.
            _, e, tb = sys.exc_info()
            action_service.update_status(liveaction=liveaction_db,
                                         new_status=LIVEACTION_STATUS_FAILED,
                                         result={
                                             'error':
                                             str(e),
                                             'traceback':
                                             ''.join(
                                                 traceback.format_tb(tb, 20))
                                         })
            # Might be a good idea to return the actual ActionExecution rather than bubble up
            # the execption.
            raise ValueValidationException(str(e))

        liveaction_db = LiveAction.add_or_update(liveaction_db, publish=False)

        _, actionexecution_db = action_service.publish_request(
            liveaction_db, actionexecution_db)
        execution_api = ActionExecutionAPI.from_model(
            actionexecution_db, mask_secrets=(not show_secrets))

        return Response(json=execution_api, status=http_client.CREATED)
Example #9
0
def _get_runner_model(action_api):
    runner_db = None
    # Check if runner exists.
    try:
        runner_db = get_runnertype_by_name(action_api.runner_type)
    except StackStormDBObjectNotFoundError:
        msg = 'RunnerType %s is not found.' % action_api.runner_type
        raise ValueValidationException(msg)
    return runner_db
Example #10
0
def validate_criteria(criteria):
    if not isinstance(criteria, dict):
        raise ValueValidationException("Criteria should be a dict.")

    for key, value in six.iteritems(criteria):
        operator = value.get("type", None)
        if operator is None:
            raise ValueValidationException(
                "Operator not specified for field: " + key)
        if operator not in allowed_operators:
            raise ValueValidationException(
                "For field: " + key + ", operator " + operator +
                " not in list of allowed operators: " +
                str(list(allowed_operators.keys())))
        pattern = value.get("pattern", None)
        if pattern is None:
            raise ValueValidationException("For field: " + key +
                                           ", no pattern specified " +
                                           "for operator " + operator)
Example #11
0
def validate_action(action_api):
    runner_db = _get_runner_model(action_api)

    # Check if pack is valid.
    if not _is_valid_pack(action_api.pack):
        msg = 'Content pack "%s" doesn\'t exist in any of the packs paths' % (action_api.pack)
        raise ValueValidationException(msg)

    # Check if parameters defined are valid.
    _validate_parameters(action_api.parameters, runner_db.runner_parameters)
Example #12
0
def _validate_position_values_contiguous(position_params):
    if not position_params:
        return True

    positions = sorted(position_params.keys())
    contiguous = positions == list(range(min(positions), max(positions) + 1))

    if not contiguous:
        msg = "Positions supplied %s for parameters are not contiguous." % positions
        raise ValueValidationException(msg)

    return True
Example #13
0
def validate_config_against_schema(config_schema,
                                   config_object,
                                   config_path,
                                   pack_name=None):
    """
    Validate provided config dictionary against the provided config schema
    dictionary.
    """
    # NOTE: Lazy improt to avoid performance overhead of importing this module when it's not used
    import jsonschema

    pack_name = pack_name or "unknown"

    schema = util_schema.get_schema_for_resource_parameters(
        parameters_schema=config_schema, allow_additional_properties=True)
    instance = config_object

    try:
        cleaned = util_schema.validate(
            instance=instance,
            schema=schema,
            cls=util_schema.CustomValidator,
            use_default=True,
            allow_default_none=True,
        )
        for key in cleaned:
            if (jinja_utils.is_jinja_expression(value=cleaned.get(key))
                    and "decrypt_kv" in cleaned.get(key)
                    and config_schema.get(key).get("secret")):
                raise ValueValidationException(
                    'Values specified as "secret: True" in config '
                    "schema are automatically decrypted by default. Use "
                    'of "decrypt_kv" jinja filter is not allowed for '
                    "such values. Please check the specified values in "
                    "the config or the default values in the schema.")
    except jsonschema.ValidationError as e:
        attribute = getattr(e, "path", [])

        if isinstance(attribute, (tuple, list, Iterable)):
            attribute = [str(item) for item in attribute]
            attribute = ".".join(attribute)
        else:
            attribute = str(attribute)

        msg = 'Failed validating attribute "%s" in config for pack "%s" (%s): %s' % (
            attribute,
            pack_name,
            config_path,
            six.text_type(e),
        )
        raise jsonschema.ValidationError(msg)

    return cleaned
Example #14
0
def get_runner_model(action_api):
    runner_db = None
    # Check if runner exists.
    try:
        runner_db = get_runnertype_by_name(action_api.runner_type)
    except StackStormDBObjectNotFoundError:
        msg = (
            'RunnerType %s is not found. If you are using old and deprecated runner name, you '
            'need to switch to a new one. For more information, please see '
            'https://docs.stackstorm.com/upgrade_notes.html#st2-v0-9' %
            (action_api.runner_type))
        raise ValueValidationException(msg)
    return runner_db
Example #15
0
def validate_action(action_api):
    runner_db = _get_runner_model(action_api)

    # Check if pack is valid.
    if not _is_valid_pack(action_api.pack):
        packs_base_paths = get_packs_base_paths()
        packs_base_paths = ','.join(packs_base_paths)
        msg = (
            'Content pack "%s" is not found or doesn\'t contain actions directory. '
            'Searched in: %s' % (action_api.pack, packs_base_paths))
        raise ValueValidationException(msg)

    # Check if parameters defined are valid.
    _validate_parameters(action_api.parameters, runner_db.runner_parameters)
Example #16
0
def _validate_parameters(action_ref, action_params=None, runner_params=None):
    for action_param, action_param_meta in six.iteritems(action_params):
        # Check if overridden runner parameters are permitted.
        if action_param in runner_params:
            for action_param_attr, value in six.iteritems(action_param_meta):
                util_schema.validate_runner_parameter_attribute_override(
                    action_ref, action_param, action_param_attr, value,
                    runner_params[action_param].get(action_param_attr))

        if 'immutable' in action_param_meta:
            if action_param in runner_params:
                runner_param_meta = runner_params[action_param]
                if 'immutable' in runner_param_meta:
                    msg = 'Param %s is declared immutable in runner. ' % action_param + \
                          'Cannot override in action.'
                    raise ValueValidationException(msg)
                if 'default' not in action_param_meta and 'default' not in runner_param_meta:
                    msg = 'Immutable param %s requires a default value.' % action_param
                    raise ValueValidationException(msg)
            else:
                if 'default' not in action_param_meta:
                    msg = 'Immutable param %s requires a default value.' % action_param
                    raise ValueValidationException(msg)
Example #17
0
def _validate_parameters(action_ref, action_params=None, runner_params=None):
    position_params = {}
    for action_param, action_param_meta in six.iteritems(action_params):
        # Check if overridden runner parameters are permitted.
        if action_param in runner_params:
            for action_param_attr, value in six.iteritems(action_param_meta):
                util_schema.validate_runner_parameter_attribute_override(
                    action_ref, action_param, action_param_attr, value,
                    runner_params[action_param].get(action_param_attr))

        if 'position' in action_param_meta:
            pos = action_param_meta['position']
            param = position_params.get(pos, None)
            if param:
                msg = ('Parameters %s and %s have same position %d.' %
                       (action_param, param, pos) +
                       ' Position values have to be unique.')
                raise ValueValidationException(msg)
            else:
                position_params[pos] = action_param

        if 'immutable' in action_param_meta:
            if action_param in runner_params:
                runner_param_meta = runner_params[action_param]
                if 'immutable' in runner_param_meta:
                    msg = 'Param %s is declared immutable in runner. ' % action_param + \
                          'Cannot override in action.'
                    raise ValueValidationException(msg)
                if 'default' not in action_param_meta and 'default' not in runner_param_meta:
                    msg = 'Immutable param %s requires a default value.' % action_param
                    raise ValueValidationException(msg)
            else:
                if 'default' not in action_param_meta:
                    msg = 'Immutable param %s requires a default value.' % action_param
                    raise ValueValidationException(msg)

    return _validate_position_values_contiguous(position_params)
def validate_not_part_of_system_pack(resource_db):
    """
    Validate that the provided resource database object doesn't belong to
    a system level pack.

    If it does, ValueValidationException is thrown.

    :param resource_db: Resource database object to check.
    :type resource_db: ``object``
    """
    pack = getattr(resource_db, 'pack', None)

    if pack == SYSTEM_PACK_NAME:
        msg = 'Resources belonging to system level packs can\'t be manipulated'
        raise ValueValidationException(msg)

    return resource_db
Example #19
0
    def _schedule_execution(self, liveaction):
        # Initialize execution context if it does not exist.
        if not hasattr(liveaction, 'context'):
            liveaction.context = dict()

        liveaction.context['user'] = get_requester()
        LOG.debug('User is: %s' % liveaction.context['user'])

        # Retrieve other st2 context from request header.
        if 'st2-context' in pecan.request.headers and pecan.request.headers[
                'st2-context']:
            context = jsonify.try_loads(pecan.request.headers['st2-context'])
            if not isinstance(context, dict):
                raise ValueError(
                    'Unable to convert st2-context from the headers into JSON.'
                )
            liveaction.context.update(context)

        # Schedule the action execution.
        liveaction_db = LiveActionAPI.to_model(liveaction)
        liveaction_db, actionexecution_db = action_service.create_request(
            liveaction_db)

        action_db = action_utils.get_action_by_ref(liveaction_db.action)
        runnertype_db = action_utils.get_runnertype_by_name(
            action_db.runner_type['name'])

        try:
            liveaction_db.parameters = param_utils.render_live_params(
                runnertype_db.runner_parameters, action_db.parameters,
                liveaction_db.parameters, liveaction_db.context)
        except ParamException as e:
            raise ValueValidationException(str(e))

        liveaction_db = LiveAction.add_or_update(liveaction_db, publish=False)

        _, actionexecution_db = action_service.publish_request(
            liveaction_db, actionexecution_db)
        from_model_kwargs = self._get_from_model_kwargs_for_request(
            request=pecan.request)
        return ActionExecutionAPI.from_model(actionexecution_db,
                                             from_model_kwargs)
Example #20
0
def validate_not_part_of_system_pack_by_name(pack_name):
    if pack_name in SYSTEM_PACK_NAMES:
        msg = "Resources belonging to system level packs can't be manipulated"
        raise ValueValidationException(msg)