예제 #1
0
    def _check_args(self):
        """Ensure specific args are set

        :return: None: In case all arguments passed are valid
        """
        try:
            if isinstance(self._data, string_types):
                self._data = json.loads(self._data)
            else:
                self._data = json.loads(json.dumps(self._data))

        except (TypeError, JSONDecodeError) as exe:
            msg = ("'data' option value is invalid, value should a valid JSON."
                   " Failed to read with error '{err}'".format(
                       err=to_text(exe, errors="surrogate_then_replace")))
            raise AnsibleError(msg)

        try:
            criteria = []
            for item in to_list(self._criteria):
                if isinstance(self._criteria, string_types):
                    criteria.append(json.loads(item))
                else:
                    criteria.append(json.loads(json.dumps(item)))

            self._criteria = criteria
        except (TypeError, JSONDecodeError) as exe:
            msg = (
                "'criteria' option value is invalid, value should a valid JSON."
                " Failed to read with error '{err}'".format(
                    err=to_text(exe, errors="surrogate_then_replace")))
            raise AnsibleError(msg)
예제 #2
0
def validate(*args, **kwargs):
    if not len(args):
        raise AnsibleError(
            "Missing either 'data' value in test plugin input,"
            "refer ansible.utils.validate test plugin documentation for details"
        )

    params = {"data": args[0]}

    for item in ["engine", "criteria"]:
        if kwargs.get(item):
            params.update({item: kwargs[item]})

    valid, argspec_result, updated_params = check_argspec(
        DOCUMENTATION,
        "validate test",
        schema_conditionals=ARGSPEC_CONDITIONALS,
        **params)
    if not valid:
        raise AnsibleError(
            "{argspec_result} with errors: {argspec_errors}".format(
                argspec_result=argspec_result.get("msg"),
                argspec_errors=argspec_result.get("errors"),
            ))

    validator_engine, validator_result = load_validator(
        engine=updated_params["engine"],
        data=updated_params["data"],
        criteria=updated_params["criteria"],
        kwargs=kwargs,
    )
    if validator_result.get("failed"):
        raise AnsibleError("validate lookup plugin failed with errors: %s" %
                           validator_result.get("msg"))

    try:
        result = validator_engine.validate()
    except AnsibleError as exc:
        raise AnsibleError(to_text(exc, errors="surrogate_then_replace"))
    except Exception as exc:
        raise AnsibleError(
            "Unhandled exception from validator '{validator}'. Error: {err}".
            format(
                validator=updated_params["engine"],
                err=to_text(exc, errors="surrogate_then_replace"),
            ))

    errors = to_list(result.get("errors", []))
    if len(errors):
        return False

    return True
예제 #3
0
    def run(self, terms, variables, **kwargs):
        if len(terms) < 2:
            raise AnsibleLookupError(
                "missing either 'data' or 'criteria' value in lookup input,"
                " refer ansible.utils.validate lookup plugin documentation for details"
            )

        params = {"data": terms[0], "criteria": terms[1]}
        if kwargs.get("engine"):
            params.update({"engine": kwargs["engine"]})

        valid, argspec_result, updated_params = check_argspec(
            DOCUMENTATION,
            "validate lookup",
            schema_conditionals=ARGSPEC_CONDITIONALS,
            **params)
        if not valid:
            raise AnsibleLookupError(
                "{argspec_result} with errors: {argspec_errors}".format(
                    argspec_result=argspec_result.get("msg"),
                    argspec_errors=argspec_result.get("errors"),
                ))

        validator_engine, validator_result = load_validator(
            engine=updated_params["engine"],
            data=updated_params["data"],
            criteria=updated_params["criteria"],
            plugin_vars=variables,
            kwargs=kwargs,
        )
        if validator_result.get("failed"):
            raise AnsibleLookupError(
                "validate lookup plugin failed with errors: {validator_result}"
                .format(validator_result=validator_result.get("msg")))

        try:
            result = validator_engine.validate()
        except AnsibleError as exc:
            raise AnsibleLookupError(
                to_text(exc, errors="surrogate_then_replace"))
        except Exception as exc:
            raise AnsibleLookupError(
                "Unhandled exception from validator '{validator}'. Error: {err}"
                .format(
                    validator=updated_params["engine"],
                    err=to_text(exc, errors="surrogate_then_replace"),
                ))

        return to_list(result.get("errors", []))
예제 #4
0
    def _check_args(self):
        """Ensure specific args are set

        :return: None: In case all arguments passed are valid
        """

        try:
            if isinstance(self._criteria, string_types):
                self._criteria = yaml.load(str(self._criteria),
                                           Loader=SafeLoader)
        except yaml.parser.ParserError as exc:
            msg = (
                "'criteria' option value is invalid, value should be valid YAML."
                " Failed to read with error '{err}'".format(
                    err=to_text(exc, errors="surrogate_then_replace")))
            raise AnsibleError(msg)

        issues = []
        for item in to_list(self._criteria):
            if "name" not in item:
                issues.append(
                    'Criteria {item} missing "name" key'.format(item=item))
            if "action" not in item:
                issues.append(
                    'Criteria {item} missing "action" key'.format(item=item))
            elif item["action"] not in ("warn", "fail"):
                issues.append(
                    'Action in criteria {item} is not one of "warn" or "fail"'.
                    format(item=item))
            if "rule" not in item:
                issues.append(
                    'Criteria {item} missing "rule" key'.format(item=item))
            else:
                try:
                    item["rule"] = re.compile(item["rule"])
                except re.error as exc:
                    issues.append(
                        'Failed to compile regex "{rule}": {exc}'.format(
                            rule=item["rule"], exc=exc))

        if issues:
            msg = "\n".join(issues)
            raise AnsibleError(msg)
예제 #5
0
    def _check_args(self):
        """Ensure specific args are set

        :return: None: In case all arguments passed are valid
        """
        try:
            if isinstance(self._data, dict):
                self._data = json.loads(json.dumps(self._data))
            elif isinstance(self._data, string_types):
                self._data = json.loads(self._data)
            else:
                msg = "Expected value of 'data' option is either dict or str, received type '{data_type}'".format(
                    data_type=type(self._data))
                raise AnsibleError(msg)

        except (TypeError, JSONDecodeError) as exe:
            msg = (
                "'data' option value is invalid, value should of type dict or str format of dict."
                " Failed to read with error '{err}'".format(
                    err=to_text(exe, errors="surrogate_then_replace")))
            raise AnsibleError(msg)

        try:
            criteria = []
            for item in to_list(self._criteria):
                if isinstance(item, dict):
                    criteria.append(json.loads(json.dumps(item)))
                elif isinstance(self._criteria, string_types):
                    criteria.append(json.loads(item))
                else:
                    msg = "Expected value of 'criteria' option is either list of dict/str or dict or str, received type '{criteria_type}'".format(
                        criteria_type=type(criteria))
                    raise AnsibleError(msg)

            self._criteria = criteria
        except (TypeError, JSONDecodeError) as exe:
            msg = (
                "'criteria' option value is invalid, value should of type dict or str format of dict."
                " Failed to read with error '{err}'".format(
                    err=to_text(exe, errors="surrogate_then_replace")))
            raise AnsibleError(msg)
예제 #6
0
    def _set_sub_plugin_options(self, doc):
        params = {}
        try:
            argspec_obj = yaml.load(doc, SafeLoader)
        except Exception as exc:
            raise AnsibleError(
                "Error '{err}' while reading validate plugin {engine} documentation: '{argspec}'"
                .format(
                    err=to_text(exc, errors="surrogate_or_strict"),
                    engine=self._engine,
                    argspec=doc,
                ))
        options = argspec_obj.get("options", {})

        if not options:
            return None

        for option_name, option_value in iteritems(options):

            option_var_name_list = option_value.get("vars", [])
            option_env_name_list = option_value.get("env", [])

            # check if plugin configuration option passed as kwargs
            # valid for lookup, filter, test plugins or pass through
            # variables if supported by the module.
            if option_name in self._kwargs:
                params[option_name] = self._kwargs[option_name]
                continue

            # check if plugin configuration option passed in task vars eg.
            #  vars:
            #  - name: ansible_validate_jsonschema_draft
            #  - name: ansible_validate_jsonschema_draft_type
            if option_var_name_list and (option_name not in params):
                for var_name_entry in to_list(option_var_name_list):
                    if not isinstance(var_name_entry, dict):
                        raise AnsibleError(
                            "invalid type '{var_name_type}' for the value of '{var_name_entry}' option,"
                            " should to be type dict".format(
                                var_name_type=type(var_name_entry),
                                var_name_entry=var_name_entry,
                            ))
                    var_name = var_name_entry.get("name")
                    if var_name and var_name in self._plugin_vars:
                        params[option_name] = self._plugin_vars[var_name]
                        break

            # check if plugin configuration option as passed as enviornment  eg.
            # env:
            # - name: ANSIBLE_VALIDATE_JSONSCHEMA_DRAFT
            if option_env_name_list and (option_name not in params):
                for env_name_entry in to_list(option_env_name_list):
                    if not isinstance(env_name_entry, dict):
                        raise AnsibleError(
                            "invalid type '{env_name_entry_type}' for the value of '{env_name_entry}' option,"
                            " should to be type dict".format(
                                env_name_entry_type=type(env_name_entry),
                                env_name_entry=env_name_entry,
                            ))
                    env_name = env_name_entry.get("name")
                    if env_name in os.environ:
                        params[option_name] = os.environ[env_name]
                        break

        valid, argspec_result, updated_params = check_argspec(
            yaml.dump(argspec_obj), self._engine, **params)
        if not valid:
            raise AnsibleError(
                "{argspec_result} with errors: {argspec_errors}".format(
                    argspec_result=argspec_result.get("msg"),
                    argspec_errors=argspec_result.get("errors"),
                ))

        if updated_params:
            self._sub_plugin_options = updated_params