diff options
Diffstat (limited to 'plugins')
10 files changed, 2036 insertions, 4 deletions
| diff --git a/plugins/module_utils/network/vyos/argspec/firewall_interfaces/__init__.py b/plugins/module_utils/network/vyos/argspec/firewall_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/firewall_interfaces/__init__.py diff --git a/plugins/module_utils/network/vyos/argspec/firewall_interfaces/firewall_interfaces.py b/plugins/module_utils/network/vyos/argspec/firewall_interfaces/firewall_interfaces.py new file mode 100644 index 00000000..f0834850 --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/firewall_interfaces/firewall_interfaces.py @@ -0,0 +1,85 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2019 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +#                WARNING                    # +############################################# +# +# This file is auto generated by the resource +#   module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +#   by the resource module builder. +# +# Changes should be made in the model used to +#   generate this file or in the resource module +#   builder template. +# +############################################# +""" +The arg spec for the vyos_firewall_interfaces module +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +class Firewall_interfacesArgs(object):  # pylint: disable=R0903 +    """The arg spec for the vyos_firewall_interfaces module +    """ + +    def __init__(self, **kwargs): +        pass + +    argument_spec = { +        "config": { +            "elements": "dict", +            "options": { +                "access_rules": { +                    "elements": "dict", +                    "options": { +                        "afi": { +                            "choices": ["ipv4", "ipv6"], +                            "required": True, +                            "type": "str", +                        }, +                        "rules": { +                            "elements": "dict", +                            "options": { +                                "direction": { +                                    "choices": ["in", "local", "out"], +                                    "required": True, +                                    "type": "str", +                                }, +                                "name": {"type": "str"}, +                            }, +                            "type": "list", +                        }, +                    }, +                    "type": "list", +                }, +                "name": {"required": True, "type": "str"}, +            }, +            "type": "list", +        }, +        "running_config": {"type": "str"}, +        "state": { +            "choices": [ +                "merged", +                "replaced", +                "overridden", +                "deleted", +                "parsed", +                "rendered", +                "gathered", +            ], +            "default": "merged", +            "type": "str", +        }, +    }  # pylint: disable=C0301 diff --git a/plugins/module_utils/network/vyos/config/firewall_interfaces/__init__.py b/plugins/module_utils/network/vyos/config/firewall_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/plugins/module_utils/network/vyos/config/firewall_interfaces/__init__.py diff --git a/plugins/module_utils/network/vyos/config/firewall_interfaces/firewall_interfaces.py b/plugins/module_utils/network/vyos/config/firewall_interfaces/firewall_interfaces.py new file mode 100644 index 00000000..b436bfad --- /dev/null +++ b/plugins/module_utils/network/vyos/config/firewall_interfaces/firewall_interfaces.py @@ -0,0 +1,455 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2019 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The vyos_firewall_interfaces class +It is in this file where the current configuration (as dict) +is compared to the provided configuration (as dict) and the command set +necessary to bring the current configuration to it's desired end-state is +created +""" +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from copy import deepcopy +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( +    ConfigBase, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( +    to_list, +    dict_diff, +    remove_empties, +    search_obj_in_list, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( +    Facts, +) + + +class Firewall_interfaces(ConfigBase): +    """ +    The vyos_firewall_interfaces class +    """ + +    gather_subset = [ +        "!all", +        "!min", +    ] + +    gather_network_resources = [ +        "firewall_interfaces", +    ] + +    def __init__(self, module): +        super(Firewall_interfaces, self).__init__(module) + +    def get_firewall_interfaces_facts(self, data=None): +        """ Get the 'facts' (the current configuration) + +        :rtype: A dictionary +        :returns: The current configuration as a dictionary +        """ +        facts, _warnings = Facts(self._module).get_facts( +            self.gather_subset, self.gather_network_resources, data=data +        ) +        firewall_interfaces_facts = facts["ansible_network_resources"].get( +            "firewall_interfaces" +        ) +        if not firewall_interfaces_facts: +            return [] +        return firewall_interfaces_facts + +    def execute_module(self): +        """ Execute the module + +        :rtype: A dictionary +        :returns: The result from module execution +        """ +        result = {"changed": False} +        warnings = list() +        commands = list() + +        if self.state in self.ACTION_STATES: +            existing_firewall_interfaces_facts = ( +                self.get_firewall_interfaces_facts() +            ) +        else: +            existing_firewall_interfaces_facts = [] + +        if self.state in self.ACTION_STATES or self.state == "rendered": +            commands.extend( +                self.set_config(existing_firewall_interfaces_facts) +            ) + +        if commands and self.state in self.ACTION_STATES: +            if not self._module.check_mode: +                self._connection.edit_config(commands) +            result["changed"] = True + +        if self.state in self.ACTION_STATES: +            result["commands"] = commands + +        if self.state in self.ACTION_STATES or self.state == "gathered": +            changed_firewall_interfaces_facts = ( +                self.get_firewall_interfaces_facts() +            ) +        elif self.state == "rendered": +            result["rendered"] = commands +        elif self.state == "parsed": +            running_config = self._module.params["running_config"] +            if not running_config: +                self._module.fail_json( +                    msg="value of running_config parameter must not be empty for state parsed" +                ) +            result["parsed"] = self.get_firewall_interfaces_facts( +                data=running_config +            ) +        else: +            changed_firewall_interfaces_facts = [] + +        if self.state in self.ACTION_STATES: +            result["before"] = existing_firewall_interfaces_facts +            if result["changed"]: +                result["after"] = changed_firewall_interfaces_facts +        elif self.state == "gathered": +            result["gathered"] = changed_firewall_interfaces_facts + +        result["warnings"] = warnings +        return result + +    def set_config(self, existing_firewall_interfaces_facts): +        """ Collect the configuration from the args passed to the module, +            collect the current configuration (as a dict from facts) + +        :rtype: A list +        :returns: the commands necessary to migrate the current configuration +                  to the desired configuration +        """ +        want = self._module.params["config"] +        have = existing_firewall_interfaces_facts +        resp = self.set_state(want, have) +        return to_list(resp) + +    def set_state(self, w, h): +        """ Select the appropriate function based on the state provided + +        :param want: the desired configuration as a dictionary +        :param have: the current configuration as a dictionary +        :rtype: A list +        :returns: the commands necessary to migrate the current configuration +                  to the desired configuration +        """ +        commands = [] +        if ( +            self.state in ("merged", "replaced", "overridden", "rendered") +            and not w +        ): +            self._module.fail_json( +                msg="value of config parameter must not be empty for state {0}".format( +                    self.state +                ) +            ) +        if self.state == "overridden": +            commands.extend(self._state_overridden(w, h)) +        elif self.state == "deleted": +            commands.extend(self._state_deleted(w, h)) +        elif w: +            if self.state == "merged" or self.state == "rendered": +                commands.extend(self._state_merged(w, h)) +            elif self.state == "replaced": +                commands.extend(self._state_replaced(w, h)) +        return commands + +    def _state_replaced(self, want, have): +        """ The command generator when state is replaced + +        :rtype: A list +        :returns: the commands necessary to migrate the current configuration +                  to the desired configuration +        """ +        commands = [] +        if have: +            for h in have: +                w = search_obj_in_list(h["name"], want) +                commands.extend(self._render_access_rules(h, w, opr=False)) +        commands.extend(self._state_merged(want, have)) +        return commands + +    def _state_overridden(self, want, have): +        """ The command generator when state is overridden + +        :rtype: A list +        :returns: the commands necessary to migrate the current configuration +                  to the desired configuration +        """ +        commands = [] +        if have: +            for h_ar in have: +                w_ar = search_obj_in_list(h_ar["name"], want) +                if not w_ar and "access_rules" in h_ar: +                    commands.append( +                        self._compute_command(name=h_ar["name"], opr=False) +                    ) +                else: +                    h_rules = h_ar.get("access_rules") or [] +                    key = "direction" +                    if w_ar: +                        w_rules = w_ar.get("access_rules") or [] +                        if not w_rules and h_rules: +                            commands.append( +                                self._compute_command( +                                    name=h_ar["name"], opr=False +                                ) +                            ) +                    if h_rules: +                        for h_rule in h_rules: +                            w_rule = search_obj_in_list( +                                h_rule["afi"], w_rules, key="afi" +                            ) +                            have_rules = h_rule.get("rules") or [] +                            if w_rule: +                                want_rules = w_rule.get("rules") or [] +                            for h in have_rules: +                                if key in h: +                                    w = search_obj_in_list( +                                        h[key], want_rules, key=key +                                    ) +                                    if ( +                                        not w +                                        or key not in w +                                        or ( +                                            "name" in h +                                            and w +                                            and "name" not in w +                                        ) +                                    ): +                                        commands.append( +                                            self._compute_command( +                                                afi=h_rule["afi"], +                                                name=h_ar["name"], +                                                attrib=h[key], +                                                opr=False, +                                            ) +                                        ) + +        commands.extend(self._state_merged(want, have)) +        return commands + +    def _state_merged(self, want, have): +        """ The command generator when state is merged + +        :rtype: A list +        :returns: the commands necessary to merge the provided into +                  the current configuration +        """ +        commands = [] +        for w in want: +            h = search_obj_in_list(w["name"], have) +            commands.extend(self._render_access_rules(w, h)) +        return commands + +    def _state_deleted(self, want, have): +        """ The command generator when state is deleted + +        :rtype: A list +        :returns: the commands necessary to remove the current configuration +                  of the provided objects +        """ +        commands = [] + +        if want: +            for w in want: +                h = search_obj_in_list(w["name"], have) +                if h and "access_rules" in h: +                    commands.extend(self._delete_access_rules(w, h, opr=False)) +        elif have: +            for h in have: +                if "access_rules" in h: +                    commands.append( +                        self._compute_command(name=h["name"], opr=False) +                    ) +        return commands + +    def _delete_access_rules(self, want, have, opr=False): +        """ +        This function forms the delete commands based on the 'opr' type +        for 'access_rules' attributes. +        :param want: desired config. +        :param have: target config. +        :param opr: True/False. +        :return: generated commands list. +        """ +        commands = [] +        h_rules = {} +        w_rs = deepcopy(remove_empties(want)) +        w_rules = w_rs.get("access_rules") or [] +        if have: +            h_rs = deepcopy(remove_empties(have)) +            h_rules = h_rs.get("access_rules") or [] + +        # if all firewall config needed to be deleted for specific interface +        # when operation is delete. +        if not w_rules and h_rules: +            commands.append(self._compute_command(name=want["name"], opr=opr)) +        if w_rules: +            for w in w_rules: +                h = search_obj_in_list(w["afi"], h_rules, key="afi") +                commands.extend(self._delete_rules(want["name"], w, h)) +        return commands + +    def _delete_rules(self, name, want, have, opr=False): +        """ +        This function forms the delete commands based on the 'opr' type +        for rules attributes. +        :param name: interface id/name. +        :param want: desired config. +        :param have: target config. +        :param opr: True/False. +        :return: generated commands list. +        """ +        commands = [] +        h_rules = [] +        key = "direction" +        w_rules = want.get("rules") or [] +        if have: +            h_rules = have.get("rules") or [] +        # when rule set needed to be removed on +        # (inbound|outbound|local interface) +        if h_rules and not w_rules: +            for h in h_rules: +                if key in h: +                    commands.append( +                        self._compute_command( +                            afi=want["afi"], name=name, attrib=h[key], opr=opr +                        ) +                    ) +        for w in w_rules: +            h = search_obj_in_list(w[key], h_rules, key=key) +            if ( +                key in w +                and h +                and key in h +                and "name" in w +                and "name" in h +                and w["name"] == h["name"] +            ): +                commands.append( +                    self._compute_command( +                        afi=want["afi"], +                        name=name, +                        attrib=w[key], +                        value=w["name"], +                        opr=opr, +                    ) +                ) +        return commands + +    def _render_access_rules(self, want, have, opr=True): +        """ +        This function forms the set/delete commands based on the 'opr' type +        for 'access_rules' attributes. +        :param want: desired config. +        :param have: target config. +        :param opr: True/False. +        :return: generated commands list. +        """ +        commands = [] +        h_rules = {} +        w_rs = deepcopy(remove_empties(want)) +        w_rules = w_rs.get("access_rules") or [] +        if have: +            h_rs = deepcopy(remove_empties(have)) +            h_rules = h_rs.get("access_rules") or [] +        if w_rules: +            for w in w_rules: +                h = search_obj_in_list(w["afi"], h_rules, key="afi") +                commands.extend(self._render_rules(want["name"], w, h, opr)) +        return commands + +    def _render_rules(self, name, want, have, opr=True): +        """ +        This function forms the set/delete commands based on the 'opr' type +        for rules attributes. +        :param name: interface id/name. +        :param want: desired config. +        :param have: target config. +        :param opr: True/False. +        :return: generated commands list. +        """ +        commands = [] +        h_rules = [] +        key = "direction" +        w_rules = want.get("rules") or [] +        if have: +            h_rules = have.get("rules") or [] +        for w in w_rules: +            h = search_obj_in_list(w[key], h_rules, key=key) +            if key in w: +                if opr: +                    if "name" in w and not ( +                        h and h[key] == w[key] and h["name"] == w["name"] +                    ): +                        commands.append( +                            self._compute_command( +                                afi=want["afi"], +                                name=name, +                                attrib=w[key], +                                value=w["name"], +                            ) +                        ) +                    elif not (h and key in h): +                        commands.append( +                            self._compute_command( +                                afi=want["afi"], name=name, attrib=w[key] +                            ) +                        ) +                elif not opr: +                    if ( +                        not h +                        or key not in h +                        or ("name" in w and h and "name" not in h) +                    ): +                        commands.append( +                            self._compute_command( +                                afi=want["afi"], +                                name=name, +                                attrib=w[key], +                                opr=opr, +                            ) +                        ) +        return commands + +    def _compute_command( +        self, afi=None, name=None, attrib=None, value=None, opr=True +    ): +        """ +        This function construct the add/delete command based on passed attributes. +        :param afi:  address type. +        :param name: interface name. +        :param attrib: attribute name. +        :param value: attribute value. +        :param opr: operation flag. +        :return: generated command. +        """ +        if not opr: +            cmd = "delete interfaces ethernet" + " " + name + " firewall" +        else: +            cmd = "set interfaces ethernet" + " " + name + " firewall" +        if attrib: +            cmd += " " + attrib +        if afi: +            cmd += " " + self._get_fw_type(afi) +        if value: +            cmd += " '" + str(value) + "'" +        return cmd + +    def _get_fw_type(self, afi): +        """ +        This function returns the firewall rule-set type based on IP address. +        :param afi: address type +        :return: rule-set type. +        """ +        return "ipv6-name" if afi == "ipv6" else "name" diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py index 6e6a82be..ff3d0988 100644 --- a/plugins/module_utils/network/vyos/facts/facts.py +++ b/plugins/module_utils/network/vyos/facts/facts.py @@ -9,6 +9,7 @@ calls the appropriate facts gathering function  from __future__ import absolute_import, division, print_function  __metaclass__ = type +  from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts import (      FactsBase,  ) @@ -36,6 +37,9 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.stati  from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firewall_global.firewall_global import (      Firewall_globalFacts,  ) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firewall_interfaces.firewall_interfaces import ( +    Firewall_interfacesFacts, +)  from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import (      Default,      Neighbors, @@ -53,6 +57,7 @@ FACT_RESOURCE_SUBSETS = dict(      static_routes=Static_routesFacts,      firewall_rules=Firewall_rulesFacts,      firewall_global=Firewall_globalFacts, +    firewall_interfaces=Firewall_interfacesFacts,  ) diff --git a/plugins/module_utils/network/vyos/facts/firewall_interfaces/__init__.py b/plugins/module_utils/network/vyos/facts/firewall_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/firewall_interfaces/__init__.py diff --git a/plugins/module_utils/network/vyos/facts/firewall_interfaces/firewall_interfaces.py b/plugins/module_utils/network/vyos/facts/firewall_interfaces/firewall_interfaces.py new file mode 100644 index 00000000..46407486 --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/firewall_interfaces/firewall_interfaces.py @@ -0,0 +1,196 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2019 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The vyos firewall_interfaces fact class +It is in this file the configuration is collected from the device +for a given resource, parsed, and the facts tree is populated +based on the configuration. +""" +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from re import findall, search, M +from copy import deepcopy +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( +    utils, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.firewall_interfaces.firewall_interfaces import ( +    Firewall_interfacesArgs, +) + + +class Firewall_interfacesFacts(object): +    """ The vyos firewall_interfaces fact class +    """ + +    def __init__(self, module, subspec="config", options="options"): +        self._module = module +        self.argument_spec = Firewall_interfacesArgs.argument_spec +        spec = deepcopy(self.argument_spec) +        if subspec: +            if options: +                facts_argument_spec = spec[subspec][options] +            else: +                facts_argument_spec = spec[subspec] +        else: +            facts_argument_spec = spec + +        self.generated_spec = utils.generate_dict(facts_argument_spec) + +    def get_device_data(self, connection): +        return connection.get_config() + +    def populate_facts(self, connection, ansible_facts, data=None): +        """ Populate the facts for firewall_interfaces +        :param connection: the device connection +        :param ansible_facts: Facts dictionary +        :param data: previously collected conf +        :rtype: dictionary +        :returns: facts +        """ +        if not data: +            # typically data is populated from the current device configuration +            # data = connection.get('show running-config | section ^interface') +            # using mock data instead +            data = self.get_device_data(connection) +        objs = [] +        interfaces = findall( +            r"^set interfaces ethernet (?:\'*)(\S+)(?:\'*)", data, M +        ) +        if interfaces: +            objs = self.get_names(data, interfaces) +        ansible_facts["ansible_network_resources"].pop( +            "firewall_interfaces", None +        ) +        facts = {} +        if objs: +            facts["firewall_interfaces"] = [] +            params = utils.validate_config( +                self.argument_spec, {"config": objs} +            ) +            for cfg in params["config"]: +                facts["firewall_interfaces"].append(utils.remove_empties(cfg)) + +        ansible_facts["ansible_network_resources"].update(facts) +        return ansible_facts + +    def get_names(self, data, interfaces): +        """ +        This function performs following: +        - Form regex to fetch 'interface name' from  interfaces firewall data. +        - Form the name list. +        :param data: configuration. +        :param rules: list of interfaces. +        :return: generated firewall interfaces configuration. +        """ +        names = [] +        for r in set(interfaces): +            int_regex = r" %s .+$" % r.strip("'") +            cfg = findall(int_regex, data, M) +            fi = self.render_config(cfg) +            fi["name"] = r.strip("'") +            names.append(fi) +        if names: +            names = sorted(names, key=lambda i: i["name"]) +        return names + +    def render_config(self, conf): +        """ +        Render config as dictionary structure and delete keys +          from spec for null values + +        :param spec: The facts tree, generated from the argspec +        :param conf: The configuration +        :rtype: dictionary +        :returns: The generated config +        """ +        conf = "\n".join(filter(lambda x: "firewall" in x, conf)) +        config = {"access_rules": self.parse_access_rules(conf)} +        return config + +    def parse_access_rules(self, conf): +        """ +        This function forms the regex to fetch the 'access-rules' +        for specific interface. +        :param conf: configuration data. +        :return: generated access-rules list configuration. +        """ +        ar_lst = [] +        v4_ar = findall(r"^.*(in|out|local) name .*$", conf, M) +        v6_ar = findall(r"^.*(in|out|local) ipv6-name .*$", conf, M) +        if v4_ar: +            v4_conf = "\n".join(findall(r"(^.*?%s.*?$)" % " name", conf, M)) +            config = self.parse_int_rules(v4_conf, "ipv4") +            if config: +                ar_lst.append(config) +        if v6_ar: +            v6_conf = "\n".join( +                findall(r"(^.*?%s.*?$)" % " ipv6-name", conf, M) +            ) +            config = self.parse_int_rules(v6_conf, "ipv6") +            if config: +                ar_lst.append(config) +        if ar_lst: +            ar_lst = sorted(ar_lst, key=lambda i: i["afi"]) +        else: +            empty_rules = findall(r"^.*(in|out|local).*", conf, M) +            if empty_rules: +                ar_lst.append({"afi": "ipv4", "rules": []}) +                ar_lst.append({"afi": "ipv6", "rules": []}) +        return ar_lst + +    def parse_int_rules(self, conf, afi): +        """ +        This function forms the regex to fetch the 'access-rules' +        for specific interface based on ip-type. +        :param conf: configuration data. +        :param rules: rules configured per interface. +        :param afi: ip address type. +        :return: generated rule configuration dictionary. +        """ +        r_lst = [] +        config = {} +        rules = ["in", "out", "local"] +        for r in set(rules): +            fr = {} +            r_regex = r" %s .+$" % r +            cfg = "\n".join(findall(r_regex, conf, M)) +            if cfg: +                fr = self.parse_rules(cfg, afi) +            else: +                out = search(r"^.*firewall " + "'" + r + "'" + "(.*)", conf, M) +                if out: +                    fr = {"direction": r} +            if fr: +                r_lst.append(fr) +        if r_lst: +            r_lst = sorted(r_lst, key=lambda i: i["direction"]) +            config = {"afi": afi, "rules": r_lst} +        return config + +    def parse_rules(self, conf, afi): +        """ +        This function triggers the parsing of 'rule' attributes. +        a_lst is a list having rule attributes which doesn't +        have further sub attributes. +        :param conf: configuration. +        :param afi: ip address type. +        :return: generated rule configuration dictionary. +        """ +        cfg = {} +        out = findall(r"[^\s]+", conf, M) +        if out: +            cfg["direction"] = out[0].strip("'") +            if afi == "ipv6": +                out = findall(r"[^\s]+ ipv6-name (?:\'*)(\S+)(?:\'*)", conf, M) +                if out: +                    cfg["name"] = str(out[0]).strip("'") +            else: +                out = findall(r"[^\s]+ name (?:\'*)(\S+)(?:\'*)", conf, M) +                if out: +                    cfg["name"] = out[-1].strip("'") +        return cfg diff --git a/plugins/module_utils/network/vyos/utils/utils.py b/plugins/module_utils/network/vyos/utils/utils.py index 402adfc9..4635234c 100644 --- a/plugins/module_utils/network/vyos/utils/utils.py +++ b/plugins/module_utils/network/vyos/utils/utils.py @@ -14,9 +14,10 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.compat import (  def search_obj_in_list(name, lst, key="name"): -    for item in lst: -        if item[key] == name: -            return item +    if lst: +        for item in lst: +            if item[key] == name: +                return item      return None diff --git a/plugins/modules/vyos_facts.py b/plugins/modules/vyos_facts.py index eec4c3b7..4a640663 100644 --- a/plugins/modules/vyos_facts.py +++ b/plugins/modules/vyos_facts.py @@ -47,7 +47,8 @@ options:        Can specify a list of values to include a larger subset. Values can also be        used with an initial C(M(!)) to specify that a specific subset should not be        collected. Valid subsets are 'all', 'interfaces', 'l3_interfaces', 'lag_interfaces', -      'lldp_global', 'lldp_interfaces', 'static_routes', 'firewall_rules', 'firewall_global'. +      'lldp_global', 'lldp_interfaces', 'static_routes', 'firewall_rules', 'firewall_global', +      'firewall_interfaces'.      required: false  """ diff --git a/plugins/modules/vyos_firewall_interfaces.py b/plugins/modules/vyos_firewall_interfaces.py new file mode 100644 index 00000000..1c2ce98a --- /dev/null +++ b/plugins/modules/vyos_firewall_interfaces.py @@ -0,0 +1,1289 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2019 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +#                WARNING                    # +############################################# +# +# This file is auto generated by the resource +#   module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +#   by the resource module builder. +# +# Changes should be made in the model used to +#   generate this file or in the resource module +#   builder template. +# +############################################# + +""" +The module file for vyos_firewall_interfaces +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +} + +DOCUMENTATION = """module: vyos_firewall_interfaces +short_description: Manage firewall rules attributes of interfaces on VyOS devices +description: Manage firewall rules of interfaces on VyOS network devices. +author: +- Rohit Thakur (@rohitthakur2590) +options: +  config: +    description: A list of firewall rules options for interfaces. +    type: list +    elements: dict +    suboptions: +      name: +        description: +        - Name/Identifier for the interface. +        type: str +        required: true +      access_rules: +        description: +        - Specifies firewall rules attached to the interfaces. +        type: list +        elements: dict +        suboptions: +          afi: +            description: +            - Specifies the AFI for the Firewall rules to be configured on this interface. +            type: str +            choices: +            - ipv4 +            - ipv6 +            required: true +          rules: +            description: +            - Specifies the firewall rules for the provided AFI. +            type: list +            elements: dict +            suboptions: +              name: +                description: +                - Specifies the name of the IPv4/IPv6 Firewall rule for the interface. +                type: str +              direction: +                description: +                - Specifies the direction of packets that the firewall rule will be +                  applied on. +                type: str +                choices: +                - in +                - local +                - out +                required: true +  running_config: +    description: +    - The module, by default, will connect to the remote device and retrieve the current +      running-config to use as a base for comparing against the contents of source. +      There are times when it is not desirable to have the task get the current running-config +      for every task in a playbook.  The I(running_config) argument allows the implementer +      to pass in the configuration to use as the base config for comparison. This +      value of this option should be the output received from device by executing +      command C(show configuration commands | grep 'firewall' +    type: str +  state: +    description: +    - The state the configuration should be left in. +    type: str +    choices: +    - merged +    - replaced +    - overridden +    - deleted +    - parsed +    - rendered +    - gathered +    default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state: +# ------------- +# +# vyos@192# run show configuration commands | grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# +- name: Merge the provided configuration with the existing running configuration +  vyos_firewall_interfaces: +    config: +      - access_rules: +          - afi: 'ipv4' +            rules: +              - name: 'INBOUND' +                direction: 'in' +              - name: 'OUTBOUND' +                direction: 'out' +              - name: 'LOCAL' +                direction: 'local' +          - afi: 'ipv6' +            rules: +              - name: 'V6-LOCAL' +                direction: 'local' +        name: 'eth1' +      - access_rules: +          - afi: 'ipv4' +            rules: +              - name: 'INBOUND' +                direction: 'in' +              - name: 'OUTBOUND' +                direction: 'out' +              - name: 'LOCAL' +                direction: 'local' +          - afi: 'ipv6' +            rules: +              - name: 'V6-LOCAL' +                direction: 'local' +        name: 'eth3' +    state: merged +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# before": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "name": "eth3" +#        } +#    ] +# +#    "commands": [ +#       "set interfaces ethernet eth1 firewall in name 'INBOUND'", +#       "set interfaces ethernet eth1 firewall out name 'OUTBOUND'", +#       "set interfaces ethernet eth1 firewall local name 'LOCAL'", +#       "set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL'", +#       "set interfaces ethernet eth3 firewall in name 'INBOUND'", +#       "set interfaces ethernet eth3 firewall out name 'OUTBOUND'", +#       "set interfaces ethernet eth3 firewall local name 'LOCAL'", +#       "set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL'" +#    ] +# +# "after": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth3" +#        } +#    ] +# +# After state: +# ------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall in name 'INBOUND' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall local name 'LOCAL' +# set interfaces ethernet eth1 firewall out name 'OUTBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth3 firewall local name 'LOCAL' +# set interfaces ethernet eth3 firewall out name 'OUTBOUND' + + +# Using merged +# +# Before state: +# ------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall in name 'INBOUND' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall local name 'LOCAL' +# set interfaces ethernet eth1 firewall out name 'OUTBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth3 firewall local name 'LOCAL' +# set interfaces ethernet eth3 firewall out name 'OUTBOUND' +# +- name: Merge the provided configuration with the existing running configuration +  vyos_firewall_interfaces: +    config: +      - access_rules: +          - afi: 'ipv4' +            rules: +              - name: 'OUTBOUND' +                direction: 'in' +              - name: 'INBOUND' +                direction: 'out' +        name: 'eth1' +    state: merged +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +#    "before": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth3" +#        } +#    ] +# +#    "commands": [ +#       "set interfaces ethernet eth1 firewall in name 'OUTBOUND'", +#       "set interfaces ethernet eth1 firewall out name 'INBOUND'" +#    ] +# +#    "after": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "OUTBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "INBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth3" +#        } +#    ] +# +# After state: +# ------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall in name 'OUTBOUND' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall local name 'LOCAL' +# set interfaces ethernet eth1 firewall out name 'INBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth3 firewall local name 'LOCAL' +# set interfaces ethernet eth3 firewall out name 'OUTBOUND' + + +# Using replaced +# +# Before state: +# ------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall in name 'INBOUND' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall local name 'LOCAL' +# set interfaces ethernet eth1 firewall out name 'OUTBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth3 firewall local name 'LOCAL' +# set interfaces ethernet eth3 firewall out name 'OUTBOUND' +# +- name: Replace device configurations of listed firewall interfaces with provided configurations +  vyos_firewall_interfaces: +    config: +      - name: 'eth1' +        access_rules: +          - afi: 'ipv4' +            rules: +              - name: 'OUTBOUND' +                direction: 'out' +          - afi: 'ipv6' +            rules: +              - name: 'V6-LOCAL' +                direction: 'local' +      - name: 'eth3' +        access_rules: +          - afi: 'ipv4' +            rules: +              - name: 'INBOUND' +                direction: 'in' +    state: replaced +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +#    "before": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth3" +#        } +#    ] +# +# "commands": [ +#        "delete interfaces ethernet eth1 firewall in name", +#        "delete interfaces ethernet eth1 firewall local name", +#        "delete interfaces ethernet eth3 firewall local name", +#        "delete interfaces ethernet eth3 firewall out name", +#        "delete interfaces ethernet eth3 firewall local ipv6-name" +#    ] +# +#    "after": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth3" +#        } +#    ] +# +# After state: +# ------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall 'in' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall out name 'OUTBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall 'local' +# set interfaces ethernet eth3 firewall 'out' + + +# Using overridden +# +# Before state +# -------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall 'in' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall out name 'OUTBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall 'local' +# set interfaces ethernet eth3 firewall 'out' +# +- name: Overrides all device configuration with provided configuration +  vyos_firewall_interfaces: +    config: +      - name: 'eth3' +        access_rules: +          - afi: 'ipv4' +            rules: +              - name: 'INBOUND' +                direction: 'out' +    state: overridden +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# "before":[ +#        { +#            "name": "eth0" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth3" +#        } +#    ] +# +#    "commands": [ +#        "delete interfaces ethernet eth1 firewall", +#        "delete interfaces ethernet eth3 firewall in name", +#        "set interfaces ethernet eth3 firewall out name 'INBOUND'" +# +# +#    "after": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "out", +#                            "name": "INBOUND" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth3" +#        } +#    ] +# +# +# After state +# ------------ +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth3 firewall 'in' +# set interfaces ethernet eth3 firewall 'local' +# set interfaces ethernet eth3 firewall out name 'INBOUND' + + +# Using deleted per interface name +# +# Before state +# ------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall in name 'INBOUND' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall local name 'LOCAL' +# set interfaces ethernet eth1 firewall out name 'OUTBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth3 firewall local name 'LOCAL' +# set interfaces ethernet eth3 firewall out name 'OUTBOUND' +# +- name: Delete firewall interfaces based on interface name. +  vyos_firewall_interfaces: +    config: +      - name: 'eth1' +      - name: 'eth3' +    state: deleted +# +# +# ------------------------ +# Module Execution Results +# ------------------------ +# +# "before": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth3" +#        } +#    ] +#    "commands": [ +#        "delete interfaces ethernet eth1 firewall", +#        "delete interfaces ethernet eth3 firewall" +#    ] +# +# "after": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "name": "eth3" +#        } +#    ] +# After state +# ------------ +# vyos@vyos# run show configuration commands | grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' + + +# Using deleted per afi +# +# Before state +# ------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall in name 'INBOUND' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall local name 'LOCAL' +# set interfaces ethernet eth1 firewall out name 'OUTBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth3 firewall local name 'LOCAL' +# set interfaces ethernet eth3 firewall out name 'OUTBOUND' +# +- name: Delete firewall interfaces config per afi. +  vyos_firewall_interfaces: +    config: +      - name: 'eth1' +        access_rules: +          - afi: 'ipv4' +          - afi: 'ipv6' +    state: deleted +# +# +# ------------------------ +# Module Execution Results +# ------------------------ +# +#    "commands": [ +#        "delete interfaces ethernet eth1 firewall in name", +#        "delete interfaces ethernet eth1 firewall out name", +#        "delete interfaces ethernet eth1 firewall local name", +#        "delete interfaces ethernet eth1 firewall local ipv6-name" +#    ] +# +# After state +# ------------ +# vyos@vyos# run show configuration commands | grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' + + +# Using deleted without config +# +# Before state +# ------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall in name 'INBOUND' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall local name 'LOCAL' +# set interfaces ethernet eth1 firewall out name 'OUTBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth3 firewall local name 'LOCAL' +# set interfaces ethernet eth3 firewall out name 'OUTBOUND' +# +- name: Delete firewall interfaces config when empty config provided. +  vyos_firewall_interfaces: +    config: +    state: deleted +# +# +# ------------------------ +# Module Execution Results +# ------------------------ +# +#    "commands": [ +#        "delete interfaces ethernet eth1 firewall", +#        "delete interfaces ethernet eth1 firewall" +#    ] +# +# After state +# ------------ +# vyos@vyos# run show configuration commands | grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' + + +# Using parsed +# +# +- name: Parse the provided  configuration +  vyos_firewall_interfaces: +    running_config: +      "set interfaces ethernet eth1 firewall in name 'INBOUND' + set interfaces ethernet eth1 firewall out name 'OUTBOUND' + set interfaces ethernet eth1 firewall local name 'LOCAL' + set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' + set interfaces ethernet eth2 firewall in name 'INBOUND' + set interfaces ethernet eth2 firewall out name 'OUTBOUND' + set interfaces ethernet eth2 firewall local name 'LOCAL' + set interfaces ethernet eth2 firewall local ipv6-name 'V6-LOCAL'" +    state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth1" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        }, +#                        { +#                            "direction": "local", +#                            "name": "LOCAL" +#                        }, +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth2" +#        }, +#        { +#            "name": "eth3" +#        } +#    ] + + +# Using gathered +# +# Before state: +# ------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall 'in' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall out name 'OUTBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall 'local' +# set interfaces ethernet eth3 firewall 'out' +# +- name: Gather listed firewall interfaces. +  vyos_firewall_interfaces: +    config: +    state: gathered +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +#    "gathered": [ +#        { +#            "name": "eth0" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "out", +#                            "name": "OUTBOUND" +#                        } +#                    ] +#                }, +#                { +#                    "afi": "ipv6", +#                    "rules": [ +#                        { +#                            "direction": "local", +#                            "name": "V6-LOCAL" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth1" +#        }, +#        { +#            "name": "eth2" +#        }, +#        { +#            "access_rules": [ +#                { +#                    "afi": "ipv4", +#                    "rules": [ +#                        { +#                            "direction": "in", +#                            "name": "INBOUND" +#                        } +#                    ] +#                } +#            ], +#            "name": "eth3" +#        } +#    ] +# +# +# After state: +# ------------- +# +# vyos@vyos:~$ show configuration commands| grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' +# set interfaces ethernet eth1 firewall 'in' +# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' +# set interfaces ethernet eth1 firewall out name 'OUTBOUND' +# set interfaces ethernet eth3 firewall in name 'INBOUND' +# set interfaces ethernet eth3 firewall 'local' +# set interfaces ethernet eth3 firewall 'out' + + +# Using rendered +# +# +- name: Render the commands for provided  configuration +  vyos_firewall_interfaces: +    config: +      - name: 'eth2' +        access_rules: +          - afi: 'ipv4' +            rules: +              - direction: 'in' +                name: 'INGRESS' +              - direction: 'out' +                name: 'OUTGRESS' +              - direction: 'local' +                name: 'DROP' +    state: rendered +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "rendered": [ +#        "set interfaces ethernet eth2 firewall in name 'INGRESS'", +#        "set interfaces ethernet eth2 firewall out name 'OUTGRESS'", +#        "set interfaces ethernet eth2 firewall local name 'DROP'", +#        "set interfaces ethernet eth2 firewall local ipv6-name 'LOCAL'" +#    ] + + +""" +RETURN = """ +before: +  description: The configuration prior to the model invocation. +  returned: always +  type: list +  sample: > +    The configuration returned will always be in the same format +     of the parameters above. +after: +  description: The resulting configuration model invocation. +  returned: when changed +  type: list +  sample: > +    The configuration returned will always be in the same format +     of the parameters above. +commands: +  description: The set of commands pushed to the remote device. +  returned: always +  type: list +  sample: +    - "set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL'" +    - "set interfaces ethernet eth3 firewall in name 'INBOUND'" +""" + + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.firewall_interfaces.firewall_interfaces import ( +    Firewall_interfacesArgs, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.firewall_interfaces.firewall_interfaces import ( +    Firewall_interfaces, +) + + +def main(): +    """ +    Main entry point for module execution + +    :returns: the result form module invocation +    """ +    required_if = [ +        ("state", "merged", ("config",)), +        ("state", "replaced", ("config",)), +        ("state", "overridden", ("config",)), +        ("state", "parsed", ("running_config",)), +    ] +    mutually_exclusive = [("config", "running_config")] + +    module = AnsibleModule( +        argument_spec=Firewall_interfacesArgs.argument_spec, +        required_if=required_if, +        supports_check_mode=True, +        mutually_exclusive=mutually_exclusive, +    ) + +    result = Firewall_interfaces(module).execute_module() +    module.exit_json(**result) + + +if __name__ == "__main__": +    main() | 
