diff --git a/plugins/module_utils/network/vyos/facts/vrrp/vrrp.py b/plugins/module_utils/network/vyos/facts/vrrp/vrrp.py index ebd245fa..5dadec03 100644 --- a/plugins/module_utils/network/vyos/facts/vrrp/vrrp.py +++ b/plugins/module_utils/network/vyos/facts/vrrp/vrrp.py @@ -1,126 +1,117 @@ # -*- 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 vrrp fact class It is in this file the configuration is collected from the device for a given resource, parsed, and the facts tree is populated based on the configuration. """ import re from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.vrrp.vrrp import ( VrrpArgs, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.vrrp import ( VrrpTemplate, ) class VrrpFacts(object): """The vyos vrrp facts class""" def __init__(self, module, subspec="config", options="options"): self._module = module self.argument_spec = VrrpArgs.argument_spec def get_device_data(self, connection): return connection.get('show configuration commands | match "set high-availability"') def get_config_set(self, data, connection): """To classify the configurations beased on vrrp""" config_dict = {} for config_line in data.splitlines(): vrrp_grp = re.search(r"set high-availability vrrp group (\S+).*", config_line) vrrp_snmp = re.search(r"set high-availability vrrp snmp", config_line) vrrp_gp = re.search( r"set high-availability vrrp global-parameters (\S+).*", config_line, ) vrrp_sg = re.search(r"set high-availability vrrp sync-group (\S+).*", config_line) vrrp_vsrv = re.search(r"set high-availability virtual-server (\S+).*", config_line) vrrp_disable = re.search(r"set high-availability disable", config_line) if vrrp_disable: config_dict["disable"] = config_dict.get("disable", "") + config_line + "\n" if vrrp_gp: config_dict["global_parameters"] = ( config_dict.get(vrrp_gp.group(1), "") + config_line + "\n" ) if vrrp_vsrv: config_dict[vrrp_vsrv.group(1)] = ( config_dict.get(vrrp_vsrv.group(1), "") + config_line + "\n" ) if vrrp_sg: config_dict[vrrp_sg.group(1)] = ( config_dict.get(vrrp_sg.group(1), "") + config_line + "\n" ) if vrrp_grp: config_dict[vrrp_grp.group(1)] = ( config_dict.get(vrrp_grp.group(1), "") + config_line + "\n" ) return list(config_dict.values()) def populate_facts(self, connection, ansible_facts, data=None): """Populate the facts for vrrp network resource :param connection: the device connection :param ansible_facts: Facts dictionary :param data: previously collected conf :rtype: dictionary :returns: facts """ facts = {} objs = {} config_lines = [] if not data: data = self.get_device_data(connection) vrrp_facts = {} groups = [] sync_groups = [] vsvrs = [] resources = self.get_config_set(data, connection) # self._module.fail_json(msg=resources) for resource in data.splitlines(): # resources: vrrp_parser = VrrpTemplate( lines=resource.split("\n"), module=self._module, ) objs = vrrp_parser.parse() - self._module.fail_json(msg=str(resource.split("\n")) + "******" + str(objs)) - if objs: - if "disable" in objs: - vrrp_facts.update(objs) - if "group" in objs: - groups.append(objs) - if "virtual_servers" in objs: - vsvrs.append(objs) - if "sync_groups" in objs: - sync_groups.append(objs) - - if groups: - vrrp_facts.update({"groups": groups}) - - self._module.fail_json(msg=str(vrrp_facts)) + if "virtual_servers" in objs: + objs["virtual_servers"] = sorted( + list(objs["virtual_servers"].values()), + key=lambda k, sk="alias": k[sk], + ) + self._module.fail_json(msg=str(objs)) ansible_facts["ansible_network_resources"].pop("vrrp", None) params = utils.remove_empties( vrrp_parser.validate_config(self.argument_spec, {"config": objs}, redact=True), ) facts["vrrp"] = params.get("config", []) ansible_facts["ansible_network_resources"].update(facts) self._module.fail_json(msg=ansible_facts) return ansible_facts diff --git a/plugins/module_utils/network/vyos/rm_templates/vrrp.py b/plugins/module_utils/network/vyos/rm_templates/vrrp.py index 8147e487..3b373dd2 100644 --- a/plugins/module_utils/network/vyos/rm_templates/vrrp.py +++ b/plugins/module_utils/network/vyos/rm_templates/vrrp.py @@ -1,717 +1,628 @@ # -*- 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 Bgp_global 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.module_utils.six import iteritems from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import ( NetworkTemplate, ) class VrrpTemplate(NetworkTemplate): def __init__(self, lines=None, module=None): prefix = {"set": "set", "remove": "delete"} super(VrrpTemplate, self).__init__( lines=lines, tmplt=self, prefix=prefix, module=module, ) def _tmplt_vsrvs(config_data): config_data = config_data["virtual-server"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_vsrvs_rsrv(config_data): config_data = config_data["virtual-server"]["real_servers"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_sgroup_hc(config_data): config_data = config_data["sync-group"]["health-check"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_sgroup_ts(config_data): config_data = config_data["sync-group"]["transition-script"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_vrrp_gp(config_data): config_data = config_data["vrrp"]["global-parameters"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_vrrp_gp_garp(config_data): config_data = config_data["vrrp"]["global-parameters"]["garp"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_vrrp_group(config_data): config_data = config_data["vrrp"]["group"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_vrrp_group_track(config_data): config_data = config_data["vrrp"]["group"]["track"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_vrrp_group_hc(config_data): config_data = config_data["vrrp"]["group"]["health-check"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_vrrp_group_ts(config_data): config_data = config_data["vrrp"]["group"]["transcription-script"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_vrrp_group_garp(config_data): config_data = config_data["vrrp"]["group"]["garp"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command def _tmplt_vrrp_group_auth(config_data): config_data = config_data["vrrp"]["group"]["authentication"] command = [] # cmd = "service snmp v3 group {group}".format(**config_data) # if "mode" in config_data: # mode_cmd = cmd + " mode {mode}".format(**config_data) # command.append(mode_cmd) # if "seclevel" in config_data: # sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) # command.append(sec_cmd) # if "view" in config_data: # view_cmd = cmd + " view {view}".format(**config_data) # command.append(view_cmd) return command # fmt: off PARSERS = [ { "name": "disable", "getval": re.compile( r""" ^set \shigh-availability \s(?Pdisable) $""", re.VERBOSE, ), "setval": "high-availability disable", "result": { "disable": "{{ True if disable is defined }}", }, }, - { - "name": "vg_addr", - "getval": re.compile( - r""" - ^set - \shigh-availability - \svrrp - \sgroup - \s(?P\S+) - \saddress - \s(?P
\S+) - $""", - re.VERBOSE, - ), - "setval": "high-availability vrrp group {{group}} address {{address}}", - "compval": "address", - "result": { - "group": "{{ group }}", - "address": "{{ address }}", - }, - }, - { - "name": "vg_addr_addr_int", - "getval": re.compile( - r""" - ^set - \shigh-availability - \svrrp - \sgroup - \s(?P\S+) - \saddress - \s(?P
\S+) - \sinterface - \s(?P\S+) - $""", - re.VERBOSE, - ), - "setval": "high-availability vrrp group {{group}} address {{address}} interface {{interface}}", - "compval": "interface", - "result": { - "group": "{{ group }}", - "address": "{{ address }}", - "interface": "{{ interface }}", - }, - }, - { - "name": "vg_excluded_addr", - "getval": re.compile( - r""" - ^set - \shigh-availability - \svrrp - \sgroup - \s(?P\S+) - \sexcluded-address - \s(?P\S+) - $""", - re.VERBOSE, - ), - "setval": "high-availability vrrp group {{group}} excluded-address {{excluded_addr}}", - "compval": "excluded_address", - "result": { - "group": "{{ group }}", - "excluded_address": "{{ excluded_addr }}", - }, - }, - { - "name": "vg_excluded_addr_int", - "getval": re.compile( - r""" - ^set - \shigh-availability - \svrrp - \sgroup - \s(?P\S+) - \sexcluded-address - \s(?P\S+) - \sinterface - \s(?P\S+) - $""", - re.VERBOSE, - ), - "setval": "high-availability vrrp group {{group}} excluded-address {{excluded_addr}} interface {{excluded_addr_interface}}", - "compval": "excluded_address_interface", - "result": { - "group": "{{ group }}", - "excluded_address_interface": "{{ excluded_address_int }}", - }, - }, { "name": "virtual_servers", "getval": re.compile( r""" ^set\shigh-availability\svirtual-server \s+(?P\S+) (?:\s+address\s+(?P
\S+))? (?:\s+algorithm\s+(?P\S+))? (?:\s+delay-loop\s+(?P\S+))? (?:\s+forward-method\s+(?P\S+))? (?:\s+fwmark\s+(?P\S+))? (?:\s+persistence-timeout\s+(?P\S+))? (?:\s+port\s+(?P\S+))? (?:\s+protocol\s+(?P\S+))? $ """, re.VERBOSE, ), "setval": _tmplt_vsrvs, "result": { "virtual_servers": { "{{ alias }}": { "alias": "{{ alias }}", "address": "{{ address if address is defined else None }}", "algorithm": "{{ algorithm if algorithm is defined else None }}", "delay_loop": "{{ delay_loop if delay_loop is defined else None }}", "forward_method": "{{ forward_method if forward_method is defined else None }}", "fwmark": "{{ fwmark if fwmark is defined else None }}", "persistence_timeout": "{{ persistence_timeout if persistence_timeout is defined else None }}", "port": "{{ port if port is defined else None }}", "protocol": "{{ protocol if protocol is defined else None }}", }, }, }, }, - { - "name": "virtual_servers.real_servers", - "getval": re.compile( - r""" - ^set\shigh-availability\svirtual-server - \s+(?P\S+) - \sreal-server - \s+(?P\S+) - (?:\s+port\s+(?P\S+))? - (?:\s+health-check\sscript\s+(?P\S+))? - (?:\s+connection-timeout\s+(?P\S+))? - $ - """, - re.VERBOSE, - ), - "setval": _tmplt_vsrvs_rsrv, - # "compval": "global_parameters.garp.master_refersh_repeat", - "result": { - "virtual_servers": { - "{{ alias }}": { - "alias": "{{ alias }}", - "real_servers": { - "{{ name }}": { - "name": "{{ name }}", - "port": "{{ portif port is defined else None }}", - "health_check_script": "{{ hcscript f hcscript is defined else None }}", - "connection_timeout": "{{ cont if cont is defined else None }}", - }, - }, - }, - }, - }, - }, - { - "name": "sync_group.member", - "getval": re.compile( - r""" - ^set\shigh-availability\svrrp\ssync-group - \s+(?P\S+) - \smember - \s+(?P\S+) - $ - """, - re.VERBOSE, - ), - "setval": "set high-availability vrrp sync-group {{sgname}} member {{member}}", - "compval": "sync_groups.member", - "result": { - "sync_groups": { - "{{ sgname }}": { - "name": "{{ sgname }}", - "member": "{{ member }}", - }, - }, - }, - }, - { - "name": "sync_group.health_check", - "getval": re.compile( - r""" - ^set\shigh-availability\svrrp\ssync-group - \s+(?P\S+) - \shealth-check - (?:\s+failure-count\s+(?P\S+)) - ?(?:\s+interval\s+(?P\S+)) - ?(?:\s+ping\s+(?P\S+)) - ?(?:\s+script\s+(?P