コード例 #1
0
ファイル: validate.py プロジェクト: aiziyuer/home-ansible
    def run(self, tmp=None, task_vars=None):
        """The std execution entry pt for an action plugin

        :param tmp: no longer used
        :type tmp: none
        :param task_vars: The vars provided when the task is run
        :type task_vars: dict
        :return: The results from the parser
        :rtype: dict
        """
        valid, argspec_result, updated_params = check_argspec(
            DOCUMENTATION,
            "validate module",
            schema_conditionals=ARGSPEC_CONDITIONALS,
            **self._task.args
        )
        if not valid:
            return argspec_result

        self._task_vars = task_vars
        self._playhost = (
            task_vars.get("inventory_hostname") if task_vars else None
        )

        self._validator_engine, validator_result = _load_validator(
            engine=updated_params["engine"],
            data=updated_params["data"],
            criteria=updated_params["criteria"],
            plugin_vars=task_vars,
        )
        if validator_result.get("failed"):
            return validator_result

        try:
            result = self._validator_engine.validate()
        except AnsibleError as exc:
            raise AnsibleActionFail(
                to_text(exc, errors="surrogate_then_replace")
            )
        except Exception as exc:
            raise AnsibleActionFail(
                "Unhandled exception from validator '{validator}'. Error: {err}".format(
                    validator=self._validator_engine,
                    err=to_text(exc, errors="surrogate_then_replace"),
                )
            )

        if result.get("errors"):
            self._result["errors"] = result["errors"]
            self._result.update({"failed": True})
            if "msg" in result:
                self._result["msg"] = (
                    "Validation errors were found.\n" + result["msg"]
                )
            else:
                self._result["msg"] = "Validation errors were found."
        else:
            self._result["msg"] = "all checks passed"
        return self._result
コード例 #2
0
ファイル: validate.py プロジェクト: samccann/ansible.utils
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 test_fn_check_argspec_fail_no_parser_name(self):
     """ Confirm failed argspec no parser name
     """
     kwargs = {"text": "anything", "parser": {"command": "show version"}}
     valid, result, updated_params = check_argspec(
         DOCUMENTATION,
         "cli_parse module",
         schema_conditionals=ARGSPEC_CONDITIONALS,
         **kwargs)
     self.assertEqual(
         "missing required arguments: name found in parser",
         result["errors"],
     )
コード例 #4
0
 def test_fn_check_argspec_pass(self):
     """Confirm a valid argspec passes"""
     kwargs = {
         "text": "text",
         "parser": {
             "name": "ansible.utils.textfsm",
             "command": "show version",
         },
     }
     valid, result, updated_params = check_argspec(DOCUMENTATION,
                                                   "cli_parse module",
                                                   schema_conditionals={},
                                                   **kwargs)
     self.assertEqual(valid, True)
コード例 #5
0
 def test_fn_check_argspec_fail_no_parser_name(self):
     """Confirm failed argspec no parser name"""
     kwargs = {"text": "anything", "parser": {"command": "show version"}}
     valid, result, updated_params = check_argspec(
         DOCUMENTATION,
         "cli_parse module",
         schema_conditionals=ARGSPEC_CONDITIONALS,
         **kwargs)
     # NOTE: Ansible 2.11+ returns result["errors"] as a list
     error_msg = "missing required arguments: name found in parser"
     if isinstance(result["errors"], list):
         self.assertIn(error_msg, result["errors"])
     else:
         self.assertEqual(error_msg, result["errors"])
コード例 #6
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", []))
コード例 #7
0
def _validate_args(plugin, doc, params):
    """ argspec validator utility function
    """

    valid, argspec_result, updated_params = check_argspec(
        doc, plugin + " test", **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"),
            )
        )
コード例 #8
0
def param_list_compare(*args, **kwargs):
    params = ["base", "target"]
    data = dict(zip(params, args))
    data.update(kwargs)

    if len(data) < 2:
        raise AnsibleFilterError(
            "Missing either 'base' or 'other value in filter input,"
            "refer 'ansible.utils.param_list_compare' filter plugin documentation for details"
        )

    valid, argspec_result, updated_params = check_argspec(
        DOCUMENTATION,
        "param_list_compare filter",
        schema_conditionals=ARGSPEC_CONDITIONALS,
        **data
    )
    if not valid:
        raise AnsibleFilterError(
            "{argspec_result} with errors: {argspec_errors}".format(
                argspec_result=argspec_result.get("msg"),
                argspec_errors=argspec_result.get("errors"),
            )
        )
    base = data["base"]
    other = data["target"]
    combined = []
    alls = [x for x in other if x == "all"]
    bangs = [x[1:] for x in other if x.startswith("!")]
    rbangs = [x for x in other if x.startswith("!")]
    remain = [
        x for x in other if x not in alls and x not in rbangs and x in base
    ]
    unsupported = [
        x for x in other if x not in alls and x not in rbangs and x not in base
    ]

    if alls:
        combined = base
    for entry in bangs:
        if entry in combined:
            combined.remove(entry)
    for entry in remain:
        if entry not in combined:
            combined.append(entry)
    combined.sort()
    output = {"actionable": combined, "unsupported": unsupported}
    return output
コード例 #9
0
    def test_fn_check_argspec_fail_no_test_or_command(self):
        """ Confirm failed argpsec w/o text or command
        """
        kwargs = {
            "parser": {
                "name": "ansible.utils.textfsm",
                "command": "show version",
            }
        }
        valid, result, updated_params = check_argspec(
            DOCUMENTATION,
            "cli_parse module",
            schema_conditionals=ARGSPEC_CONDITIONALS,
            **kwargs)

        self.assertEqual("one of the following is required: command, text",
                         result["errors"])
コード例 #10
0
    def test_fn_check_argspec_fail_no_test_or_command(self):
        """Confirm failed argpsec w/o text or command"""
        kwargs = {
            "parser": {
                "name": "ansible.utils.textfsm",
                "command": "show version",
            }
        }
        valid, result, updated_params = check_argspec(
            DOCUMENTATION,
            "cli_parse module",
            schema_conditionals=ARGSPEC_CONDITIONALS,
            **kwargs)

        # NOTE: Ansible 2.11+ returns result["errors"] as a list
        error_msg = "one of the following is required: command, text"
        if isinstance(result["errors"], list):
            self.assertIn(error_msg, result["errors"])
        else:
            self.assertEqual(error_msg, result["errors"])
コード例 #11
0
    def run(self, tmp=None, task_vars=None):
        """ The std execution entry pt for an action plugin

        :param tmp: no longer used
        :type tmp: none
        :param task_vars: The vars provided when the task is run
        :type task_vars: dict
        :return: The results from the parser
        :rtype: dict
        """
        msg = (
            "Use 'ansible.utils.cli_parse' instead of 'ansible.netcommon.cli_parse'."
            " See the plugin documentation for more details."
            " This feature will be removed from ansible.netcommon in a release after 2023-01-01"
        )
        display.deprecated(msg,
                           date="2023-01-01",
                           collection_name="ansible.netcommon")

        valid, argspec_result, updated_params = check_argspec(
            DOCUMENTATION,
            "cli_parse module",
            schema_conditionals=ARGSPEC_CONDITIONALS,
            **self._task.args)
        if not valid:
            return argspec_result

        self._extended_check_argspec()
        if self._result.get("failed"):
            return self._result

        self._task_vars = task_vars
        self._playhost = task_vars.get("inventory_hostname")
        self._parser_name = self._task.args.get("parser").get("name")

        self._run_command()
        if self._result.get("failed"):
            return self._result

        self._set_parser_command()
        self._set_text()

        parser = self._load_parser(task_vars)
        if self._result.get("failed"):
            self._prune_result()
            return self._result

        # Not all parsers use a template, in the case a parser provides
        # an extension, provide it the template path
        if getattr(parser, "DEFAULT_TEMPLATE_EXTENSION", False):
            self._update_template_path(parser.DEFAULT_TEMPLATE_EXTENSION)

        # Not all parsers require the template contents
        # when true, provide the template contents
        if getattr(parser, "PROVIDE_TEMPLATE_CONTENTS", False) is True:
            template_contents = self._get_template_contents()
        else:
            template_contents = None

        try:
            result = parser.parse(template_contents=template_contents)
            # ensure the response returned to the controller
            # contains only native types, nothing unique to the parser
            result = json.loads(json.dumps(result))
        except Exception as exc:
            raise AnsibleActionFail(
                "Unhandled exception from parser '{parser}'. Error: {err}".
                format(parser=self._parser_name, err=to_native(exc)))

        if result.get("errors"):
            self._prune_result()
            self._result.update({
                "failed": True,
                "msg": " ".join(result["errors"])
            })
        else:
            self._result["parsed"] = result["parsed"]
            set_fact = self._task.args.get("set_fact")
            if set_fact:
                self._result["ansible_facts"] = {set_fact: result["parsed"]}
        return self._result
コード例 #12
0
ファイル: _base.py プロジェクト: samccann/ansible.utils
    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