diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-05 16:18:37 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-05 16:18:37 +0000 |
commit | 5d7eda1e172f8e396536a8fbd6f85b4b991290e8 (patch) | |
tree | b18be36b43a1abdab0d40ecc8e4c8de2dbcd65c0 /ansible_collections/arista/eos/plugins | |
parent | Adding debian version 9.5.1+dfsg-1. (diff) | |
download | ansible-5d7eda1e172f8e396536a8fbd6f85b4b991290e8.tar.xz ansible-5d7eda1e172f8e396536a8fbd6f85b4b991290e8.zip |
Merging upstream version 10.0.0+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/arista/eos/plugins')
12 files changed, 40 insertions, 1124 deletions
diff --git a/ansible_collections/arista/eos/plugins/cliconf/eos.py b/ansible_collections/arista/eos/plugins/cliconf/eos.py index 9c6fb753c..847ca8e0c 100644 --- a/ansible_collections/arista/eos/plugins/cliconf/eos.py +++ b/ansible_collections/arista/eos/plugins/cliconf/eos.py @@ -328,6 +328,12 @@ class Cliconf(CliconfBase): responses.append(out) return responses + def restore(self, filename=None, path=""): + if not filename: + raise ValueError("'file_name' value is required for restore") + cmd = f"configure replace {path}{filename} best-effort" + return self.send_command(cmd) + def get_diff( self, candidate=None, diff --git a/ansible_collections/arista/eos/plugins/module_utils/network/eos/argspec/ospfv3/ospfv3.py b/ansible_collections/arista/eos/plugins/module_utils/network/eos/argspec/ospfv3/ospfv3.py index ece4db0cd..7964b4f4f 100644 --- a/ansible_collections/arista/eos/plugins/module_utils/network/eos/argspec/ospfv3/ospfv3.py +++ b/ansible_collections/arista/eos/plugins/module_utils/network/eos/argspec/ospfv3/ospfv3.py @@ -128,16 +128,6 @@ class Ospfv3Args(object): # pylint: disable=R0903 "timers": { "type": "dict", "options": { - "throttle": { - "type": "dict", - "options": { - "max": {"type": "int"}, - "initial": {"type": "int"}, - "min": {"type": "int"}, - "spf": {"type": "bool"}, - "lsa": {"type": "bool"}, - }, - }, "spf": { "type": "dict", "options": { @@ -357,16 +347,6 @@ class Ospfv3Args(object): # pylint: disable=R0903 "timers": { "type": "dict", "options": { - "throttle": { - "type": "dict", - "options": { - "max": {"type": "int"}, - "initial": {"type": "int"}, - "min": {"type": "int"}, - "spf": {"type": "bool"}, - "lsa": {"type": "bool"}, - }, - }, "spf": { "type": "dict", "options": { diff --git a/ansible_collections/arista/eos/plugins/module_utils/network/eos/config/ospfv3/ospfv3.py b/ansible_collections/arista/eos/plugins/module_utils/network/eos/config/ospfv3/ospfv3.py index ed01f1c5e..b567de6f8 100644 --- a/ansible_collections/arista/eos/plugins/module_utils/network/eos/config/ospfv3/ospfv3.py +++ b/ansible_collections/arista/eos/plugins/module_utils/network/eos/config/ospfv3/ospfv3.py @@ -147,30 +147,6 @@ class Ospfv3(ResourceModule): def _global_compare(self, want, have): for name, entry in iteritems(want): if name == "timers": - if entry.get("throttle"): - throttle = entry.pop("throttle") - modified = {} - if throttle.get("lsa"): - modified["lsa"] = { - "max": throttle["max"], - "min": throttle["min"], - "initial": throttle["initial"], - "direction": "tx", - } - if throttle.get("spf"): - modified["spf"] = { - "max": throttle["max"], - "min": throttle["min"], - "initial": throttle["initial"], - } - entry.update(modified) - self._module.warn( - " ** The 'timers' argument has been changed to have separate 'lsa' and 'spf' keys and 'throttle' has been deprecated. ** " - " \n** Your task has been modified to use {0}. ** " - " \n** timers.throttle will be removed after '2024-01-01' ** ".format( - entry, - ), - ) if entry.get("lsa") and not isinstance(entry["lsa"], dict): modified = {} if not isinstance(entry["lsa"], int): @@ -183,13 +159,6 @@ class Ospfv3(ResourceModule): "lsa": {"direction": "rx", "min": entry["lsa"]}, }, } - self._module.warn( - " ** 'timers lsa arrival' has changed to 'timers lsa rx min interval' from eos 4.23 onwards. ** " - " \n** Your task has been modified to use {0}. ** " - " \n** timers.lsa of type int will be removed after '2024-01-01' ** ".format( - modified, - ), - ) entry["lsa"] = modified["timers"]["lsa"] if name in ["vrf", "address_family"]: continue @@ -240,30 +209,6 @@ class Ospfv3(ResourceModule): for name, entry in iteritems(wafs): begin = len(self.commands) if "timers" in entry: - if entry["timers"].get("throttle"): - throttle = entry["timers"].pop("throttle") - modified = {} - if throttle.get("lsa"): - modified["lsa"] = { - "max": throttle["max"], - "min": throttle["min"], - "initial": throttle["initial"], - "direction": "tx", - } - if throttle.get("spf"): - modified["spf"] = { - "max": throttle["max"], - "min": throttle["min"], - "initial": throttle["initial"], - } - entry["timers"].update(modified) - self._module.warn( - " ** The 'timers' argument has been changed to have separate 'lsa' and 'spf' keys and 'throttle' has been deprecated. ** " - " \n** Your task has been modified to use {0}. ** " - " \n** timers.throttle will be removed after '2024-01-01' ** ".format( - entry["timers"], - ), - ) if entry["timers"].get("lsa") and not isinstance( entry["timers"]["lsa"], dict, @@ -281,13 +226,6 @@ class Ospfv3(ResourceModule): }, }, } - self._module.warn( - " ** 'timers lsa arrival' has changed to 'timers lsa rx min interval' from eos 4.23 onwards. ** " - " \n** Your task has been modified to use {0}. ** " - " \n** timers.lsa of type int will be removed after '2024-01-01' ** ".format( - modified, - ), - ) entry["timers"]["lsa"] = modified["timers"]["lsa"] self._compare_lists(want=entry, have=hafs.get(name, {})) self._areas_compare(want=entry, have=hafs.get(name, {})) diff --git a/ansible_collections/arista/eos/plugins/module_utils/network/eos/facts/static_routes/static_routes.py b/ansible_collections/arista/eos/plugins/module_utils/network/eos/facts/static_routes/static_routes.py index c97c48d5f..369f869ef 100644 --- a/ansible_collections/arista/eos/plugins/module_utils/network/eos/facts/static_routes/static_routes.py +++ b/ansible_collections/arista/eos/plugins/module_utils/network/eos/facts/static_routes/static_routes.py @@ -96,7 +96,7 @@ class Static_routesFacts(object): if obj: objs.append(obj) ansible_facts["ansible_network_resources"].pop("static_routes", None) - facts = {} + facts = {"static_routes": []} if objs: facts["static_routes"] = [] params = utils.validate_config( diff --git a/ansible_collections/arista/eos/plugins/module_utils/network/eos/facts/vlans/vlans.py b/ansible_collections/arista/eos/plugins/module_utils/network/eos/facts/vlans/vlans.py index eddd4c4e5..a6bfcb697 100644 --- a/ansible_collections/arista/eos/plugins/module_utils/network/eos/facts/vlans/vlans.py +++ b/ansible_collections/arista/eos/plugins/module_utils/network/eos/facts/vlans/vlans.py @@ -69,7 +69,7 @@ class VlansFacts(object): objs.extend(obj) ansible_facts["ansible_network_resources"].pop("vlans", None) - facts = {} + facts = {"vlans": []} if objs: params = utils.validate_config( self.argument_spec, diff --git a/ansible_collections/arista/eos/plugins/module_utils/network/eos/rm_templates/snmp_server.py b/ansible_collections/arista/eos/plugins/module_utils/network/eos/rm_templates/snmp_server.py index ef83f506a..3e22fe780 100644 --- a/ansible_collections/arista/eos/plugins/module_utils/network/eos/rm_templates/snmp_server.py +++ b/ansible_collections/arista/eos/plugins/module_utils/network/eos/rm_templates/snmp_server.py @@ -294,7 +294,7 @@ def _tmplt_snmp_server_hosts(config_data): el = list(config_data["hosts"].values())[0] command = "snmp-server host " + el["host"] if el.get("vrf"): - command += " vrf" + el["vrf"] + command += " vrf " + el["vrf"] if el.get("informs"): command += " informs" if el.get("traps"): @@ -334,7 +334,7 @@ def _tmplt_snmp_server_users_auth(config_data): command += " udp-port " + str(el["udp_port"]) command += " " + el["version"] if el.get("auth"): - command += " " + el["auth"]["algorithm"] + " " + el["auth"]["auth_passphrase"] + command += " auth " + el["auth"]["algorithm"] + " " + el["auth"]["auth_passphrase"] if el["auth"].get("encryption"): command += " priv " + el["auth"]["encryption"] + " " + el["auth"]["priv_passphrase"] return command @@ -351,7 +351,7 @@ def _tmplt_snmp_server_users_localized(config_data): if el.get("localized"): command += " localized " + el["localized"]["engineid"] el = el["localized"] - command += " " + el["algorithm"] + " " + el["auth_passphrase"] + command += " auth " + el["algorithm"] + " " + el["auth_passphrase"] if el.get("encryption"): command += " priv " + el["encryption"] + " " + el["priv_passphrase"] return command diff --git a/ansible_collections/arista/eos/plugins/modules/eos_bgp.py b/ansible_collections/arista/eos/plugins/modules/eos_bgp.py deleted file mode 100644 index e740f6c2e..000000000 --- a/ansible_collections/arista/eos/plugins/modules/eos_bgp.py +++ /dev/null @@ -1,468 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# (c) 2019, Ansible by Red Hat, inc -# 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 - - -DOCUMENTATION = """ -module: eos_bgp -author: Nilashish Chakraborty (@NilashishC) -short_description: (deprecated, removed after 2023-01-29) Configure global BGP protocol settings on Arista EOS. -description: -- This module provides configuration management of global BGP parameters on Arista - EOS devices. -version_added: 1.0.0 -deprecated: - alternative: eos_bgp_global - why: Updated module released with more functionality. - removed_at_date: '2023-01-01' -notes: -- Tested against Arista EOS 4.24.6F -options: - config: - description: - - Specifies the BGP related configuration. - type: dict - suboptions: - bgp_as: - description: - - Specifies the BGP Autonomous System (AS) number to configure on the device. - type: int - required: true - router_id: - description: - - Configures the BGP routing process router-id value. - type: str - log_neighbor_changes: - description: - - Enable/disable logging neighbor up/down and reset reason. - type: bool - neighbors: - description: - - Specifies BGP neighbor related configurations. - type: list - elements: dict - suboptions: - neighbor: - description: - - Neighbor router address. - required: true - type: str - remote_as: - description: - - Remote AS of the BGP neighbor to configure. - type: int - required: true - update_source: - description: - - Source of the routing updates. - type: str - password: - description: - - Password to authenticate the BGP peer connection. - type: str - description: - description: - - Neighbor specific description. - type: str - ebgp_multihop: - description: - - Specifies the maximum hop count for EBGP neighbors not on directly connected - networks. - - The range is from 1 to 255. - type: int - peer_group: - description: - - Name of the peer group that the neighbor is a member of. - type: str - timers: - description: - - Specifies BGP neighbor timer related configurations. - type: dict - suboptions: - keepalive: - description: - - Frequency (in seconds) with which the device sends keepalive messages - to its peer. - - The range is from 0 to 3600. - type: int - required: true - holdtime: - description: - - Interval (in seconds) after not receiving a keepalive message that - device declares a peer dead. - - The range is from 3 to 7200. - - Setting this value to 0 will not send keep-alives (hold forever). - type: int - required: true - route_reflector_client: - description: - - Specify a neighbor as a route reflector client. - type: int - remove_private_as: - description: - - Remove the private AS number from outbound updates. - type: bool - enabled: - description: - - Administratively shutdown or enable a neighbor. - type: bool - maximum_prefix: - description: - - Maximum number of prefixes to accept from this peer. - - The range is from 0 to 4294967294. - type: int - redistribute: - description: - - Specifies the redistribute information from another routing protocol. - type: list - elements: dict - suboptions: - protocol: - description: - - Specifies the protocol for configuring redistribute information. - required: true - type: str - choices: [ospf, ospfv3, static, connected, rip, isis] - route_map: - description: - - Specifies the route map reference. - type: str - networks: - description: - - Specify Networks to announce via BGP. - - For operation replace, this option is mutually exclusive with networks option - under address_family. - - For operation replace, if the device already has an address family activated, - this option is not allowed. - type: list - elements: dict - suboptions: - prefix: - description: - - Network ID to announce via BGP. - required: true - type: str - masklen: - description: - - Subnet mask length for the Network to announce(e.g, 8, 16, 24, etc.). - type: int - route_map: - description: - - Route map to modify the attributes. - type: str - address_family: - description: - - Specifies BGP address family related configurations. - type: list - elements: dict - suboptions: - afi: - description: - - Type of address family to configure. - type: str - choices: - - ipv4 - - ipv6 - required: true - redistribute: - description: - - Specifies the redistribute information from another routing protocol. - type: list - elements: dict - suboptions: - protocol: - description: - - Specifies the protocol for configuring redistribute information. - required: true - type: str - choices: - - ospfv3 - - ospf - - isis - - static - - connected - - rip - route_map: - description: - - Specifies the route map reference. - type: str - networks: - description: - - Specify Networks to announce via BGP. - - For operation replace, this option is mutually exclusive with root level - networks option. - type: list - elements: dict - suboptions: - prefix: - description: - - Network ID to announce via BGP. - required: true - type: str - masklen: - description: - - Subnet mask length for the Network to announce(e.g, 8, 16, 24, etc.). - type: int - route_map: - description: - - Route map to modify the attributes. - type: str - neighbors: - description: - - Specifies BGP neighbor related configurations in Address Family configuration - mode. - type: list - elements: dict - suboptions: - neighbor: - description: - - Neighbor router address. - required: true - type: str - activate: - description: - - Enable the Address Family for this Neighbor. - type: bool - default_originate: - description: - - Originate default route to this neighbor. - type: bool - graceful_restart: - description: - - Enable/disable graceful restart mode for this neighbor. - type: bool - weight: - description: - - Assign weight for routes learnt from this neighbor. - - The range is from 0 to 65535 - type: int - operation: - description: - - Specifies the operation to be performed on the BGP process configured on the - device. - - In case of merge, the input configuration will be merged with the existing BGP - configuration on the device. - - In case of replace, if there is a diff between the existing configuration and - the input configuration, the existing configuration will be replaced by the - input configuration for every option that has the diff. - - In case of override, all the existing BGP configuration will be removed from - the device and replaced with the input configuration. - - In case of delete the existing BGP configuration will be removed from the device. - type: str - default: merge - choices: - - merge - - replace - - override - - delete -""" - -EXAMPLES = """ -- name: configure global bgp as 64496 - arista.eos.eos_bgp: - config: - bgp_as: 64496 - router_id: 192.0.2.1 - log_neighbor_changes: true - neighbors: - - neighbor: 203.0.113.5 - remote_as: 64511 - timers: - keepalive: 300 - holdtime: 360 - - neighbor: 198.51.100.2 - remote_as: 64498 - networks: - - prefix: 198.51.100.0 - route_map: RMAP_1 - - prefix: 192.0.2.0 - masklen: 23 - address_family: - - afi: ipv4 - safi: unicast - redistribute: - - protocol: isis - route_map: RMAP_1 - operation: merge -- name: Configure BGP neighbors - arista.eos.eos_bgp: - config: - bgp_as: 64496 - neighbors: - - neighbor: 192.0.2.10 - remote_as: 64496 - description: IBGP_NBR_1 - ebgp_multihop: 100 - timers: - keepalive: 300 - holdtime: 360 - - neighbor: 192.0.2.15 - remote_as: 64496 - description: IBGP_NBR_2 - ebgp_multihop: 150 - operation: merge -- name: Configure root-level networks for BGP - arista.eos.eos_bgp: - config: - bgp_as: 64496 - networks: - - prefix: 203.0.113.0 - masklen: 27 - route_map: RMAP_1 - - prefix: 203.0.113.32 - masklen: 27 - route_map: RMAP_2 - operation: merge -- name: Configure BGP neighbors under address family mode - arista.eos.eos_bgp: - config: - bgp_as: 64496 - address_family: - - afi: ipv4 - neighbors: - - neighbor: 203.0.113.10 - activate: true - default_originate: true - - neighbor: 192.0.2.15 - activate: true - graceful_restart: true - operation: merge -- name: remove bgp as 64496 from config - arista.eos.eos_bgp: - config: - bgp_as: 64496 - operation: delete -""" -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - router bgp 64496 - - bgp router-id 192.0.2.1 - - bgp log-neighbor-changes - - neighbor 203.0.113.5 remote-as 64511 - - neighbor 203.0.113.5 timers 300 360 - - neighbor 198.51.100.2 remote-as 64498 - - network 198.51.100.0 route-map RMAP_1 - - network 192.0.2.0 mask 255.255.254.0 - - address-family ipv4 - - redistribute isis route-map RMAP_1 - - exit-address-family -""" -from ansible.module_utils._text import to_text - -from ansible_collections.arista.eos.plugins.module_utils.network.eos.providers.cli.config.bgp.process import ( - REDISTRIBUTE_PROTOCOLS, -) -from ansible_collections.arista.eos.plugins.module_utils.network.eos.providers.module import ( - NetworkModule, -) - - -def main(): - """main entry point for module execution""" - network_spec = { - "prefix": dict(required=True), - "masklen": dict(type="int"), - "route_map": dict(), - } - - redistribute_spec = { - "protocol": dict(choices=list(REDISTRIBUTE_PROTOCOLS), required=True), - "route_map": dict(), - } - - timer_spec = { - "keepalive": dict(type="int", required=True), - "holdtime": dict(type="int", required=True), - } - - neighbor_spec = { - "neighbor": dict(required=True), - "remote_as": dict(type="int", required=True), - "update_source": dict(), - "password": dict(no_log=True), - "enabled": dict(type="bool"), - "description": dict(), - "ebgp_multihop": dict(type="int"), - "timers": dict(type="dict", options=timer_spec), - "peer_group": dict(), - "maximum_prefix": dict(type="int"), - "route_reflector_client": dict(type="int"), - "remove_private_as": dict(type="bool"), - } - - af_neighbor_spec = { - "neighbor": dict(required=True), - "activate": dict(type="bool"), - "default_originate": dict(type="bool"), - "graceful_restart": dict(type="bool"), - "weight": dict(type="int"), - } - - address_family_spec = { - "afi": dict(choices=["ipv4", "ipv6"], required=True), - "networks": dict(type="list", elements="dict", options=network_spec), - "redistribute": dict( - type="list", - elements="dict", - options=redistribute_spec, - ), - "neighbors": dict( - type="list", - elements="dict", - options=af_neighbor_spec, - ), - } - - config_spec = { - "bgp_as": dict(type="int", required=True), - "router_id": dict(), - "log_neighbor_changes": dict(type="bool"), - "neighbors": dict(type="list", elements="dict", options=neighbor_spec), - "address_family": dict( - type="list", - elements="dict", - options=address_family_spec, - ), - "redistribute": dict( - type="list", - elements="dict", - options=redistribute_spec, - ), - "networks": dict(type="list", elements="dict", options=network_spec), - } - - argument_spec = { - "config": dict(type="dict", options=config_spec), - "operation": dict( - default="merge", - choices=["merge", "replace", "override", "delete"], - ), - } - - module = NetworkModule( - argument_spec=argument_spec, - supports_check_mode=True, - ) - - try: - result = module.edit_config(config_filter="| section bgp") - except Exception as exc: - module.fail_json(msg=to_text(exc)) - - module.exit_json(**result) - - -if __name__ == "__main__": - main() diff --git a/ansible_collections/arista/eos/plugins/modules/eos_lag_interfaces.py b/ansible_collections/arista/eos/plugins/modules/eos_lag_interfaces.py index 2a58f796f..1af9a2f4e 100644 --- a/ansible_collections/arista/eos/plugins/modules/eos_lag_interfaces.py +++ b/ansible_collections/arista/eos/plugins/modules/eos_lag_interfaces.py @@ -112,10 +112,10 @@ EXAMPLES = """ - name: Merge provided LAG attributes with existing device configuration arista.eos.eos_lag_interfaces: config: - - name: 5 + - name: Port-Channel5 members: - member: Ethernet2 - mode: on + mode: "on" state: merged # After state: @@ -141,10 +141,10 @@ EXAMPLES = """ - name: Replace all device configuration of specified LAGs with provided configuration arista.eos.eos_lag_interfaces: config: - - name: 5 + - name: Port-Channel5 members: - member: Ethernet2 - mode: on + mode: "on" state: replaced # After state: @@ -169,10 +169,10 @@ EXAMPLES = """ - name: Override all device configuration of all LAG attributes with provided configuration arista.eos.eos_lag_interfaces: config: - - name: 10 + - name: Port-Channel10 members: - member: Ethernet2 - mode: on + mode: "on" state: overridden # After state: @@ -198,7 +198,7 @@ EXAMPLES = """ - name: Delete LAG attributes of the given interfaces. arista.eos.eos_lag_interfaces: config: - - name: 5 + - name: Port-Channel5 members: - member: Ethernet1 state: deleted @@ -226,24 +226,24 @@ EXAMPLES = """ # Output: # parsed: -# - name: 5 +# - name: Port-Channel5 # members: # - member: Ethernet2 -# mode: on +# mode: "on" # - member: Ethernet1 -# mode: on +# mode: "on" # using rendered: - name: Use Rendered to convert the structured data to native config arista.eos.eos_lag_interfaces: config: - - name: 5 + - name: Port-Channel5 members: - member: Ethernet2 - mode: on + mode: "on" - member: Ethernet1 - mode: on + mode: "on" state: rendered # ----------- # Output @@ -271,7 +271,7 @@ EXAMPLES = """ # Output: # gathered: -# - name: 5 +# - name: Port-Channel5 # members: # - member: Ethernet2 # mode: on diff --git a/ansible_collections/arista/eos/plugins/modules/eos_logging.py b/ansible_collections/arista/eos/plugins/modules/eos_logging.py deleted file mode 100644 index 845af44d5..000000000 --- a/ansible_collections/arista/eos/plugins/modules/eos_logging.py +++ /dev/null @@ -1,505 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -from __future__ import absolute_import, division, print_function - - -__metaclass__ = type - -# Copyright: (c) 2017, Ansible by Red Hat, inc -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -DOCUMENTATION = """ -module: eos_logging -author: Trishna Guha (@trishnaguha) -short_description: Manage logging on network devices -description: -- This module provides declarative management of logging on Arista Eos devices. -version_added: 1.0.0 -deprecated: - alternative: eos_logging_global - why: Updated module released with more functionality. - removed_at_date: '2024-01-01' -notes: -- Tested against Arista EOS 4.24.6F -options: - dest: - description: - - Destination of the logs. - choices: - - "on" - - host - - console - - monitor - - buffered - type: str - name: - description: - - The hostname or IP address of the destination. - - Required when I(dest=host). - type: str - size: - description: - - Size of buffer. The acceptable value is in range from 10 to 2147483647 bytes. - type: int - facility: - description: - - Set logging facility. - type: str - level: - description: - - Set logging severity levels. - choices: - - emergencies - - alerts - - critical - - errors - - warnings - - notifications - - informational - - debugging - type: str - aggregate: - description: List of logging definitions. - type: list - elements: dict - suboptions: - dest: - description: - - Destination of the logs. - choices: - - "on" - - host - - console - - monitor - - buffered - type: str - name: - description: - - The hostname or IP address of the destination. - - Required when I(dest=host). - type: str - size: - description: - - Size of buffer. The acceptable value is in range from 10 to 2147483647 bytes. - type: int - facility: - description: - - Set logging facility. - type: str - level: - description: - - Set logging severity levels. - choices: - - emergencies - - alerts - - critical - - errors - - warnings - - notifications - - informational - - debugging - type: str - state: - description: - - State of the logging configuration. - default: present - type: str - choices: - - present - - absent - state: - description: - - State of the logging configuration. - default: present - type: str - choices: - - present - - absent -""" - -EXAMPLES = """ -- name: configure host logging - arista.eos.eos_logging: - dest: host - name: 172.16.0.1 - state: present - -- name: remove host logging configuration - arista.eos.eos_logging: - dest: host - name: 172.16.0.1 - state: absent - -- name: configure console logging level and facility - arista.eos.eos_logging: - dest: console - facility: local7 - level: debugging - state: present - -- name: enable logging to all - arista.eos.eos_logging: - dest: on - -- name: configure buffer size - arista.eos.eos_logging: - dest: buffered - size: 5000 - -- name: Configure logging using aggregate - arista.eos.eos_logging: - aggregate: - - {dest: console, level: warnings} - - {dest: buffered, size: 480000} - state: present -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - logging facility local7 - - logging host 172.16.0.1 -""" - -import re - -from copy import deepcopy - -from ansible.module_utils._text import to_text -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.validation import check_required_if -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( - remove_default_spec, -) - -from ansible_collections.arista.eos.plugins.module_utils.network.eos.eos import ( - get_config, - load_config, -) - - -DEST_GROUP = ["on", "host", "console", "monitor", "buffered"] -LEVEL_GROUP = [ - "emergencies", - "alerts", - "critical", - "errors", - "warnings", - "notifications", - "informational", - "debugging", -] - - -def validate_size(value, module): - if value: - if not int(10) <= value <= int(2147483647): - module.fail_json(msg="size must be between 10 and 2147483647") - else: - return value - - -def map_obj_to_commands(updates, module): - commands = list() - want, have = updates - - for w in want: - dest = w["dest"] - name = w["name"] - size = w["size"] - facility = w["facility"] - level = w["level"] - state = w["state"] - del w["state"] - - if state == "absent" and w in have: - if dest: - if dest == "host": - commands.append("no logging host {0}".format(name)) - - elif dest in DEST_GROUP: - commands.append("no logging {0}".format(dest)) - - else: - module.fail_json( - msg="dest must be among console, monitor, buffered, host, on", - ) - - if facility: - commands.append("no logging facility {0}".format(facility)) - - if state == "present" and w not in have: - if facility: - present = False - - # Iterate over every dictionary in the 'have' list to check if - # similar configuration for facility exists or not - - for entry in have: - if not entry["dest"] and entry["facility"] == facility: - present = True - - if not present: - commands.append("logging facility {0}".format(facility)) - - if dest == "host": - commands.append("logging host {0}".format(name)) - - elif dest == "on": - commands.append("logging on") - - elif dest == "buffered" and size: - present = False - - # Deals with the following two cases: - # Case 1: logging buffered <size> <level> - # logging buffered <same-size> - # - # Case 2: Same buffered logging configuration - # already exists (i.e., both size & - # level are same) - - for entry in have: - if entry["dest"] == "buffered" and entry["size"] == size: - if not level or entry["level"] == level: - present = True - - if not present: - if size and level: - commands.append( - "logging buffered {0} {1}".format(size, level), - ) - else: - commands.append("logging buffered {0}".format(size)) - - else: - if dest: - dest_cmd = "logging {0}".format(dest) - if level: - dest_cmd += " {0}".format(level) - - commands.append(dest_cmd) - return commands - - -def parse_facility(line): - facility = None - match = re.search(r"logging facility (\S+)", line, re.M) - if match: - facility = match.group(1) - - return facility - - -def parse_size(line, dest): - size = None - - if dest == "buffered": - match = re.search(r"logging buffered (\S+)", line, re.M) - if match: - try: - int_size = int(match.group(1)) - except ValueError: - int_size = None - - if int_size: - if isinstance(int_size, int): - size = str(match.group(1)) - else: - size = str(10) - - return size - - -def parse_name(line, dest): - name = None - if dest == "host": - match = re.search(r"logging host (\S+)", line, re.M) - if match: - name = match.group(1) - - return name - - -def parse_level(line, dest): - level = None - - if dest != "host": - # Line for buffer logging entry in running-config is of the form: - # logging buffered <size> <level> - - if dest == "buffered": - match = re.search(r"logging buffered (?:\d+) (\S+)", line, re.M) - - else: - match = re.search(r"logging {0} (\S+)".format(dest), line, re.M) - - if match: - if match.group(1) in LEVEL_GROUP: - level = match.group(1) - - return level - - -def map_config_to_obj(module): - obj = [] - - data = get_config(module, flags=["section logging"]) - - for line in data.split("\n"): - match = re.search(r"logging (\S+)", line, re.M) - - if match: - if match.group(1) in DEST_GROUP: - dest = match.group(1) - - else: - dest = None - - obj.append( - { - "dest": dest, - "name": parse_name(line, dest), - "size": parse_size(line, dest), - "facility": parse_facility(line), - "level": parse_level(line, dest), - }, - ) - - return obj - - -def parse_obj(obj, module): - if module.params["size"] is None: - obj.append( - { - "dest": module.params["dest"], - "name": module.params["name"], - "size": module.params["size"], - "facility": module.params["facility"], - "level": module.params["level"], - "state": module.params["state"], - }, - ) - - else: - obj.append( - { - "dest": module.params["dest"], - "name": module.params["name"], - "size": str(validate_size(module.params["size"], module)), - "facility": module.params["facility"], - "level": module.params["level"], - "state": module.params["state"], - }, - ) - - return obj - - -def map_params_to_obj(module, required_if=None): - obj = [] - aggregate = module.params.get("aggregate") - if aggregate: - for item in aggregate: - for key in item: - if item.get(key) is None: - item[key] = module.params[key] - - try: - check_required_if(required_if, item) - except TypeError as exc: - module.fail_json(to_text(exc)) - d = item.copy() - - if d["dest"] != "host": - d["name"] = None - - if d["dest"] == "buffered": - if "size" in d: - d["size"] = str(validate_size(d["size"], module)) - elif "size" not in d: - d["size"] = str(10) - else: - pass - - if d["dest"] != "buffered": - d["size"] = None - - obj.append(d) - - else: - if module.params["dest"] != "host": - module.params["name"] = None - - if module.params["dest"] == "buffered": - if not module.params["size"]: - module.params["size"] = str(10) - else: - module.params["size"] = None - - parse_obj(obj, module) - - return obj - - -def main(): - """main entry point for module execution""" - element_spec = dict( - dest=dict(choices=DEST_GROUP), - name=dict(), - size=dict(type="int"), - facility=dict(), - level=dict(choices=LEVEL_GROUP), - state=dict(default="present", choices=["present", "absent"]), - ) - - aggregate_spec = deepcopy(element_spec) - - # remove default in aggregate spec, to handle common arguments - remove_default_spec(aggregate_spec) - - aggregate_spec["state"].update(default="present") - argument_spec = dict( - aggregate=dict(type="list", elements="dict", options=aggregate_spec), - ) - - argument_spec.update(element_spec) - - required_if = [("dest", "host", ["name"])] - - module = AnsibleModule( - argument_spec=argument_spec, - required_if=required_if, - supports_check_mode=True, - ) - - warnings = list() - - result = {"changed": False} - if warnings: - result["warnings"] = warnings - - have = map_config_to_obj(module) - want = map_params_to_obj(module, required_if=required_if) - - commands = map_obj_to_commands((want, have), module) - result["commands"] = commands - - if commands: - commit = not module.check_mode - response = load_config(module, commands, commit=commit) - if response.get("diff") and module._diff: - result["diff"] = {"prepared": response.get("diff")} - result["session_name"] = response.get("session") - result["changed"] = True - - module.exit_json(**result) - - -if __name__ == "__main__": - main() diff --git a/ansible_collections/arista/eos/plugins/modules/eos_ospfv3.py b/ansible_collections/arista/eos/plugins/modules/eos_ospfv3.py index c1194f767..287cb12d8 100644 --- a/ansible_collections/arista/eos/plugins/modules/eos_ospfv3.py +++ b/ansible_collections/arista/eos/plugins/modules/eos_ospfv3.py @@ -284,25 +284,6 @@ options: pacing: description: Configure OSPF packet pacing. type: int - throttle: - description: This command is deprecated by 'timers lsa' or 'timers spf'. - type: dict - suboptions: - initial: - description: Initial SPF schedule delay in msecs. - type: int - min: - description: Min Hold time between two SPFs in msecs - type: int - max: - description: Max wait time between two SPFs in msecs. - type: int - lsa: - description: Configure threshold for retransmission of lsa - type: bool - spf: - description: Configure time between SPF calculations - type: bool spf: description: Configure OSPFv3 spf timers. type: dict @@ -627,25 +608,6 @@ options: description: Configure OSPF timers. type: dict suboptions: - throttle: - description: This command is deprecated by 'timers lsa' or 'timers spf'. - type: dict - suboptions: - initial: - description: Initial SPF schedule delay in msecs. - type: int - min: - description: Min Hold time between two SPFs in msecs - type: int - max: - description: Max wait time between two SPFs in msecs. - type: int - lsa: - description: Configure threshold for retransmission of lsa - type: bool - spf: - description: Configure time between SPF calculations - type: bool out_delay: description: Configure out-delay timer. type: int diff --git a/ansible_collections/arista/eos/plugins/modules/eos_system.py b/ansible_collections/arista/eos/plugins/modules/eos_system.py index b38d9772d..924e7052d 100644 --- a/ansible_collections/arista/eos/plugins/modules/eos_system.py +++ b/ansible_collections/arista/eos/plugins/modules/eos_system.py @@ -66,7 +66,7 @@ options: argument accepts either a list of DNS servers or a list of hashes that configure the name server and VRF name. See examples. type: list - elements: str + elements: raw state: description: - State of the configuration values in the device's current active configuration. When @@ -342,7 +342,7 @@ def main(): # { interface: <str>, vrf: <str> } lookup_source=dict(type="list", elements="raw"), # { server: <str>; vrf: <str> } - name_servers=dict(type="list", elements="str"), + name_servers=dict(type="list", elements="raw"), state=dict(default="present", choices=["present", "absent"]), ) diff --git a/ansible_collections/arista/eos/plugins/modules/eos_vrf.py b/ansible_collections/arista/eos/plugins/modules/eos_vrf.py index 556ef3233..14981a14d 100644 --- a/ansible_collections/arista/eos/plugins/modules/eos_vrf.py +++ b/ansible_collections/arista/eos/plugins/modules/eos_vrf.py @@ -314,16 +314,19 @@ def map_params_to_obj(module): "name": module.params["name"], "state": module.params["state"], "rd": module.params["rd"], - "interfaces": [ - intf.replace(" ", "").lower() for intf in module.params["interfaces"] - ] - if module.params["interfaces"] - else [], - "associated_interfaces": [ - intf.replace(" ", "").lower() for intf in module.params["associated_interfaces"] - ] - if module.params["associated_interfaces"] - else [], + "interfaces": ( + [intf.replace(" ", "").lower() for intf in module.params["interfaces"]] + if module.params["interfaces"] + else [] + ), + "associated_interfaces": ( + [ + intf.replace(" ", "").lower() + for intf in module.params["associated_interfaces"] + ] + if module.params["associated_interfaces"] + else [] + ), }, ) |