summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/module_utils/network/vyos/config/firewall_rules/firewall_rules.py120
-rw-r--r--plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py11
2 files changed, 113 insertions, 18 deletions
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 106b2b8b..68ceff80 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 1fc70255..3da70891 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