Page MenuHomeVyOS Platform

No OneTemporary

Size
150 KB
Referenced Files
None
Subscribers
None
diff --git a/plugins/module_utils/network/vyos/config/ha/ha.py b/plugins/module_utils/network/vyos/config/ha/ha.py
index 35eeaf3b..22ca70ad 100644
--- a/plugins/module_utils/network/vyos/config/ha/ha.py
+++ b/plugins/module_utils/network/vyos/config/ha/ha.py
@@ -1,645 +1,647 @@
#
# -*- coding: utf-8 -*-
# Copyright 2021 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#
from __future__ import absolute_import, division, print_function
__metaclass__ = type
"""
The vyos_ha config file.
It is in this file where the current configuration (as dict)
is compared to the provided configuration (as dict) and the command set
necessary to bring the current configuration to its desired end-state is
created.
"""
from copy import deepcopy
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
)
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
remove_empties,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.ha import (
HaTemplate,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import combine
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import (
LooseVersion,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import get_os_version
class Ha(ResourceModule):
"""
The vyos_ha config class
"""
def __init__(self, module):
super(Ha, self).__init__(
empty_fact_val={},
facts_module=Facts(module),
module=module,
resource="ha",
tmplt=HaTemplate(),
)
self.parsers = [
"disable",
]
def _validate_template(self):
version = get_os_version(self._module)
if LooseVersion(version) >= LooseVersion("1.4"):
self._tmplt = HaTemplate()
else:
self._module.fail_json(msg="High Availability is not supported in this version of VyOS")
def parse(self):
"""override parse to check template"""
self._validate_template()
return super().parse()
def get_parser(self, name):
"""get_parsers"""
self._validate_template()
return super().get_parser(name)
def execute_module(self):
"""Execute the module
:rtype: A dictionary
:returns: The result from module execution
"""
if self.state not in ["parsed", "gathered", "purged"]:
self.generate_commands()
self.run_commands()
if self.state == "purged":
wantd = {"disable": False}
haved = deepcopy(self.have)
if wantd != haved:
self.commands = ["delete high-availability"]
self.run_commands()
if "before" in self.result:
self._normalize_lists(self.result["before"])
if "after" in self.result:
self._normalize_lists(self.result["after"])
if "parsed" in self.result:
self._normalize_lists(self.result["parsed"])
return self.result
def generate_commands(self):
"""Generate configuration commands to send based on
want, have and desired state.
"""
wantd = {}
haved = {}
wantd = deepcopy(self.want)
haved = deepcopy(self.have)
for entry in wantd, haved:
self._vrrp_groups_list_to_dict(entry)
self._virtual_servers_list_to_dict(entry)
self._vrrp_sync_groups_list_to_dict(entry)
self._normalize_lists(entry)
if self.state in ["deleted"]:
wantd, haved, p = self._prune_stubs(self._module.params.get("config", {}), haved)
if self.state in ["overridden"]:
wo = deepcopy(wantd)
self._diff_w_h(wo, haved)
haved_disable = haved.get("disable")
for k1, v1 in wo.items():
if not isinstance(v1, dict):
continue
for name, obj in v1.items():
if isinstance(obj, dict) and not obj:
wi, hi, pi = self._prune_stubs({k1: {name: {}}}, haved)
haved = hi
for k2, v2 in v1.items():
if not isinstance(v2, dict):
continue
for name, obj in v2.items():
if isinstance(obj, dict) and not obj:
wi, hi, pi = self._prune_stubs({k1: {k2: {name: {}}}}, haved)
haved = hi
if haved_disable is not None:
haved["disable"] = haved_disable
keys = set(wantd) | set(haved)
for k in keys:
want = wantd.get(k, {})
have = haved.get(k, {})
if k == "vrrp":
if self.state in ["merged"]:
want = combine(have, want, recursive=True, list_merge="append_rp")
self._compare_vrrp(want, have)
if k == "virtual_servers":
if self.state in ["merged"]:
want = combine(have, want, recursive=True)
self._compare_vsrvs(want, have)
if self.state in ["deleted"] and k == "disable":
want = have
if self.state in ["overridden"] and k == "disable" and not want:
want = False
if self.state in ["rendered"]:
have = None
self.compare(
parsers=self.parsers,
want={k: want},
have={k: have},
)
self.commands = sorted(list(dict.fromkeys(self.commands)))
def _compare_vsrvs(self, want, have):
"""Compare virtual servers of VRRP"""
vs_parsers = [
"virtual_servers.address",
"virtual_servers.algorithm",
"virtual_servers.delay_loop",
"virtual_servers.forward_method",
"virtual_servers.persistence_timeout",
"virtual_servers.fwmark",
"virtual_servers.port",
"virtual_servers.protocol",
"virtual_servers.real_server.port",
"virtual_servers.real_server.health_check_script",
"virtual_servers.real_server.connection_timeout",
]
hlist = self._extract_named_leafs(have)
wlist = self._extract_named_leafs(want)
if self.state == "rendered":
hlist = []
if self.state in ["replaced", "deleted"]:
for hdict in hlist:
wdict = self._find_matching_vsrv(hdict, wlist)
if self.state == "deleted" and wdict:
wdict = {}
elif not wdict:
hdict = {}
self.compare(
parsers=vs_parsers,
want={"virtual_servers": wdict},
have={"virtual_servers": hdict},
)
if self.state in ["merged", "replaced", "rendered", "overridden"]:
for wdict in wlist:
hdict = self._find_matching_vsrv(wdict, hlist)
self.compare(
parsers=vs_parsers,
want={"virtual_servers": wdict},
have={"virtual_servers": hdict},
)
def _compare_vrrp(self, want, have):
"""Compare the instances of VRRP"""
vrrp_parsers = [
"vrrp.snmp",
"vrrp.global_parameters",
"vrrp.global_parameters.garp",
"vrrp.groups",
"vrrp.groups.disable",
"vrrp.groups.no_preempt",
"vrrp.groups.rfc3768_compatibility",
"vrrp.groups.address",
"vrrp.groups.excluded_address",
"vrrp.groups.garp",
"vrrp.groups.authentication",
"vrrp.groups.transition_script",
"vrrp.groups.health_check",
"vrrp.groups.track.interface",
"vrrp.groups.track.exclude_vrrp_interface",
"vrrp.sync_groups.member",
"vrrp.sync_groups.transition_script",
"vrrp.sync_groups.health_check",
]
if (
have.get("snmp") == "enabled"
and want.get("snmp") != "enabled"
and self.state not in ["deleted", "overridden"]
):
self.commands.append("delete high-availability vrrp snmp")
hlist = self._extract_leaf_items(have)
wlist = self._extract_leaf_items(want)
if self.state == "rendered":
hlist = []
if self.state in ["replaced", "deleted"]:
for hdict in hlist:
wdict = self._find_matching_vrrp(hdict, wlist)
if self.state == "deleted" and wdict:
wdict = {}
+ if self.state == "replaced" and wdict and wdict != hdict:
+ wdict = {}
elif not wdict:
hdict = {}
self.compare(parsers=vrrp_parsers, want={"vrrp": wdict}, have={"vrrp": hdict})
if self.state in ["merged", "replaced", "rendered", "overridden"]:
for wdict in wlist:
hdict = self._find_matching_vrrp(wdict, hlist)
self.compare(parsers=vrrp_parsers, want={"vrrp": wdict}, have={"vrrp": hdict})
def _vrrp_groups_list_to_dict(self, data):
vrrp = data.get("vrrp", {})
groups = vrrp.get("groups")
if not groups:
return data
if isinstance(groups, dict):
return data
if isinstance(groups, list):
new_groups = {}
for item in groups:
name = item.get("name")
if not name:
continue
new_groups[name] = item
data["vrrp"]["groups"] = new_groups
return data
return data
def _vrrp_sync_groups_list_to_dict(self, data):
vrrp = data.get("vrrp", {})
groups = vrrp.get("sync_groups")
if not groups:
return data
if isinstance(groups, dict):
return data
if isinstance(groups, list):
new_groups = {}
for item in groups:
name = item.get("name")
if not name:
continue
new_groups[name] = item
data["vrrp"]["sync_groups"] = new_groups
return data
return data
def _virtual_servers_list_to_dict(self, data):
vss = data.get("virtual_servers")
if not vss:
return data
if isinstance(vss, dict):
for vs in vss.items():
rs = vs.get("real_server")
if isinstance(rs, list):
vs["real_server"] = {
item["address"]: item
for item in rs
if isinstance(item, dict) and item.get("address")
}
return data
if isinstance(vss, list):
new_vss = {}
for vs in vss:
if not isinstance(vs, dict):
continue
name = vs.get("name")
if not name:
continue
rs = vs.get("real_server")
if isinstance(rs, list):
vs["real_server"] = {
item["address"]: item
for item in rs
if isinstance(item, dict) and item.get("address")
}
new_vss[name] = vs
data["virtual_servers"] = new_vss
return data
return data
def _extract_leaf_items(self, data, path=None, parent_name=None):
path = path or []
results = []
if isinstance(data, dict):
current_name = data.get("name", parent_name)
for k, v in data.items():
if k == "name" or (k == "snmp" and v == "disabled"):
continue
results.extend(self._extract_leaf_items(v, path + [k], current_name))
return results
leaf_key = path[-1]
top_key = path[0]
if top_key in ["groups", "sync_groups"]:
subkeys = path[2:]
else:
subkeys = path[1:]
nested = {leaf_key: data}
for p in reversed(subkeys[:-1]):
nested = {p: nested}
if parent_name:
out = {top_key: {"name": parent_name}}
out[top_key].update(nested)
else:
out = {top_key: nested}
results.append(out)
return results
def _find_matching_vsrv(self, want_item, have_list):
def build_sig(item):
if not isinstance(item, dict):
return None
name = item.get("name")
if not name:
return None
if "real_server" in item:
rs = item["real_server"]
if not isinstance(rs, dict) or "address" not in rs:
return None
addr = rs["address"]
for k in rs:
if k != "address":
return ("real_server", name, addr, k)
return ("real_server", name, addr, None)
for k in item:
if k != "name":
return ("attr", name, k)
return None
sig_want = build_sig(want_item)
for obj in have_list:
if build_sig(obj) == sig_want:
return obj
return {}
def _find_matching_vrrp(self, want_item, have_list):
def build_sig(item):
if not isinstance(item, dict) or not item:
return ()
container = next(iter(item))
inner = item[container]
sig = [container]
if isinstance(inner, dict) and "name" in inner:
sig.append(("name", inner["name"]))
if isinstance(inner, dict):
for k, v in inner.items():
if k == "name":
continue
if not isinstance(v, dict):
sig.append(k)
break
sig.append(k)
for leaf in v:
sig.append(leaf)
break
break
return tuple(sig)
sig_want = build_sig(want_item)
for obj in have_list:
if build_sig(obj) == sig_want:
return obj
return {}
def _normalize_lists(self, node):
"""
Recursively normalize all lists inside a dict or list.
All lists are sorted to ensure consistent ordering for comparison.
"""
if isinstance(node, dict):
for k, v in node.items():
if isinstance(v, list):
if all(not isinstance(i, (dict, list)) for i in v):
node[k] = sorted(v)
else:
for item in v:
self._normalize_lists(item)
elif isinstance(v, dict):
self._normalize_lists(v)
elif isinstance(node, list):
for item in node:
self._normalize_lists(item)
def _extract_named_leafs(self, data, parent_name=None, prefix_key=None):
results = []
if prefix_key == "real_server" and isinstance(data, dict):
for d, server_data in data.items():
if not isinstance(server_data, dict):
continue
address = server_data.get("address")
if not address:
continue
for k, v in server_data.items():
if k == "address":
continue
results.append(
{
"name": parent_name,
"real_server": {
"address": address,
k: v,
},
},
)
return results
if isinstance(data, dict):
current_name = data.get("name", parent_name)
for k, v in data.items():
if k == "name":
continue
results.extend(
self._extract_named_leafs(v, current_name, k),
)
return results
return [
{
"name": parent_name,
prefix_key: data,
},
]
def _prune_stubs(self, w, h, path=""):
wc = {}
hc = self._remove_defaults(h)
if not self._remove_defaults(w) and remove_empties(hc):
self.commands = ["delete high-availability"]
return {}, {}, path
for k, wg in (self._remove_defaults(w) or {}).items():
next_path = f"{path} {k}".strip()
stub = self._cli_path(next_path)
hg = remove_empties(hc).get(k)
if hg is None:
continue
if not isinstance(wg, (dict, list)):
self.commands.append(f"delete high-availability {stub}")
hc.pop(k, None)
wc.pop(k, None)
continue
if not wg:
self.commands.append(f"delete high-availability {stub}")
hc.pop(k, None)
wc.pop(k, None)
continue
if isinstance(wg, list) and isinstance(hg, dict):
for item in wg:
name = item.get("name")
if not name:
continue
if name in hg:
self.commands.append(
f"delete high-availability {stub} {name}",
)
hg.pop(name, None)
if hg:
hc[k] = hg
else:
hc.pop(k, None)
if self._remove_defaults(wg):
wc[k] = wg
else:
wc.pop(k, None)
continue
if isinstance(wg, dict) and isinstance(hg, dict):
wi, hi, p = self._prune_stubs(wg, hg, next_path)
if wi:
wc[k] = wi
if hi:
hc[k] = hi
else:
hc.pop(k, None)
return wc, hc, path
def _remove_defaults(self, data):
if isinstance(data, dict):
cleaned = {}
for k, v in data.items():
if v in [None, False, "disabled"]:
continue
v = self._remove_defaults(v)
cleaned[k] = v
return cleaned
return data
def _cli_path(self, path):
token_map = {
"groups": "group",
"sync_groups": "sync-group",
"virtual_servers": "virtual-server",
}
parts = []
for p in path.split():
p = token_map.get(p, p)
parts.append(p.replace("_", "-"))
return " ".join(parts)
def _diff_w_h(self, w, h):
NAMED_OBJECT_KEYS = {
"groups",
"sync_groups",
"virtual_servers",
"global_parameters",
}
if not isinstance(w, dict) or not isinstance(h, dict):
return w
for key in w.keys() & h.keys():
wv = w[key]
hv = h[key]
if key in NAMED_OBJECT_KEYS and isinstance(wv, dict) and isinstance(hv, dict):
for name in wv.keys() & hv.keys():
if wv[name] != hv[name] and isinstance(wv[name], (dict, list)):
wv[name] = {}
elif wv[name] != hv[name]:
wv[name] = None
continue
self._diff_w_h(wv, hv)
return w
diff --git a/plugins/module_utils/network/vyos/rm_templates/ha.py b/plugins/module_utils/network/vyos/rm_templates/ha.py
index dc7c0c86..04ac03e0 100644
--- a/plugins/module_utils/network/vyos/rm_templates/ha.py
+++ b/plugins/module_utils/network/vyos/rm_templates/ha.py
@@ -1,1010 +1,1008 @@
# -*- coding: utf-8 -*-
# Copyright 2021 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
"""
The Ha parser templates file. This contains
a list of parser definitions and associated functions that
facilitates both facts gathering and native command generation for
the given network resource.
"""
import re
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
NetworkTemplate,
)
def _tmplt_vsrvs(config_data):
config_data = config_data["virtual_servers"]
command = []
cmd = "high-availability virtual-server {name}".format(**config_data)
for key, value in config_data.items():
if key == "name" or isinstance(value, dict) or value is None:
continue
else:
command.append(f"{cmd} {key.replace('_', '-')} {value}")
return command
def _tmplt_vsrvs_rsrv(config_data):
config_data = config_data["virtual_servers"]
command = []
cmd = "high-availability virtual-server {name}".format(**config_data)
config_data = config_data["real_server"]
address = config_data["address"]
for key, value in config_data.items():
if key == "address" or value is None:
continue
if value is not None and key == "health_check_script":
command.append(cmd + " real-server " + address + " health-check script " + value)
else:
command.append(cmd + " real-server " + f"{address} {key.replace('_', '-')} {value}")
return command
def _tmplt_vrrp_sgroup_hc(config_data):
config_data = config_data["vrrp"]["sync_groups"]
command = []
cmd = "high-availability vrrp sync-group {name}".format(**config_data)
config_data = config_data["health_check"]
for key, value in config_data.items():
if value is not None:
command.append(cmd + " health-check " + f"{key.replace('_', '-')} {value}")
return command
def _tmplt_vrrp_sgroup_ts(config_data):
config_data = config_data["vrrp"]["sync_groups"]
command = []
cmd = "high-availability vrrp sync-group {name}".format(**config_data)
config_data = config_data["transition_script"]
for key, value in config_data.items():
if value is not None:
command.append(cmd + " transition-script " + f"{key.replace('_', '-')} {value}")
return command
def _tmplt_vrrp_gp(config_data):
config_data = config_data["vrrp"]["global_parameters"]
command = []
cmd = "high-availability vrrp global-parameters".format(**config_data)
for key, value in config_data.items():
if isinstance(value, dict) or value is None:
continue
else:
command.append(f"{cmd} {key.replace('_', '-')} {value}")
return command
def _tmplt_vrrp_gp_garp(config_data):
config_data = config_data["vrrp"]["global_parameters"]["garp"]
command = []
cmd = "high-availability vrrp global-parameters garp"
for key, value in config_data.items():
if value is None:
continue
command.append(f"{cmd} {key.replace('_', '-')} {value}")
return command
def _tmplt_vrrp_group(config_data):
config_data = config_data["vrrp"]["groups"]
command = []
cmd = "high-availability vrrp group {name}".format(**config_data)
for key, value in config_data.items():
if (
key == "name"
or isinstance(value, dict)
or isinstance(value, list)
or isinstance(value, bool)
or value is None
):
continue
else:
if key == "description":
value = f"'{value}'"
command.append(f"{cmd} {key.replace('_', '-')} {value}")
return command
def _tmplt_vrrp_group_bool(config_data):
config_data = config_data["vrrp"]["groups"]
command = []
cmd = "high-availability vrrp group {name}".format(**config_data)
for key, value in config_data.items():
if key != "name" and value is not None:
command.append(f"{cmd} {key.replace('_', '-')}")
return command
def _tmplt_vrrp_group_garp(config_data):
config_data = config_data["vrrp"]["groups"]
command = []
cmd = "high-availability vrrp group {name}".format(**config_data)
config_data = config_data["garp"]
for key, value in config_data.items():
if value is not None:
command.append(cmd + " garp " + f"{key.replace('_', '-')} {value}")
return command
def _tmplt_vrrp_group_auth(config_data):
config_data = config_data["vrrp"]["groups"]
command = []
cmd = "high-availability vrrp group {name}".format(**config_data)
config_data = config_data["authentication"]
for key, value in config_data.items():
if value is not None:
command.append(cmd + " authentication " + f"{key.replace('_', '-')} {value}")
return command
def _tmplt_vrrp_group_ts(config_data):
config_data = config_data["vrrp"]["groups"]
command = []
cmd = "high-availability vrrp group {name}".format(**config_data)
config_data = config_data["transition_script"]
for key, value in config_data.items():
if value is not None:
command.append(cmd + " transition-script " + f"{key.replace('_', '-')} {value}")
return command
def _tmplt_vrrp_sgroup_member(config_data):
sgroup = config_data["vrrp"]["sync_groups"]
command = []
cmd = "high-availability vrrp sync-group {name}".format(**sgroup)
members = sgroup.get("member", [])
for member in members:
if member is None:
continue
command.append(f"{cmd} member {member}")
return command
def _tmplt_vrrp_group_exaddress(config_data):
group = config_data["vrrp"]["groups"]
command = []
cmd = "high-availability vrrp group {name}".format(**group)
exaddresses = group.get("excluded_address", [])
for exaddress in exaddresses:
if exaddress is None:
continue
command.append(f"{cmd} excluded-address {exaddress}")
return command
def _tmplt_vrrp_group_address(config_data):
group = config_data["vrrp"]["groups"]
command = []
cmd = "high-availability vrrp group {name}".format(**group)
addresses = group.get("address", [])
for address in addresses:
if address is None:
continue
command.append(f"{cmd} address {address}")
return command
def _tmplt_vrrp_group_hc(config_data):
config_data = config_data["vrrp"]["groups"]
command = []
cmd = "high-availability vrrp group {name}".format(**config_data)
config_data = config_data["health_check"]
for key, value in config_data.items():
if value is not None:
command.append(cmd + " health-check " + f"{key.replace('_', '-')} {value}")
return command
def _tmplt_vrrp_group_track_list(config_data):
config_data = config_data["vrrp"]["groups"]
command = []
cmd = "high-availability vrrp group {name}".format(**config_data)
config_data = config_data["track"]
for key, value in config_data.items():
if isinstance(value, list) and value is not None and key != "name":
for item in value:
command.append(cmd + " track " + f"{key.replace('_', '-')} {item}")
return command
def _tmplt_vrrp_group_track_bool(config_data):
config_data = config_data["vrrp"]["groups"]
command = []
cmd = "high-availability vrrp group {name}".format(**config_data)
config_data = config_data["track"]
for key, value in config_data.items():
if key != "name" and value is not None:
command.append(cmd + " track " + f"{key.replace('_', '-')}")
return command
class HaTemplate(NetworkTemplate):
def __init__(self, lines=None, module=None):
prefix = {"set": "set", "remove": "delete"}
super(HaTemplate, self).__init__(
lines=lines,
tmplt=self,
prefix=prefix,
module=module,
)
# fmt: off
PARSERS = [
{
"name": "disable",
"getval": re.compile(
r"""
^set
\shigh-availability
\s(?P<disable>disable)
$""",
re.VERBOSE,
),
"setval": "high-availability disable",
"result": {
"disable": "{{ True if disable is defined else False }}",
},
},
{
"name": "virtual_servers.address",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
(?:\s+address\s+(?P<address>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"address": "{{ address if address is defined else None }}",
},
},
},
},
{
"name": "virtual_servers.algorithm",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
(?:\s+algorithm\s+(?P<algorithm>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"algorithm": "{{ algorithm if algorithm is defined else None }}",
},
},
},
},
{
"name": "virtual_servers.delay_loop",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
(?:\s+delay-loop\s+(?P<delay_loop>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"delay_loop": "{{ delay_loop if delay_loop is defined else None }}",
},
},
},
},
{
"name": "virtual_servers.forward_method",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
(?:\s+forward-method\s+(?P<forward_method>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"forward_method": "{{ forward_method if forward_method is defined else None }}",
},
},
},
},
{
"name": "virtual_servers.fwmark",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
(?:\s+fwmark\s+(?P<fwmark>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"fwmark": "{{ fwmark if fwmark is defined else None }}",
},
},
},
},
{
"name": "virtual_servers.persistence_timeout",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
(?:\s+persistence-timeout\s+(?P<persistence_timeout>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"persistence_timeout": "{{ persistence_timeout if persistence_timeout is defined else None }}",
},
},
},
},
{
"name": "virtual_servers.port",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
(?:\s+port\s+(?P<port>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"port": "{{ port if port is defined else None }}",
},
},
},
},
{
"name": "virtual_servers.protocol",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
(?:\s+protocol\s+(?P<protocol>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"protocol": "{{ protocol if protocol is defined else None }}",
},
},
},
},
{
"name": "virtual_servers.real_server.port",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
\sreal-server
\s+(?P<address>\S+)
(?:\s+port\s+(?P<port>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs_rsrv,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"real_server": {
"{{ address }}": {
"address": "{{ address }}",
"port": "{{ port if port is defined else None }}",
},
},
},
},
},
},
{
"name": "virtual_servers.real_server.health_check_script",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
\sreal-server
\s+(?P<address>\S+)
(?:\s+health-check\sscript\s+(?P<hcscript>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs_rsrv,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"real_server": {
"{{ address }}": {
"address": "{{ address }}",
"health_check_script": "{{ hcscript if hcscript is defined else None }}",
},
},
},
},
},
},
{
"name": "virtual_servers.real_server.connection_timeout",
"getval": re.compile(
r"""
^set\shigh-availability\svirtual-server
\s+(?P<name>\S+)
\sreal-server
\s+(?P<address>\S+)
(?:\s+connection-timeout\s+(?P<cont>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vsrvs_rsrv,
"result": {
"virtual_servers": {
"{{ name }}": {
"name": "{{ name }}",
"real_server": {
"{{ address }}": {
"address": "{{ address }}",
"connection_timeout": "{{ cont if cont is defined else None }}",
},
},
},
},
},
},
{
"name": "vrrp.sync_groups.member",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\ssync-group
\s+(?P<sgname>\S+)
\smember
\s+(?P<member>\S+)
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_sgroup_member,
"result": {
"vrrp": {
"sync_groups": {
"{{ sgname }}": {
"name": "{{ sgname }}",
"member": [
"{{ member }}",
],
},
},
},
},
},
{
"name": "vrrp.sync_groups.health_check",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\ssync-group
\s+(?P<sgname>\S+)
\shealth-check
(?:\s+failure-count\s+(?P<failure_count>\S+))
?(?:\s+interval\s+(?P<int>\S+))
?(?:\s+ping\s+(?P<ping>\S+))
?(?:\s+script\s+(?P<script>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_sgroup_hc,
"result": {
"vrrp": {
"sync_groups": {
"{{ sgname }}": {
"name": "{{ sgname }}",
"health_check": {
"failure_count": "{{ failure_count if failure_count is defined else None }}",
"interval": "{{ int if int is defined else None }}",
"ping": "{{ ping if ping is defined else None }}",
"script": "{{ script if script is defined else None }}",
},
},
},
},
},
},
{
"name": "vrrp.sync_groups.transition_script",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\ssync-group
\s+(?P<sgname>\S+)
\stransition-script
(?:\s+backup\s+(?P<backup>\S+))?
(?:\s+fault\s+(?P<fault>\S+))?
(?:\s+master\s+(?P<master>\S+))?
(?:\s+stop\s+(?P<stop>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_sgroup_ts,
"result": {
"vrrp": {
"sync_groups": {
"{{ sgname }}": {
"name": "{{ sgname }}",
"transition_script": {
"backup": "{{ backup if backup is defined else None }}",
"fault": "{{ fault if fault is defined else None }}",
"master": "{{ master if master is defined else None }}",
"stop": "{{ stop if stop is defined else None }}",
},
},
},
},
},
},
{
"name": "vrrp.global_parameters.garp",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sglobal-parameters
\s+garp
(?:\s+interval\s+(?P<interval>\S+))?
(?:\s+master-delay\s+(?P<master_delay>\S+))?
(?:\s+master-refresh\s+(?P<master_refresh>\S+))?
(?:\s+master-refresh-repeat\s+(?P<master_refresh_repeat>\S+))?
(?:\s+master-repeat\s+(?P<master_repeat>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_gp_garp,
"result": {
"vrrp": {
"global_parameters": {
"garp": {
"interval": "{{ interval if interval is defined else None }}",
"master_delay": "{{ master_delay if master_delay is defined else None }}",
"master_refresh": "{{ master_refresh if master_refresh is defined else None }}",
"master_refresh_repeat": "{{ master_refresh_repeat if master_refresh_repeat is defined else None }}",
"master_repeat": "{{ master_repeat if master_repeat is defined else None }}",
},
},
},
},
},
{
"name": "vrrp.global_parameters",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sglobal-parameters
(?:\s+startup-delay\s+(?P<startup_delay>\S+))?
(?:\s+version\s+(?P<version>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_gp,
"result": {
"vrrp": {
"global_parameters": {
"startup_delay": "{{ startup_delay if startup_delay is defined else None }}",
"version": "{{ version if version is defined else None }}",
},
},
},
},
{
"name": "vrrp.groups",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sgroup
\s+(?P<gname>\S+)
- # (?:\s+address\s+(?P<address>\S+))?
(?:\s+description\s+(?P<description>'.+?'|\S+))?
(?:\s+advertise-interval\s+(?P<advertise_interval>\S+))?
(?:\s+hello-source-address\s+(?P<hello_source>\S+))?
(?:\s+interface\s+(?P<interface>\S+))?
(?:\s+peer-address\s+(?P<peer_address>\S+))?
(?:\s+priority\s+(?P<priority>\S+))?
(?:\s+vrid\s+(?P<vrid>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"name": "{{ gname }}",
- # "address": "{{ address if address is defined else None }}",
"description": "{{ description if description is defined else None }}",
"advertise_interval": "{{ advertise_interval if advertise_interval is defined else None }}",
"hello_source_address": "{{ hello_source if hello_source is defined else None }}",
"interface": "{{ interface if interface is defined else None }}",
"peer_address": "{{ peer_address if peer_address is defined else None }}",
"priority": "{{ priority if priority is defined else None }}",
"vrid": "{{ vrid if vrid is defined else None }}",
},
},
},
},
},
{
"name": "vrrp.groups.excluded_address",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sgroup
\s+(?P<gname>\S+)
\sexcluded-address
\s+(?P<excluded_address>.*)
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_exaddress,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"name": "{{ gname }}",
"excluded_address": [
"{{ excluded_address | replace(\"'\", \"\") }}",
],
},
},
},
},
},
{
"name": "vrrp.groups.address",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sgroup
\s+(?P<gname>\S+)
\saddress
\s+(?P<address>.*)
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_address,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"name": "{{ gname }}",
"address": [
"{{ address | replace(\"'\", \"\") }}",
],
},
},
},
},
},
{
"name": "vrrp.groups.garp",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sgroup
\s+(?P<gname>\S+)
\s+garp
(?:\s+interval\s+(?P<interval>\S+))?
(?:\s+master-delay\s+(?P<master_delay>\S+))?
(?:\s+master-refresh\s+(?P<master_refresh>\S+))?
(?:\s+master-refresh-repeat\s+(?P<master_refresh_repeat>\S+))?
(?:\s+master-repeat\s+(?P<master_repeat>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_garp,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"name": "{{ gname }}",
"garp": {
"interval": "{{ interval if interval is defined else None }}",
"master_delay": "{{ master_delay if master_delay is defined else None }}",
"master_refresh": "{{ master_refresh if master_refresh is defined else None }}",
"master_refresh_repeat": "{{ master_refresh_repeat if master_refresh_repeat is defined else None }}",
"master_repeat": "{{ master_repeat if master_repeat is defined else None }}",
},
},
},
},
},
},
{
"name": "vrrp.groups.authentication",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sgroup
\s+(?P<gname>\S+)
\s+authentication
(?:\s+password\s+(?P<password>\S+))?
(?:\s+type\s+(?P<type>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_auth,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"name": "{{ gname }}",
"authentication": {
"password": "{{ password if password is defined else None }}",
"type": "{{ type if type is defined else None }}",
},
},
},
},
},
},
{
"name": "vrrp.groups.transition_script",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sgroup
\s+(?P<gname>\S+)
\stransition-script
(?:\s+backup\s+(?P<backup>\S+))?
(?:\s+fault\s+(?P<fault>\S+))?
(?:\s+master\s+(?P<master>\S+))?
(?:\s+stop\s+(?P<stop>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_ts,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"name": "{{ gname }}",
"transition_script": {
"backup": "{{ backup if backup is defined else None }}",
"fault": "{{ fault if fault is defined else None }}",
"master": "{{ master if master is defined else None }}",
"stop": "{{ stop if stop is defined else None }}",
},
},
},
},
},
},
{
"name": "vrrp.groups.health_check",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sgroup
\s+(?P<gname>\S+)
\shealth-check
(?:\s+failure-count\s+(?P<failure_count>\S+))
?(?:\s+interval\s+(?P<int>\S+))
?(?:\s+ping\s+(?P<ping>\S+))
?(?:\s+script\s+(?P<script>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_hc,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"name": "{{ gname }}",
"health_check": {
"failure_count": "{{ failure_count if failure_count is defined else None }}",
"interval": "{{ int if int is defined else None }}",
"ping": "{{ ping if ping is defined else None }}",
"script": "{{ script if script is defined else None }}",
},
},
},
},
},
},
{
"name": "vrrp.groups.track.interface",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sgroup
\s+(?P<gname>\S+)
\strack
(?:\s+interface\s+(?P<interface>\S+))?
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_track_list,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"name": "{{ gname }}",
"track": {
"interface": "{{ [interface.strip(\"'\")] if interface is defined else [] }}",
},
},
},
},
},
},
{
"name": "vrrp.snmp",
"getval": re.compile(
r"""
^set
\shigh-availability
\svrrp
\s(?P<snmp>snmp)
$""",
re.VERBOSE,
),
"setval": "high-availability vrrp snmp",
"result": {
"vrrp": {
"snmp": "{{ 'enabled' if snmp is defined else 'disabled' }}",
},
},
},
{
"name": "vrrp.groups.disable",
"getval": re.compile(
r"""
^set
\shigh-availability\svrrp\sgroup
\s(?P<gname>\S+)
\s(?P<disable>disable)
$""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_bool,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"disable": "{{ True if disable is defined else False }}",
},
},
},
},
},
{
"name": "vrrp.groups.no_preempt",
"getval": re.compile(
r"""
^set
\shigh-availability\svrrp\sgroup
\s(?P<gname>\S+)
\s(?P<no_preempt>no-preempt)
$""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_bool,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"no_preempt": "{{ True if no_preempt is defined else False }}",
},
},
},
},
},
{
"name": "vrrp.groups.rfc3768_compatibility",
"getval": re.compile(
r"""
^set
\shigh-availability\svrrp\sgroup
\s(?P<gname>\S+)
\s(?P<rfc3768_compatibility>rfc3768-compatibility)
$""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_bool,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"rfc3768_compatibility": "{{ True if rfc3768_compatibility is defined else False }}",
},
},
},
},
},
{
"name": "vrrp.groups.track.exclude_vrrp_interface",
"getval": re.compile(
r"""
^set\shigh-availability\svrrp\sgroup
\s+(?P<gname>\S+)
\strack
\s(?P<exclude_vrrp_inter>exclude-vrrp-interface)
$
""",
re.VERBOSE,
),
"setval": _tmplt_vrrp_group_track_bool,
"result": {
"vrrp": {
"groups": {
"{{ gname }}": {
"name": "{{ gname }}",
"track": {
"exclude_vrrp_interface": "{{ True if exclude_vrrp_inter is defined else False }}",
},
},
},
},
},
},
]
# fmt: on
diff --git a/tests/integration/targets/vyos_ha/vars/main.yaml b/tests/integration/targets/vyos_ha/vars/main.yaml
index f8994056..b8b4c802 100644
--- a/tests/integration/targets/vyos_ha/vars/main.yaml
+++ b/tests/integration/targets/vyos_ha/vars/main.yaml
@@ -1,779 +1,783 @@
---
merged:
before:
disable: false
virtual_servers:
- name: s1
address: 10.10.10.1
algorithm: "round-robin"
delay_loop: 60
forward_method: direct
fwmark: 10
persistence_timeout: 30
protocol: tcp
real_server:
- address: 10.10.50.1
health_check_script: "/var/tmp/script.sh"
port: 443
- name: s2
address: 10.10.10.2
port: 81
real_server:
- address: real1
connection_timeout: 5
port: 8081
- address: real2
port: 8080
vrrp:
global_parameters:
startup_delay: 31
version: "3"
garp:
interval: 30
master_delay: 10
master_refresh: 100
master_refresh_repeat: 200
master_repeat: 5
groups:
- name: "g1"
description: "Group_1"
interface: "eth2"
address:
- "1.1.1.1"
- "5.5.5.5"
- "8.8.8.8 interface eth2"
advertise_interval: 10
peer_address: 192.168.1.3
priority: 100
disable: true
no_preempt: true
rfc3768_compatibility: true
vrid: 20
excluded_address:
- "192.168.1.7 interface eth3"
- "192.168.1.8"
garp:
interval: 20
master_delay: 5
master_refresh: 50
master_refresh_repeat: 100
master_repeat: 3
authentication:
type: "plaintext-password"
password: "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
transition_script:
master: "/var/tmp/script.sh"
backup: "/var/tmp/script.sh"
fault: "/var/tmp/script.sh"
stop: "/var/tmp/script.sh"
track:
exclude_vrrp_interface: true
interface:
- eth0
- eth1
- name: "g2"
description: "Group_2"
interface: "eth1"
address:
- "2.2.2.2"
disable: false
no_preempt: false
rfc3768_compatibility: false
vrid: 11
health_check:
failure_count: 5
interval: 15
ping: "192.168.1.100"
script: "/var/tmp/script.sh"
hello_source_address: "2.2.2.2"
sync_groups:
- name: "sg1"
member:
- "g1"
- "g2"
transition_script:
master: "/var/tmp/script.sh"
backup: "/var/tmp/script.sh"
fault: "/var/tmp/script.sh"
stop: "/var/tmp/script.sh"
health_check:
failure_count: 3
interval: 10
ping: "192.168.2.100"
script: "/var/tmp/script.sh"
config:
disable: true
virtual_servers:
- name: s1
address: 10.10.10.5
algorithm: round-robin
real_server:
- address: 10.10.50.2
port: 8443
- name: s2
address: 10.10.10.2
persistence_timeout: 30
port: 81
protocol: tcp
- name: s3
address: 10.10.10.3
port: 88
protocol: udp
vrrp:
snmp: enabled
global_parameters:
startup_delay: 30
garp:
master_repeat: 6
groups:
- name: "g1"
peer_address: 192.168.1.3
priority: 100
disable: false
no_preempt: false
vrid: 20
- name: "g2"
address:
- "4.4.4.4"
- "6.6.6.6 interface eth3"
sync_groups:
- name: "sg1"
health_check:
failure_count: 5
commands:
- delete high-availability vrrp group g1 disable
- delete high-availability vrrp group g1 no-preempt
- delete high-availability vrrp group g1 rfc3768-compatibility
- set high-availability disable
- set high-availability virtual-server s1 address 10.10.10.5
- set high-availability virtual-server s1 real-server 10.10.50.2 port 8443
- set high-availability virtual-server s2 persistence-timeout 30
- set high-availability virtual-server s2 protocol tcp
- set high-availability virtual-server s3 address 10.10.10.3
- set high-availability virtual-server s3 port 88
- set high-availability virtual-server s3 protocol udp
- set high-availability vrrp global-parameters garp master-repeat 6
- set high-availability vrrp global-parameters startup-delay 30
- set high-availability vrrp group g2 address 2.2.2.2
- set high-availability vrrp group g2 address 4.4.4.4
- set high-availability vrrp group g2 address 6.6.6.6 interface eth3
- set high-availability vrrp snmp
- set high-availability vrrp sync-group sg1 health-check failure-count 5
populate_commands:
- set high-availability virtual-server s1 address 10.10.10.1
- set high-availability virtual-server s1 algorithm round-robin
- set high-availability virtual-server s1 delay-loop 60
- set high-availability virtual-server s1 forward-method direct
- set high-availability virtual-server s1 fwmark 10
- set high-availability virtual-server s1 persistence-timeout 30
- set high-availability virtual-server s1 protocol tcp
- set high-availability virtual-server s1 real-server 10.10.50.1 health-check script /var/tmp/script.sh
- set high-availability virtual-server s1 real-server 10.10.50.1 port 443
- set high-availability virtual-server s2 address 10.10.10.2
- set high-availability virtual-server s2 port 81
- set high-availability virtual-server s2 real-server real1 connection-timeout 5
- set high-availability virtual-server s2 real-server real1 port 8081
- set high-availability virtual-server s2 real-server real2 port 8080
- set high-availability vrrp global-parameters startup-delay 31
- set high-availability vrrp global-parameters version 3
- set high-availability vrrp global-parameters garp interval 30
- set high-availability vrrp global-parameters garp master-delay 10
- set high-availability vrrp global-parameters garp master-refresh 100
- set high-availability vrrp global-parameters garp master-refresh-repeat 200
- set high-availability vrrp global-parameters garp master-repeat 5
- set high-availability vrrp group g1 address 1.1.1.1
- set high-availability vrrp group g1 address 5.5.5.5
- set high-availability vrrp group g1 address 8.8.8.8 interface eth2
- set high-availability vrrp group g1 advertise-interval 10
- set high-availability vrrp group g1 description 'Group_1'
- set high-availability vrrp group g1 disable
- set high-availability vrrp group g1 interface eth2
- set high-availability vrrp group g1 no-preempt
- set high-availability vrrp group g1 peer-address 192.168.1.3
- set high-availability vrrp group g1 priority 100
- set high-availability vrrp group g1 rfc3768-compatibility
- set high-availability vrrp group g1 vrid 20
- set high-availability vrrp group g1 authentication password testpass
- set high-availability vrrp group g1 authentication type plaintext-password
- set high-availability vrrp group g1 excluded-address 192.168.1.7 interface eth3
- set high-availability vrrp group g1 excluded-address 192.168.1.8
- set high-availability vrrp group g1 garp interval 20
- set high-availability vrrp group g1 garp master-delay 5
- set high-availability vrrp group g1 garp master-refresh 50
- set high-availability vrrp group g1 garp master-refresh-repeat 100
- set high-availability vrrp group g1 garp master-repeat 3
- set high-availability vrrp group g1 track exclude-vrrp-interface
- set high-availability vrrp group g1 track interface eth0
- set high-availability vrrp group g1 track interface eth1
- set high-availability vrrp group g1 transition-script backup /var/tmp/script.sh
- set high-availability vrrp group g1 transition-script fault /var/tmp/script.sh
- set high-availability vrrp group g1 transition-script master /var/tmp/script.sh
- set high-availability vrrp group g1 transition-script stop /var/tmp/script.sh
- set high-availability vrrp group g2 address 2.2.2.2
- set high-availability vrrp group g2 description 'Group_2'
- set high-availability vrrp group g2 interface eth1
- set high-availability vrrp group g2 vrid 11
- set high-availability vrrp group g2 health-check failure-count 5
- set high-availability vrrp group g2 health-check interval 15
- set high-availability vrrp group g2 health-check ping 192.168.1.100
- set high-availability vrrp group g2 health-check script /var/tmp/script.sh
- set high-availability vrrp group g2 hello-source-address 2.2.2.2
- set high-availability vrrp sync-group sg1 health-check failure-count 3
- set high-availability vrrp sync-group sg1 health-check interval 10
- set high-availability vrrp sync-group sg1 health-check ping 192.168.2.100
- set high-availability vrrp sync-group sg1 health-check script /var/tmp/script.sh
- set high-availability vrrp sync-group sg1 member g1
- set high-availability vrrp sync-group sg1 member g2
- set high-availability vrrp sync-group sg1 transition-script backup /var/tmp/script.sh
- set high-availability vrrp sync-group sg1 transition-script fault /var/tmp/script.sh
- set high-availability vrrp sync-group sg1 transition-script master /var/tmp/script.sh
- set high-availability vrrp sync-group sg1 transition-script stop /var/tmp/script.sh
rendered:
config:
virtual_servers:
- name: s1
address: 10.10.10.1
algorithm: round-robin
delay_loop: 60
forward_method: direct
fwmark: 10
persistence_timeout: 30
protocol: tcp
real_server:
- address: 10.10.50.1
health_check_script: /var/tmp/script.sh
port: 443
- name: s2
address: 10.10.10.2
port: 81
real_server:
- address: real1
connection_timeout: 5
port: 8081
- address: real2
port: 8080
vrrp:
snmp: enabled
global_parameters:
startup_delay: 31
version: "3"
garp:
interval: 30
master_delay: 10
master_refresh: 100
master_refresh_repeat: 200
master_repeat: 5
groups:
- name: "g1"
description: "Group_1"
interface: "eth2"
address:
- "1.1.1.1"
- "2.2.2.2"
- "3.3.3.3 interface eth2"
advertise_interval: 10
peer_address: 192.168.1.3
priority: 100
disable: true
no_preempt: true
rfc3768_compatibility: true
vrid: 20
excluded_address:
- "192.168.1.7 interface eth3"
garp:
interval: 20
master_delay: 5
master_refresh: 50
master_refresh_repeat: 100
master_repeat: 3
authentication:
type: "plaintext-password"
password: "test123"
transition_script:
master: "/var/tmp/script.sh"
backup: "/var/tmp/script.sh"
fault: "/var/tmp/script.sh"
stop: "/var/tmp/script.sh"
track:
exclude_vrrp_interface: true
interface:
- eth0
- name: "g2"
description: "Group_2"
interface: "eth1"
address: "2.2.2.2"
disable: false
no_preempt: false
rfc3768_compatibility: false
vrid: 11
health_check:
failure_count: 5
interval: 15
ping: "192.168.1.100"
script: "/var/tmp/script.sh"
hello_source_address: "2.2.2.2"
sync_groups:
- name: "sg1"
member:
- "g1"
transition_script:
master: "/var/tmp/script.sh"
backup: "/var/tmp/script.sh"
fault: "/var/tmp/script.sh"
stop: "/var/tmp/script.sh"
health_check:
failure_count: 3
interval: 10
ping: "192.168.2.100"
script: "/var/tmp/script.sh"
commands:
- set high-availability virtual-server s1 address 10.10.10.1
- set high-availability virtual-server s1 algorithm round-robin
- set high-availability virtual-server s1 delay-loop 60
- set high-availability virtual-server s1 forward-method direct
- set high-availability virtual-server s1 fwmark 10
- set high-availability virtual-server s1 persistence-timeout 30
- set high-availability virtual-server s1 protocol tcp
- set high-availability virtual-server s1 real-server 10.10.50.1 health-check script /var/tmp/script.sh
- set high-availability virtual-server s1 real-server 10.10.50.1 port 443
- set high-availability virtual-server s2 address 10.10.10.2
- set high-availability virtual-server s2 port 81
- set high-availability virtual-server s2 real-server real1 connection-timeout 5
- set high-availability virtual-server s2 real-server real1 port 8081
- set high-availability virtual-server s2 real-server real2 port 8080
- set high-availability vrrp global-parameters garp interval 30
- set high-availability vrrp global-parameters garp master-delay 10
- set high-availability vrrp global-parameters garp master-refresh 100
- set high-availability vrrp global-parameters garp master-refresh-repeat 200
- set high-availability vrrp global-parameters garp master-repeat 5
- set high-availability vrrp global-parameters startup-delay 31
- set high-availability vrrp global-parameters version 3
- set high-availability vrrp group g1 address 1.1.1.1
- set high-availability vrrp group g1 address 2.2.2.2
- set high-availability vrrp group g1 address 3.3.3.3 interface eth2
- set high-availability vrrp group g1 advertise-interval 10
- set high-availability vrrp group g1 authentication password ********
- set high-availability vrrp group g1 authentication type plaintext-password
- set high-availability vrrp group g1 description 'Group_1'
- set high-availability vrrp group g1 disable
- set high-availability vrrp group g1 excluded-address 192.168.1.7 interface eth3
- set high-availability vrrp group g1 garp interval 20
- set high-availability vrrp group g1 garp master-delay 5
- set high-availability vrrp group g1 garp master-refresh 50
- set high-availability vrrp group g1 garp master-refresh-repeat 100
- set high-availability vrrp group g1 garp master-repeat 3
- set high-availability vrrp group g1 interface eth2
- set high-availability vrrp group g1 no-preempt
- set high-availability vrrp group g1 peer-address 192.168.1.3
- set high-availability vrrp group g1 priority 100
- set high-availability vrrp group g1 rfc3768-compatibility
- set high-availability vrrp group g1 track exclude-vrrp-interface
- set high-availability vrrp group g1 track interface eth0
- set high-availability vrrp group g1 transition-script backup /var/tmp/script.sh
- set high-availability vrrp group g1 transition-script fault /var/tmp/script.sh
- set high-availability vrrp group g1 transition-script master /var/tmp/script.sh
- set high-availability vrrp group g1 transition-script stop /var/tmp/script.sh
- set high-availability vrrp group g1 vrid 20
- set high-availability vrrp group g2 address 2.2.2.2
- set high-availability vrrp group g2 description 'Group_2'
- set high-availability vrrp group g2 health-check failure-count 5
- set high-availability vrrp group g2 health-check interval 15
- set high-availability vrrp group g2 health-check ping 192.168.1.100
- set high-availability vrrp group g2 health-check script /var/tmp/script.sh
- set high-availability vrrp group g2 hello-source-address 2.2.2.2
- set high-availability vrrp group g2 interface eth1
- set high-availability vrrp group g2 vrid 11
- set high-availability vrrp snmp
- set high-availability vrrp sync-group sg1 health-check failure-count 3
- set high-availability vrrp sync-group sg1 health-check interval 10
- set high-availability vrrp sync-group sg1 health-check ping 192.168.2.100
- set high-availability vrrp sync-group sg1 health-check script /var/tmp/script.sh
- set high-availability vrrp sync-group sg1 member g1
- set high-availability vrrp sync-group sg1 transition-script backup /var/tmp/script.sh
- set high-availability vrrp sync-group sg1 transition-script fault /var/tmp/script.sh
- set high-availability vrrp sync-group sg1 transition-script master /var/tmp/script.sh
- set high-availability vrrp sync-group sg1 transition-script stop /var/tmp/script.sh
purged:
commands:
- delete high-availability
after:
disable: false
deleted_vrrp_groups:
commands:
- delete high-availability vrrp group g1
- delete high-availability vrrp sync-group sg1
after:
disable: false
virtual_servers:
- name: s1
address: 10.10.10.1
algorithm: round-robin
delay_loop: 60
forward_method: direct
fwmark: 10
persistence_timeout: 30
protocol: tcp
real_server:
- address: 10.10.50.1
port: 443
health_check_script: /var/tmp/script.sh
- name: s2
address: 10.10.10.2
port: 81
real_server:
- address: real1
port: 8081
connection_timeout: 5
- address: real2
port: 8080
vrrp:
global_parameters:
startup_delay: 31
version: "3"
garp:
interval: 30
master_delay: 10
master_refresh: 100
master_refresh_repeat: 200
master_repeat: 5
groups:
- name: g2
address:
- "2.2.2.2"
description: Group_2
disable: false
interface: eth1
vrid: 11
hello_source_address: 2.2.2.2
no_preempt: false
rfc3768_compatibility: false
health_check:
failure_count: 5
interval: 15
ping: 192.168.1.100
script: /var/tmp/script.sh
deleted_bulk:
commands:
- delete high-availability virtual-server
- delete high-availability vrrp global-parameters garp
- delete high-availability vrrp global-parameters startup-delay
- delete high-availability vrrp group g1
- delete high-availability vrrp sync-group
after:
disable: false
vrrp:
global_parameters:
version: "3"
groups:
- name: g2
address:
- "2.2.2.2"
description: Group_2
disable: false
hello_source_address: 2.2.2.2
interface: eth1
vrid: 11
no_preempt: false
rfc3768_compatibility: false
health_check:
failure_count: 5
interval: 15
ping: 192.168.1.100
script: /var/tmp/script.sh
overridden:
config:
disable: false
vrrp:
snmp: disabled
global_parameters:
startup_delay: 32
version: 3
garp:
interval: 30
master_delay: 11
master_refresh: 100
master_refresh_repeat: 200
master_repeat: 6
groups:
- name: "g1"
description: "Group_1"
interface: "eth2"
address:
- "1.1.1.1"
- "3.3.3.3 interface eth3"
disable: true
no_preempt: true
rfc3768_compatibility: true
vrid: 20
peer_address: "192.168.1.3"
advertise_interval: 10
priority: 100
garp:
interval: 20
master_delay: 5
master_refresh: 50
master_refresh_repeat: 100
master_repeat: 3
authentication:
type: "plaintext-password"
password: "test123"
transition_script:
master: "/var/tmp/script.sh"
backup: "/var/tmp/script.sh"
fault: "/var/tmp/script.sh"
stop: "/var/tmp/script.sh"
track:
exclude_vrrp_interface: true
sync_groups:
- name: "sg1"
member:
- "g1"
- "g2"
transition_script:
master: "/var/tmp/script.sh"
backup: "/var/tmp/script.sh"
fault: "/var/tmp/script.sh"
stop: "/var/tmp/script.sh"
health_check:
failure_count: 4
interval: 10
ping: "192.168.1.100"
script: "/var/tmp/script.sh"
virtual_servers:
- name: "s1"
address: "10.10.10.15"
algorithm: "round-robin"
delay_loop: 60
fwmark: 12
forward_method: "direct"
persistence_timeout: 30
protocol: "tcp"
real_server:
- address: "10.10.10.1"
connection_timeout: 61
port: 443
after:
disable: false
virtual_servers:
- address: "10.10.10.15"
algorithm: round-robin
delay_loop: 60
forward_method: direct
fwmark: 12
name: s1
persistence_timeout: 30
protocol: tcp
real_server:
- address: "10.10.10.1"
connection_timeout: 61
port: 443
- address: "10.10.10.2"
name: s2
port: 81
real_server:
- address: real1
connection_timeout: 5
port: 8081
- address: real2
port: 8080
vrrp:
global_parameters:
garp:
interval: 30
master_delay: 11
master_refresh: 100
master_refresh_repeat: 200
master_repeat: 6
startup_delay: 32
version: "3"
groups:
- address: "1.1.1.1"
advertise_interval: 10
authentication:
password: VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
type: plaintext-password
description: Group_1
disable: true
garp:
interval: 20
master_delay: 5
master_refresh: 50
master_refresh_repeat: 100
master_repeat: 3
interface: eth2
name: g1
no_preempt: true
peer_address: "192.168.1.3"
priority: 100
rfc3768_compatibility: true
track:
exclude_vrrp_interface: true
transition_script:
backup: /var/tmp/script.sh
fault: /var/tmp/script.sh
master: /var/tmp/script.sh
stop: /var/tmp/script.sh
vrid: 20
- address: "2.2.2.2"
description: Group_2
disable: false
health_check:
failure_count: 5
interval: 15
ping: "192.168.1.100"
script: /var/tmp/script.sh
hello_source_address: "2.2.2.2"
interface: eth1
name: g2
no_preempt: false
rfc3768_compatibility: false
vrid: 11
sync_groups:
- health_check:
failure_count: 4
interval: 10
ping: "192.168.1.100"
script: /var/tmp/script.sh
member:
- g1
- g2
name: sg1
transition_script:
backup: /var/tmp/script.sh
fault: /var/tmp/script.sh
master: /var/tmp/script.sh
stop: /var/tmp/script.sh
replaced:
commands:
+ - delete high-availability vrrp global-parameters garp master-repeat 5
+ - delete high-availability vrrp global-parameters startup-delay 31
- delete high-availability vrrp group g1 disable
- delete high-availability vrrp group g1 no-preempt
- delete high-availability vrrp group g1 rfc3768-compatibility
+ - delete high-availability vrrp group g2 address 2.2.2.2
+ - delete high-availability vrrp sync-group sg1 health-check failure-count 3
- set high-availability disable
- set high-availability virtual-server s1 address 10.10.10.5
- set high-availability virtual-server s1 real-server 10.10.50.2 port 8443
- set high-availability virtual-server s2 persistence-timeout 30
- set high-availability virtual-server s2 protocol tcp
- set high-availability virtual-server s3 address 10.10.10.3
- set high-availability virtual-server s3 port 88
- set high-availability virtual-server s3 protocol udp
- set high-availability vrrp global-parameters garp master-repeat 6
- set high-availability vrrp global-parameters startup-delay 30
- set high-availability vrrp group g2 address 4.4.4.4
- set high-availability vrrp group g2 address 6.6.6.6 interface eth3
- set high-availability vrrp snmp
- set high-availability vrrp sync-group sg1 health-check failure-count 5
rtt:
commands:
- set high-availability disable
- set high-availability virtual-server s1 address 10.10.10.5
- set high-availability virtual-server s1 algorithm round-robin
- set high-availability virtual-server s1 real-server 10.10.50.2 port 8443
- set high-availability virtual-server s2 address 10.10.10.2
- set high-availability virtual-server s2 persistence-timeout 30
- set high-availability virtual-server s2 port 81
- set high-availability virtual-server s2 protocol tcp
- set high-availability virtual-server s3 address 10.10.10.3
- set high-availability virtual-server s3 port 88
- set high-availability virtual-server s3 protocol udp
- set high-availability vrrp global-parameters garp master-repeat 6
- set high-availability vrrp global-parameters startup-delay 30
- set high-availability vrrp group g1 peer-address 192.168.1.3
- set high-availability vrrp group g1 priority 100
- set high-availability vrrp group g1 vrid 20
- set high-availability vrrp group g2 address 4.4.4.4
- set high-availability vrrp group g2 address 6.6.6.6 interface eth3
- set high-availability vrrp snmp
- set high-availability vrrp sync-group sg1 health-check failure-count 5
config:
disable: false
virtual_servers:
- name: s1
address: 10.10.10.5
fwmark: 10
algorithm: least-connection
real_server:
- address: 10.10.50.2
port: 8443
- name: s2
address: 10.10.10.2
persistence_timeout: 36
port: 443
protocol: tcp
real_server:
- address: 10.10.50.3
port: 8443
- name: s3
address: 10.10.10.3
port: 80
protocol: udp
real_server:
- address: 10.10.50.4
port: 8443
vrrp:
snmp: disabled
global_parameters:
startup_delay: 36
garp:
master_repeat: 6
groups:
- name: "g1"
peer_address: 192.168.1.3
address: "1.1.1.1"
priority: 100
disable: true
no_preempt: false
interface: eth2
vrid: 20
- name: "g2"
address:
- "2.2.2.2"
interface: eth1
vrid: 11
sync_groups:
- name: "sg1"
health_check:
failure_count: 10
after:
disable: true
virtual_servers:
- address: "10.10.10.5"
algorithm: "round-robin"
name: "s1"
real_server:
- address: "10.10.50.2"
port: 8443
- address: "10.10.10.2"
name: "s2"
persistence_timeout: 30
port: 81
protocol: "tcp"
- address: "10.10.10.3"
name: "s3"
port: 88
protocol: "udp"
vrrp:
global_parameters:
garp:
master_repeat: 6
startup_delay: 30
groups:
- disable: false
name: "g1"
no_preempt: false
peer_address: "192.168.1.3"
priority: 100
rfc3768_compatibility: false
vrid: 20
snmp: "enabled"
sync_groups:
- health_check:
failure_count: 5
name: "sg1"
diff --git a/tests/unit/modules/network/vyos/test_vyos_ha.py b/tests/unit/modules/network/vyos/test_vyos_ha.py
index ce388810..5b11f644 100644
--- a/tests/unit/modules/network/vyos/test_vyos_ha.py
+++ b/tests/unit/modules/network/vyos/test_vyos_ha.py
@@ -1,1391 +1,1394 @@
# (c) 2021 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_ha
from ansible_collections.vyos.vyos.tests.unit.modules.utils import set_module_args
from .vyos_module import TestVyosModule, load_fixture
class TestVyosHaModule(TestVyosModule):
module = vyos_ha
def setUp(self):
super(TestVyosHaModule, self).setUp()
self.mock_get_resource_connection_config = patch(
"ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_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.ha.ha.HaFacts.get_config",
)
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.ha.ha.get_os_version",
)
self.get_os_version = self.mock_get_os_version.start()
self.get_os_version.return_value = "1.5"
self.maxDiff = None
def tearDown(self):
super(TestVyosHaModule, self).tearDown()
self.mock_get_resource_connection_config.stop()
self.mock_get_resource_connection_facts.stop()
self.mock_execute_show_command.stop()
self.mock_get_os_version.stop()
def load_fixtures(self, commands=None, filename=None):
if filename is None:
filename = "vyos_ha_config.cfg"
def load_from_file(*args, **kwargs):
output = load_fixture(filename)
return output
self.execute_show_command.side_effect = load_from_file
def test_vrrp_merged_idempotent(self):
set_module_args(
dict(
config=dict(
disable=True,
virtual_servers=[
dict(
address="10.10.10.1",
algorithm="round-robin",
delay_loop=60,
forward_method="direct",
fwmark=10,
name="s1",
persistence_timeout="30",
protocol="tcp",
real_server=[
dict(
address="10.10.50.1",
port=443,
health_check_script="/var/tmp/script.sh",
),
],
),
dict(
address="10.10.10.2",
name="s2",
port=81,
real_server=[
dict(
address="real1",
port=8081,
connection_timeout=5,
),
dict(
address="real2",
port=8080,
),
],
),
],
vrrp=dict(
global_parameters=dict(
garp=dict(
master_refresh=100,
),
version="3",
),
groups=[
dict(
authentication=dict(
password="testpass",
type="plaintext-password",
),
address=[
"1.1.1.1",
"3.3.3.3",
"5.5.5.5 interface eth2",
],
advertise_interval=10,
description="Group_1",
disable=True,
excluded_address=[
"192.168.1.8",
"192.168.1.7 interface eth3",
],
garp=dict(
interval=20,
master_delay=5,
master_refresh_repeat=100,
master_repeat=3,
),
health_check=dict(
failure_count=3,
interval=10,
ping="192.168.1.5",
script="script.sh",
),
hello_source_address="192.168.1.2",
interface="eth2",
name="g1",
no_preempt=True,
peer_address="192.168.1.3",
priority=100,
rfc3768_compatibility=True,
track=dict(
exclude_vrrp_interface=True,
interface=["eth1"],
),
transition_script=dict(
backup="/var/tmp/script.sh",
master="/var/tmp/script.sh",
stop="/var/tmp/script.sh",
),
vrid=20,
),
],
snmp="enabled",
sync_groups=[
dict(
health_check=dict(
failure_count=3,
interval=10,
),
member=["g1"],
name="sg1",
transition_script=dict(
backup="/var/tmp/script.sh",
master="/var/tmp/script.sh",
stop="/var/tmp/script.sh",
),
),
],
),
),
state="merged",
),
)
self.execute_module(changed=False, commands=[])
def test_vrrp_merged(self):
set_module_args(
dict(
config=dict(
disable=True,
virtual_servers=[
dict(
name="s1",
address="10.10.10.5",
algorithm="round-robin",
real_server=[
dict(
address="10.10.50.2",
port=8443,
),
],
),
dict(
name="s2",
address="10.10.10.2",
persistence_timeout=30,
port=81,
protocol="tcp",
),
dict(
name="s3",
address="10.10.10.3",
port=88,
protocol="udp",
),
],
vrrp=dict(
snmp="disabled",
global_parameters=dict(
startup_delay=35,
garp=dict(
master_repeat=6,
),
),
groups=[
dict(
name="g1",
peer_address="192.168.1.3",
priority=100,
disable=False,
no_preempt=False,
),
dict(
name="g2",
address=[
"192.168.3.3",
"192.168.4.4 interface eth3",
],
),
],
sync_groups=[
dict(
name="sg1",
health_check=dict(
failure_count=5,
),
),
],
),
),
state="merged",
),
)
commands = [
"delete high-availability vrrp group g1 no-preempt",
"delete high-availability vrrp group g1 disable",
"delete high-availability vrrp group g1 rfc3768-compatibility",
"set high-availability vrrp group g2 address 192.168.3.3",
"set high-availability vrrp group g2 address 192.168.4.4 interface eth3",
"delete high-availability vrrp snmp",
"set high-availability virtual-server s1 address 10.10.10.5",
"set high-availability virtual-server s1 real-server 10.10.50.2 port 8443",
"set high-availability virtual-server s2 persistence-timeout 30",
"set high-availability virtual-server s2 protocol tcp",
"set high-availability virtual-server s3 address 10.10.10.3",
"set high-availability virtual-server s3 port 88",
"set high-availability virtual-server s3 protocol udp",
"set high-availability vrrp global-parameters garp master-repeat 6",
"set high-availability vrrp global-parameters startup-delay 35",
"set high-availability vrrp sync-group sg1 health-check failure-count 5",
]
self.execute_module(changed=True, commands=commands)
def test_vrrp_replaced(self):
set_module_args(
dict(
config=dict(
disable=False,
virtual_servers=[
dict(
name="s1",
address="10.10.10.5",
algorithm="round-robin",
real_server=[
dict(
address="10.10.50.2",
port=8443,
),
],
),
dict(
name="s2",
address="10.10.10.2",
persistence_timeout=30,
port=81,
protocol="tcp",
),
dict(
name="s3",
address="10.10.10.3",
port=88,
protocol="udp",
),
],
vrrp=dict(
snmp="disabled",
global_parameters=dict(
startup_delay=32,
garp=dict(
master_repeat=6,
),
),
groups=[
dict(
name="g1",
peer_address="192.168.1.3",
priority=100,
disable=False,
no_preempt=False,
vrid=20,
),
dict(
name="g2",
address=[
"192.168.3.3",
"192.168.4.4 interface eth3",
],
),
],
sync_groups=[
dict(
name="sg1",
health_check=dict(
failure_count=5,
),
),
],
),
),
state="replaced",
),
)
commands = [
+ "delete high-availability vrrp global-parameters garp master-repeat 5",
+ "delete high-availability vrrp global-parameters startup-delay 30",
"delete high-availability vrrp group g1 disable",
"delete high-availability vrrp group g1 no-preempt",
"delete high-availability vrrp group g1 rfc3768-compatibility",
+ "delete high-availability vrrp sync-group sg1 health-check failure-count 3",
"set high-availability vrrp group g2 address 192.168.3.3",
"set high-availability vrrp group g2 address 192.168.4.4 interface eth3",
"delete high-availability disable",
"delete high-availability vrrp snmp",
"set high-availability virtual-server s1 address 10.10.10.5",
"set high-availability virtual-server s1 real-server 10.10.50.2 port 8443",
"set high-availability virtual-server s2 persistence-timeout 30",
"set high-availability virtual-server s2 protocol tcp",
"set high-availability virtual-server s3 address 10.10.10.3",
"set high-availability virtual-server s3 port 88",
"set high-availability virtual-server s3 protocol udp",
"set high-availability vrrp global-parameters garp master-repeat 6",
"set high-availability vrrp global-parameters startup-delay 32",
"set high-availability vrrp sync-group sg1 health-check failure-count 5",
]
self.execute_module(changed=True, commands=commands)
def test_ntp_replaced_idempotent(self):
set_module_args(
dict(
config=dict(
disable=True,
virtual_servers=[
dict(
address="10.10.10.1",
algorithm="round-robin",
delay_loop=60,
forward_method="direct",
fwmark=10,
name="s1",
persistence_timeout="30",
protocol="tcp",
real_server=[
dict(
address="10.10.50.1",
port=443,
health_check_script="/var/tmp/script.sh",
),
],
),
dict(
address="10.10.10.2",
name="s2",
port=81,
real_server=[
dict(
address="real1",
port=8081,
connection_timeout=5,
),
dict(
address="real2",
port=8080,
),
],
),
],
vrrp=dict(
global_parameters=dict(
garp=dict(
interval=30,
master_delay=10,
master_refresh=100,
master_refresh_repeat=200,
master_repeat=5,
),
version="3",
startup_delay=30,
),
groups=[
dict(
authentication=dict(
password="testpass",
type="plaintext-password",
),
address=[
"1.1.1.1",
"3.3.3.3",
"5.5.5.5 interface eth2",
],
advertise_interval=10,
description="Group_1",
disable=True,
excluded_address=[
"192.168.1.8",
"192.168.1.7 interface eth3",
],
garp=dict(
interval=20,
master_delay=5,
master_refresh=50,
master_refresh_repeat=100,
master_repeat=3,
),
health_check=dict(
failure_count=3,
interval=10,
ping="192.168.1.5",
script="script.sh",
),
hello_source_address="192.168.1.2",
interface="eth2",
name="g1",
no_preempt=True,
peer_address="192.168.1.3",
priority=100,
rfc3768_compatibility=True,
track=dict(
exclude_vrrp_interface=True,
interface=["eth1"],
),
transition_script=dict(
backup="/var/tmp/script.sh",
fault="/var/tmp/script.sh",
master="/var/tmp/script.sh",
stop="/var/tmp/script.sh",
),
vrid=20,
),
],
snmp="enabled",
sync_groups=[
dict(
health_check=dict(
failure_count=3,
interval=10,
ping="192.168.1.1",
script="/var/tmp/script.sh",
),
member=["g1"],
name="sg1",
transition_script=dict(
backup="/var/tmp/script.sh",
fault="/var/tmp/script.sh",
master="/var/tmp/script.sh",
stop="/var/tmp/script.sh",
),
),
],
),
),
state="replaced",
),
)
self.execute_module(changed=False, commands=[])
def test_vrrp_overridden(self):
set_module_args(
dict(
config=dict(
disable=False,
vrrp=dict(
snmp="disabled",
global_parameters=dict(
startup_delay=32,
version=3,
garp=dict(
interval=30,
master_delay=11,
master_refresh=100,
master_refresh_repeat=200,
master_repeat=6,
),
),
groups=[
dict(
name="g1",
description="Group_1",
interface="eth2",
address="1.1.1.1",
disable=True,
no_preempt=True,
rfc3768_compatibility=True,
vrid=20,
peer_address="192.168.1.3",
advertise_interval=10,
priority=100,
garp=dict(
interval=20,
master_delay=5,
master_refresh=50,
master_refresh_repeat=100,
master_repeat=3,
),
authentication=dict(
type="plaintext-password",
password="testpass",
),
transition_script=dict(
master="/var/tmp/script.sh",
backup="/var/tmp/script.sh",
fault="/var/tmp/script.sh",
stop="/var/tmp/script.sh",
),
track=dict(
exclude_vrrp_interface=True,
),
),
dict(
name="g2",
address=[
"192.168.3.3",
"192.168.4.4 interface eth3",
],
),
],
sync_groups=[
dict(
name="sg1",
member=["g1", "g2"],
transition_script=dict(
master="/var/tmp/script.sh",
backup="/var/tmp/script.sh",
fault="/var/tmp/script.sh",
stop="/var/tmp/script.sh",
),
health_check=dict(
failure_count=4,
interval=10,
ping="192.168.1.100",
script="/var/tmp/script.sh",
),
),
],
),
virtual_servers=[
dict(
name="s1",
address="10.10.10.15",
algorithm="round-robin",
delay_loop=60,
fwmark=12,
forward_method="direct",
persistence_timeout=30,
protocol="tcp",
real_server=[
dict(
address="10.10.10.1",
connection_timeout=61,
port=443,
),
],
),
],
),
state="overridden",
),
)
commands = [
"delete high-availability disable",
"delete high-availability virtual-server s1",
"delete high-availability vrrp global-parameters garp",
"delete high-availability vrrp group g1",
"delete high-availability vrrp sync-group sg1",
"set high-availability virtual-server s1 address 10.10.10.15",
"set high-availability virtual-server s1 algorithm round-robin",
"set high-availability virtual-server s1 delay-loop 60",
"set high-availability virtual-server s1 forward-method direct",
"set high-availability virtual-server s1 fwmark 12",
"set high-availability virtual-server s1 persistence-timeout 30",
"set high-availability virtual-server s1 protocol tcp",
"set high-availability virtual-server s1 real-server 10.10.10.1 connection-timeout 61",
"set high-availability virtual-server s1 real-server 10.10.10.1 port 443",
"set high-availability vrrp global-parameters garp interval 30",
"set high-availability vrrp global-parameters garp master-delay 11",
"set high-availability vrrp global-parameters garp master-refresh 100",
"set high-availability vrrp global-parameters garp master-refresh-repeat 200",
"set high-availability vrrp global-parameters garp master-repeat 6",
"set high-availability vrrp global-parameters startup-delay 32",
"set high-availability vrrp group g1 address 1.1.1.1",
"set high-availability vrrp group g1 advertise-interval 10",
"set high-availability vrrp group g1 authentication password testpass",
"set high-availability vrrp group g1 authentication type plaintext-password",
"set high-availability vrrp group g1 description 'Group_1'",
"set high-availability vrrp group g1 disable",
"set high-availability vrrp group g1 garp interval 20",
"set high-availability vrrp group g1 garp master-delay 5",
"set high-availability vrrp group g1 garp master-refresh 50",
"set high-availability vrrp group g1 garp master-refresh-repeat 100",
"set high-availability vrrp group g1 garp master-repeat 3",
"set high-availability vrrp group g1 interface eth2",
"set high-availability vrrp group g1 no-preempt",
"set high-availability vrrp group g1 peer-address 192.168.1.3",
"set high-availability vrrp group g1 priority 100",
"set high-availability vrrp group g1 rfc3768-compatibility",
"set high-availability vrrp group g1 track exclude-vrrp-interface",
"set high-availability vrrp group g1 transition-script backup /var/tmp/script.sh",
"set high-availability vrrp group g1 transition-script fault /var/tmp/script.sh",
"set high-availability vrrp group g1 transition-script master /var/tmp/script.sh",
"set high-availability vrrp group g1 transition-script stop /var/tmp/script.sh",
"set high-availability vrrp group g1 vrid 20",
"set high-availability vrrp group g2 address 192.168.3.3",
"set high-availability vrrp group g2 address 192.168.4.4 interface eth3",
"set high-availability vrrp sync-group sg1 health-check failure-count 4",
"set high-availability vrrp sync-group sg1 health-check interval 10",
"set high-availability vrrp sync-group sg1 health-check ping 192.168.1.100",
"set high-availability vrrp sync-group sg1 health-check script /var/tmp/script.sh",
"set high-availability vrrp sync-group sg1 member g1",
"set high-availability vrrp sync-group sg1 member g2",
"set high-availability vrrp sync-group sg1 transition-script backup /var/tmp/script.sh",
"set high-availability vrrp sync-group sg1 transition-script fault /var/tmp/script.sh",
"set high-availability vrrp sync-group sg1 transition-script master /var/tmp/script.sh",
"set high-availability vrrp sync-group sg1 transition-script stop /var/tmp/script.sh",
]
self.execute_module(changed=True, commands=commands)
def test_vrrp_overridden_idempotent(self):
set_module_args(
dict(
config=dict(
disable=True,
virtual_servers=[
dict(
address="10.10.10.1",
algorithm="round-robin",
delay_loop=60,
forward_method="direct",
fwmark=10,
name="s1",
persistence_timeout="30",
protocol="tcp",
real_server=[
dict(
address="10.10.50.1",
port=443,
health_check_script="/var/tmp/script.sh",
),
],
),
dict(
address="10.10.10.2",
name="s2",
port=81,
real_server=[
dict(
address="real1",
port=8081,
connection_timeout=5,
),
dict(
address="real2",
port=8080,
),
],
),
],
vrrp=dict(
global_parameters=dict(
garp=dict(
interval=30,
master_delay=10,
master_refresh=100,
master_refresh_repeat=200,
master_repeat=5,
),
version="3",
startup_delay=30,
),
groups=[
dict(
authentication=dict(
password="testpass",
type="plaintext-password",
),
address=[
"1.1.1.1",
"3.3.3.3",
"5.5.5.5 interface eth2",
],
advertise_interval=10,
description="Group_1",
disable=True,
excluded_address=[
"192.168.1.8",
"192.168.1.7 interface eth3",
],
garp=dict(
interval=20,
master_delay=5,
master_refresh=50,
master_refresh_repeat=100,
master_repeat=3,
),
health_check=dict(
failure_count=3,
interval=10,
ping="192.168.1.5",
script="script.sh",
),
hello_source_address="192.168.1.2",
interface="eth2",
name="g1",
no_preempt=True,
peer_address="192.168.1.3",
priority=100,
rfc3768_compatibility=True,
track=dict(
exclude_vrrp_interface=True,
interface=["eth1"],
),
transition_script=dict(
backup="/var/tmp/script.sh",
fault="/var/tmp/script.sh",
master="/var/tmp/script.sh",
stop="/var/tmp/script.sh",
),
vrid=20,
),
],
snmp="enabled",
sync_groups=[
dict(
health_check=dict(
failure_count=3,
interval=10,
ping="192.168.1.1",
script="/var/tmp/script.sh",
),
member=["g1"],
name="sg1",
transition_script=dict(
backup="/var/tmp/script.sh",
fault="/var/tmp/script.sh",
master="/var/tmp/script.sh",
stop="/var/tmp/script.sh",
),
),
],
),
),
state="overridden",
),
)
self.execute_module(changed=False, commands=[])
def test_vrrp_rendered(self):
set_module_args(
dict(
config=dict(
virtual_servers=[
dict(
name="s1",
address="10.10.10.1",
algorithm="round-robin",
delay_loop=60,
forward_method="direct",
fwmark=10,
persistence_timeout=30,
protocol="tcp",
real_server=[
dict(
address="10.10.50.1",
health_check_script="/var/tmp/script.sh",
port=443,
),
],
),
dict(
name="s2",
address="10.10.10.2",
port=81,
real_server=[
dict(
address="real1",
connection_timeout=5,
port=8081,
),
dict(
address="real2",
port=8080,
),
],
),
],
vrrp=dict(
snmp="enabled",
global_parameters=dict(
startup_delay=31,
version="3",
garp=dict(
interval=30,
master_delay=10,
master_refresh=100,
master_refresh_repeat=200,
master_repeat=5,
),
),
groups=[
dict(
name="g1",
description="Group_1",
interface="eth2",
address="1.1.1.1",
advertise_interval=10,
peer_address="192.168.1.3",
priority=100,
disable=True,
no_preempt=True,
rfc3768_compatibility=True,
vrid=20,
excluded_address=[
"192.168.1.7 interface eth3",
],
garp=dict(
interval=20,
master_delay=5,
master_refresh=50,
master_refresh_repeat=100,
master_repeat=3,
),
authentication=dict(
type="plaintext-password",
password="testpass",
),
transition_script=dict(
master="/var/tmp/script.sh",
backup="/var/tmp/script.sh",
fault="/var/tmp/script.sh",
stop="/var/tmp/script.sh",
),
track=dict(
exclude_vrrp_interface=True,
interface=[
"eth0",
],
),
),
dict(
name="g2",
description="Group_2",
interface="eth1",
address=[
"2.2.2.2",
"2.2.2.3 interface eth3",
],
disable=False,
no_preempt=False,
rfc3768_compatibility=False,
vrid=11,
health_check=dict(
failure_count=5,
interval=15,
ping="192.168.1.100",
script="/var/tmp/script.sh",
),
hello_source_address="2.2.2.2",
),
],
sync_groups=[
dict(
name="sg1",
member=[
"g1",
],
transition_script=dict(
master="/var/tmp/script.sh",
backup="/var/tmp/script.sh",
fault="/var/tmp/script.sh",
stop="/var/tmp/script.sh",
),
health_check=dict(
failure_count=3,
interval=10,
ping="192.168.2.100",
script="/var/tmp/script.sh",
),
),
],
),
),
state="rendered",
),
)
rendered_commands = [
"set high-availability virtual-server s1 address 10.10.10.1",
"set high-availability virtual-server s1 algorithm round-robin",
"set high-availability virtual-server s1 delay-loop 60",
"set high-availability virtual-server s1 forward-method direct",
"set high-availability virtual-server s1 fwmark 10",
"set high-availability virtual-server s1 persistence-timeout 30",
"set high-availability virtual-server s1 protocol tcp",
"set high-availability virtual-server s1 real-server 10.10.50.1 health-check script /var/tmp/script.sh",
"set high-availability virtual-server s1 real-server 10.10.50.1 port 443",
"set high-availability virtual-server s2 address 10.10.10.2",
"set high-availability virtual-server s2 port 81",
"set high-availability virtual-server s2 real-server real1 connection-timeout 5",
"set high-availability virtual-server s2 real-server real1 port 8081",
"set high-availability virtual-server s2 real-server real2 port 8080",
"set high-availability vrrp global-parameters garp interval 30",
"set high-availability vrrp global-parameters garp master-delay 10",
"set high-availability vrrp global-parameters garp master-refresh 100",
"set high-availability vrrp global-parameters garp master-refresh-repeat 200",
"set high-availability vrrp global-parameters garp master-repeat 5",
"set high-availability vrrp global-parameters startup-delay 31",
"set high-availability vrrp global-parameters version 3",
"set high-availability vrrp group g1 address 1.1.1.1",
"set high-availability vrrp group g1 advertise-interval 10",
"set high-availability vrrp group g1 authentication password testpass",
"set high-availability vrrp group g1 authentication type plaintext-password",
"set high-availability vrrp group g1 description 'Group_1'",
"set high-availability vrrp group g1 disable",
"set high-availability vrrp group g1 excluded-address 192.168.1.7 interface eth3",
"set high-availability vrrp group g1 garp interval 20",
"set high-availability vrrp group g1 garp master-delay 5",
"set high-availability vrrp group g1 garp master-refresh 50",
"set high-availability vrrp group g1 garp master-refresh-repeat 100",
"set high-availability vrrp group g1 garp master-repeat 3",
"set high-availability vrrp group g1 interface eth2",
"set high-availability vrrp group g1 no-preempt",
"set high-availability vrrp group g1 peer-address 192.168.1.3",
"set high-availability vrrp group g1 priority 100",
"set high-availability vrrp group g1 rfc3768-compatibility",
"set high-availability vrrp group g1 track exclude-vrrp-interface",
"set high-availability vrrp group g1 track interface eth0",
"set high-availability vrrp group g1 transition-script backup /var/tmp/script.sh",
"set high-availability vrrp group g1 transition-script fault /var/tmp/script.sh",
"set high-availability vrrp group g1 transition-script master /var/tmp/script.sh",
"set high-availability vrrp group g1 transition-script stop /var/tmp/script.sh",
"set high-availability vrrp group g1 vrid 20",
"set high-availability vrrp group g2 address 2.2.2.2",
"set high-availability vrrp group g2 address 2.2.2.3 interface eth3",
"set high-availability vrrp group g2 description 'Group_2'",
"set high-availability vrrp group g2 health-check failure-count 5",
"set high-availability vrrp group g2 health-check interval 15",
"set high-availability vrrp group g2 health-check ping 192.168.1.100",
"set high-availability vrrp group g2 health-check script /var/tmp/script.sh",
"set high-availability vrrp group g2 hello-source-address 2.2.2.2",
"set high-availability vrrp group g2 interface eth1",
"set high-availability vrrp group g2 vrid 11",
"set high-availability vrrp snmp",
"set high-availability vrrp sync-group sg1 health-check failure-count 3",
"set high-availability vrrp sync-group sg1 health-check interval 10",
"set high-availability vrrp sync-group sg1 health-check ping 192.168.2.100",
"set high-availability vrrp sync-group sg1 health-check script /var/tmp/script.sh",
"set high-availability vrrp sync-group sg1 member g1",
"set high-availability vrrp sync-group sg1 transition-script backup /var/tmp/script.sh",
"set high-availability vrrp sync-group sg1 transition-script fault /var/tmp/script.sh",
"set high-availability vrrp sync-group sg1 transition-script master /var/tmp/script.sh",
"set high-availability vrrp sync-group sg1 transition-script stop /var/tmp/script.sh",
]
result = self.execute_module(changed=False)
self.assertEqual(
sorted(result["rendered"]),
sorted(rendered_commands),
result["rendered"],
)
def test_vrrp_parsed(self):
commands = (
"set high-availability disable",
"set high-availability virtual-server s1 address 10.10.10.1",
"set high-availability virtual-server s1 algorithm round-robin",
"set high-availability virtual-server s1 delay-loop 60",
"set high-availability virtual-server s1 forward-method direct",
"set high-availability virtual-server s1 fwmark 10",
"set high-availability virtual-server s1 persistence-timeout 30",
"set high-availability virtual-server s1 protocol tcp",
"set high-availability virtual-server s1 real-server 10.10.50.1 health-check script '/var/tmp/script.sh'",
"set high-availability virtual-server s1 real-server 10.10.50.1 port 443",
"set high-availability virtual-server s2 address 10.10.10.2",
"set high-availability virtual-server s2 port 81",
"set high-availability virtual-server s2 real-server real1 connection-timeout 5",
"set high-availability virtual-server s2 real-server real1 port 8081",
"set high-availability virtual-server s2 real-server real2 port 8080",
"set high-availability vrrp global-parameters garp interval 30",
"set high-availability vrrp global-parameters garp master-delay 10",
"set high-availability vrrp global-parameters garp master-refresh 100",
"set high-availability vrrp global-parameters garp master-refresh-repeat 200",
"set high-availability vrrp global-parameters garp master-repeat 5",
"set high-availability vrrp global-parameters startup-delay 30",
"set high-availability vrrp global-parameters version 3",
"set high-availability vrrp group g1 address '1.1.1.1'",
"set high-availability vrrp group g1 advertise-interval 10",
"set high-availability vrrp group g1 authentication password 'testpass'",
"set high-availability vrrp group g1 authentication type 'plaintext-password'",
"set high-availability vrrp group g1 description 'Group_1'",
"set high-availability vrrp group g1 disable",
"set high-availability vrrp group g1 excluded-address '192.168.1.7' interface 'eth3'",
"set high-availability vrrp group g1 excluded-address '192.168.1.8'",
"set high-availability vrrp group g1 garp interval 20",
"set high-availability vrrp group g1 garp master-delay 5",
"set high-availability vrrp group g1 garp master-refresh 50",
"set high-availability vrrp group g1 garp master-refresh-repeat 100",
"set high-availability vrrp group g1 garp master-repeat 3",
"set high-availability vrrp group g1 health-check failure-count 3",
"set high-availability vrrp group g1 health-check interval 10",
"set high-availability vrrp group g1 health-check ping '192.168.1.5'",
"set high-availability vrrp group g1 health-check script 'script.sh'",
"set high-availability vrrp group g1 hello-source-address '192.168.1.2'",
"set high-availability vrrp group g1 interface 'eth2'",
"set high-availability vrrp group g1 no-preempt",
"set high-availability vrrp group g1 peer-address '192.168.1.3'",
"set high-availability vrrp group g1 priority 100",
"set high-availability vrrp group g1 rfc3768-compatibility",
"set high-availability vrrp group g1 track exclude-vrrp-interface",
"set high-availability vrrp group g1 track interface 'eth1'",
"set high-availability vrrp group g1 transition-script backup '/var/tmp/script.sh'",
"set high-availability vrrp group g1 transition-script fault '/var/tmp/script.sh'",
"set high-availability vrrp group g1 transition-script master '/var/tmp/script.sh'",
"set high-availability vrrp group g1 transition-script stop '/var/tmp/script.sh'",
"set high-availability vrrp group g1 vrid 20",
"set high-availability vrrp group g2 address '192.168.3.3'",
"set high-availability vrrp group g2 address '192.168.4.4' interface 'eth3'",
"set high-availability vrrp snmp",
"set high-availability vrrp sync-group sg1 health-check failure-count 3",
"set high-availability vrrp sync-group sg1 health-check interval 10",
"set high-availability vrrp sync-group sg1 health-check ping '192.168.1.1'",
"set high-availability vrrp sync-group sg1 health-check script '/var/tmp/script.sh'",
"set high-availability vrrp sync-group sg1 member 'g1'",
"set high-availability vrrp sync-group sg1 transition-script backup '/var/tmp/script.sh'",
"set high-availability vrrp sync-group sg1 transition-script fault '/var/tmp/script.sh'",
"set high-availability vrrp sync-group sg1 transition-script master '/var/tmp/script.sh'",
"set high-availability vrrp sync-group sg1 transition-script stop '/var/tmp/script.sh'",
)
parsed_str = "\n".join(commands)
set_module_args(dict(running_config=parsed_str, state="parsed"))
result = self.execute_module(changed=False)
parsed_list = {
"disable": True,
"virtual_servers": [
{
"name": "s1",
"address": "10.10.10.1",
"algorithm": "round-robin",
"delay_loop": 60,
"forward_method": "direct",
"fwmark": 10,
"persistence_timeout": 30,
"protocol": "tcp",
"real_server": [
{
"address": "10.10.50.1",
"health_check_script": "/var/tmp/script.sh",
"port": 443,
},
],
},
{
"name": "s2",
"address": "10.10.10.2",
"port": 81,
"real_server": [
{
"address": "real1",
"connection_timeout": 5,
"port": 8081,
},
{
"address": "real2",
"port": 8080,
},
],
},
],
"vrrp": {
"snmp": "enabled",
"global_parameters": {
"startup_delay": 30,
"version": "3",
"garp": {
"interval": 30,
"master_delay": 10,
"master_refresh": 100,
"master_refresh_repeat": 200,
"master_repeat": 5,
},
},
"groups": [
{
"name": "g1",
"description": "Group_1",
"disable": True,
"no_preempt": True,
"rfc3768_compatibility": True,
"interface": "eth2",
"address": "1.1.1.1",
"advertise_interval": 10,
"peer_address": "192.168.1.3",
"priority": 100,
"vrid": 20,
"garp": {
"interval": 20,
"master_delay": 5,
"master_refresh": 50,
"master_refresh_repeat": 100,
"master_repeat": 3,
},
"authentication": {
"type": "plaintext-password",
"password": "testpass",
},
"transition_script": {
"master": "/var/tmp/script.sh",
"backup": "/var/tmp/script.sh",
"fault": "/var/tmp/script.sh",
"stop": "/var/tmp/script.sh",
},
"health_check": {
"failure_count": 3,
"interval": 10,
"ping": "192.168.1.5",
"script": "script.sh",
},
"track": {
"exclude_vrrp_interface": True,
"interface": ["eth1"],
},
"excluded_address": [
"192.168.1.7 interface eth3",
"192.168.1.8",
],
"hello_source_address": "192.168.1.2",
},
],
"sync_groups": [
{
"name": "sg1",
"member": ["g1"],
"transition_script": {
"master": "/var/tmp/script.sh",
"backup": "/var/tmp/script.sh",
"fault": "/var/tmp/script.sh",
"stop": "/var/tmp/script.sh",
},
"health_check": {
"failure_count": 3,
"interval": 10,
"ping": "192.168.1.1",
"script": "/var/tmp/script.sh",
},
},
],
},
}
self.assertEqual(sorted(parsed_list), sorted(result["parsed"]))
def test_vrrp_gathered(self):
set_module_args(dict(state="gathered"))
result = self.execute_module(changed=False)
gathered_list = {
"disable": True,
"virtual_servers": [
{
"name": "s1",
"address": "10.10.10.1",
"algorithm": "round-robin",
"delay_loop": 60,
"forward_method": "direct",
"fwmark": 10,
"persistence_timeout": 30,
"protocol": "tcp",
"real_server": [
{
"address": "10.10.50.1",
"health_check_script": "/var/tmp/script.sh",
"port": 443,
},
],
},
{
"name": "s2",
"address": "10.10.10.2",
"port": 81,
"real_server": [
{
"address": "real1",
"connection_timeout": 5,
"port": 8081,
},
{
"address": "real2",
"port": 8080,
},
],
},
],
"vrrp": {
"snmp": "enabled",
"global_parameters": {
"startup_delay": 30,
"version": "3",
"garp": {
"interval": 30,
"master_delay": 10,
"master_refresh": 100,
"master_refresh_repeat": 200,
"master_repeat": 5,
},
},
"groups": [
{
"name": "g1",
"description": "Group_1",
"disable": True,
"no_preempt": True,
"rfc3768_compatibility": True,
"interface": "eth2",
"address": "1.1.1.1",
"advertise_interval": 10,
"peer_address": "192.168.1.3",
"priority": 100,
"vrid": 20,
"garp": {
"interval": 20,
"master_delay": 5,
"master_refresh": 50,
"master_refresh_repeat": 100,
"master_repeat": 3,
},
"authentication": {
"type": "plaintext-password",
"password": "testpass",
},
"transition_script": {
"master": "/var/tmp/script.sh",
"backup": "/var/tmp/script.sh",
"fault": "/var/tmp/script.sh",
"stop": "/var/tmp/script.sh",
},
"health_check": {
"failure_count": 3,
"interval": 10,
"ping": "192.168.1.5",
"script": "script.sh",
},
"track": {
"exclude_vrrp_interface": True,
"interface": ["eth1"],
},
"excluded_address": [
"192.168.1.7 interface eth3",
"192.168.1.8",
],
"hello_source_address": "192.168.1.2",
},
],
"sync_groups": [
{
"name": "sg1",
"member": ["g1"],
"transition_script": {
"master": "/var/tmp/script.sh",
"backup": "/var/tmp/script.sh",
"fault": "/var/tmp/script.sh",
"stop": "/var/tmp/script.sh",
},
"health_check": {
"failure_count": 3,
"interval": 10,
"ping": "192.168.1.1",
"script": "/var/tmp/script.sh",
},
},
],
},
}
self.assertEqual(sorted(gathered_list), sorted(result["gathered"]))
def test_vrrp_groups_deleted(self):
set_module_args(
dict(
config=dict(
vrrp=dict(
groups=[
dict(name="g1"),
],
sync_groups=[
dict(name="sg1"),
],
),
),
state="deleted",
),
)
commands = [
"delete high-availability vrrp group g1",
"delete high-availability vrrp sync-group sg1",
]
self.execute_module(changed=True, commands=commands)
def test_vrrp_objs_deleted(self):
set_module_args(
dict(
config=dict(
disable=False,
vrrp=dict(
global_parameters=dict(
startup_delay=32,
garp=dict(),
),
groups=[
dict(name="g1"),
],
sync_groups=[],
),
virtual_servers=[],
),
state="deleted",
),
)
commands = [
"delete high-availability virtual-server",
"delete high-availability vrrp global-parameters garp",
"delete high-availability vrrp global-parameters startup-delay",
"delete high-availability vrrp group g1",
"delete high-availability vrrp sync-group",
]
self.execute_module(changed=True, commands=commands)
def test_vrrp_deleted_all(self):
set_module_args(
dict(
config=dict(),
state="deleted",
),
)
commands = [
"delete high-availability",
]
self.execute_module(changed=True, commands=commands)
def test_vrrp_purged(self):
set_module_args(
dict(
config=dict(),
state="purged",
),
)
commands = [
"delete high-availability",
]
self.execute_module(changed=True, commands=commands)

File Metadata

Mime Type
text/x-diff
Expires
Sat, Sep 26, 1:02 PM (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4285206
Default Alt Text
(150 KB)

Event Timeline