diff options
author | omnom62 <75066712+omnom62@users.noreply.github.com> | 2025-01-25 21:38:00 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-25 06:38:00 -0500 |
commit | d0c73e6bdd3ca3ff9d87c8339b2c5611b694d6dc (patch) | |
tree | 3b4f957ae38250dd4062e35ae44d7bb7bf66d635 | |
parent | af5b93277699b2dc3732f08573ef127b784cb2ce (diff) | |
download | vyos.vyos-d0c73e6bdd3ca3ff9d87c8339b2c5611b694d6dc.tar.gz vyos.vyos-d0c73e6bdd3ca3ff9d87c8339b2c5611b694d6dc.zip |
T6817 & T6825 & T7004 updates - fw_rules override and replaced fixes (#368)
* T6817 updates
* updates / additions to unit tests and code for fw_rules (t6817)
* code and use cases for override fw_rules
* ovr idem unit test for fw rules v14 in WIP
* Fixed replace add_rule func to remove unmatching confug - t6825
* first cut of unit tests for t6825 and t6817 - dfaft
* Fixed replaced unit tests and code for inbound/outbound interface attributes
* use network_cli's remove_empties
* fixed disabled=True and a few unit tests in v1.3
* add_log func for firewall_rules updated
* firewall_rules log attribute processing for v1.4 and idemp
* + In overriden :
- Added func to compare r_sets
- Added code to isolate r_set changes to only targeted
- Fixed parsers for packet_length_exclude
- started to troubleshoot filter processing
* completed fixes and unit tests for firewall_rules as in T6817 and T6825
* T7004 integration tests init fix
* 'state' attrib processing fix
* deleted and merged integration tests fixed for 1.3- and 1.4+
* fixed deleted, parsed, replaced integration tests for 1.3- and 1.4+
* fixed _remove_config, merged integration tests
* added comments to unit tests
* more v1.3- unit tests moved to 1.4+ unit test suite
* 1.3/1.4 unit test suite synced
* overridden integration test fixed
* fixed replaced idempotency
* moved data to vars (integration tests)
* updated parsed (integration tests)
* D.R.Y. for integration tests for firewall_rules plugin
* vanilla data set for integration tests to support 1.5
24 files changed, 2592 insertions, 678 deletions
diff --git a/changelogs/fragments/T6817_T6825_ovr_rep.yml b/changelogs/fragments/T6817_T6825_ovr_rep.yml new file mode 100644 index 0000000..ab4d70c --- /dev/null +++ b/changelogs/fragments/T6817_T6825_ovr_rep.yml @@ -0,0 +1,6 @@ +--- +minor_changes: + - fixed behavior for override and replaced states + - added support for packet-length-exclude for 1.4+ and the states + - fixed behavior for log, disable attributes + - added a separate test suite test_vyos_firewall_rules14.py diff --git a/plugins/module_utils/network/vyos/config/firewall_rules/firewall_rules.py b/plugins/module_utils/network/vyos/config/firewall_rules/firewall_rules.py index 106b2b8..68ceff8 100644 --- a/plugins/module_utils/network/vyos/config/firewall_rules/firewall_rules.py +++ b/plugins/module_utils/network/vyos/config/firewall_rules/firewall_rules.py @@ -85,7 +85,7 @@ class Firewall_rules(ConfigBase): existing_firewall_rules_facts = [] if self.state in self.ACTION_STATES or self.state == "rendered": - commands.extend(self.set_config(existing_firewall_rules_facts)) + commands.extend(self.set_config(deepcopy(existing_firewall_rules_facts))) if commands and self.state in self.ACTION_STATES: if not self._module.check_mode: @@ -128,6 +128,7 @@ class Firewall_rules(ConfigBase): to the desired configuration """ want = self._module.params["config"] + self._prune_stubs(want) have = existing_firewall_rules_facts resp = self.set_state(want, have) return to_list(resp) @@ -175,6 +176,8 @@ class Firewall_rules(ConfigBase): # configuration's rule set). rs_id = self._rs_id(rs, h["afi"]) wanted_rule_set = self.search_r_sets_in_have(want, rs_id, "r_list") + if self._is_same_rs(remove_empties(wanted_rule_set), remove_empties(rs)): + continue if wanted_rule_set is not None: # Remove the rules that we already have if the wanted # rules exist under the same name. @@ -204,11 +207,21 @@ class Firewall_rules(ConfigBase): for rs in have_r_sets: rs_id = self._rs_id(rs, h["afi"]) w = self.search_r_sets_in_have(want, rs_id, "r_list") - if not w: - commands.append(self._compute_command(rs_id, remove=True)) + if self._is_same_rs(remove_empties(w), remove_empties(rs)): + continue else: - commands.extend(self._add_r_sets(h["afi"], rs, w, opr=False)) - commands.extend(self._state_merged(want, have)) + commands.append(self._compute_command(rs_id, remove=True)) + # Blank out the only rule set that it is removed. + for entry in have: + if entry['afi'] == rs_id['afi'] and rs_id['name']: + entry["rule_sets"] = [ + rule_set for rule_set in entry["rule_sets"] if rule_set.get("name") != rs_id['name'] + ] + elif entry['afi'] == rs_id['afi'] and rs_id['filter']: + entry["rule_sets"] = [ + rule_set for rule_set in entry["rule_sets"] if rule_set.get("filter") != rs_id['filter'] + ] + commands.extend(self._state_merged(want, have)) return commands def _state_merged(self, want, have): @@ -224,7 +237,10 @@ class Firewall_rules(ConfigBase): for rs in r_sets: rs_id = self._rs_id(rs, w["afi"]) h = self.search_r_sets_in_have(have, rs_id, "r_list") - commands.extend(self._add_r_sets(w["afi"], rs, h)) + if self._is_same_rs(remove_empties(h), remove_empties(rs)): + continue + else: + commands.extend(self._add_r_sets(w["afi"], rs, h)) return commands def _state_deleted(self, want, have): @@ -321,13 +337,14 @@ class Firewall_rules(ConfigBase): "fragment", "disable", "description", - "log", "jump_target", ) if w_rules: for w in w_rules: cmd = self._compute_command(rs_id, w["number"], opr=opr) h = self.search_rules_in_have_rs(h_rules, w["number"]) + if w != h and self.state == "replaced": + h = {} for key, val in iteritems(w): if val: if opr and key in l_set and not (h and self._is_w_same(w, h, key)): @@ -376,8 +393,11 @@ class Firewall_rules(ConfigBase): commands.extend(self._add_packet_length(key, w, h, cmd, opr)) elif key == "disable" and val and h and (key not in h or not h[key]): commands.append(self._add_r_base_attrib(rs_id, key, w, opr=opr)) - elif key in ("inbound_interface", "outbound_interface") and not ( - h and self._is_w_same(w, h, key) + if ( + key in ("inbound_interface", "outbound_interface") + and val + and h + and (key not in h or not h[key] or h[key] != w[key]) ): commands.extend(self._add_interface(key, w, h, cmd, opr)) elif ( @@ -396,6 +416,8 @@ class Firewall_rules(ConfigBase): commands.extend(self._add_icmp(key, w, h, cmd, opr)) elif key == "state": commands.extend(self._add_state(key, w, h, cmd, opr)) + elif key == "log": + commands.extend(self._add_log(key, w, h, cmd, opr)) elif key == "limit": commands.extend(self._add_limit(key, w, h, cmd, opr)) elif key == "recent": @@ -462,6 +484,38 @@ class Firewall_rules(ConfigBase): commands.append(cmd + (" " + attr + " " + item)) return commands + def _add_log(self, attr, w, h, cmd, opr): + """ + This function forms the command for 'log' attributes based on the 'opr'. + :param attr: attribute name. + :param w: base config. + :param h: target config. + :param cmd: commands to be prepend. + :return: generated list of commands. + """ + h_state = {} + commands = [] + if w[attr]: + if h and attr in h.keys(): + h_state = h.get(attr) or {} + + if ( + LooseVersion(get_os_version(self._module)) < LooseVersion("1.4") + and opr + and not (h and self._is_w_same(w, h, attr)) + ): + commands.append(cmd + " " + attr + " '" + w[attr] + "'") + elif ( + LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4") + and opr + and not (h and self._is_w_same(w, h, attr)) + ): + commands.append(cmd + " " + attr) + elif not opr and not self._in_target(h_state, w[attr]): + commands.append(cmd + (" " + attr + " '" + w[attr] + "'")) + + return commands + def _add_recent(self, attr, w, h, cmd, opr): """ This function forms the command for 'recent' attributes based on the 'opr'. @@ -512,7 +566,7 @@ class Firewall_rules(ConfigBase): and not (h_icmp and self._is_w_same(w[attr], h_icmp, item)) ): if item == "type_name": - if LooseVersion(get_os_version(self._module)) >= LooseVersion("1.3"): + if LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"): param_name = "type-name" else: param_name = "type" @@ -849,11 +903,10 @@ class Firewall_rules(ConfigBase): :return: rule. """ if have_rules: - for h in have_rules: - key = "number" - for r in have_rules: - if key in r and r[key] == r_number: - return r + key = "number" + for r in have_rules: + if key in r and r[key] == r_number: + return r return None def search_r_sets_in_have(self, have, rs_id, type="rule_sets"): @@ -1075,3 +1128,40 @@ class Firewall_rules(ConfigBase): :return: True/False. """ return True if h and key in h else False + + def _prune_stubs(self, rs): + if isinstance(rs, list): + for item in rs: + self._prune_stubs(item) + elif isinstance(rs, dict): + keys_to_remove = [key for key, value in rs.items() + if ( + (key == "disable" and value is False) + or + (key == "log" and value == "disable" and + LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4")) + or + (key in ["new", "invalid", "related", "established"] and value is False and + LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4")))] + for key in keys_to_remove: + del rs[key] + for key in rs: + self._prune_stubs(rs[key]) + + def _is_same_rs(self, w, rs): + if isinstance(w, dict) and isinstance(rs, dict): + if w.keys() != rs.keys(): + return False + for key in w: + if not self._is_same_rs(w[key], rs[key]): + return False + return True + elif isinstance(w, list) and isinstance(rs, list): + try: + sorted_list1 = sorted(w, key=lambda x: str(x)) # pylint: disable=unnecessary-lambda + sorted_list2 = sorted(rs, key=lambda x: str(x)) # pylint: disable=unnecessary-lambda + except TypeError: + return False + return all(self._is_same_rs(x, y) for x, y in zip(sorted_list1, sorted_list2)) + else: + return w == rs diff --git a/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py b/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py index 1fc7025..3da7089 100644 --- a/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py +++ b/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py @@ -260,7 +260,7 @@ class Firewall_rulesFacts(object): :return: generated config dictionary. """ lengths = [] - rule_regex = r"%s (\d+)" % attrib + rule_regex = r"%s (.+)$" % attrib found_lengths = findall(rule_regex, conf, M) if found_lengths: lengths = [] @@ -484,14 +484,19 @@ class Firewall_rulesFacts(object): config[attrib] = True else: out = search(r"^.*" + regex + " (.+)", conf, M) - if not out and attrib == "disable": - out = search(r"^.*\d+" + " ('disable'$)", conf, M) + if not out: + if attrib == "disable": + out = search(r"^.*\d+" + " (disable$)", conf, M) + if attrib == 'log': + out = search(r"^.*\d+" + " (log$)", conf, M) if out: val = out.group(1).strip("'") if self.is_num(attrib): val = int(val) if attrib == "disable": val = True + if attrib == "log": + val = "enable" config[attrib] = val return config diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/_get_version.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/_get_version.yaml new file mode 100644 index 0000000..dda9fcc --- /dev/null +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/_get_version.yaml @@ -0,0 +1,31 @@ +- name: make sure to get facts + vyos.vyos.vyos_facts: + vars: + ansible_connection: ansible.netcommon.network_cli + register: vyos_facts + when: vyos_version is not defined + +- name: debug vyos_facts + debug: + var: vyos_facts + +- name: pull version from facts + set_fact: + vyos_version: "{{ vyos_facts.ansible_facts.ansible_net_version.split('-')[0].split(' ')[-1] }}" + when: vyos_version is not defined + +- name: fix '.0' versions + set_fact: + vyos_version: "{{ vyos_version }}.0" + when: vyos_version.count('.') == 1 + +- name: include correct vars + include_vars: pre-v1_4.yaml + when: vyos_version is version('1.4.0', '<', version_type='semver') + +- name: include correct vars + include_vars: v1_4.yaml + when: vyos_version is version('1.4.0', '>=', version_type='semver') + +- name: include common vars + include_vars: main.yaml diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/_parsed_config.cfg b/tests/integration/targets/vyos_firewall_rules/tests/cli/_parsed_config_1_3.cfg index b54c109..bb8bc23 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/_parsed_config.cfg +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/_parsed_config_1_3.cfg @@ -3,18 +3,18 @@ set firewall ipv6-name UPLINK default-action 'accept' set firewall ipv6-name UPLINK description 'This is ipv6 specific rule-set' set firewall ipv6-name UPLINK rule 1 action 'accept' set firewall ipv6-name UPLINK rule 1 description 'Fwipv6-Rule 1 is configured by Ansible' -set firewall ipv6-name UPLINK rule 1 ipsec 'match-ipsec' +set firewall ipv6-name UPLINK rule 1 protocol 'tcp' set firewall ipv6-name UPLINK rule 2 action 'accept' set firewall ipv6-name UPLINK rule 2 description 'Fwipv6-Rule 2 is configured by Ansible' -set firewall ipv6-name UPLINK rule 2 ipsec 'match-ipsec' +set firewall ipv6-name UPLINK rule 2 protocol 'tcp' set firewall name INBOUND default-action 'accept' set firewall name INBOUND description 'IPv4 INBOUND rule set' set firewall name INBOUND rule 101 action 'accept' set firewall name INBOUND rule 101 description 'Rule 101 is configured by Ansible' -set firewall name INBOUND rule 101 ipsec 'match-ipsec' +set firewall name INBOUND rule 101 protocol 'tcp' set firewall name INBOUND rule 102 action 'reject' set firewall name INBOUND rule 102 description 'Rule 102 is configured by Ansible' -set firewall name INBOUND rule 102 ipsec 'match-ipsec' +set firewall name INBOUND rule 102 protocol 'tcp' set firewall name INBOUND rule 103 action 'accept' set firewall name INBOUND rule 103 description 'Rule 103 is configured by Ansible' set firewall name INBOUND rule 103 destination group address-group 'inbound' diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/_parsed_config_1_4.cfg b/tests/integration/targets/vyos_firewall_rules/tests/cli/_parsed_config_1_4.cfg new file mode 100644 index 0000000..315ae95 --- /dev/null +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/_parsed_config_1_4.cfg @@ -0,0 +1,23 @@ +set firewall group address-group 'inbound' +set firewall ipv6 name UPLINK default-action 'accept' +set firewall ipv6 name UPLINK description 'This is ipv6 specific rule-set' +set firewall ipv6 name UPLINK rule 1 action 'accept' +set firewall ipv6 name UPLINK rule 1 description 'Fwipv6-Rule 1 is configured by Ansible' +set firewall ipv6 name UPLINK rule 1 protocol 'tcp' +set firewall ipv6 name UPLINK rule 2 action 'accept' +set firewall ipv6 name UPLINK rule 2 description 'Fwipv6-Rule 2 is configured by Ansible' +set firewall ipv6 name UPLINK rule 2 protocol 'tcp' +set firewall ipv4 name INBOUND default-action 'accept' +set firewall ipv4 name INBOUND description 'IPv4 INBOUND rule set' +set firewall ipv4 name INBOUND rule 101 action 'accept' +set firewall ipv4 name INBOUND rule 101 description 'Rule 101 is configured by Ansible' +set firewall ipv4 name INBOUND rule 101 protocol 'tcp' +set firewall ipv4 name INBOUND rule 102 action 'reject' +set firewall ipv4 name INBOUND rule 102 description 'Rule 102 is configured by Ansible' +set firewall ipv4 name INBOUND rule 102 protocol 'tcp' +set firewall ipv4 name INBOUND rule 103 action 'accept' +set firewall ipv4 name INBOUND rule 103 description 'Rule 103 is configured by Ansible' +set firewall ipv4 name INBOUND rule 103 destination group address-group 'inbound' +set firewall ipv4 name INBOUND rule 103 source address '192.0.2.0' +set firewall ipv4 name INBOUND rule 103 state established +set firewall ipv4 name INBOUND rule 103 state related diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/_populate.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/_populate.yaml index 31e0d13..6c235be 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/_populate.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/_populate.yaml @@ -1,31 +1,11 @@ --- -- name: Setup +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: ensure facts + include_tasks: _get_version.yaml + +- name: Setup {{ vyos_version }} + vyos.vyos.vyos_config: + lines: "{{ populate_config }}" vars: - lines: |- - set firewall group address-group 'inbound' - set firewall ipv6-name UPLINK default-action 'accept' - set firewall ipv6-name UPLINK description 'This is ipv6 specific rule-set' - set firewall ipv6-name UPLINK rule 1 action 'accept' - set firewall ipv6-name UPLINK rule 1 description 'Fwipv6-Rule 1 is configured by Ansible' - set firewall ipv6-name UPLINK rule 1 ipsec 'match-ipsec' - set firewall ipv6-name UPLINK rule 2 action 'accept' - set firewall ipv6-name UPLINK rule 2 description 'Fwipv6-Rule 2 is configured by Ansible' - set firewall ipv6-name UPLINK rule 2 ipsec 'match-ipsec' - set firewall name INBOUND default-action 'accept' - set firewall name INBOUND description 'IPv4 INBOUND rule set' - set firewall name INBOUND rule 101 action 'accept' - set firewall name INBOUND rule 101 description 'Rule 101 is configured by Ansible' - set firewall name INBOUND rule 101 ipsec 'match-ipsec' - set firewall name INBOUND rule 102 action 'reject' - set firewall name INBOUND rule 102 description 'Rule 102 is configured by Ansible' - set firewall name INBOUND rule 102 ipsec 'match-ipsec' - set firewall name INBOUND rule 103 action 'accept' - set firewall name INBOUND rule 103 description 'Rule 103 is configured by Ansible' - set firewall name INBOUND rule 103 destination group address-group 'inbound' - set firewall name INBOUND rule 103 source address '192.0.2.0' - set firewall name INBOUND rule 103 state established 'enable' - set firewall name INBOUND rule 103 state invalid 'disable' - set firewall name INBOUND rule 103 state new 'disable' - set firewall name INBOUND rule 103 state related 'enable' - ansible.netcommon.cli_config: - config: "{{ lines }}" + ansible_connection: ansible.netcommon.network_cli diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/_remove_config.yaml index b4fc796..31f527f 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/_remove_config.yaml @@ -1,6 +1,10 @@ --- -- name: Remove Config +- name: ensure facts + include_tasks: _get_version.yaml + +- name: Remove pre-existing firewall rules + vyos.vyos.vyos_config: + lines: "{{ remove_config }}" + ignore_errors: true vars: - lines: "delete firewall ipv6-name\ndelete firewall name\n" - ansible.netcommon.cli_config: - config: "{{ lines }}" + ansible_connection: ansible.netcommon.network_cli diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted.yaml index 97b3ae8..2784c2d 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted.yaml @@ -5,7 +5,7 @@ - include_tasks: _populate.yaml - block: - - name: Delete firewall rule set. + - name: Delete firewall rule set register: result vyos.vyos.vyos_firewall_rules: &id001 config: diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted_afi.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted_afi.yaml index c7a2278..3df19cd 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted_afi.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted_afi.yaml @@ -5,7 +5,7 @@ - include_tasks: _populate.yaml - block: - - name: Delete firewall rule. + - name: Delete firewall rule register: result vyos.vyos.vyos_firewall_rules: &id001 config: diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted_all.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted_all.yaml index c55a4c5..84c66bd 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted_all.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/deleted_all.yaml @@ -5,7 +5,7 @@ - include_tasks: _populate.yaml - block: - - name: Delete all the firewall rules. + - name: Delete all the firewall rules register: result vyos.vyos.vyos_firewall_rules: &id001 config: diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/merged.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/merged.yaml index 674b437..27973d8 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/merged.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/merged.yaml @@ -20,12 +20,12 @@ - number: 1 action: accept description: Fwipv6-Rule 1 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 2 action: accept description: Fwipv6-Rule 2 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - afi: ipv4 rule_sets: @@ -36,13 +36,13 @@ - number: 101 action: accept description: Rule 101 is configured by Ansible - ipsec: match-ipsec + protocol: tcp disabled: true - number: 102 action: reject description: Rule 102 is configured by Ansible - ipsec: match-ipsec + protocol: tcp disable: true - number: 103 diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/overridden.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/overridden.yaml index 6e1b3a3..3b64939 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/overridden.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/overridden.yaml @@ -20,14 +20,18 @@ - number: 501 action: accept description: Rule 501 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 502 action: reject description: Rule 502 is configured by Ansible - ipsec: match-ipsec + protocol: tcp state: overridden + - name: Print result + debug: + msg: "Result: {{ result }}" + - name: Assert that before dicts were correctly generated assert: that: diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/parsed.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/parsed.yaml index e6eae78..85a7c33 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/parsed.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/parsed.yaml @@ -2,13 +2,22 @@ - debug: msg: START vyos_firewall_rules parsed integration tests on connection={{ ansible_connection }} -- name: Parse externally provided Firewall rules config to agnostic model - register: result - vyos.vyos.vyos_firewall_rules: - running_config: "{{ lookup('file', '_parsed_config.cfg') }}" - state: parsed +- name: ensure facts + include_tasks: _get_version.yaml + +- name: version {{ vyos_version }} + block: + - name: Parse externally provided Firewall rules config to agnostic model + register: result + vyos.vyos.vyos_firewall_rules: + running_config: "{{ lookup('file', parsed_config_file) }}" + state: parsed + - name: set result + set_fact: + parsed_result: "{{ result }}" - name: Assert that config was correctly parsed assert: that: - - "{{ parsed['after'] | symmetric_difference(result['parsed']) |length == 0 }}" + - parsed_result.changed == false + - "{{ parsed['after'] | symmetric_difference(parsed_result['parsed']) |length == 0 }}" diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/rendered.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/rendered.yaml index 36feb69..229ceb0 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/rendered.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/rendered.yaml @@ -24,12 +24,12 @@ - number: 101 action: accept description: Rule 101 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 102 action: reject description: Rule 102 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 103 action: accept diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/replaced.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/replaced.yaml index 5959c22..b194462 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/replaced.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/replaced.yaml @@ -26,12 +26,12 @@ - number: 101 action: accept description: Rule 101 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 104 action: reject description: Rule 104 is configured by Ansible - ipsec: match-none + protocol: udp state: replaced - name: Assert that correct set of commands were generated diff --git a/tests/integration/targets/vyos_firewall_rules/tests/cli/rtt.yaml b/tests/integration/targets/vyos_firewall_rules/tests/cli/rtt.yaml index dcf5b28..be066f9 100644 --- a/tests/integration/targets/vyos_firewall_rules/tests/cli/rtt.yaml +++ b/tests/integration/targets/vyos_firewall_rules/tests/cli/rtt.yaml @@ -2,6 +2,8 @@ - debug: msg: START vyos_firewall_rules round trip integration tests on connection={{ ansible_connection }} +- include_tasks: _populate.yaml + - include_tasks: _remove_config.yaml - block: @@ -18,12 +20,12 @@ - number: 1 action: accept description: Fwipv6-Rule 1 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 2 action: accept description: Fwipv6-Rule 2 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - afi: ipv4 rule_sets: @@ -34,12 +36,12 @@ - number: 101 action: accept description: Rule 101 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 102 action: reject description: Rule 102 is configured by Ansible - ipsec: match-ipsec + protocol: tcp state: merged - name: Gather firewall_rules facts diff --git a/tests/integration/targets/vyos_firewall_rules/vars/main.yaml b/tests/integration/targets/vyos_firewall_rules/vars/main.yaml index e2b3e10..c249b34 100644 --- a/tests/integration/targets/vyos_firewall_rules/vars/main.yaml +++ b/tests/integration/targets/vyos_firewall_rules/vars/main.yaml @@ -1,38 +1,7 @@ --- merged: before: [] - commands: - - set firewall ipv6-name UPLINK default-action 'accept' - - set firewall ipv6-name UPLINK description 'This is ipv6 specific rule-set' - - set firewall ipv6-name UPLINK rule 1 action 'accept' - - set firewall ipv6-name UPLINK rule 1 - - set firewall ipv6-name UPLINK rule 1 description 'Fwipv6-Rule 1 is configured by Ansible' - - set firewall ipv6-name UPLINK rule 1 ipsec 'match-ipsec' - - set firewall ipv6-name UPLINK rule 2 action 'accept' - - set firewall ipv6-name UPLINK rule 2 - - set firewall ipv6-name UPLINK rule 2 description 'Fwipv6-Rule 2 is configured by Ansible' - - set firewall ipv6-name UPLINK rule 2 ipsec 'match-ipsec' - - set firewall name INBOUND default-action 'accept' - - set firewall name INBOUND description 'IPv4 INBOUND rule set' - - set firewall name INBOUND rule 101 action 'accept' - - set firewall name INBOUND rule 101 disable - - set firewall name INBOUND rule 101 - - set firewall name INBOUND rule 101 description 'Rule 101 is configured by Ansible' - - set firewall name INBOUND rule 101 ipsec 'match-ipsec' - - set firewall name INBOUND rule 102 action 'reject' - - set firewall name INBOUND rule 102 disable - - set firewall name INBOUND rule 102 - - set firewall name INBOUND rule 102 description 'Rule 102 is configured by Ansible' - - set firewall name INBOUND rule 102 ipsec 'match-ipsec' - - set firewall name INBOUND rule 103 description 'Rule 103 is configured by Ansible' - - set firewall name INBOUND rule 103 destination group address-group inbound - - set firewall name INBOUND rule 103 - - set firewall name INBOUND rule 103 source address 192.0.2.0 - - set firewall name INBOUND rule 103 state established enable - - set firewall name INBOUND rule 103 state related enable - - set firewall name INBOUND rule 103 state invalid disable - - set firewall name INBOUND rule 103 state new disable - - set firewall name INBOUND rule 103 action 'accept' + commands: "{{ merged_commands }}" after: - afi: ipv6 rule_sets: @@ -43,11 +12,11 @@ merged: - number: 1 action: accept description: Fwipv6-Rule 1 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 2 action: accept description: Fwipv6-Rule 2 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - afi: ipv4 rule_sets: - name: INBOUND @@ -57,13 +26,13 @@ merged: - number: 101 action: accept description: Rule 101 is configured by Ansible - ipsec: match-ipsec + protocol: tcp disable: true - number: 102 action: reject disable: true description: Rule 102 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 103 action: accept description: Rule 103 is configured by Ansible @@ -72,11 +41,8 @@ merged: address_group: inbound source: address: 192.0.2.0 - state: - established: true - new: false - invalid: false - related: true + state: "{{ state_dict }}" + populate: - afi: ipv6 rule_sets: @@ -87,11 +53,11 @@ populate: - number: 1 action: accept description: Fwipv6-Rule 1 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 2 action: accept description: Fwipv6-Rule 2 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - afi: ipv4 rule_sets: - name: INBOUND @@ -101,11 +67,11 @@ populate: - number: 101 action: accept description: Rule 101 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 102 action: reject description: Rule 102 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 103 action: accept description: Rule 103 is configured by Ansible @@ -114,21 +80,10 @@ populate: address_group: inbound source: address: 192.0.2.0 - state: - established: true - new: false - invalid: false - related: true + state: "{{ state_dict }}" + replaced: - commands: - - delete firewall ipv6-name UPLINK rule 1 - - delete firewall ipv6-name UPLINK rule 2 - - delete firewall name INBOUND rule 102 - - delete firewall name INBOUND rule 103 - - set firewall name INBOUND rule 104 action 'reject' - - set firewall name INBOUND rule 104 description 'Rule 104 is configured by Ansible' - - set firewall name INBOUND rule 104 - - set firewall name INBOUND rule 104 ipsec 'match-none' + commands: "{{ replaced_commands }}" after: - afi: ipv6 rule_sets: @@ -144,11 +99,11 @@ replaced: - number: 101 action: accept description: Rule 101 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 104 action: reject description: Rule 104 is configured by Ansible - ipsec: match-none + protocol: udp overridden: before: - afi: ipv6 @@ -165,24 +120,12 @@ overridden: - number: 101 action: accept description: Rule 101 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 104 action: reject description: Rule 104 is configured by Ansible - ipsec: match-none - commands: - - delete firewall ipv6-name UPLINK - - delete firewall name INBOUND - - set firewall name Downlink default-action 'accept' - - set firewall name Downlink description 'IPv4 INBOUND rule set' - - set firewall name Downlink rule 501 action 'accept' - - set firewall name Downlink rule 501 - - set firewall name Downlink rule 501 description 'Rule 501 is configured by Ansible' - - set firewall name Downlink rule 501 ipsec 'match-ipsec' - - set firewall name Downlink rule 502 action 'reject' - - set firewall name Downlink rule 502 - - set firewall name Downlink rule 502 description 'Rule 502 is configured by Ansible' - - set firewall name Downlink rule 502 ipsec 'match-ipsec' + protocol: udp + commands: "{{ overridden_commands }}" after: - afi: ipv4 rule_sets: @@ -193,11 +136,11 @@ overridden: - number: 501 action: accept description: Rule 501 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 502 action: reject description: Rule 502 is configured by Ansible - ipsec: match-ipsec + protocol: tcp parsed: after: - afi: ipv6 @@ -209,11 +152,11 @@ parsed: - number: 1 action: accept description: Fwipv6-Rule 1 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 2 action: accept description: Fwipv6-Rule 2 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - afi: ipv4 rule_sets: - name: INBOUND @@ -223,11 +166,11 @@ parsed: - number: 101 action: accept description: Rule 101 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 102 action: reject description: Rule 102 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 103 action: accept description: Rule 103 is configured by Ansible @@ -236,44 +179,8 @@ parsed: address_group: inbound source: address: 192.0.2.0 - state: - established: true - new: false - invalid: false - related: true -rendered: - commands: - - set firewall ipv6-name UPLINK default-action 'accept' - - set firewall ipv6-name UPLINK description 'This is ipv6 specific rule-set' - - set firewall name INBOUND default-action 'accept' - - set firewall name INBOUND description 'IPv4 INBOUND rule set' - - set firewall name INBOUND rule 101 action 'accept' - - set firewall name INBOUND rule 101 - - set firewall name INBOUND rule 101 description 'Rule 101 is configured by Ansible' - - set firewall name INBOUND rule 101 ipsec 'match-ipsec' - - set firewall name INBOUND rule 102 action 'reject' - - set firewall name INBOUND rule 102 - - set firewall name INBOUND rule 102 description 'Rule 102 is configured by Ansible' - - set firewall name INBOUND rule 102 ipsec 'match-ipsec' - - set firewall name INBOUND rule 103 description 'Rule 103 is configured by Ansible' - - set firewall name INBOUND rule 103 destination group address-group inbound - - set firewall name INBOUND rule 103 - - set firewall name INBOUND rule 103 source address 192.0.2.0 - - set firewall name INBOUND rule 103 state established enable - - set firewall name INBOUND rule 103 state related enable - - set firewall name INBOUND rule 103 state invalid disable - - set firewall name INBOUND rule 103 state new disable - - set firewall name INBOUND rule 103 action 'accept' -deleted_rs: - commands: - - delete firewall ipv6-name UPLINK - - delete firewall name INBOUND - after: [] -deleted_afi_all: - commands: - - delete firewall ipv6-name - - delete firewall name - after: [] + state: "{{ state_dict }}" + round_trip: after: - afi: ipv6 @@ -285,11 +192,11 @@ round_trip: - number: 1 action: accept description: Fwipv6-Rule 1 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 2 action: accept description: Fwipv6-Rule 2 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - afi: ipv4 rule_sets: - name: INBOUND @@ -299,18 +206,14 @@ round_trip: - number: 101 action: accept description: Rule 101 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 102 action: reject description: Rule 102 is configured by Ansible - ipsec: match-ipsec + protocol: tcp - number: 103 action: accept description: Rule 103 is configured by Ansible source: address: 192.0.2.0 - state: - established: true - new: false - invalid: false - related: true + state: "{{ state_dict }}" diff --git a/tests/integration/targets/vyos_firewall_rules/vars/pre-v1_4.yaml b/tests/integration/targets/vyos_firewall_rules/vars/pre-v1_4.yaml new file mode 100644 index 0000000..c7d7398 --- /dev/null +++ b/tests/integration/targets/vyos_firewall_rules/vars/pre-v1_4.yaml @@ -0,0 +1,130 @@ +--- +merged_commands: + - set firewall ipv6-name UPLINK default-action 'accept' + - set firewall ipv6-name UPLINK description 'This is ipv6 specific rule-set' + - set firewall ipv6-name UPLINK rule 1 action 'accept' + - set firewall ipv6-name UPLINK rule 1 + - set firewall ipv6-name UPLINK rule 1 description 'Fwipv6-Rule 1 is configured by Ansible' + - set firewall ipv6-name UPLINK rule 1 protocol 'tcp' + - set firewall ipv6-name UPLINK rule 2 action 'accept' + - set firewall ipv6-name UPLINK rule 2 + - set firewall ipv6-name UPLINK rule 2 description 'Fwipv6-Rule 2 is configured by Ansible' + - set firewall ipv6-name UPLINK rule 2 protocol 'tcp' + - set firewall name INBOUND default-action 'accept' + - set firewall name INBOUND description 'IPv4 INBOUND rule set' + - set firewall name INBOUND rule 101 action 'accept' + - set firewall name INBOUND rule 101 disable + - set firewall name INBOUND rule 101 + - set firewall name INBOUND rule 101 description 'Rule 101 is configured by Ansible' + - set firewall name INBOUND rule 101 protocol 'tcp' + - set firewall name INBOUND rule 102 action 'reject' + - set firewall name INBOUND rule 102 disable + - set firewall name INBOUND rule 102 + - set firewall name INBOUND rule 102 description 'Rule 102 is configured by Ansible' + - set firewall name INBOUND rule 102 protocol 'tcp' + - set firewall name INBOUND rule 103 description 'Rule 103 is configured by Ansible' + - set firewall name INBOUND rule 103 destination group address-group inbound + - set firewall name INBOUND rule 103 + - set firewall name INBOUND rule 103 source address 192.0.2.0 + - set firewall name INBOUND rule 103 state established enable + - set firewall name INBOUND rule 103 state related enable + - set firewall name INBOUND rule 103 state invalid disable + - set firewall name INBOUND rule 103 state new disable + - set firewall name INBOUND rule 103 action 'accept' + +populate_config: + - set firewall group address-group 'inbound' + - set firewall ipv6-name UPLINK default-action 'accept' + - set firewall ipv6-name UPLINK description 'This is ipv6 specific rule-set' + - set firewall ipv6-name UPLINK rule 1 action 'accept' + - set firewall ipv6-name UPLINK rule 1 description 'Fwipv6-Rule 1 is configured by Ansible' + - set firewall ipv6-name UPLINK rule 1 protocol 'tcp' + - set firewall ipv6-name UPLINK rule 2 action 'accept' + - set firewall ipv6-name UPLINK rule 2 description 'Fwipv6-Rule 2 is configured by Ansible' + - set firewall ipv6-name UPLINK rule 2 protocol 'tcp' + - set firewall name INBOUND default-action 'accept' + - set firewall name INBOUND description 'IPv4 INBOUND rule set' + - set firewall name INBOUND rule 101 action 'accept' + - set firewall name INBOUND rule 101 description 'Rule 101 is configured by Ansible' + - set firewall name INBOUND rule 101 protocol 'tcp' + - set firewall name INBOUND rule 102 action 'reject' + - set firewall name INBOUND rule 102 description 'Rule 102 is configured by Ansible' + - set firewall name INBOUND rule 102 protocol 'tcp' + - set firewall name INBOUND rule 103 action 'accept' + - set firewall name INBOUND rule 103 description 'Rule 103 is configured by Ansible' + - set firewall name INBOUND rule 103 destination group address-group 'inbound' + - set firewall name INBOUND rule 103 source address '192.0.2.0' + - set firewall name INBOUND rule 103 state established 'enable' + - set firewall name INBOUND rule 103 state invalid 'disable' + - set firewall name INBOUND rule 103 state new 'disable' + - set firewall name INBOUND rule 103 state related 'enable' + +remove_config: + - delete firewall name + - delete firewall ipv6-name + +parsed_config_file: "_parsed_config_1_3.cfg" + +replaced_commands: + - delete firewall ipv6-name UPLINK rule 1 + - delete firewall ipv6-name UPLINK rule 2 + - delete firewall name INBOUND rule 102 + - delete firewall name INBOUND rule 103 + - set firewall name INBOUND rule 104 action 'reject' + - set firewall name INBOUND rule 104 description 'Rule 104 is configured by Ansible' + - set firewall name INBOUND rule 104 + - set firewall name INBOUND rule 104 protocol 'udp' + +overridden_commands: + - delete firewall ipv6-name UPLINK + - delete firewall name INBOUND + - set firewall name Downlink default-action 'accept' + - set firewall name Downlink description 'IPv4 INBOUND rule set' + - set firewall name Downlink rule 501 action 'accept' + - set firewall name Downlink rule 501 + - set firewall name Downlink rule 501 description 'Rule 501 is configured by Ansible' + - set firewall name Downlink rule 501 protocol 'tcp' + - set firewall name Downlink rule 502 action 'reject' + - set firewall name Downlink rule 502 + - set firewall name Downlink rule 502 description 'Rule 502 is configured by Ansible' + - set firewall name Downlink rule 502 protocol 'tcp' + +rendered: + commands: + - set firewall ipv6-name UPLINK default-action 'accept' + - set firewall ipv6-name UPLINK description 'This is ipv6 specific rule-set' + - set firewall name INBOUND default-action 'accept' + - set firewall name INBOUND description 'IPv4 INBOUND rule set' + - set firewall name INBOUND rule 101 action 'accept' + - set firewall name INBOUND rule 101 + - set firewall name INBOUND rule 101 description 'Rule 101 is configured by Ansible' + - set firewall name INBOUND rule 101 protocol 'tcp' + - set firewall name INBOUND rule 102 action 'reject' + - set firewall name INBOUND rule 102 + - set firewall name INBOUND rule 102 description 'Rule 102 is configured by Ansible' + - set firewall name INBOUND rule 102 protocol 'tcp' + - set firewall name INBOUND rule 103 description 'Rule 103 is configured by Ansible' + - set firewall name INBOUND rule 103 destination group address-group inbound + - set firewall name INBOUND rule 103 + - set firewall name INBOUND rule 103 source address 192.0.2.0 + - set firewall name INBOUND rule 103 state established enable + - set firewall name INBOUND rule 103 state related enable + - set firewall name INBOUND rule 103 state invalid disable + - set firewall name INBOUND rule 103 state new disable + - set firewall name INBOUND rule 103 action 'accept' +deleted_rs: + commands: + - delete firewall ipv6-name UPLINK + - delete firewall name INBOUND + after: [] +deleted_afi_all: + commands: + - delete firewall ipv6-name + - delete firewall name + after: [] + +state_dict: + established: true + new: false + invalid: false + related: true diff --git a/tests/integration/targets/vyos_firewall_rules/vars/v1_4.yaml b/tests/integration/targets/vyos_firewall_rules/vars/v1_4.yaml new file mode 100644 index 0000000..267803f --- /dev/null +++ b/tests/integration/targets/vyos_firewall_rules/vars/v1_4.yaml @@ -0,0 +1,123 @@ +--- +merged_commands: + - set firewall ipv6 name UPLINK default-action 'accept' + - set firewall ipv6 name UPLINK description 'This is ipv6 specific rule-set' + - set firewall ipv6 name UPLINK rule 1 action 'accept' + - set firewall ipv6 name UPLINK rule 1 + - set firewall ipv6 name UPLINK rule 1 description 'Fwipv6-Rule 1 is configured by Ansible' + - set firewall ipv6 name UPLINK rule 1 protocol 'tcp' + - set firewall ipv6 name UPLINK rule 2 action 'accept' + - set firewall ipv6 name UPLINK rule 2 + - set firewall ipv6 name UPLINK rule 2 description 'Fwipv6-Rule 2 is configured by Ansible' + - set firewall ipv6 name UPLINK rule 2 protocol 'tcp' + - set firewall ipv4 name INBOUND default-action 'accept' + - set firewall ipv4 name INBOUND description 'IPv4 INBOUND rule set' + - set firewall ipv4 name INBOUND rule 101 action 'accept' + - set firewall ipv4 name INBOUND rule 101 disable + - set firewall ipv4 name INBOUND rule 101 + - set firewall ipv4 name INBOUND rule 101 description 'Rule 101 is configured by Ansible' + - set firewall ipv4 name INBOUND rule 101 protocol 'tcp' + - set firewall ipv4 name INBOUND rule 102 action 'reject' + - set firewall ipv4 name INBOUND rule 102 disable + - set firewall ipv4 name INBOUND rule 102 + - set firewall ipv4 name INBOUND rule 102 description 'Rule 102 is configured by Ansible' + - set firewall ipv4 name INBOUND rule 102 protocol 'tcp' + - set firewall ipv4 name INBOUND rule 103 description 'Rule 103 is configured by Ansible' + - set firewall ipv4 name INBOUND rule 103 destination group address-group inbound + - set firewall ipv4 name INBOUND rule 103 + - set firewall ipv4 name INBOUND rule 103 source address 192.0.2.0 + - set firewall ipv4 name INBOUND rule 103 state established + - set firewall ipv4 name INBOUND rule 103 state related + - set firewall ipv4 name INBOUND rule 103 action 'accept' + +populate_config: + - set firewall group address-group 'inbound' + - set firewall ipv6 name UPLINK default-action 'accept' + - set firewall ipv6 name UPLINK description 'This is ipv6 specific rule-set' + - set firewall ipv6 name UPLINK rule 1 action 'accept' + - set firewall ipv6 name UPLINK rule 1 description 'Fwipv6-Rule 1 is configured by Ansible' + - set firewall ipv6 name UPLINK rule 1 protocol 'tcp' + - set firewall ipv6 name UPLINK rule 2 action 'accept' + - set firewall ipv6 name UPLINK rule 2 description 'Fwipv6-Rule 2 is configured by Ansible' + - set firewall ipv6 name UPLINK rule 2 protocol 'tcp' + - set firewall ipv4 name INBOUND default-action 'accept' + - set firewall ipv4 name INBOUND description 'IPv4 INBOUND rule set' + - set firewall ipv4 name INBOUND rule 101 action 'accept' + - set firewall ipv4 name INBOUND rule 101 description 'Rule 101 is configured by Ansible' + - set firewall ipv4 name INBOUND rule 101 protocol 'tcp' + - set firewall ipv4 name INBOUND rule 102 action 'reject' + - set firewall ipv4 name INBOUND rule 102 description 'Rule 102 is configured by Ansible' + - set firewall ipv4 name INBOUND rule 102 protocol 'tcp' + - set firewall ipv4 name INBOUND rule 103 action 'accept' + - set firewall ipv4 name INBOUND rule 103 description 'Rule 103 is configured by Ansible' + - set firewall ipv4 name INBOUND rule 103 destination group address-group 'inbound' + - set firewall ipv4 name INBOUND rule 103 source address '192.0.2.0' + - set firewall ipv4 name INBOUND rule 103 state established + - set firewall ipv4 name INBOUND rule 103 state related + +remove_config: + - delete firewall ipv4 + - delete firewall ipv6 + +parsed_config_file: "_parsed_config_1_4.cfg" + +replaced_commands: + - delete firewall ipv6 name UPLINK rule 1 + - delete firewall ipv6 name UPLINK rule 2 + - delete firewall ipv4 name INBOUND rule 102 + - delete firewall ipv4 name INBOUND rule 103 + - set firewall ipv4 name INBOUND rule 104 action 'reject' + - set firewall ipv4 name INBOUND rule 104 description 'Rule 104 is configured by Ansible' + - set firewall ipv4 name INBOUND rule 104 + - set firewall ipv4 name INBOUND rule 104 protocol 'udp' + +overridden_commands: + - delete firewall ipv6 name UPLINK + - delete firewall ipv4 name INBOUND + - set firewall ipv4 name Downlink default-action 'accept' + - set firewall ipv4 name Downlink description 'IPv4 INBOUND rule set' + - set firewall ipv4 name Downlink rule 501 action 'accept' + - set firewall ipv4 name Downlink rule 501 + - set firewall ipv4 name Downlink rule 501 description 'Rule 501 is configured by Ansible' + - set firewall ipv4 name Downlink rule 501 protocol 'tcp' + - set firewall ipv4 name Downlink rule 502 action 'reject' + - set firewall ipv4 name Downlink rule 502 + - set firewall ipv4 name Downlink rule 502 description 'Rule 502 is configured by Ansible' + - set firewall ipv4 name Downlink rule 502 protocol 'tcp' + + +rendered: + commands: + - set firewall ipv6 name UPLINK default-action 'accept' + - set firewall ipv6 name UPLINK description 'This is ipv6 specific rule-set' + - set firewall ipv4 name INBOUND default-action 'accept' + - set firewall ipv4 name INBOUND description 'IPv4 INBOUND rule set' + - set firewall ipv4 name INBOUND rule 101 action 'accept' + - set firewall ipv4 name INBOUND rule 101 + - set firewall ipv4 name INBOUND rule 101 description 'Rule 101 is configured by Ansible' + - set firewall ipv4 name INBOUND rule 101 protocol 'tcp' + - set firewall ipv4 name INBOUND rule 102 action 'reject' + - set firewall ipv4 name INBOUND rule 102 + - set firewall ipv4 name INBOUND rule 102 description 'Rule 102 is configured by Ansible' + - set firewall ipv4 name INBOUND rule 102 protocol 'tcp' + - set firewall ipv4 name INBOUND rule 103 description 'Rule 103 is configured by Ansible' + - set firewall ipv4 name INBOUND rule 103 destination group address-group inbound + - set firewall ipv4 name INBOUND rule 103 + - set firewall ipv4 name INBOUND rule 103 source address 192.0.2.0 + - set firewall ipv4 name INBOUND rule 103 state established + - set firewall ipv4 name INBOUND rule 103 state related + - set firewall ipv4 name INBOUND rule 103 action 'accept' +deleted_rs: + commands: + - delete firewall ipv6 name UPLINK + - delete firewall ipv4 name INBOUND + after: [] +deleted_afi_all: + commands: + - delete firewall ipv6 + - delete firewall ipv4 + after: [] + +state_dict: + established: true + related: true diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_firewall_rules_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_firewall_rules_config.cfg index f1fdf1e..6c248d2 100644 --- a/tests/unit/modules/network/vyos/fixtures/vyos_firewall_rules_config.cfg +++ b/tests/unit/modules/network/vyos/fixtures/vyos_firewall_rules_config.cfg @@ -6,7 +6,7 @@ set firewall name V4-INGRESS rule 101 protocol 'icmp' set firewall name V4-INGRESS rule 101 description 'Rule 101 is configured by Ansible' set firewall name V4-INGRESS rule 101 fragment 'match-frag' set firewall name V4-INGRESS rule 101 -set firewall name V4-INGRESS rule 101 'disable' +set firewall name V4-INGRESS rule 101 disable set firewall name V4-INGRESS rule 101 action 'accept' set firewall name V4-INGRESS rule 101 ipsec 'match-ipsec' set firewall name V4-INGRESS rule 101 log 'enable' diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_firewall_rules_config_v14.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_firewall_rules_config_v14.cfg index ef596cd..e82e390 100644 --- a/tests/unit/modules/network/vyos/fixtures/vyos_firewall_rules_config_v14.cfg +++ b/tests/unit/modules/network/vyos/fixtures/vyos_firewall_rules_config_v14.cfg @@ -8,17 +8,25 @@ set firewall ipv4 name V4-INGRESS rule 101 packet-length-exclude 100 set firewall ipv4 name V4-INGRESS rule 101 packet-length-exclude 300 set firewall ipv4 name V4-INGRESS rule 101 log set firewall ipv4 name V4-INGRESS rule 101 -set firewall ipv4 name V4-INGRESS rule 101 'disable' +set firewall ipv4 name V4-INGRESS rule 101 disable set firewall ipv4 name V4-INGRESS rule 101 action 'accept' set firewall ipv4 name EGRESS default-action 'reject' set firewall ipv6 name EGRESS default-action 'reject' set firewall ipv6 name EGRESS rule 20 set firewall ipv6 name EGRESS rule 20 icmpv6 type-name 'echo-request' -set firewall ipv6 input filter 1 jump-target 'V6-INGRESS' -set firewall ipv6 output filter 1 jump-target 'EGRESS' -set firewall ipv4 input filter 1 jump-target 'INGRESS' -set firewall ipv4 output filter 1 jump-target 'EGRESS' -set firewall ipv4 name IF-TEST rule 10 'disable' +set firewall ipv6 input filter rule 1 +set firewall ipv6 input filter rule 1 action 'jump' +set firewall ipv6 input filter rule 1 jump-target 'V6-INGRESS' +set firewall ipv6 output filter rule 1 +set firewall ipv6 output filter rule 1 action 'jump' +set firewall ipv6 output filter rule 1 jump-target 'EGRESS' +set firewall ipv4 input filter rule 1 +set firewall ipv4 input filter rule 1 action 'jump' +set firewall ipv4 input filter rule 1 jump-target 'INGRESS' +set firewall ipv4 output filter rule 1 +set firewall ipv4 output filter rule 1 action 'jump' +set firewall ipv4 output filter rule 1 jump-target 'EGRESS' +set firewall ipv4 name IF-TEST rule 10 disable set firewall ipv4 name IF-TEST rule 10 action 'accept' set firewall ipv4 name IF-TEST rule 10 inbound-interface name 'eth0' set firewall ipv4 name IF-TEST rule 10 outbound-interface group 'the-ethers' diff --git a/tests/unit/modules/network/vyos/test_vyos_firewall_rules.py b/tests/unit/modules/network/vyos/test_vyos_firewall_rules13.py index c0815bf..101f389 100644 --- a/tests/unit/modules/network/vyos/test_vyos_firewall_rules.py +++ b/tests/unit/modules/network/vyos/test_vyos_firewall_rules13.py @@ -29,11 +29,11 @@ from ansible_collections.vyos.vyos.tests.unit.modules.utils import set_module_ar from .vyos_module import TestVyosModule, load_fixture -class TestVyosFirewallRulesModule(TestVyosModule): +class TestVyosFirewallRulesModule13(TestVyosModule): module = vyos_firewall_rules def setUp(self): - super(TestVyosFirewallRulesModule, self).setUp() + super(TestVyosFirewallRulesModule13, self).setUp() self.mock_get_config = patch( "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config", ) @@ -69,7 +69,7 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.get_os_version.return_value = "1.2" def tearDown(self): - super(TestVyosFirewallRulesModule, self).tearDown() + super(TestVyosFirewallRulesModule13, self).tearDown() self.mock_get_resource_connection_config.stop() self.mock_get_resource_connection_facts.stop() self.mock_get_config.stop() @@ -143,67 +143,8 @@ class TestVyosFirewallRulesModule(TestVyosModule): ] self.execute_module(changed=True, commands=commands) - def test_vyos_firewall_rule_set_02_merged(self): - set_module_args( - dict( - config=[ - dict( - afi="ipv6", - rule_sets=[ - dict( - name="V6-INBOUND", - description="This is IPv6 INBOUND rule set", - default_action="reject", - enable_default_log=True, - rules=[], - ), - dict( - name="V6-OUTBOUND", - description="This is IPv6 OUTBOUND rule set", - default_action="accept", - enable_default_log=False, - rules=[], - ), - ], - ), - dict( - afi="ipv4", - rule_sets=[ - dict( - name="V4-INBOUND", - description="This is IPv4 INBOUND rule set", - default_action="reject", - enable_default_log=True, - rules=[], - ), - dict( - name="V4-OUTBOUND", - description="This is IPv4 OUTBOUND rule set", - default_action="accept", - enable_default_log=False, - rules=[], - ), - ], - ), - ], - state="merged", - ), - ) - commands = [ - "set firewall ipv6-name V6-INBOUND default-action 'reject'", - "set firewall ipv6-name V6-INBOUND description 'This is IPv6 INBOUND rule set'", - "set firewall ipv6-name V6-INBOUND enable-default-log", - "set firewall ipv6-name V6-OUTBOUND default-action 'accept'", - "set firewall ipv6-name V6-OUTBOUND description 'This is IPv6 OUTBOUND rule set'", - "set firewall name V4-INBOUND default-action 'reject'", - "set firewall name V4-INBOUND description 'This is IPv4 INBOUND rule set'", - "set firewall name V4-INBOUND enable-default-log", - "set firewall name V4-OUTBOUND default-action 'accept'", - "set firewall name V4-OUTBOUND description 'This is IPv4 OUTBOUND rule set'", - ] - self.execute_module(changed=True, commands=commands) - def test_vyos_firewall_v4_rule_sets_rule_merged_01(self): + """Test if plugin correctly adds new rules set and a rule with variant attributes""" set_module_args( dict( config=[ @@ -250,6 +191,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4_rule_sets_rule_merged_02(self): + """Test if plugin correctly adds new rules with variant attributes + within existing rule set + """ set_module_args( dict( config=[ @@ -308,6 +252,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4_rule_sets_rule_merged_03(self): + """Test if plugin correctly adds new rules with variant attributes + within existing rule set + """ set_module_args( dict( config=[ @@ -354,6 +301,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4_rule_sets_rule_merged_04(self): + """Test if plugin correctly adds new rules with variant attributes + within existing rule set + """ set_module_args( dict( config=[ @@ -403,6 +353,7 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v6_rule_sets_rule_merged_01(self): + """Test if plugin correctly adds new ipv6 rules set and a rule with variant attributes""" set_module_args( dict( config=[ @@ -447,6 +398,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v6_rule_sets_rule_merged_02(self): + """Test if plugin correctly adds new rules with variant attributes + within existing ipv6 rule set + """ set_module_args( dict( config=[ @@ -505,6 +459,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v6_rule_sets_rule_merged_03(self): + """Test if plugin correctly adds new rules with variant attributes + within existing ipv6 rule set + """ set_module_args( dict( config=[ @@ -551,6 +508,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v6_rule_sets_rule_merged_04(self): + """Test if plugin correctly adds new rules with variant attributes + within existing ipv6 rule set + """ set_module_args( dict( config=[ @@ -611,6 +571,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v6_rule_sets_rule_merged_icmp_01(self): + """Test if plugin correctly adds new rules with variant attributes + within existing ipv6 rule set + """ set_module_args( dict( config=[ @@ -641,6 +604,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4_rule_sets_rule_merged_icmp_01(self): + """Test if plugin correctly adds new rules with variant attributes + within existing rule set + """ set_module_args( dict( config=[ @@ -672,6 +638,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4_rule_sets_rule_merged_icmp_02(self): + """Test if plugin correctly adds new rules with variant attributes + within existing rule set + """ set_module_args( dict( config=[ @@ -702,6 +671,8 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4_rule_sets_del_01(self): + """Test if plugin correctly removes existing rule set + """ set_module_args( dict( config=[dict(afi="ipv4", rule_sets=[dict(name="V4-INGRESS")])], @@ -712,6 +683,8 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4v6_rule_sets_del_02(self): + """Test if plugin correctly removes existing rule sets, both ipv4 and ipv6 + """ set_module_args( dict( config=[ @@ -728,11 +701,15 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4v6_rule_sets_del_03(self): + """Test if plugin correctly removes existing AFIs, both ipv4 and ipv6 + """ set_module_args(dict(config=[], state="deleted")) commands = ["delete firewall name", "delete firewall ipv6-name"] self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4v6_rule_sets_del_04(self): + """Test if plugin has no effect on non-existent rule sets + """ set_module_args( dict( config=[ @@ -745,6 +722,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=False, commands=[]) def test_vyos_firewall_v4v6_rule_sets_rule_rep_01(self): + """Test if plugin correctly replaces a particular rule set(s) + without affecting the others + """ set_module_args( dict( config=[ @@ -803,12 +783,14 @@ class TestVyosFirewallRulesModule(TestVyosModule): ), ) commands = [ - "delete firewall name V4-INGRESS rule 101 disable", + "delete firewall name V4-INGRESS rule 101", + "set firewall name V4-INGRESS rule 101", "set firewall name V4-INGRESS description 'This is IPv4 INGRESS rule set'", + "set firewall name V4-INGRESS rule 101 fragment 'match-frag'", + "set firewall name V4-INGRESS rule 101 ipsec 'match-ipsec'", "set firewall name V4-INGRESS rule 101 protocol 'tcp'", "set firewall name V4-INGRESS rule 101 description 'Rule 101 is configured by Ansible RM'", "set firewall name V4-INGRESS rule 101 action 'reject'", - "delete firewall name V4-INGRESS rule 101 log", "set firewall name V4-INGRESS rule 102 disable", "set firewall name V4-INGRESS rule 102 action 'accept'", "set firewall name V4-INGRESS rule 102 protocol 'icmp'", @@ -820,6 +802,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4v6_rule_sets_rule_rep_02(self): + """Test if plugin correctly replaces a particular rule(s) and rule set attribute(s) + without affecting the others + """ set_module_args( dict( config=[ @@ -869,12 +854,21 @@ class TestVyosFirewallRulesModule(TestVyosModule): ), ) commands = [ + "delete firewall name V4-INGRESS rule 101", "delete firewall name V4-INGRESS enable-default-log", - "delete firewall name V4-INGRESS rule 101 log", + "set firewall name V4-INGRESS rule 101", + "set firewall name V4-INGRESS rule 101 action 'accept'", + "set firewall name V4-INGRESS rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall name V4-INGRESS rule 101 disable", + "set firewall name V4-INGRESS rule 101 fragment 'match-frag'", + "set firewall name V4-INGRESS rule 101 ipsec 'match-ipsec'", + "set firewall name V4-INGRESS rule 101 protocol 'icmp'", ] self.execute_module(changed=True, commands=commands) def test_vyos_firewall_v4v6_rule_sets_rule_rep_idem_01(self): + """Test if plugin correctly has no effect if there is no change in the configuration + """ set_module_args( dict( config=[ @@ -931,6 +925,8 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=False, commands=[]) def test_vyos_firewall_v4v6_rule_sets_rule_rep_idem_02(self): + """Test if plugin correctly has no effect if there is no change in the configuration + """ set_module_args( dict( config=[ @@ -964,6 +960,8 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=False, commands=[]) def test_vyos_firewall_v4v6_rule_sets_rule_mer_idem_01(self): + """Test if plugin correctly has no effect if there is no change in the configuration + """ set_module_args( dict( config=[ @@ -1019,6 +1017,8 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=False, commands=[]) def test_vyos_firewall_v4v6_rule_sets_rule_ovr_01(self): + """Test if plugin correctly resets the entire rule set if there is a change in the configuration + """ set_module_args( dict( config=[ @@ -1108,7 +1108,74 @@ class TestVyosFirewallRulesModule(TestVyosModule): ] self.execute_module(changed=True, commands=commands) + def test_vyos_firewall_v4v6_rule_sets_rule_ovr_02(self): + """Test if plugin correctly resets the entire rule set + while removing the absent ones if there is a change in the configuration + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INGRESS", + description="This is IPv4 INGRESS rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + protocol="udp", + ), + ], + ), + ], + ), + dict( + afi="ipv6", + rule_sets=[ + dict( + name="EGRESS", + default_action="reject", + description="This rule-set is configured by Ansible RM", + rules=[ + dict( + number="20", + action="accept", + protocol="udp", + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + commands = [ + "delete firewall ipv6-name V6-INGRESS", + "delete firewall ipv6-name EGRESS", + "delete firewall name V4-INGRESS", + "delete firewall name EGRESS", + "set firewall name V4-INGRESS rule 101", + "set firewall name V4-INGRESS description 'This is IPv4 INGRESS rule set'", + "set firewall name V4-INGRESS default-action 'accept'", + "set firewall name V4-INGRESS enable-default-log", + "set firewall name V4-INGRESS rule 101 protocol 'udp'", + "set firewall name V4-INGRESS rule 101 action 'accept'", + "set firewall ipv6-name EGRESS description 'This rule-set is configured by Ansible RM'", + "set firewall ipv6-name EGRESS default-action 'reject'", + "set firewall ipv6-name EGRESS rule 20", + "set firewall ipv6-name EGRESS rule 20 protocol 'udp'", + "set firewall ipv6-name EGRESS rule 20 action 'accept'" + ] + self.execute_module(changed=True, commands=commands) + def test_vyos_firewall_v4v6_rule_sets_rule_ovr_idem_01(self): + """Test if plugin correctly has no effect if there is no change in the configuration + """ set_module_args( dict( config=[ @@ -1165,7 +1232,9 @@ class TestVyosFirewallRulesModule(TestVyosModule): self.execute_module(changed=False, commands=[]) def test_vyos_firewall_v6_rule_sets_rule_merged_01_version(self): - self.get_os_version.return_value = "1.4" + """Test if plugin correctly adds ipv6 rule set with rules + """ + self.get_os_version.return_value = "1.3" set_module_args( dict( config=[ @@ -1204,27 +1273,28 @@ class TestVyosFirewallRulesModule(TestVyosModule): ), ) commands = [ - "set firewall ipv6 name INBOUND default-action 'accept'", - "set firewall ipv6 name INBOUND description 'This is IPv6 INBOUND rule set'", - "set firewall ipv6 name INBOUND default-log", - "set firewall ipv6 name INBOUND rule 101 protocol 'icmp'", - "set firewall ipv6 name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", - "set firewall ipv6 name INBOUND rule 101", - "set firewall ipv6 name INBOUND rule 101 disable", - "set firewall ipv6 name INBOUND rule 101 action 'accept'", - "set firewall ipv6 name INBOUND rule 101 ipsec 'match-ipsec'", - "set firewall ipv6 name INBOUND rule 101 icmpv6 type-name echo-request", - "set firewall ipv6 name INBOUND rule 101 log 'enable'", - "set firewall ipv6 name INBOUND rule 102", - "set firewall ipv6 name INBOUND rule 102 action 'reject'", - "set firewall ipv6 name INBOUND rule 102 description 'Rule 102 is configured by Ansible'", - "set firewall ipv6 name INBOUND rule 102 protocol 'ipv6-icmp'", - 'set firewall ipv6 name INBOUND rule 102 icmpv6 type 7', + "set firewall ipv6-name INBOUND default-action 'accept'", + "set firewall ipv6-name INBOUND description 'This is IPv6 INBOUND rule set'", + "set firewall ipv6-name INBOUND enable-default-log", + "set firewall ipv6-name INBOUND rule 101 protocol 'icmp'", + "set firewall ipv6-name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv6-name INBOUND rule 101", + "set firewall ipv6-name INBOUND rule 101 disable", + "set firewall ipv6-name INBOUND rule 101 action 'accept'", + "set firewall ipv6-name INBOUND rule 101 ipsec 'match-ipsec'", + "set firewall ipv6-name INBOUND rule 101 icmpv6 type echo-request", + "set firewall ipv6-name INBOUND rule 101 log 'enable'", + "set firewall ipv6-name INBOUND rule 102", + "set firewall ipv6-name INBOUND rule 102 action 'reject'", + "set firewall ipv6-name INBOUND rule 102 description 'Rule 102 is configured by Ansible'", + "set firewall ipv6-name INBOUND rule 102 protocol 'ipv6-icmp'", + 'set firewall ipv6-name INBOUND rule 102 icmpv6 type 7', ] self.execute_module(changed=True, commands=commands) def test_vyos_firewall_jump_rules_merged_01(self): - self.get_os_version.return_value = "1.4" + """Test if plugin correctly adds rule set with a jump action + """ set_module_args( dict( config=[ @@ -1263,83 +1333,28 @@ class TestVyosFirewallRulesModule(TestVyosModule): ) ) commands = [ - "set firewall ipv6 name INBOUND default-action 'accept'", - "set firewall ipv6 name INBOUND description 'This is IPv6 INBOUND rule set with a jump action'", - "set firewall ipv6 name INBOUND default-log", - "set firewall ipv6 name INBOUND rule 101 protocol 'icmp'", - "set firewall ipv6 name INBOUND rule 101 packet-length-exclude 100", - "set firewall ipv6 name INBOUND rule 101 packet-length-exclude 200", - "set firewall ipv6 name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", - "set firewall ipv6 name INBOUND rule 101", - "set firewall ipv6 name INBOUND rule 101 ipsec 'match-ipsec'", - "set firewall ipv6 name INBOUND rule 101 icmpv6 type-name echo-request", - "set firewall ipv6 name INBOUND rule 101 action 'jump'", - "set firewall ipv6 name INBOUND rule 101 jump-target 'PROTECT-RE'", - "set firewall ipv6 name INBOUND rule 102", - "set firewall ipv6 name INBOUND rule 102 action 'reject'", - "set firewall ipv6 name INBOUND rule 102 description 'Rule 102 is configured by Ansible'", - "set firewall ipv6 name INBOUND rule 102 protocol 'ipv6-icmp'", - 'set firewall ipv6 name INBOUND rule 102 icmpv6 type 7', + "set firewall ipv6-name INBOUND default-action 'accept'", + "set firewall ipv6-name INBOUND description 'This is IPv6 INBOUND rule set with a jump action'", + "set firewall ipv6-name INBOUND enable-default-log", + "set firewall ipv6-name INBOUND rule 101 protocol 'icmp'", + "set firewall ipv6-name INBOUND rule 101 packet-length-exclude 100", + "set firewall ipv6-name INBOUND rule 101 packet-length-exclude 200", + "set firewall ipv6-name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv6-name INBOUND rule 101", + "set firewall ipv6-name INBOUND rule 101 ipsec 'match-ipsec'", + "set firewall ipv6-name INBOUND rule 101 icmpv6 type echo-request", + "set firewall ipv6-name INBOUND rule 101 action 'jump'", + "set firewall ipv6-name INBOUND rule 101 jump-target 'PROTECT-RE'", + "set firewall ipv6-name INBOUND rule 102", + "set firewall ipv6-name INBOUND rule 102 action 'reject'", + "set firewall ipv6-name INBOUND rule 102 description 'Rule 102 is configured by Ansible'", + "set firewall ipv6-name INBOUND rule 102 protocol 'ipv6-icmp'", + 'set firewall ipv6-name INBOUND rule 102 icmpv6 type 7', ] self.execute_module(changed=True, commands=commands) - -class TestVyosFirewallRulesModule14(TestVyosModule): - module = vyos_firewall_rules - - def setUp(self): - super(TestVyosFirewallRulesModule14, self).setUp() - self.mock_get_config = patch( - "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config" - ) - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch( - "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config" - ) - self.load_config = self.mock_load_config.start() - - self.mock_get_resource_connection_config = patch( - "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection" - ) - self.get_resource_connection_config = self.mock_get_resource_connection_config.start() - - self.mock_get_resource_connection_facts = patch( - "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection" - ) - self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() - self.mock_execute_show_command = patch( - "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.static_routes.static_routes.Static_routesFacts.get_device_data" - ) - - self.mock_execute_show_command = patch( - "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firewall_rules.firewall_rules.Firewall_rulesFacts.get_device_data" - ) - self.execute_show_command = self.mock_execute_show_command.start() - - self.mock_get_os_version = patch( - "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.firewall_rules.firewall_rules.get_os_version" - ) - self.get_os_version = self.mock_get_os_version.start() - self.get_os_version.return_value = "1.4" - self.maxDiff = None - - def tearDown(self): - super(TestVyosFirewallRulesModule14, self).tearDown() - self.mock_get_resource_connection_config.stop() - self.mock_get_resource_connection_facts.stop() - self.mock_get_config.stop() - self.mock_load_config.stop() - self.mock_execute_show_command.stop() - self.mock_get_os_version.stop() - - def load_fixtures(self, commands=None, filename=None): - def load_from_file(*args, **kwargs): - return load_fixture("vyos_firewall_rules_config_v14.cfg") - - self.execute_show_command.side_effect = load_from_file - - def test_vyos_firewall_packet_length_merged_01(self): + def test_vyos_firewall_log_merged_01(self): + """Test if new stanza log is correctly applied""" set_module_args( dict( config=[ @@ -1348,17 +1363,15 @@ class TestVyosFirewallRulesModule14(TestVyosModule): rule_sets=[ dict( name="INBOUND", - description="This is IPv6 INBOUND rule set with a jump action", + description="This is IPv6 INBOUND rule set with a log", default_action="accept", enable_default_log=True, rules=[ dict( number="101", - action="jump", + action="accept", description="Rule 101 is configured by Ansible", - jump_target="PROTECT-RE", - packet_length_exclude=[dict(length=100), dict(length=200)], - packet_length=[dict(length=22)] + log="enable", ), ], ), @@ -1369,21 +1382,21 @@ class TestVyosFirewallRulesModule14(TestVyosModule): ) ) commands = [ - "set firewall ipv6 name INBOUND default-action 'accept'", - "set firewall ipv6 name INBOUND description 'This is IPv6 INBOUND rule set with a jump action'", - "set firewall ipv6 name INBOUND default-log", - "set firewall ipv6 name INBOUND rule 101 packet-length-exclude 100", - "set firewall ipv6 name INBOUND rule 101 packet-length-exclude 200", - "set firewall ipv6 name INBOUND rule 101 packet-length 22", - "set firewall ipv6 name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", - "set firewall ipv6 name INBOUND rule 101", - "set firewall ipv6 name INBOUND rule 101 action 'jump'", - "set firewall ipv6 name INBOUND rule 101 jump-target 'PROTECT-RE'", + "set firewall ipv6-name INBOUND default-action 'accept'", + "set firewall ipv6-name INBOUND description 'This is IPv6 INBOUND rule set with a log'", + "set firewall ipv6-name INBOUND enable-default-log", + "set firewall ipv6-name INBOUND rule 101 log 'enable'", + "set firewall ipv6-name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv6-name INBOUND rule 101", + "set firewall ipv6-name INBOUND rule 101 action 'accept'", ] self.maxDiff = None self.execute_module(changed=True, commands=commands) - def test_vyos_firewall_packet_length_replace_01(self): + def test_vyos_firewall_log_replace_01(self): + """Test that stanza is correctly replaced + without touching the other stanzas + """ set_module_args( dict( config=[ @@ -1401,126 +1414,8 @@ class TestVyosFirewallRulesModule14(TestVyosModule): action="accept", description="Rule 101 is configured by Ansible", packet_length_exclude=[dict(length=100), dict(length=200)], - packet_length=[dict(length=22)] - ), - ], - ), - ], - ) - ], - state="replaced", - ) - ) - commands = [ - "delete firewall ipv4 name V4-INGRESS rule 101 protocol", - "delete firewall ipv4 name V4-INGRESS rule 101 disable", - "delete firewall ipv4 name V4-INGRESS rule 101 packet-length-exclude 300", - "set firewall ipv4 name V4-INGRESS rule 101 packet-length-exclude 200", - "set firewall ipv4 name V4-INGRESS rule 101 packet-length 22", - ] - self.maxDiff = None - self.execute_module(changed=True, commands=commands) - - def test_vyos_firewall_filter_merged_01(self): - set_module_args( - dict( - config=[ - dict( - afi="ipv6", - rule_sets=[ - dict( - filter="input", - description="This is IPv6 INBOUND rule set with a jump action", - default_action="accept", - enable_default_log=True, - rules=[ - dict( - number="101", - action="jump", - description="Rule 101 is configured by Ansible", - jump_target="PROTECT-RE", - packet_length_exclude=[dict(length=100), dict(length=200)], - packet_length=[dict(length=22)] - ), - ], - ), - ], - ) - ], - state="merged", - ) - ) - commands = [ - "set firewall ipv6 input filter default-action 'accept'", - "set firewall ipv6 input filter description 'This is IPv6 INBOUND rule set with a jump action'", - "set firewall ipv6 input filter default-log", - "set firewall ipv6 input filter rule 101 packet-length-exclude 100", - "set firewall ipv6 input filter rule 101 packet-length-exclude 200", - "set firewall ipv6 input filter rule 101 packet-length 22", - "set firewall ipv6 input filter rule 101 description 'Rule 101 is configured by Ansible'", - "set firewall ipv6 input filter rule 101", - "set firewall ipv6 input filter rule 101 action 'jump'", - "set firewall ipv6 input filter rule 101 jump-target 'PROTECT-RE'", - ] - self.maxDiff = None - self.execute_module(changed=True, commands=commands) - - def test_vyos_firewall_interface_merged_01(self): - set_module_args( - dict( - config=[ - dict( - afi="ipv6", - rule_sets=[ - dict( - name="V6-INGRESS", - description="This is IPv6 INBOUND rule set with a jump action", - default_action="accept", - rules=[ - dict( - number="101", - action="jump", - description="Rule 101 is configured by Ansible", - jump_target="PROTECT-RE", - inbound_interface=dict(name="eth0"), - outbound_interface=dict(group="eth1"), - ), - ], - ), - ], - ) - ], - state="merged", - ) - ) - commands = [ - "set firewall ipv6 name V6-INGRESS description 'This is IPv6 INBOUND rule set with a jump action'", - "set firewall ipv6 name V6-INGRESS rule 101 inbound-interface name eth0", - "set firewall ipv6 name V6-INGRESS rule 101 outbound-interface group eth1", - "set firewall ipv6 name V6-INGRESS rule 101 description 'Rule 101 is configured by Ansible'", - "set firewall ipv6 name V6-INGRESS rule 101", - "set firewall ipv6 name V6-INGRESS rule 101 action 'jump'", - "set firewall ipv6 name V6-INGRESS rule 101 jump-target 'PROTECT-RE'", - ] - self.maxDiff = None - self.execute_module(changed=True, commands=commands) - - def test_vyos_firewall_interface_replace_02(self): - set_module_args( - dict( - config=[ - dict( - afi="ipv4", - rule_sets=[ - dict( - name="IF-TEST", - description="Changed", - rules=[ - dict( - number="10", - action="accept", - description="Rule 10 is configured by Ansible", - inbound_interface=dict(name="eth1"), + packet_length=[dict(length=22)], + log="enable", ), ], ), @@ -1531,176 +1426,14 @@ class TestVyosFirewallRulesModule14(TestVyosModule): ) ) commands = [ - "set firewall ipv4 name IF-TEST description 'Changed'", - "set firewall ipv4 name IF-TEST rule 10 description 'Rule 10 is configured by Ansible'", - 'set firewall ipv4 name IF-TEST rule 10 inbound-interface name eth1', - "delete firewall ipv4 name IF-TEST rule 10 outbound-interface group", - "delete firewall ipv4 name IF-TEST rule 10 disable", - "delete firewall ipv4 name IF-TEST rule 10 state related", - "delete firewall ipv4 name IF-TEST rule 10 icmp type-name echo-request", + "delete firewall name V4-INGRESS rule 101", + "set firewall name V4-INGRESS rule 101", + "set firewall name V4-INGRESS rule 101 action 'accept'", + "set firewall name V4-INGRESS rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall name V4-INGRESS rule 101 packet-length-exclude 100", + "set firewall name V4-INGRESS rule 101 packet-length-exclude 200", + "set firewall name V4-INGRESS rule 101 packet-length 22", + "set firewall name V4-INGRESS rule 101 log 'enable'", ] self.maxDiff = None self.execute_module(changed=True, commands=commands) - - def test_vyos_firewall_v4_rule_sets_rule_merged_02(self): - set_module_args( - dict( - config=[ - dict( - afi="ipv4", - rule_sets=[ - dict( - name="INBOUND", - rules=[ - dict( - number="101", - protocol="tcp", - source=dict( - address="192.0.2.0", - mac_address="38:00:25:19:76:0c", - port=2127, - ), - destination=dict(address="192.0.1.0", port=2124), - limit=dict( - burst=10, - rate=dict(number=20, unit="second"), - ), - recent=dict(count=10, time=20), - state=dict( - established=True, - related=True, - invalid=True, - new=True, - ), - ), - ], - ), - ], - ), - ], - state="merged", - ), - ) - commands = [ - "set firewall ipv4 name INBOUND rule 101 protocol 'tcp'", - "set firewall ipv4 name INBOUND rule 101 destination port 2124", - "set firewall ipv4 name INBOUND rule 101", - "set firewall ipv4 name INBOUND rule 101 destination address 192.0.1.0", - "set firewall ipv4 name INBOUND rule 101 source address 192.0.2.0", - "set firewall ipv4 name INBOUND rule 101 source mac-address 38:00:25:19:76:0c", - "set firewall ipv4 name INBOUND rule 101 source port 2127", - "set firewall ipv4 name INBOUND rule 101 state new", - "set firewall ipv4 name INBOUND rule 101 state invalid", - "set firewall ipv4 name INBOUND rule 101 state related", - "set firewall ipv4 name INBOUND rule 101 state established", - "set firewall ipv4 name INBOUND rule 101 limit burst 10", - "set firewall ipv4 name INBOUND rule 101 limit rate 20/second", - "set firewall ipv4 name INBOUND rule 101 recent count 10", - "set firewall ipv4 name INBOUND rule 101 recent time 20", - ] - self.execute_module(changed=True, commands=commands) - - def test_vyos_firewall_v4_rule_sets_change_state_01(self): - set_module_args( - dict( - config=[ - dict( - afi="ipv4", - rule_sets=[ - dict( - name="IF-TEST", - rules=[ - dict( - number="10", - disable=False, - action="accept", - state=dict( - established=True, - new=True, - ), - ), - ], - ), - ], - ), - ], - state="replaced", - ), - ) - commands = [ - "delete firewall ipv4 name IF-TEST rule 10 disable", - "delete firewall ipv4 name IF-TEST rule 10 inbound-interface name", - "delete firewall ipv4 name IF-TEST rule 10 icmp type-name echo-request", - "delete firewall ipv4 name IF-TEST rule 10 outbound-interface group", - "delete firewall ipv4 name IF-TEST rule 10 state related", - "set firewall ipv4 name IF-TEST rule 10 state established", - "set firewall ipv4 name IF-TEST rule 10 state new", - ] - self.execute_module(changed=True, commands=commands) - - def test_vyos_firewall_v4v6_rule_sets_del_03(self): - set_module_args(dict(config=[], state="deleted")) - commands = ["delete firewall ipv4", "delete firewall ipv6"] - self.execute_module(changed=True, commands=commands) - - def test_vyos_firewall_v6_rule_sets_rule_merged_04(self): - set_module_args( - dict( - config=[ - dict( - afi="ipv6", - rule_sets=[ - dict( - name="INBOUND", - rules=[ - dict( - number="101", - time=dict( - monthdays="2", - startdate="2020-01-24", - starttime="13:20:00", - stopdate="2020-01-28", - stoptime="13:30:00", - weekdays="!Sat,Sun", - utc=True, - ), - tcp=dict( - flags=[ - dict(flag="all"), - ] - ), - ), - dict( - number="102", - tcp=dict( - flags=[ - dict(flag="ack"), - dict(flag="syn"), - dict(flag="fin", invert=True), - ], - ) - ) - ], - ), - ], - ), - ], - state="merged", - ), - ) - commands = [ - "set firewall ipv6 name INBOUND rule 101", - "set firewall ipv6 name INBOUND rule 101 tcp flags all", - "set firewall ipv6 name INBOUND rule 101 time utc", - "set firewall ipv6 name INBOUND rule 101 time monthdays 2", - "set firewall ipv6 name INBOUND rule 101 time startdate 2020-01-24", - "set firewall ipv6 name INBOUND rule 101 time stopdate 2020-01-28", - "set firewall ipv6 name INBOUND rule 101 time weekdays !Sat,Sun", - "set firewall ipv6 name INBOUND rule 101 time stoptime 13:30:00", - "set firewall ipv6 name INBOUND rule 101 time starttime 13:20:00", - "set firewall ipv6 name INBOUND rule 102", - "set firewall ipv6 name INBOUND rule 102 tcp flags ack", - "set firewall ipv6 name INBOUND rule 102 tcp flags not fin", - "set firewall ipv6 name INBOUND rule 102 tcp flags syn", - ] - self.execute_module(changed=True, commands=commands) diff --git a/tests/unit/modules/network/vyos/test_vyos_firewall_rules14.py b/tests/unit/modules/network/vyos/test_vyos_firewall_rules14.py new file mode 100644 index 0000000..547b8f4 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_firewall_rules14.py @@ -0,0 +1,1863 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.vyos.vyos.plugins.modules import vyos_firewall_rules +from ansible_collections.vyos.vyos.tests.unit.modules.utils import set_module_args + +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosFirewallRulesModule14(TestVyosModule): + module = vyos_firewall_rules + + def setUp(self): + super(TestVyosFirewallRulesModule14, self).setUp() + self.mock_get_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config" + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection" + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection" + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + self.mock_execute_show_command = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.static_routes.static_routes.Static_routesFacts.get_device_data" + ) + + self.mock_execute_show_command = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firewall_rules.firewall_rules.Firewall_rulesFacts.get_device_data" + ) + self.execute_show_command = self.mock_execute_show_command.start() + + self.mock_get_os_version = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.firewall_rules.firewall_rules.get_os_version" + ) + self.get_os_version = self.mock_get_os_version.start() + self.get_os_version.return_value = "1.4" + self.maxDiff = None + + def tearDown(self): + super(TestVyosFirewallRulesModule14, self).tearDown() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_execute_show_command.stop() + self.mock_get_os_version.stop() + + def load_fixtures(self, commands=None, filename=None): + def load_from_file(*args, **kwargs): + return load_fixture("vyos_firewall_rules_config_v14.cfg") + + self.execute_show_command.side_effect = load_from_file + + def test_vyos_firewall_rule_set_01_merged(self): + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="V6-INBOUND", + description="This is IPv6 INBOUND rule set", + default_action="reject", + enable_default_log=True, + rules=[], + ), + dict( + name="V6-OUTBOUND", + description="This is IPv6 OUTBOUND rule set", + default_action="accept", + enable_default_log=False, + rules=[], + ), + ], + ), + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INBOUND", + description="This is IPv4 INBOUND rule set", + default_action="reject", + enable_default_log=True, + rules=[], + ), + dict( + name="V4-OUTBOUND", + description="This is IPv4 OUTBOUND rule set", + default_action="accept", + enable_default_log=False, + rules=[], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv6 name V6-INBOUND default-action 'reject'", + "set firewall ipv6 name V6-INBOUND description 'This is IPv6 INBOUND rule set'", + "set firewall ipv6 name V6-INBOUND default-log", + "set firewall ipv6 name V6-OUTBOUND default-action 'accept'", + "set firewall ipv6 name V6-OUTBOUND description 'This is IPv6 OUTBOUND rule set'", + "set firewall ipv4 name V4-INBOUND default-action 'reject'", + "set firewall ipv4 name V4-INBOUND description 'This is IPv4 INBOUND rule set'", + "set firewall ipv4 name V4-INBOUND default-log", + "set firewall ipv4 name V4-OUTBOUND default-action 'accept'", + "set firewall ipv4 name V4-OUTBOUND description 'This is IPv4 OUTBOUND rule set'", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_packet_length_merged_01(self): + """Test if new stanza packet-lenght is correctly applied""" + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="INBOUND", + description="This is IPv6 INBOUND rule set with a jump action", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="jump", + description="Rule 101 is configured by Ansible", + jump_target="PROTECT-RE", + packet_length_exclude=[dict(length=100), dict(length=200)], + packet_length=[dict(length=22)] + ), + ], + ), + ], + ) + ], + state="merged", + ) + ) + commands = [ + "set firewall ipv6 name INBOUND default-action 'accept'", + "set firewall ipv6 name INBOUND description 'This is IPv6 INBOUND rule set with a jump action'", + "set firewall ipv6 name INBOUND default-log", + "set firewall ipv6 name INBOUND rule 101 packet-length-exclude 100", + "set firewall ipv6 name INBOUND rule 101 packet-length-exclude 200", + "set firewall ipv6 name INBOUND rule 101 packet-length 22", + "set firewall ipv6 name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv6 name INBOUND rule 101", + "set firewall ipv6 name INBOUND rule 101 action 'jump'", + "set firewall ipv6 name INBOUND rule 101 jump-target 'PROTECT-RE'", + ] + self.maxDiff = None + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_packet_length_replace_01(self): + """Test that stanza is correctly replaced + without touching the other stanzas + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INGRESS", + description="This is IPv4 V4-INGRESS rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + packet_length_exclude=[dict(length=100), dict(length=200)], + packet_length=[dict(length=22)] + ), + ], + ), + ], + ) + ], + state="replaced", + ) + ) + commands = [ + "delete firewall ipv4 name V4-INGRESS rule 101", + "set firewall ipv4 name V4-INGRESS rule 101", + "set firewall ipv4 name V4-INGRESS rule 101 action 'accept'", + "set firewall ipv4 name V4-INGRESS rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv4 name V4-INGRESS rule 101 packet-length-exclude 100", + "set firewall ipv4 name V4-INGRESS rule 101 packet-length-exclude 200", + "set firewall ipv4 name V4-INGRESS rule 101 packet-length 22", + ] + self.maxDiff = None + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_filter_merged_01(self): + """Test if new stanza filter is correctly applied""" + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + filter="input", + description="This is IPv6 INBOUND rule set with a jump action", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="jump", + description="Rule 101 is configured by Ansible", + jump_target="PROTECT-RE", + packet_length_exclude=[dict(length=100), dict(length=200)], + packet_length=[dict(length=22)] + ), + ], + ), + ], + ) + ], + state="merged", + ) + ) + commands = [ + "set firewall ipv6 input filter default-action 'accept'", + "set firewall ipv6 input filter description 'This is IPv6 INBOUND rule set with a jump action'", + "set firewall ipv6 input filter default-log", + "set firewall ipv6 input filter rule 101 packet-length-exclude 100", + "set firewall ipv6 input filter rule 101 packet-length-exclude 200", + "set firewall ipv6 input filter rule 101 packet-length 22", + "set firewall ipv6 input filter rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv6 input filter rule 101", + "set firewall ipv6 input filter rule 101 action 'jump'", + "set firewall ipv6 input filter rule 101 jump-target 'PROTECT-RE'", + ] + self.maxDiff = None + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_interface_merged_01(self): + """Test that the rule with a jump action is correctly applied""" + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="V6-INGRESS", + description="This is IPv6 INBOUND rule set with a jump action", + default_action="accept", + rules=[ + dict( + number="101", + action="jump", + description="Rule 101 is configured by Ansible", + jump_target="PROTECT-RE", + inbound_interface=dict(name="eth0"), + outbound_interface=dict(group="eth1"), + ), + ], + ), + ], + ) + ], + state="merged", + ) + ) + commands = [ + "set firewall ipv6 name V6-INGRESS description 'This is IPv6 INBOUND rule set with a jump action'", + "set firewall ipv6 name V6-INGRESS rule 101 inbound-interface name eth0", + "set firewall ipv6 name V6-INGRESS rule 101 outbound-interface group eth1", + "set firewall ipv6 name V6-INGRESS rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv6 name V6-INGRESS rule 101", + "set firewall ipv6 name V6-INGRESS rule 101 action 'jump'", + "set firewall ipv6 name V6-INGRESS rule 101 jump-target 'PROTECT-RE'", + ] + self.maxDiff = None + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_interface_replace_02(self): + """Test that new stanza is correctly replaced + without touching the other stanzas + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="IF-TEST", + description="Changed", + rules=[ + dict( + number="10", + action="accept", + description="Rule 10 is configured by Ansible", + inbound_interface=dict(name="eth1"), + ), + ], + ), + ], + ) + ], + state="replaced", + ) + ) + commands = [ + "delete firewall ipv4 name IF-TEST rule 10", + "set firewall ipv4 name IF-TEST rule 10", + "set firewall ipv4 name IF-TEST description 'Changed'", + "set firewall ipv4 name IF-TEST rule 10 description 'Rule 10 is configured by Ansible'", + 'set firewall ipv4 name IF-TEST rule 10 inbound-interface name eth1', + "set firewall ipv4 name IF-TEST rule 10 action 'accept'", + ] + self.maxDiff = None + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4_rule_sets_rule_merged_01(self): + """Test if plugin correctly adds new rules set and a rule with variant attributes""" + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="INBOUND", + description="This is IPv4 INBOUND rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + ipsec="match-ipsec", + log="disable", + protocol="icmp", + fragment="match-frag", + disable=True, + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv4 name INBOUND default-action 'accept'", + "set firewall ipv4 name INBOUND description 'This is IPv4 INBOUND rule set'", + "set firewall ipv4 name INBOUND default-log", + "set firewall ipv4 name INBOUND rule 101", + "set firewall ipv4 name INBOUND rule 101 protocol 'icmp'", + "set firewall ipv4 name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv4 name INBOUND rule 101 fragment 'match-frag'", + "set firewall ipv4 name INBOUND rule 101 disable", + "set firewall ipv4 name INBOUND rule 101 action 'accept'", + "set firewall ipv4 name INBOUND rule 101 ipsec 'match-ipsec'", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4_rule_sets_rule_merged_02(self): + """Test that a rule set is correctly applied + including variant attributes such as state + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="INBOUND", + rules=[ + dict( + number="101", + protocol="tcp", + source=dict( + address="192.0.2.0", + mac_address="38:00:25:19:76:0c", + port=2127, + ), + destination=dict(address="192.0.1.0", port=2124), + limit=dict( + burst=10, + rate=dict(number=20, unit="second"), + ), + recent=dict(count=10, time=20), + state=dict( + established=True, + related=True, + invalid=True, + new=True, + ), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv4 name INBOUND rule 101 protocol 'tcp'", + "set firewall ipv4 name INBOUND rule 101 destination port 2124", + "set firewall ipv4 name INBOUND rule 101", + "set firewall ipv4 name INBOUND rule 101 destination address 192.0.1.0", + "set firewall ipv4 name INBOUND rule 101 source address 192.0.2.0", + "set firewall ipv4 name INBOUND rule 101 source mac-address 38:00:25:19:76:0c", + "set firewall ipv4 name INBOUND rule 101 source port 2127", + "set firewall ipv4 name INBOUND rule 101 state new", + "set firewall ipv4 name INBOUND rule 101 state invalid", + "set firewall ipv4 name INBOUND rule 101 state related", + "set firewall ipv4 name INBOUND rule 101 state established", + "set firewall ipv4 name INBOUND rule 101 limit burst 10", + "set firewall ipv4 name INBOUND rule 101 limit rate 20/second", + "set firewall ipv4 name INBOUND rule 101 recent count 10", + "set firewall ipv4 name INBOUND rule 101 recent time 20", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4_rule_sets_rule_merged_03(self): + """Test if plugin correctly adds new rules with variant attributes + within existing rule set + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="INBOUND", + rules=[ + dict( + number="101", + destination=dict( + group=dict( + address_group="OUT-ADDR-GROUP", + network_group="OUT-NET-GROUP", + port_group="OUT-PORT-GROUP", + ), + ), + source=dict( + group=dict( + address_group="IN-ADDR-GROUP", + network_group="IN-NET-GROUP", + port_group="IN-PORT-GROUP", + ), + ), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv4 name INBOUND rule 101 source group address-group IN-ADDR-GROUP", + "set firewall ipv4 name INBOUND rule 101 source group network-group IN-NET-GROUP", + "set firewall ipv4 name INBOUND rule 101 source group port-group IN-PORT-GROUP", + "set firewall ipv4 name INBOUND rule 101 destination group address-group OUT-ADDR-GROUP", + "set firewall ipv4 name INBOUND rule 101 destination group network-group OUT-NET-GROUP", + "set firewall ipv4 name INBOUND rule 101 destination group port-group OUT-PORT-GROUP", + "set firewall ipv4 name INBOUND rule 101", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4_rule_sets_rule_merged_04(self): + """Test if plugin correctly adds new rules with variant attributes + within existing rule set + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="INBOUND", + rules=[ + dict( + number="101", + time=dict( + monthdays="2", + startdate="2020-01-24", + starttime="13:20:00", + stopdate="2020-01-28", + stoptime="13:30:00", + weekdays="!Sat,Sun", + utc=True, + ), + tcp=dict( + flags=[ + dict(flag="all"), + ] + ), + + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv4 name INBOUND rule 101", + "set firewall ipv4 name INBOUND rule 101 tcp flags all", + "set firewall ipv4 name INBOUND rule 101 time utc", + "set firewall ipv4 name INBOUND rule 101 time monthdays 2", + "set firewall ipv4 name INBOUND rule 101 time startdate 2020-01-24", + "set firewall ipv4 name INBOUND rule 101 time stopdate 2020-01-28", + "set firewall ipv4 name INBOUND rule 101 time weekdays !Sat,Sun", + "set firewall ipv4 name INBOUND rule 101 time stoptime 13:30:00", + "set firewall ipv4 name INBOUND rule 101 time starttime 13:20:00", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v6_rule_sets_rule_merged_01(self): + """Test if plugin correctly adds new ipv6 rules set and a rule with variant attributes""" + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="INBOUND", + description="This is IPv6 INBOUND rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + ipsec="match-ipsec", + protocol="icmp", + disable=True, + icmp=dict(type_name="echo-request"), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv6 name INBOUND default-action 'accept'", + "set firewall ipv6 name INBOUND description 'This is IPv6 INBOUND rule set'", + "set firewall ipv6 name INBOUND default-log", + "set firewall ipv6 name INBOUND rule 101 protocol 'icmp'", + "set firewall ipv6 name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv6 name INBOUND rule 101", + "set firewall ipv6 name INBOUND rule 101 disable", + "set firewall ipv6 name INBOUND rule 101 action 'accept'", + "set firewall ipv6 name INBOUND rule 101 ipsec 'match-ipsec'", + "set firewall ipv6 name INBOUND rule 101 icmpv6 type-name echo-request", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v6_rule_sets_rule_merged_02(self): + """Test if plugin correctly adds new rules with variant attributes + within existing ipv6 rule set + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="INBOUND", + rules=[ + dict( + number="101", + protocol="tcp", + source=dict( + address="2001:db8::12", + mac_address="38:00:25:19:76:0c", + port=2127, + ), + destination=dict(address="2001:db8::11", port=2124), + limit=dict( + burst=10, + rate=dict(number=20, unit="second"), + ), + recent=dict(count=10, time=20), + state=dict( + established=True, + related=True, + invalid=True, + new=True, + ), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv6 name INBOUND rule 101 protocol 'tcp'", + "set firewall ipv6 name INBOUND rule 101 destination address 2001:db8::11", + "set firewall ipv6 name INBOUND rule 101 destination port 2124", + "set firewall ipv6 name INBOUND rule 101", + "set firewall ipv6 name INBOUND rule 101 source address 2001:db8::12", + "set firewall ipv6 name INBOUND rule 101 source mac-address 38:00:25:19:76:0c", + "set firewall ipv6 name INBOUND rule 101 source port 2127", + "set firewall ipv6 name INBOUND rule 101 state new", + "set firewall ipv6 name INBOUND rule 101 state invalid", + "set firewall ipv6 name INBOUND rule 101 state related", + "set firewall ipv6 name INBOUND rule 101 state established", + "set firewall ipv6 name INBOUND rule 101 limit burst 10", + "set firewall ipv6 name INBOUND rule 101 recent count 10", + "set firewall ipv6 name INBOUND rule 101 recent time 20", + "set firewall ipv6 name INBOUND rule 101 limit rate 20/second", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v6_rule_sets_rule_merged_03(self): + """Test if plugin correctly adds new rules with variant attributes + within existing ipv6 rule set + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="INBOUND", + rules=[ + dict( + number="101", + destination=dict( + group=dict( + address_group="OUT-ADDR-GROUP", + network_group="OUT-NET-GROUP", + port_group="OUT-PORT-GROUP", + ), + ), + source=dict( + group=dict( + address_group="IN-ADDR-GROUP", + network_group="IN-NET-GROUP", + port_group="IN-PORT-GROUP", + ), + ), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv6 name INBOUND rule 101 source group address-group IN-ADDR-GROUP", + "set firewall ipv6 name INBOUND rule 101 source group network-group IN-NET-GROUP", + "set firewall ipv6 name INBOUND rule 101 source group port-group IN-PORT-GROUP", + "set firewall ipv6 name INBOUND rule 101 destination group address-group OUT-ADDR-GROUP", + "set firewall ipv6 name INBOUND rule 101 destination group network-group OUT-NET-GROUP", + "set firewall ipv6 name INBOUND rule 101 destination group port-group OUT-PORT-GROUP", + "set firewall ipv6 name INBOUND rule 101", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v6_rule_sets_rule_merged_04(self): + """Test that the plugin correctly applies configuration + within exsiting rule set + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="INBOUND", + rules=[ + dict( + number="101", + time=dict( + monthdays="2", + startdate="2020-01-24", + starttime="13:20:00", + stopdate="2020-01-28", + stoptime="13:30:00", + weekdays="!Sat,Sun", + utc=True, + ), + tcp=dict( + flags=[ + dict(flag="all"), + ] + ), + ), + dict( + number="102", + tcp=dict( + flags=[ + dict(flag="ack"), + dict(flag="syn"), + dict(flag="fin", invert=True), + ], + ) + ) + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv6 name INBOUND rule 101", + "set firewall ipv6 name INBOUND rule 101 tcp flags all", + "set firewall ipv6 name INBOUND rule 101 time utc", + "set firewall ipv6 name INBOUND rule 101 time monthdays 2", + "set firewall ipv6 name INBOUND rule 101 time startdate 2020-01-24", + "set firewall ipv6 name INBOUND rule 101 time stopdate 2020-01-28", + "set firewall ipv6 name INBOUND rule 101 time weekdays !Sat,Sun", + "set firewall ipv6 name INBOUND rule 101 time stoptime 13:30:00", + "set firewall ipv6 name INBOUND rule 101 time starttime 13:20:00", + "set firewall ipv6 name INBOUND rule 102", + "set firewall ipv6 name INBOUND rule 102 tcp flags ack", + "set firewall ipv6 name INBOUND rule 102 tcp flags not fin", + "set firewall ipv6 name INBOUND rule 102 tcp flags syn", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4_rule_sets_change_state_01(self): + """Test that a rule set is replaced applied without touching the other stanzas + in particular variant attributes such as state + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="IF-TEST", + rules=[ + dict( + number="10", + disable=False, + action="accept", + state=dict( + established=True, + new=True, + ), + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + commands = [ + "delete firewall ipv4 name IF-TEST rule 10", + "set firewall ipv4 name IF-TEST rule 10", + "set firewall ipv4 name IF-TEST rule 10 state established", + "set firewall ipv4 name IF-TEST rule 10 state new", + "set firewall ipv4 name IF-TEST rule 10 action 'accept'", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v6_rule_sets_rule_merged_icmp_01(self): + """Test if plugin correctly adds new rules with variant attributes + within existing ipv6 rule set + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="INBOUND", + rules=[ + dict( + number="101", + protocol="icmp", + icmp=dict(type_name="port-unreachable"), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv6 name INBOUND rule 101 icmpv6 type-name port-unreachable", + "set firewall ipv6 name INBOUND rule 101 protocol 'icmp'", + "set firewall ipv6 name INBOUND rule 101", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4_rule_sets_rule_merged_icmp_01(self): + """Test if plugin correctly adds new rules with variant attributes + within existing rule set + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="INBOUND", + rules=[ + dict( + number="101", + protocol="icmp", + icmp=dict(type=1, code=1), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv4 name INBOUND rule 101 icmp type 1", + "set firewall ipv4 name INBOUND rule 101 icmp code 1", + "set firewall ipv4 name INBOUND rule 101 protocol 'icmp'", + "set firewall ipv4 name INBOUND rule 101", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4_rule_sets_rule_merged_icmp_02(self): + """Test if plugin correctly adds new rules with variant attributes + within existing rule set + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="INBOUND", + rules=[ + dict( + number="101", + protocol="icmp", + icmp=dict(type_name="echo-request"), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv4 name INBOUND rule 101 icmp type-name echo-request", + "set firewall ipv4 name INBOUND rule 101 protocol 'icmp'", + "set firewall ipv4 name INBOUND rule 101", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4_rule_sets_del_01(self): + """Test if plugin correctly removes existing rule set + """ + set_module_args( + dict( + config=[dict(afi="ipv4", rule_sets=[dict(name="V4-INGRESS")])], + state="deleted", + ), + ) + commands = ["delete firewall ipv4 name V4-INGRESS"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4v6_rule_sets_del_02(self): + """Test if plugin correctly removes existing rule sets, both ipv4 and ipv6 + """ + set_module_args( + dict( + config=[ + dict(afi="ipv4", rule_sets=[dict(name="V4-INGRESS")]), + dict(afi="ipv6", rule_sets=[dict(name="V6-INGRESS")]), + ], + state="deleted", + ), + ) + commands = [ + "delete firewall ipv4 name V4-INGRESS", + "delete firewall ipv6 name V6-INGRESS", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4v6_rule_sets_del_03(self): + """Test that the plugin correctly deprovisions + variant configuration + """ + set_module_args(dict(config=[], state="deleted")) + commands = ["delete firewall ipv4", "delete firewall ipv6"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4v6_rule_sets_del_04(self): + """Test if plugin has no effect on non-existent rule sets + """ + set_module_args( + dict( + config=[ + dict(afi="ipv4", rule_sets=[dict(name="V4-ING")]), + dict(afi="ipv6", rule_sets=[dict(name="V6-ING")]), + ], + state="deleted", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_vyos_firewall_v4v6_rule_sets_rule_rep_01(self): + """Test if plugin correctly replaces a particular rule set(s) + without affecting the others + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INGRESS", + description="This is IPv4 INGRESS rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="reject", + description="Rule 101 is configured by Ansible RM", + ipsec="match-ipsec", + protocol="tcp", + fragment="match-frag", + disable=False, + ), + dict( + number="102", + action="accept", + description="Rule 102 is configured by Ansible RM", + protocol="icmp", + disable=True, + ), + ], + ), + ], + ), + dict( + afi="ipv6", + rule_sets=[ + dict( + name="V6-INGRESS", + default_action="accept", + description="This rule-set is configured by Ansible RM", + ), + dict( + name="EGRESS", + default_action="reject", + description="This rule-set is configured by Ansible RM", + rules=[ + dict( + icmp=dict(type_name="echo-request"), + number=20, + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + commands = [ + "delete firewall ipv4 name V4-INGRESS rule 101", + "set firewall ipv4 name V4-INGRESS rule 101", + "set firewall ipv4 name V4-INGRESS description 'This is IPv4 INGRESS rule set'", + "set firewall ipv4 name V4-INGRESS rule 101 fragment 'match-frag'", + "set firewall ipv4 name V4-INGRESS rule 101 ipsec 'match-ipsec'", + "set firewall ipv4 name V4-INGRESS rule 101 protocol 'tcp'", + "set firewall ipv4 name V4-INGRESS rule 101 description 'Rule 101 is configured by Ansible RM'", + "set firewall ipv4 name V4-INGRESS rule 101 action 'reject'", + "set firewall ipv4 name V4-INGRESS rule 102 disable", + "set firewall ipv4 name V4-INGRESS rule 102 action 'accept'", + "set firewall ipv4 name V4-INGRESS rule 102 protocol 'icmp'", + "set firewall ipv4 name V4-INGRESS rule 102 description 'Rule 102 is configured by Ansible RM'", + "set firewall ipv4 name V4-INGRESS rule 102", + "set firewall ipv6 name V6-INGRESS description 'This rule-set is configured by Ansible RM'", + "set firewall ipv6 name EGRESS description 'This rule-set is configured by Ansible RM'", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4v6_rule_sets_rule_rep_02(self): + """Test if plugin correctly replaces a particular rule(s) and rule set attribute(s) + without affecting the others + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INGRESS", + description="This is IPv4 V4-INGRESS rule set", + default_action="accept", + enable_default_log=False, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + ipsec="match-ipsec", + protocol="icmp", + fragment="match-frag", + disable=True, + ), + ], + ), + ], + ), + dict( + afi="ipv6", + rule_sets=[ + dict( + name="V6-INGRESS", + default_action="accept", + ), + dict( + name="EGRESS", + default_action="reject", + rules=[ + dict( + icmp=dict(type_name="echo-request"), + number=20, + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + commands = [ + "delete firewall ipv4 name V4-INGRESS rule 101", + "delete firewall ipv4 name V4-INGRESS default-log", + "set firewall ipv4 name V4-INGRESS rule 101", + "set firewall ipv4 name V4-INGRESS rule 101 action 'accept'", + "set firewall ipv4 name V4-INGRESS rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv4 name V4-INGRESS rule 101 disable", + "set firewall ipv4 name V4-INGRESS rule 101 fragment 'match-frag'", + "set firewall ipv4 name V4-INGRESS rule 101 ipsec 'match-ipsec'", + "set firewall ipv4 name V4-INGRESS rule 101 protocol 'icmp'", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4v6_rule_sets_rule_rep_idem_01(self): + """Test if plugin correctly has no effect if there is no change in the configuration + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INGRESS", + description="This is IPv4 V4-INGRESS rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + packet_length_exclude=[dict(length=100), dict(length=300)], + protocol="icmp", + disable=True, + log="enable", + ) + ], + ), + dict( + filter="input", + rules=[ + dict( + number="1", + action="jump", + jump_target="INGRESS", + ), + ], + ), + dict( + filter="output", + rules=[ + dict( + number="1", + action="jump", + jump_target="EGRESS", + ), + ], + ), + dict( + name="IF-TEST", + rules=[ + dict( + number="10", + action="accept", + icmp=dict(type_name="echo-request"), + state=dict(related=True), + inbound_interface=dict(name="eth0"), + outbound_interface=dict(group="the-ethers"), + disable=True, + ) + ], + ), + dict( + name="EGRESS", + default_action="reject", + ), + ], + ), + dict( + afi="ipv6", + rule_sets=[ + dict( + name="V6-INGRESS", + default_action="accept", + ), + dict( + name="EGRESS", + default_action="reject", + rules=[ + dict( + icmp=dict(type_name="echo-request"), + number=20, + ), + ], + ), + dict( + filter="input", + rules=[ + dict( + number="1", + action="jump", + jump_target="V6-INGRESS", + ), + ], + ), + dict( + filter="output", + rules=[ + dict( + number="1", + action="jump", + jump_target="EGRESS", + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_vyos_firewall_v4v6_rule_sets_rule_rep_idem_02(self): + """Test if plugin correctly has no effect if there is no change in the configuration + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INGRESS", + description="This is IPv4 V4-INGRESS rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + packet_length_exclude=[dict(length=100), dict(length=300)], + protocol="icmp", + disable=True, + log="enable", + ) + ], + ), + ], + ), + ], + state="replaced", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_vyos_firewall_v4v6_rule_sets_rule_mer_idem_01(self): + """Test if plugin correctly has no effect if there is no change in the configuration + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INGRESS", + description="This is IPv4 V4-INGRESS rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + packet_length_exclude=[dict(length=100), dict(length=300)], + protocol="icmp", + disable=True, + log="enable", + ) + ], + ), + dict( + filter="input", + rules=[ + dict( + number="1", + action="jump", + jump_target="INGRESS", + ), + ], + ), + dict( + filter="output", + rules=[ + dict( + number="1", + action="jump", + jump_target="EGRESS", + ), + ], + ), + dict( + name="IF-TEST", + rules=[ + dict( + number="10", + action="accept", + icmp=dict(type_name="echo-request"), + state=dict(related=True), + inbound_interface=dict(name="eth0"), + outbound_interface=dict(group="the-ethers"), + disable=True, + ) + ], + ), + dict( + name="EGRESS", + default_action="reject", + ), + ], + ), + dict( + afi="ipv6", + rule_sets=[ + dict( + name="V6-INGRESS", + default_action="accept", + ), + dict( + name="EGRESS", + default_action="reject", + rules=[ + dict( + icmp=dict(type_name="echo-request"), + number=20, + ), + ], + ), + dict( + filter="input", + rules=[ + dict( + number="1", + action="jump", + jump_target="V6-INGRESS", + ), + ], + ), + dict( + filter="output", + rules=[ + dict( + number="1", + action="jump", + jump_target="EGRESS", + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_vyos_firewall_v4v6_rule_sets_rule_ovr_01(self): + """Test if plugin correctly resets the entire rule set if there is a change in the configuration + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-IN", + description="This is IPv4 INGRESS rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="1", + action="reject", + description="Rule 1 is configured by Ansible RM", + ipsec="match-ipsec", + log="enable", + protocol="tcp", + fragment="match-frag", + disable=False, + source=dict( + group=dict( + address_group="IN-ADDR-GROUP", + network_group="IN-NET-GROUP", + port_group="IN-PORT-GROUP", + ), + ), + ), + dict( + number="2", + action="accept", + description="Rule 102 is configured by Ansible RM", + protocol="icmp", + disable=True, + ), + ], + ), + ], + ), + dict( + afi="ipv6", + rule_sets=[ + dict( + name="V6-IN", + default_action="accept", + description="This rule-set is configured by Ansible RM", + ), + dict( + name="V6-EG", + default_action="reject", + description="This rule-set is configured by Ansible RM", + ), + ], + ), + ], + state="overridden", + ), + ) + commands = [ + "delete firewall ipv6 name V6-INGRESS", + "delete firewall ipv6 name EGRESS", + "delete firewall ipv4 name V4-INGRESS", + "delete firewall ipv4 name EGRESS", + "delete firewall ipv4 input filter", + "delete firewall ipv4 output filter", + "delete firewall ipv6 input filter", + "delete firewall ipv6 output filter", + "delete firewall ipv4 name IF-TEST", + "set firewall ipv4 name V4-IN default-action 'accept'", + "set firewall ipv4 name V4-IN description 'This is IPv4 INGRESS rule set'", + "set firewall ipv4 name V4-IN default-log", + "set firewall ipv4 name V4-IN rule 1 protocol 'tcp'", + "set firewall ipv4 name V4-IN rule 1 log", + "set firewall ipv4 name V4-IN rule 1 description 'Rule 1 is configured by Ansible RM'", + "set firewall ipv4 name V4-IN rule 1 fragment 'match-frag'", + "set firewall ipv4 name V4-IN rule 1 source group address-group IN-ADDR-GROUP", + "set firewall ipv4 name V4-IN rule 1 source group network-group IN-NET-GROUP", + "set firewall ipv4 name V4-IN rule 1 source group port-group IN-PORT-GROUP", + "set firewall ipv4 name V4-IN rule 1", + "set firewall ipv4 name V4-IN rule 1 action 'reject'", + "set firewall ipv4 name V4-IN rule 1 ipsec 'match-ipsec'", + "set firewall ipv4 name V4-IN rule 2 disable", + "set firewall ipv4 name V4-IN rule 2 action 'accept'", + "set firewall ipv4 name V4-IN rule 2 protocol 'icmp'", + "set firewall ipv4 name V4-IN rule 2 description 'Rule 102 is configured by Ansible RM'", + "set firewall ipv4 name V4-IN rule 2", + "set firewall ipv6 name V6-IN default-action 'accept'", + "set firewall ipv6 name V6-IN description 'This rule-set is configured by Ansible RM'", + "set firewall ipv6 name V6-EG default-action 'reject'", + "set firewall ipv6 name V6-EG description 'This rule-set is configured by Ansible RM'", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4v6_rule_sets_rule_ovr_02(self): + """Test that the plugin correctly resets the entire + rule sets configuration if changes are detected + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INGRESS", + description="This is IPv4 INGRESS rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + protocol="udp", + ), + ], + ), + ], + ), + dict( + afi="ipv6", + rule_sets=[ + dict( + name="EGRESS", + default_action="reject", + description="This rule-set is configured by Ansible RM", + rules=[ + dict( + number="20", + action="accept", + protocol="udp", + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + commands = [ + "delete firewall ipv6 name V6-INGRESS", + "delete firewall ipv6 name EGRESS", + "delete firewall ipv4 name V4-INGRESS", + "delete firewall ipv4 name EGRESS", + "delete firewall ipv4 input filter", + "delete firewall ipv4 output filter", + "delete firewall ipv6 input filter", + "delete firewall ipv6 output filter", + "delete firewall ipv4 name IF-TEST", + "set firewall ipv4 name V4-INGRESS rule 101", + "set firewall ipv4 name V4-INGRESS default-log", + "set firewall ipv4 name V4-INGRESS description 'This is IPv4 INGRESS rule set'", + "set firewall ipv4 name V4-INGRESS default-action 'accept'", + "set firewall ipv4 name V4-INGRESS rule 101 protocol 'udp'", + "set firewall ipv4 name V4-INGRESS rule 101 action 'accept'", + "set firewall ipv6 name EGRESS description 'This rule-set is configured by Ansible RM'", + "set firewall ipv6 name EGRESS default-action 'reject'", + "set firewall ipv6 name EGRESS rule 20", + "set firewall ipv6 name EGRESS rule 20 protocol 'udp'", + "set firewall ipv6 name EGRESS rule 20 action 'accept'" + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_v4v6_rule_sets_rule_ovr_idem_01(self): + """Test that the plugin is idempotent in overridden state + if there are no changes to the rule sets + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INGRESS", + description="This is IPv4 V4-INGRESS rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + packet_length_exclude=[dict(length=100), dict(length=300)], + protocol="icmp", + disable=True, + log="enable", + ) + ], + ), + dict( + filter="input", + rules=[ + dict( + number="1", + action="jump", + jump_target="INGRESS", + ), + ], + ), + dict( + filter="output", + rules=[ + dict( + number="1", + action="jump", + jump_target="EGRESS", + ), + ], + ), + dict( + name="IF-TEST", + rules=[ + dict( + number="10", + action="accept", + icmp=dict(type_name="echo-request"), + state=dict(related=True), + inbound_interface=dict(name="eth0"), + outbound_interface=dict(group="the-ethers"), + disable=True, + ) + ], + ), + dict( + name="EGRESS", + default_action="reject", + ), + ], + ), + dict( + afi="ipv6", + rule_sets=[ + dict( + name="V6-INGRESS", + default_action="accept", + ), + dict( + name="EGRESS", + default_action="reject", + rules=[ + dict( + icmp=dict(type_name="echo-request"), + number=20, + ), + ], + ), + dict( + filter="input", + rules=[ + dict( + number="1", + action="jump", + jump_target="V6-INGRESS", + ), + ], + ), + dict( + filter="output", + rules=[ + dict( + number="1", + action="jump", + jump_target="EGRESS", + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_vyos_firewall_v6_rule_sets_rule_merged_01_version(self): + """Test if plugin correctly adds ipv6 rule set with rules + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="INBOUND", + description="This is IPv6 INBOUND rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + ipsec="match-ipsec", + protocol="icmp", + disable=True, + icmp=dict(type_name="echo-request"), + log="enable", + ), + dict( + number="102", + action="reject", + description="Rule 102 is configured by Ansible", + protocol="ipv6-icmp", + icmp=dict(type=7), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "set firewall ipv6 name INBOUND default-action 'accept'", + "set firewall ipv6 name INBOUND description 'This is IPv6 INBOUND rule set'", + "set firewall ipv6 name INBOUND default-log", + "set firewall ipv6 name INBOUND rule 101 protocol 'icmp'", + "set firewall ipv6 name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv6 name INBOUND rule 101", + "set firewall ipv6 name INBOUND rule 101 disable", + "set firewall ipv6 name INBOUND rule 101 action 'accept'", + "set firewall ipv6 name INBOUND rule 101 ipsec 'match-ipsec'", + "set firewall ipv6 name INBOUND rule 101 icmpv6 type-name echo-request", + "set firewall ipv6 name INBOUND rule 101 log", + "set firewall ipv6 name INBOUND rule 102", + "set firewall ipv6 name INBOUND rule 102 action 'reject'", + "set firewall ipv6 name INBOUND rule 102 description 'Rule 102 is configured by Ansible'", + "set firewall ipv6 name INBOUND rule 102 protocol 'ipv6-icmp'", + 'set firewall ipv6 name INBOUND rule 102 icmpv6 type 7', + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_jump_rules_merged_01(self): + """Test if plugin correctly adds rule set with a jump action + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="INBOUND", + description="This is IPv6 INBOUND rule set with a jump action", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="jump", + description="Rule 101 is configured by Ansible", + ipsec="match-ipsec", + protocol="icmp", + icmp=dict(type_name="echo-request"), + jump_target="PROTECT-RE", + packet_length_exclude=[dict(length=100), dict(length=200)] + ), + dict( + number="102", + action="reject", + description="Rule 102 is configured by Ansible", + protocol="ipv6-icmp", + icmp=dict(type=7), + ), + ], + ), + ], + ) + ], + state="merged", + ) + ) + commands = [ + "set firewall ipv6 name INBOUND default-action 'accept'", + "set firewall ipv6 name INBOUND description 'This is IPv6 INBOUND rule set with a jump action'", + "set firewall ipv6 name INBOUND default-log", + "set firewall ipv6 name INBOUND rule 101 protocol 'icmp'", + "set firewall ipv6 name INBOUND rule 101 packet-length-exclude 100", + "set firewall ipv6 name INBOUND rule 101 packet-length-exclude 200", + "set firewall ipv6 name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv6 name INBOUND rule 101", + "set firewall ipv6 name INBOUND rule 101 ipsec 'match-ipsec'", + "set firewall ipv6 name INBOUND rule 101 icmpv6 type-name echo-request", + "set firewall ipv6 name INBOUND rule 101 action 'jump'", + "set firewall ipv6 name INBOUND rule 101 jump-target 'PROTECT-RE'", + "set firewall ipv6 name INBOUND rule 102", + "set firewall ipv6 name INBOUND rule 102 action 'reject'", + "set firewall ipv6 name INBOUND rule 102 description 'Rule 102 is configured by Ansible'", + "set firewall ipv6 name INBOUND rule 102 protocol 'ipv6-icmp'", + 'set firewall ipv6 name INBOUND rule 102 icmpv6 type 7', + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_log_merged_01(self): + """Test if new stanza log is correctly applied""" + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + rule_sets=[ + dict( + name="INBOUND", + description="This is IPv6 INBOUND rule set with a log", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + log="enable", + ), + ], + ), + ], + ) + ], + state="merged", + ) + ) + commands = [ + "set firewall ipv6 name INBOUND default-action 'accept'", + "set firewall ipv6 name INBOUND description 'This is IPv6 INBOUND rule set with a log'", + "set firewall ipv6 name INBOUND default-log", + "set firewall ipv6 name INBOUND rule 101 log", + "set firewall ipv6 name INBOUND rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv6 name INBOUND rule 101", + "set firewall ipv6 name INBOUND rule 101 action 'accept'", + ] + self.maxDiff = None + self.execute_module(changed=True, commands=commands) + + def test_vyos_firewall_log_replace_01(self): + """Test that stanza is correctly replaced + without touching the other stanzas + """ + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + rule_sets=[ + dict( + name="V4-INGRESS", + description="This is IPv4 V4-INGRESS rule set", + default_action="accept", + enable_default_log=True, + rules=[ + dict( + number="101", + action="accept", + description="Rule 101 is configured by Ansible", + packet_length_exclude=[dict(length=100), dict(length=200)], + packet_length=[dict(length=22)], + log="enable", + ), + ], + ), + ], + ) + ], + state="replaced", + ) + ) + commands = [ + "delete firewall ipv4 name V4-INGRESS rule 101", + "set firewall ipv4 name V4-INGRESS rule 101", + "set firewall ipv4 name V4-INGRESS rule 101 action 'accept'", + "set firewall ipv4 name V4-INGRESS rule 101 description 'Rule 101 is configured by Ansible'", + "set firewall ipv4 name V4-INGRESS rule 101 packet-length-exclude 100", + "set firewall ipv4 name V4-INGRESS rule 101 packet-length-exclude 200", + "set firewall ipv4 name V4-INGRESS rule 101 packet-length 22", + "set firewall ipv4 name V4-INGRESS rule 101 log", + ] + self.maxDiff = None + self.execute_module(changed=True, commands=commands) |