diff --git a/changelogs/fragments/rm_base.yaml b/changelogs/fragments/rm_base.yaml new file mode 100644 index 0000000..eeca679 --- /dev/null +++ b/changelogs/fragments/rm_base.yaml @@ -0,0 +1,3 @@ +--- +trivial: + - Move references for ResourceModule to the rm_base package as the non-rm_base path is going away. (https://github.com/ansible-collections/ansible.netcommon/pull/496) diff --git a/plugins/module_utils/network/vyos/config/bgp_address_family/bgp_address_family.py b/plugins/module_utils/network/vyos/config/bgp_address_family/bgp_address_family.py index 876402f..a62e6a5 100644 --- a/plugins/module_utils/network/vyos/config/bgp_address_family/bgp_address_family.py +++ b/plugins/module_utils/network/vyos/config/bgp_address_family/bgp_address_family.py @@ -1,369 +1,369 @@ # # -*- 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_bgp_address_family 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. """ import re from ansible.module_utils.six import iteritems from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( dict_merge, ) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.resource_module import ( +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import ( ResourceModule, ) 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.bgp_address_family import ( Bgp_address_familyTemplate, ) class Bgp_address_family(ResourceModule): """ The vyos_bgp_address_family config class """ def __init__(self, module): super(Bgp_address_family, self).__init__( empty_fact_val={}, facts_module=Facts(module), module=module, resource="bgp_address_family", tmplt=Bgp_address_familyTemplate(), ) self.parsers = [] def execute_module(self): """Execute the module :rtype: A dictionary :returns: The result from module execution """ if self.state not in ["parsed", "gathered"]: self.generate_commands() self.run_commands() return self.result def generate_commands(self): """Generate configuration commands to send based on want, have and desired state. """ wantd = {} haved = {} if ( self.want.get("as_number") == self.have.get("as_number") or not self.have ): if self.want: wantd = {self.want["as_number"]: self.want} if self.have: haved = {self.have["as_number"]: self.have} else: self._module.fail_json( msg="Only one bgp instance is allowed per device" ) # turn all lists of dicts into dicts prior to merge for entry in wantd, haved: self._bgp_af_list_to_dict(entry) # if state is merged, merge want onto have and then compare if self.state == "merged": wantd = dict_merge(haved, wantd) # if state is deleted, empty out wantd and set haved to wantd if self.state == "deleted": for k, have in iteritems(haved): self._delete_af(wantd, have) wantd = {} if self.state == "overridden": for k, have in iteritems(haved): if k not in wantd: self._compare(want={}, have=have) for k, want in iteritems(wantd): self._compare(want=want, have=haved.pop(k, {})) def _compare(self, want, have): """Leverages the base class `compare()` method and populates the list of commands to be run by comparing the `want` and `have` data with the `parsers` defined for the Bgp_address_family network resource. """ self._compare_af(want, have) self._compare_neighbors(want, have) # Do the negation first command_set = [] for cmd in self.commands: if cmd not in command_set: if "delete" in cmd: command_set.insert(0, cmd) else: command_set.append(cmd) self.commands = command_set def _compare_af(self, want, have): waf = want.get("address_family", {}) haf = have.get("address_family", {}) for name, entry in iteritems(waf): self._compare_lists( entry, have=haf.get(name, {}), as_number=want["as_number"], afi=name, ) for name, entry in iteritems(haf): if name not in waf.keys() and self.state == "replaced": continue self._compare_lists( {}, entry, as_number=have["as_number"], afi=name ) def _delete_af(self, want, have): for as_num, entry in iteritems(want): for afi, af_entry in iteritems(entry.get("address_family", {})): if have.get("address_family"): for hafi, hentry in iteritems(have["address_family"]): if hafi == afi: self.commands.append( self._tmplt.render( { "as_number": as_num, "address_family": {"afi": afi}, }, "address_family", True, ) ) for neigh, neigh_entry in iteritems(entry.get("neighbors", {})): if have.get("neighbors"): for hneigh, hnentry in iteritems(have["neighbors"]): if hneigh == neigh: if not neigh_entry.get("address_family"): self.commands.append( self._tmplt.render( { "as_number": as_num, "neighbors": { "neighbor_address": neigh }, }, "neighbors", True, ) ) else: for k in neigh_entry["address_family"].keys(): if ( hnentry.get("address_family") and k in hnentry["address_family"].keys() ): self.commands.append( self._tmplt.render( { "as_number": as_num, "neighbors": { "neighbor_address": neigh, "address_family": { "afi": k }, }, }, "neighbors.address_family", True, ) ) def _compare_neighbors(self, want, have): parsers = [ "neighbors.allowas_in", "neighbors.as_override", "neighbors.attribute_unchanged.as_path", "neighbors.attribute_unchanged.med", "neighbors.attribute_unchanged.next_hop", "neighbors.capability_dynamic", "neighbors.capability_orf", "neighbors.default_originate", "neighbors.distribute_list", "neighbors.prefix_list", "neighbors.filter_list", "neighbors.maximum_prefix", "neighbors.nexthop_local", "neighbors.nexthop_self", "neighbors.peer_group", "neighbors.remove_private_as", "neighbors.route_map", "neighbors.route_reflector_client", "neighbors.route_server_client", "neighbors.soft_reconfiguration", "neighbors.unsuppress_map", "neighbors.weight", ] wneigh = want.get("neighbors", {}) hneigh = have.get("neighbors", {}) for name, entry in iteritems(wneigh): for afi, af_entry in iteritems(entry.get("address_family")): for k, val in iteritems(af_entry): w = { "as_number": want["as_number"], "neighbors": { "neighbor_address": name, "address_family": {"afi": afi, k: val}, }, } h = {} if hneigh.get(name): if hneigh[name]["address_family"].get(afi): if hneigh[name]["address_family"][afi].get(k): h = { "as_number": want["as_number"], "neighbors": { "neighbor_address": name, "address_family": { "afi": afi, k: hneigh[name]["address_family"][ afi ].pop(k, {}), }, }, } self.compare( parsers=parsers, want=w, have=h, ) for name, entry in iteritems(hneigh): if name not in wneigh.keys(): # remove surplus config for overridden and replaced if self.state != "replaced": self.commands.append( self._tmplt.render( { "as_number": have["as_number"], "neighbors": {"neighbor_address": name}, }, "neighbors", True, ) ) continue for hafi, haf_entry in iteritems(entry.get("address_family")): # remove surplus configs for given neighbor - replace and overridden for k, val in iteritems(haf_entry): h = { "as_number": have["as_number"], "neighbors": { "neighbor_address": name, "address_family": {"afi": hafi, k: val}, }, } self.compare(parsers=parsers, want={}, have=h) def _compare_lists(self, want, have, as_number, afi): parsers = [ "aggregate_address", "network.backdoor", "network.path_limit", "network.route_map", "redistribute.metric", "redistribute.route_map", "redistribute.table", ] for attrib in ["redistribute", "networks", "aggregate_address"]: wdict = want.pop(attrib, {}) hdict = have.pop(attrib, {}) for key, entry in iteritems(wdict): if entry != hdict.get(key, {}): self.compare( parsers=parsers, want={ "as_number": as_number, "address_family": {"afi": afi, attrib: entry}, }, have={ "as_number": as_number, "address_family": { "afi": afi, attrib: hdict.pop(key, {}), }, }, ) hdict.pop(key, {}) # remove remaining items in have for replaced if not wdict and hdict: attrib = re.sub("_", "-", attrib) attrib = re.sub("networks", "network", attrib) self.commands.append( "delete protocols bgp " + str(as_number) + " " + "address-family " + afi + " " + attrib ) hdict = {} for key, entry in iteritems(hdict): self.compare( parsers=parsers, want={}, have={ "as_number": as_number, "address_family": {"afi": afi, attrib: entry}, }, ) def _bgp_af_list_to_dict(self, entry): for name, proc in iteritems(entry): if "address_family" in proc: af_dict = {} for entry in proc.get("address_family"): if "networks" in entry: network_dict = {} for n_entry in entry.get("networks", []): network_dict.update({n_entry["prefix"]: n_entry}) entry["networks"] = network_dict if "aggregate_address" in entry: agg_dict = {} for a_entry in entry.get("aggregate_address", []): agg_dict.update({a_entry["prefix"]: a_entry}) entry["aggregate_address"] = agg_dict if "redistribute" in entry: redis_dict = {} for r_entry in entry.get("redistribute", []): proto_key = r_entry.get("protocol", "table") redis_dict.update({proto_key: r_entry}) entry["redistribute"] = redis_dict for af in proc.get("address_family"): af_dict.update({af["afi"]: af}) proc["address_family"] = af_dict if "neighbors" in proc: neigh_dict = {} for entry in proc.get("neighbors", []): neigh_dict.update({entry["neighbor_address"]: entry}) proc["neighbors"] = neigh_dict self._bgp_af_list_to_dict(proc["neighbors"]) diff --git a/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py b/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py index 0a5f15d..f8de74e 100644 --- a/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py +++ b/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py @@ -1,426 +1,426 @@ # # -*- 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_bgp_global 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. """ import re from ansible.module_utils.six import iteritems from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( dict_merge, ) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.resource_module import ( +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import ( ResourceModule, ) 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.bgp_global import ( Bgp_globalTemplate, ) class Bgp_global(ResourceModule): """ The vyos_bgp_global config class """ def __init__(self, module): super(Bgp_global, self).__init__( empty_fact_val={}, facts_module=Facts(module), module=module, resource="bgp_global", tmplt=Bgp_globalTemplate(), ) self.parsers = [] def execute_module(self): """Execute the module :rtype: A dictionary :returns: The result from module execution """ if self.state not in ["parsed", "gathered"]: self.generate_commands() self.run_commands() return self.result def generate_commands(self): """Generate configuration commands to send based on want, have and desired state. """ wantd = {} haved = {} if ( self.want.get("as_number") == self.have.get("as_number") or not self.have ): if self.want: wantd = {self.want["as_number"]: self.want} if self.have: haved = {self.have["as_number"]: self.have} else: self._module.fail_json( msg="Only one bgp instance is allowed per device" ) # turn all lists of dicts into dicts prior to merge for entry in wantd, haved: self._bgp_global_list_to_dict(entry) # if state is merged, merge want onto have and then compare if self.state == "merged": wantd = dict_merge(haved, wantd) # if state is deleted, empty out wantd and set haved to wantd if self.state == "purged": h_del = {} for k, v in iteritems(haved): if k in wantd or not wantd: h_del.update({k: v}) for num, entry in iteritems(h_del): self.commands.append( self._tmplt.render({"as_number": num}, "router", True) ) wantd = {} if self.state == "deleted": self._compare(want={}, have=self.have) wantd = {} for k, want in iteritems(wantd): self._compare(want=want, have=haved.pop(k, {})) def _compare(self, want, have): """Leverages the base class `compare()` method and populates the list of commands to be run by comparing the `want` and `have` data with the `parsers` defined for the Bgp_global network resource. """ parsers = ["maximum_paths", "timers"] self._compare_neighbor(want, have) self._compare_lists(want, have) self._compare_bgp_params(want, have) for name, entry in iteritems(want): if name != "as_number": self.compare( parsers=parsers, want={"as_number": want["as_number"], name: entry}, have={ "as_number": want["as_number"], name: have.pop(name, {}), }, ) for name, entry in iteritems(have): if name != "as_number": self.compare( parsers=parsers, want={}, have={"as_number": have["as_number"], name: entry}, ) # Do the negation first command_set = [] for cmd in self.commands: if cmd not in command_set: if "delete" in cmd: command_set.insert(0, cmd) else: command_set.append(cmd) self.commands = command_set def _compare_neighbor(self, want, have): parsers = [ "neighbor.advertisement_interval", "neighbor.allowas_in", "neighbor.as_override", "neighbor.attribute_unchanged.as_path", "neighbor.attribute_unchanged.med", "neighbor.attribute_unchanged.next_hop", "neighbor.capability_dynamic", "neighbor.capability_orf", "neighbor.default_originate", "neighbor.description", "neighbor.disable_capability_negotiation", "neighbor.disable_connected_check", "neighbor.disable_send_community", "neighbor.distribute_list", "neighbor.ebgp_multihop", "neighbor.filter_list", "neighbor.local_as", "neighbor.maximum_prefix", "neighbor.nexthop_self", "neighbor.override_capability", "neighbor.passive", "neighbor.password", "neighbor.peer_group_name", "neighbor.port", "neighbor.prefix_list", "neighbor.remote_as", "neighbor.remove_private_as", "neighbor.route_map", "neighbor.route_reflector_client", "neighbor.route_server_client", "neighbor.shutdown", "neighbor.soft_reconfiguration", "neighbor.strict_capability_match", "neighbor.unsuppress_map", "neighbor.update_source", "neighbor.weight", "neighbor.ttl_security", "neighbor.timers", "network.backdoor", "network.route_map", ] wneigh = want.pop("neighbor", {}) hneigh = have.pop("neighbor", {}) self._compare_neigh_lists(wneigh, hneigh) for name, entry in iteritems(wneigh): for k, v in entry.items(): if k == "address": continue if hneigh.get(name): h = {"address": name, k: hneigh[name].pop(k, {})} else: h = {} self.compare( parsers=parsers, want={ "as_number": want["as_number"], "neighbor": {"address": name, k: v}, }, have={"as_number": want["as_number"], "neighbor": h}, ) for name, entry in iteritems(hneigh): if name not in wneigh.keys(): if self._check_af(name): msg = "Use the _bgp_address_family module to delete the address_family under neighbor {0}, before replacing/deleting the neighbor.".format( name ) self._module.fail_json(msg=msg) else: self.commands.append( "delete protocols bgp " + str(have["as_number"]) + " neighbor " + name ) continue for k, v in entry.items(): self.compare( parsers=parsers, want={}, have={ "as_number": have["as_number"], "neighbor": {"address": name, k: v}, }, ) def _compare_bgp_params(self, want, have): parsers = [ "bgp_params.always_compare_med", "bgp_params.bestpath.as_path", "bgp_params.bestpath.compare_routerid", "bgp_params.bestpath.med", "bgp_params.cluster_id", "bgp_params.confederation", "bgp_params.dampening_half_life", "bgp_params.dampening_max_suppress_time", "bgp_params.dampening_re_use", "bgp_params.dampening_start_suppress_time", "bgp_params.default", "bgp_params.deterministic_med", "bgp_params.disbale_network_import_check", "bgp_params.enforce_first_as", "bgp_params.graceful_restart", "bgp_params.log_neighbor_changes", "bgp_params.no_client_to_client_reflection", "bgp_params.no_fast_external_failover", "bgp_params.routerid", "bgp_params.scan_time", ] wbgp = want.pop("bgp_params", {}) hbgp = have.pop("bgp_params", {}) for name, entry in iteritems(wbgp): if name == "confederation": if entry != hbgp.pop(name, {}): self.addcmd( { "as_number": want["as_number"], "bgp_params": {name: entry}, }, "bgp_params.confederation", False, ) elif name == "distance": if entry != hbgp.pop(name, {}): distance_parsers = [ "bgp_params.distance.global", "bgp_params.distance.prefix", ] for distance_type in entry: self.compare( parsers=distance_parsers, want={ "as_number": want["as_number"], "bgp_params": {name: distance_type}, }, have={ "as_number": want["as_number"], "bgp_params": {name: hbgp.pop(name, {})}, }, ) else: self.compare( parsers=parsers, want={ "as_number": want["as_number"], "bgp_params": {name: entry}, }, have={ "as_number": want["as_number"], "bgp_params": {name: hbgp.pop(name, {})}, }, ) if not wbgp and hbgp: self.commands.append( "delete protocols bgp " + str(have["as_number"]) + " parameters" ) hbgp = {} for name, entry in iteritems(hbgp): if name == "confederation": self.commands.append( "delete protocols bgp " + str(have["as_number"]) + " parameters confederation" ) elif name == "distance": distance_parsers = [ "bgp_params.distance.global", "bgp_params.distance.prefix", ] self.compare( parsers=distance_parsers, want={}, have={ "as_number": have["as_number"], "bgp_params": {name: entry[0]}, }, ) else: self.compare( parsers=parsers, want={}, have={ "as_number": have["as_number"], "bgp_params": {name: entry}, }, ) def _compare_lists(self, want, have): parsers = [ "network.backdoor", "network.route_map", "redistribute.metric", "redistribute.route_map", "aggregate_address", ] for attrib in ["redistribute", "network", "aggregate_address"]: wdict = want.pop(attrib, {}) hdict = have.pop(attrib, {}) for key, entry in iteritems(wdict): if entry != hdict.get(key, {}): self.compare( parsers=parsers, want={"as_number": want["as_number"], attrib: entry}, have=hdict.pop(key, {}), ) hdict.pop(key, {}) # remove remaining items in have for replaced if not wdict and hdict: attrib = re.sub("_", "-", attrib) self.commands.append( "delete protocols bgp " + str(have["as_number"]) + " " + attrib ) hdict = {} for key, entry in iteritems(hdict): self.compare( parsers=parsers, want={}, have={"as_number": have["as_number"], attrib: entry}, ) def _compare_neigh_lists(self, want, have): for attrib in [ "distribute_list", "filter_list", "prefix_list", "route_map", ]: wdict = want.pop(attrib, {}) hdict = have.pop(attrib, {}) for key, entry in iteritems(wdict): if entry != hdict.pop(key, {}): self.addcmd(entry, "neighbor.{0}".format(attrib), False) # remove remaining items in have for replaced for entry in hdict.values(): self.addcmd(entry, "neighbor.{0}".format(attrib), True) def _bgp_global_list_to_dict(self, entry): for name, proc in iteritems(entry): if "neighbor" in proc: neigh_dict = {} for entry in proc.get("neighbor", []): neigh_dict.update({entry["address"]: entry}) proc["neighbor"] = neigh_dict if "network" in proc: network_dict = {} for entry in proc.get("network", []): network_dict.update({entry["address"]: entry}) proc["network"] = network_dict if "aggregate_address" in proc: agg_dict = {} for entry in proc.get("aggregate_address", []): agg_dict.update({entry["prefix"]: entry}) proc["aggregate_address"] = agg_dict if "redistribute" in proc: redis_dict = {} for entry in proc.get("redistribute", []): redis_dict.update({entry["protocol"]: entry}) proc["redistribute"] = redis_dict def _check_af(self, neighbor): af_present = False if self._connection: config_lines = self._get_config(self._connection).splitlines() for line in config_lines: if "address-family" in line: af_present = True return af_present def _get_config(self, connection): return connection.get( 'show configuration commands | match "set protocols bgp .* neighbor"' ) diff --git a/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py b/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py index c7590ee..dbdce48 100644 --- a/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py +++ b/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py @@ -1,170 +1,170 @@ # # -*- coding: utf-8 -*- # Copyright 2020 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_ospf_interfaces 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 ansible.module_utils.six import iteritems from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( dict_merge, ) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.resource_module import ( +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import ( ResourceModule, ) 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.ospf_interfaces import ( Ospf_interfacesTemplate, ) class Ospf_interfaces(ResourceModule): """ The vyos_ospf_interfaces config class """ def __init__(self, module): super(Ospf_interfaces, self).__init__( empty_fact_val={}, facts_module=Facts(module), module=module, resource="ospf_interfaces", tmplt=Ospf_interfacesTemplate(), ) self.parsers = [ "authentication_password", "authentication_md5", "bandwidth", "cost", "hello_interval", "dead_interval", "mtu_ignore", "network", "priority", "retransmit_interval", "transmit_delay", "ifmtu", "instance", "passive", ] def execute_module(self): """Execute the module :rtype: A dictionary :returns: The result from module execution """ if self.state not in ["parsed", "gathered"]: self.generate_commands() self.run_commands() return self.result def generate_commands(self): """Generate configuration commands to send based on want, have and desired state. """ wantd = {} haved = {} for entry in self.want: wantd.update({entry["name"]: entry}) for entry in self.have: haved.update({entry["name"]: entry}) # turn all lists of dicts into dicts prior to merge for entry in wantd, haved: self._ospf_int_list_to_dict(entry) # if state is merged, merge want onto have and then compare if self.state == "merged": wantd = dict_merge(haved, wantd) # if state is deleted, empty out wantd and set haved to wantd if self.state == "deleted": h_del = {} for k, v in iteritems(haved): if k in wantd or not wantd: h_del.update({k: v}) haved = h_del have_int = [] for k, have in iteritems(haved): if k in wantd: have_int.append(k) self._remove_ospf_int(have) wantd = {} if self.state == "overridden": have_int = [] for k, have in iteritems(haved): if k not in wantd: have_int.append(k) self._remove_ospf_int(have) # remove superfluous config for overridden and deleted if self.state in ["overridden", "deleted"]: # removing the interfaces from haved that are already negated for interface in have_int: haved.pop(interface) for k, have in iteritems(haved): if k not in wantd: self._compare(want={}, have=have) for k, want in iteritems(wantd): self._compare(want=want, have=haved.pop(k, {})) def _remove_ospf_int(self, entry): int_name = entry.get("name", {}) int_addr = entry.get("address_family", {}) for k, addr in iteritems(int_addr): rem_entry = {"name": int_name, "address_family": {"afi": k}} self.addcmd(rem_entry, "ip_ospf", True) def _compare(self, want, have): """Leverages the base class `compare()` method and populates the list of commands to be run by comparing the `want` and `have` data with the `parsers` defined for the Ospf_interfaces network resource. """ self._compare_addr_family(want=want, have=have) def _compare_addr_family(self, want, have): wdict = want.get("address_family", {}) hdict = have.get("address_family", {}) wname = want.get("name") hname = have.get("name") for name, entry in iteritems(wdict): for key, param in iteritems(entry): w_addr = {"afi": name, key: param} h_addr = {} if hdict.get(name): h_addr = {"afi": name, key: hdict[name].pop(key, {})} w = {"name": wname, "address_family": w_addr} h = {"name": hname, "address_family": h_addr} self.compare(parsers=self.parsers, want=w, have=h) for name, entry in iteritems(hdict): for key, param in iteritems(entry): h_addr = {"afi": name, key: param} w_addr = {} w = {"name": wname, "address_family": w_addr} h = {"name": hname, "address_family": h_addr} self.compare(parsers=self.parsers, want=w, have=h) def _ospf_int_list_to_dict(self, entry): for name, family in iteritems(entry): if "address_family" in family: addr_dict = {} for entry in family.get("address_family", []): addr_dict.update({entry["afi"]: entry}) family["address_family"] = addr_dict self._ospf_int_list_to_dict(family["address_family"]) diff --git a/plugins/module_utils/network/vyos/config/route_maps/route_maps.py b/plugins/module_utils/network/vyos/config/route_maps/route_maps.py index 467d782..c719e6d 100644 --- a/plugins/module_utils/network/vyos/config/route_maps/route_maps.py +++ b/plugins/module_utils/network/vyos/config/route_maps/route_maps.py @@ -1,160 +1,160 @@ # # -*- 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_route_maps 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 ansible.module_utils.six import iteritems from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( dict_merge, ) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.resource_module import ( +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import ( ResourceModule, ) 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.route_maps import ( Route_mapsTemplate, ) class Route_maps(ResourceModule): """ The vyos_route_maps config class """ def __init__(self, module): super(Route_maps, self).__init__( empty_fact_val=[], facts_module=Facts(module), module=module, resource="route_maps", tmplt=Route_mapsTemplate(), ) self.parsers = [ "call", "description", "action", "continue_sequence", "set_aggregator_ip", "set_aggregator_as", "set_as_path_exclude", "set_as_path_prepend", "set_atomic_aggregate", "set_bgp_extcommunity_rt", "set_extcommunity_rt", "set_extcommunity_soo", "set_ip_next_hop", "set_ipv6_next_hop", "set_large_community", "set_local_preference", "set_metric", "set_metric_type", "set_origin", "set_originator_id", "set_src", "set_tag", "set_weight", "set_comm_list", "set_comm_list_delete", "set_community", "match_as_path", "match_community_community_list", "match_community_exact_match", "match_extcommunity", "match_interface", "match_large_community_large_community_list", "match_metric", "match_origin", "match_peer", "match_ip_address", "match_ip_next_hop", "match_ip_route_source", "on_match_goto", "on_match_next", "match_ipv6_address", "match_ipv6_nexthop", "match_rpki", ] def execute_module(self): """Execute the module :rtype: A dictionary :returns: The result from module execution """ if self.state not in ["parsed", "gathered"]: self.generate_commands() self.run_commands() return self.result def generate_commands(self): """Generate configuration commands to send based on want, have and desired state. """ wantd = self._route_maps_list_to_dict(self.want) haved = self._route_maps_list_to_dict(self.have) # if state is merged, merge want onto have and then compare if self.state == "merged": wantd = dict_merge(haved, wantd) # if state is deleted, empty out wantd and set haved to wantd if self.state == "deleted": haved = { k: v for k, v in iteritems(haved) if k in wantd or not wantd } wantd = {} # remove superfluous config for overridden and deleted if self.state in ["overridden", "deleted"]: for k, have in iteritems(haved): if k not in wantd: self.commands.append( self._tmplt.render({"route_map": k}, "route_map", True) ) for wk, want in iteritems(wantd): self._compare(want=want, have=haved.pop(wk, {})) def _compare(self, want, have): """Leverages the base class `compare()` method and populates the list of commands to be run by comparing the `want` and `have` data with the `parsers` defined for the Route_maps network resource. """ w_entries = want.get("entries", {}) h_entries = have.get("entries", {}) self._compare_entries(want=w_entries, have=h_entries) def _compare_entries(self, want, have): for wk, wentry in iteritems(want): hentry = have.pop(wk, {}) self.compare(parsers=self.parsers, want=wentry, have=hentry) def _route_maps_list_to_dict(self, entry): entry = {x["route_map"]: x for x in entry} for rmap, data in iteritems(entry): if "entries" in data: for x in data["entries"]: x.update({"route_map": rmap}) data["entries"] = { (rmap, entry.get("sequence")): entry for entry in data["entries"] } return entry diff --git a/plugins/module_utils/network/vyos/rm_templates/bgp_address_family.py b/plugins/module_utils/network/vyos/rm_templates/bgp_address_family.py index ae953e4..ddff1bb 100644 --- a/plugins/module_utils/network/vyos/rm_templates/bgp_address_family.py +++ b/plugins/module_utils/network/vyos/rm_templates/bgp_address_family.py @@ -1,1421 +1,1421 @@ # -*- 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_address_family 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.network_template import ( +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import ( NetworkTemplate, ) def _tmplt_bgp_af_aggregate_address(config_data): afi = config_data["address_family"]["afi"] + "-unicast" command = "protocols bgp {as_number} address-family ".format(**config_data) config_data = config_data["address_family"] if config_data["aggregate_address"].get("as_set"): command += afi + " aggregate-address {prefix} as-set".format( **config_data["aggregate_address"] ) if config_data["aggregate_address"].get("summary_only"): command += afi + " aggregate-address {prefix} summary-only".format( **config_data["aggregate_address"] ) return command def _tmplt_bgp_af_redistribute_metric(config_data): if config_data["address_family"]["redistribute"].get("metric"): afi = config_data["address_family"]["afi"] + "-unicast" command = "protocols bgp {as_number} address-family ".format( **config_data ) if config_data["address_family"]["redistribute"].get("metric"): command += afi + " redistribute {protocol} metric {metric}".format( **config_data["address_family"]["redistribute"] ) return command def _tmplt_bgp_af_redistribute_route_map(config_data): if config_data["address_family"]["redistribute"].get("route_map"): afi = config_data["address_family"]["afi"] + "-unicast" command = "protocols bgp {as_number} address-family ".format( **config_data ) if config_data["address_family"]["redistribute"].get("route_map"): command += ( afi + " redistribute {protocol} route-map {route_map}".format( **config_data["address_family"]["redistribute"] ) ) return command def _tmplt_bgp_af_redistribute_table(config_data): if config_data["address_family"]["redistribute"].get("table"): afi = config_data["address_family"]["afi"] + "-unicast" command = "protocols bgp {as_number} address-family ".format( **config_data ) if config_data["address_family"]["redistribute"].get("table"): command += afi + " table {table}".format( **config_data["address_family"]["redistribute"] ) return command def _tmplt_bgp_af_delete_redistribute(config_data): afi = config_data["address_family"]["afi"] + "-unicast" command = "protocols bgp {as_number} address-family ".format(**config_data) config_data = config_data["address_family"] command += afi + " redistribute {protocol}".format( **config_data["redistribute"] ) return command def _tmplt_bgp_af_neighbor_distribute_list(config_data): command = [] afi = config_data["neighbors"]["address_family"]["afi"] + "-unicast" cmd = "protocols bgp {as_number} neighbor ".format(**config_data) cmd += "{neighbor_address} address-family ".format( **config_data["neighbors"] ) config_data = config_data["neighbors"]["address_family"] for list_el in config_data["distribute_list"]: command.append( cmd + afi + " distribute-list " + list_el["action"] + " " + str(list_el["acl"]) ) return command def _tmplt_bgp_af_neighbor_route_map(config_data): command = [] afi = config_data["neighbors"]["address_family"]["afi"] + "-unicast" cmd = "protocols bgp {as_number} neighbor ".format(**config_data) cmd += "{neighbor_address} address-family ".format( **config_data["neighbors"] ) config_data = config_data["neighbors"]["address_family"] for list_el in config_data["route_map"]: command.append( cmd + afi + " route-map " + list_el["action"] + " " + str(list_el["route_map"]) ) return command def _tmplt_bgp_af_neighbor_prefix_list(config_data): command = [] afi = config_data["neighbors"]["address_family"]["afi"] + "-unicast" cmd = "protocols bgp {as_number} neighbor ".format(**config_data) cmd += "{neighbor_address} address-family ".format( **config_data["neighbors"] ) config_data = config_data["neighbors"]["address_family"] for list_el in config_data["prefix_list"]: command.append( cmd + afi + " prefix-list " + list_el["action"] + " " + str(list_el["prefix_list"]) ) return command def _tmplt_bgp_af_neighbor_filter_list(config_data): command = [] afi = config_data["neighbors"]["address_family"]["afi"] + "-unicast" cmd = "protocols bgp {as_number} neighbor ".format(**config_data) cmd += "{neighbor_address} address-family ".format( **config_data["neighbors"] ) config_data = config_data["neighbors"]["address_family"] for list_el in config_data["filter_list"]: command.append( cmd + afi + " filter-list " + list_el["action"] + " " + str(list_el["path_list"]) ) return command def _tmplt_bgp_af_neighbor_attribute(config_data): command = [] afi = config_data["neighbors"]["address_family"]["afi"] + "-unicast" cmd = "protocols bgp {as_number} neighbor ".format(**config_data) cmd += "{neighbor_address} address-family ".format( **config_data["neighbors"] ) config_data = config_data["neighbors"]["address_family"] for k in config_data["attribute_unchanged"].keys(): if config_data["attribute_unchanged"][k]: k = re.sub("_", "-", k) c = cmd + afi + " attribute-unchanged " + k command.append(c) return command def _tmplt_bgp_af_neighbor_delete(config_data): afi = config_data["neighbors"]["address_family"]["afi"] + "-unicast" command = "protocols bgp {as_number} ".format(**config_data) command += ( "neighbor {neighbor_address} address-family ".format( **config_data["neighbors"] ) + afi ) config_data = config_data["neighbors"]["address_family"] if config_data.get("allowas_in"): command += " allowas-in" elif config_data.get("as_override"): command += " as-override" elif config_data.get("attribute_unchanged"): command += " attribute-unchanged" elif config_data.get("capability"): command += " capability" elif config_data.get("default_originate"): command += " default-originate" elif config_data.get("maximum_prefix"): command += " maximum-prefix" elif config_data.get("nexthop_local"): command += " nexthop-local" elif config_data.get("nexthop_self"): command += " nexthop-self" elif config_data.get("peer_group"): command += " peer-group" elif config_data.get("remote_private_as"): command += " remote-private-as" elif config_data.get("route_reflector_client"): command += " route-reflector-client" elif config_data.get("route_server_client"): command += " route-server-client" elif config_data.get("soft_reconfiguration"): command += " soft-reconfiguration" elif config_data.get("unsuppress_map"): command += " unsuppress-map" elif config_data.get("weight"): command += " weight" elif config_data.get("filter_list"): command += " filter-list" elif config_data.get("prefix_list"): command += " prefix-list" elif config_data.get("distribute_list"): command += " distribute-list" elif config_data.get("route_map"): command += " route-map" return command def _tmplt_bgp_af_neighbor(config_data): afi = config_data["neighbors"]["address_family"]["afi"] + "-unicast" command = "protocols bgp {as_number} ".format(**config_data) command += ( "neighbor {neighbor_address} address-family ".format( **config_data["neighbors"] ) + afi ) config_data = config_data["neighbors"]["address_family"] if config_data.get("allowas_in"): command += " allowas-in number {allowas_in}".format(**config_data) elif config_data.get("as_override"): command += " as-override" elif config_data.get("capability"): command += " capability " if config_data["capability"].get("dynamic"): command += "dynamic" elif config_data["capability"].get("orf"): command += " prefix-list {orf}".format(**config_data["capability"]) elif config_data.get("default_originate"): command += " default-originate route-map {default_originate}".format( **config_data ) elif config_data.get("maximum_prefix"): command += " maximum-prefix {maximum_prefix}".format(**config_data) elif config_data.get("nexthop_local"): command += " nexthop-local" elif config_data.get("nexthop_self"): command += " nexthop-self" elif config_data.get("peer_group"): command += " peer-group {peer_group}".format(**config_data) elif config_data.get("remote_private_as"): command += " remote-private-as" elif config_data.get("route_reflector_client"): command += " route-reflector-client" elif config_data.get("route_server_client"): command += " route-server-client" elif config_data.get("soft_reconfiguration"): command += " soft-reconfiguration inbound" elif config_data.get("unsuppress_map"): command += " unsuppress-map {unsuppress_map}".format(**config_data) elif config_data.get("weight"): command += " weight {weight}".format(**config_data) return command class Bgp_address_familyTemplate(NetworkTemplate): def __init__(self, lines=None, module=None): prefix = {"set": "set", "remove": "delete"} super(Bgp_address_familyTemplate, self).__init__( lines=lines, tmplt=self, prefix=prefix, module=module ) # fmt: off PARSERS = [ { "name": "address_family", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+address-family \s+(?P\S+)-unicast *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} address-family {{ address_family.afi }}-unicast", "compval": "as_number", "result": { "as_number": "{{ as_num }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", } } } }, { "name": "aggregate_address", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+address-family \s+(?P\S+)-unicast \s+aggregate-address \s+(?P
\S+) \s*(?Pas-set)* \s*(?Psummary-only)* $""", re.VERBOSE, ), "setval": _tmplt_bgp_af_aggregate_address, "remval": "protocols bgp {{ as_number }} address-family {{ address_family.afi }}-unicast aggregate-address" + " {{ address_family.aggregate_address.prefix }}", "compval": "address_family.aggregate_address", "result": { "as_number": "{{ as_num }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "aggregate_address": [ { "prefix": "{{ address }}", "as_set": "{{ True if as_set is defined }}", "summary_only": "{{ True if summary_only is defined }}" } ] } } } }, { "name": "network.backdoor", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+address-family \s+(?P\S+)-unicast \s+network \s+(?P
\S+) \s+backdoor *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} address-family {{ address_family.afi }}-unicast network {{ address_family.networks.prefix }} backdoor", "remval": "protocols bgp {{ as_number }} address-family {{ address_family.afi }}-unicast network {{ address_family.networks.prefix }}", "compval": "address_family.networks.backdoor", "result": { "as_number": "{{ as_num }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "networks": [ { "prefix": "{{ address }}", "backdoor": "{{ True }}" } ] } } } }, { "name": "network.path_limit", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+address-family \s+(?P\S+)-unicast \s+network \s+(?P
\S+) \s+path-limit \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} address-family {{ address_family.afi }}-unicast network" + "{{ address_family.networks.prefix }} path-limit {{ address_family.networks.path_limit }}", "remval": "protocols bgp {{ as_number }} address-family {{ address_family.afi }}-unicast network {{ address_family.networks.address }}", "compval": "address_family.networks.path_limit", "result": { "as_number": "{{ as_num }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "networks": [ { "prefix": "{{ address }}", "path_limit": "{{ limit|int }}" } ] } } } }, { "name": "network.route_map", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+address-family \s+(?P\S+)-unicast \s+network \s+(?P
\S+) \s+route-map \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} address-family {{ address_family.afi }}-unicast network" + " {{ address_family.networks.prefix }} route-map {{ address_family.networks.route_map }}", "remval": "protocols bgp {{ as_number }} address-family {{ address_family.afi }}-unicast network {{ address_family.networks.prefix }}", "compval": "address_family.networks.route_map", "result": { "as_number": "{{ as_num }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "networks": [ { "prefix": "{{ address }}", "route_map": "{{ map }}" } ] } } } }, { "name": "redistribute.metric", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+address-family \s+(?P\S+)-unicast \s+redistribute \s+(?P\S+) \s+metric \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_redistribute_metric, "remval": _tmplt_bgp_af_delete_redistribute, "compval": "address_family.redistribute.metric", "result": { "as_number": "{{ as_num }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "redistribute": [ { "protocol": "{{ proto }}", "metric": "{{ val|int }}" } ] } } } }, { "name": "redistribute.route_map", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+address-family \s+(?P\S+)-unicast \s+redistribute \s+(?P\S+) \s+route-map \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_redistribute_route_map, "remval": _tmplt_bgp_af_delete_redistribute, "compval": "address_family.redistribute.route_map", "result": { "as_number": "{{ as_num }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "redistribute": [ { "protocol": "{{ proto }}", "route_map": "{{ map }}" } ] } } } }, { "name": "redistribute.table", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+address-family \s+(?P\S+)-unicast \s+redistribute \s+table \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_redistribute_table, "remval": _tmplt_bgp_af_delete_redistribute, "compval": "address_family.redistribute.table", "result": { "as_number": "{{ as_num }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "redistribute": [ { "table": "{{ tab }}" } ] } } } }, { "name": "neighbors", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbors.neighbor_address }} address-family", "compval": "neighbors", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", } } } }, { "name": "neighbors.address_family", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbors.neighbor_address }} address-family {{ neighbors.address_family.afi }}-unicast", "compval": "neighbors", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", } } } } } }, { "name": "neighbors.allowas_in", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+allowas-in \s+number \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.allowas_in", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "allowas_in": "{{ num }}" } } } } } }, { "name": "neighbors.as_override", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+as-override *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.as_override", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "as_override": "{{ True }}" } } } } } }, { "name": "neighbors.attribute_unchanged.as_path", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+attribute-unchanged \s+(?Pas-path) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor_attribute, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.attribute_unchanged.as_path", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "attribute_unchanged": { "as_path": "{{ True }}" } } } } } } }, { "name": "neighbors.attribute_unchanged.med", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+attribute-unchanged \s+(?Pmed) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor_attribute, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.attribute_unchanged.med", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "attribute_unchanged": { "med": "{{ True }}" } } } } } } }, { "name": "neighbors.attribute_unchanged.next_hop", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+attribute-unchanged \s+(?Pnext-hop) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor_attribute, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.attribute_unchanged.next_hop", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "attribute_unchanged": { "next_hop": "{{ True }}" } } } } } } }, { "name": "neighbors.capability_dynamic", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+capability \s+dynamic *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.capability.dynamic", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "capability": { "dynamic": "{{ true }}" } } } } } } }, { "name": "neighbors.capability_orf", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+capability \s+prefix-list \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.capability.orf", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "capability": { "orf": "{{ orf }}" } } } } } } }, { "name": "neighbors.default_originate", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+default-originate \s+route-map \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.default_originate", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "default_originate": "{{ map }}" } } } } } }, { "name": "neighbors.distribute_list", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+distribute-list \s+(?Pexport|import) \s+(?P\d+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor_distribute_list, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.distribute_list", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "distribute_list": [ { "action": "{{ action }}", "acl": "{{ list }}" } ] } } } } } }, { "name": "neighbors.prefix_list", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+prefix-list \s+(?Pexport|import) \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor_prefix_list, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.prefix_list", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "prefix_list": [ { "action": "{{ action }}", "prefix_list": "{{ list }}" } ] } } } } } }, { "name": "neighbors.filter_list", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+filter-list \s+(?Pexport|import) \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor_filter_list, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.filter_list", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "filter_list": [ { "action": "{{ action }}", "path_list": "{{ list }}" } ] } } } } } }, { "name": "neighbors.maximum_prefix", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+maximum-prefix \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.maximum_prefix", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "maximum_prefix": "{{ num }}" } } } } } }, { "name": "neighbors.nexthop_local", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+nexthop-local *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.nexthop_local", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "nexthop_local": "{{ True }}" } } } } } }, { "name": "neighbors.nexthop_self", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+nexthop-self *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.nexthop_self", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "nexthop_self": "{{ True }}" } } } } } }, { "name": "neighbors.peer_group", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+peer-group \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.peer_group", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "peer_group": "{{ name }}" } } } } } }, { "name": "neighbors.remove_private_as", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+remove-private-as *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.remove_private_as", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "remove_private_as": "{{ True }}" } } } } } }, { "name": "neighbors.route_map", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+route-map \s+(?Pexport|import) \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor_route_map, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.route_map", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "route_map": [ { "action": "{{ action }}", "route_map": "{{ map }}" } ] } } } } } }, { "name": "neighbors.route_reflector_client", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+route-reflector-client *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.route_reflector_client", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "route_reflector_client": "{{ True }}" } } } } } }, { "name": "neighbors.route_server_client", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+route-server-client *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.route_server_client", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "route_server_client": "{{ True }}" } } } } } }, { "name": "neighbors.soft_reconfiguration", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+soft-reconfiguration \s+inbound *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.soft_reconfiguration", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "soft_reconfiguration": "{{ True }}" } } } } } }, { "name": "neighbors.unsuppress_map", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+unsuppress-map \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.unsuppress_map", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "unsuppress_map": "{{ map }}" } } } } } }, { "name": "neighbors.weight", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+address-family \s+(?P\S+)-unicast \s+weight \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_af_neighbor, "remval": _tmplt_bgp_af_neighbor_delete, "compval": "neighbors.address_family.weight", "result": { "as_number": "{{ as_num }}", "neighbors": { "{{ address }}": { "neighbor_address": "{{ address }}", "address_family": { "{{ afi }}": { "afi": "{{ afi }}", "weight": "{{ num }}" } } } } } }, ] # fmt: on diff --git a/plugins/module_utils/network/vyos/rm_templates/bgp_global.py b/plugins/module_utils/network/vyos/rm_templates/bgp_global.py index cb9907b..0671ff7 100644 --- a/plugins/module_utils/network/vyos/rm_templates/bgp_global.py +++ b/plugins/module_utils/network/vyos/rm_templates/bgp_global.py @@ -1,2043 +1,2043 @@ # -*- 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.network_template import ( +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import ( NetworkTemplate, ) def _tmplt_bgp_params_confederation(config_data): command = [] for list_el in config_data["bgp_params"]["confederation"]: for k, v in iteritems(list_el): command.append( "protocols bgp {as_number} parameters confederation ".format( **config_data ) + k + " " + str(v) ) return command def _tmplt_bgp_maximum_paths(config_data): command = [] for list_el in config_data["maximum_paths"]: command.append( "protocols bgp {as_number} maximum-paths ".format(**config_data) + list_el["path"] + " " + str(list_el["count"]) ) return command def _tmplt_bgp_aggregate_address(config_data): command = "protocols bgp {as_number} aggregate-address".format( **config_data ) if config_data["aggregate_address"].get("as_set"): command += " {prefix} as-set".format( **config_data["aggregate_address"] ) if config_data["aggregate_address"].get("summary_only"): command += " {prefix} summary-only".format( **config_data["aggregate_address"] ) return command def _tmplt_delete_bgp_maximum_paths(config_data): command = "protocols bgp {as_number} maximum-paths".format(**config_data) return command def _tmplt_bgp_params_default(config_data): command = "protocols bgp {as_number} parameters default".format( **config_data ) if config_data["bgp_params"]["default"].get("no_ipv4_unicast"): command += " no-ipv4-unicast" if config_data["bgp_params"]["default"].get("local_pref"): command += " local-pref {local_pref}".format( **config_data["bgp_params"]["default"] ) return command def _tmplt_bgp_delete_redistribute(config_data): command = ( "protocols bgp {as_number} redistribute ".format(**config_data) + config_data["redistribute"]["protocol"] ) return command def _tmplt_bgp_neighbor_timers(config_data): command = [] for k, v in iteritems(config_data["neighbor"]["timers"]): command.append( "protocols bgp {as_number} neighbor ".format(**config_data) + config_data["neighbor"]["address"] + " timers " + k + " " + str(v) ) return command def _tmplt_bgp_timers(config_data): command = [] for k, v in iteritems(config_data["timers"]): command.append( "protocols bgp {as_number} ".format(**config_data) + "timers " + k + " " + str(v) ) return command def _tmplt_bgp_neighbor_attribute_unchanged_as_path(config_data): command = "protocols bgp {as_number} ".format( **config_data ) + "neighbor {address} attribute-unchanged as-path".format( **config_data["neighbor"] ) return command def _tmplt_bgp_neighbor_attribute_unchanged_med(config_data): command = "protocols bgp {as_number} ".format( **config_data ) + "neighbor {address} attribute-unchanged med".format( **config_data["neighbor"] ) return command def _tmplt_bgp_neighbor_attribute_unchanged_next_hop(config_data): command = "protocols bgp {as_number} ".format( **config_data ) + "neighbor {address} attribute-unchanged next-hop".format( **config_data["neighbor"] ) return command def _tmplt_bgp_neighbor_distribute_list(config_data): command = [] for list_el in config_data["neighbor"]["distribute_list"]: command.append( "protocols bgp {as_number} ".format(**config_data) + "neighbor {address} distribute-list ".format( **config_data["neighbor"] ) + list_el["action"] + " " + str(list_el["acl"]) ) return command def _tmplt_bgp_neighbor_route_map(config_data): command = [] for list_el in config_data["neighbor"]["route_map"]: command.append( "protocols bgp {as_number} ".format(**config_data) + "neighbor {address} route-map ".format(**config_data["neighbor"]) + list_el["action"] + " " + str(list_el["route_map"]) ) return command def _tmplt_bgp_neighbor_prefix_list(config_data): command = [] for list_el in config_data["neighbor"]["prefix_list"]: command.append( "protocols bgp {as_number} ".format(**config_data) + "neighbor {address} prefix-list ".format( **config_data["neighbor"] ) + list_el["action"] + " " + str(list_el["prefix_list"]) ) return command def _tmplt_bgp_neighbor_filter_list(config_data): command = [] for list_el in config_data["neighbor"]["filter_list"]: command.append( "protocols bgp {as_number} ".format(**config_data) + "neighbor {address} filter-list ".format( **config_data["neighbor"] ) + list_el["action"] + " " + str(list_el["path_list"]) ) return command def _tmplt_bgp_params_distance(config_data): command = ( "protocols bgp {as_number} parameters distance global ".format( **config_data ) + config_data["bgp_params"]["distance"]["type"] + " " + str(config_data["bgp_params"]["distance"]["value"]) ) return command class Bgp_globalTemplate(NetworkTemplate): def __init__(self, lines=None, module=None): prefix = {"set": "set", "remove": "delete"} super(Bgp_globalTemplate, self).__init__( lines=lines, tmplt=self, prefix=prefix, module=module ) # fmt: off PARSERS = [ { "name": "router", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }}", "compval": "as_number", "result": { "as_number": "{{ as_num }}", } }, { "name": "aggregate_address", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+aggregate-address \s+(?P
\S+) \s*(?Pas-set)* \s*(?Psummary-only)* $""", re.VERBOSE, ), "setval": _tmplt_bgp_aggregate_address, "remval": "protocols bgp {{ as_number }} aggregate-address {{ aggregate_address.prefix }}", "compval": "aggregate_address", "result": { "as_number": "{{ as_num }}", "aggregate_address": [ { "prefix": "{{ address }}", "as_set": "{{ True if as_set is defined }}", "summary_only": "{{ True if summary_only is defined }}" } ] } }, { "name": "maximum_paths", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+maximum-paths \s+(?Pebgp|ibgp) \s+(?P\d+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_maximum_paths, "remval": _tmplt_delete_bgp_maximum_paths, "compval": "maximum_paths", "result": { "as_number": "{{ as_num }}", "maximum_paths": [ { "path": "{{ path }}", "count": "{{ count }}", } ] } }, { "name": "neighbor.advertisement_interval", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+advertisement-interval \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} advertisement-interval {{ neighbor.advertisement_interval }}", "remval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} advertisement-interval", "compval": "neighbor.advertisement_interval", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "advertisement_interval": "{{ interval }}" } } } }, { "name": "neighbor.allowas_in", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+allowas-in \s+number \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} allowas-in number {{ neighbor.allowas_in }}", "compval": "neighbor.allowas_in", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "allowas_in": "{{ count }}" } } } }, { "name": "neighbor.as_override", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+as-override *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} as-override", "compval": "neighbor.as_override", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "as_override": "{{ True }}" } } } }, { "name": "neighbor.attribute_unchanged.as_path", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+attribute-unchanged \s+(?Pas-path) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_neighbor_attribute_unchanged_as_path, "compval": "neighbor.attribute_unchanged", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "attribute_unchanged": { "{{ 'as_path' }}": "{{ True }}" } } } } }, { "name": "neighbor.attribute_unchanged.med", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+attribute-unchanged \s+(?Pmed) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_neighbor_attribute_unchanged_med, "compval": "neighbor.attribute_unchanged", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "attribute_unchanged": { "{{ 'med' }}": "{{ True }}" } } } } }, { "name": "neighbor.attribute_unchanged.next_hop", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+attribute-unchanged \s+(?Pnext-hop) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_neighbor_attribute_unchanged_next_hop, "compval": "neighbor.attribute_unchanged", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "attribute_unchanged": { "{{ 'next_hop' }}": "{{ True }}" } } } } }, { "name": "neighbor.capability_dynamic", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+capability \s+(?Pdynamic) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} capability dynamic", "compval": "neighbor.capability.dynamic", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "capability": { "dynamic": "{{ True if dynamic is defined}}" } } } } }, { "name": "neighbor.capability_orf", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+capability \s+orf \s+prefix-list \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} capability orf prefix-list {{ neighbor.capability.orf }}", "compval": "neighbor.capability.orf", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "capability": { "orf": "{{ orf }}" } } } } }, { "name": "neighbor.default_originate", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+default-originate \s+route-map \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} default-originate route-map {{ neighbor.default_originate }}", "compval": "neighbor.advertisement_interval", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "default_originate": "{{ map }}" } } } }, { "name": "neighbor.description", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+description \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} description {{ neighbor.description }}", "compval": "neighbor.description", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "description": "{{ desc }}" } } } }, { "name": "neighbor.disable_capability_negotiation", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+disable-capability-negotiation *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} disable-capability-negotiation", "compval": "neighbor.disable_capability_negotiation", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "disable_capability_negotiation": "{{ True }}" } } } }, { "name": "neighbor.disable_connected_check", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+disable-connected-check *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} disable-connected-check", "compval": "neighbor.disable_connected_check", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "disable_connected_check": "{{ True }}" } } } }, { "name": "neighbor.disable_send_community", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+disable-send-community \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} disable-send-community {{ neighbor.disable_send_community }}", "compval": "neighbor.disable_send_community", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "disable_send_community": "{{ comm }}" } } } }, { "name": "neighbor.distribute_list", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+distribute-list \s+(?Pexport|import) \s+(?P\d+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_neighbor_distribute_list, "compval": "neighbor.distribute_list", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "distribute_list": [ { "action": "{{ action }}", "acl": "{{ list }}" } ] } } } }, { "name": "neighbor.ebgp_multihop", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+ebgp-multihop \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} ebgp-multihop {{ neighbor.ebgp_multihop }}", "compval": "neighbor.ebgp_multihop", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "ebgp_multihop": "{{ hop|int }}" } } } }, { "name": "neighbor.filter_list", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+filter-list \s+(?Pexport|import) \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_neighbor_filter_list, "compval": "neighbor.filter_list", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "filter_list": [ { "action": "{{ action }}", "path_list": "{{ list }}" } ] } } } }, { "name": "neighbor.local_as", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+local-as \s+(?P\S+) \s+no-prepend *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} local-as {{ neighbor.local_as }} no-prepend", "compval": "neighbor.local_as", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "local_as": "{{ as }}" } } } }, { "name": "neighbor.maximum_prefix", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+maximum-prefix \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} maximum-prefix {{ neighbor.maximum_prefix }}", "compval": "neighbor.maximum_prefix", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "maximum_prefix": "{{ num }}" } } } }, { "name": "neighbor.nexthop_self", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+nexthop-self *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} nexthop-self", "compval": "neighbor.nexthop_self", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "nexthop_self": "{{ True }}" } } } }, { "name": "neighbor.override_capability", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+override-capability *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} override-capability", "compval": "neighbor.override_capability", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "override_capability": "{{ True }}" } } } }, { "name": "neighbor.passive", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+passive *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} nexthop-self", "compval": "neighbor.passive", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "passive": "{{ True }}" } } } }, { "name": "neighbor.password", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+password \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} password {{ neighbor.address }}", "compval": "neighbor.password", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "password": "{{ pwd }}" } } } }, { "name": "neighbor.peer_group_name", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+peer-group \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} peer-group {{ neighbor.peer_group_name }}", "compval": "neighbor.peer_group_name", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "peer_group_name": "{{ name }}" } } } }, { "name": "neighbor.port", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+port \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} port {{ neighbor.port }}", "compval": "neighbor.port", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "port": "{{ num|int }}" } } } }, { "name": "neighbor.prefix_list", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+prefix-list \s+(?Pexport|import) \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_neighbor_prefix_list, "compval": "neighbor.prefix_list", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "prefix_list": [ { "action": "{{ action }}", "prefix_list": "{{ list }}" } ] } } } }, { "name": "neighbor.remote_as", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+remote-as \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} remote-as {{ neighbor.remote_as }}", "compval": "neighbor.remote_as", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "remote_as": "{{ num|int }}" } } } }, { "name": "neighbor.remove_private_as", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+remote-private-as *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} remote-private-as", "compval": "neighbor.remove_private_as", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "remove_private_as": "{{ True }}" } } } }, { "name": "neighbor.route_map", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+route-map \s+(?Pexport|import) \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_neighbor_route_map, "compval": "neighbor.route_map", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "route_map": [ { "action": "{{ action }}", "route_map": "{{ map }}" } ] } } } }, { "name": "neighbor.route_reflector_client", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+route-reflector-client *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} router-reflector-client", "compval": "neighbor.route_reflector_client", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "route_reflector_client": "{{ True }}" } } } }, { "name": "neighbor.route_server_client", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+route-server-client *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} route-server-client", "compval": "neighbor.route_server_client", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "route_server_client": "{{ True }}" } } } }, { "name": "neighbor.shutdown", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+shutdown *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} shutdown", "compval": "neighbor.shutdown", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "shutdown": "{{ True }}" } } } }, { "name": "neighbor.soft_reconfiguration", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+soft-reconfiguration \s+inbound *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} soft-reconfiguration", "compval": "neighbor.soft_reconfiguration", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "soft_reconfiguration": "{{ True }}" } } } }, { "name": "neighbor.strict_capability_match", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+strict-capability-match *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} strict-capability-match", "compval": "neighbor.strict_capability_match", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "strict_capability_match": "{{ True }}" } } } }, { "name": "neighbor.unsuppress_map", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+unsuppress-map \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} unsuppress-map {{ neighbor.unsuppress_map }}", "compval": "neighbor.unsuppress_map", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "unsuppress_map": "{{ map }}" } } } }, { "name": "neighbor.update_source", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+update-source \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} update-source {{ neighbor.update_source }}", "compval": "neighbor.update_source", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "update_source": "{{ src }}" } } } }, { "name": "neighbor.weight", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+weight \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} weight {{ neighbor.weight }}", "compval": "neighbor.weight", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "weight": "{{ num }}" } } } }, { "name": "neighbor.ttl_security", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+ttl-security \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} ttl-security {{ neighbor.ttl_security }}", "compval": "neighbor.ttl_security", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "ttl_security": "{{ ttl|int }}" } } } }, { "name": "neighbor.timers", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+neighbor \s+(?P
\S+) \s+timers \s+(?Pconnect|holdtime|keepalive) \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_neighbor_timers, "remval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} timers", "compval": "neighbor.timers", "result": { "as_number": "{{ as_num }}", "neighbor": { "{{ address }}": { "address": "{{ address }}", "timers": { "{{ type }}": "{{ sec }}" } } } } }, { "name": "network.backdoor", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+network \s+(?P
\S+) \s+backdoor *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} network {{ network.address }} backdoor", "remval": "protocols bgp {{ as_number }} network {{ network.address }}", "compval": "network.backdoor", "result": { "as_number": "{{ as_num }}", "network": [ { "address": "{{ address }}", "backdoor": "{{ True }}" } ] } }, { "name": "network.route_map", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+network \s+(?P
\S+) \s+route-map \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} network {{ network.address }} route-map {{ network.route_map }}", "remval": "protocols bgp {{ as_number }} network {{ network.address }}", "compval": "network.route_map", "result": { "as_number": "{{ as_num }}", "network": [ { "address": "{{ address }}", "route_map": "{{ map }}" } ] } }, { "name": "redistribute.metric", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+redistribute \s+(?P\S+) \s+metric \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} redistribute {{ redistribute.protocol }} metric {{ redistribute.metric }}", "remval": _tmplt_bgp_delete_redistribute, "compval": "redistribute", "result": { "as_number": "{{ as_num }}", "redistribute": [ { "protocol": "{{ proto }}", "metric": "{{ val|int }}" } ] } }, { "name": "redistribute.route_map", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+redistribute \s+(?P\S+) \s+route-map \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} redistribute {{ redistribute.protocol }} route-map {{ redistribute.route_map }}", "remval": _tmplt_bgp_delete_redistribute, "compval": "redistribute", "result": { "as_number": "{{ as_num }}", "redistribute": [ { "protocol": "{{ proto }}", "route_map": "{{ val }}" } ] } }, { "name": "timers", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+timers \s+(?P\S+) \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_timers, "remval": "protocols bgp {{ as_number }} timers", "compval": "timers", "result": { "as_number": "{{ as_num }}", "timers": { "{{ type }}": "{{ val }}", } } }, { "name": "bgp_params.always_compare_med", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+always-compare-med *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters always-compare-med", "compval": "bgp_params.always_compare_med", "result": { "as_number": "{{ as_num }}", "bgp_params": { "always_compare_med": "{{ True }}", } } }, { "name": "bgp_params.bestpath.as_path", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+bestpath \s+as-path \s+(?Pconfed|ignore) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters bestpath as-path {{ bgp_params.bestpath.as_path }}", "compval": "bgp_params.bestpath.as_path", "result": { "as_number": "{{ as_num }}", "bgp_params": { "bestpath": { "as_path": "{{ path }}", } } } }, { "name": "bgp_params.bestpath.compare_routerid", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+bestpath \s+compare-routerid *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters bestpath compare-routerid", "compval": "bgp_params.bestpath.compare_routerid", "result": { "as_number": "{{ as_num }}", "bgp_params": { "bestpath": { "compare_routerid": "{{ True }}", } } } }, { "name": "bgp_params.bestpath.med", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+bestpath \s+med \s+(?Pconfed|missing-as-worst) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters bestpath med {{ bestpath.med }}", "compval": "bgp_params.bestpath.med", "result": { "as_number": "{{ as_num }}", "bgp_params": { "bestpath": { "med": "{{ path }}", } } } }, { "name": "bgp_params.cluster_id", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+cluster-id \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters cluster-id {{ bgp_params.cluster_id }}", "compval": "bgp_params.cluster_id", "result": { "as_number": "{{ as_num }}", "bgp_params": { "cluster_id": "{{ id }}", } } }, { "name": "bgp_params.confederation", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+confederation \s+(?Pidentifier|peers) \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_params_confederation, "compval": "bgp_params.always_compare_med", "result": { "as_number": "{{ as_num }}", "bgp_params": { "confederation": [ { "peers": "{{ val if type == 'peers' }}", "identifier": "{{ val if type == 'identifier' }}" } ] } } }, { "name": "bgp_params.dampening_half_life", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+dampening \s+half-life \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters dampening half-life {{ bgp_params.dampening.half_life}}", "compval": "bgp_params.dampening.half_life", "result": { "as_number": "{{ as_num }}", "bgp_params": { "dampening": { "half_life": "{{ val }}" } } } }, { "name": "bgp_params.dampening_max_suppress_time", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+dampening \s+max-suppress-time \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters dampening max-suppress-time {{ bgp_params.dampening.max_suppress_time}}", "compval": "bgp_params.dampening.max_suppress_time", "result": { "as_number": "{{ as_num }}", "bgp_params": { "dampening": { "max_suppress_time": "{{ val }}" } } } }, { "name": "bgp_params.dampening_re_use", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+dampening \s+re-use \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters dampening re-use {{ bgp_params.dampening.re_use}}", "compval": "bgp_params.dampening.re_use", "result": { "as_number": "{{ as_num }}", "bgp_params": { "dampening": { "re_use": "{{ val }}" } } } }, { "name": "bgp_params.dampening_start_suppress_time", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+dampening \s+start-suppress-time \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters dampening start-suppress-time {{ bgp_params.dampening.start_suppress_time}}", "compval": "bgp_params.dampening.start_suppress_time", "result": { "as_number": "{{ as_num }}", "bgp_params": { "dampening": { "start_suppress_time": "{{ val }}" } } } }, { "name": "bgp_params.default", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+default \s*(?Pno-ipv4-unicast)* \s*(?Plocal-pref\s\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_params_default, "remval": "protocols bgp {{ as_number }} parameters default", "compval": "bgp_params.default", "result": { "as_number": "{{ as_num }}", "bgp_params": { "default": { "no_ipv4_unicast": "{{ True if no_ipv4_unicast is defined }}", "local_pref": "{{ local_pref.split(" " )[1] if local_pref is defined }}" } } } }, { "name": "bgp_params.deterministic_med", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+deterministic-med *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters deterministic-med", "compval": "bgp_params.deterministic_med", "result": { "as_number": "{{ as_num }}", "bgp_params": { "deterministic_med": "{{ True }}", } } }, { "name": "bgp_params.disbale_network_import_check", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+disable-network-import-check *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters disable-network-import-check", "compval": "bgp_params.disable_network_import_check", "result": { "as_number": "{{ as_num }}", "bgp_params": { "disable_network_import_check": "{{ True }}", } } }, { "name": "bgp_params.distance.prefix", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+distance\sprefix \s+(?P\S+) \s+distance \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters distance prefix {{ bgp_params.distance.prefix }} distance {{ bgp_params.distance.value }}", "compval": "bgp_params.distance.prefix", "remval": "protocols bgp {{ as_number }} parameters distance prefix", "result": { "as_number": "{{ as_num }}", "bgp_params": { "distance": [ { "prefix": "{{ prefix }}", "value": "{{ val }}" } ] } } }, { "name": "bgp_params.distance.global", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+distance\sglobal \s+(?P\S+) \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_bgp_params_distance, "remval": "protocols bgp {{ as_number }} parameters distance global", "compval": "bgp_params.distance", "result": { "as_number": "{{ as_num }}", "bgp_params": { "distance": [ { "type": "{{ type }}", "value": "{{ val }}" } ] } } }, { "name": "bgp_params.enforce_first_as", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+enforce-first-as *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters enforce-first-as", "compval": "bgp_params.enforce_first_as", "result": { "as_number": "{{ as_num }}", "bgp_params": { "enforce_first_as": "{{ True }}", } } }, { "name": "bgp_params.graceful_restart", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+graceful-restart\s+stalepath-time \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters graceful-restart stalepath-time {{ bgp_params.graceful_restart }}", "compval": "bgp_params.graceful_restart", "result": { "as_number": "{{ as_num }}", "bgp_params": { "graceful_restart": "{{ val }}", } } }, { "name": "bgp_params.log_neighbor_changes", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+log-neighbor-changes *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters log-neighbor-changes", "compval": "bgp_params.log_neighbor_changes", "result": { "as_number": "{{ as_num }}", "bgp_params": { "log_neighbor_changes": "{{ True }}", } } }, { "name": "bgp_params.no_client_to_client_reflection", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+no-client-to-client-reflection *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters no-client-to-client-reflection", "compval": "bgp_params.log_neighbor_changes", "result": { "as_number": "{{ as_num }}", "bgp_params": { "no_client_to_client_reflection": "{{ True }}", } } }, { "name": "bgp_params.no_fast_external_failover", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+no-fast-external-failover *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters no-fast-external-failover", "compval": "bgp_params.no_fast_external_failover", "result": { "as_number": "{{ as_num }}", "bgp_params": { "no_fast_external_failover": "{{ True }}", } } }, { "name": "bgp_params.routerid", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+router-id \s+(?P\S+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters router-id {{ bgp_params.router_id }}", "compval": "bgp_params.router_id", "result": { "as_number": "{{ as_num }}", "bgp_params": { "router_id": "{{ id }}", } } }, { "name": "bgp_params.scan_time", "getval": re.compile( r""" ^set \s+protocols \s+bgp \s+(?P\d+) \s+parameters \s+scan-time \s+(?P\d+) *$""", re.VERBOSE, ), "setval": "protocols bgp {{ as_number }} parameters scan-time {{ bgp_params.scan_time }}", "compval": "bgp_params.scan_time", "result": { "as_number": "{{ as_num }}", "bgp_params": { "scan_time": "{{ val }}", } } }, ] # fmt: on diff --git a/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py b/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py index 1e3afbe..bda17df 100644 --- a/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py +++ b/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py @@ -1,743 +1,743 @@ # -*- coding: utf-8 -*- # Copyright 2020 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 Ospf_interfaces 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.network_template import ( +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import ( NetworkTemplate, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( get_interface_type, ) def _get_parameters(data): if data["afi"] == "ipv6": val = ["ospfv3", "ipv6"] else: val = ["ospf", "ip"] return val def _tmplt_ospf_int_delete(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] ) return command def _tmplt_ospf_int_cost(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " cost {cost}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_auth_password(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " authentication plaintext-password {plaintext_password}".format( **config_data["address_family"]["authentication"] ) ) return command def _tmplt_ospf_int_auth_md5(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " authentication md5 key-id {key_id} ".format( **config_data["address_family"]["authentication"]["md5_key"] ) + "md5-key {key}".format( **config_data["address_family"]["authentication"]["md5_key"] ) ) return command def _tmplt_ospf_int_auth_md5_delete(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " authentication" ) return command def _tmplt_ospf_int_bw(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " bandwidth {bandwidth}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_hello_interval(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " hello-interval {hello_interval}".format( **config_data["address_family"] ) ) return command def _tmplt_ospf_int_dead_interval(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " dead-interval {dead_interval}".format( **config_data["address_family"] ) ) return command def _tmplt_ospf_int_mtu_ignore(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " mtu-ignore" ) return command def _tmplt_ospf_int_network(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " network {network}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_priority(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " priority {priority}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_retransmit_interval(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " retransmit-interval {retransmit_interval}".format( **config_data["address_family"] ) ) return command def _tmplt_ospf_int_transmit_delay(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " transmit-delay {transmit_delay}".format( **config_data["address_family"] ) ) return command def _tmplt_ospf_int_ifmtu(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " ifmtu {ifmtu}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_instance(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " instance-id {instance}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_passive(config_data): int_type = get_interface_type(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] + " passive" ) return command class Ospf_interfacesTemplate(NetworkTemplate): def __init__(self, lines=None, module=None): prefix = {"set": "set", "remove": "delete"} super(Ospf_interfacesTemplate, self).__init__( lines=lines, tmplt=self, prefix=prefix, module=module ) # fmt: off PARSERS = [ { "name": "ip_ospf", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) *$""", re.VERBOSE, ), "remval": _tmplt_ospf_int_delete, "compval": "address_family", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', } } } }, { "name": "authentication_password", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+authentication \s+plaintext-password \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_auth_password, "compval": "address_family.authentication", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "authentication": { "plaintext_password": "{{ text }}" } } } } }, { "name": "authentication_md5", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+authentication \s+md5 \s+key-id \s+(?P\d+) \s+md5-key \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_auth_md5, "remval": _tmplt_ospf_int_auth_md5_delete, "compval": "address_family.authentication", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "authentication": { "md5_key": { "key_id": "{{ id }}", "key": "{{ text }}" } } } } } }, { "name": "bandwidth", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+bandwidth \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_bw, "compval": "address_family.bandwidth", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "bandwidth": "{{ bw }}" } } } }, { "name": "cost", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+cost \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_cost, "compval": "address_family.cost", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "cost": "{{ val }}" } } } }, { "name": "hello_interval", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+hello-interval \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_hello_interval, "compval": "address_family.hello_interval", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "hello_interval": "{{ val }}" } } } }, { "name": "dead_interval", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+dead-interval \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_dead_interval, "compval": "address_family.dead_interval", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "dead_interval": "{{ val }}" } } } }, { "name": "mtu_ignore", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+(?P\'mtu-ignore\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_mtu_ignore, "compval": "address_family.mtu_ignore", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "mtu_ignore": "{{ True if mtu is defined }}" } } } }, { "name": "network", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+network \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_network, "compval": "address_family.network", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "network": "{{ val }}" } } } }, { "name": "priority", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+priority \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_priority, "compval": "address_family.priority", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "priority": "{{ val }}" } } } }, { "name": "retransmit_interval", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+retransmit-interval \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_retransmit_interval, "compval": "address_family.retransmit_interval", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "retransmit_interval": "{{ val }}" } } } }, { "name": "transmit_delay", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+transmit-delay \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_transmit_delay, "compval": "address_family.transmit_delay", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "transmit_delay": "{{ val }}" } } } }, { "name": "ifmtu", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+ifmtu \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_ifmtu, "compval": "address_family.ifmtu", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "ifmtu": "{{ val }}" } } } }, { "name": "instance", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+instance-id \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_instance, "compval": "address_family.instance", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "instance": "{{ val }}" } } } }, { "name": "passive", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+(?P\'passive\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_passive, "compval": "address_family.passive", "result": { "name": "{{ name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', "passive": "{{ True if pass is defined }}" } } } }, { "name": "interface_name", "getval": re.compile( r""" ^set \s+interfaces \s+(?P\S+) \s+(?P\S+) .*$""", re.VERBOSE, ), "setval": "set interface {{ type }} {{ name }}", "result": { "name": "{{ name }}", } }, ] # fmt: on diff --git a/plugins/module_utils/network/vyos/rm_templates/route_maps.py b/plugins/module_utils/network/vyos/rm_templates/route_maps.py index 3ab18b4..262721e 100644 --- a/plugins/module_utils/network/vyos/rm_templates/route_maps.py +++ b/plugins/module_utils/network/vyos/rm_templates/route_maps.py @@ -1,1293 +1,1293 @@ # -*- 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 Route_maps 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.network_template import ( +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import ( NetworkTemplate, ) class Route_mapsTemplate(NetworkTemplate): def __init__(self, lines=None): prefix = {"set": "set", "remove": "delete"} super(Route_mapsTemplate, self).__init__( lines=lines, tmplt=self, prefix=prefix ) # fmt: off PARSERS = [ { "name": "route_map", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+) *$""", re.VERBOSE, ), "compval": "route_map", "setval": "policy route-map {{route_map}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', } } }, }, { "name": "sequence", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+) *$""", re.VERBOSE, ), "compval": "sequence", "setval": "policy route-map {{route_map}} rule {{sequence}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}" } } } } } }, { "name": "call", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\scall\s(?P\S+) *$""", re.VERBOSE, ), "setval": "policy route-map {{route_map}} rule {{sequence}} call {{call}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "call": "{{call}}" } } } } } }, { "name": "description", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sdescription\s(?P\S+) *$""", re.VERBOSE, ), "setval": "policy route-map {{route_map}} rule {{sequence}} description {{description}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "description": "{{description}}" } } } } } }, { "name": "action", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\saction\s(?P\S+) *$""", re.VERBOSE, ), "setval": "policy route-map {{route_map}} rule {{sequence}} action {{action}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "action": "{{action}}" } } } } } }, { "name": "continue_sequence", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\scontinue\s(?P\S+) *$""", re.VERBOSE, ), "setval": "policy route-map {{route_map}} rule {{sequence}} continue {{continue_sequence}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "continue_sequence": "{{continue}}" } } } } } }, { "name": "on_match_next", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\son-match\s(?Pnext) *$""", re.VERBOSE, ), "compval": "on_match.next", "setval": "policy route-map {{route_map}} rule {{sequence}} on-match next", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "on_match": { "next": "{{True if next is defined}}" } } } } } } }, { "name": "on_match_goto", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\son-match\sgoto\s(?P\S+) *$""", re.VERBOSE, ), "compval": "on_match.goto", "setval": "policy route-map {{route_map}} rule {{sequence}} on-match goto {{on_match.goto}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "on_match": { "goto": "{{goto}}" } } } } } } }, { "name": "set_aggregator_ip", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\saggregator\sip\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.aggregator.ip", "setval": "policy route-map {{route_map}} rule {{sequence}} set aggregator ip {{set.aggregator.ip}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "aggregator": { "ip": "{{ip}}" } } } } } } } }, { "name": "set_aggregator_as", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\saggregator\sas\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.aggregator.as", "setval": "policy route-map {{route_map}} rule {{sequence}} set aggregator as {{set.aggregator.as}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "aggregator": { "as": "{{as}}" } } } } } } } }, { "name": "set_as_path_exclude", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\sas-path-exclude\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.as_path_exclude", "setval": "policy route-map {{route_map}} rule {{sequence}} set as-path-exclude {{set.as_path_exclude}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "as_path_exclude": "{{as}}" } } } } } } }, { "name": "set_as_path_prepend", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\sas-path-prepend\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.as_path_prepend", "setval": "policy route-map {{route_map}} rule {{sequence}} set as-path-prepend {{set.as_path_prepend}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "as_path_prepend": "{{as}}" } } } } } } }, { "name": "set_atomic_aggregate", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\satomic-aggregate(?P) *$""", re.VERBOSE, ), "setval": "policy route-map {{route_map}} rule {{sequence}} set atomic-aggregate", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "atomic_aggregate": "{{True if as is defined}}" } } } } } } }, { "name": "set_bgp_extcommunity_rt", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\sbgp-extcommunity-rt\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.bgp_extcommunity_rt", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set bgp-extcommunity-rt {{set.bgp_extcommunity_rt}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "bgp_extcommunity_rt": "{{bgp}}" } } } } } } }, { "name": "set_comm_list", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\scomm-list\scomm-list\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.comm_list.comm_list", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set comm-list comm-list {{set.comm_list.comm_list}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "comm_list": {"comm_list": "{{comm_list}}"} } } } } } } }, { "name": "set_comm_list_delete", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\scomm-list\sdelete(?P\S+) *$""", re.VERBOSE, ), "compval": "set.comm_list.comm_list", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set comm-list delete", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "comm_list": {"delete": "{{True if delete is defined}}"} } } } } } } }, { "name": "set_extcommunity_rt", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\sextcommunity-rt\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.extcommunity_rt", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set extcommunity-rt {{set.extcommunity_rt}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "extcommunity_rt": "{{extcommunity_rt}}" } } } } } } }, { "name": "set_extcommunity_soo", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\sextcommunity-soo\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.extcommunity_soo", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set extcommunity-soo {{set.extcommunity_soo}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "extcommunity_soo": "{{set.extcommunity_soo}}" } } } } } } }, { "name": "set_ip_next_hop", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\sip-next-hop\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.ip_next_hop", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set ip-next-hop {{set.ip_next_hop}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "ip_next_hop": "{{ip_next_hop}}" } } } } } } }, { "name": "set_ipv6_next_hop", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\sipv6-next-hop \s(?Pglobal|local) \s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.ipv6_next_hop", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set ipv6-next-hop {{set.ipv6_next_hop.ip_type}} {{set.ipv6_next_hop.value}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "ipv6_next_hop": { "ip_type": "{{type}}", "value": "{{value}}" } } } } } } } }, { "name": "set_large_community", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\slarge-community\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.large_community", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set large-community {{set.large_community}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "large_community": "{{large_community}}" } } } } } } }, { "name": "set_local_preference", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\slocal-preference\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.local_preference", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set local-preference {{set.local_preference}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "local_preference": "{{local_preference}}" } } } } } } }, { "name": "set_metric", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\smetric\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.metric", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set metric {{set.metric}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "metric": "{{metric}}" } } } } } } }, { "name": "set_metric_type", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\smetric-type\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.metric_type", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set metric-type {{set.metric_type}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "metric_type": "{{metric_type}}" } } } } } } }, { "name": "set_origin", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\sorigin\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.origin", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set origin {{set.origin}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "origin": "{{origin}}" } } } } } } }, { "name": "set_originator_id", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\soriginator-id\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.originator_id", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set originator-id {{set.originator_id}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "originator_id": "{{originator_id}}" } } } } } } }, { "name": "set_src", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\ssrc\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.src", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set src {{set.src}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "src": "{{src}}" } } } } } } }, { "name": "set_tag", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\stag\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.tag", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set tag {{set.tag}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "tag": "{{tag}}" } } } } } } }, { "name": "set_weight", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\sweight\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.weight", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set weight {{set.weight}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "weight": "{{weight}}" } } } } } } }, { "name": "set_community", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\sset\scommunity\s(?P\S+) *$""", re.VERBOSE, ), "compval": "set.community.value", "setval": "policy route-map {{route_map}} rule {{sequence}} " "set community {{set.community.value}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "set": { "community": { "value": "{{value}}", } } } } } } } }, { "name": "match_as_path", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\sas-path\s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.as_path", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match as-path {{match.as_path}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "as_path": "{{as_path}}" } } } } } } }, { "name": "match_community_community_list", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\scommunity\scommunity-list\s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.community.community_list", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match community community-list {{match.community.community_list}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "community": {"community_list": "{{community_list}}"} } } } } } } }, { "name": "match_community_exact_match", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\scommunity\sexact-match(?P) *$""", re.VERBOSE, ), "compval": "match.community.exact_match", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match community exact-match", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "community": {"exact_match": "{{True if exact_match is defined}}"} } } } } } } }, { "name": "match_extcommunity", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\sextcommunity\s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.extcommunity", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match extcommunity {{match.extcommunity}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "extcommunity": "{{extcommunity}}" } } } } } } }, { "name": "match_interface", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\sinterface\s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.interface", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match interface {{match.interface}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "interface": "{{interface}}" } } } } } } }, { "name": "match_large_community_large_community_list", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\slarge-community\slarge-community-list\s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.large_community_large_community_list", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match large-community large-community-list {{match.large_community_large_community_list}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "large_community_large_community_list": "{{lc}}" } } } } } } }, { "name": "match_metric", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\smetric\s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.metric", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match metric {{match.metric}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "metric": "{{metric}}" } } } } } } }, { "name": "match_origin", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\sorigin\s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.origin", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match origin {{match.origin}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "origin": "{{origin}}" } } } } } } }, { "name": "match_peer", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\speer\s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.peer", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match peer {{match.peer}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "peer": "{{peer}}" } } } } } } }, { "name": "match_ip_address", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\sip\saddress \s(?Paccess-list|prefix-list) \s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.ip.address", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match ip address {{match.ip.address.list_type}} {{match.ip.address.value}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "ip": { "address": { "list_type": "{{list_type}}", "value": "{{value}}" } } } } } } } } }, { "name": "match_ip_next_hop", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\sip\snexthop \s(?Paccess-list|prefix-list) \s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.ip.next_hop", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match ip nexthop {{match.ip.next_hop.list_type}} {{match.ip.next_hop.value}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "ip": { "next_hop": { "list_type": "{{list_type}}", "value": "{{value}}" } } } } } } } } }, { "name": "match_ip_route_source", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\sip\sroute-source \s(?Paccess-list|prefix-list) \s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.ip.route_source", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match ip route-source {{match.ip.route_source.list_type}} {{match.ip.route_source.value}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "ip": { "route_source": { "list_type": "{{list_type}}", "value": "{{value}}" } } } } } } } } }, { "name": "match_ipv6_address", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\sipv6\saddress \s(?Paccess-list|prefix-list) \s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.ipv6.address", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match ipv6 address {{match.ipv6.address.list_type}} {{match.ipv6.address.value}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "ipv6": { "address": { "list_type": "{{list_type}}", "value": "{{value}}" } } } } } } } } }, { "name": "match_ipv6_nexthop", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\sipv6\snexthop \s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.ipv6.next_hop", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match ipv6 nexthop {{match.ipv6.next_hop}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "ipv6": { "next_hop": "{{value}}" } } } } } } } }, { "name": "match_rpki", "getval": re.compile( r""" ^set\spolicy\sroute-map\s(?P\S+)\srule\s(?P\d+)\smatch\srpki \s(?P\S+) *$""", re.VERBOSE, ), "compval": "match.rpki", "setval": "policy route-map {{route_map}} rule {{sequence}} " "match rpki {{match.rpki}}", "result": { "route_maps": { "{{ route_map }}": { "route_map": '{{ route_map }}', "entries": { "{{sequence}}": { "sequence": "{{sequence}}", "match": { "rpki": "{{value}}" } } } } } } }, ] # fmt: on