summaryrefslogtreecommitdiffstats
path: root/ansible_collections/arista/eos/plugins/modules
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:04:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:04:41 +0000
commit975f66f2eebe9dadba04f275774d4ab83f74cf25 (patch)
tree89bd26a93aaae6a25749145b7e4bca4a1e75b2be /ansible_collections/arista/eos/plugins/modules
parentInitial commit. (diff)
downloadansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.tar.xz
ansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.zip
Adding upstream version 7.7.0+dfsg.upstream/7.7.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/arista/eos/plugins/modules')
-rw-r--r--ansible_collections/arista/eos/plugins/modules/__init__.py0
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_acl_interfaces.py423
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_acls.py904
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_banner.py199
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_bgp.py469
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_bgp_address_family.py1351
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_bgp_global.py2353
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_command.py320
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_config.py630
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_eapi.py437
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_facts.py210
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_hostname.py333
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_interfaces.py415
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_l2_interfaces.py430
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_l3_interfaces.py412
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_lacp.py247
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_lacp_interfaces.py340
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_lag_interfaces.py342
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_lldp.py117
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_lldp_global.py347
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_lldp_interfaces.py346
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_logging.py505
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_logging_global.py942
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_ntp_global.py1053
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_ospf_interfaces.py1230
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_ospfv2.py1563
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_ospfv3.py1583
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_prefix_lists.py1197
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_route_maps.py1406
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_snmp_server.py1522
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_static_routes.py969
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_system.py378
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_user.py491
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_vlans.py329
-rw-r--r--ansible_collections/arista/eos/plugins/modules/eos_vrf.py427
35 files changed, 24220 insertions, 0 deletions
diff --git a/ansible_collections/arista/eos/plugins/modules/__init__.py b/ansible_collections/arista/eos/plugins/modules/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/__init__.py
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_acl_interfaces.py b/ansible_collections/arista/eos/plugins/modules/eos_acl_interfaces.py
new file mode 100644
index 000000000..e609a7c09
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_acl_interfaces.py
@@ -0,0 +1,423 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_acl_interfaces
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_acl_interfaces
+short_description: ACL interfaces resource module
+description:
+- This module manages adding and removing Access Control Lists (ACLs) from interfaces
+ on devices running EOS software.
+version_added: 1.0.0
+author: GomathiSelvi S (@GomathiselviS)
+options:
+ config:
+ description: A dictionary of ACL options for interfaces.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Name/Identifier for the interface.
+ type: str
+ required: true
+ access_groups:
+ type: list
+ elements: dict
+ description:
+ - Specifies ACLs attached to the interfaces.
+ suboptions:
+ afi:
+ description:
+ - Specifies the AFI for the ACL(s) to be configured on this interface.
+ type: str
+ choices:
+ - ipv4
+ - ipv6
+ required: true
+ acls:
+ type: list
+ description:
+ - Specifies the ACLs for the provided AFI.
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Specifies the name of the IPv4/IPv4 ACL for the interface.
+ type: str
+ required: true
+ direction:
+ description:
+ - Specifies the direction of packets that the ACL will be applied
+ on.
+ type: str
+ choices:
+ - in
+ - out
+ required: true
+ running_config:
+ description:
+ - The module, by default, will connect to the remote device and retrieve the current
+ running-config to use as a base for comparing against the contents of source.
+ There are times when it is not desirable to have the task get the current running-config
+ for every task in a playbook. The I(running_config) argument allows the implementer
+ to pass in the configuration to use as the base config for comparison. This
+ value of this option should be the output received from device by executing
+ command
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - gathered
+ - parsed
+ - rendered
+ default: merged
+
+"""
+EXAMPLES = """
+# Using Merged
+
+# Before state:
+# -------------
+#
+# eos#sh running-config | include interface|access-group
+# interface Ethernet1
+# interface Ethernet2
+# interface Ethernet3
+
+- name: Merge module attributes of given access-groups
+ arista.eos.eos_acl_interfaces:
+ config:
+ - name: Ethernet2
+ access_groups:
+ - afi: ipv4
+ acls:
+ name: acl01
+ direction: in
+ - afi: ipv6
+ acls:
+ name: acl03
+ direction: out
+ state: merged
+
+# Commands Fired:
+# ---------------
+#
+# interface Ethernet2
+# ip access-group acl01 in
+# ipv6 access-group acl03 out
+
+# After state:
+# -------------
+#
+# eos#sh running-config | include interface| access-group
+# interface Loopback888
+# interface Ethernet1
+# interface Ethernet2
+# ip access-group acl01 in
+# ipv6 access-group acl03 out
+# interface Ethernet3
+
+
+# Using Replaced
+
+# Before state:
+# -------------
+#
+# eos#sh running-config | include interface|access-group
+# interface Ethernet1
+# interface Ethernet2
+# ip access-group acl01 in
+# ipv6 access-group acl03 out
+# interface Ethernet3
+# ip access-group acl01 in
+
+- name: Replace module attributes of given access-groups
+ arista.eos.eos_acl_interfaces:
+ config:
+ - name: Ethernet2
+ access_groups:
+ - afi: ipv4
+ acls:
+ name: acl01
+ direction: out
+ state: replaced
+
+# Commands Fired:
+# ---------------
+#
+# interface Ethernet2
+# no ip access-group acl01 in
+# no ipv6 access-group acl03 out
+# ip access-group acl01 out
+
+# After state:
+# -------------
+#
+# eos#sh running-config | include interface| access-group
+# interface Loopback888
+# interface Ethernet1
+# interface Ethernet2
+# ip access-group acl01 out
+# interface Ethernet3
+# ip access-group acl01 in
+
+
+# Using Overridden
+
+# Before state:
+# -------------
+#
+# eos#sh running-config | include interface|access-group
+# interface Ethernet1
+# interface Ethernet2
+# ip access-group acl01 in
+# ipv6 access-group acl03 out
+# interface Ethernet3
+# ip access-group acl01 in
+
+- name: Override module attributes of given access-groups
+ arista.eos.eos_acl_interfaces:
+ config:
+ - name: Ethernet2
+ access_groups:
+ - afi: ipv4
+ acls:
+ name: acl01
+ direction: out
+ state: overridden
+
+# Commands Fired:
+# ---------------
+#
+# interface Ethernet2
+# no ip access-group acl01 in
+# no ipv6 access-group acl03 out
+# ip access-group acl01 out
+# interface Ethernet3
+# no ip access-group acl01 in
+
+# After state:
+# -------------
+#
+# eos#sh running-config | include interface| access-group
+# interface Loopback888
+# interface Ethernet1
+# interface Ethernet2
+# ip access-group acl01 out
+# interface Ethernet3
+
+
+# Using Deleted
+
+# Before state:
+# -------------
+#
+# eos#sh running-config | include interface|access-group
+# interface Ethernet1
+# interface Ethernet2
+# ip access-group acl01 in
+# ipv6 access-group acl03 out
+# interface Ethernet3
+# ip access-group acl01 out
+
+- name: Delete module attributes of given access-groups
+ arista.eos.eos_acl_interfaces:
+ config:
+ - name: Ethernet2
+ access_groups:
+ - afi: ipv4
+ acls:
+ name: acl01
+ direction: in
+ - afi: ipv6
+ acls:
+ name: acl03
+ direction: out
+ state: deleted
+
+# Commands Fired:
+# ---------------
+#
+# interface Ethernet2
+# no ip access-group acl01 in
+# no ipv6 access-group acl03 out
+
+# After state:
+# -------------
+#
+# eos#sh running-config | include interface| access-group
+# interface Loopback888
+# interface Ethernet1
+# interface Ethernet2
+# interface Ethernet3
+# ip access-group acl01 out
+
+
+# Before state:
+# -------------
+#
+# eos#sh running-config | include interface| access-group
+# interface Ethernet1
+# interface Ethernet2
+# ip access-group acl01 in
+# ipv6 access-group acl03 out
+# interface Ethernet3
+# ip access-group acl01 out
+
+- name: Delete module attributes of given access-groups from ALL Interfaces
+ arista.eos.eos_acl_interfaces:
+ config:
+ state: deleted
+
+# Commands Fired:
+# ---------------
+#
+# interface Ethernet2
+# no ip access-group acl01 in
+# no ipv6 access-group acl03 out
+# interface Ethernet3
+# no ip access-group acl01 out
+
+# After state:
+# -------------
+#
+# eos#sh running-config | include interface| access-group
+# interface Loopback888
+# interface Ethernet1
+# interface Ethernet2
+# interface Ethernet3
+
+# Before state:
+# -------------
+#
+# eos#sh running-config | include interface| access-group
+# interface Ethernet1
+# interface Ethernet2
+# ip access-group acl01 in
+# ipv6 access-group acl03 out
+# interface Ethernet3
+# ip access-group acl01 out
+
+- name: Delete acls under afi
+ arista.eos.eos_acl_interfaces:
+ config:
+ - name: Ethernet3
+ access_groups:
+ - afi: ipv4
+ - name: Ethernet2
+ access_groups:
+ - afi: ipv6
+ state: deleted
+
+# Commands Fired:
+# ---------------
+#
+# interface Ethernet2
+# no ipv6 access-group acl03 out
+# interface Ethernet3
+# no ip access-group acl01 out
+
+# After state:
+# -------------
+#
+# eos#sh running-config | include interface| access-group
+# interface Loopback888
+# interface Ethernet1
+# interface Ethernet2
+# ip access-group acl01 in
+# interface Ethernet3
+
+
+"""
+RETURN = """
+before:
+ description: The configuration prior to the model invocation.
+ returned: always
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+after:
+ description: The resulting configuration model invocation.
+ returned: when changed
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample:
+ - interface Ethernet2
+ - ip access-group acl01 in
+ - ipv6 access-group acl03 out
+ - interface Ethernet3
+ - ip access-group acl01 out
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.acl_interfaces.acl_interfaces import (
+ Acl_interfacesArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.acl_interfaces.acl_interfaces import (
+ Acl_interfaces,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Acl_interfacesArgs.argument_spec,
+ supports_check_mode=True,
+ )
+
+ result = Acl_interfaces(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_acls.py b/ansible_collections/arista/eos/plugins/modules/eos_acls.py
new file mode 100644
index 000000000..95c961d5a
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_acls.py
@@ -0,0 +1,904 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_acls
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_acls
+short_description: ACLs resource module
+description: This module manages the IP access-list attributes of Arista EOS interfaces.
+version_added: 1.0.0
+author: Gomathiselvi S (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.6F
+options:
+ config:
+ description: A dictionary of IP access-list options
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description:
+ - The Address Family Indicator (AFI) for the Access Control Lists (ACL).
+ type: str
+ required: true
+ choices:
+ - ipv4
+ - ipv6
+ acls:
+ description:
+ - A list of Access Control Lists (ACL).
+ type: list
+ elements: dict
+ suboptions:
+ standard:
+ description: standard access-list or not
+ type: bool
+ name:
+ description: Name of the acl-list
+ type: str
+ required: true
+ aces:
+ description: Filtering data
+ type: list
+ elements: dict
+ suboptions:
+ sequence:
+ description: sequence number for the ordered list of rules
+ type: int
+ remark:
+ description: Specify a comment
+ type: str
+ fragment_rules:
+ description: Add fragment rules
+ type: bool
+ grant:
+ description: Action to be applied on the rule
+ type: str
+ choices:
+ - permit
+ - deny
+ line:
+ description: For fact gathering, any ACE that is not fully parsed,
+ while show up as a value of this attribute.
+ type: str
+ aliases:
+ - ace
+ protocol:
+ description:
+ - Specify the protocol to match.
+ - Refer to vendor documentation for valid values.
+ type: str
+ vlan:
+ description: Vlan options
+ type: str
+ protocol_options:
+ description: All the possible sub options for the protocol chosen.
+ type: dict
+ suboptions:
+ tcp:
+ description: Options for tcp protocol.
+ type: dict
+ suboptions:
+ flags:
+ description: Match TCP packet flags
+ type: dict
+ suboptions:
+ ack:
+ description: Match on the ACK bit
+ type: bool
+ established:
+ description: Match established connections
+ type: bool
+ fin:
+ description: Match on the FIN bit
+ type: bool
+ psh:
+ description: Match on the PSH bit
+ type: bool
+ rst:
+ description: Match on the RST bit
+ type: bool
+ syn:
+ description: Match on the SYN bit
+ type: bool
+ urg:
+ description: Match on the URG bit
+ type: bool
+ icmp:
+ description:
+ - Internet Control Message Protocol settings.
+ type: dict
+ suboptions:
+ administratively_prohibited:
+ description: Administratively prohibited
+ type: bool
+ alternate_address:
+ description: Alternate address
+ type: bool
+ conversion_error:
+ description: Datagram conversion
+ type: bool
+ dod_host_prohibited:
+ description: Host prohibited
+ type: bool
+ dod_net_prohibited:
+ description: Net prohibited
+ type: bool
+ echo:
+ description: Echo (ping)
+ type: bool
+ echo_reply:
+ description: Echo reply
+ type: bool
+ general_parameter_problem:
+ description: Parameter problem
+ type: bool
+ host_isolated:
+ description: Host isolated
+ type: bool
+ host_precedence_unreachable:
+ description: Host unreachable for precedence
+ type: bool
+ host_redirect:
+ description: Host redirect
+ type: bool
+ host_tos_redirect:
+ description: Host redirect for TOS
+ type: bool
+ host_tos_unreachable:
+ description: Host unreachable for TOS
+ type: bool
+ host_unknown:
+ description: Host unknown
+ type: bool
+ host_unreachable:
+ description: Host unreachable
+ type: bool
+ information_reply:
+ description: Information replies
+ type: bool
+ information_request:
+ description: Information requests
+ type: bool
+ mask_reply:
+ description: Mask replies
+ type: bool
+ mask_request:
+ description: Mask requests
+ type: bool
+ message_code:
+ description: ICMP message code
+ type: int
+ message_type:
+ description: ICMP message type
+ type: int
+ mobile_redirect:
+ description: Mobile host redirect
+ type: bool
+ net_redirect:
+ description: Network redirect
+ type: bool
+ net_tos_redirect:
+ description: Net redirect for TOS
+ type: bool
+ net_tos_unreachable:
+ description: Network unreachable for TOS
+ type: bool
+ net_unreachable:
+ description: Net unreachable
+ type: bool
+ network_unknown:
+ description: Network unknown
+ type: bool
+ no_room_for_option:
+ description: Parameter required but no room
+ type: bool
+ option_missing:
+ description: Parameter required but not present
+ type: bool
+ packet_too_big:
+ description: Fragmentation needed and DF set
+ type: bool
+ parameter_problem:
+ description: All parameter problems
+ type: bool
+ port_unreachable:
+ description: Port unreachable
+ type: bool
+ precedence_unreachable:
+ description: Precedence cutoff
+ type: bool
+ protocol_unreachable:
+ description: Protocol unreachable
+ type: bool
+ reassembly_timeout:
+ description: Reassembly timeout
+ type: bool
+ redirect:
+ description: All redirects
+ type: bool
+ router_advertisement:
+ description: Router discovery advertisements
+ type: bool
+ router_solicitation:
+ description: Router discovery solicitations
+ type: bool
+ source_quench:
+ description: Source quenches
+ type: bool
+ source_route_failed:
+ description: Source route failed
+ type: bool
+ time_exceeded:
+ description: All time exceededs
+ type: bool
+ timestamp_reply:
+ description: Timestamp replies
+ type: bool
+ timestamp_request:
+ description: Timestamp requests
+ type: bool
+ traceroute:
+ description: Traceroute
+ type: bool
+ ttl_exceeded:
+ description: TTL exceeded
+ type: bool
+ unreachable:
+ description: All unreachables
+ type: bool
+ message_num:
+ description: icmp msg type number.
+ type: int
+ icmpv6:
+ description: Options for icmpv6.
+ type: dict
+ suboptions:
+ address_unreachable:
+ description: address unreachable
+ type: bool
+ beyond_scope:
+ description: beyond_scope
+ type: bool
+ echo_reply:
+ description: echo_reply
+ type: bool
+ echo_request:
+ description: echo reques
+ type: bool
+ erroneous_header:
+ description: erroneous header
+ type: bool
+ fragment_reassembly_exceeded:
+ description: fragment_reassembly_exceeded
+ type: bool
+ hop_limit_exceeded:
+ description: hop limit exceeded
+ type: bool
+ neighbor_advertisement:
+ description: neighbor advertisement
+ type: bool
+ neighbor_solicitation:
+ description: neighbor_solicitation
+ type: bool
+ no_admin:
+ description: no admin
+ type: bool
+ no_route:
+ description: no route
+ type: bool
+ packet_too_big:
+ description: packet too big
+ type: bool
+ parameter_problem:
+ description: parameter problem
+ type: bool
+ port_unreachable:
+ description: port unreachable
+ type: bool
+ redirect_message:
+ description: redirect message
+ type: bool
+ reject_route:
+ description: reject route
+ type: bool
+ router_advertisement:
+ description: router_advertisement
+ type: bool
+ router_solicitation:
+ description: router_solicitation
+ type: bool
+ source_address_failed:
+ description: source_address_failed
+ type: bool
+ source_routing_error:
+ description: source_routing_error
+ type: bool
+ time_exceeded:
+ description: time_exceeded
+ type: bool
+ unreachable:
+ description: unreachable
+ type: bool
+ unrecognized_ipv6_option:
+ description: unrecognized_ipv6_option
+ type: bool
+ unrecognized_next_header:
+ description: unrecognized_next_header
+ type: bool
+ ip:
+ description: Internet Protocol.
+ type: dict
+ suboptions:
+ nexthop_group:
+ description: Nexthop-group name.
+ type: str
+ ipv6:
+ description: Internet V6 Protocol.
+ type: dict
+ suboptions:
+ nexthop_group:
+ description: Nexthop-group name.
+ type: str
+ source:
+ description: The packet's source address
+ type: dict
+ suboptions:
+ address:
+ description: dotted decimal notation of IP address
+ type: str
+ wildcard_bits:
+ description: Source wildcard bits
+ type: str
+ subnet_address:
+ description: A subnet address
+ type: str
+ host:
+ description: Host IP address
+ type: str
+ any:
+ description: Rule matches all source addresses
+ type: bool
+ port_protocol:
+ description: Specify source port/protocoli, along with operator.
+ (comes with tcp/udp).
+ type: dict
+ destination:
+ description: The packet's destination address
+ type: dict
+ suboptions:
+ address:
+ description: dotted decimal notation of IP address
+ type: str
+ wildcard_bits:
+ description: Source wildcard bits
+ type: str
+ subnet_address:
+ description: A subnet address
+ type: str
+ host:
+ description: Host IP address
+ type: str
+ any:
+ description: Rule matches all source addresses
+ type: bool
+ port_protocol:
+ description: Specify dest port/protocol, along with operator .
+ (comes with tcp/udp).
+ type: dict
+ ttl:
+ description: Compares the TTL (time-to-live) value in the packet to
+ a specified value
+ type: dict
+ suboptions:
+ eq:
+ description: Match a single TTL value
+ type: int
+ lt:
+ description: Match TTL lesser than this number
+ type: int
+ gt:
+ description: Match TTL greater than this number
+ type: int
+ neq:
+ description: Match TTL not equal to this value
+ type: int
+ fragments:
+ description: Match non-head fragment packets
+ type: bool
+ log:
+ description: Log matches against this rule
+ type: bool
+ tracked:
+ description: Match packets in existing ICMP/UDP/TCP connections
+ type: bool
+ hop_limit:
+ description: Hop limit value.
+ type: dict
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section access-list).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices:
+ - deleted
+ - merged
+ - overridden
+ - replaced
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+
+"""
+EXAMPLES = """
+# Using merged
+
+# Before state:
+# -------------
+# show running-config | section access-list
+# ip access-list test1
+# 10 permit ip 10.10.10.0/24 any ttl eq 200
+# 20 permit ip 10.30.10.0/24 host 10.20.10.1
+# 30 deny tcp host 10.10.20.1 eq finger www any syn log
+# 40 permit ip any any
+# ipv6 access-list test2
+# 10 deny icmpv6 any any reject-route hop-limit eq 20
+
+- name: Merge provided configuration with device configuration
+ arista.eos.eos_acls:
+ config:
+ - afi: ipv4
+ acls:
+ - name: test1
+ aces:
+ - sequence: 35
+ grant: deny
+ protocol: ospf
+ source:
+ subnet_address: 20.0.0.0/8
+ destination:
+ any: true
+ state: merged
+
+# After state:
+# ------------
+#
+# show running-config | section access-list
+# ip access-list test1
+# 10 permit ip 10.10.10.0/24 any ttl eq 200
+# 20 permit ip 10.30.10.0/24 host 10.20.10.1
+# 30 deny tcp host 10.10.20.1 eq finger www any syn log
+# 35 deny ospf 20.0.0.0/8 any
+# 40 permit ip any any
+# ipv6 access-list test2
+# 10 deny icmpv6 any any reject-route hop-limit eq 20
+
+# Using merged
+
+# Before state:
+# -------------
+# show running-config | section access-list
+# ip access-list test1
+# 10 permit ip 10.10.10.0/24 any ttl eq 200
+# 20 permit ip 10.30.10.0/24 host 10.20.10.1
+# 30 deny tcp host 10.10.20.1 eq finger www any syn log
+# 40 permit ip any any
+# ipv6 access-list test2
+# 10 deny icmpv6 any any reject-route hop-limit eq 20
+
+- name: Merge to update the given configuration with an existing ace
+ arista.eos.eos_acls:
+ config:
+ - afi: ipv4
+ acls:
+ - name: test1
+ aces:
+ - sequence: 35
+ log: true
+ ttl:
+ eq: 33
+ state: merged
+
+# After state:
+# ------------
+#
+# show running-config | section access-list
+# ip access-list test1
+# 10 permit ip 10.10.10.0/24 any ttl eq 200
+# 20 permit ip 10.30.10.0/24 host 10.20.10.1
+# 30 deny tcp host 10.10.20.1 eq finger www any syn log
+# 35 deny ospf 20.0.0.0/8 any ttl eq 33 log
+# 40 permit ip any any
+# ipv6 access-list test2
+# 10 deny icmpv6 any any reject-route hop-limit eq 20
+
+# Using replaced
+
+# Before state:
+# -------------
+# show running-config | section access-list
+# ip access-list test1
+# 10 permit ip 10.10.10.0/24 any ttl eq 200
+# 20 permit ip 10.30.10.0/24 host 10.20.10.1
+# 30 deny tcp host 10.10.20.1 eq finger www any syn log
+# 40 permit ip any any
+# !
+# ip access-list test3
+# 10 permit ip 35.33.0.0/16 any log
+# !
+# ipv6 access-list test2
+# 10 deny icmpv6 any any reject-route hop-limit eq 20
+
+
+
+- name: Replace device configuration with provided configuration
+ arista.eos.eos_acls:
+ config:
+ - afi: ipv4
+ acls:
+ - name: test1
+ aces:
+ - sequence: 35
+ grant: permit
+ protocol: ospf
+ source:
+ subnet_address: 20.0.0.0/8
+ destination:
+ any: true
+ state: replaced
+
+# After state:
+# ------------
+#
+# show running-config | section access-list
+# ip access-list test1
+# 35 permit ospf 20.0.0.0/8 any
+# !
+# ip access-list test3
+# 10 permit ip 35.33.0.0/16 any log
+# !
+# ipv6 access-list test2
+# 10 deny icmpv6 any any reject-route hop-limit eq 20
+
+
+# Using overridden
+
+# Before state:
+# -------------
+# show running-config | section access-list
+# ip access-list test1
+# 10 permit ip 10.10.10.0/24 any ttl eq 200
+# 20 permit ip 10.30.10.0/24 host 10.20.10.1
+# 30 deny tcp host 10.10.20.1 eq finger www any syn log
+# 40 permit ip any any
+# !
+# ip access-list test3
+# 10 permit ip 35.33.0.0/16 any log
+# !
+# ipv6 access-list test2
+# 10 deny icmpv6 any any reject-route hop-limit eq 20
+
+
+
+- name: override device configuration with provided configuration
+ arista.eos.eos_acls:
+ config:
+ - afi: ipv4
+ acls:
+ - name: test1
+ aces:
+ - sequence: 35
+ grant: permit
+ protocol: ospf
+ source:
+ subnet_address: 20.0.0.0/8
+ destination:
+ any: true
+ state: overridden
+
+# After state:
+# ------------
+#
+# show running-config | section access-list
+# ip access-list test1
+# 35 permit ospf 20.0.0.0/8 any
+# !
+
+# Using deleted:
+
+# Before state:
+# -------------
+# show running-config | section access-list
+# ip access-list test1
+# 10 permit ip 10.10.10.0/24 any ttl eq 200
+# 20 permit ip 10.30.10.0/24 host 10.20.10.1
+# 30 deny tcp host 10.10.20.1 eq finger www any syn log
+# 40 permit ip any any
+# ipv6 access-list test2
+# 10 deny icmpv6 any any reject-route hop-limit eq 20
+
+# !
+
+- name: Delete provided configuration
+ arista.eos.eos_acls:
+ config:
+ - afi: ipv4
+ acls:
+ - name: test1
+ state: deleted
+
+# After state:
+# ------------
+#
+# show running-config | section access-list
+
+# ipv6 access-list test2
+# 10 deny icmpv6 any any reject-route hop-limit eq 20
+
+
+# using gathered
+
+# ip access-list test1
+# 35 deny ospf 20.0.0.0/8 any
+# ip access-list test2
+# 40 permit vlan 55 0xE2 icmpv6 any any log
+
+- name: Gather the existing configuration
+ arista.eos.eos_acls:
+ state: gathered
+
+# returns:
+
+
+# arista.eos.eos_acls:
+# config:
+# - afi: "ipv4"
+# acls:
+# - name: test1
+# aces:
+# - sequence: 35
+# grant: "deny"
+# protocol: "ospf"
+# source:
+# subnet_address: 20.0.0.0/8
+# destination:
+# any: true
+# - afi: "ipv6"
+# acls:
+# - name: test2
+# aces:
+# - sequence: 40
+# grant: "permit"
+# vlan: "55 0xE2"
+# protocol: "icmpv6"
+# log: true
+# source:
+# any: true
+# destination:
+# any: true
+
+
+# using rendered
+
+- name: Delete provided configuration
+ arista.eos.eos_acls:
+ config:
+ - afi: ipv4
+ acls:
+ - name: test1
+ aces:
+ - sequence: 35
+ grant: deny
+ protocol: ospf
+ source:
+ subnet_address: 20.0.0.0/8
+ destination:
+ any: true
+ - afi: ipv6
+ acls:
+ - name: test2
+ aces:
+ - sequence: 40
+ grant: permit
+ vlan: 55 0xE2
+ protocol: icmpv6
+ log: true
+ source:
+ any: true
+ destination:
+ any: true
+ state: rendered
+
+# returns:
+
+# ip access-list test1
+# 35 deny ospf 20.0.0.0/8 any
+# ip access-list test2
+# 40 permit vlan 55 0xE2 icmpv6 any any log
+
+
+# Using Parsed
+
+# parsed_acls.cfg
+
+# ipv6 access-list standard test2
+# 10 permit any log
+# !
+# ip access-list test1
+# 35 deny ospf 20.0.0.0/8 any
+# 45 remark Run by ansible
+# 55 permit tcp any any
+# !
+
+- name: parse configs
+ arista.eos.eos_acls:
+ running_config: "{{ lookup('file', './parsed_acls.cfg') }}"
+ state: parsed
+
+# returns
+# "parsed": [
+# {
+# "acls": [
+# {
+# "aces": [
+# {
+# "destination": {
+# "any": true
+# },
+# "grant": "deny",
+# "protocol": "ospf",
+# "sequence": 35,
+# "source": {
+# "subnet_address": "20.0.0.0/8"
+# }
+# },
+# {
+# "remark": "Run by ansible",
+# "sequence": 45
+# },
+# {
+# "destination": {
+# "any": true
+# },
+# "grant": "permit",
+# "protocol": "tcp",
+# "sequence": 55,
+# "source": {
+# "any": true
+# }
+# }
+# ],
+# "name": "test1"
+# }
+# ],
+# "afi": "ipv4"
+# },
+# {
+# "acls": [
+# {
+# "aces": [
+# {
+# "grant": "permit",
+# "log": true,
+# "sequence": 10,
+# "source": {
+# "any": true
+# }
+# }
+# ],
+# "name": "test2",
+# "standard": true
+# }
+# ],
+# "afi": "ipv6"
+# }
+# ]
+
+"""
+RETURN = """
+before:
+ description: The configuration prior to the model invocation.
+ returned: always
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+after:
+ description: The resulting configuration model invocation.
+ returned: when changed
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample:
+ - ipv6 access-list standard test2
+ - 10 permit any log
+ - ip access-list test1
+ - 35 deny ospf 20.0.0.0/8 any
+ - 45 remark Run by ansible
+ - 55 permit tcp any any
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.acls.acls import (
+ AclsArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.acls.acls import (
+ Acls,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+
+ module = AnsibleModule(
+ argument_spec=AclsArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = Acls(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_banner.py b/ansible_collections/arista/eos/plugins/modules/eos_banner.py
new file mode 100644
index 000000000..19a187c4c
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_banner.py
@@ -0,0 +1,199 @@
+#!/usr/bin/python
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_banner
+author: Peter Sprygada (@privateip)
+short_description: Manage multiline banners on Arista EOS devices
+description:
+- This will configure both login and motd banners on remote devices running Arista
+ EOS. It allows playbooks to add or remote banner text from the active running configuration.
+version_added: 1.0.0
+notes:
+- Tested against Arista EOS 4.24.6F
+options:
+ banner:
+ description:
+ - Specifies which banner that should be configured on the remote device.
+ required: true
+ choices:
+ - login
+ - motd
+ type: str
+ text:
+ description:
+ - The banner text that should be present in the remote device running configuration. This
+ argument accepts a multiline string. Requires I(state=present).
+ type: str
+ state:
+ description:
+ - Specifies whether or not the configuration is present in the current devices
+ active running configuration.
+ default: present
+ type: str
+ choices:
+ - present
+ - absent
+"""
+
+EXAMPLES = """
+- name: configure the login banner
+ arista.eos.eos_banner:
+ banner: login
+ text: |
+ this is my login banner
+ that contains a multiline
+ string
+ state: present
+
+- name: remove the motd banner
+ arista.eos.eos_banner:
+ banner: motd
+ state: absent
+"""
+
+RETURN = """
+commands:
+ description: The list of configuration mode commands to send to the device
+ returned: always
+ type: list
+ sample:
+ - banner login
+ - this is my login banner
+ - that contains a multiline
+ - string
+ - EOF
+session_name:
+ description: The EOS config session name used to load the configuration
+ returned: if changes
+ type: str
+ sample: ansible_1479315771
+"""
+from ansible.module_utils._text import to_text
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.six import string_types
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.eos import (
+ load_config,
+ run_commands,
+)
+
+
+def map_obj_to_commands(updates, module):
+ commands = list()
+ want, have = updates
+ state = module.params["state"]
+
+ if state == "absent" and have.get("text"):
+ if isinstance(have["text"], string_types):
+ commands.append("no banner %s" % module.params["banner"])
+ elif have["text"].get("loginBanner") or have["text"].get("motd"):
+ commands.append({"cmd": "no banner %s" % module.params["banner"]})
+
+ elif state == "present":
+ if isinstance(have["text"], string_types):
+ if want["text"] != have["text"]:
+ commands.append("banner %s" % module.params["banner"])
+ commands.extend(want["text"].strip().split("\n"))
+ commands.append("EOF")
+ else:
+ have_text = have["text"].get("loginBanner") or have["text"].get(
+ "motd",
+ )
+ if have_text:
+ have_text = have_text.strip()
+
+ if to_text(want["text"]) != have_text or not have_text:
+ # For EAPI we need to construct a dict with cmd/input
+ # key/values for the banner
+ commands.append(
+ {
+ "cmd": "banner %s" % module.params["banner"],
+ "input": want["text"].strip("\n"),
+ },
+ )
+
+ return commands
+
+
+def map_config_to_obj(module):
+ output = run_commands(module, ["show banner %s" % module.params["banner"]])
+ obj = {"banner": module.params["banner"], "state": "absent"}
+ if output:
+ obj["text"] = output[0]
+ obj["state"] = "present"
+ return obj
+
+
+def map_params_to_obj(module):
+ text = module.params["text"]
+ if text:
+ text = to_text(text).strip()
+
+ return {
+ "banner": module.params["banner"],
+ "text": text,
+ "state": module.params["state"],
+ }
+
+
+def main():
+ """main entry point for module execution"""
+ argument_spec = dict(
+ banner=dict(required=True, choices=["login", "motd"]),
+ text=dict(),
+ state=dict(default="present", choices=["present", "absent"]),
+ )
+
+ required_if = [("state", "present", ("text",))]
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ )
+
+ warnings = list()
+
+ result = {"changed": False}
+ if warnings:
+ result["warnings"] = warnings
+ want = map_params_to_obj(module)
+ have = map_config_to_obj(module)
+
+ 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_bgp.py b/ansible_collections/arista/eos/plugins/modules/eos_bgp.py
new file mode 100644
index 000000000..a9d01d60a
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_bgp.py
@@ -0,0 +1,469 @@
+#!/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: yes
+ default_originate: true
+ - neighbor: 192.0.2.15
+ activate: yes
+ 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_bgp_address_family.py b/ansible_collections/arista/eos/plugins/modules/eos_bgp_address_family.py
new file mode 100644
index 000000000..67aaabef7
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_bgp_address_family.py
@@ -0,0 +1,1351 @@
+#!/usr/bin/python
+# -*- 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)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_bgp_address_family
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: eos_bgp_address_family
+short_description: Manages BGP address family resource module
+description: This module configures and manages the attributes of BGP AF on Arista
+ EOS platforms.
+version_added: 1.4.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,eos_platform_options).
+options:
+ config:
+ description: Configurations for BGP address family.
+ type: dict
+ suboptions:
+ as_number:
+ description: Autonomous system number.
+ type: str
+ address_family: &address_family
+ description: Enable address family and enter its config mode
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description: address family.
+ type: str
+ choices: ['ipv4', 'ipv6', 'evpn']
+ safi:
+ description: Address family type for ipv4.
+ type: str
+ choices: ['labeled-unicast', 'multicast']
+ bgp_params:
+ description: BGP parameters.
+ type: dict
+ suboptions:
+ additional_paths:
+ description: BGP additional-paths commands
+ type: str
+ choices: ['install', 'send', 'receive']
+ next_hop_address_family:
+ description: Next-hop address-family configuration
+ type: str
+ choices: ['ipv6']
+ next_hop_unchanged:
+ description: Preserve original nexthop while advertising routes to
+ eBGP peers.
+ type: bool
+ redistribute_internal:
+ description: Redistribute internal BGP routes.
+ type: bool
+ route:
+ description: Configure route-map for route installation.
+ type: str
+ graceful_restart:
+ description: Enable graceful restart mode.
+ type: bool
+ neighbor:
+ description: Configure routing for a network.
+ type: list
+ elements: dict
+ suboptions:
+ peer:
+ type: str
+ description: Neighbor address/ peer group name.
+ activate:
+ description: Activate neighbor in the address family.
+ type: bool
+ additional_paths:
+ description: BGP additional-paths commands.
+ type: str
+ choices: ['send', 'receive']
+ default_originate:
+ description: Originate default route to this neighbor.
+ type: dict
+ suboptions:
+ route_map:
+ description: Route map reference.
+ type: str
+ always:
+ description: Always originate default route to this neighbor.
+ type: bool
+ graceful_restart:
+ description: Enable graceful restart mode.
+ type: bool
+ next_hop_address_family:
+ description: Next-hop address-family configuration
+ type: str
+ choices: ['ipv6']
+ next_hop_unchanged:
+ description: Preserve original nexthop while advertising routes to
+ eBGP peers.
+ type: bool
+ prefix_list:
+ description: Prefix list reference.
+ type: dict
+ suboptions:
+ direction:
+ description: Configure an inbound/outbound prefix-list.
+ type: str
+ choices: ['in', 'out']
+ name:
+ description: prefix list name.
+ type: str
+ route_map:
+ description: Route map reference.
+ type: dict
+ suboptions:
+ direction:
+ description: Configure an inbound/outbound route-map.
+ type: str
+ choices: ['in', 'out']
+ name:
+ description: Route map name.
+ type: str
+ weight:
+ description: Weight to assign.
+ type: int
+ encapsulation:
+ description: Default transport encapsulation for neighbor. Applicable for evpn address-family.
+ type: dict
+ suboptions:
+ transport:
+ description: MPLS/VXLAN transport.
+ type: str
+ choices: ['mpls', 'vxlan']
+ source_interface:
+ description: Source interface to update BGP next hop address. Applicable for mpls transport.
+ type: str
+ network:
+ description: configure routing for network.
+ type: list
+ elements: dict
+ suboptions:
+ route_map:
+ description: Route map reference.
+ type: str
+ address:
+ description: network address.
+ type: str
+ redistribute:
+ description: Redistribute routes in to BGP.
+ type: list
+ elements: dict
+ suboptions:
+ protocol:
+ description: Routes to be redistributed.
+ type: str
+ choices: ['isis', 'ospfv3', 'dhcp']
+ route_map:
+ description: Route map reference.
+ type: str
+ isis_level:
+ description: Applicable for isis routes. Specify isis route level.
+ type: str
+ choices: ['level-1', 'level-2', 'level-1-2']
+ ospf_route:
+ description: ospf route options.
+ type: str
+ choices: ['internal', 'external', 'nssa_external_1', 'nssa_external_2']
+ route_target:
+ description: Route target.
+ type: dict
+ suboptions:
+ action:
+ description: Route action.
+ type: str
+ choices: ['both', 'import', 'export']
+ type:
+ description: Type of address fmaily
+ type: str
+ choices: ['evpn', 'vpn-ipv4', 'vpn-ipv6']
+ aliases: ['mode']
+ route_map:
+ description: Name of a route map.
+ type: str
+ target:
+ description: Route Target.
+ type: str
+ imported_route:
+ description: Export routes imported from the same Afi/Safi
+ type: bool
+ vrf:
+ description: name of the VRF in which BGP will be configured.
+ type: str
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section bgp).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices: [deleted, merged, overridden, replaced, gathered, rendered, parsed]
+ default: merged
+
+"""
+
+EXAMPLES = """
+
+# Using merged
+
+# Before state
+
+# veos(config)#show running-config | section bgp
+# veos(config)#
+
+ - name: Merge provided configuration with device configuration
+ arista.eos.eos_bgp_address_family:
+ config:
+ as_number: "10"
+ address_family:
+ - afi: "ipv4"
+ redistribute:
+ - protocol: "ospfv3"
+ ospf_route: "external"
+ network:
+ - address: "1.1.1.0/24"
+ - address: "1.5.1.0/24"
+ route_map: "MAP01"
+ - afi: "ipv6"
+ bgp_params:
+ additional_paths: "receive"
+ neighbor:
+ - peer: "peer2"
+ default_originate:
+ always: True
+ - afi: "ipv6"
+ redistribute:
+ - protocol: "isis"
+ isis_level: "level-2"
+ route_target:
+ mode: "export"
+ target: "33:11"
+ vrf: "vrft"
+ state: merged
+
+# After state:
+
+# veos(config-router-bgp)#show running-config | section bgp
+# router bgp 10
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# neighbor 1.1.1.1 maximum-routes 12000
+# !
+# address-family ipv4
+# neighbor 1.1.1.1 activate
+# network 1.1.1.0/24
+# network 1.5.1.0/24 route-map MAP01
+# redistribute ospfv3 match external
+# !
+# address-family ipv6
+# bgp additional-paths receive
+# neighbor peer2 activate
+# neighbor peer2 default-originate always
+# !
+# vrf vrft
+# address-family ipv6
+# route-target export 33:11
+# redistribute isis level-2
+# veos(config-router-bgp)#
+
+# Module Execution:
+
+# "after": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "redistribute": [
+# {
+# "isis_level": "level-2",
+# "protocol": "isis"
+# }
+# ],
+# "route_target": {
+# "mode": "export",
+# "target": "33:11"
+# },
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# },
+# "before": {},
+# "changed": true,
+# "commands": [
+# "router bgp 10",
+# "address-family ipv4",
+# "redistribute ospfv3 match external",
+# "network 1.1.1.0/24",
+# "network 1.5.1.0/24 route-map MAP01",
+# "exit",
+# "address-family ipv6",
+# "neighbor peer2 default-originate always",
+# "bgp additional-paths receive",
+# "exit",
+# "vrf vrft",
+# "address-family ipv6",
+# "redistribute isis level-2",
+# "route-target export 33:11",
+# "exit",
+# "exit"
+# ],
+
+# Using replaced:
+
+# Before State:
+
+# veos(config-router-bgp)#show running-config | section bgp
+# router bgp 10
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# neighbor 1.1.1.1 maximum-routes 12000
+# !
+# address-family ipv4
+# neighbor 1.1.1.1 activate
+# network 1.1.1.0/24
+# network 1.5.1.0/24 route-map MAP01
+# redistribute ospfv3 match external
+# !
+# address-family ipv6
+# bgp additional-paths receive
+# neighbor peer2 activate
+# neighbor peer2 default-originate always
+# !
+# vrf vrft
+# address-family ipv6
+# route-target export 33:11
+# redistribute isis level-2
+# veos(config-router-bgp)#
+#
+
+ - name: Replace
+ arista.eos.eos_bgp_address_family:
+ config:
+ as_number: "10"
+ address_family:
+ - afi: "ipv6"
+ vrf: "vrft"
+ redistribute:
+ - protocol: "ospfv3"
+ ospf_route: "external"
+ - afi: "ipv6"
+ redistribute:
+ - protocol: "isis"
+ isis_level: "level-2"
+ state: replaced
+
+# After State:
+
+# veos(config-router-bgp)#show running-config | section bgp
+# router bgp 10
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# neighbor 1.1.1.1 maximum-routes 12000
+# !
+# address-family ipv4
+# neighbor 1.1.1.1 activate
+# network 1.1.1.0/24
+# network 1.5.1.0/24 route-map MAP01
+# redistribute ospfv3 match external
+# !
+# address-family ipv6
+# neighbor peer2 default-originate always
+# redistribute isis level-2
+# !
+# vrf vrft
+# address-family ipv6
+# redistribute ospfv3 match external
+# veos(config-router-bgp)#
+#
+#
+# # Module Execution:
+#
+# "after": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "neighbor": [
+# {
+# "activate": true,
+# "peer": "1.1.1.1"
+# }
+# ],
+# "network": [
+# {
+# "address": "1.1.1.0/24"
+# },
+# {
+# "address": "1.5.1.0/24",
+# "route_map": "MAP01"
+# }
+# ],
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ],
+# "redistribute": [
+# {
+# "isis_level": "level-2",
+# "protocol": "isis"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ],
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# },
+# "before": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "neighbor": [
+# {
+# "activate": true,
+# "peer": "1.1.1.1"
+# }
+# ],
+# "network": [
+# {
+# "address": "1.1.1.0/24"
+# },
+# {
+# "address": "1.5.1.0/24",
+# "route_map": "MAP01"
+# }
+# ],
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "activate": true,
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "redistribute": [
+# {
+# "isis_level": "level-2",
+# "protocol": "isis"
+# }
+# ],
+# "route_target": {
+# "mode": "export",
+# "target": "33:11"
+# },
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# },
+# "changed": true,
+# "commands": [
+# "router bgp 10",
+# "vrf vrft",
+# "address-family ipv6",
+# "redistribute ospfv3 match external",
+# "no redistribute isis level-2",
+# "no route-target export 33:11",
+# "exit",
+# "exit",
+# "address-family ipv6",
+# "redistribute isis level-2",
+# "no neighbor peer2 activate",
+# "no bgp additional-paths receive",
+# "exit"
+# ],
+
+# Using overridden (overriding af at global context):
+# Before state:
+
+# veos(config-router-bgp)#show running-config | section bgp
+# router bgp 10
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# neighbor 1.1.1.1 maximum-routes 12000
+# !
+# address-family ipv4
+# neighbor 1.1.1.1 activate
+# network 1.1.1.0/24
+# network 1.5.1.0/24 route-map MAP01
+# redistribute ospfv3 match external
+# !
+# address-family ipv6
+# neighbor peer2 default-originate always
+# redistribute isis level-2
+# !
+# vrf vrft
+# address-family ipv6
+# redistribute ospfv3 match external
+# veos(config-router-bgp)#
+
+ - name: Overridden
+ arista.eos.eos_bgp_address_family:
+ config:
+ as_number: "10"
+ address_family:
+ - afi: "ipv4"
+ bgp_params:
+ additional_paths: "receive"
+ neighbor:
+ - peer: "peer2"
+ default_originate:
+ always: True
+ state: overridden
+
+# After State:
+# veos(config-router-bgp)#show running-config | section bgp
+# router bgp 10
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# neighbor 1.1.1.1 maximum-routes 12000
+# !
+# address-family ipv4
+# bgp additional-paths receive
+# neighbor peer2 default-originate always
+# !
+# vrf vrft
+# address-family ipv6
+# redistribute ospfv3 match external
+# veos(config-router-bgp)#
+#
+# Module Execution:
+#
+# "after": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ],
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# },
+# "before": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "neighbor": [
+# {
+# "activate": true,
+# "peer": "1.1.1.1"
+# }
+# ],
+# "network": [
+# {
+# "address": "1.1.1.0/24"
+# },
+# {
+# "address": "1.5.1.0/24",
+# "route_map": "MAP01"
+# }
+# ],
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ],
+# "redistribute": [
+# {
+# "isis_level": "level-2",
+# "protocol": "isis"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ],
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# },
+# "changed": true,
+# "commands": [
+# "router bgp 10",
+# "address-family ipv4",
+# "no redistribute ospfv3 match external",
+# "no network 1.1.1.0/24",
+# "no network 1.5.1.0/24 route-map MAP01",
+# "neighbor peer2 default-originate always",
+# "no neighbor 1.1.1.1 activate",
+# "bgp additional-paths receive",
+# "exit",
+# "no address-family ipv6"
+# ],
+
+# using Overridden (overridding af in vrf context):
+
+# Before State:
+
+# veos(config-router-bgp)#show running-config | section bgp
+# router bgp 10
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# neighbor 1.1.1.1 maximum-routes 12000
+# !
+# address-family ipv4
+# bgp additional-paths receive
+# neighbor peer2 default-originate always
+# no neighbor 1.1.1.1 activate
+# network 1.1.1.0/24
+# network 1.5.1.0/24 route-map MAP01
+# redistribute ospfv3 match external
+# !
+# address-family ipv6
+# bgp additional-paths receive
+# neighbor peer2 default-originate always
+# !
+# vrf vrft
+# address-family ipv6
+# route-target export 33:11
+# redistribute isis level-2
+# redistribute ospfv3 match external
+# veos(config-router-bgp)#
+
+
+ - name: Overridden
+ arista.eos.eos_bgp_address_family:
+ config:
+ as_number: "10"
+ address_family:
+ - afi: "ipv4"
+ bgp_params:
+ additional_paths: "receive"
+ neighbor:
+ - peer: "peer2"
+ default_originate:
+ always: True
+ vrf: vrft
+ state: overridden
+
+# After State:
+
+# veos(config-router-bgp)#show running-config | section bgp
+# router bgp 10
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# neighbor 1.1.1.1 maximum-routes 12000
+# !
+# address-family ipv4
+# bgp additional-paths receive
+# neighbor peer2 default-originate always
+# network 1.1.1.0/24
+# network 1.5.1.0/24 route-map MAP01
+# redistribute ospfv3 match external
+# !
+# address-family ipv6
+# bgp additional-paths receive
+# neighbor peer2 default-originate always
+# !
+# vrf vrft
+# address-family ipv4
+# bgp additional-paths receive
+# veos(config-router-bgp)#
+#
+# Module Execution:
+#
+# "after": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ],
+# "network": [
+# {
+# "address": "1.1.1.0/24"
+# },
+# {
+# "address": "1.5.1.0/24",
+# "route_map": "MAP01"
+# }
+# ],
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ]
+# },
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# },
+# "before": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ],
+# "network": [
+# {
+# "address": "1.1.1.0/24"
+# },
+# {
+# "address": "1.5.1.0/24",
+# "route_map": "MAP01"
+# }
+# ],
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "redistribute": [
+# {
+# "isis_level": "level-2",
+# "protocol": "isis"
+# },
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ],
+# "route_target": {
+# "mode": "export",
+# "target": "33:11"
+# },
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# },
+# "changed": true,
+# "commands": [
+# "router bgp 10",
+# "vrf vrft",
+# "address-family ipv4",
+# "neighbor peer2 default-originate always",
+# "bgp additional-paths receive",
+# "exit",
+# "exit",
+# " vrf vrft",
+# "no address-family ipv6"
+# ],
+
+# Using Deleted:
+
+# veos(config-router-bgp)#show running-config | section bgp
+# router bgp 10
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# neighbor 1.1.1.1 maximum-routes 12000
+# !
+# address-family ipv4
+# bgp additional-paths receive
+# neighbor peer2 default-originate always
+# no neighbor 1.1.1.1 activate
+# network 1.1.1.0/24
+# network 1.5.1.0/24 route-map MAP01
+# redistribute ospfv3 match external
+# !
+# address-family ipv6
+# bgp additional-paths receive
+# neighbor peer2 default-originate always
+# !
+# vrf vrft
+# address-family ipv4
+# bgp additional-paths receive
+# veos(config-router-bgp)#
+
+ - name: Delete
+ arista.eos.eos_bgp_address_family:
+ config:
+ as_number: "10"
+ address_family:
+ - afi: "ipv6"
+ vrf: "vrft"
+ - afi: "ipv6"
+ state: deleted
+
+# After State:
+
+# veos(config-router-bgp)#show running-config | section bgp
+# router bgp 10
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# neighbor 1.1.1.1 maximum-routes 12000
+# !
+# address-family ipv4
+# bgp additional-paths receive
+# neighbor peer2 default-originate always
+# no neighbor 1.1.1.1 activate
+# network 1.1.1.0/24
+# network 1.5.1.0/24 route-map MAP01
+# redistribute ospfv3 match external
+# !
+# vrf vrft
+# address-family ipv4
+# bgp additional-paths receive
+# veos(config-router-bgp)#
+#
+# Module Execution:
+#
+# "after": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ],
+# "network": [
+# {
+# "address": "1.1.1.0/24"
+# },
+# {
+# "address": "1.5.1.0/24",
+# "route_map": "MAP01"
+# }
+# ],
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ]
+# },
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# },
+# "before": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ],
+# "network": [
+# {
+# "address": "1.1.1.0/24"
+# },
+# {
+# "address": "1.5.1.0/24",
+# "route_map": "MAP01"
+# }
+# ],
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ]
+# },
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# },
+
+# Using parsed:
+
+# parsed_bgp_address_family.cfg :
+
+# router bgp 10
+# neighbor n2 peer group
+# neighbor n2 next-hop-unchanged
+# neighbor n2 maximum-routes 12000
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# network 1.1.1.0/24
+# network 1.5.1.0/24 route-map MAP01
+# !
+# address-family ipv4
+# bgp additional-paths receive
+# neighbor peer2 default-originate always
+# redistribute ospfv3 match external
+# !
+# address-family ipv6
+# no bgp additional-paths receive
+# neighbor n2 next-hop-unchanged
+# redistribute isis level-2
+# !
+# vrf bgp_10
+# ip access-group acl01
+# ucmp fec threshold trigger 33 clear 22 warning-only
+# !
+# address-family ipv4
+# route-target import 20:11
+# !
+# vrf vrft
+# address-family ipv4
+# bgp additional-paths receive
+# !
+# address-family ipv6
+# redistribute ospfv3 match external
+
+ - name: parse configs
+ arista.eos.eos_bgp_address_family:
+ running_config: "{{ lookup('file', './parsed_bgp_address_family.cfg') }}"
+ state: parsed
+
+# Module Execution:
+# "parsed": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ],
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "neighbor": [
+# {
+# "next_hop_unchanged": true,
+# "peer": "n2"
+# }
+# ],
+# "redistribute": [
+# {
+# "isis_level": "level-2",
+# "protocol": "isis"
+# }
+# ]
+# },
+# {
+# "afi": "ipv4",
+# "route_target": {
+# "mode": "import",
+# "target": "20:11"
+# },
+# "vrf": "bgp_10"
+# },
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "vrf": "vrft"
+# },
+# {
+# "afi": "ipv6",
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ],
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# }
+# }
+
+# Using gathered:
+
+# Device config:
+# veos(config-router-bgp)#show running-config | section bgp
+# router bgp 10
+# neighbor peer2 peer group
+# neighbor peer2 maximum-routes 12000
+# neighbor 1.1.1.1 maximum-routes 12000
+# !
+# address-family ipv4
+# bgp additional-paths receive
+# neighbor peer2 default-originate always
+# no neighbor 1.1.1.1 activate
+# network 1.1.1.0/24
+# network 1.5.1.0/24 route-map MAP01
+# redistribute ospfv3 match external
+# !
+# vrf vrft
+# address-family ipv4
+# bgp additional-paths receive
+# veos(config-router-bgp)#
+
+ - name: gather configs
+ arista.eos.eos_bgp_address_family:
+ state: gathered
+
+# Module Execution:
+# "gathered": {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "neighbor": [
+# {
+# "default_originate": {
+# "always": true
+# },
+# "peer": "peer2"
+# }
+# ],
+# "network": [
+# {
+# "address": "1.1.1.0/24"
+# },
+# {
+# "address": "1.5.1.0/24",
+# "route_map": "MAP01"
+# }
+# ],
+# "redistribute": [
+# {
+# "ospf_route": "external",
+# "protocol": "ospfv3"
+# }
+# ]
+# },
+# {
+# "afi": "ipv4",
+# "bgp_params": {
+# "additional_paths": "receive"
+# },
+# "vrf": "vrft"
+# }
+# ],
+# "as_number": "10"
+# },
+
+# using rendered:
+
+ - name: Render
+ arista.eos.eos_bgp_address_family:
+ config:
+ as_number: "10"
+ address_family:
+ - afi: "ipv4"
+ redistribute:
+ - protocol: "ospfv3"
+ ospf_route: "external"
+ network:
+ - address: "1.1.1.0/24"
+ - address: "1.5.1.0/24"
+ route_map: "MAP01"
+ - afi: "ipv6"
+ bgp_params:
+ additional_paths: "receive"
+ neighbor:
+ - peer: "peer2"
+ default_originate:
+ always: True
+ - afi: "ipv6"
+ redistribute:
+ - protocol: "isis"
+ isis_level: "level-2"
+ route_target:
+ mode: "export"
+ target: "33:11"
+ vrf: "vrft"
+
+ state: rendered
+
+# Module Execution:
+
+# "rendered": [
+# "router bgp 10",
+# "address-family ipv4",
+# "redistribute ospfv3 match external",
+# "network 1.1.1.0/24",
+# "network 1.5.1.0/24 route-map MAP01",
+# "exit",
+# "address-family ipv6",
+# "neighbor peer2 default-originate always",
+# "bgp additional-paths receive",
+# "exit",
+# "vrf vrft",
+# "address-family ipv6",
+# "redistribute isis level-2",
+# "route-target export 33:11",
+# "exit",
+# "exit"
+# ]
+#
+
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.bgp_address_family.bgp_address_family import (
+ Bgp_afArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.bgp_address_family.bgp_address_family import (
+ Bgp_af,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Bgp_afArgs.argument_spec,
+ mutually_exclusive=[["config", "running_config"]],
+ required_if=[
+ ["state", "merged", ["config"]],
+ ["state", "replaced", ["config"]],
+ ["state", "overridden", ["config"]],
+ ["state", "rendered", ["config"]],
+ ["state", "parsed", ["running_config"]],
+ ],
+ supports_check_mode=True,
+ )
+
+ result = Bgp_af(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_bgp_global.py b/ansible_collections/arista/eos/plugins/modules/eos_bgp_global.py
new file mode 100644
index 000000000..06168db54
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_bgp_global.py
@@ -0,0 +1,2353 @@
+#!/usr/bin/python
+# -*- 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)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_bgp_global
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: eos_bgp_global
+short_description: Manages BGP global resource module
+description: This module configures and manages the attributes of BGP global on Arista
+ EOS platforms.
+version_added: 1.4.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,eos_platform_options).
+options:
+ config:
+ description: A list of configurations for BGP global.
+ type: dict
+ suboptions:
+ as_number:
+ description: Autonomous system number.
+ type: str
+ aggregate_address:
+ description: Configure aggregate address.
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description: ipv4/ipv6 address prefix.
+ type: str
+ advertise_only:
+ description: Advertise without installing the generated blackhole route in
+ FIB.
+ type: bool
+ as_set:
+ description: Generate autonomous system set path information.
+ type: bool
+ attribute_map:
+ description: Name of the route map used to set the attribute of the
+ aggregate route.
+ type: str
+ match_map:
+ description: Name of the route map used to filter the contributors of the
+ aggregate route.
+ type: str
+ summary_only:
+ description: Filters all more-specific routes from updates.
+ type: bool
+ bgp_params:
+ description: BGP parameters.
+ type: dict
+ suboptions:
+ additional_paths:
+ description: BGP additional-paths commands
+ type: str
+ choices: ['install', 'send', 'receive']
+ advertise_inactive:
+ description: Advertise BGP routes even if they are inactive in RIB.
+ type: bool
+ allowas_in:
+ description: Allow local-as in updates.
+ type: dict
+ suboptions:
+ set:
+ description: When True, it is set.
+ type: bool
+ count:
+ description: Number of local ASNs allowed in a BGP update.
+ type: int
+ always_compare_med:
+ description: BGP Always Compare MED
+ type: bool
+ asn:
+ description: AS Number notation.
+ type: str
+ choices: ['asdot', 'asplain']
+ auto_local_addr:
+ description: Automatically determine the local address to be used
+ for the non-transport AF.
+ type: bool
+ bestpath:
+ description: Select the bestpath selection algorithim for BGP routes.
+ type: dict
+ suboptions:
+ as_path:
+ description: Select the bestpath selection based on as-path.
+ type: str
+ choices: ['ignore', 'multipath_relax']
+ ecmp_fast:
+ description: Tie-break BGP paths in a ECMP group based on the order of arrival.
+ type: bool
+ med:
+ description: MED attribute
+ type: dict
+ suboptions:
+ confed:
+ description: MED Confed.
+ type: bool
+ missing_as_worst:
+ description: MED missing-as-worst.
+ type: bool
+ skip:
+ description: skip one of the tie breaking rules in the bestpath selection.
+ type: bool
+ tie_break:
+ description: Configure the tie-break option for BGP bestpath selection.
+ choices: ['cluster_list_length', 'router_id']
+ type: str
+ client_to_client:
+ description: client to client configuration.
+ type: bool
+ cluster_id:
+ description: Cluster ID of this router acting as a route reflector.
+ type: str
+ confederation:
+ description: confederation.
+ type: dict
+ suboptions:
+ identifier:
+ description: Confederation identifier.
+ type: str
+ peers:
+ description: Confederation peers.
+ type: str
+ control_plane_filter:
+ description: Control plane filter for BGP.
+ type: bool
+ convergence:
+ description: Bgp convergence parameters.
+ type: dict
+ suboptions:
+ slow_peer:
+ description: Maximum amount of time to wait for slow peers to estabilsh session.
+ type: bool
+ time:
+ description: time in secs
+ type: int
+ default:
+ description: Default neighbor configuration commands.
+ type: str
+ choices: ['ipv4_unicast', 'ipv6_unicast']
+ enforce_first_as:
+ description: Enforce the First AS for EBGP routes(default).
+ type: bool
+ host_routes:
+ description: BGP host routes configuration.
+ type: bool
+ labeled_unicast:
+ description: Labeled Unicast.
+ type: str
+ choices: ['ip', 'tunnel']
+ listen:
+ description: BGP listen.
+ type: dict
+ suboptions:
+ limit:
+ description: Set limit on the number of dynamic BGP peers allowed.
+ type: int
+ range:
+ description: Subnet Range to be associated with the peer group.
+ type: dict
+ suboptions:
+ address:
+ description: Address prefix
+ type: str
+ peer_group:
+ description: Name of peer group.
+ type: dict
+ suboptions:
+ name:
+ description: name.
+ type: str
+ peer_filter:
+ description: Name of peer filter.
+ type: str
+ remote_as:
+ description: Neighbor AS number
+ type: str
+ log_neighbor_changes:
+ description: Log neighbor up/down events.
+ type: bool
+ missing_policy:
+ description: Missing policy override configuration commands.
+ type: dict
+ suboptions:
+ direction:
+ description: Missing policy direction options.
+ type: str
+ choices: ['in', 'out']
+ action:
+ description: Missing policy action options.
+ type: str
+ choices: ['deny', 'permit', 'deny-in-out']
+ monitoring:
+ description: Enable Bgp monitoring for all/specified stations.
+ type: bool
+ next_hop_unchanged:
+ description: Preserve original nexthop while advertising routes to
+ eBGP peers.
+ type: bool
+ redistribute_internal:
+ description: Redistribute internal BGP routes.
+ type: bool
+ route:
+ description: Configure route-map for route installation.
+ type: str
+ route_reflector:
+ description: Configure route reflector options
+ type: dict
+ suboptions:
+ set:
+ description: When True route_reflector is set.
+ type: bool
+ preserve:
+ description: preserve route attributes, overwriting route-map changes
+ type: bool
+ transport:
+ description: Configure transport port for TCP session
+ type: int
+ default_metric:
+ description: Default metric.
+ type: int
+ distance:
+ description: Define an administrative distance.
+ type: dict
+ suboptions:
+ external:
+ description: distance for external routes.
+ type: int
+ internal:
+ description: distance for internal routes.
+ type: int
+ local:
+ description: distance for local routes.
+ type: int
+ graceful_restart:
+ description: Enable graceful restart mode.
+ type: dict
+ suboptions:
+ set:
+ description: When True, graceful restart is set.
+ type: bool
+ restart_time:
+ description: Set the max time needed to restart and come back up.
+ type: int
+ stalepath_time:
+ description: Set the max time to hold onto restarting peer stale paths.
+ type: int
+ graceful_restart_helper:
+ description: Enable graceful restart helper mode.
+ type: bool
+ access_group:
+ description: ip/ipv6 access list configuration.
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description: Specify ip/ipv6.
+ type: str
+ choices: ['ipv4', 'ipv6']
+ acl_name:
+ description: access list name.
+ type: str
+ direction:
+ description: direction of packets.
+ type: str
+ maximum_paths:
+ description: Maximum number of equal cost paths.
+ type: dict
+ suboptions:
+ max_equal_cost_paths:
+ description: Value for maximum number of equal cost paths.
+ type: int
+ max_installed_ecmp_paths:
+ description: Value for maximum number of installed ECMP routes.
+ type: int
+ monitoring:
+ description: BGP monitoring protocol configuration.
+ type: dict
+ suboptions:
+ port:
+ description: Configure the BGP monitoring protocol port number <1024-65535>.
+ type: int
+ received:
+ description: BGP monitoring protocol received route selection.
+ type: str
+ choices: ['post_policy', 'pre_policy']
+ station:
+ description: BGP monitoring station configuration.
+ type: str
+ timestamp:
+ description: BGP monitoring protocol Per-Peer Header timestamp behavior.
+ type: str
+ choices: ['none', 'send_time']
+ neighbor:
+ description: Configure routing for a network.
+ type: list
+ elements: dict
+ suboptions:
+ neighbor_address:
+ type: str
+ description: Neighbor address or peer group.
+ aliases:
+ - peer
+ additional_paths:
+ description: BGP additional-paths commands.
+ type: str
+ choices: ['send', 'receive']
+ allowas_in:
+ description: Allow local-as in updates.
+ type: dict
+ suboptions:
+ set:
+ description: When True, it is set.
+ type: bool
+ count:
+ description: Number of local ASNs allowed in a BGP update.
+ type: int
+ auto_local_addr:
+ description: Automatically determine the local address to be used
+ for the non-transport AF.
+ type: bool
+ bfd:
+ description: Configure BFD fallover for this peer
+ type: str
+ choices: ['enable', 'c_bit']
+ default_originate:
+ description: Originate default route to this neighbor.
+ type: dict
+ suboptions:
+ route_map:
+ description: Route map reference.
+ type: str
+ always:
+ description: Always originate default route to this neighbor.
+ type: bool
+ description:
+ description: Text describing the neighbor.
+ type: str
+ dont_capability_negotiate:
+ description: Donot perform Capability Negotiation with this
+ neighbor.
+ type: bool
+ ebgp_multihop:
+ description: Allow BGP connections to indirectly connected
+ external peers.
+ type: dict
+ suboptions:
+ ttl:
+ description: Time-to-live in the range 1-255 hops.
+ type: int
+ set:
+ description: If True, ttl is not set.
+ type: bool
+ enforce_first_as:
+ description: Enforce the First AS for EBGP routes(default).
+ type: bool
+ export_localpref:
+ description: Override localpref when exporting to an internal
+ peer.
+ type: int
+ fall_over:
+ description: Configure BFD protocol options for this peer.
+ type: bool
+ graceful_restart:
+ description: Enable graceful restart mode.
+ type: bool
+ graceful_restart_helper:
+ description: Enable graceful restart helper mode.
+ type: bool
+ idle_restart_timer:
+ description: Neighbor idle restart timer.
+ type: int
+ import_localpref:
+ description: Override localpref when importing from an external
+ peer.
+ type: int
+ link_bandwidth:
+ description: Enable link bandwidth community for routes to this
+ peer.
+ type: dict
+ suboptions:
+ set:
+ description: If True, set link bandwidth
+ type: bool
+ auto:
+ description: Enable link bandwidth auto generation for routes from this peer.
+ type: bool
+ default:
+ description: Enable link bandwidth default generation for routes from this
+ peer.
+ type: str
+ update_delay:
+ description: Delay outbound route updates.
+ type: int
+ local_as:
+ description: Configure local AS number advertised to peer.
+ type: dict
+ suboptions:
+ as_number:
+ description: AS number.
+ type: str
+ fallback:
+ description: Prefer router AS Number over local AS Number.
+ type: bool
+ local_v6_addr:
+ description: The local IPv6 address of the neighbor in A:B:C:D:E:F:G:H format.
+ type: str
+ maximum_accepted_routes:
+ description: Maximum number of routes accepted from this peer.
+ type: dict
+ suboptions:
+ count:
+ description: Maximum number of accepted routes (0 means unlimited).
+ type: int
+ warning_limit:
+ description: Maximum number of accepted routes after which a warning is issued.
+ (0 means never warn)
+ type: int
+ maximum_received_routes:
+ description: Maximum number of routes received from this peer.
+ type: dict
+ suboptions:
+ count:
+ description: Maximum number of routes (0 means unlimited).
+ type: int
+ warning_limit:
+ description: Percentage of maximum-routes at which warning is to be issued.
+ type: dict
+ suboptions:
+ limit_count:
+ description: Number of routes at which to warn.
+ type: int
+ limit_percent:
+ description: Percentage of maximum number of routes at which to warn( 1-100).
+ type: int
+ warning_only:
+ description: Only warn, no restart, if max route limit exceeded.
+ type: bool
+ metric_out:
+ description: MED value to advertise to peer.
+ type: int
+ monitoring:
+ description: Enable BGP Monitoring Protocol for this peer.
+ type: bool
+ next_hop_self:
+ description: Always advertise this router address as the BGP
+ next hop
+ type: bool
+ next_hop_unchanged:
+ description: Preserve original nexthop while advertising routes to
+ eBGP peers.
+ type: bool
+ next_hop_v6_address:
+ description: IPv6 next-hop address for the neighbor
+ type: str
+ out_delay:
+ description: Delay outbound route updates.
+ type: int
+ encryption_password:
+ description: Password to use in computation of MD5 hash.
+ type: dict
+ suboptions:
+ type:
+ description: Encryption type.
+ type: int
+ choices: [0, 7]
+ password:
+ description: password (up to 80 chars).
+ type: str
+ remote_as:
+ description: Neighbor Autonomous System.
+ type: str
+ remove_private_as:
+ description: Remove private AS number from updates to this peer.
+ type: dict
+ suboptions:
+ set:
+ description: If True, set remove_private_as.
+ type: bool
+ all:
+ description: Remove private AS number.
+ type: bool
+ replace_as:
+ description: Replace private AS number with local AS number.
+ type: bool
+ peer_group:
+ description: Name of the peer group.
+ type: str
+
+ prefix_list:
+ description: Prefix list reference.
+ type: dict
+ suboptions:
+ direction:
+ description: Configure an inbound/outbound prefix-list.
+ type: str
+ choices: ['in', 'out']
+ name:
+ description: prefix list name.
+ type: str
+ route_map:
+ description: Route map reference.
+ type: dict
+ suboptions:
+ direction:
+ description: Configure an inbound/outbound route-map.
+ type: str
+ choices: ['in', 'out']
+ name:
+ description: Route map name.
+ type: str
+ route_reflector_client:
+ description: Configure peer as a route reflector client.
+ type: bool
+ route_to_peer:
+ description: Use routing table information to reach the peer.
+ type: bool
+ send_community:
+ description: Send community attribute to this neighbor.
+ type: dict
+ suboptions:
+ set:
+ description: Enable send-community
+ type: bool
+ community_attribute:
+ description: Type of community attributes to send to this neighbor.
+ type: str
+ sub_attribute:
+ description: Attribute to be sent to the neighbor.
+ type: str
+ choices: ['extended', 'link-bandwidth', 'standard']
+ link_bandwidth_attribute:
+ description: cumulative/aggregate attribute to be sent.
+ type: str
+ choices: ['aggregate', 'divide']
+ speed:
+ description: Reference link speed in bits/second
+ type: str
+ divide:
+ description: link-bandwidth divide attribute.
+ type: str
+ choices: ['equal', 'ratio']
+ shutdown:
+ description: Administratively shut down this neighbor.
+ type: bool
+ soft_recognition:
+ description: Configure how to handle routes that fail import.
+ type: str
+ choices: ['all', 'None']
+ timers:
+ description: Timers.
+ type: dict
+ suboptions:
+ keepalive:
+ description: Keep Alive Interval in secs.
+ type: int
+ holdtime:
+ description: Hold time in secs.
+ type: int
+ transport:
+ description: Configure transport options for TCP session.
+ type: dict
+ suboptions:
+ connection_mode:
+ description: Configure connection-mode for TCP session.
+ type: str
+ remote_port:
+ description: Configure BGP peer TCP port to connect to.
+ type: int
+ ttl:
+ description: BGP ttl security check
+ type: int
+ update_source:
+ description: Specify the local source interface for peer BGP
+ sessions.
+ type: str
+ weight:
+ description: Weight to assign.
+ type: int
+ aliases:
+ - neighbors
+ network:
+ description: Configure routing for a network.
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description: address prefix.
+ type: str
+ route_map:
+ description: Name of route map.
+ type: str
+ aliases:
+ - networks
+ redistribute:
+ description: Redistribute routes in to BGP.
+ type: list
+ elements: dict
+ suboptions:
+ protocol:
+ description: Routes to be redistributed.
+ type: str
+ choices: ['isis', 'ospfv3', 'ospf', 'attached-host', 'connected', 'rip', 'static']
+ route_map:
+ description: Route map reference.
+ type: str
+ isis_level:
+ description: Applicable for isis routes. Specify isis route level.
+ type: str
+ choices: ['level-1', 'level-2', 'level-1-2']
+ ospf_route:
+ description: ospf route options.
+ type: str
+ choices: ['internal', 'external', 'nssa_external_1', 'nssa_external_2']
+ router_id:
+ description: Router id.
+ type: str
+ route_target:
+ description: Route target.
+ type: dict
+ suboptions:
+ action:
+ description: Route action.
+ type: str
+ choices: ['both', 'import', 'export']
+ target:
+ description: Route Target.
+ type: str
+ shutdown:
+ description: When True, shut down BGP.
+ type: bool
+ timers:
+ description: Timers.
+ type: dict
+ suboptions:
+ keepalive:
+ description: Keep Alive Interval in secs.
+ type: int
+ holdtime:
+ description: Hold time in secs.
+ type: int
+ ucmp:
+ description: Configure unequal cost multipathing.
+ type: dict
+ suboptions:
+ fec:
+ description: Configure UCMP fec utilization threshold.
+ type: dict
+ suboptions:
+ trigger:
+ description: UCMP fec utilization too high threshold.
+ type: int
+ clear:
+ description: UCMP FEC utilization Clear thresholds.
+ type: int
+ link_bandwidth:
+ description: Configure link-bandwidth propagation delay.
+ type: dict
+ suboptions:
+ mode:
+ description: UCMP link bandwidth mode
+ type: str
+ choices: ['encoding_weighted', 'recursive']
+ update_delay:
+ description: Link Bandwidth Advertisement delay.
+ type: int
+ mode:
+ description: UCMP mode.
+ type: dict
+ suboptions:
+ set:
+ description: If True, ucmp mode is set to 1.
+ type: bool
+ nexthops:
+ description: Value for total number UCMP nexthops.
+ type: int
+ update:
+ description: Configure BGP update generation.
+ type: dict
+ suboptions:
+ wait_for:
+ description: wait for options before converge or synchronize.
+ type: str
+ choices: ['wait_for_convergence', 'wait_install']
+ batch_size:
+ description: batch size for FIB route acknowledgements.
+ type: int
+ vlan:
+ description: Configure MAC VRF BGP for single VLAN support.
+ type: int
+ vlan_aware_bundle:
+ description: Configure MAC VRF BGP for multiple VLAN support.
+ type: str
+ vrfs:
+ description: Configure BGP in a VRF.
+ type: list
+ elements: dict
+ suboptions:
+ vrf:
+ description: VRF name.
+ type: str
+ aggregate_address:
+ description: Configure aggregate address.
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description: ipv4/ipv6 address prefix.
+ type: str
+ advertise_only:
+ description: Advertise without installing the generated blackhole route in
+ FIB.
+ type: bool
+ as_set:
+ description: Generate autonomous system set path information.
+ type: bool
+ attribute_map:
+ description: Name of the route map used to set the attribute of the
+ aggregate route.
+ type: str
+ match_map:
+ description: Name of the route map used to filter the contributors of the
+ aggregate route.
+ type: str
+ summary_only:
+ description: Filters all more-specific routes from updates.
+ type: bool
+ bgp_params:
+ description: BGP parameters.
+ type: dict
+ suboptions:
+ additional_paths:
+ description: BGP additional-paths commands
+ type: str
+ choices: ['install', 'send', 'receive']
+ advertise_inactive:
+ description: Advertise BGP routes even if they are inactive in RIB.
+ type: bool
+ allowas_in:
+ description: Allow local-as in updates.
+ type: dict
+ suboptions:
+ set:
+ description: When True, it is set.
+ type: bool
+ count:
+ description: Number of local ASNs allowed in a BGP update.
+ type: int
+ always_compare_med:
+ description: BGP Always Compare MED
+ type: bool
+ asn:
+ description: AS Number notation.
+ type: str
+ choices: ['asdot', 'asplain']
+ auto_local_addr:
+ description: Automatically determine the local address to be used
+ for the non-transport AF.
+ type: bool
+ bestpath:
+ description: Select the bestpath selection algorithim for BGP routes.
+ type: dict
+ suboptions:
+ as_path:
+ description: Select the bestpath selection based on as-path.
+ type: str
+ choices: ['ignore', 'multipath_relax']
+ ecmp_fast:
+ description: Tie-break BGP paths in a ECMP group based on the order of arrival.
+ type: bool
+ med:
+ description: MED attribute
+ type: dict
+ suboptions:
+ confed:
+ description: MED Confed.
+ type: bool
+ missing_as_worst:
+ description: MED missing-as-worst.
+ type: bool
+ skip:
+ description: skip one of the tie breaking rules in the bestpath selection.
+ type: bool
+ tie_break:
+ description: Configure the tie-break option for BGP bestpath selection.
+ choices: ['cluster_list_length', 'router_id']
+ type: str
+ client_to_client:
+ description: client to client configuration.
+ type: bool
+ cluster_id:
+ description: Cluster ID of this router acting as a route reflector.
+ type: str
+ confederation:
+ description: confederation.
+ type: dict
+ suboptions:
+ identifier:
+ description: Confederation identifier.
+ type: str
+ peers:
+ description: Confederation peers.
+ type: str
+ control_plane_filter:
+ description: Control plane filter for BGP.
+ type: bool
+ convergence:
+ description: Bgp convergence parameters.
+ type: dict
+ suboptions:
+ slow_peer:
+ description: Maximum amount of time to wait for slow peers to estabilsh session.
+ type: bool
+ time:
+ description: time in secs
+ type: int
+ default:
+ description: Default neighbor configuration commands.
+ type: str
+ choices: ['ipv4_unicast', 'ipv6_unicast']
+ enforce_first_as:
+ description: Enforce the First AS for EBGP routes(default).
+ type: bool
+ host_routes:
+ description: BGP host routes configuration.
+ type: bool
+ labeled_unicast:
+ description: Labeled Unicast.
+ type: str
+ choices: ['ip', 'tunnel']
+ listen:
+ description: BGP listen.
+ type: dict
+ suboptions:
+ limit:
+ description: Set limit on the number of dynamic BGP peers allowed.
+ type: int
+ range:
+ description: Subnet Range to be associated with the peer group.
+ type: dict
+ suboptions:
+ address:
+ description: Address prefix
+ type: str
+ peer_group:
+ description: Name of peer group.
+ type: dict
+ suboptions:
+ name:
+ description: name.
+ type: str
+ peer_filter:
+ description: Name of peer filter.
+ type: str
+ remote_as:
+ description: Neighbor AS number
+ type: str
+ log_neighbor_changes:
+ description: Log neighbor up/down events.
+ type: bool
+ missing_policy:
+ description: Missing policy override configuration commands.
+ type: dict
+ suboptions:
+ direction:
+ description: Missing policy direction options.
+ type: str
+ choices: ['in', 'out']
+ action:
+ description: Missing policy action options.
+ type: str
+ choices: ['deny', 'permit', 'deny-in-out']
+ monitoring:
+ description: Enable Bgp monitoring for all/specified stations.
+ type: bool
+ next_hop_unchanged:
+ description: Preserve original nexthop while advertising routes to
+ eBGP peers.
+ type: bool
+ redistribute_internal:
+ description: Redistribute internal BGP routes.
+ type: bool
+ route:
+ description: Configure route-map for route installation.
+ type: str
+ route_reflector:
+ description: Configure route reflector options
+ type: dict
+ suboptions:
+ set:
+ description: When True route_reflector is set.
+ type: bool
+ preserve:
+ description: preserve route attributes, overwriting route-map changes
+ type: bool
+ transport:
+ description: Configure transport port for TCP session
+ type: int
+ default_metric:
+ description: Default metric.
+ type: int
+ distance:
+ description: Define an administrative distance.
+ type: dict
+ suboptions:
+ external:
+ description: distance for external routes.
+ type: int
+ internal:
+ description: distance for internal routes.
+ type: int
+ local:
+ description: distance for local routes.
+ type: int
+ graceful_restart:
+ description: Enable graceful restart mode.
+ type: dict
+ suboptions:
+ set:
+ description: When True, graceful restart is set.
+ type: bool
+ restart_time:
+ description: Set the max time needed to restart and come back up.
+ type: int
+ stalepath_time:
+ description: Set the max time to hold onto restarting peer stale paths.
+ type: int
+ graceful_restart_helper:
+ description: Enable graceful restart helper mode.
+ type: bool
+ access_group:
+ description: ip/ipv6 access list configuration.
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description: Specify ip/ipv6.
+ type: str
+ choices: ['ipv4', 'ipv6']
+ acl_name:
+ description: access list name.
+ type: str
+ direction:
+ description: direction of packets.
+ type: str
+ maximum_paths:
+ description: Maximum number of equal cost paths.
+ type: dict
+ suboptions:
+ max_equal_cost_paths:
+ description: Value for maximum number of equal cost paths.
+ type: int
+ max_installed_ecmp_paths:
+ description: Value for maximum number of installed ECMP routes.
+ type: int
+ neighbor:
+ description: Configure routing for a network.
+ aliases:
+ - neighbors
+ type: list
+ elements: dict
+ suboptions:
+ neighbor_address:
+ type: str
+ description: Neighbor address or peer group.
+ aliases: ["peer"]
+ additional_paths:
+ description: BGP additional-paths commands.
+ type: str
+ choices: ['send', 'receive']
+ allowas_in:
+ description: Allow local-as in updates.
+ type: dict
+ suboptions:
+ set:
+ description: When True, it is set.
+ type: bool
+ count:
+ description: Number of local ASNs allowed in a BGP update.
+ type: int
+ auto_local_addr:
+ description: Automatically determine the local address to be used
+ for the non-transport AF.
+ type: bool
+ bfd:
+ description: Configure BFD fallover for this peer
+ type: str
+ choices: ['enable', 'c_bit']
+ default_originate:
+ description: Originate default route to this neighbor.
+ type: dict
+ suboptions:
+ route_map:
+ description: Route map reference.
+ type: str
+ always:
+ description: Always originate default route to this neighbor.
+ type: bool
+ description:
+ description: Text describing the neighbor.
+ type: str
+ dont_capability_negotiate:
+ description: Donot perform Capability Negotiation with this
+ neighbor.
+ type: bool
+ ebgp_multihop:
+ description: Allow BGP connections to indirectly connected
+ external peers.
+ type: dict
+ suboptions:
+ ttl:
+ description: Time-to-live in the range 1-255 hops.
+ type: int
+ set:
+ description: If True, ttl is not set.
+ type: bool
+ enforce_first_as:
+ description: Enforce the First AS for EBGP routes(default).
+ type: bool
+ export_localpref:
+ description: Override localpref when exporting to an internal
+ peer.
+ type: int
+ fall_over:
+ description: Configure BFD protocol options for this peer.
+ type: bool
+ graceful_restart:
+ description: Enable graceful restart mode.
+ type: bool
+ graceful_restart_helper:
+ description: Enable graceful restart helper mode.
+ type: bool
+ idle_restart_timer:
+ description: Neighbor idle restart timer.
+ type: int
+ import_localpref:
+ description: Override localpref when importing from an external
+ peer.
+ type: int
+ link_bandwidth:
+ description: Enable link bandwidth community for routes to this
+ peer.
+ type: dict
+ suboptions:
+ set:
+ description: If True, set link bandwidth
+ type: bool
+ auto:
+ description: Enable link bandwidth auto generation for routes from this peer.
+ type: bool
+ default:
+ description: Enable link bandwidth default generation for routes from this
+ peer.
+ type: str
+ update_delay:
+ description: Delay outbound route updates.
+ type: int
+ local_as:
+ description: Configure local AS number advertised to peer.
+ type: dict
+ suboptions:
+ as_number:
+ description: AS number.
+ type: str
+ fallback:
+ description: Prefer router AS Number over local AS Number.
+ type: bool
+ local_v6_addr:
+ description: The local IPv6 address of the neighbor in A:B:C:D:E:F:G:H format.
+ type: str
+ maximum_accepted_routes:
+ description: Maximum number of routes accepted from this peer.
+ type: dict
+ suboptions:
+ count:
+ description: Maximum number of accepted routes (0 means unlimited).
+ type: int
+ warning_limit:
+ description: Maximum number of accepted routes after which a warning is issued.
+ (0 means never warn)
+ type: int
+ maximum_received_routes:
+ description: Maximum number of routes received from this peer.
+ type: dict
+ suboptions:
+ count:
+ description: Maximum number of routes (0 means unlimited).
+ type: int
+ warning_limit:
+ description: Percentage of maximum-routes at which warning is to be issued.
+ type: dict
+ suboptions:
+ limit_count:
+ description: Number of routes at which to warn.
+ type: int
+ limit_percent:
+ description: Percentage of maximum number of routes at which to warn( 1-100).
+ type: int
+ warning_only:
+ description: Only warn, no restart, if max route limit exceeded.
+ type: bool
+ metric_out:
+ description: MED value to advertise to peer.
+ type: int
+ monitoring:
+ description: Enable BGP Monitoring Protocol for this peer.
+ type: bool
+ next_hop_self:
+ description: Always advertise this router address as the BGP
+ next hop
+ type: bool
+ next_hop_unchanged:
+ description: Preserve original nexthop while advertising routes to
+ eBGP peers.
+ type: bool
+ next_hop_v6_address:
+ description: IPv6 next-hop address for the neighbor
+ type: str
+ out_delay:
+ description: Delay outbound route updates.
+ type: int
+ encryption_password:
+ description: Password to use in computation of MD5 hash.
+ type: dict
+ suboptions:
+ type:
+ description: Encryption type.
+ type: int
+ choices: [0, 7]
+ password:
+ description: password (up to 80 chars).
+ type: str
+ remote_as:
+ description: Neighbor Autonomous System.
+ type: str
+ remove_private_as:
+ description: Remove private AS number from updates to this peer.
+ type: dict
+ suboptions:
+ set:
+ description: If True, set remove_private_as.
+ type: bool
+ all:
+ description: Remove private AS number.
+ type: bool
+ replace_as:
+ description: Replace private AS number with local AS number.
+ type: bool
+ peer_group:
+ description: Name of the peer group.
+ type: str
+
+ prefix_list:
+ description: Prefix list reference.
+ type: dict
+ suboptions:
+ direction:
+ description: Configure an inbound/outbound prefix-list.
+ type: str
+ choices: ['in', 'out']
+ name:
+ description: prefix list name.
+ type: str
+ route_map:
+ description: Route map reference.
+ type: dict
+ suboptions:
+ direction:
+ description: Configure an inbound/outbound route-map.
+ type: str
+ choices: ['in', 'out']
+ name:
+ description: Route map name.
+ type: str
+ route_reflector_client:
+ description: Configure peer as a route reflector client.
+ type: bool
+ route_to_peer:
+ description: Use routing table information to reach the peer.
+ type: bool
+ send_community:
+ description: Send community attribute to this neighbor.
+ type: dict
+ suboptions:
+ community_attribute:
+ description: Type of community attributes to send to this neighbor.
+ type: str
+ sub_attribute:
+ description: Attribute to be sent to the neighbor.
+ type: str
+ choices: ['extended', 'link-bandwidth', 'standard']
+ link_bandwidth_attribute:
+ description: cumulative/aggregate attribute to be sent.
+ type: str
+ choices: ['aggregate', 'divide']
+ speed:
+ description: Reference link speed in bits/second
+ type: str
+ divide:
+ description: link-bandwidth divide attribute.
+ type: str
+ choices: ['equal', 'ratio']
+ shutdown:
+ description: Administratively shut down this neighbor.
+ type: bool
+ soft_recognition:
+ description: Configure how to handle routes that fail import.
+ type: str
+ choices: ['all', 'None']
+ timers:
+ description: Timers.
+ type: dict
+ suboptions:
+ keepalive:
+ description: Keep Alive Interval in secs.
+ type: int
+ holdtime:
+ description: Hold time in secs.
+ type: int
+ transport:
+ description: Configure transport options for TCP session.
+ type: dict
+ suboptions:
+ connection_mode:
+ description: Configure connection-mode for TCP session.
+ type: str
+ remote_port:
+ description: Configure BGP peer TCP port to connect to.
+ type: int
+ ttl:
+ description: BGP ttl security check
+ type: int
+ update_source:
+ description: Specify the local source interface for peer BGP
+ sessions.
+ type: str
+ weight:
+ description: Weight to assign.
+ type: int
+ network:
+ description: Configure routing for a network.
+ aliases:
+ - networks
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description: address prefix.
+ type: str
+ route_map:
+ description: Name of route map.
+ type: str
+ redistribute:
+ description: Redistribute routes in to BGP.
+ type: list
+ elements: dict
+ suboptions:
+ protocol:
+ description: Routes to be redistributed.
+ type: str
+ choices: ['isis', 'ospfv3', 'ospf', 'attached-host', 'connected', 'rip', 'static']
+ route_map:
+ description: Route map reference.
+ type: str
+ isis_level:
+ description: Applicable for isis routes. Specify isis route level.
+ type: str
+ choices: ['level-1', 'level-2', 'level-1-2']
+ ospf_route:
+ description: ospf route options.
+ type: str
+ choices: ['internal', 'external', 'nssa_external_1', 'nssa_external_2']
+ route_target:
+ description: Route target.
+ type: dict
+ suboptions:
+ action:
+ description: Route action.
+ type: str
+ choices: ['both', 'import', 'export']
+ type:
+ description: Type of address fmaily
+ type: str
+ choices: ['evpn', 'vpn-ipv4', 'vpn-ipv6']
+ route_map:
+ description: Name of a route map.
+ type: str
+ target:
+ description: Route Target.
+ type: str
+ imported_route:
+ description: Export routes imported from the same Afi/Safi.
+ type: bool
+ router_id:
+ description: Router id.
+ type: str
+ shutdown:
+ description: When True, shut down BGP.
+ type: bool
+ timers:
+ description: Timers.
+ type: dict
+ suboptions:
+ keepalive:
+ description: Keep Alive Interval in secs.
+ type: int
+ holdtime:
+ description: Hold time in secs.
+ type: int
+ ucmp:
+ description: Configure unequal cost multipathing.
+ type: dict
+ suboptions:
+ fec:
+ description: Configure UCMP fec utilization threshold.
+ type: dict
+ suboptions:
+ trigger:
+ description: UCMP fec utilization too high threshold.
+ type: int
+ clear:
+ description: UCMP FEC utilization Clear thresholds.
+ type: int
+ link_bandwidth:
+ description: Configure link-bandwidth propagation delay.
+ type: dict
+ suboptions:
+ mode:
+ description: UCMP link bandwidth mode
+ type: str
+ choices: ['encoding_weighted', 'recursive', 'update_delay']
+ update_delay:
+ description: Link Bandwidth Advertisement delay.
+ type: int
+ mode:
+ description: UCMP mode.
+ type: dict
+ suboptions:
+ set:
+ description: If True, ucmp mode is set to 1.
+ type: bool
+ nexthops:
+ description: Value for total number UCMP nexthops.
+ type: int
+ update:
+ description: Configure BGP update generation.
+ type: dict
+ suboptions:
+ wait_for:
+ description: wait for options before converge or synchronize.
+ type: str
+ choices: ['wait_for_convergence', 'wait_install']
+ batch_size:
+ description: batch size for FIB route acknowledgements.
+ type: int
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section bgp).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ - State I(purged) removes all the BGP configurations from the
+ target device. Use caution with this state.('no router bgp <x>')
+ - State I(deleted) only removes BGP attributes that this modules
+ manages and does not negate the BGP process completely. Thereby, preserving
+ address-family related configurations under BGP context.
+ - Running states I(deleted) and I(replaced) will result in an error if there
+ are address-family configuration lines present under vrf context that is
+ is to be removed. Please use the M(arista.eos.eos_bgp_address_family)
+ module for prior cleanup.
+ - Refer to examples for more details.
+ type: str
+ choices: [deleted, merged, purged, replaced, gathered, rendered, parsed]
+ default: merged
+"""
+EXAMPLES = """
+# Using merged
+# Before state
+
+# veos(config)#show running-config | section bgp
+# veos(config)#
+
+ - name: Merge provided configuration with device configuration
+ arista.eos.eos_bgp_global:
+ config:
+ as_number: "100"
+ bgp_params:
+ host_routes: True
+ convergence:
+ slow_peer: True
+ time: 6
+ additional_paths: "send"
+ log_neighbor_changes: True
+ maximum_paths:
+ max_equal_cost_paths: 55
+ aggregate_address:
+ - address: "1.2.1.0/24"
+ as_set: true
+ match_map: "match01"
+ - address: "5.2.1.0/24"
+ attribute_map: "attrmatch01"
+ advertise_only: true
+ redistribute:
+ - protocol: "static"
+ route_map: "map_static"
+ - protocol: "attached-host"
+ distance:
+ internal: 50
+ neighbor:
+ - peer: "10.1.3.2"
+ allowas_in:
+ set: true
+ default_originate:
+ always: true
+ dont_capability_negotiate: true
+ export_localpref: 4000
+ maximum_received_routes:
+ count: 500
+ warning_limit:
+ limit_percent: 5
+ next_hop_unchanged: true
+ prefix_list:
+ name: "prefix01"
+ direction: "out"
+ - neighbor_address: "peer1"
+ fall_over: true
+ link_bandwidth:
+ update_delay: 5
+ monitoring: True
+ send_community:
+ community_attribute: "extended"
+ sub_attribute: "link-bandwidth"
+ link_bandwidth_attribute: "aggregate"
+ speed: "600"
+ vlan: 5
+ state: merged
+
+# After State:
+# veos(config)#show running-config | section bgp
+# router bgp 100
+# bgp convergence slow-peer time 6
+# distance bgp 50 50 50
+# maximum-paths 55
+# bgp additional-paths send any
+# neighbor peer1 peer group
+# neighbor peer1 link-bandwidth update-delay 5
+# neighbor peer1 fall-over bfd
+# neighbor peer1 monitoring
+# neighbor peer1 send-community extended link-bandwidth aggregate 600
+# neighbor peer1 maximum-routes 12000
+# neighbor 10.1.3.2 export-localpref 4000
+# neighbor 10.1.3.2 next-hop-unchanged
+# neighbor 10.1.3.2 dont-capability-negotiate
+# neighbor 10.1.3.2 allowas-in 3
+# neighbor 10.1.3.2 default-originate always
+# neighbor 10.1.3.2 maximum-routes 500 warning-limit 5 percent
+# aggregate-address 1.2.1.0/24 as-set match-map match01
+# aggregate-address 5.2.1.0/24 attribute-map attrmatch01 advertise-only
+# redistribute static route-map map_static
+# redistribute attached-host
+# !
+# vlan 5
+# !
+# address-family ipv4
+# neighbor 10.1.3.2 prefix-list prefix01 out
+# veos(config)#
+#
+# Module Execution:
+#
+# "after": {
+# "aggregate_address": [
+# {
+# "address": "1.2.1.0/24",
+# "as_set": true,
+# "match_map": "match01"
+# },
+# {
+# "address": "5.2.1.0/24",
+# "advertise_only": true,
+# "attribute_map": "attrmatch01"
+# }
+# ],
+# "as_number": "100",
+# "bgp_params": {
+# "additional_paths": "send",
+# "convergence": {
+# "slow_peer": true,
+# "time": 6
+# }
+# },
+# "distance": {
+# "external": 50,
+# "internal": 50,
+# "local": 50
+# },
+# "maximum_paths": {
+# "max_equal_cost_paths": 55
+# },
+# "neighbor": [
+# {
+# "fall_over": true,
+# "link_bandwidth": {
+# "set": true,
+# "update_delay": 5
+# },
+# "maximum_received_routes": {
+# "count": 12000
+# },
+# "monitoring": true,
+# "peer": "peer1",
+# "peer_group": "peer1",
+# "send_community": {
+# "community_attribute": "extended",
+# "link_bandwidth_attribute": "aggregate",
+# "speed": "600",
+# "sub_attribute": "link-bandwidth"
+# }
+# },
+# {
+# "allowas_in": {
+# "count": 3
+# },
+# "default_originate": {
+# "always": true
+# },
+# "dont_capability_negotiate": true,
+# "export_localpref": 4000,
+# "maximum_received_routes": {
+# "count": 500,
+# "warning_limit": {
+# "limit_percent": 5
+# }
+# },
+# "next_hop_unchanged": true,
+# "peer": "10.1.3.2"
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "static",
+# "route_map": "map_static"
+# },
+# {
+# "protocol": "attached-host"
+# }
+# ],
+# "vlan": 5
+# },
+# "before": {},
+# "changed": true,
+# "commands": [
+# "router bgp 100",
+# "neighbor 10.1.3.2 allowas-in",
+# "neighbor 10.1.3.2 default-originate always",
+# "neighbor 10.1.3.2 dont-capability-negotiate",
+# "neighbor 10.1.3.2 export-localpref 4000",
+# "neighbor 10.1.3.2 maximum-routes 500 warning-limit 5 percent",
+# "neighbor 10.1.3.2 next-hop-unchanged",
+# "neighbor 10.1.3.2 prefix-list prefix01 out",
+# "neighbor peer1 fall-over bfd",
+# "neighbor peer1 link-bandwidth update-delay 5",
+# "neighbor peer1 monitoring",
+# "neighbor peer1 send-community extended link-bandwidth aggregate 600",
+# "redistribute static route-map map_static",
+# "redistribute attached-host",
+# "aggregate-address 1.2.1.0/24 as-set match-map match01",
+# "aggregate-address 5.2.1.0/24 attribute-map attrmatch01 advertise-only",
+# "bgp host-routes fib direct-install",
+# "bgp convergence slow-peer time 6",
+# "bgp additional-paths send any",
+# "bgp log-neighbor-changes",
+# "maximum-paths 55",
+# "distance bgp 50",
+# "vlan 5"
+# ],
+
+# Using replaced:
+
+# Before state:
+# veos(config)#show running-config | section bgp
+# router bgp 100
+# bgp convergence slow-peer time 6
+# distance bgp 50 50 50
+# maximum-paths 55
+# bgp additional-paths send any
+# neighbor peer1 peer group
+# neighbor peer1 link-bandwidth update-delay 5
+# neighbor peer1 fall-over bfd
+# neighbor peer1 monitoring
+# neighbor peer1 send-community extended link-bandwidth aggregate 600
+# neighbor peer1 maximum-routes 12000
+# neighbor 10.1.3.2 export-localpref 4000
+# neighbor 10.1.3.2 next-hop-unchanged
+# neighbor 10.1.3.2 dont-capability-negotiate
+# neighbor 10.1.3.2 allowas-in 3
+# neighbor 10.1.3.2 default-originate always
+# neighbor 10.1.3.2 maximum-routes 500 warning-limit 5 percent
+# aggregate-address 1.2.1.0/24 as-set match-map match01
+# aggregate-address 5.2.1.0/24 attribute-map attrmatch01 advertise-only
+# redistribute static route-map map_static
+# redistribute attached-host
+# !
+# vlan 5
+# !
+# address-family ipv4
+# neighbor 10.1.3.2 prefix-list prefix01 out
+# !
+# vrf vrf01
+# route-target import 54:11
+# neighbor 12.1.3.2 dont-capability-negotiate
+# neighbor 12.1.3.2 allowas-in 3
+# neighbor 12.1.3.2 default-originate always
+# neighbor 12.1.3.2 maximum-routes 12000
+# veos(config)#
+
+ - name: replace provided configuration with device configuration
+ arista.eos.eos_bgp_global:
+ config:
+ as_number: "100"
+ bgp_params:
+ host_routes: True
+ convergence:
+ slow_peer: True
+ time: 6
+ additional_paths: "send"
+ log_neighbor_changes: True
+ vrfs:
+ - vrf: "vrf01"
+ maximum_paths:
+ max_equal_cost_paths: 55
+ aggregate_address:
+ - address: "1.2.1.0/24"
+ as_set: true
+ match_map: "match01"
+ - address: "5.2.1.0/24"
+ attribute_map: "attrmatch01"
+ advertise_only: true
+ redistribute:
+ - protocol: "static"
+ route_map: "map_static"
+ - protocol: "attached-host"
+ distance:
+ internal: 50
+ neighbor:
+ - neighbor_address: "10.1.3.2"
+ allowas_in:
+ set: true
+ default_originate:
+ always: true
+ dont_capability_negotiate: true
+ export_localpref: 4000
+ maximum_received_routes:
+ count: 500
+ warning_limit:
+ limit_percent: 5
+ next_hop_unchanged: true
+ prefix_list:
+ name: "prefix01"
+ direction: "out"
+ - neighbor_address: "peer1"
+ fall_over: true
+ link_bandwidth:
+ update_delay: 5
+ monitoring: True
+ send_community:
+ community_attribute: "extended"
+ sub_attribute: "link-bandwidth"
+ link_bandwidth_attribute: "aggregate"
+ speed: "600"
+ state: replaced
+
+# After State:
+
+# veos(config)#show running-config | section bgp
+# router bgp 100
+# bgp convergence slow-peer time 6
+# bgp additional-paths send any
+# !
+# vrf vrf01
+# distance bgp 50 50 50
+# maximum-paths 55
+# neighbor 10.1.3.2 export-localpref 4000
+# neighbor 10.1.3.2 next-hop-unchanged
+# neighbor 10.1.3.2 dont-capability-negotiate
+# neighbor 10.1.3.2 allowas-in 3
+# neighbor 10.1.3.2 default-originate always
+# neighbor 10.1.3.2 maximum-routes 500 warning-limit 5 percent
+# aggregate-address 1.2.1.0/24 as-set match-map match01
+# aggregate-address 5.2.1.0/24 attribute-map attrmatch01 advertise-only
+# redistribute static route-map map_static
+# redistribute attached-host
+# !
+# address-family ipv4
+# neighbor 10.1.3.2 prefix-list prefix01 out
+# veos(config)#
+#
+#
+# Module Execution:
+#
+# "after": {
+# "as_number": "100",
+# "bgp_params": {
+# "additional_paths": "send",
+# "convergence": {
+# "slow_peer": true,
+# "time": 6
+# }
+# },
+# "vrfs": [
+# {
+# "aggregate_address": [
+# {
+# "address": "1.2.1.0/24",
+# "as_set": true,
+# "match_map": "match01"
+# },
+# {
+# "address": "5.2.1.0/24",
+# "advertise_only": true,
+# "attribute_map": "attrmatch01"
+# }
+# ],
+# "distance": {
+# "external": 50,
+# "internal": 50,
+# "local": 50
+# },
+# "maximum_paths": {
+# "max_equal_cost_paths": 55
+# },
+# "neighbor": [
+# {
+# "allowas_in": {
+# "count": 3
+# },
+# "default_originate": {
+# "always": true
+# },
+# "dont_capability_negotiate": true,
+# "export_localpref": 4000,
+# "maximum_received_routes": {
+# "count": 500,
+# "warning_limit": {
+# "limit_percent": 5
+# }
+# },
+# "next_hop_unchanged": true,
+# "peer": "10.1.3.2"
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "static",
+# "route_map": "map_static"
+# },
+# {
+# "protocol": "attached-host"
+# }
+# ],
+# "vrf": "vrf01"
+# }
+# ]
+# },
+# "before": {
+# "aggregate_address": [
+# {
+# "address": "1.2.1.0/24",
+# "as_set": true,
+# "match_map": "match01"
+# },
+# {
+# "address": "5.2.1.0/24",
+# "advertise_only": true,
+# "attribute_map": "attrmatch01"
+# }
+# ],
+# "as_number": "100",
+# "bgp_params": {
+# "additional_paths": "send",
+# "convergence": {
+# "slow_peer": true,
+# "time": 6
+# }
+# },
+# "distance": {
+# "external": 50,
+# "internal": 50,
+# "local": 50
+# },
+# "maximum_paths": {
+# "max_equal_cost_paths": 55
+# },
+# "neighbor": [
+# {
+# "fall_over": true,
+# "link_bandwidth": {
+# "set": true,
+# "update_delay": 5
+# },
+# "maximum_received_routes": {
+# "count": 12000
+# },
+# "monitoring": true,
+# "peer": "peer1",
+# "peer_group": "peer1",
+# "send_community": {
+# "community_attribute": "extended",
+# "link_bandwidth_attribute": "aggregate",
+# "speed": "600",
+# "sub_attribute": "link-bandwidth"
+# }
+# },
+# {
+# "allowas_in": {
+# "count": 3
+# },
+# "default_originate": {
+# "always": true
+# },
+# "dont_capability_negotiate": true,
+# "export_localpref": 4000,
+# "maximum_received_routes": {
+# "count": 500,
+# "warning_limit": {
+# "limit_percent": 5
+# }
+# },
+# "next_hop_unchanged": true,
+# "peer": "10.1.3.2"
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "static",
+# "route_map": "map_static"
+# },
+# {
+# "protocol": "attached-host"
+# }
+# ],
+# "vlan": 5,
+# "vrfs": [
+# {
+# "neighbor": [
+# {
+# "allowas_in": {
+# "count": 3
+# },
+# "default_originate": {
+# "always": true
+# },
+# "dont_capability_negotiate": true,
+# "maximum_received_routes": {
+# "count": 12000
+# },
+# "peer": "12.1.3.2"
+# }
+# ],
+# "route_target": {
+# "action": "import",
+# "target": "54:11"
+# },
+# "vrf": "vrf01"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "router bgp 100",
+# "vrf vrf01",
+# "no route-target import 54:11",
+# "neighbor 10.1.3.2 allowas-in",
+# "neighbor 10.1.3.2 default-originate always",
+# "neighbor 10.1.3.2 dont-capability-negotiate",
+# "neighbor 10.1.3.2 export-localpref 4000",
+# "neighbor 10.1.3.2 maximum-routes 500 warning-limit 5 percent",
+# "neighbor 10.1.3.2 next-hop-unchanged",
+# "neighbor 10.1.3.2 prefix-list prefix01 out",
+# "neighbor peer1 fall-over bfd",
+# "neighbor peer1 link-bandwidth update-delay 5",
+# "neighbor peer1 monitoring",
+# "neighbor peer1 send-community extended link-bandwidth aggregate 600",
+# "no neighbor 12.1.3.2",
+# "redistribute static route-map map_static",
+# "redistribute attached-host",
+# "aggregate-address 1.2.1.0/24 as-set match-map match01",
+# "aggregate-address 5.2.1.0/24 attribute-map attrmatch01 advertise-only",
+# "maximum-paths 55",
+# "distance bgp 50",
+# "exit",
+# "no neighbor peer1 peer group",
+# "no neighbor peer1 link-bandwidth update-delay 5",
+# "no neighbor peer1 fall-over bfd",
+# "no neighbor peer1 monitoring",
+# "no neighbor peer1 send-community extended link-bandwidth aggregate 600",
+# "no neighbor peer1 maximum-routes 12000",
+# "no neighbor 10.1.3.2",
+# "no redistribute static route-map map_static",
+# "no redistribute attached-host",
+# "no aggregate-address 1.2.1.0/24 as-set match-map match01",
+# "no aggregate-address 5.2.1.0/24 attribute-map attrmatch01 advertise-only",
+# "bgp host-routes fib direct-install",
+# "bgp log-neighbor-changes",
+# "no distance bgp 50 50 50",
+# "no maximum-paths 55",
+# "no vlan 5"
+# ],
+#
+
+# Using replaced (in presence of address_family under vrf):
+# Before State:
+
+#veos(config)#show running-config | section bgp
+# router bgp 100
+# bgp convergence slow-peer time 6
+# bgp additional-paths send any
+# !
+# vrf vrf01
+# distance bgp 50 50 50
+# maximum-paths 55
+# neighbor 10.1.3.2 export-localpref 4000
+# neighbor 10.1.3.2 next-hop-unchanged
+# neighbor 10.1.3.2 dont-capability-negotiate
+# neighbor 10.1.3.2 allowas-in 3
+# neighbor 10.1.3.2 default-originate always
+# neighbor 10.1.3.2 maximum-routes 500 warning-limit 5 percent
+# aggregate-address 1.2.1.0/24 as-set match-map match01
+# aggregate-address 5.2.1.0/24 attribute-map attrmatch01 advertise-only
+# redistribute static route-map map_static
+# redistribute attached-host
+# !
+# address-family ipv4
+# neighbor 10.1.3.2 prefix-list prefix01 out
+# !
+# address-family ipv6
+# redistribute dhcp
+# veos(config)#
+
+ - name: Replace
+ arista.eos.eos_bgp_global:
+ config:
+ as_number: "100"
+ graceful_restart:
+ set: True
+ router_id: "1.1.1.1"
+ timers:
+ keepalive: 2
+ holdtime: 5
+ ucmp:
+ mode:
+ set: True
+ vlan_aware_bundle: "bundle1 bundle2 bundle3"
+ state: replaced
+
+# Module Execution:
+
+# fatal: [192.168.122.113]: FAILED! => {
+# "changed": false,
+# "invocation": {
+# "module_args": {
+# "config": {
+# "access_group": null,
+# "aggregate_address": null,
+# "as_number": "100",
+# "bgp_params": null,
+# "default_metric": null,
+# "distance": null,
+# "graceful_restart": {
+# "restart_time": null,
+# "set": true,
+# "stalepath_time": null
+# },
+# "graceful_restart_helper": null,
+# "maximum_paths": null,
+# "monitoring": null,
+# "neighbor": null,
+# "network": null,
+# "redistribute": null,
+# "route_target": null,
+# "router_id": "1.1.1.1",
+# "shutdown": null,
+# "timers": {
+# "holdtime": 5,
+# "keepalive": 2
+# },
+# "ucmp": {
+# "fec": null,
+# "link_bandwidth": null,
+# "mode": {
+# "nexthops": null,
+# "set": true
+# }
+# },
+# "update": null,
+# "vlan": null,
+# "vlan_aware_bundle": "bundle1 bundle2 bundle3",
+# "vrfs": null
+# },
+# "running_config": null,
+# "state": "replaced"
+# }
+# },
+# "msg": "Use the _bgp_af module to delete the address_family under vrf, before replacing/deleting the vrf."
+# }
+
+# Using deleted:
+
+# Before state:
+
+# veos(config)#show running-config | section bgp
+# router bgp 100
+# bgp convergence slow-peer time 6
+# bgp additional-paths send any
+# !
+# vrf vrf01
+# distance bgp 50 50 50
+# maximum-paths 55
+# neighbor 10.1.3.2 export-localpref 4000
+# neighbor 10.1.3.2 next-hop-unchanged
+# neighbor 10.1.3.2 dont-capability-negotiate
+# neighbor 10.1.3.2 allowas-in 3
+# neighbor 10.1.3.2 default-originate always
+# neighbor 10.1.3.2 maximum-routes 500 warning-limit 5 percent
+# aggregate-address 1.2.1.0/24 as-set match-map match01
+# aggregate-address 5.2.1.0/24 attribute-map attrmatch01 advertise-only
+# redistribute static route-map map_static
+# redistribute attached-host
+# !
+
+ - name: Delete configuration
+ arista.eos.eos_bgp_global:
+ config:
+ as_number: "100"
+ state: deleted
+
+# After State:
+
+# veos(config)#show running-config | section bgp
+# router bgp 100
+#
+#
+# Module Execution:
+#
+# "after": {
+# "as_number": "100"
+# },
+# "before": {
+# "as_number": "100",
+# "bgp_params": {
+# "additional_paths": "send",
+# "convergence": {
+# "slow_peer": true,
+# "time": 6
+# }
+# },
+# "vrfs": [
+# {
+# "aggregate_address": [
+# {
+# "address": "1.2.1.0/24",
+# "as_set": true,
+# "match_map": "match01"
+# },
+# {
+# "address": "5.2.1.0/24",
+# "advertise_only": true,
+# "attribute_map": "attrmatch01"
+# }
+# ],
+# "distance": {
+# "external": 50,
+# "internal": 50,
+# "local": 50
+# },
+# "maximum_paths": {
+# "max_equal_cost_paths": 55
+# },
+# "neighbor": [
+# {
+# "allowas_in": {
+# "count": 3
+# },
+# "default_originate": {
+# "always": true
+# },
+# "dont_capability_negotiate": true,
+# "export_localpref": 4000,
+# "maximum_received_routes": {
+# "count": 500,
+# "warning_limit": {
+# "limit_percent": 5
+# }
+# },
+# "next_hop_unchanged": true,
+# "peer": "10.1.3.2"
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "static",
+# "route_map": "map_static"
+# },
+# {
+# "protocol": "attached-host"
+# }
+# ],
+# "vrf": "vrf01"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "router bgp 100",
+# "no vrf vrf01",
+# "no bgp convergence slow-peer time 6",
+# "no bgp additional-paths send any"
+# ],
+#
+
+# Using purged:
+
+# Before state:
+
+# veos(config)#show running-config | section bgp
+# router bgp 100
+# bgp convergence slow-peer time 6
+# distance bgp 50 50 50
+# maximum-paths 55
+# bgp additional-paths send any
+# neighbor peer1 peer group
+# neighbor peer1 link-bandwidth update-delay 5
+# neighbor peer1 fall-over bfd
+# neighbor peer1 monitoring
+# neighbor peer1 send-community extended link-bandwidth aggregate 600
+# neighbor peer1 maximum-routes 12000
+# neighbor 10.1.3.2 export-localpref 4000
+# neighbor 10.1.3.2 next-hop-unchanged
+# neighbor 10.1.3.2 dont-capability-negotiate
+# neighbor 10.1.3.2 allowas-in 3
+# neighbor 10.1.3.2 default-originate always
+# neighbor 10.1.3.2 maximum-routes 500 warning-limit 5 percent
+# aggregate-address 1.2.1.0/24 as-set match-map match01
+# aggregate-address 5.2.1.0/24 attribute-map attrmatch01 advertise-only
+# redistribute static route-map map_static
+# redistribute attached-host
+# !
+# vlan 5
+# !
+# address-family ipv4
+# neighbor 10.1.3.2 prefix-list prefix01 out
+# !
+# vrf vrf01
+# route-target import 54:11
+# neighbor 12.1.3.2 dont-capability-negotiate
+# neighbor 12.1.3.2 allowas-in 3
+# neighbor 12.1.3.2 default-originate always
+# neighbor 12.1.3.2 maximum-routes 12000
+# veos(config)#
+
+ - name: Purge configuration
+ arista.eos.eos_bgp_global:
+ config:
+ as_number: "100"
+ state: purged
+
+# After State:
+
+# veos(config)#show running-config | section bgp
+# veos(config)#
+
+# Module Execution:
+
+# "after": {},
+# "before": {
+# "aggregate_address": [
+# {
+# "address": "1.2.1.0/24",
+# "as_set": true,
+# "match_map": "match01"
+# },
+# {
+# "address": "5.2.1.0/24",
+# "advertise_only": true,
+# "attribute_map": "attrmatch01"
+# }
+# ],
+# "as_number": "100",
+# "bgp_params": {
+# "additional_paths": "send",
+# "convergence": {
+# "slow_peer": true,
+# "time": 6
+# }
+# },
+# "distance": {
+# "external": 50,
+# "internal": 50,
+# "local": 50
+# },
+# "maximum_paths": {
+# "max_equal_cost_paths": 55
+# },
+# "neighbor": [
+# {
+# "fall_over": true,
+# "link_bandwidth": {
+# "set": true,
+# "update_delay": 5
+# },
+# "maximum_received_routes": {
+# "count": 12000
+# },
+# "monitoring": true,
+# "peer": "peer1",
+# "peer_group": "peer1",
+# "send_community": {
+# "community_attribute": "extended",
+# "link_bandwidth_attribute": "aggregate",
+# "speed": "600",
+# "sub_attribute": "link-bandwidth"
+# }
+# },
+# {
+# "allowas_in": {
+# "count": 3
+# },
+# "default_originate": {
+# "always": true
+# },
+# "dont_capability_negotiate": true,
+# "export_localpref": 4000,
+# "maximum_received_routes": {
+# "count": 500,
+# "warning_limit": {
+# "limit_percent": 5
+# }
+# },
+# "next_hop_unchanged": true,
+# "peer": "10.1.3.2"
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "static",
+# "route_map": "map_static"
+# },
+# {
+# "protocol": "attached-host"
+# }
+# ],
+# "vlan": 5,
+# "vrfs": [
+# {
+# "neighbor": [
+# {
+# "allowas_in": {
+# "count": 3
+# },
+# "default_originate": {
+# "always": true
+# },
+# "dont_capability_negotiate": true,
+# "maximum_received_routes": {
+# "count": 12000
+# },
+# "peer": "12.1.3.2"
+# }
+# ],
+# "route_target": {
+# "action": "import",
+# "target": "54:11"
+# },
+# "vrf": "vrf01"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "no router bgp 100"
+# ],
+
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.bgp_global.bgp_global import (
+ Bgp_globalArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.bgp_global.bgp_global import (
+ Bgp_global,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Bgp_globalArgs.argument_spec,
+ mutually_exclusive=[["config", "running_config"]],
+ required_if=[
+ ["state", "merged", ["config"]],
+ ["state", "replaced", ["config"]],
+ ["state", "rendered", ["config"]],
+ ["state", "parsed", ["running_config"]],
+ ],
+ supports_check_mode=True,
+ )
+
+ result = Bgp_global(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_command.py b/ansible_collections/arista/eos/plugins/modules/eos_command.py
new file mode 100644
index 000000000..437e3bc63
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_command.py
@@ -0,0 +1,320 @@
+#!/usr/bin/python
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_command
+author: Peter Sprygada (@privateip)
+short_description: Run arbitrary commands on an Arista EOS device
+description:
+- Sends an arbitrary set of commands to an EOS node and returns the results read from
+ the device. This module includes an argument that will cause the module to wait
+ for a specific condition before returning or timing out if the condition is not
+ met.
+version_added: 1.0.0
+notes:
+- Tested against Arista EOS 4.24.6F
+options:
+ commands:
+ description:
+ - The commands to send to the remote EOS device. The
+ resulting output from the command is returned. If the I(wait_for) argument
+ is provided, the module is not returned until the condition is satisfied or
+ the number of I(retries) has been exceeded.
+ - Commands may be represented either as simple strings or as dictionaries as described below.
+ Refer to the Examples setion for some common uses.
+ required: true
+ type: list
+ elements: raw
+ suboptions:
+ command:
+ description:
+ - The command to send to the remote network device. The resulting output from
+ the command is returned, unless I(sendonly) is set.
+ required: true
+ type: str
+ output:
+ description:
+ - How the remote device should format the command response data.
+ type: str
+ choices: ["text", "json"]
+ version:
+ description:
+ - Specifies the version of the JSON response returned when I(output=json).
+ type: str
+ choices: ["1", "latest"]
+ default: "latest"
+ prompt:
+ description:
+ - A single regex pattern or a sequence of patterns to evaluate the expected prompt
+ from I(command).
+ required: false
+ type: list
+ elements: str
+ answer:
+ description:
+ - The answer to reply with if I(prompt) is matched. The value can be a single
+ answer or a list of answer for multiple prompts. In case the command execution
+ results in multiple prompts the sequence of the prompt and excepted answer should
+ be in same order.
+ required: false
+ type: list
+ elements: str
+ sendonly:
+ description:
+ - The boolean value, that when set to true will send I(command) to the device
+ but not wait for a result.
+ type: bool
+ default: false
+ required: false
+ newline:
+ description:
+ - The boolean value, that when set to false will send I(answer) to the device
+ without a trailing newline.
+ type: bool
+ default: true
+ required: false
+ check_all:
+ description:
+ - By default if any one of the prompts mentioned in C(prompt) option is matched
+ it won't check for other prompts. This boolean flag, that when set to I(True)
+ will check for all the prompts mentioned in C(prompt) option in the given order.
+ If the option is set to I(True) all the prompts should be received from remote
+ host if not it will result in timeout.
+ type: bool
+ default: false
+ wait_for:
+ description:
+ - Specifies what to evaluate from the output of the command and what conditionals
+ to apply. This argument will cause the task to wait for a particular conditional
+ to be true before moving forward. If the conditional is not true by the configured
+ retries, the task fails. Note - With I(wait_for) the value in C(result['stdout'])
+ can be accessed using C(result), that is to access C(result['stdout'][0]) use
+ C(result[0]) See examples.
+ type: list
+ elements: str
+ aliases:
+ - waitfor
+ match:
+ description:
+ - The I(match) argument is used in conjunction with the I(wait_for) argument to
+ specify the match policy. Valid values are C(all) or C(any). If the value
+ is set to C(all) then all conditionals in the I(wait_for) must be satisfied. If
+ the value is set to C(any) then only one of the values must be satisfied.
+ type: str
+ default: all
+ choices:
+ - any
+ - all
+ retries:
+ description:
+ - Specifies the number of retries a command should be tried before it is considered
+ failed. The command is run on the target device every retry and evaluated against
+ the I(wait_for) conditionals.
+ default: 10
+ type: int
+ interval:
+ description:
+ - Configures the interval in seconds to wait between retries of the command. If
+ the command does not pass the specified conditional, the interval indicates
+ how to long to wait before trying the command again.
+ default: 1
+ type: int
+"""
+
+EXAMPLES = r"""
+- name: run show version on remote devices
+ arista.eos.eos_command:
+ commands: show version
+
+- name: run show version and check to see if output contains Arista
+ arista.eos.eos_command:
+ commands: show version
+ wait_for: result[0] contains Arista
+
+- name: run multiple commands on remote nodes
+ arista.eos.eos_command:
+ commands:
+ - show version
+ - show interfaces
+
+- name: run multiple commands and evaluate the output
+ arista.eos.eos_command:
+ commands:
+ - show version
+ - show interfaces
+ wait_for:
+ - result[0] contains Arista
+ - result[1] contains Loopback0
+
+- name: run commands and specify the output format
+ arista.eos.eos_command:
+ commands:
+ - command: show version
+ output: json
+
+- name: check whether the switch is in maintenance mode
+ arista.eos.eos_command:
+ commands: show maintenance
+ wait_for: result[0] contains 'Under Maintenance'
+
+- name: check whether the switch is in maintenance mode using json output
+ arista.eos.eos_command:
+ commands:
+ - command: show maintenance
+ output: json
+ wait_for: result[0].units.System.state eq 'underMaintenance'
+
+- name: check whether the switch is in maintenance, with 8 retries
+ and 2 second interval between retries
+ arista.eos.eos_command:
+ commands: show maintenance
+ wait_for: result[0]['units']['System']['state'] eq 'underMaintenance'
+ interval: 2
+ retries: 8
+
+- name: run a command that requires a confirmation. Note that prompt
+ takes regexes, and so strings containing characters like brackets
+ need to be escaped.
+ arista.eos.eos_command:
+ commands:
+ - command: reload power
+ prompt: \[confirm\]
+ answer: y
+ newline: false
+"""
+
+RETURN = """
+stdout:
+ description: The set of responses from the commands
+ returned: always apart from low level errors (such as action plugin)
+ type: list
+ sample: ['...', '...']
+stdout_lines:
+ description: The value of stdout split into a list
+ returned: always apart from low level errors (such as action plugin)
+ type: list
+ sample: [['...', '...'], ['...'], ['...']]
+failed_conditions:
+ description: The list of conditionals that have failed
+ returned: failed
+ type: list
+ sample: ['...', '...']
+"""
+import time
+
+from ansible.module_utils._text import to_text
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.parsing import (
+ Conditional,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ to_lines,
+)
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.eos import (
+ run_commands,
+ transform_commands,
+)
+
+
+def parse_commands(module, warnings):
+ commands = transform_commands(module)
+
+ if module.check_mode:
+ for item in list(commands):
+ if not item["command"].startswith("show"):
+ warnings.append(
+ "Only show commands are supported when using check mode, not "
+ "executing %s" % item["command"],
+ )
+ commands.remove(item)
+
+ return commands
+
+
+def to_cli(obj):
+ cmd = obj["command"]
+ if obj.get("output") == "json":
+ cmd += " | json"
+ return cmd
+
+
+def main():
+ """entry point for module execution"""
+ argument_spec = dict(
+ commands=dict(type="list", required=True, elements="raw"),
+ wait_for=dict(type="list", aliases=["waitfor"], elements="str"),
+ match=dict(default="all", choices=["all", "any"]),
+ retries=dict(default=10, type="int"),
+ interval=dict(default=1, type="int"),
+ )
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=True,
+ )
+
+ warnings = list()
+ result = {"changed": False, "warnings": warnings}
+ commands = parse_commands(module, warnings)
+ wait_for = module.params["wait_for"] or list()
+
+ try:
+ conditionals = [Conditional(c) for c in wait_for]
+ except AttributeError as exc:
+ module.fail_json(msg=to_text(exc))
+
+ retries = module.params["retries"]
+ interval = module.params["interval"]
+ match = module.params["match"]
+
+ while retries > 0:
+ responses = run_commands(module, commands)
+
+ for item in list(conditionals):
+ if item(responses):
+ if match == "any":
+ conditionals = list()
+ break
+ conditionals.remove(item)
+
+ if not conditionals:
+ break
+
+ time.sleep(interval)
+ retries -= 1
+
+ if conditionals:
+ failed_conditions = [item.raw for item in conditionals]
+ msg = "One or more conditional statements have not been satisfied"
+ module.fail_json(msg=msg, failed_conditions=failed_conditions)
+
+ result.update(
+ {"stdout": responses, "stdout_lines": list(to_lines(responses))},
+ )
+
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_config.py b/ansible_collections/arista/eos/plugins/modules/eos_config.py
new file mode 100644
index 000000000..0c8271adc
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_config.py
@@ -0,0 +1,630 @@
+#!/usr/bin/python
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_config
+author: Peter Sprygada (@privateip)
+short_description: Manage Arista EOS configuration sections
+description:
+- Arista EOS configurations use a simple block indent file syntax for segmenting configuration
+ into sections. This module provides an implementation for working with EOS configuration
+ sections in a deterministic way. This module works with either CLI or eAPI transports.
+version_added: 1.0.0
+notes:
+- Tested against Arista EOS 4.24.6F
+- Abbreviated commands are NOT idempotent, see
+ L(Network FAQ,../network/user_guide/faq.html#why-do-the-config-modules-always-return-changed-true-with-abbreviated-commands).
+- To ensure idempotency and correct diff the configuration lines in the relevant module options should be similar to how they
+ appear if present in the running configuration on device including the indentation.
+options:
+ lines:
+ description:
+ - The ordered set of commands that should be configured in the section. The commands
+ must be the exact same commands as found in the device running-config as found in the
+ device running-config to ensure idempotency and correct diff. Be sure
+ to note the configuration command syntax as some commands are automatically
+ modified by the device config parser.
+ aliases:
+ - commands
+ type: list
+ elements: str
+ parents:
+ description:
+ - The ordered set of parents that uniquely identify the section or hierarchy the
+ commands should be checked against. If the parents argument is omitted, the
+ commands are checked against the set of top level or global commands.
+ type: list
+ elements: str
+ src:
+ description:
+ - The I(src) argument provides a path to the configuration file to load into the
+ remote system. The path can either be a full system path to the configuration
+ file if the value starts with / or relative to the root of the implemented role
+ or playbook. This argument is mutually exclusive with the I(lines) and I(parents)
+ arguments. It can be a Jinja2 template as well. The configuration lines in the source
+ file should be similar to how it will appear if present in the running-configuration
+ (live switch config) of the device i ncluding the indentation to ensure idempotency
+ and correct diff. Arista EOS device config has 3 spaces indentation.
+ type: path
+ before:
+ description:
+ - The ordered set of commands to push on to the command stack if a change needs
+ to be made. This allows the playbook designer the opportunity to perform configuration
+ commands prior to pushing any changes without affecting how the set of commands
+ are matched against the system.
+ type: list
+ elements: str
+ after:
+ description:
+ - The ordered set of commands to append to the end of the command stack if a change
+ needs to be made. Just like with I(before) this allows the playbook designer
+ to append a set of commands to be executed after the command set.
+ type: list
+ elements: str
+ match:
+ description:
+ - Instructs the module on the way to perform the matching of the set of commands
+ against the current device config. If match is set to I(line), commands are
+ matched line by line. If match is set to I(strict), command lines are matched
+ with respect to position. If match is set to I(exact), command lines must be
+ an equal match. Finally, if match is set to I(none), the module will not attempt
+ to compare the source configuration with the running configuration on the remote
+ device.
+ type: str
+ default: line
+ choices:
+ - line
+ - strict
+ - exact
+ - none
+ replace:
+ description:
+ - Instructs the module on the way to perform the configuration on the device. If
+ the replace argument is set to I(line) then the modified lines are pushed to
+ the device in configuration mode. If the replace argument is set to I(block)
+ then the entire command block is pushed to the device in configuration mode
+ if any line is not correct.
+ type: str
+ default: line
+ choices:
+ - line
+ - block
+ - config
+ backup:
+ description:
+ - This argument will cause the module to create a full backup of the current C(running-config)
+ from the remote device before any changes are made. If the C(backup_options)
+ value is not given, the backup file is written to the C(backup) folder in the
+ playbook root directory or role root directory, if playbook is part of an ansible
+ role. If the directory does not exist, it is created.
+ type: bool
+ default: no
+ running_config:
+ description:
+ - The module, by default, will connect to the remote device and retrieve the current
+ running-config to use as a base for comparing against the contents of source. There
+ are times when it is not desirable to have the task get the current running-config
+ for every task in a playbook. The I(running_config) argument allows the implementer
+ to pass in the configuration to use as the base config for this module.
+ The configuration lines for this option should be similar to how it will appear if present
+ in the running-configuration of the device including the indentation to ensure idempotency
+ and correct diff.
+ type: str
+ aliases:
+ - config
+ defaults:
+ description:
+ - The I(defaults) argument will influence how the running-config is collected
+ from the device. When the value is set to true, the command used to collect
+ the running-config is append with the all keyword. When the value is set to
+ false, the command is issued without the all keyword
+ type: bool
+ default: no
+ save_when:
+ description:
+ - When changes are made to the device running-configuration, the changes are not
+ copied to non-volatile storage by default. Using this argument will change
+ that before. If the argument is set to I(always), then the running-config will
+ always be copied to the startup-config and the I(modified) flag will always
+ be set to True. If the argument is set to I(modified), then the running-config
+ will only be copied to the startup-config if it has changed since the last save
+ to startup-config. If the argument is set to I(never), the running-config will
+ never be copied to the startup-config. If the argument is set to I(changed),
+ then the running-config will only be copied to the startup-config if the task
+ has made a change. I(changed) was added in Ansible 2.5.
+ default: never
+ type: str
+ choices:
+ - always
+ - never
+ - modified
+ - changed
+ diff_against:
+ description:
+ - When using the C(ansible-playbook --diff) command line argument the module can
+ generate diffs against different sources.
+ - When this option is configure as I(startup), the module will return the diff
+ of the running-config against the startup-config.
+ - When this option is configured as I(intended), the module will return the diff
+ of the running-config against the configuration provided in the C(intended_config)
+ argument.
+ - When this option is configured as I(running), the module will return the before
+ and after diff of the running-config with respect to any changes made to the
+ device configuration.
+ - When this option is configured as C(session), the diff returned will be based
+ on the configuration session.
+ - When this option is configured as C(validate_config), the module will return before
+ with the running-config before applying the intended config and after with the session
+ config after applying the intended config to the session.
+ default: session
+ type: str
+ choices:
+ - startup
+ - running
+ - intended
+ - session
+ - validate_config
+ diff_ignore_lines:
+ description:
+ - Use this argument to specify one or more lines that should be ignored during
+ the diff. This is used for lines in the configuration that are automatically
+ updated by the system. This argument takes a list of regular expressions or
+ exact line matches.
+ type: list
+ elements: str
+ intended_config:
+ description:
+ - The C(intended_config) provides the master configuration that the node should
+ conform to and is used to check the final running-config against. This argument
+ will not modify any settings on the remote device and is strictly used to check
+ the compliance of the current device's configuration against. When specifying
+ this argument, the task should also modify the C(diff_against) value and set
+ it to I(intended). The configuration lines for this value should be similar to how it
+ will appear if present in the running-configuration of the device including the indentation
+ to ensure correct diff.
+ type: str
+ backup_options:
+ description:
+ - This is a dict object containing configurable options related to backup file
+ path. The value of this option is read only when C(backup) is set to I(yes),
+ if C(backup) is set to I(no) this option will be silently ignored.
+ suboptions:
+ filename:
+ description:
+ - The filename to be used to store the backup configuration. If the filename
+ is not given it will be generated based on the hostname, current time and
+ date in format defined by <hostname>_config.<current-date>@<current-time>
+ type: str
+ dir_path:
+ description:
+ - This option provides the path ending with directory name in which the backup
+ configuration file will be stored. If the directory does not exist it will
+ be first created and the filename is either the value of C(filename) or
+ default filename as described in C(filename) options description. If the
+ path value is not given in that case a I(backup) directory will be created
+ in the current working directory and backup configuration will be copied
+ in C(filename) within I(backup) directory.
+ type: path
+ type: dict
+"""
+# noqa: E501
+
+EXAMPLES = """
+- name: configure top level settings
+ arista.eos.eos_config:
+ lines: hostname {{ inventory_hostname }}
+
+- name: load an acl into the device
+ arista.eos.eos_config:
+ lines:
+ - 10 permit ip host 192.0.2.1 any log
+ - 20 permit ip host 192.0.2.2 any log
+ - 30 permit ip host 192.0.2.3 any log
+ - 40 permit ip host 192.0.2.4 any log
+ parents: ip access-list test
+ before: no ip access-list test
+ replace: block
+
+- name: load configuration from file
+ arista.eos.eos_config:
+ src: eos.cfg
+
+- name: render a Jinja2 template onto an Arista switch
+ arista.eos.eos_config:
+ backup: yes
+ src: eos_template.j2
+
+- name: diff the running config against a master config
+ arista.eos.eos_config:
+ diff_against: intended
+ intended_config: "{{ lookup('file', 'master.cfg') }}"
+
+- name: for idempotency, use full-form commands
+ arista.eos.eos_config:
+ lines:
+ # - shut
+ - shutdown
+ # parents: int eth1
+ parents: interface Ethernet1
+
+- name: configurable backup path
+ arista.eos.eos_config:
+ src: eos_template.j2
+ backup: yes
+ backup_options:
+ filename: backup.cfg
+ dir_path: /home/user
+"""
+
+RETURN = """
+commands:
+ description: The set of commands that will be pushed to the remote device
+ returned: always
+ type: list
+ sample: ['hostname switch01', 'interface Ethernet1', 'no shutdown']
+updates:
+ description: The set of commands that will be pushed to the remote device
+ returned: always
+ type: list
+ sample: ['hostname switch01', 'interface Ethernet1', 'no shutdown']
+backup_path:
+ description: The full path to the backup file
+ returned: when backup is yes
+ type: str
+ sample: /playbooks/ansible/backup/eos_config.2016-07-16@22:28:34
+filename:
+ description: The name of the backup file
+ returned: when backup is yes and filename is not specified in backup options
+ type: str
+ sample: eos_config.2016-07-16@22:28:34
+shortname:
+ description: The full path to the backup file excluding the timestamp
+ returned: when backup is yes and filename is not specified in backup options
+ type: str
+ sample: /playbooks/ansible/backup/eos_config
+date:
+ description: The date extracted from the backup file name
+ returned: when backup is yes
+ type: str
+ sample: "2016-07-16"
+time:
+ description: The time extracted from the backup file name
+ returned: when backup is yes
+ type: str
+ sample: "22:28:34"
+"""
+from ansible.module_utils._text import to_text
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import ConnectionError
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import (
+ NetworkConfig,
+ dumps,
+)
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.eos import (
+ get_config,
+ get_connection,
+ get_session_config,
+ load_config,
+ run_commands,
+)
+
+
+def get_candidate(module):
+ candidate = ""
+ if module.params["src"]:
+ candidate = module.params["src"]
+ elif module.params["lines"]:
+ candidate_obj = NetworkConfig(indent=3)
+ parents = module.params["parents"] or list()
+ candidate_obj.add(module.params["lines"], parents=parents)
+ candidate = dumps(candidate_obj, "raw")
+ return candidate
+
+
+def get_running_config(module, config=None, flags=None):
+ contents = module.params["running_config"]
+ if not contents:
+ if config:
+ contents = config
+ else:
+ contents = get_config(module, flags=flags)
+ return contents
+
+
+def save_config(module, result):
+ result["changed"] = True
+ if not module.check_mode:
+ cmd = {
+ "command": "copy running-config startup-config",
+ "output": "text",
+ }
+ run_commands(module, [cmd])
+ else:
+ module.warn(
+ "Skipping command `copy running-config startup-config` "
+ "due to check_mode. Configuration not copied to "
+ "non-volatile storage",
+ )
+
+
+def main():
+ """main entry point for module execution"""
+ backup_spec = dict(filename=dict(), dir_path=dict(type="path"))
+ argument_spec = dict(
+ src=dict(type="path"),
+ lines=dict(aliases=["commands"], type="list", elements="str"),
+ parents=dict(type="list", elements="str"),
+ before=dict(type="list", elements="str"),
+ after=dict(type="list", elements="str"),
+ match=dict(
+ default="line",
+ choices=["line", "strict", "exact", "none"],
+ ),
+ replace=dict(default="line", choices=["line", "block", "config"]),
+ defaults=dict(type="bool", default=False),
+ backup=dict(type="bool", default=False),
+ backup_options=dict(type="dict", options=backup_spec),
+ save_when=dict(
+ choices=["always", "never", "modified", "changed"],
+ default="never",
+ ),
+ diff_against=dict(
+ choices=[
+ "startup",
+ "session",
+ "intended",
+ "running",
+ "validate_config",
+ ],
+ default="session",
+ ),
+ diff_ignore_lines=dict(type="list", elements="str"),
+ running_config=dict(aliases=["config"]),
+ intended_config=dict(),
+ )
+
+ mutually_exclusive = [("lines", "src"), ("parents", "src")]
+
+ required_if = [
+ ("match", "strict", ["lines"]),
+ ("match", "exact", ["lines"]),
+ ("replace", "block", ["lines"]),
+ ("replace", "config", ["src"]),
+ ("diff_against", "intended", ["intended_config"]),
+ ("diff_against", "validate_config", ["intended_config"]),
+ ]
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ mutually_exclusive=mutually_exclusive,
+ required_if=required_if,
+ supports_check_mode=True,
+ )
+
+ warnings = list()
+
+ result = {"changed": False}
+ if warnings:
+ result["warnings"] = warnings
+
+ diff_ignore_lines = module.params["diff_ignore_lines"]
+ config = None
+ contents = None
+ flags = ["all"] if module.params["defaults"] else []
+ connection = get_connection(module)
+ # Refuse to diff_against: session if sessions are disabled
+ if (
+ module.params["diff_against"] in ["session", "validate_config"]
+ and not connection.supports_sessions
+ ):
+ module.fail_json(
+ msg="Cannot diff against sessions when sessions are disabled. Please change diff_against to another value",
+ )
+
+ if module.params["backup"] or (
+ module._diff and module.params["diff_against"] == "running"
+ ):
+ contents = get_config(module, flags=flags)
+ config = NetworkConfig(indent=1, contents=contents)
+ if module.params["backup"]:
+ result["__backup__"] = contents
+
+ if any((module.params["src"], module.params["lines"])):
+ match = module.params["match"]
+ replace = module.params["replace"]
+ path = module.params["parents"]
+
+ candidate = get_candidate(module)
+ running = get_running_config(module, contents, flags=flags)
+
+ try:
+ response = connection.get_diff(
+ candidate=candidate,
+ running=running,
+ diff_match=match,
+ diff_ignore_lines=diff_ignore_lines,
+ path=path,
+ diff_replace=replace,
+ )
+ except ConnectionError as exc:
+ module.fail_json(msg=to_text(exc, errors="surrogate_then_replace"))
+
+ config_diff = response["config_diff"]
+ if config_diff:
+ commands = config_diff.split("\n")
+ if module.params["before"]:
+ commands[:0] = module.params["before"]
+
+ if module.params["after"]:
+ commands.extend(module.params["after"])
+
+ result["commands"] = commands
+ result["updates"] = commands
+
+ replace = module.params["replace"] == "config"
+ commit = not module.check_mode
+
+ response = load_config(
+ module,
+ commands,
+ replace=replace,
+ commit=commit,
+ )
+
+ result["changed"] = True
+
+ if module.params["diff_against"] == "session":
+ if "diff" in response:
+ result["diff"] = {"prepared": response["diff"]}
+ else:
+ result["changed"] = False
+
+ if "session" in response:
+ result["session"] = response["session"]
+
+ running_config = module.params["running_config"]
+ startup_config = None
+ if module.params["save_when"] == "always":
+ save_config(module, result)
+ elif module.params["save_when"] == "modified":
+ output = run_commands(
+ module,
+ [
+ {"command": "show running-config", "output": "text"},
+ {"command": "show startup-config", "output": "text"},
+ ],
+ )
+
+ running_config = NetworkConfig(
+ indent=3,
+ contents=output[0],
+ ignore_lines=diff_ignore_lines,
+ )
+ startup_config = NetworkConfig(
+ indent=3,
+ contents=output[1],
+ ignore_lines=diff_ignore_lines,
+ )
+
+ if running_config.sha1 != startup_config.sha1:
+ save_config(module, result)
+
+ elif module.params["save_when"] == "changed" and result["changed"]:
+ save_config(module, result)
+ if module._diff:
+ if not running_config:
+ output = run_commands(
+ module,
+ {"command": "show running-config", "output": "text"},
+ )
+ contents = output[0]
+ else:
+ contents = running_config
+
+ # recreate the object in order to process diff_ignore_lines
+ running_config = NetworkConfig(
+ indent=3,
+ contents=contents,
+ ignore_lines=diff_ignore_lines,
+ )
+
+ if module.params["diff_against"] == "running":
+ if module.check_mode:
+ module.warn(
+ "unable to perform diff against running-config due to check mode",
+ )
+ contents = None
+ else:
+ contents = config.config_text
+
+ elif module.params["diff_against"] == "startup":
+ if not startup_config:
+ output = run_commands(
+ module,
+ {"command": "show startup-config", "output": "text"},
+ )
+ contents = output[0]
+ else:
+ contents = startup_config.config_text
+
+ elif module.params["diff_against"] in ["intended", "validate_config"]:
+ contents = module.params["intended_config"]
+
+ if contents is not None:
+ base_config = NetworkConfig(
+ indent=3,
+ contents=contents,
+ ignore_lines=diff_ignore_lines,
+ )
+
+ if running_config.sha1 != base_config.sha1:
+ before = ""
+ after = ""
+ if module.params["diff_against"] == "intended":
+ before = running_config
+ after = base_config
+ elif module.params["diff_against"] in ("startup", "running"):
+ before = base_config
+ after = running_config
+ elif module.params["diff_against"] == "validate_config":
+ before = running = get_running_config(
+ module,
+ None,
+ flags=flags,
+ )
+ replace = module.params["replace"] == "config"
+ after = get_session_config(
+ module,
+ contents.split("\n"),
+ replace=replace,
+ commit=False,
+ )
+
+ result.update(
+ {
+ "changed": False,
+ "diff": {"before": str(before), "after": str(after)},
+ },
+ )
+
+ if result.get("changed") and any(
+ (module.params["src"], module.params["lines"]),
+ ):
+ msg = (
+ "To ensure idempotency and correct diff the input configuration lines should be"
+ " similar to how they appear if present in"
+ " the running configuration on device"
+ )
+ if module.params["src"]:
+ msg += " including the indentation"
+ if "warnings" in result:
+ result["warnings"].append(msg)
+ else:
+ result["warnings"] = msg
+
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_eapi.py b/ansible_collections/arista/eos/plugins/modules/eos_eapi.py
new file mode 100644
index 000000000..2b3add753
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_eapi.py
@@ -0,0 +1,437 @@
+#!/usr/bin/python
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_eapi
+author: Peter Sprygada (@privateip)
+short_description: Manage and configure Arista EOS eAPI.
+requirements:
+- EOS v4.12 or greater
+description:
+- Use to enable or disable eAPI access, and set the port and state of http, https,
+ local_http and unix-socket servers.
+- When enabling eAPI access the default is to enable HTTP on port 80, enable HTTPS
+ on port 443, disable local HTTP, and disable Unix socket server. Use the options
+ listed below to override the default configuration.
+- Requires EOS v4.12 or greater.
+version_added: 1.0.0
+options:
+ http:
+ description:
+ - The C(http) argument controls the operating state of the HTTP transport protocol
+ when eAPI is present in the running-config. When the value is set to True, the
+ HTTP protocol is enabled and when the value is set to False, the HTTP protocol
+ is disabled. By default, when eAPI is first configured, the HTTP protocol is
+ disabled.
+ type: bool
+ aliases:
+ - enable_http
+ http_port:
+ description:
+ - Configures the HTTP port that will listen for connections when the HTTP transport
+ protocol is enabled. This argument accepts integer values in the valid range
+ of 1 to 65535.
+ type: int
+ https:
+ description:
+ - The C(https) argument controls the operating state of the HTTPS transport protocol
+ when eAPI is present in the running-config. When the value is set to True, the
+ HTTPS protocol is enabled and when the value is set to False, the HTTPS protocol
+ is disabled. By default, when eAPI is first configured, the HTTPS protocol is
+ enabled.
+ type: bool
+ aliases:
+ - enable_https
+ https_port:
+ description:
+ - Configures the HTTP port that will listen for connections when the HTTP transport
+ protocol is enabled. This argument accepts integer values in the valid range
+ of 1 to 65535.
+ type: int
+ local_http:
+ description:
+ - The C(local_http) argument controls the operating state of the local HTTP transport
+ protocol when eAPI is present in the running-config. When the value is set
+ to True, the HTTP protocol is enabled and restricted to connections from localhost
+ only. When the value is set to False, the HTTP local protocol is disabled.
+ - Note is value is independent of the C(http) argument
+ type: bool
+ aliases:
+ - enable_local_http
+ local_http_port:
+ description:
+ - Configures the HTTP port that will listen for connections when the HTTP transport
+ protocol is enabled. This argument accepts integer values in the valid range
+ of 1 to 65535.
+ type: int
+ socket:
+ description:
+ - The C(socket) argument controls the operating state of the UNIX Domain Socket
+ used to receive eAPI requests. When the value of this argument is set to True,
+ the UDS will listen for eAPI requests. When the value is set to False, the
+ UDS will not be available to handle requests. By default when eAPI is first
+ configured, the UDS is disabled.
+ type: bool
+ aliases:
+ - enable_socket
+ timeout:
+ description:
+ - The time (in seconds) to wait for the eAPI configuration to be reflected in
+ the running-config.
+ type: int
+ default: 30
+ vrf:
+ description:
+ - The C(vrf) argument will configure eAPI to listen for connections in the specified
+ VRF. By default, eAPI transports will listen for connections in the global
+ table. This value requires the VRF to already be created otherwise the task
+ will fail.
+ default: default
+ type: str
+ config:
+ description:
+ - The module, by default, will connect to the remote device and retrieve the current
+ running-config to use as a base for comparing against the contents of source. There
+ are times when it is not desirable to have the task get the current running-config
+ for every task in a playbook. The I(config) argument allows the implementer
+ to pass in the configuration to use as the base config for comparison.
+ type: str
+ state:
+ description:
+ - The C(state) argument controls the operational state of eAPI on the remote device. When
+ this argument is set to C(started), eAPI is enabled to receive requests and
+ when this argument is C(stopped), eAPI is disabled and will not receive requests.
+ type: str
+ default: started
+ choices:
+ - started
+ - stopped
+"""
+
+EXAMPLES = """
+- name: Enable eAPI access with default configuration
+ arista.eos.eos_eapi:
+ state: started
+
+- name: Enable eAPI with no HTTP, HTTPS at port 9443, local HTTP at port 80, and socket
+ enabled
+ arista.eos.eos_eapi:
+ state: started
+ http: false
+ https_port: 9443
+ local_http: yes
+ local_http_port: 80
+ socket: yes
+
+- name: Shutdown eAPI access
+ arista.eos.eos_eapi:
+ state: stopped
+"""
+
+RETURN = """
+commands:
+ description: The list of configuration mode commands to send to the device
+ returned: always
+ type: list
+ sample:
+ - management api http-commands
+ - protocol http port 81
+ - no protocol https
+urls:
+ description: Hash of URL endpoints eAPI is listening on per interface
+ returned: when eAPI is started
+ type: dict
+ sample: {'Management1': ['http://172.26.10.1:80']}
+session_name:
+ description: The EOS config session name used to load the configuration
+ returned: when changed is True
+ type: str
+ sample: ansible_1479315771
+"""
+import re
+import time
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.six import iteritems
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.eos import (
+ load_config,
+ run_commands,
+)
+
+
+def validate_http_port(value, module):
+ if not 1 <= value <= 65535:
+ module.fail_json(msg="http_port must be between 1 and 65535")
+
+
+def validate_https_port(value, module):
+ if not 1 <= value <= 65535:
+ module.fail_json(msg="http_port must be between 1 and 65535")
+
+
+def validate_local_http_port(value, module):
+ if not 1 <= value <= 65535:
+ module.fail_json(msg="http_port must be between 1 and 65535")
+
+
+def validate_vrf(value, module):
+ out = run_commands(module, ["show vrf"])
+ configured_vrfs = []
+ lines = out[0].strip().splitlines()[3:]
+ for line in lines:
+ if not line:
+ continue
+ splitted_line = re.split(r"\s{2,}", line.strip())
+ if len(splitted_line) > 2:
+ configured_vrfs.append(splitted_line[0])
+
+ configured_vrfs.append("default")
+ if value not in configured_vrfs:
+ module.fail_json(
+ msg="vrf `%s` is not configured on the system" % value,
+ )
+
+
+def map_obj_to_commands(updates, module, warnings):
+ commands = list()
+ want, have = updates
+
+ def needs_update(x):
+ return want.get(x) is not None and (want.get(x) != have.get(x))
+
+ def add(cmd):
+ if "management api http-commands" not in commands:
+ commands.insert(0, "management api http-commands")
+ commands.append(cmd)
+
+ if any((needs_update("http"), needs_update("http_port"))):
+ if want["http"] is False:
+ add("no protocol http")
+ else:
+ if have["http"] is False and want["http"] in (False, None):
+ warnings.append(
+ "protocol http is not enabled, not configuring http port value",
+ )
+ else:
+ port = want["http_port"] or 80
+ add("protocol http port %s" % port)
+
+ if any((needs_update("https"), needs_update("https_port"))):
+ if want["https"] is False:
+ add("no protocol https")
+ else:
+ if have["https"] is False and want["https"] in (False, None):
+ warnings.append(
+ "protocol https is not enabled, not configuring https port value",
+ )
+ else:
+ port = want["https_port"] or 443
+ add("protocol https port %s" % port)
+
+ if any((needs_update("local_http"), needs_update("local_http_port"))):
+ if want["local_http"] is False:
+ add("no protocol http localhost")
+ else:
+ if have["local_http"] is False and want["local_http"] in (
+ False,
+ None,
+ ):
+ warnings.append(
+ "protocol local_http is not enabled, not configuring local_http port value",
+ )
+ else:
+ port = want["local_http_port"] or 8080
+ add("protocol http localhost port %s" % port)
+
+ if any((needs_update("socket"), needs_update("socket"))):
+ if want["socket"] is False:
+ add("no protocol unix-socket")
+ else:
+ add("protocol unix-socket")
+ if needs_update("state"):
+ if want["state"] == "stopped":
+ add("shutdown")
+ elif want["state"] == "started":
+ add("no shutdown")
+
+ if needs_update("vrf"):
+ add("vrf %s" % want["vrf"])
+ # switching operational vrfs here
+ # need to add the desired state as well
+ if want["state"] == "stopped":
+ add("shutdown")
+ elif want["state"] == "started":
+ add("no shutdown")
+
+ return commands
+
+
+def parse_state(data):
+ if data[0]["enabled"]:
+ return "started"
+ else:
+ return "stopped"
+
+
+def map_config_to_obj(module):
+ out = run_commands(module, ["show management api http-commands | json"])
+ return {
+ "http": out[0]["httpServer"]["configured"],
+ "http_port": out[0]["httpServer"]["port"],
+ "https": out[0]["httpsServer"]["configured"],
+ "https_port": out[0]["httpsServer"]["port"],
+ "local_http": out[0]["localHttpServer"]["configured"],
+ "local_http_port": out[0]["localHttpServer"]["port"],
+ "socket": out[0]["unixSocketServer"]["configured"],
+ "vrf": out[0]["vrf"] or "default",
+ "state": parse_state(out),
+ }
+
+
+def map_params_to_obj(module):
+ obj = {
+ "http": module.params["http"],
+ "http_port": module.params["http_port"],
+ "https": module.params["https"],
+ "https_port": module.params["https_port"],
+ "local_http": module.params["local_http"],
+ "local_http_port": module.params["local_http_port"],
+ "socket": module.params["socket"],
+ "vrf": module.params["vrf"],
+ "state": module.params["state"],
+ }
+
+ for key, value in iteritems(obj):
+ if value:
+ validator = globals().get("validate_%s" % key)
+ if validator:
+ validator(value, module)
+
+ return obj
+
+
+def verify_state(updates, module):
+ want, have = updates
+
+ invalid_state = [
+ ("http", "httpServer"),
+ ("https", "httpsServer"),
+ ("local_http", "localHttpServer"),
+ ("socket", "unixSocketServer"),
+ ]
+
+ timeout = module.params["timeout"]
+ state = module.params["state"]
+
+ while invalid_state:
+ out = run_commands(
+ module,
+ ["show management api http-commands | json"],
+ )
+ for index, item in enumerate(invalid_state):
+ want_key, eapi_key = item
+ if want[want_key] is not None:
+ if want[want_key] == out[0][eapi_key]["running"]:
+ del invalid_state[index]
+ elif state == "stopped":
+ if not out[0][eapi_key]["running"]:
+ del invalid_state[index]
+ else:
+ del invalid_state[index]
+ time.sleep(1)
+ timeout -= 1
+ if timeout == 0:
+ module.fail_json(
+ msg="timeout expired before eapi running state changed",
+ )
+
+
+def collect_facts(module, result):
+ out = run_commands(module, ["show management api http-commands | json"])
+ facts = dict(eos_eapi_urls=dict())
+ for each in out[0]["urls"]:
+ intf, url = each.split(":", 1)
+ key = str(intf).strip()
+ if key not in facts["eos_eapi_urls"]:
+ facts["eos_eapi_urls"][key] = list()
+ facts["eos_eapi_urls"][key].append(str(url).strip())
+ result["ansible_facts"] = facts
+
+
+def main():
+ """main entry point for module execution"""
+ argument_spec = dict(
+ http=dict(aliases=["enable_http"], type="bool"),
+ http_port=dict(type="int"),
+ https=dict(aliases=["enable_https"], type="bool"),
+ https_port=dict(type="int"),
+ local_http=dict(aliases=["enable_local_http"], type="bool"),
+ local_http_port=dict(type="int"),
+ socket=dict(aliases=["enable_socket"], type="bool"),
+ timeout=dict(type="int", default=30),
+ vrf=dict(default="default"),
+ config=dict(),
+ state=dict(default="started", choices=["stopped", "started"]),
+ )
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=True,
+ )
+
+ result = {"changed": False}
+
+ warnings = list()
+ if module.params["config"]:
+ warnings.append(
+ "config parameter is no longer necessary and will be ignored",
+ )
+
+ want = map_params_to_obj(module)
+ have = map_config_to_obj(module)
+
+ commands = map_obj_to_commands((want, have), module, warnings)
+ 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
+
+ if result["changed"]:
+ verify_state((want, have), module)
+
+ collect_facts(module, result)
+
+ if warnings:
+ result["warnings"] = warnings
+
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_facts.py b/ansible_collections/arista/eos/plugins/modules/eos_facts.py
new file mode 100644
index 000000000..f404d54bb
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_facts.py
@@ -0,0 +1,210 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 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
+
+
+DOCUMENTATION = """
+module: eos_facts
+author:
+- Peter Sprygada (@privateip)
+- Nathaniel Case (@Qalthos)
+short_description: Collect facts from remote devices running Arista EOS
+description:
+- Collects facts from Arista devices running the EOS operating system. This module
+ places the facts gathered in the fact tree keyed by the respective resource name. The
+ facts module will always collect a base set of facts from the device and can enable
+ or disable collection of additional facts.
+version_added: 1.0.0
+options:
+ gather_subset:
+ description:
+ - When supplied, this argument will restrict the facts collected to a given subset. Possible
+ values for this argument include C(all), C(hardware), C(config), C(legacy), C(interfaces), and C(min).
+ Can specify a list of values to include a larger subset. Values can also be used
+ with an initial C(!) to specify that a specific subset should not be collected.
+ required: false
+ type: list
+ elements: str
+ default: 'min'
+ gather_network_resources:
+ description:
+ - When supplied, this argument will restrict the facts collected to a given subset.
+ Possible values for this argument include all and the resources like interfaces,
+ vlans etc. Can specify a list of values to include a larger subset. Values can
+ also be used with an initial C(!) to specify that a specific subset should
+ not be collected. Values can also be used with an initial C(!) to specify
+ that a specific subset should not be collected. Valid subsets are 'all', 'interfaces',
+ 'l2_interfaces', 'l3_interfaces', 'lacp', 'lacp_interfaces', 'lag_interfaces',
+ 'lldp_global', 'lldp_interfaces', 'vlans', 'acls'.
+ required: false
+ type: list
+ elements: str
+ available_network_resources:
+ description: When 'True' a list of network resources for which resource modules are available will be provided.
+ type: bool
+ default: false
+"""
+
+EXAMPLES = """
+- name: Gather all legacy facts
+- arista.eos.eos_facts:
+ gather_subset: all
+
+- name: Gather only the config and default facts
+ arista.eos.eos_facts:
+ gather_subset:
+ - config
+
+- name: Do not gather hardware facts
+ arista.eos.eos_facts:
+ gather_subset:
+ - '!hardware'
+
+- name: Gather legacy and resource facts
+ arista.eos.eos_facts:
+ gather_subset: all
+ gather_network_resources: all
+
+- name: Gather only the interfaces resource facts and no legacy facts
+- arista.eos.eos_facts:
+ gather_subset:
+ - '!all'
+ - '!min'
+ gather_network_resources:
+ - interfaces
+
+- name: Gather all resource facts and minimal legacy facts
+ arista.eos.eos_facts:
+ gather_subset: min
+ gather_network_resources: all
+"""
+
+RETURN = """
+ansible_net_gather_subset:
+ description: The list of fact subsets collected from the device
+ returned: always
+ type: list
+
+ansible_net_gather_network_resources:
+ description: The list of fact for network resource subsets collected from the device
+ returned: when the resource is configured
+ type: list
+
+# default
+ansible_net_model:
+ description: The model name returned from the device
+ returned: always
+ type: str
+ansible_net_serialnum:
+ description: The serial number of the remote device
+ returned: always
+ type: str
+ansible_net_version:
+ description: The operating system version running on the remote device
+ returned: always
+ type: str
+ansible_net_hostname:
+ description: The configured hostname of the device
+ returned: always
+ type: str
+ansible_net_image:
+ description: The image file the device is running
+ returned: always
+ type: str
+ansible_net_fqdn:
+ description: The fully qualified domain name of the device
+ returned: always
+ type: str
+ansible_net_api:
+ description: The name of the transport
+ returned: always
+ type: str
+ansible_net_python_version:
+ description: The Python version Ansible controller is using
+ returned: always
+ type: str
+
+# hardware
+ansible_net_filesystems:
+ description: All file system names available on the device
+ returned: when hardware is configured
+ type: list
+ansible_net_memfree_mb:
+ description: The available free memory on the remote device in Mb
+ returned: when hardware is configured
+ type: int
+ansible_net_memtotal_mb:
+ description: The total memory on the remote device in Mb
+ returned: when hardware is configured
+ type: int
+
+# config
+ansible_net_config:
+ description: The current active config from the device
+ returned: when config is configured
+ type: str
+
+# interfaces
+ansible_net_all_ipv4_addresses:
+ description: All IPv4 addresses configured on the device
+ returned: when interfaces is configured
+ type: list
+ansible_net_all_ipv6_addresses:
+ description: All IPv6 addresses configured on the device
+ returned: when interfaces is configured
+ type: list
+ansible_net_interfaces:
+ description: A hash of all interfaces running on the system
+ returned: when interfaces is configured
+ type: dict
+ansible_net_neighbors:
+ description: The list of LLDP neighbors from the remote device
+ returned: when interfaces is configured
+ type: dict
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.facts.facts import (
+ FactsArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.facts.facts import (
+ FACT_RESOURCE_SUBSETS,
+ Facts,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: ansible_facts
+ """
+ argument_spec = FactsArgs.argument_spec
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=True,
+ )
+ warnings = []
+ ansible_facts = {}
+ if module.params.get("available_network_resources"):
+ ansible_facts["available_network_resources"] = sorted(
+ FACT_RESOURCE_SUBSETS.keys(),
+ )
+ result = Facts(module).get_facts()
+ additional_facts, additional_warnings = result
+ ansible_facts.update(additional_facts)
+ warnings.extend(additional_warnings)
+
+ module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_hostname.py b/ansible_collections/arista/eos/plugins/modules/eos_hostname.py
new file mode 100644
index 000000000..dddadb71a
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_hostname.py
@@ -0,0 +1,333 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2022 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+The module file for eos_hostname
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+---
+module: eos_hostname
+short_description: Manages hostname resource module
+description: This module configures and manages the attribute of hostname on Arista
+ EOS platforms.
+version_added: 4.1.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.60M
+- This module works with connection C(network_cli). See the L(EOS Platform Options,eos_platform_options).
+options:
+ config:
+ description: A dictionary of hostname options
+ type: dict
+ suboptions:
+ hostname:
+ description:
+ - The system's hostname
+ type: str
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section hostname).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ - The states I(rendered), I(gathered) and I(parsed) does not perform any change
+ on the device.
+ - The state I(rendered) will transform the configuration in C(config) option to
+ platform specific CLI commands which will be returned in the I(rendered) key
+ within the result. For state I(rendered) active connection to remote host is
+ not required.
+ - The states I(merged), I(replaced) and I(overridden) have identical
+ behaviour for this module.
+ - The state I(gathered) will fetch the running configuration from device and transform
+ it into structured data in the format as per the resource module argspec and
+ the value is returned in the I(gathered) key within the result.
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into JSON format as per the resource module parameters and the
+ value is returned in the I(parsed) key within the result. The value of C(running_config)
+ option should be the same format as the output of command
+ I(show running-config | section ^hostname) executed on device. For state I(parsed) active
+ connection to remote host is not required.
+ type: str
+ choices:
+ - deleted
+ - merged
+ - overridden
+ - replaced
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+"""
+
+EXAMPLES = """
+
+# Using state: merged
+# Before state:
+# -------------
+# test#show running-config | section ^hostname
+# hostname eos
+# Merged play:
+# ------------
+- name: Apply the provided configuration
+ arista.eos.eos_hostname:
+ config:
+ hostname: eos
+ state: merged
+# Commands Fired:
+# ---------------
+# "commands": [
+# "hostname eos",
+# ],
+# After state:
+# ------------
+# test#show running-config | section ^hostname
+# hostname eos
+
+
+# Using state: deleted
+# Before state:
+# -------------
+# test#show running-config | section ^hostname
+# hostname eosTest
+# Deleted play:
+# -------------
+- name: Remove all existing configuration
+ arista.eos.eos_hostname:
+ state: deleted
+# Commands Fired:
+# ---------------
+# "commands": [
+# "no hostname eosTest",
+# ],
+# After state:
+# ------------
+# test#show running-config | section ^hostname
+# hostname eos
+
+
+# Using state: overridden
+# Before state:
+# -------------
+# test#show running-config | section ^hostname
+# hostname eos
+# Overridden play:
+# ----------------
+- name: Override commands with provided configuration
+ arista.eos.eos_hostname:
+ config:
+ hostname: eosTest
+ state: overridden
+# Commands Fired:
+# ---------------
+# "commands": [
+# "hostname eosTest",
+# ],
+# After state:
+# ------------
+# test#show running-config | section ^hostname
+# hostname eosTest
+
+
+# Using state: replaced
+# Before state:
+# -------------
+# test#show running-config | section ^hostname
+# hostname eosTest
+# Replaced play:
+# --------------
+- name: Replace commands with provided configuration
+ arista.eos.eos_hostname:
+ config:
+ hostname: eosTest
+ state: replaced
+# Commands Fired:
+# ---------------
+# "commands": [],
+# After state:
+# ------------
+# test#show running-config | section ^hostname
+# hostname eosTest
+
+# Using state: gathered
+# Before state:
+# -------------
+#test#show running-config | section ^hostname
+# hostname eosTest
+# Gathered play:
+# --------------
+- name: Gather listed hostname config
+ arista.eos.eos_hostname:
+ state: gathered
+# Module Execution Result:
+# ------------------------
+# "gathered": {
+# "hostname": "eosTest"
+# },
+
+# Using state: rendered
+# Rendered play:
+# --------------
+- name: Render the commands for provided configuration
+ arista.eos.eos_hostname:
+ config:
+ hostname: eosTest
+ state: rendered
+# Module Execution Result:
+# ------------------------
+# "rendered": [
+# "hostname eosTest",
+# ]
+
+# Using state: parsed
+# File: parsed.cfg
+# ----------------
+# hostname eosTest
+# Parsed play:
+# ------------
+- name: Parse the provided configuration with the existing running configuration
+ arista.eos.eos_hostname:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+# Module Execution Result:
+# ------------------------
+# "parsed": {
+# "hostname": "eosTest"
+# }
+"""
+
+RETURN = """
+before:
+ description: The configuration prior to the module execution.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+after:
+ description: The resulting configuration after module execution.
+ returned: when changed
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: list
+ sample:
+ - hostname eos
+rendered:
+ description: The provided configuration in the task rendered in device-native format (offline).
+ returned: when I(state) is C(rendered)
+ type: list
+ sample:
+ - hostname eos
+gathered:
+ description: Facts about the network resource gathered from the remote device as structured data.
+ returned: when I(state) is C(gathered)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+parsed:
+ description: The device native config provided in I(running_config) option parsed into structured data as per module argspec.
+ returned: when I(state) is C(parsed)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+"""
+
+RETURN = """
+before:
+ description: The configuration prior to the module execution.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+after:
+ description: The resulting configuration after module execution.
+ returned: when changed
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: list
+ sample:
+ - hostname eost_test
+rendered:
+ description: The provided configuration in the task rendered in device-native format (offline).
+ returned: when I(state) is C(rendered)
+ type: list
+ sample:
+ - hostname eost_test
+gathered:
+ description: Facts about the network resource gathered from the remote device as structured data.
+ returned: when I(state) is C(gathered)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+parsed:
+ description: The device native config provided in I(running_config) option parsed into structured data as per module argspec.
+ returned: when I(state) is C(parsed)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.hostname.hostname import (
+ HostnameArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.hostname.hostname import (
+ Hostname,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=HostnameArgs.argument_spec,
+ mutually_exclusive=[["config", "running_config"]],
+ required_if=[
+ ["state", "merged", ["config"]],
+ ["state", "replaced", ["config"]],
+ ["state", "overridden", ["config"]],
+ ["state", "rendered", ["config"]],
+ ["state", "parsed", ["running_config"]],
+ ],
+ supports_check_mode=True,
+ )
+
+ result = Hostname(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_interfaces.py b/ansible_collections/arista/eos/plugins/modules/eos_interfaces.py
new file mode 100644
index 000000000..c7d0ae021
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_interfaces.py
@@ -0,0 +1,415 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+##############################################
+# WARNING #
+##############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+##############################################
+
+"""
+The module file for eos_interfaces
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_interfaces
+short_description: Interfaces resource module
+description:
+- This module manages the interface attributes of Arista EOS interfaces.
+version_added: 1.0.0
+author:
+- Nathaniel Case (@qalthos)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description: The provided configuration
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Full name of the interface, e.g. GigabitEthernet1.
+ type: str
+ required: True
+ description:
+ description:
+ - Interface description
+ type: str
+ duplex:
+ description:
+ - Interface link status. Applicable for Ethernet interfaces only.
+ - Values other than C(auto) must also set I(speed).
+ - Ignored when I(speed) is set above C(1000).
+ type: str
+ enabled:
+ default: true
+ description:
+ - Administrative state of the interface.
+ - Set the value to C(true) to administratively enable the interface or C(false)
+ to disable it.
+ type: bool
+ mtu:
+ description:
+ - MTU for a specific interface. Must be an even number between 576 and 9216.
+ Applicable for Ethernet interfaces only.
+ type: int
+ speed:
+ description:
+ - Interface link speed. Applicable for Ethernet interfaces only.
+ type: str
+ mode:
+ description:
+ - Manage Layer2 or Layer3 state of the interface. Applicable for Ethernet
+ and port channel interfaces only.
+ choices:
+ - layer2
+ - layer3
+ type: str
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section ^interface).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - parsed
+ - rendered
+ - gathered
+ default: merged
+ description:
+ - The state of the configuration after module completion.
+ type: str
+
+"""
+
+EXAMPLES = """
+
+# Using merged
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# description "Interface 1"
+# !
+# interface Ethernet2
+# !
+# interface Management1
+# description "Management interface"
+# ip address dhcp
+# !
+
+- name: Merge provided configuration with device configuration
+ arista.eos.eos_interfaces:
+ config:
+ - name: Ethernet1
+ enabled: true
+ mode: layer3
+ - name: Ethernet2
+ description: Configured by Ansible
+ enabled: false
+ state: merged
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# description "Interface 1"
+# no switchport
+# !
+# interface Ethernet2
+# description "Configured by Ansible"
+# shutdown
+# !
+# interface Management1
+# description "Management interface"
+# ip address dhcp
+# !
+
+# Using replaced
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# description "Interface 1"
+# !
+# interface Ethernet2
+# !
+# interface Management1
+# description "Management interface"
+# ip address dhcp
+# !
+
+- name: Replaces device configuration of listed interfaces with provided configuration
+ arista.eos.eos_interfaces:
+ config:
+ - name: Ethernet1
+ enabled: true
+ - name: Ethernet2
+ description: Configured by Ansible
+ enabled: false
+ state: replaced
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# !
+# interface Ethernet2
+# description "Configured by Ansible"
+# shutdown
+# !
+# interface Management1
+# description "Management interface"
+# ip address dhcp
+# !
+
+# Using overridden
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# description "Interface 1"
+# !
+# interface Ethernet2
+# !
+# interface Management1
+# description "Management interface"
+# ip address dhcp
+# !
+
+- name: Overrides all device configuration with provided configuration
+ arista.eos.eos_interfaces:
+ config:
+ - name: Ethernet1
+ enabled: true
+ - name: Ethernet2
+ description: Configured by Ansible
+ enabled: false
+ state: overridden
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# !
+# interface Ethernet2
+# description "Configured by Ansible"
+# shutdown
+# !
+# interface Management1
+# ip address dhcp
+# !
+
+# Using deleted
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# description "Interface 1"
+# no switchport
+# !
+# interface Ethernet2
+# !
+# interface Management1
+# description "Management interface"
+# ip address dhcp
+# !
+
+- name: Delete or return interface parameters to default settings
+ arista.eos.eos_interfaces:
+ config:
+ - name: Ethernet1
+ state: deleted
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# !
+# interface Ethernet2
+# !
+# interface Management1
+# description "Management interface"
+# ip address dhcp
+# !
+
+# Using rendered
+
+- name: Use Rendered to convert the structured data to native config
+ arista.eos.eos_interfaces:
+ config:
+ - name: Ethernet1
+ enabled: true
+ mode: layer3
+ - name: Ethernet2
+ description: Configured by Ansible
+ enabled: false
+ state: merged
+
+# Output:
+# ------------
+
+# - "interface Ethernet1"
+# - "description "Interface 1""
+# - "no swithcport"
+# - "interface Ethernet2"
+# - "description "Configured by Ansible""
+# - "shutdown"
+# - "interface Management1"
+# - "description "Management interface""
+# - "ip address dhcp"
+
+# Using parsed
+# parsed.cfg
+
+# interface Ethernet1
+# description "Interface 1"
+# !
+# interface Ethernet2
+# description "Configured by Ansible"
+# shutdown
+# !
+
+- name: Use parsed to convert native configs to structured data
+ arista.eos.interfaces:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# Output
+# parsed:
+# - name: Ethernet1
+# enabled: True
+# mode: layer2
+# - name: Ethernet2
+# description: 'Configured by Ansible'
+# enabled: False
+# mode: layer2
+
+# Using gathered:
+
+# Existing config on the device
+# -----------------------------
+# interface Ethernet1
+# description "Interface 1"
+# !
+# interface Ethernet2
+# description "Configured by Ansible"
+# shutdown
+# !
+
+- name: Gather interfaces facts from the device
+ arista.eos.interfaces:
+ state: gathered
+
+# output
+# gathered:
+# - name: Ethernet1
+# enabled: True
+# mode: layer2
+# - name: Ethernet2
+# description: 'Configured by Ansible'
+# enabled: False
+# mode: layer2
+"""
+
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: dict
+ sample: The configuration returned will always be in the same format of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: dict
+ sample: The configuration returned will always be in the same format of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample: ['interface Ethernet2', 'shutdown', 'speed 10full']
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.interfaces.interfaces import (
+ InterfacesArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.interfaces.interfaces import (
+ Interfaces,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+
+ module = AnsibleModule(
+ argument_spec=InterfacesArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = Interfaces(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_l2_interfaces.py b/ansible_collections/arista/eos/plugins/modules/eos_l2_interfaces.py
new file mode 100644
index 000000000..863a2cf2a
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_l2_interfaces.py
@@ -0,0 +1,430 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+##############################################
+# WARNING #
+##############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+##############################################
+
+"""
+The module file for eos_l2_interfaces
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_l2_interfaces
+short_description: L2 interfaces resource module
+description: This module provides declarative management of Layer-2 interface on Arista
+ EOS devices.
+version_added: 1.0.0
+author: Nathaniel Case (@qalthos)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description: A dictionary of Layer-2 interface options
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Full name of interface, e.g. Ethernet1.
+ type: str
+ required: true
+ access:
+ description:
+ - Switchport mode access command to configure the interface as a layer 2 access.
+ type: dict
+ suboptions:
+ vlan:
+ description:
+ - Configure given VLAN in access port. It's used as the access VLAN ID.
+ type: int
+ trunk:
+ description:
+ - Switchport mode trunk command to configure the interface as a Layer 2 trunk.
+ type: dict
+ suboptions:
+ native_vlan:
+ description:
+ - Native VLAN to be configured in trunk port. It is used as the trunk
+ native VLAN ID.
+ type: int
+ trunk_allowed_vlans:
+ description:
+ - List of allowed VLANs in a given trunk port. These are the only VLANs
+ that will be configured on the trunk.
+ type: list
+ elements: str
+ mode:
+ description:
+ - Mode in which interface needs to be configured.
+ - Access mode is not shown in interface facts, so idempotency will not be
+ maintained for switchport mode access and every time the output will come
+ as changed=True.
+ type: str
+ choices:
+ - access
+ - trunk
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section ^interface).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - parsed
+ - rendered
+ - gathered
+ default: merged
+ description:
+ - The state of the configuration after module completion
+ type: str
+
+"""
+
+EXAMPLES = """
+
+# Using merged
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# switchport access vlan 20
+# !
+# interface Ethernet2
+# switchport trunk native vlan 20
+# switchport mode trunk
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+# !
+
+- name: Merge provided configuration with device configuration.
+ arista.eos.eos_l2_interfaces:
+ config:
+ - name: Ethernet1
+ mode: trunk
+ trunk:
+ native_vlan: 10
+ - name: Ethernet2
+ mode: access
+ access:
+ vlan: 30
+ state: merged
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# switchport trunk native vlan 10
+# switchport mode trunk
+# !
+# interface Ethernet2
+# switchport access vlan 30
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+# !
+
+# Using replaced
+
+# Before state:
+# -------------
+#
+# veos2#show running-config | s int
+# interface Ethernet1
+# switchport access vlan 20
+# !
+# interface Ethernet2
+# switchport trunk native vlan 20
+# switchport mode trunk
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+# !
+
+- name: Replace device configuration of specified L2 interfaces with provided configuration.
+ arista.eos.eos_l2_interfaces:
+ config:
+ - name: Ethernet1
+ mode: trunk
+ trunk:
+ native_vlan: 20
+ trunk_allowed_vlans: 5-10, 15
+ state: replaced
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# switchport trunk native vlan 20
+# switchport trunk allowed vlan 5-10,15
+# switchport mode trunk
+# !
+# interface Ethernet2
+# switchport trunk native vlan 20
+# switchport mode trunk
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+# !
+
+# Using overridden
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# switchport access vlan 20
+# !
+# interface Ethernet2
+# switchport trunk native vlan 20
+# switchport mode trunk
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+# !
+
+- name: Override device configuration of all L2 interfaces on device with provided
+ configuration.
+ arista.eos.eos_l2_interfaces:
+ config:
+ - name: Ethernet2
+ mode: access
+ access:
+ vlan: 30
+ state: overridden
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# !
+# interface Ethernet2
+# switchport access vlan 30
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+# !
+
+# Using deleted
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# switchport access vlan 20
+# !
+# interface Ethernet2
+# switchport trunk native vlan 20
+# switchport mode trunk
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+# !
+
+- name: Delete EOS L2 interfaces as in given arguments.
+ arista.eos.eos_l2_interfaces:
+ config:
+ - name: Ethernet1
+ - name: Ethernet2
+ state: deleted
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# !
+# interface Ethernet2
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+
+# using rendered
+
+- name: Use Rendered to convert the structured data to native config
+ arista.eos.eos_l2_interfaces:
+ config:
+ - name: Ethernet1
+ mode: trunk
+ trunk:
+ native_vlan: 10
+ - name: Ethernet2
+ mode: access
+ access:
+ vlan: 30
+ state: merged
+
+# Output :
+# ------------
+#
+# - "interface Ethernet1"
+# - "switchport trunk native vlan 10"
+# - "switchport mode trunk"
+# - "interface Ethernet2"
+# - "switchport access vlan 30"
+# - "interface Management1"
+# - "ip address dhcp"
+# - "ipv6 address auto-config"
+
+
+# using parsed
+
+# parsed.cfg
+
+# interface Ethernet1
+# switchport trunk native vlan 10
+# switchport mode trunk
+# !
+# interface Ethernet2
+# switchport access vlan 30
+# !
+
+- name: Use parsed to convert native configs to structured data
+ arista.eos.l2_interfaces:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# Output:
+# parsed:
+# - name: Ethernet1
+# mode: trunk
+# trunk:
+# native_vlan: 10
+# - name: Ethernet2
+# mode: access
+# access:
+# vlan: 30
+
+
+# Using gathered:
+# Existing config on the device:
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# switchport trunk native vlan 10
+# switchport mode trunk
+# !
+# interface Ethernet2
+# switchport access vlan 30
+# !
+
+- name: Gather interfaces facts from the device
+ arista.eos.l2_interfaces:
+ state: gathered
+# output:
+# gathered:
+# - name: Ethernet1
+# mode: trunk
+# trunk:
+# native_vlan: 10
+# - name: Ethernet2
+# mode: access
+# access:
+# vlan: 30
+
+"""
+
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: list
+ sample: The configuration returned will always be in the same format of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: list
+ sample: The configuration returned will always be in the same format of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample: ['interface Ethernet2', 'switchport access vlan 20']
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.l2_interfaces.l2_interfaces import (
+ L2_interfacesArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.l2_interfaces.l2_interfaces import (
+ L2_interfaces,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+
+ module = AnsibleModule(
+ argument_spec=L2_interfacesArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = L2_interfaces(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_l3_interfaces.py b/ansible_collections/arista/eos/plugins/modules/eos_l3_interfaces.py
new file mode 100644
index 000000000..93da7612c
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_l3_interfaces.py
@@ -0,0 +1,412 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_l3_interfaces
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_l3_interfaces
+short_description: L3 interfaces resource module
+description: This module provides declarative management of Layer 3 interfaces on
+ Arista EOS devices.
+version_added: 1.0.0
+author: Nathaniel Case (@qalthos)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+ 'eos_l2_interfaces/eos_interfaces' should be used for preparing the interfaces , before applying L3 configurations using
+ this module (eos_l3_interfaces).
+options:
+ config:
+ description: A dictionary of Layer 3 interface options
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Full name of the interface, i.e. Ethernet1.
+ type: str
+ required: true
+ ipv4:
+ description:
+ - List of IPv4 addresses to be set for the Layer 3 interface mentioned in
+ I(name) option.
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description:
+ - IPv4 address to be set in the format <ipv4 address>/<mask> eg. 192.0.2.1/24,
+ or C(dhcp) to query DHCP for an IP address.
+ type: str
+ secondary:
+ description:
+ - Whether or not this address is a secondary address.
+ type: bool
+ virtual:
+ description:
+ - Whether or not this address is a virtual address.
+ type: bool
+ ipv6:
+ description:
+ - List of IPv6 addresses to be set for the Layer 3 interface mentioned in
+ I(name) option.
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description:
+ - IPv6 address to be set in the address format is <ipv6 address>/<mask>
+ eg. 2001:db8:2201:1::1/64 or C(auto-config) to use SLAAC to chose an
+ address.
+ type: str
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section ^interface).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state of the configuration after module completion
+ type: str
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - parsed
+ - gathered
+ - rendered
+ default: merged
+
+"""
+
+EXAMPLES = """
+
+# Using deleted
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# ip address 192.0.2.12/24
+# !
+# interface Ethernet2
+# ipv6 address 2001:db8::1/64
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+
+- name: Delete L3 attributes of given interfaces.
+ arista.eos.eos_l3_interfaces:
+ config:
+ - name: Ethernet1
+ - name: Ethernet2
+ state: deleted
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# !
+# interface Ethernet2
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+
+
+# Using merged
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# ip address 192.0.2.12/24
+# !
+# interface Ethernet2
+# ipv6 address 2001:db8::1/64
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+
+- name: Merge provided configuration with device configuration.
+ arista.eos.eos_l3_interfaces:
+ config:
+ - name: Ethernet1
+ ipv4:
+ - address: 198.51.100.14/24
+ - name: Ethernet2
+ ipv4:
+ - address: 203.0.113.27/24
+ state: merged
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# ip address 198.51.100.14/24
+# !
+# interface Ethernet2
+# ip address 203.0.113.27/24
+# ipv6 address 2001:db8::1/64
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+
+
+# Using overridden
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# ip address 192.0.2.12/24
+# !
+# interface Ethernet2
+# ipv6 address 2001:db8::1/64
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+
+- name: Override device configuration of all L2 interfaces on device with provided
+ configuration.
+ arista.eos.eos_l3_interfaces:
+ config:
+ - name: Ethernet1
+ ipv6:
+ - address: 2001:db8:feed::1/96
+ - name: Management1
+ ipv4:
+ - address: dhcp
+ ipv6: auto-config
+ state: overridden
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# ipv6 address 2001:db8:feed::1/96
+# !
+# interface Ethernet2
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+
+
+# Using replaced
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# ip address 192.0.2.12/24
+# !
+# interface Ethernet2
+# ipv6 address 2001:db8::1/64
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+
+- name: Replace device configuration of specified L2 interfaces with provided configuration.
+ arista.eos.eos_l3_interfaces:
+ config:
+ - name: Ethernet2
+ ipv4:
+ - address: 203.0.113.27/24
+ state: replaced
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# ip address 192.0.2.12/24
+# !
+# interface Ethernet2
+# ip address 203.0.113.27/24
+# !
+# interface Management1
+# ip address dhcp
+# ipv6 address auto-config
+
+# Using parsed:
+
+# parsed.cfg
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# ip address 198.51.100.14/24
+# !
+# interface Ethernet2
+# ip address 203.0.113.27/24
+# !
+
+- name: Use parsed to convert native configs to structured data
+ arista.eos.interfaces:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# Output:
+
+# parsed:
+# - name: Ethernet1
+# ipv4:
+# - address: 198.51.100.14/24
+# - name: Ethernet2
+# ipv4:
+# - address: 203.0.113.27/24
+
+# Using rendered:
+
+- name: Use Rendered to convert the structured data to native config
+ arista.eos.eos_l3_interfaces:
+ config:
+ - name: Ethernet1
+ ipv4:
+ - address: 198.51.100.14/24
+ - name: Ethernet2
+ ipv4:
+ - address: 203.0.113.27/24
+ state: rendered
+
+# Output
+# ------------
+#rendered:
+# - "interface Ethernet1"
+# - "ip address 198.51.100.14/24"
+# - "interface Ethernet2"
+# - "ip address 203.0.113.27/24"
+
+# using gathered:
+
+# Native COnfig:
+# veos#show running-config | section interface
+# interface Ethernet1
+# ip address 198.51.100.14/24
+# !
+# interface Ethernet2
+# ip address 203.0.113.27/24
+# !
+
+- name: Gather l3 interfaces facts from the device
+ arista.eos.l3_interfaces:
+ state: gathered
+
+# gathered:
+# - name: Ethernet1
+# ipv4:
+# - address: 198.51.100.14/24
+# - name: Ethernet2
+# ipv4:
+# - address: 203.0.113.27/24
+
+
+"""
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample: ['interface Ethernet2', 'ip address 192.0.2.12/24']
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.l3_interfaces.l3_interfaces import (
+ L3_interfacesArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.l3_interfaces.l3_interfaces import (
+ L3_interfaces,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+ module = AnsibleModule(
+ argument_spec=L3_interfacesArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = L3_interfaces(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_lacp.py b/ansible_collections/arista/eos/plugins/modules/eos_lacp.py
new file mode 100644
index 000000000..d79ca8805
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_lacp.py
@@ -0,0 +1,247 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_lacp
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_lacp
+short_description: LACP resource module
+description:
+- This module manages Global Link Aggregation Control Protocol (LACP) on Arista EOS
+ devices.
+version_added: 1.0.0
+author: Nathaniel Case (@Qalthos)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description: LACP global options.
+ type: dict
+ suboptions:
+ system:
+ description: LACP system options.
+ type: dict
+ suboptions:
+ priority:
+ description:
+ - The system priority to use in LACP negotiations.
+ - Lower value is higher priority.
+ - Refer to vendor documentation for valid values.
+ type: int
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section ^lacp).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state of the configuration after module completion.
+ type: str
+ choices:
+ - merged
+ - replaced
+ - deleted
+ - parsed
+ - rendered
+ - gathered
+ default: merged
+
+"""
+EXAMPLES = """
+# Using merged
+
+# Before state:
+# -------------
+# veos# show running-config | include lacp
+# lacp system-priority 10
+
+- name: Merge provided global LACP attributes with device attributes
+ arista.eos.eos_lacp:
+ config:
+ system:
+ priority: 20
+ state: merged
+
+# After state:
+# ------------
+# veos# show running-config | include lacp
+# lacp system-priority 20
+#
+
+
+# Using replaced
+
+# Before state:
+# -------------
+# veos# show running-config | include lacp
+# lacp system-priority 10
+
+- name: Replace device global LACP attributes with provided attributes
+ arista.eos.eos_lacp:
+ config:
+ system:
+ priority: 20
+ state: replaced
+
+# After state:
+# ------------
+# veos# show running-config | include lacp
+# lacp system-priority 20
+#
+
+
+# Using deleted
+
+# Before state:
+# -------------
+# veos# show running-config | include lacp
+# lacp system-priority 10
+
+- name: Delete global LACP attributes
+ arista.eos.eos_lacp:
+ state: deleted
+
+# After state:
+# ------------
+# veos# show running-config | include lacp
+#
+
+#Using rendered:
+
+- name: Use Rendered to convert the structured data to native config
+ arista.eos.eos_lacp:
+ config:
+ system:
+ priority: 20
+ state: rendered
+
+# Output:
+# ------------
+# rendered:
+# - "lacp system-priority 20"
+#
+
+# Using parsed:
+
+# parsed.cfg
+# lacp system-priority 20
+
+- name: Use parsed to convert native configs to structured data
+ arista.eos.eos_lacp:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# Output:
+# parsed:
+# system:
+# priority: 20
+
+# Using gathered:
+# nathive config:
+# -------------
+# lacp system-priority 10
+
+- name: Gather lacp facts from the device
+ arista.eos.eos_lacp:
+ state: gathered
+
+# Output:
+# gathered:
+# system:
+# priority: 10
+#
+
+"""
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: dict
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: dict
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample: ['lacp system-priority 10']
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.lacp.lacp import (
+ LacpArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.lacp.lacp import (
+ Lacp,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+ module = AnsibleModule(
+ argument_spec=LacpArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = Lacp(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_lacp_interfaces.py b/ansible_collections/arista/eos/plugins/modules/eos_lacp_interfaces.py
new file mode 100644
index 000000000..47a3662e8
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_lacp_interfaces.py
@@ -0,0 +1,340 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_lacp_interfaces
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_lacp_interfaces
+short_description: LACP interfaces resource module
+description:
+- This module manages Link Aggregation Control Protocol (LACP) attributes of interfaces
+ on Arista EOS devices.
+version_added: 1.0.0
+author: Nathaniel Case (@Qalthos)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description: A dictionary of LACP interfaces options.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Full name of the interface (i.e. Ethernet1).
+ type: str
+ port_priority:
+ description:
+ - LACP port priority for the interface. Range 1-65535.
+ type: int
+ timer:
+ description:
+ - Rate at which PDUs are sent by LACP. At fast rate LACP is transmitted once
+ every 1 second. At normal rate LACP is transmitted every 30 seconds after
+ the link is bundled.
+ type: str
+ choices:
+ - fast
+ - normal
+ aliases:
+ - rate
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section ^interfaces).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state of the configuration after module completion.
+ type: str
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - parsed
+ - rendered
+ - gathered
+ default: merged
+
+"""
+EXAMPLES = """
+# Using merged
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# lacp port-priority 30
+# interface Ethernet2
+# lacp rate fast
+
+- name: Merge provided configuration with device configuration
+ arista.eos.eos_lacp_interfaces:
+ config:
+ - name: Ethernet1
+ rate: fast
+ - name: Ethernet2
+ rate: normal
+ state: merged
+
+#
+# -----------
+# After state
+# -----------
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# lacp port-priority 30
+# lacp rate fast
+# interface Ethernet2
+
+
+# Using replaced
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# lacp port-priority 30
+# interface Ethernet2
+# lacp rate fast
+
+- name: Replace existing LACP configuration of specified interfaces with provided
+ configuration
+ arista.eos.eos_lacp_interfaces:
+ config:
+ - name: Ethernet1
+ rate: fast
+ state: replaced
+
+#
+# -----------
+# After state
+# -----------
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# lacp rate fast
+# interface Ethernet2
+# lacp rate fast
+
+
+# Using overridden
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# lacp port-priority 30
+# interface Ethernet2
+# lacp rate fast
+
+- name: Override the LACP configuration of all the interfaces with provided configuration
+ arista.eos.eos_lacp_interfaces:
+ config:
+ - name: Ethernet1
+ rate: fast
+ state: overridden
+
+#
+# -----------
+# After state
+#
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# lacp rate fast
+# interface Ethernet2
+
+
+# Using deleted
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# lacp port-priority 30
+# interface Ethernet2
+# lacp rate fast
+
+- name: Delete LACP attributes of given interfaces (or all interfaces if none specified).
+ arista.eos.eos_lacp_interfaces:
+ state: deleted
+
+#
+# -----------
+# After state
+# -----------
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# interface Ethernet2
+
+# using rendered:
+
+- name: Use Rendered to convert the structured data to native config
+ arista.eos.eos_lacp_interfaces:
+ config:
+ - name: Ethernet1
+ rate: fast
+ - name: Ethernet2
+ rate: normal
+ state: rendered
+
+#
+# -----------
+# Output
+# -----------
+# rendered:
+# - "interface Ethernet1"
+# - "lacp rate fast"
+
+# Using parsed:
+
+# parsed.cfg:
+# "interface Ethernet1"
+# "lacp rate fast"
+# "interface Ethernet2"
+
+- name: Use parsed to convert native configs to structured data
+ arista.eos.eos_lacp_interfaces:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# Output:
+# parsed:
+# - name: Ethernet1
+# rate: fast
+# - name: Ethernet2
+# rate: normal
+
+# Using gathered:
+# native config:
+# veos#show run | section ^interface
+# interface Ethernet1
+# lacp port-priority 30
+# interface Ethernet2
+# lacp rate fast
+
+- name: Gather LACP facts from the device
+ arista.eos.eos_lacp_interfaces:
+ state: gathered
+
+# Output:
+# gathered:
+# - name: Ethernet1
+# - name: Ethernet2
+# rate: fast
+
+"""
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample: ['interface Ethernet1', 'lacp rate fast']
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.lacp_interfaces.lacp_interfaces import (
+ Lacp_interfacesArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.lacp_interfaces.lacp_interfaces import (
+ Lacp_interfaces,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+ module = AnsibleModule(
+ argument_spec=Lacp_interfacesArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = Lacp_interfaces(module).execute_module()
+ 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
new file mode 100644
index 000000000..471652772
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_lag_interfaces.py
@@ -0,0 +1,342 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_lag_interfaces
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_lag_interfaces
+short_description: LAG interfaces resource module
+description: This module manages attributes of link aggregation groups on Arista EOS
+ devices.
+version_added: 1.0.0
+author: Nathaniel Case (@Qalthos)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description: A list of link aggregation group configurations.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Name of the port-channel interface of the link aggregation group (LAG) e.g.,
+ Port-Channel5.
+ type: str
+ required: true
+ members:
+ description:
+ - Ethernet interfaces that are part of the group.
+ type: list
+ elements: dict
+ suboptions:
+ member:
+ description:
+ - Name of ethernet interface that is a member of the LAG.
+ type: str
+ mode:
+ description:
+ - LAG mode for this interface.
+ type: str
+ choices:
+ - 'active'
+ - 'on'
+ - 'passive'
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section interfaces).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state of the configuration after module completion.
+ type: str
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - rendered
+ - gathered
+ - parsed
+ default: merged
+
+"""
+
+EXAMPLES = """
+
+# Using merged
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# channel-group 5 mode on
+# interface Ethernet2
+
+- name: Merge provided LAG attributes with existing device configuration
+ arista.eos.eos_lag_interfaces:
+ config:
+ - name: 5
+ members:
+ - member: Ethernet2
+ mode: on
+ state: merged
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# channel-group 5 mode on
+# interface Ethernet2
+# channel-group 5 mode on
+
+
+# Using replaced
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# channel-group 5 mode on
+# interface Ethernet2
+
+- name: Replace all device configuration of specified LAGs with provided configuration
+ arista.eos.eos_lag_interfaces:
+ config:
+ - name: 5
+ members:
+ - member: Ethernet2
+ mode: on
+ state: replaced
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# interface Ethernet2
+# channel-group 5 mode on
+
+
+# Using overridden
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# channel-group 5 mode on
+# interface Ethernet2
+
+- name: Override all device configuration of all LAG attributes with provided configuration
+ arista.eos.eos_lag_interfaces:
+ config:
+ - name: 10
+ members:
+ - member: Ethernet2
+ mode: on
+ state: overridden
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# interface Ethernet2
+# channel-group 10 mode on
+
+
+# Using deleted
+
+# Before state:
+# -------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# channel-group 5 mode on
+# interface Ethernet2
+# channel-group 5 mode on
+
+- name: Delete LAG attributes of the given interfaces.
+ arista.eos.eos_lag_interfaces:
+ config:
+ - name: 5
+ members:
+ - member: Ethernet1
+ state: deleted
+
+# After state:
+# ------------
+#
+# veos#show running-config | section interface
+# interface Ethernet1
+# interface Ethernet2
+# channel-group 5 mode on
+
+# Using parsed:
+
+# parsed.cfg
+# interface Ethernet1
+# channel-group 5 mode on
+# interface Ethernet2
+# channel-group 5 mode on
+
+- name: Use parsed to convert native configs to structured data
+ arista.eos.lag_interfaces:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# Output:
+# parsed:
+# - name: 5
+# members:
+# - member: Ethernet2
+# mode: on
+# - member: Ethernet1
+# mode: on
+
+# using rendered:
+
+- name: Use Rendered to convert the structured data to native config
+ arista.eos.eos_lag_interfaces:
+ config:
+ - name: 5
+ members:
+ - member: Ethernet2
+ mode: on
+ - member: Ethernet1
+ mode: on
+ state: rendered
+# -----------
+# Output
+# -----------
+#
+# rendered:
+
+# interface Ethernet1
+# channel-group 5 mode on
+# interface Ethernet2
+# channel-group 5 mode on
+
+
+# Using gathered:
+
+# native config:
+# interface Ethernet1
+# channel-group 5 mode on
+# interface Ethernet2
+# channel-group 5 mode on
+
+- name: Gather lldp_global facts from the device
+ arista.eos.lldp_global:
+ state: gathered
+
+# Output:
+# gathered:
+# - name: 5
+# members:
+# - member: Ethernet2
+# mode: on
+# - member: Ethernet1
+# mode: on
+
+"""
+
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample: ['command 1', 'command 2', 'command 3']
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.lag_interfaces.lag_interfaces import (
+ Lag_interfacesArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.lag_interfaces.lag_interfaces import (
+ Lag_interfaces,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+ module = AnsibleModule(
+ argument_spec=Lag_interfacesArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = Lag_interfaces(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_lldp.py b/ansible_collections/arista/eos/plugins/modules/eos_lldp.py
new file mode 100644
index 000000000..86a3cfba8
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_lldp.py
@@ -0,0 +1,117 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (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)
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_lldp
+author: Ganesh Nalawade (@ganeshrn)
+short_description: Manage LLDP configuration on Arista EOS network devices
+description:
+- This module provides declarative management of LLDP service on Arista EOS network
+ devices.
+version_added: 1.0.0
+notes:
+- Tested against Arista EOS 4.24.6F
+options:
+ state:
+ description:
+ - State of the LLDP configuration. If value is I(present) lldp will be enabled
+ else if it is I(absent) it will be disabled.
+ default: present
+ type: str
+ choices:
+ - present
+ - absent
+ - enabled
+ - disabled
+"""
+
+EXAMPLES = """
+- name: Enable LLDP service
+ arista.eos.eos_lldp:
+ state: present
+
+- name: Disable LLDP service
+ arista.eos.eos_lldp:
+ state: absent
+"""
+
+RETURN = """
+commands:
+ description: The list of configuration mode commands to send to the device
+ returned: always, except for the platforms that use Netconf transport to manage the device.
+ type: list
+ sample:
+ - lldp run
+"""
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.eos import (
+ get_config,
+ load_config,
+)
+
+
+def has_lldp(module):
+ config = get_config(module, flags=["| section lldp"])
+
+ is_lldp_enable = False
+ if "no lldp run" not in config:
+ is_lldp_enable = True
+
+ return is_lldp_enable
+
+
+def main():
+ """main entry point for module execution"""
+ argument_spec = dict(
+ state=dict(
+ default="present",
+ choices=["present", "absent", "enabled", "disabled"],
+ ),
+ )
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=True,
+ )
+
+ warnings = list()
+
+ result = {"changed": False}
+
+ if warnings:
+ result["warnings"] = warnings
+
+ HAS_LLDP = has_lldp(module)
+
+ commands = []
+
+ if module.params["state"] == "absent" and HAS_LLDP:
+ commands.append("no lldp run")
+ elif module.params["state"] == "present" and not HAS_LLDP:
+ commands.append("lldp run")
+
+ 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_lldp_global.py b/ansible_collections/arista/eos/plugins/modules/eos_lldp_global.py
new file mode 100644
index 000000000..a98535c66
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_lldp_global.py
@@ -0,0 +1,347 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_lldp_global
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_lldp_global
+short_description: LLDP resource module
+description:
+- This module manages Global Link Layer Discovery Protocol (LLDP) settings on Arista
+ EOS devices.
+version_added: 1.0.0
+author: Nathaniel Case (@Qalthos)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description: The provided global LLDP configuration.
+ type: dict
+ suboptions:
+ holdtime:
+ description:
+ - Specifies the holdtime (in sec) to be sent in packets.
+ type: int
+ reinit:
+ description:
+ - Specifies the delay (in sec) for LLDP initialization on any interface.
+ type: int
+ timer:
+ description:
+ - Specifies the rate at which LLDP packets are sent (in sec).
+ type: int
+ tlv_select:
+ description:
+ - Specifies the LLDP TLVs to enable or disable.
+ type: dict
+ suboptions:
+ link_aggregation:
+ description:
+ - Enable or disable link aggregation TLV.
+ type: bool
+ management_address:
+ description:
+ - Enable or disable management address TLV.
+ type: bool
+ max_frame_size:
+ description:
+ - Enable or disable maximum frame size TLV.
+ type: bool
+ port_description:
+ description:
+ - Enable or disable port description TLV.
+ type: bool
+ system_capabilities:
+ description:
+ - Enable or disable system capabilities TLV.
+ type: bool
+ system_description:
+ description:
+ - Enable or disable system description TLV.
+ type: bool
+ system_name:
+ description:
+ - Enable or disable system name TLV.
+ type: bool
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section lldp).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state of the configuration after module completion.
+ type: str
+ choices:
+ - merged
+ - replaced
+ - deleted
+ - rendered
+ - gathered
+ - parsed
+ default: merged
+
+"""
+EXAMPLES = """
+# Using merged
+#
+# ------------
+# Before State
+# ------------
+#
+# veos# show run | section lldp
+# lldp timer 3000
+# lldp holdtime 100
+# lldp reinit 5
+# no lldp tlv-select management-address
+# no lldp tlv-select system-description
+
+- name: Merge provided LLDP configuration with the existing configuration
+ arista.eos.eos_lldp_global:
+ config:
+ holdtime: 100
+ tlv_select:
+ management_address: false
+ port_description: false
+ system_description: true
+ state: merged
+
+# -----------
+# After state
+# -----------
+#
+# veos# show run | section lldp
+# lldp timer 3000
+# lldp holdtime 100
+# lldp reinit 5
+# no lldp tlv-select management-address
+# no lldp tlv-select port-description
+
+
+# Using replaced
+#
+# ------------
+# Before State
+# ------------
+#
+# veos# show run | section lldp
+# lldp timer 3000
+# lldp holdtime 100
+# lldp reinit 5
+# no lldp tlv-select management-address
+# no lldp tlv-select system-description
+
+- name: Replace existing LLDP device configuration with provided configuration
+ arista.eos.eos_lldp_global:
+ config:
+ holdtime: 100
+ tlv_select:
+ management_address: false
+ port_description: false
+ system_description: true
+ state: replaced
+
+# -----------
+# After state
+# -----------
+#
+# veos# show run | section lldp
+# lldp holdtime 100
+# no lldp tlv-select management-address
+# no lldp tlv-select port-description
+
+
+# Using deleted
+#
+# ------------
+# Before State
+# ------------
+#
+# veos# show run | section lldp
+# lldp timer 3000
+# lldp holdtime 100
+# lldp reinit 5
+# no lldp tlv-select management-address
+# no lldp tlv-select system-description
+
+- name: Delete existing LLDP configurations from the device
+ arista.eos.eos_lldp_global:
+ state: deleted
+
+# -----------
+# After state
+# -----------
+#
+# veos# show run | section ^lldp
+
+# Using rendered:
+
+- name: Use Rendered to convert the structured data to native config
+ arista.eos.eos_lldp_global:
+ config:
+ holdtime: 100
+ tlv_select:
+ management_address: false
+ port_description: false
+ system_description: true
+ state: rendered
+
+# -----------
+# Output
+# -----------
+#
+# rendered:
+# - "lldp holdtime 100"
+# - "no lldp tlv-select management-address"
+# - "no lldp tlv-select port-description"
+
+# Using parsed
+
+# parsed.cfg
+
+# lldp timer 3000
+# lldp holdtime 100
+# lldp reinit 5
+# no lldp tlv-select management-address
+# no lldp tlv-select system-description
+
+- name: Use parsed to convert native configs to structured data
+ arista.eos.lldp_global:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# -----------
+# Output
+# -----------
+
+# parsed:
+# holdtime: 100
+# timer 3000
+# reinit 5
+# tlv_select:
+# management_address: False
+# port_description: False
+# system_description: True
+
+# Using gathered:
+# native config:
+# lldp timer 3000
+# lldp holdtime 100
+# lldp reinit 5
+# no lldp tlv-select management-address
+# no lldp tlv-select system-description
+
+
+- name: Gather lldp_global facts from the device
+ arista.eos.lldp_global:
+ state: gathered
+
+# -----------
+# Output
+# -----------
+
+# gathered:
+# holdtime: 100
+# timer 3000
+# reinit 5
+# tlv_select:
+# management_address: False
+# port_description: False
+# system_description: True
+
+"""
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: dict
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: dict
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample: ['lldp holdtime 100', 'no lldp timer', 'lldp tlv-select system-description']
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.lldp_global.lldp_global import (
+ Lldp_globalArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.lldp_global.lldp_global import (
+ Lldp_global,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+ module = AnsibleModule(
+ argument_spec=Lldp_globalArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = Lldp_global(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_lldp_interfaces.py b/ansible_collections/arista/eos/plugins/modules/eos_lldp_interfaces.py
new file mode 100644
index 000000000..6b5aae118
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_lldp_interfaces.py
@@ -0,0 +1,346 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_lldp_interfaces
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_lldp_interfaces
+short_description: LLDP interfaces resource module
+description:
+- This module manages Link Layer Discovery Protocol (LLDP) attributes of interfaces
+ on Arista EOS devices.
+version_added: 1.0.0
+author: Nathaniel Case (@Qalthos)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description: A dictionary of LLDP interfaces options.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Full name of the interface (i.e. Ethernet1).
+ type: str
+ receive:
+ description:
+ - Enable/disable LLDP RX on an interface.
+ type: bool
+ transmit:
+ description:
+ - Enable/disable LLDP TX on an interface.
+ type: bool
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section ^interface).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state of the configuration after module completion.
+ type: str
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - parsed
+ - gathered
+ - rendered
+ default: merged
+
+"""
+EXAMPLES = """
+# Using merged
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# no lldp receive
+# interface Ethernet2
+# no lldp transmit
+
+- name: Merge provided configuration with running configuration
+ arista.eos.eos_lldp_interfaces:
+ config:
+ - name: Ethernet1
+ transmit: false
+ - name: Ethernet2
+ transmit: false
+ state: merged
+
+#
+# ------------
+# After state
+# ------------
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# no lldp transmit
+# no lldp receive
+# interface Ethernet2
+# no lldp transmit
+
+
+# Using replaced
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# no lldp receive
+# interface Ethernet2
+# no lldp transmit
+
+- name: Replace existing LLDP configuration of specified interfaces with provided
+ configuration
+ arista.eos.eos_lldp_interfaces:
+ config:
+ - name: Ethernet1
+ transmit: false
+ state: replaced
+
+#
+# ------------
+# After state
+# ------------
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# no lldp transmit
+# interface Ethernet2
+# no lldp transmit
+
+
+# Using overridden
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# no lldp receive
+# interface Ethernet2
+# no lldp transmit
+
+- name: Override the LLDP configuration of all the interfaces with provided configuration
+ arista.eos.eos_lldp_interfaces:
+ config:
+ - name: Ethernet1
+ transmit: false
+ state: overridden
+
+#
+# ------------
+# After state
+# ------------
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# no lldp transmit
+# interface Ethernet2
+
+
+# Using deleted
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# no lldp receive
+# interface Ethernet2
+# no lldp transmit
+
+- name: Delete LLDP configuration of specified interfaces (or all interfaces if none
+ are specified)
+ arista.eos.eos_lldp_interfaces:
+ state: deleted
+
+#
+# ------------
+# After state
+# ------------
+#
+# veos#show run | section ^interface
+# interface Ethernet1
+# interface Ethernet2
+
+# using rendered:
+
+- name: Use Rendered to convert the structured data to native config
+ arista.eos.eos_lldp_interfaces:
+ config:
+ - name: Ethernet1
+ transmit: false
+ - name: Ethernet2
+ transmit: false
+ state: rendered
+
+#
+# ------------
+# Output
+# ------------
+#
+# interface Ethernet1
+# no lldp transmit
+# interface Ethernet2
+# no lldp transmit
+
+# Using parsed
+# parsed.cfg
+
+# interface Ethernet1
+# no lldp transmit
+# interface Ethernet2
+# no lldp transmit
+
+
+- name: Use parsed to convert native configs to structured data
+ arista.eos.lldp_interfaces:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# ------------
+# Output
+# ------------
+
+# parsed:
+# - name: Ethernet1
+# transmit: False
+# - name: Ethernet2
+# transmit: False
+
+# Using gathered:
+
+# native config:
+# interface Ethernet1
+# no lldp transmit
+# interface Ethernet2
+# no lldp transmit
+
+- name: Gather lldp interfaces facts from the device
+ arista.eos.lldp_interfaces:
+ state: gathered
+
+# ------------
+# Output
+# ------------
+
+# gathered:
+# - name: Ethernet1
+# transmit: False
+# - name: Ethernet2
+# transmit: False
+
+"""
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample: ['interface Ethernet1', 'no lldp transmit']
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.lldp_interfaces.lldp_interfaces import (
+ Lldp_interfacesArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.lldp_interfaces.lldp_interfaces import (
+ Lldp_interfaces,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+ module = AnsibleModule(
+ argument_spec=Lldp_interfacesArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = Lldp_interfaces(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_logging.py b/ansible_collections/arista/eos/plugins/modules/eos_logging.py
new file mode 100644
index 000000000..b2b9106f6
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_logging.py
@@ -0,0 +1,505 @@
+#!/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_logging_global.py b/ansible_collections/arista/eos/plugins/modules/eos_logging_global.py
new file mode 100644
index 000000000..a614dcb8e
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_logging_global.py
@@ -0,0 +1,942 @@
+#!/usr/bin/python
+# -*- 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)
+
+"""
+The module file for eos_logging_global
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+---
+module: eos_logging_global
+short_description: Manages logging resource module
+description: This module configures and manages the attributes of logging on Arista
+ EOS platforms.
+version_added: 3.0.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.6M
+- This module works with connection C(network_cli). See the L(EOS Platform Options,eos_platform_options).
+options:
+ config:
+ description: A dictionary of logging options
+ type: dict
+ suboptions:
+ buffered:
+ description:
+ - Set buffered logging parameters.
+ type: dict
+ suboptions: &message_options
+ severity: &sev
+ description: Severity level .
+ type: str
+ choices:
+ - emergencies
+ - alerts
+ - critical
+ - errors
+ - warnings
+ - notifications
+ - informational
+ - debugging
+ buffer_size:
+ description: Logging buffer size
+ type: int
+ console:
+ description:
+ - Set console logging parameters.
+ type: dict
+ suboptions:
+ severity: *sev
+ event:
+ description: Global events
+ type: str
+ choices: ["link-status", "port-channel", "spanning-tree"]
+ facility:
+ description: Set logging facility.
+ type: str
+ "choices": [
+ "auth",
+ "cron",
+ "daemon",
+ "kern",
+ "local0",
+ "local1",
+ "local2",
+ "local3",
+ "local4",
+ "local5",
+ "local6",
+ "local7",
+ "lpr",
+ "mail",
+ "news",
+ "sys10",
+ "sys11",
+ "sys12",
+ "sys13",
+ "sys14",
+ "sys9",
+ "syslog",
+ "user",
+ "uucp",
+ ]
+ format:
+ description: Set logging format parameters
+ type: dict
+ suboptions:
+ hostname:
+ description: Specify hostname logging format.
+ type: str
+ timestamp:
+ description: Set timestamp logging parameters.
+ type: dict
+ suboptions:
+ high_resolution:
+ description: RFC3339 timestamps.
+ type: bool
+ traditional:
+ description: Traditional syslog timestamp format as specified in RFC3164.
+ type: dict
+ suboptions:
+ state:
+ description: When enabled traditional timestamp format is set.
+ type: str
+ choices: ["enabled", "disabled"]
+ timezone:
+ description: Show timezone in traditional format timestamp
+ type: bool
+ year:
+ description: Show year in traditional format timestamp
+ type: bool
+ sequence_numbers:
+ description: No. of log messages.
+ type: bool
+ hosts: &host
+ description: Set syslog server IP address and parameters.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description: Hostname or IP address of the syslog server.
+ type: str
+ add:
+ description: Configure ports on the given host.
+ type: bool
+ remove:
+ description: Remove configured ports from the given host
+ type: bool
+ protocol:
+ description: Set syslog server transport protocol
+ type: str
+ choices: ["tcp", "udp"]
+ port:
+ description: Port of the syslog server.
+ type: int
+ level:
+ description: Configure logging severity
+ type: dict
+ suboptions:
+ facility:
+ description: Facility level
+ type: str
+ severity: *sev
+ monitor:
+ description: Set terminal monitor severity
+ type: str
+ turn_on:
+ description: Turn on logging.
+ type: bool
+ persistent:
+ description: Save logging messages to the flash disk.
+ type: dict
+ suboptions:
+ set:
+ description: Save logging messages to the flash dis.
+ type: bool
+ size:
+ description: The maximum size (in bytes) of logging file stored on flash disk.
+ type: int
+ policy:
+ description: Configure logging policies.
+ type: dict
+ suboptions:
+ invert_result:
+ description: Invert the match of match-list.
+ type: bool
+ match_list:
+ description: Configure logging message filtering.
+ type: str
+ qos:
+ description: Set DSCP value in IP header.
+ type: int
+ relogging_interval:
+ description: Configure relogging-interval for critical log messages
+ type: int
+ repeat_messages:
+ description: Repeat messages instead of summarizing number of repeats
+ type: bool
+ source_interface: &srcint
+ description: Use IP Address of interface as source IP of log messages.
+ type: str
+ synchronous:
+ description: Set synchronizing unsolicited with solicited messages
+ type: dict
+ suboptions:
+ set:
+ description: Set synchronizing unsolicited with solicited messages.
+ type: bool
+ level:
+ description: Configure logging severity
+ type: str
+ trap:
+ description: Severity of messages sent to the syslog server.
+ type: dict
+ suboptions:
+ set:
+ description: Severity of messages sent to the syslog server.
+ type: bool
+ severity: *sev
+ vrfs:
+ description: Specify vrf
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description: vrf name.
+ type: str
+ hosts: *host
+ source_interface: *srcint
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section access-list).
+ - The states I(replaced) and I(overridden) have identical
+ behaviour for this module.
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices:
+ - deleted
+ - merged
+ - overridden
+ - replaced
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+"""
+EXAMPLES = """
+
+# Using merged
+
+# Before state
+
+# test(config)#show running-config | section logging
+# test(config)#
+
+ - name: Merge provided configuration with device configuration
+ arista.eos.eos_logging_global:
+ config:
+ hosts:
+ - name: "host01"
+ protocol: "tcp"
+ - name: "11.11.11.1"
+ port: 25
+ vrfs:
+ - name: "vrf01"
+ source_interface: "Ethernet1"
+ - name: "vrf02"
+ hosts:
+ - name: "hostvrf1"
+ protocol: "tcp"
+ - name: "24.1.1.1"
+ port: "33"
+
+# After State:
+
+# test(config)#show running-config | section logging
+# logging host 11.11.11.1 25
+# logging host host01 514 protocol tcp
+# logging vrf vrf02 host 24.1.1.1 33
+# logging vrf vrf02 host hostvrf1 514 protocol tcp
+# logging vrf vrf01 source-interface Ethernet1
+# test(config)#
+#
+#
+# Module Execution:
+# "after": {
+# "hosts": [
+# {
+# "name": "11.11.11.1",
+# "port": 25
+# },
+# {
+# "name": "host01",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "vrfs": [
+# {
+# "name": "vrf01",
+# "source_interface": "Ethernet1"
+# },
+# {
+# "hosts": [
+# {
+# "name": "24.1.1.1",
+# "port": 33
+# },
+# {
+# "name": "hostvrf1",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "name": "vrf02"
+# }
+# ]
+# },
+# "before": {},
+# "changed": true,
+# "commands": [
+# "logging host host01 protocol tcp",
+# "logging host 11.11.11.1 25",
+# "logging vrf vrf01 source-interface Ethernet1",
+# "logging vrf vrf02 host hostvrf1 protocol tcp",
+# "logging vrf vrf02 host 24.1.1.1 33"
+# ],
+#
+
+# Using replaced:
+# Before State:
+
+# test(config)#show running-config | section logging
+# logging host 11.11.11.1 25
+# logging host host01 514 protocol tcp
+# logging vrf vrf02 host 24.1.1.1 33
+# logging vrf vrf02 host hostvrf1 514 protocol tcp
+# logging format timestamp traditional timezone
+# logging vrf vrf01 source-interface Ethernet1
+# logging policy match inverse-result match-list list01 discard
+# logging persistent 4096
+# !
+# logging level AAA alerts
+# test(config)#
+
+ - name: Repalce
+ arista.eos.eos_logging_global:
+ config:
+ synchronous:
+ set: True
+ trap:
+ severity: "critical"
+ hosts:
+ - name: "host02"
+ protocol: "tcp"
+ vrfs:
+ - name: "vrf03"
+ source_interface: "Vlan100"
+ - name: "vrf04"
+ hosts:
+ - name: "hostvrf1"
+ protocol: "tcp"
+
+ state: replaced
+
+# After State:
+# test(config)#show running-config | section logging
+# logging synchronous
+# logging trap critical
+# logging host host02 514 protocol tcp
+# logging vrf vrf04 host hostvrf1 514 protocol tcp
+# logging vrf vrf03 source-interface Vlan100
+# test(config)#
+#
+# Module Execution:
+# "after": {
+# "hosts": [
+# {
+# "name": "host02",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "synchronous": {
+# "set": True
+# },
+# "trap": {
+# "severity": "critical"
+# },
+# "vrfs": [
+# {
+# "name": "vrf03",
+# "source_interface": "Vlan100"
+# },
+# {
+# "hosts": [
+# {
+# "name": "hostvrf1",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "name": "vrf04"
+# }
+# ]
+# },
+# "before": {
+# "format": {
+# "timestamp": {
+# "traditional": {
+# "timezone": true
+# }
+# }
+# },
+# "hosts": [
+# {
+# "name": "11.11.11.1",
+# "port": 25
+# },
+# {
+# "name": "host01",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "level": {
+# "facility": "AAA",
+# "severity": "alerts"
+# },
+# "persistent": {
+# "size": 4096
+# },
+# "policy": {
+# "invert_result": true,
+# "match_list": "list01"
+# },
+# "vrfs": [
+# {
+# "name": "vrf01",
+# "source_interface": "Ethernet1"
+# },
+# {
+# "hosts": [
+# {
+# "name": "24.1.1.1",
+# "port": 33
+# },
+# {
+# "name": "hostvrf1",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "name": "vrf02"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "logging host host02 protocol tcp",
+# "no logging host 11.11.11.1 25",
+# "no logging host host01 514 protocol tcp",
+# "logging vrf vrf03 source-interface Vlan100",
+# "logging vrf vrf04 host hostvrf1 protocol tcp",
+# "no logging vrf vrf01 source-interface Ethernet1",
+# "no logging vrf vrf02 host 24.1.1.1 33",
+# "no logging vrf vrf02 host hostvrf1 514 protocol tcp",
+# "no logging format timestamp traditional timezone",
+# "no logging level AAA alerts",
+# "no logging persistent 4096",
+# "no logging policy match invert-result match-list list01 discard",
+# "logging synchronous",
+# "logging trap critical"
+# ],
+#
+#
+
+
+# Using overridden:
+# Before State:
+
+# test(config)#show running-config | section logging
+# logging host 11.11.11.1 25
+# logging host host01 514 protocol tcp
+# logging vrf vrf02 host 24.1.1.1 33
+# logging vrf vrf02 host hostvrf1 514 protocol tcp
+# logging format timestamp traditional timezone
+# logging vrf vrf01 source-interface Ethernet1
+# logging policy match inverse-result match-list list01 discard
+# logging persistent 4096
+# !
+# logging level AAA alerts
+# test(config)#
+
+ - name: Repalce
+ arista.eos.eos_logging_global:
+ config:
+ synchronous:
+ set: True
+ trap:
+ severity: "critical"
+ hosts:
+ - name: "host02"
+ protocol: "tcp"
+ vrfs:
+ - name: "vrf03"
+ source_interface: "Vlan100"
+ - name: "vrf04"
+ hosts:
+ - name: "hostvrf1"
+ protocol: "tcp"
+
+ state: overridden
+
+# After State:
+# test(config)#show running-config | section logging
+# logging synchronous
+# logging trap critical
+# logging host host02 514 protocol tcp
+# logging vrf vrf04 host hostvrf1 514 protocol tcp
+# logging vrf vrf03 source-interface Vlan100
+# test(config)#
+#
+# Module Execution:
+# "after": {
+# "hosts": [
+# {
+# "name": "host02",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "synchronous": {
+# "set": True
+# },
+# "trap": {
+# "severity": "critical"
+# },
+# "vrfs": [
+# {
+# "name": "vrf03",
+# "source_interface": "Vlan100"
+# },
+# {
+# "hosts": [
+# {
+# "name": "hostvrf1",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "name": "vrf04"
+# }
+# ]
+# },
+# "before": {
+# "format": {
+# "timestamp": {
+# "traditional": {
+# "timezone": true
+# }
+# }
+# },
+# "hosts": [
+# {
+# "name": "11.11.11.1",
+# "port": 25
+# },
+# {
+# "name": "host01",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "level": {
+# "facility": "AAA",
+# "severity": "alerts"
+# },
+# "persistent": {
+# "size": 4096
+# },
+# "policy": {
+# "invert_result": true,
+# "match_list": "list01"
+# },
+# "vrfs": [
+# {
+# "name": "vrf01",
+# "source_interface": "Ethernet1"
+# },
+# {
+# "hosts": [
+# {
+# "name": "24.1.1.1",
+# "port": 33
+# },
+# {
+# "name": "hostvrf1",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "name": "vrf02"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "logging host host02 protocol tcp",
+# "no logging host 11.11.11.1 25",
+# "no logging host host01 514 protocol tcp",
+# "logging vrf vrf03 source-interface Vlan100",
+# "logging vrf vrf04 host hostvrf1 protocol tcp",
+# "no logging vrf vrf01 source-interface Ethernet1",
+# "no logging vrf vrf02 host 24.1.1.1 33",
+# "no logging vrf vrf02 host hostvrf1 514 protocol tcp",
+# "no logging format timestamp traditional timezone",
+# "no logging level AAA alerts",
+# "no logging persistent 4096",
+# "no logging policy match invert-result match-list list01 discard",
+# "logging synchronous",
+# "logging trap critical"
+# ],
+#
+#
+
+# Using deleted:
+
+# Before State:
+# test(config)#show running-config | section logging
+# logging synchronous level critical
+# logging host 11.11.11.1 25
+# logging host host01 514 protocol tcp
+# logging host host02 514 protocol tcp
+# logging vrf vrf02 host 24.1.1.1 33
+# logging vrf vrf02 host hostvrf1 514 protocol tcp
+# logging vrf vrf04 host hostvrf1 514 protocol tcp
+# logging vrf vrf01 source-interface Ethernet1
+# logging vrf vrf03 source-interface Vlan100
+# test(config)#
+
+ - name: Delete all logging configs
+ arista.eos.eos_logging_global:
+ state: deleted
+ become: yes
+
+# After state:
+# test(config)#show running-config | section logging
+# test(config)#
+#
+# "after": {},
+# "before": {
+# "hosts": [
+# {
+# "name": "11.11.11.1",
+# "port": 25
+# },
+# {
+# "name": "host01",
+# "port": 514,
+# "protocol": "tcp"
+# },
+# {
+# "name": "host02",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "synchronous": {
+# "level": "critical"
+# },
+# "vrfs": [
+# {
+# "name": "vrf01",
+# "source_interface": "Ethernet1"
+# },
+# {
+# "hosts": [
+# {
+# "name": "24.1.1.1",
+# "port": 33
+# },
+# {
+# "name": "hostvrf1",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "name": "vrf02"
+# },
+# {
+# "name": "vrf03",
+# "source_interface": "Vlan100"
+# },
+# {
+# "hosts": [
+# {
+# "name": "hostvrf1",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "name": "vrf04"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "no logging host 11.11.11.1 25",
+# "no logging host host01 514 protocol tcp",
+# "no logging host host02 514 protocol tcp",
+# "no logging vrf vrf01 source-interface Ethernet1",
+# "no logging vrf vrf02 host 24.1.1.1 33",
+# "no logging vrf vrf02 host hostvrf1 514 protocol tcp",
+# "no logging vrf vrf03 source-interface Vlan100",
+# "no logging vrf vrf04 host hostvrf1 514 protocol tcp",
+# "no logging synchronous level critical"
+# ],
+
+# Using parsed:
+# parsed.cfg
+
+# logging host 11.11.11.1 25
+# logging host host01 514 protocol tcp
+# logging vrf vrf02 host 24.1.1.1 33
+# logging vrf vrf02 host hostvrf1 514 protocol tcp
+# logging format timestamp traditional timezone
+# logging vrf vrf01 source-interface Ethernet1
+# logging policy match inverse-result match-list list01 discard
+# logging persistent 4096
+# !
+# logging level AAA alerts
+
+ - name: parse configs
+ arista.eos.eos_logging_global:
+ running_config: "{{ lookup('file', './parsed.cfg') }}"
+ state: parsed
+
+# Module Execution
+# "parsed": {
+# "format": {
+# "timestamp": {
+# "traditional": {
+# "timezone": true
+# }
+# }
+# },
+# "hosts": [
+# {
+# "name": "11.11.11.1",
+# "port": 25
+# },
+# {
+# "name": "host01",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "level": {
+# "facility": "AAA",
+# "severity": "alerts"
+# },
+# "persistent": {
+# "size": 4096
+# },
+# "policy": {
+# "invert_result": true,
+# "match_list": "list01"
+# },
+# "vrfs": [
+# {
+# "name": "vrf01",
+# "source_interface": "Ethernet1"
+# },
+# {
+# "hosts": [
+# {
+# "name": "24.1.1.1",
+# "port": 33
+# },
+# {
+# "name": "hostvrf1",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "name": "vrf02"
+# }
+# ]
+# }
+#
+
+# Using gathered:
+# Before State:
+# test(config)#show running-config | section logging
+# logging host 11.11.11.1 25
+# logging host host01 514 protocol tcp
+# logging vrf vrf02 host 24.1.1.1 33
+# logging vrf vrf02 host hostvrf1 514 protocol tcp
+# logging format timestamp traditional timezone
+# logging vrf vrf01 source-interface Ethernet1
+# logging policy match inverse-result match-list list01 discard
+# logging persistent 4096
+# !
+# logging level AAA alerts
+# test(config)#
+
+ - name: gather configs
+ arista.eos.eos_logging_global:
+ state: gathered
+
+# Module Execution:
+# "gathered": {
+# "format": {
+# "timestamp": {
+# "traditional": {
+# "timezone": true
+# }
+# }
+# },
+# "hosts": [
+# {
+# "name": "11.11.11.1",
+# "port": 25
+# },
+# {
+# "name": "host01",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "level": {
+# "facility": "AAA",
+# "severity": "alerts"
+# },
+# "persistent": {
+# "size": 4096
+# },
+# "policy": {
+# "invert_result": true,
+# "match_list": "list01"
+# },
+# "vrfs": [
+# {
+# "name": "vrf01",
+# "source_interface": "Ethernet1"
+# },
+# {
+# "hosts": [
+# {
+# "name": "24.1.1.1",
+# "port": 33
+# },
+# {
+# "name": "hostvrf1",
+# "port": 514,
+# "protocol": "tcp"
+# }
+# ],
+# "name": "vrf02"
+# }
+# ]
+# },
+#
+
+# Using rendered:
+ - name: Render provided configuration
+ arista.eos.eos_logging_global:
+ config:
+ format:
+ timestamp:
+ traditional:
+ timezone: True
+ level:
+ facility: "AAA"
+ severity: "alerts"
+ persistent:
+ size: 4096
+ policy:
+ invert_result: True
+ match_list: "list01"
+ hosts:
+ - name: "host01"
+ protocol: "tcp"
+ - name: "11.11.11.1"
+ port: 25
+ vrfs:
+ - name: "vrf01"
+ source_interface: "Ethernet1"
+ - name: "vrf02"
+ hosts:
+ - name: "hostvrf1"
+ protocol: "tcp"
+ - name: "24.1.1.1"
+ port: "33"
+# Module Execution:
+
+# "rendered": [
+# "logging host host01 protocol tcp",
+# "logging host 11.11.11.1 25",
+# "logging vrf vrf01 source-interface Ethernet1",
+# "logging vrf vrf02 host hostvrf1 protocol tcp",
+# "logging vrf vrf02 host 24.1.1.1 33",
+# "logging format timestamp traditional timezone",
+# "logging level AAA alerts",
+# "logging persistent 4096",
+# "logging policy match invert-result match-list list01 discard"
+# ]
+#
+
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.logging_global.logging_global import (
+ Logging_globalArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.logging_global.logging_global import (
+ Logging_global,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Logging_globalArgs.argument_spec,
+ mutually_exclusive=[["config", "running_config"]],
+ required_if=[
+ ["state", "merged", ["config"]],
+ ["state", "replaced", ["config"]],
+ ["state", "overridden", ["config"]],
+ ["state", "rendered", ["config"]],
+ ["state", "parsed", ["running_config"]],
+ ],
+ supports_check_mode=True,
+ )
+
+ result = Logging_global(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_ntp_global.py b/ansible_collections/arista/eos/plugins/modules/eos_ntp_global.py
new file mode 100644
index 000000000..cb89f3a9d
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_ntp_global.py
@@ -0,0 +1,1053 @@
+#!/usr/bin/python
+# -*- 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)
+
+"""
+The module file for eos_ntp_global
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+---
+module: eos_ntp_global
+short_description: Manages ntp resource module
+description: This module configures and manages the attributes of ntp on Arista
+ EOS platforms.
+version_added: 3.1.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.60M
+- This module works with connection C(network_cli). See the U(https://docs.ansible.com/ansible/latest/network/user_guide/platform_eos.html).
+options:
+ config:
+ description: A dictionary of ntp options
+ type: dict
+ suboptions:
+ authenticate:
+ description:
+ - Require authentication for NTP synchronization.
+ type: dict
+ suboptions:
+ enable:
+ description: Enable authentication for NTP synchronization.
+ type: bool
+ servers:
+ description: Authentication required only for incoming NTP server responses.
+ type: bool
+ authentication_keys:
+ description:
+ - Define a key to use for authentication.
+ type: list
+ elements: dict
+ suboptions:
+ id:
+ description: key identifier.
+ type: int
+ algorithm:
+ description: hash algorithm,
+ type: str
+ choices: ["md5", "sha1"]
+ encryption:
+ description: key type
+ type: int
+ choices: [0, 7]
+ key:
+ description: Unobfuscated key string.
+ type: str
+ local_interface:
+ description: Configure the interface from which the IP source address is taken.
+ type: str
+ qos_dscp:
+ description: Set DSCP value in IP header
+ type: int
+ serve:
+ description: Configure the switch as an NTP server.
+ type: dict
+ suboptions:
+ all:
+ description: Service NTP requests received on any interface.
+ type: bool
+ access_lists:
+ description: Configure access control list.
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description: ip/ipv6 config commands.
+ type: str
+ acls:
+ description: Access lists to be configured under the afi
+ type: list
+ elements: dict
+ suboptions:
+ acl_name:
+ description: Name of the access list.
+ type: str
+ direction:
+ description: direction for the packets.
+ type: str
+ choices: ["in", "out"]
+ vrf:
+ description: VRF in which to apply the access control list.
+ type: str
+ servers:
+ description: Configure NTP server to synchronize to.
+ type: list
+ elements: dict
+ suboptions:
+ vrf:
+ description: vrf name.
+ type: str
+ server:
+ description: Hostname or A.B.C.D or A:B:C:D:E:F:G:H.
+ type: str
+ required: True
+ burst:
+ description: Send a burst of packets instead of the usual one.
+ type: bool
+ iburst:
+ description: Send bursts of packets until the server is reached
+ type: bool
+ key_id:
+ description: Set a key to use for authentication.
+ type: int
+ local_interface:
+ description: Configure the interface from which the IP source address is taken.
+ type: str
+ source:
+ description: Configure the interface from which the IP source address is taken.
+ type: str
+ maxpoll:
+ description: Maximum poll interval.
+ type: int
+ minpoll:
+ description: Minimum poll interval.
+ type: int
+ prefer:
+ description: Mark this server as preferred.
+ type: bool
+ version:
+ description: NTP version.
+ type: int
+ trusted_key:
+ description: Configure the set of keys that are accepted for incoming messages
+ type: str
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section ntp).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ - The states I(replaced) and I(overridden) have identical
+ behaviour for this module.
+ - Please refer to examples for more details.
+ type: str
+ choices:
+ - deleted
+ - merged
+ - overridden
+ - replaced
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+"""
+EXAMPLES = """
+
+# Using merged
+
+# Before state
+
+# localhost(config)#show running-config | section ntp
+# localhost(config)#
+
+ - name: Merge provided configuration with device configuration
+ arista.eos.eos_ntp_global:
+ config:
+ authenticate:
+ enable: true
+ authentication_keys:
+ - id: 2
+ algorithm: "sha1"
+ encryption: 7
+ key: "123456"
+ - id: 23
+ algorithm: "md5"
+ encryption: 7
+ key: "123456"
+ local_interface: "Ethernet1"
+ qos_dscp: 10
+ trusted_key: 23
+ servers:
+ - server: "10.1.1.1"
+ vrf: "vrf01"
+ burst: True
+ prefer: True
+ - server: "25.1.1.1"
+ vrf: "vrf01"
+ maxpoll: 15
+ key_id: 2
+ serve:
+ access_lists:
+ - afi: "ip"
+ acls:
+ - acl_name: "acl01"
+ direction: "in"
+ - afi: "ipv6"
+ acls:
+ - acl_name: "acl02"
+ direction: "in"
+
+# After State
+
+# localhost(config)#show running-config | section ntp
+# ntp authentication-key 2 sha1 7 123456
+# ntp authentication-key 23 md5 7 123456
+# ntp trusted-key 23
+# ntp authenticate
+# ntp local-interface Ethernet1
+# ntp qos dscp 10
+# ntp server vrf vrf01 10.1.1.1 prefer burst
+# ntp server vrf vrf01 25.1.1.1 maxpoll 15 key 2
+# ntp serve ip access-group acl01 in
+# ntp serve ipv6 access-group acl02 in
+# localhost(config)#
+#
+#
+# Module Execution:
+# "after": {
+# "authenticate": {
+# "enable": true
+# },
+# "authentication_keys": [
+# {
+# "algorithm": "sha1",
+# "encryption": 7,
+# "id": 2,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# },
+# {
+# "algorithm": "md5",
+# "encryption": 7,
+# "id": 23,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# }
+# ],
+# "local_interface": "Ethernet1",
+# "qos_dscp": 10,
+# "serve": {
+# "access_lists": [
+# {
+# "acls": [
+# {
+# "acl_name": "acl01",
+# "direction": "in"
+# }
+# ],
+# "afi": "ip"
+# },
+# {
+# "acls": [
+# {
+# "acl_name": "acl02",
+# "direction": "in"
+# }
+# ],
+# "afi": "ipv6"
+# }
+# ]
+# },
+# "servers": [
+# {
+# "burst": true,
+# "prefer": true,
+# "server": "10.1.1.1",
+# "vrf": "vrf01"
+# },
+# {
+# "key_id": 2,
+# "maxpoll": 15,
+# "server": "25.1.1.1",
+# "vrf": "vrf01"
+# }
+# ],
+# "trusted_key": "23"
+# },
+# "before": {},
+# "changed": true,
+# "commands": [
+# "ntp serve ip access-group acl01 in",
+# "ntp serve ipv6 access-group acl02 in",
+# "ntp authentication-key 2 sha1 7 ********",
+# "ntp authentication-key 23 md5 7 ********",
+# "ntp server vrf vrf01 10.1.1.1 burst prefer",
+# "ntp server vrf vrf01 25.1.1.1 key 2 maxpoll 15",
+# "ntp authenticate",
+# "ntp local-interface Ethernet1",
+# "ntp qos dscp 10",
+# "ntp trusted-key 23"
+# ],
+
+# Using Replaced
+
+# Before State
+
+# localhost(config)#show running-config | section ntp
+# ntp authentication-key 2 sha1 7 123456
+# ntp authentication-key 23 md5 7 123456
+# ntp trusted-key 23
+# ntp authenticate
+# ntp local-interface Ethernet1
+# ntp qos dscp 10
+# ntp server vrf vrf01 10.1.1.1 prefer burst
+# ntp server vrf vrf01 25.1.1.1 maxpoll 15 key 2
+# ntp serve ip access-group acl01 in
+# ntp serve ipv6 access-group acl02 in
+# localhost(config)#
+
+ - name: Replace
+ arista.eos.eos_ntp_global:
+ config:
+ qos_dscp: 15
+ authentication_keys:
+ - id: 2
+ algorithm: "md5"
+ encryption: 7
+ key: "123456"
+ servers:
+ - server: "11.21.1.1"
+ vrf: "vrf01"
+ burst: True
+ prefer: True
+ minpoll: 13
+ serve:
+ access_lists:
+ - afi: "ip"
+ acls:
+ - acl_name: "acl03"
+ direction: "in"
+ state: replaced
+# After State:
+# localhost(config)#show running-config | section ntp
+# ntp authentication-key 2 md5 7 123456
+# ntp qos dscp 15
+# ntp server vrf vrf01 11.21.1.1 prefer burst minpoll 13
+# ntp serve ip access-group acl03 in
+# localhost(config)#
+#
+#
+# Module Execution:
+# "after": {
+# "authentication_keys": [
+# {
+# "algorithm": "md5",
+# "encryption": 7,
+# "id": 2,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# }
+# ],
+# "qos_dscp": 15,
+# "serve": {
+# "access_lists": [
+# {
+# "acls": [
+# {
+# "acl_name": "acl03",
+# "direction": "in"
+# }
+# ],
+# "afi": "ip"
+# }
+# ]
+# },
+# "servers": [
+# {
+# "burst": true,
+# "minpoll": 13,
+# "prefer": true,
+# "server": "11.21.1.1",
+# "vrf": "vrf01"
+# }
+# ]
+# },
+# "before": {
+# "authenticate": {
+# "enable": true
+# },
+# "authentication_keys": [
+# {
+# "algorithm": "sha1",
+# "encryption": 7,
+# "id": 2,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# },
+# {
+# "algorithm": "md5",
+# "encryption": 7,
+# "id": 23,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# }
+# ],
+# "local_interface": "Ethernet1",
+# "qos_dscp": 10,
+# "serve": {
+# "access_lists": [
+# {
+# "acls": [
+# {
+# "acl_name": "acl01",
+# "direction": "in"
+# }
+# ],
+# "afi": "ip"
+# },
+# {
+# "acls": [
+# {
+# "acl_name": "acl02",
+# "direction": "in"
+# }
+# ],
+# "afi": "ipv6"
+# }
+# ]
+# },
+# "servers": [
+# {
+# "burst": true,
+# "prefer": true,
+# "server": "10.1.1.1",
+# "vrf": "vrf01"
+# },
+# {
+# "key_id": 2,
+# "maxpoll": 15,
+# "server": "25.1.1.1",
+# "vrf": "vrf01"
+# }
+# ],
+# "trusted_key": "23"
+# },
+# "changed": true,
+# "commands": [
+# "no ntp serve ip access-group acl01 in",
+# "no ntp serve ipv6 access-group acl02 in",
+# "no ntp authentication-key 23 md5 7 ********",
+# "no ntp server vrf vrf01 10.1.1.1 burst prefer",
+# "no ntp server vrf vrf01 25.1.1.1 key 2 maxpoll 15",
+# "no ntp authenticate",
+# "no ntp local-interface Ethernet1",
+# "no ntp trusted-key 23",
+# "ntp serve ip access-group acl03 in",
+# "ntp authentication-key 2 md5 7 ********",
+# "ntp server vrf vrf01 11.21.1.1 burst minpoll 13 prefer",
+# "ntp qos dscp 15"
+# ],
+#
+# Using Overridden
+
+# Before State
+
+# localhost(config)#show running-config | section ntp
+# ntp authentication-key 2 sha1 7 123456
+# ntp authentication-key 23 md5 7 123456
+# ntp trusted-key 23
+# ntp authenticate
+# ntp local-interface Ethernet1
+# ntp qos dscp 10
+# ntp server vrf vrf01 10.1.1.1 prefer burst
+# ntp server vrf vrf01 25.1.1.1 maxpoll 15 key 2
+# ntp serve ip access-group acl01 in
+# ntp serve ipv6 access-group acl02 in
+# localhost(config)#
+
+ - name: Replace
+ arista.eos.eos_ntp_global:
+ config:
+ qos_dscp: 15
+ authentication_keys:
+ - id: 2
+ algorithm: "md5"
+ encryption: 7
+ key: "123456"
+ servers:
+ - server: "11.21.1.1"
+ vrf: "vrf01"
+ burst: True
+ prefer: True
+ minpoll: 13
+ serve:
+ access_lists:
+ - afi: "ip"
+ acls:
+ - acl_name: "acl03"
+ direction: "in"
+ state: overridden
+# After State:
+# localhost(config)#show running-config | section ntp
+# ntp authentication-key 2 md5 7 123456
+# ntp qos dscp 15
+# ntp server vrf vrf01 11.21.1.1 prefer burst minpoll 13
+# ntp serve ip access-group acl03 in
+# localhost(config)#
+#
+#
+# Module Execution:
+# "after": {
+# "authentication_keys": [
+# {
+# "algorithm": "md5",
+# "encryption": 7,
+# "id": 2,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# }
+# ],
+# "qos_dscp": 15,
+# "serve": {
+# "access_lists": [
+# {
+# "acls": [
+# {
+# "acl_name": "acl03",
+# "direction": "in"
+# }
+# ],
+# "afi": "ip"
+# }
+# ]
+# },
+# "servers": [
+# {
+# "burst": true,
+# "minpoll": 13,
+# "prefer": true,
+# "server": "11.21.1.1",
+# "vrf": "vrf01"
+# }
+# ]
+# },
+# "before": {
+# "authenticate": {
+# "enable": true
+# },
+# "authentication_keys": [
+# {
+# "algorithm": "sha1",
+# "encryption": 7,
+# "id": 2,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# },
+# {
+# "algorithm": "md5",
+# "encryption": 7,
+# "id": 23,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# }
+# ],
+# "local_interface": "Ethernet1",
+# "qos_dscp": 10,
+# "serve": {
+# "access_lists": [
+# {
+# "acls": [
+# {
+# "acl_name": "acl01",
+# "direction": "in"
+# }
+# ],
+# "afi": "ip"
+# },
+# {
+# "acls": [
+# {
+# "acl_name": "acl02",
+# "direction": "in"
+# }
+# ],
+# "afi": "ipv6"
+# }
+# ]
+# },
+# "servers": [
+# {
+# "burst": true,
+# "prefer": true,
+# "server": "10.1.1.1",
+# "vrf": "vrf01"
+# },
+# {
+# "key_id": 2,
+# "maxpoll": 15,
+# "server": "25.1.1.1",
+# "vrf": "vrf01"
+# }
+# ],
+# "trusted_key": "23"
+# },
+# "changed": true,
+# "commands": [
+# "no ntp serve ip access-group acl01 in",
+# "no ntp serve ipv6 access-group acl02 in",
+# "no ntp authentication-key 23 md5 7 ********",
+# "no ntp server vrf vrf01 10.1.1.1 burst prefer",
+# "no ntp server vrf vrf01 25.1.1.1 key 2 maxpoll 15",
+# "no ntp authenticate",
+# "no ntp local-interface Ethernet1",
+# "no ntp trusted-key 23",
+# "ntp serve ip access-group acl03 in",
+# "ntp authentication-key 2 md5 7 ********",
+# "ntp server vrf vrf01 11.21.1.1 burst minpoll 13 prefer",
+# "ntp qos dscp 15"
+# ],
+#
+
+# using deleted:
+# Before State
+
+# localhost(config)#show running-config | section ntp
+# ntp authentication-key 2 sha1 7 123456
+# ntp authentication-key 23 md5 7 123456
+# ntp trusted-key 23
+# ntp authenticate
+# ntp local-interface Ethernet1
+# ntp qos dscp 10
+# ntp server vrf vrf01 10.1.1.1 prefer burst
+# ntp server vrf vrf01 11.21.1.1 prefer burst minpoll 13
+# ntp server vrf vrf01 25.1.1.1 maxpoll 15 key 2
+# ntp serve ip access-group acl01 in
+# ntp serve ipv6 access-group acl02 in
+# localhost(config)#
+
+ - name: Delete ntp-global
+ arista.eos.eos_ntp_global:
+ state: deleted
+
+# After State:
+# localhost(config)#show running-config | section ntp
+# localhost(config)#
+#
+#
+# # Module Execution
+# "after": {},
+# "before": {
+# "authenticate": {
+# "enable": true
+# },
+# "authentication_keys": [
+# {
+# "algorithm": "sha1",
+# "encryption": 7,
+# "id": 2,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# },
+# {
+# "algorithm": "md5",
+# "encryption": 7,
+# "id": 23,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# }
+# ],
+# "local_interface": "Ethernet1",
+# "qos_dscp": 10,
+# "serve": {
+# "access_lists": [
+# {
+# "acls": [
+# {
+# "acl_name": "acl01",
+# "direction": "in"
+# }
+# ],
+# "afi": "ip"
+# },
+# {
+# "acls": [
+# {
+# "acl_name": "acl02",
+# "direction": "in"
+# }
+# ],
+# "afi": "ipv6"
+# }
+# ]
+# },
+# "servers": [
+# {
+# "burst": true,
+# "prefer": true,
+# "server": "10.1.1.1",
+# "vrf": "vrf01"
+# },
+# {
+# "burst": true,
+# "minpoll": 13,
+# "prefer": true,
+# "server": "11.21.1.1",
+# "vrf": "vrf01"
+# },
+# {
+# "key": 2,
+# "maxpoll": 15,
+# "server": "25.1.1.1",
+# "vrf": "vrf01"
+# }
+# ],
+# "trusted_key": "23"
+# },
+# "changed": true,
+# "commands": [
+# "no ntp serve ip access-group acl01 in",
+# "no ntp serve ipv6 access-group acl02 in",
+# "no ntp authentication-key 2 sha1 7 ********",
+# "no ntp authentication-key 23 md5 7 ********",
+# "no ntp server vrf vrf01 10.1.1.1 burst prefer",
+# "no ntp server vrf vrf01 11.21.1.1 burst minpoll 13 prefer",
+# "no ntp server vrf vrf01 25.1.1.1 key 2 maxpoll 15",
+# "no ntp authenticate",
+# "no ntp local-interface Ethernet1",
+# "no ntp qos dscp 10",
+# "no ntp trusted-key 23"
+# ],
+#
+
+# Using parsed:
+# parsed.cfg
+# ntp authentication-key 2 sha1 7 123456
+# ntp authentication-key 23 md5 7 123456
+# ntp trusted-key 23
+# ntp authenticate
+# ntp local-interface Ethernet1
+# ntp qos dscp 10
+# ntp server vrf vrf01 10.1.1.1 prefer burst
+# ntp server vrf vrf01 11.21.1.1 prefer burst minpoll 13
+# ntp server vrf vrf01 25.1.1.1 maxpoll 15 key 2
+# ntp serve ip access-group acl01 in
+# ntp serve ipv6 access-group acl02 in
+
+ - name: parse configs
+ arista.eos.eos_ntp_global:
+ running_config: "{{ lookup('file', './parsed_ntp_global.cfg') }}"
+ state: parsed
+ tags:
+ - parsed
+# Module Execution
+# "parsed": {
+# "authenticate": {
+# "enable": true
+# },
+# "authentication_keys": [
+# {
+# "algorithm": "sha1",
+# "encryption": 7,
+# "id": 2,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# },
+# {
+# "algorithm": "md5",
+# "encryption": 7,
+# "id": 23,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# }
+# ],
+# "local_interface": "Ethernet1",
+# "qos_dscp": 10,
+# "serve": {
+# "access_lists": [
+# {
+# "acls": [
+# {
+# "acl_name": "acl01",
+# "direction": "in"
+# }
+# ],
+# "afi": "ip"
+# },
+# {
+# "acls": [
+# {
+# "acl_name": "acl02",
+# "direction": "in"
+# }
+# ],
+# "afi": "ipv6"
+# }
+# ]
+# },
+# "servers": [
+# {
+# "burst": true,
+# "prefer": true,
+# "server": "10.1.1.1",
+# "vrf": "vrf01"
+# },
+# {
+# "burst": true,
+# "minpoll": 13,
+# "prefer": true,
+# "server": "11.21.1.1",
+# "vrf": "vrf01"
+# },
+# {
+# "key": 2,
+# "maxpoll": 15,
+# "server": "25.1.1.1",
+# "vrf": "vrf01"
+# }
+# ],
+# "trusted_key": "23"
+# }
+# }
+
+# using Gathered
+# Device config:
+# localhost(config)#show running-config | section ntp
+# ntp authentication-key 2 sha1 7 123456
+# ntp authentication-key 23 md5 7 123456
+# ntp trusted-key 23
+# ntp authenticate
+# ntp local-interface Ethernet1
+# ntp qos dscp 10
+# ntp server vrf vrf01 10.1.1.1 prefer burst
+# ntp server vrf vrf01 25.1.1.1 maxpoll 15 key 2
+# ntp serve ip access-group acl01 in
+# ntp serve ipv6 access-group acl02 in
+# localhost(config)#
+
+
+ - name: gather configs
+ arista.eos.eos_ntp_global:
+ state: gathered
+ tags:
+ - gathered
+# Module Execution
+# "gathered": {
+# "authenticate": {
+# "enable": true
+# },
+# "authentication_keys": [
+# {
+# "algorithm": "sha1",
+# "encryption": 7,
+# "id": 2,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# },
+# {
+# "algorithm": "md5",
+# "encryption": 7,
+# "id": 23,
+# "key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
+# }
+# ],
+# "local_interface": "Ethernet1",
+# "qos_dscp": 10,
+# "serve": {
+# "access_lists": [
+# {
+# "acls": [
+# {
+# "acl_name": "acl01",
+# "direction": "in"
+# }
+# ],
+# "afi": "ip"
+# },
+# {
+# "acls": [
+# {
+# "acl_name": "acl02",
+# "direction": "in"
+# }
+# ],
+# "afi": "ipv6"
+# }
+# ]
+# },
+# "servers": [
+# {
+# "burst": true,
+# "prefer": true,
+# "server": "10.1.1.1",
+# "vrf": "vrf01"
+# },
+# {
+# "key_id": 2,
+# "maxpoll": 15,
+# "server": "25.1.1.1",
+# "vrf": "vrf01"
+# }
+# ],
+# "trusted_key": "23"
+# },
+# "invocation": {
+# "module_args": {
+# "config": null,
+# "running_config": null,
+# "state": "gathered"
+# }
+# }
+# }
+
+
+# using rendered:
+
+ - name: Render provided configuration
+ arista.eos.eos_ntp_global:
+ config:
+ authenticate:
+ enable: true
+ authentication_keys:
+ - id: 2
+ algorithm: "sha1"
+ encryption: 7
+ key: "123456"
+ - id: 23
+ algorithm: "md5"
+ encryption: 7
+ key: "123456"
+ local_interface: "Ethernet1"
+ qos_dscp: 10
+ trusted_key: 23
+ servers:
+ - server: "10.1.1.1"
+ vrf: "vrf01"
+ burst: True
+ prefer: True
+ - server: "25.1.1.1"
+ vrf: "vrf01"
+ maxpoll: 15
+ key_id: 2
+ serve:
+ access_lists:
+ - afi: "ip"
+ acls:
+ - acl_name: "acl01"
+ direction: "in"
+ - afi: "ipv6"
+ acls:
+ - acl_name: "acl02"
+ direction: "in"
+ state: rendered
+ become: yes
+
+# Module Execution:
+# "rendered": [
+# "ntp serve ip access-group acl01 in",
+# "ntp serve ipv6 access-group acl02 in",
+# "ntp authentication-key 2 sha1 7 ********",
+# "ntp authentication-key 23 md5 7 ********",
+# "ntp server vrf vrf01 10.1.1.1 burst prefer",
+# "ntp server vrf vrf01 25.1.1.1 key 2 maxpoll 15",
+# "ntp authenticate",
+# "ntp local-interface Ethernet1",
+# "ntp qos dscp 10",
+# "ntp trusted-key 23"
+# ]
+#
+"""
+
+RETURN = """
+before:
+ description: The configuration prior to the module execution.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+after:
+ description: The resulting configuration after module execution.
+ returned: when changed
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: list
+ sample:
+ - ntp master stratum 2
+ - ntp peer 198.51.100.1 use-vrf test maxpoll 7
+ - ntp authentication-key 10 md5 wawyhanx2 7
+ - ntp access-group peer PeerAcl1
+ - ntp access-group peer PeerAcl2
+ - ntp access-group query-only QueryAcl1
+rendered:
+ description: The provided configuration in the task rendered in device-native format (offline).
+ returned: when I(state) is C(rendered)
+ type: list
+ sample:
+
+ - ntp authentication-key 2 sha1 7 123456
+ - ntp authentication-key 23 md5 7 123456
+ - ntp trusted-key 23
+ - ntp authenticate
+ - ntp local-interface Ethernet1
+ - ntp qos dscp 10
+ - ntp server vrf vrf01 10.1.1.1 prefer burst
+ - ntp server vrf vrf01 25.1.1.1 maxpoll 15 key 2
+ - ntp serve ip access-group acl01 in
+ - ntp serve ipv6 access-group acl02 in
+
+gathered:
+ description: Facts about the network resource gathered from the remote device as structured data.
+ returned: when I(state) is C(gathered)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+parsed:
+ description: The device native config provided in I(running_config) option parsed into structured data as per module argspec.
+ returned: when I(state) is C(parsed)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.ntp_global.ntp_global import (
+ Ntp_globalArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.ntp_global.ntp_global import (
+ Ntp_global,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Ntp_globalArgs.argument_spec,
+ mutually_exclusive=[["config", "running_config"]],
+ required_if=[
+ ["state", "merged", ["config"]],
+ ["state", "replaced", ["config"]],
+ ["state", "overridden", ["config"]],
+ ["state", "rendered", ["config"]],
+ ["state", "parsed", ["running_config"]],
+ ],
+ supports_check_mode=True,
+ )
+
+ result = Ntp_global(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_ospf_interfaces.py b/ansible_collections/arista/eos/plugins/modules/eos_ospf_interfaces.py
new file mode 100644
index 000000000..29ad037f7
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_ospf_interfaces.py
@@ -0,0 +1,1230 @@
+#!/usr/bin/python
+# -*- 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)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_ospf_interfaces
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: eos_ospf_interfaces
+version_added: 1.1.0
+short_description: OSPF Interfaces Resource Module.
+description:
+- This module manages OSPF configuration of interfaces on devices running Arista EOS.
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+options:
+ config:
+ description: A list of OSPF configuration for interfaces.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Name/Identifier of the interface.
+ type: str
+ address_family:
+ description:
+ - OSPF settings on the interfaces in address-family context.
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description:
+ - Address Family Identifier (AFI) for OSPF settings on the interfaces.
+ type: str
+ choices: ['ipv4', 'ipv6']
+ required: True
+ area:
+ description:
+ - Area associated with interface.
+ - Valid only when afi = ipv4.
+ type: dict
+ suboptions:
+ area_id:
+ description:
+ - Area ID as a decimal or IP address format.
+ type: str
+ required: True
+ authentication_v2:
+ description:
+ - Authentication settings on the interface.
+ - Valid only when afi = ipv4.
+ type: dict
+ suboptions:
+ message_digest:
+ description:
+ - Use message-digest authentication.
+ type: bool
+ set:
+ description:
+ - Enable authentication on the interface.
+ type: bool
+ authentication_v3:
+ description:
+ - Authentication settings on the interface.
+ - Valid only when afi = ipv6.
+ type: dict
+ suboptions:
+ spi:
+ description: IPsec Security Parameter Index.
+ type: int
+ algorithm:
+ description: Encryption alsgorithm.
+ type: str
+ choices: ["md5", "sha1"]
+ keytype:
+ description:
+ - Specifies if an unencrypted/hidden follows.
+ - 0 denotes unencrypted key.
+ - 7 denotes hidden key.
+ type: str
+ passphrase:
+ description: Passphrase String for deriving keys for authentication and encryption.
+ type: str
+ key:
+ description: 128 bit MD5 key or 140 bit SHA1 key.
+ type: str
+ authentication_key:
+ description:
+ - Configure the authentication key for the interface.
+ - Valid only when afi = ipv4.
+ type: dict
+ suboptions:
+ encryption:
+ description:
+ - 0 Specifies an UNENCRYPTED authentication key will follow.
+ - 7 Specifies a proprietry encryption type.`
+ type: str
+ key:
+ description:
+ - password (up to 8 chars).
+ type: str
+ bfd:
+ description: Enable BFD.
+ type: bool
+ cost:
+ description:
+ - metric associated with interface.
+ type: int
+ dead_interval:
+ description:
+ - Time interval to detect a dead router.
+ type: int
+ encryption_v3:
+ description:
+ - Authentication settings on the interface.
+ - Valid only when afi = ipv6.
+ type: dict
+ suboptions:
+ spi:
+ description: IPsec Security Parameter Index.
+ type: int
+ encryption:
+ description: encryption type.
+ choices: ["3des-cbc", "aes-128-cbc", "aes-192-cbc", "aes-256-cbc", "null"]
+ type: str
+ algorithm:
+ description: algorithm.
+ type: str
+ choices: ["md5", "sha1"]
+ keytype:
+ description:
+ - Specifies if an unencrypted/hidden follows.
+ - 0 denotes unencrypted key.
+ - 7 denotes hidden key.
+ type: str
+ passphrase:
+ description: Passphrase String for deriving keys for authentication and encryption.
+ type: str
+ key:
+ description: key
+ type: str
+ hello_interval:
+ description:
+ - Timer interval between transmission of hello packets.
+ type: int
+ ip_params:
+ description:
+ - Specify parameters for IPv4/IPv6.
+ - Valid only when afi = ipv6.
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description:
+ - Address Family Identifier (AFI) for OSPF settings on the interfaces.
+ type: str
+ choices: ['ipv4', 'ipv6']
+ required: True
+ area:
+ description:
+ - Area associated with interface.
+ - Valid only when afi = ipv4.
+ type: dict
+ suboptions:
+ area_id:
+ description:
+ - Area ID as a decimal or IP address format.
+ type: str
+ required: True
+ bfd:
+ description: Enable BFD.
+ type: bool
+ cost:
+ description:
+ - metric associated with interface.
+ type: int
+ dead_interval:
+ description:
+ - Time interval to detect a dead router.
+ type: int
+ hello_interval:
+ description:
+ - Timer interval between transmission of hello packets.
+ type: int
+ mtu_ignore:
+ description:
+ - if True, Disable MTU check for Database Description packets.
+ type: bool
+ network:
+ description:
+ - Interface type.
+ type: str
+ priority:
+ description:
+ - Interface priority.
+ type: int
+ retransmit_interval:
+ description:
+ - LSA retransmission interval.
+ type: int
+ passive_interface:
+ description:
+ - Suppress routing updates in an interface.
+ type: bool
+ transmit_delay:
+ description:
+ - LSA transmission delay.
+ type: int
+ message_digest_key:
+ description:
+ - Message digest authentication password (key) settings.
+ type: dict
+ suboptions:
+ key_id:
+ description:
+ - Key ID.
+ type: int
+ encryption:
+ description:
+ - 0 Specifies an UNENCRYPTED ospf password (key) will follow.
+ - 7 Specifies a proprietry encryption type.
+ type: str
+ key:
+ description:
+ - Authentication key (upto 16 chars).
+ type: str
+ mtu_ignore:
+ description:
+ - if True, Disable MTU check for Database Description packets.
+ type: bool
+ network:
+ description:
+ - Interface type.
+ type: str
+ passive_interface:
+ description:
+ - Suppress routing updates in an interface.
+ - Valid only when afi = ipv6.
+ type: bool
+ priority:
+ description:
+ - Interface priority.
+ type: int
+ retransmit_interval:
+ description:
+ - LSA retransmission interval.
+ type: int
+ shutdown:
+ description:
+ - Shutdown OSPF on this interface.
+ type: bool
+ transmit_delay:
+ description:
+ - LSA transmission delay.
+ type: int
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section interface).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - gathered
+ - parsed
+ - rendered
+ default: merged
+"""
+
+EXAMPLES = """
+
+# Using merged
+
+# Before state
+
+# veos(config)#show running-config | section interface | ospf
+# veos(config)#
+
+ - name: Merge provided configuration with device configuration
+ arista.eos.eos_ospf_interfaces:
+ config:
+ - name: "Vlan1"
+ address_family:
+ - afi: "ipv4"
+ area:
+ area_id: "0.0.0.50"
+ cost: 500
+ mtu_ignore: True
+ - afi: "ipv6"
+ dead_interval: 44
+ ip_params:
+ - afi: "ipv6"
+ mtu_ignore: True
+ network: "point-to-point"
+ state: merged
+
+# After State
+
+# veos(config)#show running-config | section interface | ospf
+# interface Vlan1
+# ip ospf cost 500
+# ip ospf mtu-ignore
+# ip ospf area 0.0.0.50
+# ospfv3 dead-interval 44
+# ospfv3 ipv6 network point-to-point
+# ospfv3 ipv6 mtu-ignore
+# veos(config)#
+#
+#
+# Module Execution:
+#
+# "after": [
+# {
+# "name": "Ethernet1"
+# },
+# {
+# "name": "Ethernet2"
+# },
+# {
+# "name": "Management1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.50"
+# },
+# "cost": 500,
+# "mtu_ignore": True
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 44,
+# "ip_params": [
+# {
+# "afi": "ipv6",
+# "mtu_ignore": True,
+# "network": "point-to-point"
+# }
+# ]
+# }
+# ],
+# "name": "Vlan1"
+# }
+# ],
+# "before": [
+# {
+# "name": "Ethernet1"
+# },
+# {
+# "name": "Ethernet2"
+# },
+# {
+# "name": "Management1"
+# }
+# ],
+# "changed": True,
+# "commands": [
+# "interface Vlan1",
+# "ip ospf area 0.0.0.50",
+# "ip ospf cost 500",
+# "ip ospf mtu-ignore",
+# "ospfv3 dead-interval 44",
+# "ospfv3 ipv6 mtu-ignore",
+# "ospfv3 ipv6 network point-to-point"
+# ],
+#
+
+# Using replaced
+#---------------
+
+# Before State:
+
+# veos(config)#show running-config | section interface | ospf
+# interface Vlan1
+# ip ospf cost 500
+# ip ospf dead-interval 29
+# ip ospf hello-interval 66
+# ip ospf mtu-ignore
+# ip ospf area 0.0.0.50
+# ospfv3 cost 106
+# ospfv3 hello-interval 77
+# ospfv3 dead-interval 44
+# ospfv3 transmit-delay 100
+# ospfv3 ipv4 priority 45
+# ospfv3 ipv4 area 0.0.0.5
+# ospfv3 ipv6 passive-interface
+# ospfv3 ipv6 retransmit-interval 115
+# ospfv3 ipv6 network point-to-point
+# ospfv3 ipv6 mtu-ignore
+# !
+# interface Vlan2
+# ospfv3 ipv4 hello-interval 45
+# ospfv3 ipv4 retransmit-interval 100
+# ospfv3 ipv4 area 0.0.0.6
+# veos(config)#
+
+
+ - name: Replace device configuration with provided configuration
+ arista.eos.eos_ospf_interfaces:
+ config:
+ - name: "Vlan1"
+ address_family:
+ - afi: "ipv6"
+ cost: 44
+ bfd: True
+ ip_params:
+ - afi: "ipv6"
+ mtu_ignore: True
+ network: "point-to-point"
+ dead_interval: 56
+ state: replaced
+
+# After State:
+
+# veos(config)#show running-config | section interface | ospf
+# interface Vlan1
+# ospfv3 bfd
+# ospfv3 cost 44
+# no ospfv3 ipv6 passive-interface
+# ospfv3 ipv6 network point-to-point
+# ospfv3 ipv6 mtu-ignore
+# !
+# interface Vlan2
+# ospfv3 ipv4 hello-interval 45
+# ospfv3 ipv4 retransmit-interval 100
+# ospfv3 ipv4 area 0.0.0.6
+# veos(config)#
+#
+# Module Execution:
+#
+# "after": [
+# {
+# "name": "Ethernet1"
+# },
+# {
+# "name": "Ethernet2"
+# },
+# {
+# "name": "Management1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "bfd": True,
+# "cost": 44,
+# "ip_params": [
+# {
+# "afi": "ipv6",
+# "mtu_ignore": True,
+# "network": "point-to-point"
+# }
+# ]
+# }
+# ],
+# "name": "Vlan1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.6"
+# },
+# "hello_interval": 45,
+# "retransmit_interval": 100
+# }
+# ]
+# }
+# ],
+# "name": "Vlan2"
+# }
+# ],
+# "before": [
+# {
+# "name": "Ethernet1"
+# },
+# {
+# "name": "Ethernet2"
+# },
+# {
+# "name": "Management1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.50"
+# },
+# "cost": 500,
+# "dead_interval": 29,
+# "hello_interval": 66,
+# "mtu_ignore": True
+# },
+# {
+# "afi": "ipv6",
+# "cost": 106,
+# "dead_interval": 44,
+# "hello_interval": 77,
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.5"
+# },
+# "priority": 45
+# },
+# {
+# "afi": "ipv6",
+# "mtu_ignore": True,
+# "network": "point-to-point",
+# "passive_interface": True,
+# "retransmit_interval": 115
+# }
+# ],
+# "transmit_delay": 100
+# }
+# ],
+# "name": "Vlan1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.6"
+# },
+# "hello_interval": 45,
+# "retransmit_interval": 100
+# }
+# ]
+# }
+# ],
+# "name": "Vlan2"
+# }
+# ],
+# "changed": True,
+# "commands": [
+# "interface Vlan1",
+# "no ip ospf cost 500",
+# "no ip ospf dead-interval 29",
+# "no ip ospf hello-interval 66",
+# "no ip ospf mtu-ignore",
+# "no ip ospf area 0.0.0.50",
+# "ospfv3 cost 44",
+# "ospfv3 bfd",
+# "ospfv3 authentication ipsec spi 30 md5 passphrase 7 7hl8FV3lZ6H1mAKpjL47hQ==",
+# "no ospfv3 ipv4 priority 45",
+# "no ospfv3 ipv4 area 0.0.0.5",
+# "ospfv3 ipv6 dead-interval 56",
+# "no ospfv3 ipv6 passive-interface",
+# "no ospfv3 ipv6 retransmit-interval 115",
+# "no ospfv3 hello-interval 77",
+# "no ospfv3 dead-interval 44",
+# "no ospfv3 transmit-delay 100"
+# ],
+#
+
+# Using overidden:
+# ----------------
+
+# Before State:
+# veos(config)#show running-config | section interface | ospf
+# interface Vlan1
+# ip ospf dead-interval 29
+# ip ospf hello-interval 66
+# ip ospf mtu-ignore
+# ospfv3 bfd
+# ospfv3 cost 106
+# ospfv3 hello-interval 77
+# ospfv3 transmit-delay 100
+# ospfv3 ipv4 priority 45
+# ospfv3 ipv4 area 0.0.0.5
+# ospfv3 ipv6 passive-interface
+# ospfv3 ipv6 dead-interval 56
+# ospfv3 ipv6 retransmit-interval 115
+# ospfv3 ipv6 network point-to-point
+# ospfv3 ipv6 mtu-ignore
+# !
+# interface Vlan2
+# ospfv3 ipv4 hello-interval 45
+# ospfv3 ipv4 retransmit-interval 100
+# ospfv3 ipv4 area 0.0.0.6
+# veos(config)#
+
+ - name: Override device configuration with provided configuration
+ arista.eos.eos_ospf_interfaces:
+ config:
+ - name: "Vlan1"
+ address_family:
+ - afi: "ipv6"
+ cost: 44
+ bfd: True
+ ip_params:
+ - afi: "ipv6"
+ mtu_ignore: True
+ network: "point-to-point"
+ dead_interval: 56
+ state: overridden
+
+# After State:
+
+# veos(config)#show running-config | section interface | ospf
+# interface Vlan1
+# ospfv3 bfd
+# ospfv3 cost 44
+# no ospfv3 ipv6 passive-interface
+# ospfv3 ipv6 dead-interval 56
+# ospfv3 ipv6 network point-to-point
+# ospfv3 ipv6 mtu-ignore
+# veos(config)#
+#
+#
+# Module Execution:
+#
+# "after": [
+# {
+# "name": "Ethernet1"
+# },
+# {
+# "name": "Ethernet2"
+# },
+# {
+# "name": "Management1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "bfd": True,
+# "cost": 44,
+# "ip_params": [
+# {
+# "afi": "ipv6",
+# "dead_interval": 56,
+# "mtu_ignore": True,
+# "network": "point-to-point"
+# }
+# ]
+# }
+# ],
+# "name": "Vlan1"
+# },
+# {
+# "name": "Vlan2"
+# }
+# ],
+# "before": [
+# {
+# "name": "Ethernet1"
+# },
+# {
+# "name": "Ethernet2"
+# },
+# {
+# "name": "Management1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "dead_interval": 29,
+# "hello_interval": 66,
+# "mtu_ignore": True
+# },
+# {
+# "afi": "ipv6",
+# "bfd": True,
+# "cost": 106,
+# "hello_interval": 77,
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.5"
+# },
+# "priority": 45
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 56,
+# "mtu_ignore": True,
+# "network": "point-to-point",
+# "passive_interface": True,
+# "retransmit_interval": 115
+# }
+# ],
+# "transmit_delay": 100
+# }
+# ],
+# "name": "Vlan1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.6"
+# },
+# "hello_interval": 45,
+# "retransmit_interval": 100
+# }
+# ]
+# }
+# ],
+# "name": "Vlan2"
+# }
+# ],
+# "changed": True,
+# "commands": [
+# "interface Vlan2",
+# "no ospfv3 ipv4 hello-interval 45",
+# "no ospfv3 ipv4 retransmit-interval 100",
+# "no ospfv3 ipv4 area 0.0.0.6",
+# "interface Vlan1",
+# "no ip ospf dead-interval 29",
+# "no ip ospf hello-interval 66",
+# "no ip ospf mtu-ignore",
+# "ospfv3 cost 44",
+# "ospfv3 authentication ipsec spi 30 md5 passphrase 7 7hl8FV3lZ6H1mAKpjL47hQ==",
+# "no ospfv3 ipv4 priority 45",
+# "no ospfv3 ipv4 area 0.0.0.5",
+# "no ospfv3 ipv6 passive-interface",
+# "no ospfv3 ipv6 retransmit-interval 115",
+# "no ospfv3 hello-interval 77",
+# "no ospfv3 transmit-delay 100"
+# ],
+#
+
+# Using deleted:
+#--------------
+
+# before State:
+
+# veos(config)#show running-config | section interface | ospf
+# interface Vlan1
+# ip ospf dead-interval 29
+# ip ospf hello-interval 66
+# ip ospf mtu-ignore
+# ospfv3 bfd
+# ospfv3 cost 106
+# ospfv3 hello-interval 77
+# ospfv3 transmit-delay 100
+# ospfv3 ipv4 priority 45
+# ospfv3 ipv4 area 0.0.0.5
+# ospfv3 ipv6 passive-interface
+# ospfv3 ipv6 dead-interval 56
+# ospfv3 ipv6 retransmit-interval 115
+# ospfv3 ipv6 network point-to-point
+# ospfv3 ipv6 mtu-ignore
+# !
+# interface Vlan2
+# ospfv3 ipv4 hello-interval 45
+# ospfv3 ipv4 retransmit-interval 100
+# ospfv3 ipv4 area 0.0.0.6
+# veos(config)#
+
+ - name: Delete device configuration
+ arista.eos.eos_ospf_interfaces:
+ config:
+ - name: "Vlan1"
+ state: deleted
+
+# After State:
+
+# veos#show running-config | section interface | ospf
+# interface Vlan2
+# ospfv3 ipv4 hello-interval 45
+# ospfv3 ipv4 retransmit-interval 100
+# ospfv3 ipv4 area 0.0.0.6
+#
+# Module Execution:
+#
+# "after": [
+# {
+# "name": "Ethernet1"
+# },
+# {
+# "name": "Ethernet2"
+# },
+# {
+# "name": "Management1"
+# },
+# {
+# "name": "Vlan1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.6"
+# },
+# "hello_interval": 45,
+# "retransmit_interval": 100
+# }
+# ]
+# }
+# ],
+# "name": "Vlan2"
+# }
+# ],
+# "before": [
+# {
+# "name": "Ethernet1"
+# },
+# {
+# "name": "Ethernet2"
+# },
+# {
+# "name": "Management1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "dead_interval": 29,
+# "hello_interval": 66,
+# "mtu_ignore": True
+# },
+# {
+# "afi": "ipv6",
+# "bfd": True,
+# "cost": 106,
+# "hello_interval": 77,
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.5"
+# },
+# "priority": 45
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 56,
+# "mtu_ignore": True,
+# "network": "point-to-point",
+# "passive_interface": True,
+# "retransmit_interval": 115
+# }
+# ],
+# "transmit_delay": 100
+# }
+# ],
+# "name": "Vlan1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.6"
+# },
+# "hello_interval": 45,
+# "retransmit_interval": 100
+# }
+# ]
+# }
+# ],
+# "name": "Vlan2"
+# }
+# ],
+# "changed": True,
+# "commands": [
+# "interface Vlan1",
+# "no ip ospf dead-interval 29",
+# "no ip ospf hello-interval 66",
+# "no ip ospf mtu-ignore",
+# "no ospfv3 bfd",
+# "no ospfv3 cost 106",
+# "no ospfv3 hello-interval 77",
+# "no ospfv3 transmit-delay 100",
+# "no ospfv3 ipv4 priority 45",
+# "no ospfv3 ipv4 area 0.0.0.5",
+# "no ospfv3 ipv6 passive-interface",
+# "no ospfv3 ipv6 dead-interval 56",
+# "no ospfv3 ipv6 retransmit-interval 115",
+# "no ospfv3 ipv6 network point-to-point",
+# "no ospfv3 ipv6 mtu-ignore"
+# ],
+#
+
+# Using parsed:
+# ------------
+
+# parsed.cfg:
+# ----------
+
+# interface Vlan1
+# ip ospf dead-interval 29
+# ip ospf hello-interval 66
+# ip ospf mtu-ignore
+# ip ospf cost 500
+# ospfv3 bfd
+# ospfv3 cost 106
+# ospfv3 hello-interval 77
+# ospfv3 transmit-delay 100
+# ospfv3 ipv4 priority 45
+# ospfv3 ipv4 area 0.0.0.5
+# ospfv3 ipv6 passive-interface
+# ospfv3 ipv6 dead-interval 56
+# ospfv3 ipv6 retransmit-interval 115
+# ospfv3 ipv6 network point-to-point
+# ospfv3 ipv6 mtu-ignore
+# !
+# interface Vlan2
+# ospfv3 ipv4 hello-interval 45
+# ospfv3 ipv4 retransmit-interval 100
+# ospfv3 ipv4 area 0.0.0.6
+#
+
+ - name: parse configs
+ arista.eos.eos_ospf_interfaces:
+ running_config: "{{ lookup('file', './parsed.cfg') }}"
+ state: parsed
+
+# Module Execution:
+# "parsed": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "cost": 500,
+# "dead_interval": 29,
+# "hello_interval": 66,
+# "mtu_ignore": True
+# },
+# {
+# "afi": "ipv6",
+# "bfd": True,
+# "cost": 106,
+# "hello_interval": 77,
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.5"
+# },
+# "priority": 45
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 56,
+# "mtu_ignore": True,
+# "network": "point-to-point",
+# "passive_interface": True,
+# "retransmit_interval": 115
+# }
+# ],
+# "transmit_delay": 100
+# }
+# ],
+# "name": "Vlan1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.6"
+# },
+# "hello_interval": 45,
+# "retransmit_interval": 100
+# }
+# ]
+# }
+# ],
+# "name": "Vlan2"
+# }
+# ]
+
+# Using gathered:
+
+# Device COnfig:
+
+# veos#show running-config | section interface | ospf
+# interface Vlan1
+# ip ospf cost 500
+# ip ospf dead-interval 29
+# ip ospf hello-interval 66
+# ip ospf mtu-ignore
+# ip ospf area 0.0.0.50
+# ospfv3 cost 106
+# ospfv3 hello-interval 77
+# ospfv3 transmit-delay 100
+# ospfv3 ipv4 priority 45
+# ospfv3 ipv4 area 0.0.0.5
+# ospfv3 ipv6 passive-interface
+# ospfv3 ipv6 dead-interval 56
+# ospfv3 ipv6 retransmit-interval 115
+# ospfv3 ipv6 network point-to-point
+# ospfv3 ipv6 mtu-ignore
+# !
+# interface Vlan2
+# ospfv3 ipv4 hello-interval 45
+# ospfv3 ipv4 retransmit-interval 100
+# ospfv3 ipv4 area 0.0.0.6
+# veos#
+
+ - name: gather configs
+ arista.eos.eos_ospf_interfaces:
+ state: gathered
+
+# Module Execution:
+#
+# "gathered": [
+# {
+# "name": "Ethernet1"
+# },
+# {
+# "name": "Ethernet2"
+# },
+# {
+# "name": "Management1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.50"
+# },
+# "cost": 500,
+# "dead_interval": 29,
+# "hello_interval": 66,
+# "mtu_ignore": True
+# },
+# {
+# "afi": "ipv6",
+# "cost": 106,
+# "hello_interval": 77,
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.5"
+# },
+# "priority": 45
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 56,
+# "mtu_ignore": True,
+# "network": "point-to-point",
+# "passive_interface": True,
+# "retransmit_interval": 115
+# }
+# ],
+# "transmit_delay": 100
+# }
+# ],
+# "name": "Vlan1"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "ip_params": [
+# {
+# "afi": "ipv4",
+# "area": {
+# "area_id": "0.0.0.6"
+# },
+# "hello_interval": 45,
+# "retransmit_interval": 100
+# }
+# ]
+# }
+# ],
+# "name": "Vlan2"
+# }
+# ],
+#
+
+
+# Using rendered:
+# --------------
+
+ - name: Render provided configuration
+ arista.eos.eos_ospf_interfaces:
+ config:
+ - name: "Vlan1"
+ address_family:
+ - afi: "ipv4"
+ dead_interval: 29
+ mtu_ignore: True
+ hello_interval: 66
+ - afi: "ipv6"
+ hello_interval: 77
+ cost : 106
+ transmit_delay: 100
+ ip_params:
+ - afi: "ipv6"
+ retransmit_interval: 115
+ dead_interval: 56
+ passive_interface: True
+ - afi: "ipv4"
+ area:
+ area_id: "0.0.0.5"
+ priority: 45
+ - name: "Vlan2"
+ address_family:
+ - afi: "ipv6"
+ ip_params:
+ - afi: "ipv4"
+ area:
+ area_id: "0.0.0.6"
+ hello_interval: 45
+ retransmit_interval: 100
+ - afi: "ipv4"
+ message_digest_key:
+ key_id: 200
+ encryption: 7
+ key: "hkdfhtu=="
+
+ state: rendered
+
+# Module Execution:
+#
+# "rendered": [
+# "interface Vlan1",
+# "ip ospf dead-interval 29",
+# "ip ospf mtu-ignore",
+# "ip ospf hello-interval 66",
+# "ospfv3 hello-interval 77",
+# "ospfv3 cost 106",
+# "ospfv3 transmit-delay 100",
+# "ospfv3 ipv4 area 0.0.0.5",
+# "ospfv3 ipv4 priority 45",
+# "ospfv3 ipv6 retransmit-interval 115",
+# "ospfv3 ipv6 dead-interval 56",
+# "ospfv3 ipv6 passive-interface",
+# "interface Vlan2",
+# "ip ospf message-digest-key 200 md5 7 hkdfhtu==",
+# "ospfv3 ipv4 area 0.0.0.6",
+# "ospfv3 ipv4 hello-interval 45",
+# "ospfv3 ipv4 retransmit-interval 100"
+# ]
+#
+
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.ospf_interfaces.ospf_interfaces import (
+ Ospf_interfacesArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.ospf_interfaces.ospf_interfaces import (
+ Ospf_interfaces,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Ospf_interfacesArgs.argument_spec,
+ mutually_exclusive=[],
+ required_if=[],
+ supports_check_mode=False,
+ )
+
+ result = Ospf_interfaces(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_ospfv2.py b/ansible_collections/arista/eos/plugins/modules/eos_ospfv2.py
new file mode 100644
index 000000000..470efb023
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_ospfv2.py
@@ -0,0 +1,1563 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_ospfv2
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_ospfv2
+short_description: OSPFv2 resource module
+description: This module configures and manages the attributes of ospfv2 on Arista
+ EOS platforms.
+version_added: 1.0.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description: A list of configurations for ospfv2.
+ type: dict
+ suboptions:
+ processes:
+ description: A list of dictionary specifying the ospfv2 processes.
+ type: list
+ elements: dict
+ suboptions:
+ process_id:
+ description: ID of OSPFV2 process.
+ type: int
+ vrf:
+ description: VRF name .
+ type: str
+ traffic_engineering:
+ description: Enter traffic engineering config mode
+ type: bool
+ adjacency:
+ description: Configure adjacency options for OSPF instance.
+ type: dict
+ suboptions:
+ exchange_start:
+ description: Configure exchange-start options for OSPF instance.
+ type: dict
+ suboptions:
+ threshold:
+ description: Number of peers to bring up simultaneously.
+ type: int
+ router_id:
+ description: 32-bit number assigned to a router running OSPFv2.
+ type: str
+ max_lsa:
+ description: Specifies the switch behavior on reaching max lsa count.
+ type: dict
+ suboptions:
+ count:
+ description: maximum count of lsas.
+ type: int
+ threshold:
+ description: percentage of <count> , when a warning should be raised.
+ type: int
+ ignore_time:
+ description: time in minutes, for which the switch shoud be shutdown
+ on max-lsa warning
+ type: int
+ ignore_count:
+ description: No. of times the switch can shut down temporarily on
+ warning
+ type: int
+ reset_time:
+ description: Time in minutes, after which the shutdown counter resets.
+ type: int
+ warning:
+ description: Only give warning message when limit is exceeded
+ type: bool
+ max_metric:
+ description: Set maximum metric.
+ type: dict
+ suboptions:
+ router_lsa:
+ description: Maximum metric in self-originated router-LSAs.
+ type: dict
+ suboptions:
+ set:
+ description:
+ - Set router-lsa attribute.
+ type: bool
+ external_lsa:
+ description: Override external-lsa metric with max-metric value.
+ type: dict
+ suboptions:
+ set:
+ description:
+ - Set external-lsa attribute.
+ type: bool
+ max_metric_value:
+ description:
+ - Set max metric value for external LSAs.
+ type: int
+ include_stub:
+ description: Set maximum metric for stub links in router-LSAs.
+ type: bool
+ on_startup:
+ description: Set maximum metric temporarily after reboot.
+ type: dict
+ suboptions:
+ wait_period:
+ description:
+ - Wait period in seconds after startup.
+ type: int
+ summary_lsa:
+ description: Override summary-lsa metric with max-metric value.
+ type: dict
+ suboptions:
+ set:
+ description:
+ - Set external-lsa attribute.
+ type: bool
+ max_metric_value:
+ description:
+ - Set max metric value for external LSAs.
+ type: int
+ log_adjacency_changes:
+ description: To configure link-state changes and transitions of OSPFv2
+ neighbors.
+ type: dict
+ suboptions:
+ detail:
+ description: If true , configures the switch to log all link-state
+ changes.
+ type: bool
+ maximum_paths:
+ description: Maximum number of next-hops in an ECMP route.
+ type: int
+ mpls_ldp:
+ description: mpls ldp sync configuration.
+ type: bool
+ networks:
+ description: Configure routing for a network.
+ type: list
+ elements: dict
+ suboptions:
+ network_address:
+ description: Network Address.
+ type: str
+ prefix:
+ description: Prefix.
+ type: str
+ mask:
+ description: Network Wildcard Mask.
+ type: str
+ area:
+ description: Configure OSPF area.
+ type: str
+ passive_interface:
+ description: Include interface but without actively running OSPF.
+ type: dict
+ suboptions:
+ interface_list:
+ description: Interface range.
+ type: str
+ default:
+ description: If True, Set all interfaces to passive by default
+ type: bool
+ point_to_point:
+ description: Configure Point-to-point specific features.
+ type: bool
+ rfc1583compatibility:
+ description: Specifies different methods for calculating summary route
+ metrics.
+ type: bool
+ distance:
+ description: Specifies the administrative distance for routes.
+ type: dict
+ suboptions:
+ external:
+ description: Routes external to the area
+ type: int
+ inter_area:
+ description: Routes from other areas
+ type: int
+ intra_area:
+ description: Routes with in an area
+ type: int
+ redistribute:
+ description: Specifies the routes to be redistributed
+ type: list
+ elements: dict
+ suboptions:
+ routes:
+ description: Route types (BGP,isis,connected etc)
+ type: str
+ route_map:
+ description: Specify which route map to use.
+ type: str
+ isis_level:
+ description: ISIS levels.
+ type: str
+ retransmission_threshold:
+ description: Configure threshold for retransmission.
+ type: int
+ distribute_list:
+ description: Specifies the list of routes to be filtered.
+ type: dict
+ suboptions:
+ route_map:
+ description: route map to be filtered
+ type: str
+ prefix_list:
+ description: prefix list to be filtered
+ type: str
+ areas:
+ description: Specifies the configuration for OSPF areas
+ type: list
+ elements: dict
+ suboptions:
+ area_id:
+ description: Specifies a 32 bit number expressed in decimal or dotted-decimal
+ notation.
+ type: str
+ default_cost:
+ description: Specify the cost for default summary route in stub/NSSA
+ area.
+ type: int
+ filter:
+ description: Specify the filter for incoming summary LSAs.
+ type: dict
+ suboptions:
+ address:
+ description: IP address.
+ type: str
+ subnet_address:
+ description: IP address with mask length
+ type: str
+ subnet_mask:
+ description: IP subnet mask
+ type: str
+ prefix_list:
+ description: Specify list to filter for incoming LSAs.
+ type: str
+ nssa:
+ description: Configures NSSA parameters.
+ type: dict
+ suboptions:
+ default_information_originate:
+ description: Originate default Type 7 LSA.
+ type: dict
+ suboptions:
+ metric:
+ description: Metric for default route.
+ type: int
+ metric_type:
+ description: Metric type for default route.
+ type: int
+ nssa_only:
+ description: Limit default advertisement to this NSSA area.
+ type: bool
+ no_summary:
+ description: Filter all type-3 LSAs in the nssa area.
+ type: bool
+ nssa_only:
+ description: Disable Type-7 LSA p-bit setting
+ type: bool
+ set:
+ description: Set config up to nssa
+ type: bool
+ not_so_stubby:
+ description: Configures NSSA parameters.
+ type: dict
+ suboptions:
+ default_information_originate:
+ description: Originate default Type 7 LSA.
+ type: dict
+ suboptions:
+ metric:
+ description: Metric for default route.
+ type: int
+ metric_type:
+ description: Metric type for default route.
+ type: int
+ nssa_only:
+ description: Limit default advertisement to this NSSA area.
+ type: bool
+ lsa:
+ description: lsa parameters
+ type: bool
+ no_summary:
+ description: Filter all type-3 LSAs in the nssa area.
+ type: bool
+ nssa_only:
+ description: Disable Type-7 LSA p-bit setting
+ type: bool
+ set:
+ description: Set config up to not-so-stubby
+ type: bool
+ range:
+ description: Configure route summarization.
+ type: dict
+ suboptions:
+ address:
+ description: IP address.
+ type: str
+ subnet_address:
+ description: IP address with mask length
+ type: str
+ subnet_mask:
+ description: IP subnet mask
+ type: str
+ advertise:
+ description: Enable Advertisement of the range.
+ type: bool
+ cost:
+ description: Configures the metric.
+ type: int
+ stub:
+ description: Stub area.
+ type: dict
+ suboptions:
+ no_summary:
+ description: If False , Filter all type-3 LSAs in the stub area.
+ type: bool
+ set:
+ description: When true sets the stub config alone.
+ type: bool
+ auto_cost:
+ description: Set auto-cost.
+ type: dict
+ suboptions:
+ reference_bandwidth:
+ description: reference bandwidth in megabits per sec.
+ type: int
+ bfd:
+ description: Enable BFD.
+ type: dict
+ suboptions:
+ all_interfaces:
+ description: Enable BFD on all interfaces.
+ type: bool
+ default_information:
+ description: Control distribution of default information.
+ type: dict
+ suboptions:
+ originate:
+ description: Distribute a default route.
+ type: bool
+ always:
+ description: Always advertise default route.
+ type: bool
+ metric:
+ description: Metric for default route.
+ type: int
+ metric_type:
+ description: Metric type for default route.
+ type: int
+ route_map:
+ description: Specify which route-map to use.
+ type: str
+ default_metric:
+ description: Configure the default metric for redistributed routes
+ type: int
+ dn_bit_ignore:
+ description: If True, Disable dn-bit check for Type-3 LSAs in non-default
+ VRFs.
+ type: bool
+ graceful_restart:
+ description: Enable graceful restart mode.
+ type: dict
+ suboptions:
+ grace_period:
+ description: Specify maximum time to wait for graceful-restart to
+ complete.
+ type: int
+ set:
+ description: When true sets the grace_fulrestart config alone.
+ type: bool
+ graceful_restart_helper:
+ description: If True, Enable graceful restart helper.
+ type: bool
+ shutdown:
+ description: Disable the OSPF instance.
+ type: bool
+ summary_address:
+ description: Summary route configuration.
+ type: dict
+ suboptions:
+ address:
+ description: IP summary address.
+ type: str
+ prefix:
+ description: Prefix.
+ type: str
+ mask:
+ description: Summary Mask.
+ type: str
+ attribute_map:
+ description: Set attributes of summary route.
+ type: str
+ not_advertise:
+ description: Do not advertise summary route.
+ type: bool
+ tag:
+ description: Set tag.
+ type: int
+ timers:
+ description: Configure OSPF timers.
+ type: list
+ elements: dict
+ suboptions:
+ lsa:
+ description: Configure OSPF LSA timers.
+ type: dict
+ suboptions:
+ rx:
+ description: Configure OSPF LSA receiving timers
+ type: dict
+ suboptions:
+ min_interval:
+ description: Configure OSPF LSA arrival timer.
+ type: int
+ tx:
+ description: Configure OSPF LSA transmission timers.
+ type: dict
+ suboptions:
+ delay:
+ description: Configure OSPF LSA transmission delay.
+ type: dict
+ suboptions:
+ initial:
+ description: Delay to generate first occurrence of LSA
+ in msecs.
+ type: int
+ min:
+ description: Min delay between originating the same LSA
+ in msecs.
+ type: int
+ max:
+ description: Maximum delay between originating the same
+ LSA in msecs.
+ type: int
+ out_delay:
+ description: Configure out-delay timer.
+ type: int
+ pacing:
+ description: Configure OSPF packet pacing.
+ type: int
+ spf:
+ description: Configure SPF timers
+ type: dict
+ suboptions:
+ seconds:
+ description: Seconds.
+ type: int
+ 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
+ throttle:
+ description: Configure throttle timers(valid only for eos version < 4.23).
+ type: dict
+ suboptions:
+ attr:
+ description: throttle attribute.
+ type: str
+ initial:
+ description: Initial schedule delay in msecs.
+ type: int
+ min:
+ description: Min Hold time
+ type: int
+ max:
+ description: Max wait time
+ type: int
+ fips_restrictions:
+ description: Use FIPS compliant algorithms
+ type: str
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section ospf).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices: [deleted, merged, overridden, replaced, gathered, rendered, parsed]
+ default: merged
+
+"""
+EXAMPLES = """
+# Using merged
+
+# Before state:
+# ------------
+# localhost#show running-config | section ospf
+# localhost#
+
+ - name: replace Ospf configs
+ arista.eos.eos_ospfv2:
+ config:
+ - processes:
+ - process_id: 1
+ adjacency:
+ exchange_start:
+ threshold: 20045623
+ areas:
+ - filter:
+ address: "10.1.1.0/24"
+ id: "0.0.0.2"
+ - id: "0.0.0.50"
+ range:
+ address: "172.20.0.0/16"
+ cost: 34
+ default_information:
+ metric: 100
+ metric_type: 1
+ originate: True
+ distance:
+ intra_area: 85
+ max_lsa:
+ count: 8000
+ ignore_count: 3
+ ignore_time: 6
+ reset_time: 20
+ threshold: 40
+ networks:
+ - area: "0.0.0.0"
+ prefix: 10.10.2.0/24
+ - area: "0.0.0.0"
+ prefix: "10.10.3.0/24"
+ redistribute:
+ - routes: "static"
+ router_id: "170.21.0.4"
+ - process_id: 2
+ vrf: "vrf01"
+ areas:
+ - id: "0.0.0.9"
+ default_cost: 20
+ max_lsa:
+ count: 8000
+ ignore_count: 3
+ ignore_time: 6
+ reset_time: 20
+ threshold: 40
+ networks:
+ - area: "0.0.0.0"
+ prefix: 10.10.2.0/24
+ - area: "0.0.0.0"
+ prefix: "10.10.3.0/24"
+ redistribute:
+ - routes: "static"
+ router_id: "170.21.0.4"
+ - process_id: 2
+ vrf: "vrf01"
+ areas:
+ - id: "0.0.0.9"
+ default_cost: 20
+ max_lsa:
+ count: 8000
+ ignore_count: 3
+ ignore_time: 6
+ reset_time: 20
+ threshold: 40
+ - process_id: 3
+ vrf: "vrf02"
+ redistribute:
+ - routes: "connected"
+
+# After state:
+# localhost#show running-config | section ospf
+# router ospf 1
+# router-id 170.21.0.4
+# distance ospf intra-area 85
+# redistribute static
+# area 0.0.0.2 filter 10.1.1.0/24
+# area 0.0.0.50 range 172.20.0.0/16 cost 34
+# network 10.10.2.0/24 area 0.0.0.0
+# network 10.10.3.0/24 area 0.0.0.0
+# max-lsa 8000 40 ignore-time 6 ignore-count 3 reset-time 20
+# adjacency exchange-start threshold 20045623
+# default-information originate metric 100 metric-type 1
+#
+# router ospf 2 vrf vrf01
+# area 0.0.0.9 default-cost 20
+# max-lsa 8000 40 ignore-time 6 ignore-count 3 reset-time 20
+# !
+# router ospf 3 vrf vrf02
+# redistribute connected
+# max-lsa 12000
+# localhost#
+#
+# "processes": [
+# {
+# "adjacency": {
+# "exchange_start": {
+# "threshold": 20045623
+# }
+# },
+# "areas": [
+# {
+# "filter": {
+# "address": "10.1.1.0/24"
+# },
+# "id": "0.0.0.2"
+# },
+# {
+# "id": "0.0.0.50",
+# "range": {
+# "address": "172.20.0.0/16",
+# "cost": 34
+# }
+# }
+# ],
+# "default_information": {
+# "metric": 100,
+# "metric_type": 1,
+# "originate": true
+# },
+# "distance": {
+# "intra_area": 85
+# },
+# "max_lsa": {
+# "count": 8000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "networks": [
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.2.0/24"
+# },
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.3.0/24"
+# }
+# ],
+# "process_id": 1,
+# "redistribute": [
+# {
+# "routes": "static"
+# }
+# ],
+# "router_id": "170.21.0.4"
+# },
+# {
+# "areas": [
+# {
+# "default_cost": 20,
+# "id": "0.0.0.9"
+# }
+# ],
+# "max_lsa": {
+# "count": 8000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "process_id": 2,
+# "vrf": "vrf01"
+# },
+# {
+# "max_lsa": {
+# "count": 12000
+# },
+# "process_id": 3,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf02"
+# }
+# ]
+# }
+# ]
+#
+
+
+# Using replaced:
+# --------------
+
+# Before State:
+
+# localhost#show running-config | section ospf
+# router ospf 1
+# router-id 170.21.0.4
+# distance ospf intra-area 85
+# redistribute static
+# area 0.0.0.2 filter 10.1.1.0/24
+# area 0.0.0.50 range 172.20.0.0/16 cost 34
+# network 10.10.2.0/24 area 0.0.0.0
+# network 10.10.3.0/24 area 0.0.0.0
+# max-lsa 8000 40 ignore-time 6 ignore-count 3 reset-time 20
+# adjacency exchange-start threshold 20045623
+# default-information originate metric 100 metric-type 1
+# !
+# router ospf 2 vrf vrf01
+# area 0.0.0.9 default-cost 20
+# max-lsa 8000 40 ignore-time 6 ignore-count 3 reset-time 20
+# !
+# router ospf 3 vrf vrf02
+# redistribute connected
+# max-lsa 12000
+# localhost#
+#
+# "before": [
+# {
+# "processes": [
+# {
+# "adjacency": {
+# "exchange_start": {
+# "threshold": 20045623
+# }
+# },
+# "areas": [
+# {
+# "filter": {
+# "address": "10.1.1.0/24"
+# },
+# "id": "0.0.0.2"
+# },
+# {
+# "id": "0.0.0.50",
+# "range": {
+# "address": "172.20.0.0/16",
+# "cost": 34
+# }
+# }
+# ],
+# "default_information": {
+# "metric": 100,
+# "metric_type": 1,
+# "originate": true
+# },
+# "distance": {
+# "intra_area": 85
+# },
+# "max_lsa": {
+# "count": 8000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "networks": [
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.2.0/24"
+# },
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.3.0/24"
+# }
+# ],
+# "process_id": 1,
+# "redistribute": [
+# {
+# "routes": "static"
+# }
+# ],
+# "router_id": "170.21.0.4"
+# },
+# {
+# "areas": [
+# {
+# "default_cost": 20,
+# "id": "0.0.0.9"
+# }
+# ],
+# "max_lsa": {
+# "count": 8000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "process_id": 2,
+# "vrf": "vrf01"
+# },
+# {
+# "max_lsa": {
+# "count": 12000
+# },
+# "process_id": 3,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf02"
+# }
+# ]
+# }
+# ]
+#
+ - name: replace Ospf configs
+ arista.eos.eos_ospfv2:
+ config:
+ - processes:
+ - process_id: 2
+ vrf: "vrf01"
+ point_to_point: True
+ redistribute:
+ - routes: "isis"
+ isis_level: "level-1"
+
+ state: replaced
+
+# After State:
+# -----------
+# "router ospf 2 vrf vrf01",
+# "no area 0.0.0.9 default-cost 20",
+# "no max-lsa 8000 40 ignore-time 6 ignore-count 3 reset-time 20",
+# "point-to-point routes",
+# "redistribute isis level-1"
+#
+# "after": [
+# {
+# "processes": [
+# {
+# "adjacency": {
+# "exchange_start": {
+# "threshold": 20045623
+# }
+# },
+# "areas": [
+# {
+# "filter": {
+# "address": "10.1.1.0/24"
+# },
+# "id": "0.0.0.2"
+# },
+# {
+# "id": "0.0.0.50",
+# "range": {
+# "address": "172.20.0.0/16",
+# "cost": 34
+# }
+# }
+# ],
+# "default_information": {
+# "metric": 100,
+# "metric_type": 1,
+# "originate": true
+# },
+# "distance": {
+# "intra_area": 85
+# },
+# "max_lsa": {
+# "count": 8000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "networks": [
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.2.0/24"
+# },
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.3.0/24"
+# }
+# ],
+# "process_id": 1,
+# "redistribute": [
+# {
+# "routes": "static"
+# }
+# ],
+# "router_id": "170.21.0.4"
+# },
+# {
+# "max_lsa": {
+# "count": 12000
+# },
+# "process_id": 2,
+# "redistribute": [
+# {
+# "isis_level": "level-1",
+# "routes": "isis"
+# }
+# ],
+# "vrf": "vrf01"
+# },
+# {
+# "max_lsa": {
+# "count": 12000
+# },
+# "process_id": 3,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf02"
+# }
+# ]
+# }
+# ]
+#
+
+# Using overridden:
+# ----------------
+
+# Before State:
+# localhost#show running-config | section ospf
+# router ospf 1
+# router-id 170.21.0.4
+# distance ospf intra-area 85
+# redistribute static
+# area 0.0.0.2 filter 10.1.1.0/24
+# area 0.0.0.50 range 172.20.0.0/16 cost 34
+# network 10.10.2.0/24 area 0.0.0.0
+# network 10.10.3.0/24 area 0.0.0.0
+# max-lsa 8000 40 ignore-time 6 ignore-count 3 reset-time 20
+# adjacency exchange-start threshold 20045623
+# default-information originate metric 100 metric-type 1
+# !
+# router ospf 2 vrf vrf01
+# redistribute isis level-1
+# max-lsa 12000
+# !
+# router ospf 3 vrf vrf02
+# redistribute connected
+# max-lsa 12000
+# localhost#
+#
+# "before": [
+# {
+# "processes": [
+# {
+# "adjacency": {
+# "exchange_start": {
+# "threshold": 20045623
+# }
+# },
+# "areas": [
+# {
+# "filter": {
+# "address": "10.1.1.0/24"
+# },
+# "id": "0.0.0.2"
+# },
+# {
+# "id": "0.0.0.50",
+# "range": {
+# "address": "172.20.0.0/16",
+# "cost": 34
+# }
+# }
+# ],
+# "default_information": {
+# "metric": 100,
+# "metric_type": 1,
+# "originate": true
+# },
+# "distance": {
+# "intra_area": 85
+# },
+# "max_lsa": {
+# "count": 8000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "networks": [
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.2.0/24"
+# },
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.3.0/24"
+# }
+# ],
+# "process_id": 1,
+# "redistribute": [
+# {
+# "routes": "static"
+# }
+# ],
+# "router_id": "170.21.0.4"
+# },
+# {
+# "max_lsa": {
+# "count": 12000
+# },
+# "process_id": 2,
+# "redistribute": [
+# {
+# "isis_level": "level-1",
+# "routes": "isis"
+# }
+# ],
+# "vrf": "vrf01"
+# },
+# {
+# "max_lsa": {
+# "count": 12000
+# },
+# "process_id": 3,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf02"
+# }
+# ]
+# }
+# ]
+
+ - name: override Ospf configs
+ arista.eos.eos_ospfv2:
+ config:
+ - processes:
+ - process_id: 2
+ vrf: "vrf01"
+ redistribute:
+ - routes: "connected"
+
+ state: override
+
+# After State:
+
+# "no router ospf 1",
+# "no router ospf 3",
+# "router ospf 2 vrf vrf01",
+# "no max-lsa 12000",
+# "no redistribute isis level-1",
+# "redistribute connected"
+#
+# "after": [
+# {
+# "processes": [
+# {
+# "max_lsa": {
+# "count": 12000
+# },
+# "process_id": 2,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf01"
+# }
+# ]
+# }
+# ]
+
+# Using Deleted:
+
+# localhost#show running-config | section ospf
+# router ospf 1
+# router-id 170.21.0.4
+# distance ospf intra-area 85
+# redistribute static
+# area 0.0.0.2 filter 10.1.1.0/24
+# area 0.0.0.50 range 172.20.0.0/16 cost 34
+# network 10.10.2.0/24 area 0.0.0.0
+# network 10.10.3.0/24 area 0.0.0.0
+# max-lsa 8000 40 ignore-time 6 ignore-count 3 reset-time 20
+# adjacency exchange-start threshold 20045623
+# default-information originate metric 100 metric-type 1
+# !
+# router ospf 2 vrf vrf01
+# redistribute connected
+# area 0.0.0.9 default-cost 20
+# max-lsa 8000 40 ignore-time 6 ignore-count 3 reset-time 20
+# !
+# router ospf 3 vrf vrf02
+# redistribute connected
+# max-lsa 12000
+# localhost#
+#
+# "before": [
+# {
+# "processes": [
+# {
+# "adjacency": {
+# "exchange_start": {
+# "threshold": 20045623
+# }
+# },
+# "areas": [
+# {
+# "filter": {
+# "address": "10.1.1.0/24"
+# },
+# "id": "0.0.0.2"
+# },
+# {
+# "id": "0.0.0.50",
+# "range": {
+# "address": "172.20.0.0/16",
+# "cost": 34
+# }
+# }
+# ],
+# "default_information": {
+# "metric": 100,
+# "metric_type": 1,
+# "originate": true
+# },
+# "distance": {
+# "intra_area": 85
+# },
+# "max_lsa": {
+# "count": 8000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "networks": [
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.2.0/24"
+# },
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.3.0/24"
+# }
+# ],
+# "process_id": 1,
+# "redistribute": [
+# {
+# "routes": "static"
+# }
+# ],
+# "router_id": "170.21.0.4"
+# },
+# {
+# "areas": [
+# {
+# "default_cost": 20,
+# "id": "0.0.0.9"
+# }
+# ],
+# "max_lsa": {
+# "count": 8000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "process_id": 2,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf01"
+# },
+# {
+# "max_lsa": {
+# "count": 12000
+# },
+# "process_id": 3,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf02"
+# }
+# ]
+# }
+# ]
+
+ - name: Delete Ospf configs
+ arista.eos.eos_ospfv2:
+ config:
+ - processes:
+ - process_id: 1
+
+ state: deleted
+
+# After State:
+# Commands:
+# "no router ospf 1"
+
+# "after": [
+# {
+# "processes": [
+# {
+# "areas": [
+# {
+# "default_cost": 20,
+# "id": "0.0.0.9"
+# }
+# ],
+# "max_lsa": {
+# "count": 8000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "process_id": 2,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf01"
+# },
+# {
+# "max_lsa": {
+# "count": 12000
+# },
+# "process_id": 3,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf02"
+# }
+# ]
+# }
+# ]
+
+# Using gathered:
+# localhost#show running-config | section ospf
+# router ospf 2 vrf vrf01
+# redistribute connected
+# area 0.0.0.9 default-cost 20
+# max-lsa 8000 40 ignore-time 6 ignore-count 3 reset-time 20
+# !
+# router ospf 3 vrf vrf02
+# redistribute connected
+# max-lsa 12000
+# localhost#
+
+ - name: replace Ospf configs
+ arista.eos.eos_ospfv2:
+ state: gathered
+
+# "gathered": [
+# {
+# "processes": [
+# {
+# "areas": [
+# {
+# "default_cost": 20,
+# "id": "0.0.0.9"
+# }
+# ],
+# "max_lsa": {
+# "count": 8000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "process_id": 2,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf01"
+# },
+# {
+# "max_lsa": {
+# "count": 12000
+# },
+# "process_id": 3,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ],
+# "vrf": "vrf02"
+# }
+# ]
+# }
+# ]
+
+# Using parsed:
+# ------------
+
+# parsed.cfg
+# router ospf 1
+# adjacency exchange-start threshold 20045623
+# area 0.0.0.2 filter 10.1.1.0/24
+# area 0.0.0.50 range 172.20.0.0/16 cost 34
+# default-information originate metric 100 metric-type 1
+# distance ospf intra-area 85
+# max-lsa 80000 40 ignore-count 3 ignore-time 6 reset-time 20
+# network 10.10.2.0/24 area 0.0.0.0
+# network 10.10.3.0/24 area 0.0.0.0
+# redistribute static
+# router-id 170.21.0.4
+# router ospf 2 vrf vrf01,
+# area 0.0.0.9 default-cost 20
+# max-lsa 80000 40 ignore-count 3 ignore-time 6 reset-time 20
+# router ospf 3 vrf vrf02
+# redistribute static
+
+ - name: Parse Ospf configs
+ arista.eos.eos_ospfv2:
+ running_config: "{{ lookup('file', './parsed.cfg') }}"
+ state: parsed
+
+# "parsed": [
+# {
+# "processes": [
+# {
+# "adjacency": {
+# "exchange_start": {
+# "threshold": 20045623
+# }
+# },
+# "areas": [
+# {
+# "filter": {
+# "address": "10.1.1.0/24"
+# },
+# "id": "0.0.0.2"
+# },
+# {
+# "id": "0.0.0.50",
+# "range": {
+# "address": "172.20.0.0/16",
+# "cost": 34
+# }
+# }
+# ],
+# "default_information": {
+# "metric": 100,
+# "metric_type": 1,
+# "originate": true
+# },
+# "distance": {
+# "intra_area": 85
+# },
+# "max_lsa": {
+# "count": 80000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "networks": [
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.2.0/24"
+# },
+# {
+# "area": "0.0.0.0",
+# "prefix": "10.10.3.0/24"
+# }
+# ],
+# "process_id": 1,
+# "redistribute": [
+# {
+# "routes": "static"
+# }
+# ],
+# "router_id": "170.21.0.4"
+# },
+# {
+# "areas": [
+# {
+# "default_cost": 20,
+# "id": "0.0.0.9"
+# }
+# ],
+# "max_lsa": {
+# "count": 80000,
+# "ignore_count": 3,
+# "ignore_time": 6,
+# "reset_time": 20,
+# "threshold": 40
+# },
+# "process_id": 2,
+# "vrf": "vrf01,"
+# },
+# {
+# "process_id": 3,
+# "redistribute": [
+# {
+# "routes": "static"
+# }
+# ],
+# "vrf": "vrf02"
+# }
+# ]
+# }
+# ]
+
+# Using rendered:
+# --------------
+
+ - name: replace Ospf configs
+ arista.eos.eos_ospfv2:
+ config:
+ - processes:
+ - process_id: 1
+ adjacency:
+ exchange_start:
+ threshold: 20045623
+ areas:
+ - filter:
+ address: 10.1.1.0/24
+ id: 0.0.0.2
+ - id: 0.0.0.50
+ range:
+ address: 172.20.0.0/16
+ cost: 34
+ default_information:
+ metric: 100
+ metric_type: 1
+ originate: true
+ distance:
+ intra_area: 85
+ max_lsa:
+ count: 8000
+ ignore_count: 3
+ ignore_time: 6
+ reset_time: 20
+ threshold: 40
+ networks:
+ - area: 0.0.0.0
+ prefix: 10.10.2.0/24
+ - area: 0.0.0.0
+ prefix: 10.10.3.0/24
+ redistribute:
+ - routes: static
+ router_id: 170.21.0.4
+ state: rendered
+
+# "rendered": [
+# "router ospf 1",
+# "adjacency exchange-start threshold 20045623",
+# "area 0.0.0.2 filter 10.1.1.0/24",
+# "area 0.0.0.50 range 172.20.0.0/16 cost 34",
+# "default-information originate metric 100 metric-type 1",
+# "distance ospf intra-area 85",
+# "max-lsa 8000 40 ignore-count 3 ignore-time 6 reset-time 20",
+# "network 10.10.2.0/24 area 0.0.0.0",
+# "network 10.10.3.0/24 area 0.0.0.0",
+# "redistribute static",
+# "router-id 170.21.0.4"
+# ]
+#
+
+"""
+RETURN = """
+before:
+ description: The configuration prior to the model invocation.
+ returned: always
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+ type: list
+after:
+ description: The resulting configuration model invocation.
+ returned: when changed
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+ type: list
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample: ["router ospf 1",
+ "adjacency exchange-start threshold 20045623",
+ "area 0.0.0.2 filter 10.1.1.0/24",
+ "area 0.0.0.50 range 172.20.0.0/16 cost 34",
+ "default-information originate metric 100 metric-type 1",
+ "distance ospf intra-area 85",
+ "max-lsa 8000 40 ignore-count 3 ignore-time 6 reset-time 20",
+ "network 10.10.2.0/24 area 0.0.0.0",
+ "network 10.10.3.0/24 area 0.0.0.0",
+ "redistribute static",
+ "router-id 170.21.0.4"]
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.ospfv2.ospfv2 import (
+ Ospfv2Args,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.ospfv2.ospfv2 import (
+ Ospfv2,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+
+ module = AnsibleModule(
+ argument_spec=Ospfv2Args.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = Ospfv2(module).execute_module()
+ 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
new file mode 100644
index 000000000..8c1845262
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_ospfv3.py
@@ -0,0 +1,1583 @@
+#!/usr/bin/python
+# -*- 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)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_ospfv3
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: eos_ospfv3
+short_description: OSPFv3 resource module
+description: This module configures and manages the attributes of ospfv3 on Arista
+ EOS platforms.
+version_added: 1.1.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description: A list of configurations for ospfv3.
+ type: dict
+ suboptions:
+ processes:
+ description: A list of dictionary specifying the ospfv3 processes.
+ type: list
+ elements: dict
+ suboptions:
+ vrf:
+ description: VRF name .
+ type: str
+ adjacency:
+ description: Configure adjacency options for OSPF instance.
+ type: dict
+ suboptions:
+ exchange_start:
+ description: Configure exchange-start options for OSPF instance.
+ type: dict
+ suboptions:
+ threshold:
+ description: Number of peers to bring up simultaneously.
+ type: int
+ auto_cost:
+ description: Set auto-cost.
+ type: dict
+ suboptions:
+ reference_bandwidth:
+ description: reference bandwidth in megabits per sec.
+ type: int
+ areas:
+ description: Specifies the configuration for OSPF areas
+ type: list
+ elements: dict
+ suboptions:
+ area_id:
+ description: Specifies a 32 bit number expressed in decimal or dotted-decimal
+ notation.
+ type: str
+ default_cost:
+ description: Specify the cost for default summary route in stub/NSSA
+ area.
+ type: int
+ authentication:
+ description: Configure authentication for the area incase of ospfv3.
+ type: dict
+ suboptions:
+ spi:
+ description: Specify the SPI value
+ type: int
+ algorithm:
+ description: Name of algorithm to be used.
+ type: str
+ choices: ['md5', 'sha1']
+ encrypt_key:
+ description: If False, key string is not encrypted
+ type: bool
+ hidden_key:
+ description: If True, Specifies that a HIDDEN key will follow.
+ type: bool
+ key:
+ description: 128 bit MD5 key or 140 bit SHA1 key.
+ type: str
+ passphrase:
+ description: Passphrase String for deriving keys for authentication and encryption.
+ type: str
+ encryption:
+ description: Configure encryption for the area
+ type: dict
+ suboptions:
+ spi:
+ description: Specify the SPI value
+ type: int
+ encryption:
+ description: name of encryption to be used.
+ type: str
+ choices: ['3des-cbc', 'aes-128-cbc', 'aes-192-cbc', 'aes-256-cbc', 'null']
+ algorithm:
+ description: name of the algorithm to be used.
+ type: str
+ choices: ['sha1', 'md5']
+ encrypt_key:
+ description: If False, key string is not encrypted
+ type: bool
+ hidden_key:
+ description: If True, Specifies that a HIDDEN key will follow.
+ type: bool
+ key:
+ description: 128 bit MD5 key or 140 bit SHA1 key.
+ type: str
+ passphrase:
+ description: Passphrase String for deriving keys for authentication and encryption.
+ type: str
+ nssa:
+ description: Configures NSSA parameters.
+ type: dict
+ suboptions:
+ default_information_originate:
+ description: Originate default Type 7 LSA.
+ type: dict
+ suboptions:
+ metric:
+ description: Metric for default route.
+ type: int
+ metric_type:
+ description: Metric type for default route.
+ type: int
+ nssa_only:
+ description: Limit default advertisement to this NSSA area.
+ type: bool
+ set:
+ description: True if only default information orignate is set
+ type: bool
+ no_summary:
+ description: Filter all type-3 LSAs in the nssa area.
+ type: bool
+ nssa_only:
+ description: Disable Type-7 LSA p-bit setting
+ type: bool
+ translate:
+ description: Enable LSA translation.
+ type: bool
+ set:
+ description: True if only nssa is set
+ type: bool
+ stub:
+ description: Stub area.
+ type: dict
+ suboptions:
+ set:
+ description: True if only stub is set.
+ type: bool
+ summary_lsa:
+ description: If False , Filter all type-3 LSAs in the stub area.
+ type: bool
+
+ bfd:
+ description: Enable BFD.
+ type: dict
+ suboptions:
+ all_interfaces:
+ description: Enable BFD on all interfaces.
+ type: bool
+ fips_restrictions:
+ description: Use FIPS compliant algorithms
+ type: bool
+ graceful_restart:
+ description: Enable graceful restart mode.
+ type: dict
+ suboptions:
+ grace_period:
+ description: Specify maximum time to wait for graceful-restart to
+ complete.
+ type: int
+ set:
+ description: When true sets the grace_fulrestart config alone.
+ type: bool
+ graceful_restart_helper:
+ description: If True, Enable graceful restart helper.
+ type: bool
+ log_adjacency_changes:
+ description: To configure link-state changes and transitions of OSPFv3
+ neighbors.
+ type: dict
+ suboptions:
+ detail:
+ description: If true , configures the switch to log all link-state
+ changes.
+ type: bool
+ set:
+ description: When true sets the log_adjacency_changes config alone.
+ type: bool
+ max_metric:
+ description: Set maximum metric.
+ type: dict
+ suboptions:
+ router_lsa:
+ description: Maximum metric in self-originated router-LSAs.
+ type: dict
+ suboptions:
+ set:
+ description:
+ - Set router-lsa attribute.
+ type: bool
+ external_lsa:
+ description: Override external-lsa metric with max-metric value.
+ type: dict
+ suboptions:
+ set:
+ description:
+ - Set external-lsa attribute.
+ type: bool
+ max_metric_value:
+ description:
+ - Set max metric value for external LSAs.
+ type: int
+ include_stub:
+ description: Set maximum metric for stub links in router-LSAs.
+ type: bool
+ on_startup:
+ description: Set maximum metric temporarily after reboot.
+ type: dict
+ suboptions:
+ wait_period:
+ description:
+ - Wait period in seconds after startup.
+ type: int
+ wait_for_bgp:
+ description:
+ - Let BGP decide when to originate router-LSA with normal metric
+ type: bool
+ summary_lsa:
+ description: Override summary-lsa metric with max-metric value.
+ type: dict
+ suboptions:
+ set:
+ description:
+ - Set external-lsa attribute.
+ type: bool
+ max_metric_value:
+ description:
+ - Set max metric value for external LSAs.
+ type: int
+ passive_interface:
+ description: Include interface but without actively running OSPF.
+ type: bool
+ router_id:
+ description: 32-bit number assigned to a router running OSPFv3.
+ type: str
+ shutdown:
+ description: Disable the OSPF instance.
+ type: bool
+ timers:
+ description: Configure OSPF timers.
+ type: dict
+ suboptions:
+ out_delay:
+ description: Configure out-delay timer.
+ type: int
+ 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
+ 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 OSPFv3 LSA timers.
+ type: raw
+ suboptions:
+ direction:
+ description: Configure OSPFv3 LSA receiving/transmission timers.
+ type: str
+ choices: ["rx", "tx"]
+ 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
+ address_family:
+ description: Enable address family and enter its config mode
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description: address family .
+ type: str
+ choices:
+ - ipv4
+ - ipv6
+ adjacency:
+ description: Configure adjacency options for OSPF instance.
+ type: dict
+ suboptions:
+ exchange_start:
+ description: Configure exchange-start options for OSPF instance.
+ type: dict
+ suboptions:
+ threshold:
+ description: Number of peers to bring up simultaneously.
+ type: int
+ auto_cost:
+ description: Set auto-cost.
+ type: dict
+ suboptions:
+ reference_bandwidth:
+ description: reference bandwidth in megabits per sec.
+ type: int
+ areas:
+ description: Specifies the configuration for OSPF areas
+ type: list
+ elements: dict
+ suboptions:
+ area_id:
+ description: Specifies a 32 bit number expressed in decimal or dotted-decimal
+ notation.
+ type: str
+ default_cost:
+ description: Specify the cost for default summary route in stub/NSSA
+ area.
+ type: int
+ authentication:
+ description: Configure authentication for the area incase of ospfv3.
+ type: dict
+ suboptions:
+ spi:
+ description: Specify the SPI value
+ type: int
+ algorithm:
+ description: Name of algorithm to be used.
+ type: str
+ choices: ['md5', 'sha1']
+ encrypt_key:
+ description: If False, key string is not encrypted
+ type: bool
+ hidden_key:
+ description: If True, Specifies that a HIDDEN key will follow.
+ type: bool
+ key:
+ description: 128 bit MD5 key or 140 bit SHA1 key.
+ type: str
+ passphrase:
+ description: Passphrase String for deriving keys for authentication and encryption.
+ type: str
+ encryption:
+ description: Configure encryption for the area
+ type: dict
+ suboptions:
+ spi:
+ description: Specify the SPI value
+ type: int
+ encryption:
+ description: name of encryption to be used.
+ type: str
+ choices: ['3des-cbc', 'aes-128-cbc', 'aes-192-cbc', 'aes-256-cbc', 'null']
+ algorithm:
+ description: name of the algorithm to be used.
+ type: str
+ choices: ['sha1', 'md5']
+ encrypt_key:
+ description: If False, key string is not encrypted
+ type: bool
+ hidden_key:
+ description: If True, Specifies that a HIDDEN key will follow.
+ type: bool
+ key:
+ description: 128 bit MD5 key or 140 bit SHA1 key.
+ type: str
+ passphrase:
+ description: Passphrase String for deriving keys for authentication and encryption.
+ type: str
+ nssa:
+ description: Configures NSSA parameters.
+ type: dict
+ suboptions:
+ default_information_originate:
+ description: Originate default Type 7 LSA.
+ type: dict
+ suboptions:
+ metric:
+ description: Metric for default route.
+ type: int
+ metric_type:
+ description: Metric type for default route.
+ type: int
+ nssa_only:
+ description: Limit default advertisement to this NSSA area.
+ type: bool
+ set:
+ description: True if only default information orignate is set
+ type: bool
+ no_summary:
+ description: Filter all type-3 LSAs in the nssa area.
+ type: bool
+ nssa_only:
+ description: Disable Type-7 LSA p-bit setting
+ type: bool
+ translate:
+ description: Enable LSA translation.
+ type: bool
+ set:
+ description: True if only nssa is set
+ type: bool
+ ranges:
+ description: Configure route summarization.
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description: IP address.
+ type: str
+ subnet_address:
+ description: IP address with mask length
+ type: str
+ subnet_mask:
+ description: IP subnet mask
+ type: str
+ advertise:
+ description: Enable Advertisement of the range.
+ type: bool
+ cost:
+ description: Configures the metric.
+ type: int
+ stub:
+ description: Stub area.
+ type: dict
+ suboptions:
+ set:
+ description: True if only stub is set
+ type: bool
+ summary_lsa:
+ description: If False , Filter all type-3 LSAs in the stub area.
+ type: bool
+
+ bfd:
+ description: Enable BFD.
+ type: dict
+ suboptions:
+ all_interfaces:
+ description: Enable BFD on all interfaces.
+ type: bool
+ default_information:
+ description: Control distribution of default information.
+ type: dict
+ suboptions:
+ originate:
+ description: Distribute a default route.
+ type: bool
+ always:
+ description: Always advertise default route.
+ type: bool
+ metric:
+ description: Metric for default route.
+ type: int
+ metric_type:
+ description: Metric type for default route.
+ type: int
+ route_map:
+ description: Specify which route-map to use.
+ type: str
+ default_metric:
+ description: Configure the default metric for redistributed routes.
+ type: int
+ distance:
+ description: Specifies the administrative distance for routes.
+ type: int
+ fips_restrictions:
+ description: Use FIPS compliant algorithms
+ type: bool
+ graceful_restart:
+ description: Enable graceful restart mode.
+ type: dict
+ suboptions:
+ grace_period:
+ description: Specify maximum time to wait for graceful-restart to complete.
+ type: int
+ set:
+ description: When true sets the grace_fulrestart config alone.
+ type: bool
+ graceful_restart_helper:
+ description: If True, Enable graceful restart helper.
+ type: bool
+ log_adjacency_changes:
+ description: To configure link-state changes and transitions of OSPFv3
+ neighbors.
+ type: dict
+ suboptions:
+ detail:
+ description: If true , configures the switch to log all link-state
+ changes.
+ type: bool
+ set:
+ description: When true sets the log_adjacency_changes config alone.
+ type: bool
+ max_metric:
+ description: Set maximum metric.
+ type: dict
+ suboptions:
+ router_lsa:
+ description: Maximum metric in self-originated router-LSAs.
+ type: dict
+ suboptions:
+ set:
+ description:
+ - Set router-lsa attribute.
+ type: bool
+ external_lsa:
+ description: Override external-lsa metric with max-metric value.
+ type: dict
+ suboptions:
+ set:
+ description:
+ - Set external-lsa attribute.
+ type: bool
+ max_metric_value:
+ description:
+ - Set max metric value for external LSAs.
+ type: int
+ include_stub:
+ description: Set maximum metric for stub links in router-LSAs.
+ type: bool
+ on_startup:
+ description: Set maximum metric temporarily after reboot.
+ type: dict
+ suboptions:
+ wait_period:
+ description:
+ - Wait period in seconds after startup.
+ type: int
+ wait_for_bgp:
+ description:
+ - Let BGP decide when to originate router-LSA with normal metric
+ type: bool
+ summary_lsa:
+ description: Override summary-lsa metric with max-metric value.
+ type: dict
+ suboptions:
+ set:
+ description:
+ - Set external-lsa attribute.
+ type: bool
+ max_metric_value:
+ description:
+ - Set max metric value for external LSAs.
+ type: int
+ maximum_paths:
+ description: Maximum number of next-hops in an ECMP route.
+ type: int
+ passive_interface:
+ description: Include interface but without actively running OSPF.
+ type: bool
+ redistribute:
+ description: Specifies the routes to be redistributed.
+ type: list
+ elements: dict
+ suboptions:
+ routes:
+ description: Route types (BGP,static,connected)
+ type: str
+ choices: ['bgp', 'connected', 'static']
+ route_map:
+ description: Specify which route map to use.
+ type: str
+ router_id:
+ description: 32-bit number assigned to a router running OSPFv3.
+ type: str
+ shutdown:
+ description: Disable the OSPF instance.
+ type: bool
+ timers:
+ 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
+ pacing:
+ description: Configure OSPF packet pacing.
+ type: int
+ spf:
+ description: Configure OSPFv3 spf timers.
+ 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 OSPFv3 LSA timers.
+ type: raw
+ suboptions:
+ direction:
+ description: Configure OSPFv3 LSA receiving/transmission timers.
+ type: str
+ choices: ["rx", "tx"]
+ 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
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section ospfv3).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices: [deleted, merged, overridden, replaced, gathered, rendered, parsed]
+ default: merged
+"""
+
+EXAMPLES = """
+
+# Using merged
+
+# Before state
+
+# veos#show running-config | section ospfv3
+# veos#
+
+
+ - arista.eos.eos_ospfv3:
+ config:
+ processes:
+ - address_family:
+ - timers:
+ lsa: 22
+ graceful_restart:
+ grace_period: 35
+ afi: "ipv6"
+ timers:
+ pacing: 55
+ fips_restrictions: True
+ router_id: "2.2.2.2"
+ vrf: "vrfmerge"
+
+
+# After state
+
+# veos#show running-config | section ospfv3
+# router ospfv3 vrf vrfmerge
+# router-id 2.2.2.2
+# test
+# fips restrictions
+# timers pacing flood 55
+# !
+# address-family ipv6
+# fips restrictions
+# timers lsa arrival 22
+# graceful-restart grace-period 35
+# veos#
+
+# Module Execution
+# "after": {
+# "processes": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "fips_restrictions": true,
+# "graceful_restart": {
+# "grace_period": 35
+# },
+# "timers": {
+# "lsa": 22
+# }
+# }
+# ],
+# "fips_restrictions": true,
+# "router_id": "2.2.2.2",
+# "timers": {
+# "pacing": 55
+# },
+# "vrf": "vrfmerge"
+# }
+# ]
+# },
+# "before": {},
+# "changed": true,
+# "commands": [
+# "router ospfv3 vrf vrfmerge",
+# "address-family ipv6",
+# "graceful-restart grace-period 35",
+# "timers lsa arrival 22",
+# "exit",
+# "timers pacing flood 55",
+# "fips restrictions",
+# "router-id 2.2.2.2",
+# "exit"
+# ],
+
+
+# using replaced
+
+# before state
+
+# veos#show running-config | section ospfv3
+# router ospfv3
+# fips restrictions
+# area 0.0.0.0 encryption ipsec spi 43 esp null md5 passphrase 7 h8pZp9eprTYjjoY/NKFFe0Ei7x03Y7dyLotRhI0a5t4=
+# !
+# router ospfv3 vrf vrfmerge
+# router-id 2.2.2.2
+# fips restrictions
+# timers pacing flood 55
+# !
+# address-family ipv6
+# fips restrictions
+# timers lsa arrival 22
+# graceful-restart grace-period 35
+# veos#
+
+
+ - arista.eos.eos_ospfv3:
+ config:
+ processes:
+ - areas:
+ - area_id: "0.0.0.0"
+ encryption:
+ spi: 43
+ encryption: "null"
+ algorithm: "md5"
+ encrypt_key: False
+ passphrase: "7hl8FV3lZ6H1mAKpjL47hQ=="
+ vrf: "default"
+ address_family:
+ - afi: "ipv4"
+ router_id: "7.1.1.1"
+ state: replaced
+
+# After state
+# veos#show running-config | section ospfv3
+# router ospfv3
+# area 0.0.0.0 encryption ipsec spi 43 esp null md5 passphrase 7 h8pZp9eprTYjjoY/NKFFe0Ei7x03Y7dyLotRhI0a5t4=
+# !
+# router ospfv3 vrf vrfmerge
+# passive-interface default
+# !
+# address-family ipv6
+# area 0.0.0.3 range 10.1.2.0/24
+# area 0.0.0.3 range 60.1.0.0/16 cost 30
+# veos#
+
+# Module execution
+
+# "after": {
+# "processes": [
+# {
+# "areas": [
+# {
+# "area_id": "0.0.0.0",
+# "encryption": {
+# "algorithm": "md5",
+# "encryption": "null",
+# "hidden_key": true,
+# "passphrase": "h8pZp9eprTYjjoY/NKFFe0Ei7x03Y7dyLotRhI0a5t4="
+# }
+# }
+# ],
+# "vrf": "default"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "areas": [
+# {
+# "area_id": "0.0.0.3",
+# "ranges": [
+# {
+# "address": "10.1.2.0/24"
+# },
+# {
+# "address": "60.1.0.0/16",
+# "cost": 30
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "passive_interface": true,
+# "vrf": "vrfmerge"
+# }
+# ]
+# },
+# "before": {
+# "processes": [
+# {
+# "areas": [
+# {
+# "area_id": "0.0.0.0",
+# "encryption": {
+# "algorithm": "md5",
+# "encryption": "null",
+# "hidden_key": true,
+# "passphrase": "h8pZp9eprTYjjoY/NKFFe0Ei7x03Y7dyLotRhI0a5t4="
+# }
+# }
+# ],
+# "fips_restrictions": true,
+# "vrf": "default"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "fips_restrictions": true,
+# "graceful_restart": {
+# "grace_period": 35
+# },
+# "timers": {
+# "lsa": 22
+# }
+# }
+# ],
+# "fips_restrictions": true,
+# "router_id": "2.2.2.2",
+# "timers": {
+# "pacing": 55
+# },
+# "vrf": "vrfmerge"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "router ospfv3 vrf vrfmerge",
+# "address-family ipv6",
+# "no fips restrictions",
+# "no graceful-restart",
+# "no timers lsa arrival 22",
+# "area 0.0.0.3 range 10.1.2.2/24 advertise",
+# "area 0.0.0.3 range 60.1.1.1 255.255.0.0 cost 30",
+# "exit",
+# "passive-interface default",
+# "no router-id",
+# "no fips restrictions",
+# "no timers pacing flood 55",
+# "exit"
+# ],
+
+
+# using overridden
+
+# before state
+
+# veos#show running-config | section ospfv3
+# router ospfv3
+# area 0.0.0.0 encryption ipsec spi 43 esp null md5 passphrase 7 h8pZp9eprTYjjoY/NKFFe0Ei7x03Y7dyLotRhI0a5t4=
+# !
+# router ospfv3 vrf vrfmerge
+# passive-interface default
+# !
+# address-family ipv6
+# area 0.0.0.3 range 10.1.2.0/24
+# area 0.0.0.3 range 60.1.0.0/16 cost 30
+# veos#
+
+
+ - arista.eos.eos_ospfv3:
+ config:
+ processes:
+ - address_family:
+ - areas:
+ - area_id: "0.0.0.3"
+ ranges:
+ - address: 10.1.2.2/24
+ advertise: True
+ - address: 60.1.1.1
+ subnet_mask: 255.255.0.0
+ cost: 30
+ afi: "ipv6"
+ passive_interface: True
+ vrf: "vrfmerge"
+ state: overridden
+
+# After state
+
+# veos#show running-config | section ospfv3
+# router ospfv3 vrf vrfmerge
+# passive-interface default
+# !
+# address-family ipv6
+# area 0.0.0.3 range 10.1.2.0/24
+# area 0.0.0.3 range 60.1.0.0/16 cost 30
+# veos#
+
+
+
+# Module execution
+
+# "after": {
+# "processes": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "areas": [
+# {
+# "area_id": "0.0.0.3",
+# "ranges": [
+# {
+# "address": "10.1.2.0/24"
+# },
+# {
+# "address": "60.1.0.0/16",
+# "cost": 30
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "passive_interface": true,
+# "vrf": "vrfmerge"
+# }
+# ]
+# },
+# "before": {
+# "processes": [
+# {
+# "areas": [
+# {
+# "area_id": "0.0.0.0",
+# "encryption": {
+# "algorithm": "md5",
+# "encryption": "null",
+# "hidden_key": true,
+# "passphrase": "h8pZp9eprTYjjoY/NKFFe0Ei7x03Y7dyLotRhI0a5t4="
+# }
+# }
+# ],
+# "vrf": "default"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "areas": [
+# {
+# "area_id": "0.0.0.3",
+# "ranges": [
+# {
+# "address": "10.1.2.0/24"
+# },
+# {
+# "address": "60.1.0.0/16",
+# "cost": 30
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "passive_interface": true,
+# "vrf": "vrfmerge"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "no router ospfv3",
+# "router ospfv3 vrf vrfmerge",
+# "address-family ipv6",
+# "no area 0.0.0.3 range 10.1.2.0/24",
+# "no area 0.0.0.3 range 60.1.0.0/16 cost 30",
+# "area 0.0.0.3 range 10.1.2.2/24 advertise",
+# "area 0.0.0.3 range 60.1.1.1 255.255.0.0 cost 30",
+# "exit",
+# "exit"
+# ],
+
+# using deleted
+
+# Before state
+
+# veos#show running-config | section ospfv3
+# router ospfv3
+# area 0.0.0.0 encryption ipsec spi 43 esp null md5 passphrase 7 h8pZp9eprTYjjoY/NKFFe0Ei7x03Y7dyLotRhI0a5t4=
+# !
+# router ospfv3 vrf vrfmerge
+# passive-interface default
+# !
+# address-family ipv4
+# redistribute connected
+# redistribute static route-map MAP01
+# area 0.0.0.3 range 10.1.2.0/24
+# area 0.0.0.3 range 60.1.0.0/16 cost 30
+# !
+# address-family ipv6
+# area 0.0.0.3 range 10.1.2.0/24
+# area 0.0.0.3 range 60.1.0.0/16 cost 30
+# veos#
+
+
+ - arista.eos.eos_ospfv3:
+ config:
+ processes:
+ - vrf: "default"
+ state: deleted
+
+# After state
+
+# veos#show running-config | section ospfv3
+# router ospfv3 vrf vrfmerge
+# passive-interface default
+# !
+# address-family ipv4
+# redistribute connected
+# redistribute static route-map MAP01
+# area 0.0.0.3 range 10.1.2.0/24
+# area 0.0.0.3 range 60.1.0.0/16 cost 30
+# !
+# address-family ipv6
+# area 0.0.0.3 range 10.1.2.0/24
+# area 0.0.0.3 range 60.1.0.0/16 cost 30
+# veos#
+
+
+# Module execution
+# "after": {
+# "processes": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "areas": [
+# {
+# "area_id": "0.0.0.3",
+# "ranges": [
+# {
+# "address": "10.1.2.0/24"
+# },
+# {
+# "address": "60.1.0.0/16",
+# "cost": 30
+# }
+# ]
+# }
+# ],
+# "redistribute": [
+# {
+# "routes": "connected"
+# },
+# {
+# "route_map": "MAP01",
+# "routes": "static"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "areas": [
+# {
+# "area_id": "0.0.0.3",
+# "ranges": [
+# {
+# "address": "10.1.2.0/24"
+# },
+# {
+# "address": "60.1.0.0/16",
+# "cost": 30
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "passive_interface": true,
+# "vrf": "vrfmerge"
+# }
+# ]
+# },
+# "before": {
+# "processes": [
+# {
+# "areas": [
+# {
+# "area_id": "0.0.0.0",
+# "encryption": {
+# "algorithm": "md5",
+# "encryption": "null",
+# "hidden_key": true,
+# "passphrase": "h8pZp9eprTYjjoY/NKFFe0Ei7x03Y7dyLotRhI0a5t4="
+# }
+# }
+# ],
+# "vrf": "default"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "areas": [
+# {
+# "area_id": "0.0.0.3",
+# "ranges": [
+# {
+# "address": "10.1.2.0/24"
+# },
+# {
+# "address": "60.1.0.0/16",
+# "cost": 30
+# }
+# ]
+# }
+# ],
+# "redistribute": [
+# {
+# "routes": "connected"
+# },
+# {
+# "route_map": "MAP01",
+# "routes": "static"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "areas": [
+# {
+# "area_id": "0.0.0.3",
+# "ranges": [
+# {
+# "address": "10.1.2.0/24"
+# },
+# {
+# "address": "60.1.0.0/16",
+# "cost": 30
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "passive_interface": true,
+# "vrf": "vrfmerge"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "no router ospfv3"
+# ],
+
+# using parsed
+
+# parsed_ospfv3.cfg
+
+# router ospfv3
+# fips restrictions
+# area 0.0.0.20 stub
+# area 0.0.0.20 authentication ipsec spi 33 sha1 passphrase 7 4O8T3zo4xBdRWXBnsnK934o9SEb+jEhHUN6+xzZgCo2j9EnQBUvtwNxxLEmYmm6w
+# area 0.0.0.40 default-cost 45
+# area 0.0.0.40 stub
+# timers pacing flood 7
+# adjacency exchange-start threshold 11
+# !
+# address-family ipv4
+# fips restrictions
+# redistribute connected
+# !
+# address-family ipv6
+# router-id 10.1.1.1
+# fips restrictions
+# !
+# router ospfv3 vrf vrf01
+# bfd all-interfaces
+# fips restrictions
+# area 0.0.0.0 encryption ipsec spi 256 esp null sha1 passphrase 7 7hl8FV3lZ6H1mAKpjL47hQ==
+# log-adjacency-changes detail
+# !
+# address-family ipv4
+# passive-interface default
+# fips restrictions
+# redistribute connected route-map MAP01
+# maximum-paths 100
+# !
+# address-family ipv6
+# fips restrictions
+# area 0.0.0.10 nssa no-summary
+# default-information originate route-map DefaultRouteFilter
+# max-metric router-lsa external-lsa 25 summary-lsa
+# !
+# router ospfv3 vrf vrf02
+# fips restrictions
+# !
+# address-family ipv6
+# router-id 10.17.0.3
+# distance ospf intra-area 200
+# fips restrictions
+# area 0.0.0.1 stub
+# timers spf delay initial 56 56 56
+# timers out-delay 10
+
+
+ - arista.eos.eos_ospfv3:
+ running_config: "{{ lookup('file', './parsed_ospfv3.cfg') }}"
+ state: parsed
+
+# Module execution
+
+# "parsed": {
+# "processes": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "fips_restrictions": true,
+# "redistribute": [
+# {
+# "routes": "connected"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "fips_restrictions": true,
+# "router_id": "10.1.1.1"
+# }
+# ],
+# "adjacency": {
+# "exchange_start": {
+# "threshold": 11
+# }
+# },
+# "areas": [
+# {
+# "area_id": "0.0.0.20",
+# "authentication": {
+# "algorithm": "sha1",
+# "hidden_key": true,
+# "passphrase": "4O8T3zo4xBdRWXBnsnK934o9SEb+jEhHUN6+xzZgCo2j9EnQBUvtwNxxLEmYmm6w",
+# "spi": 33
+# },
+# "stub": {
+# "set": true
+# }
+# },
+# {
+# "area_id": "0.0.0.40",
+# "default_cost": 45,
+# "stub": {
+# "set": true
+# }
+# }
+# ],
+# "fips_restrictions": true,
+# "timers": {
+# "pacing": 7
+# },
+# "vrf": "default"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "fips_restrictions": true,
+# "maximum_paths": 100,
+# "passive_interface": true,
+# "redistribute": [
+# {
+# "route_map": "MAP01",
+# "routes": "connected"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "areas": [
+# {
+# "area_id": "0.0.0.10",
+# "nssa": {
+# "no_summary": true
+# }
+# }
+# ],
+# "default_information": {
+# "originate": true,
+# "route_map": "DefaultRouteFilter"
+# },
+# "fips_restrictions": true,
+# "max_metric": {
+# "router_lsa": {
+# "external_lsa": {
+# "max_metric_value": 25
+# },
+# "summary_lsa": {
+# "set": true
+# }
+# }
+# }
+# }
+# ],
+# "areas": [
+# {
+# "area_id": "0.0.0.0",
+# "encryption": {
+# "algorithm": "sha1",
+# "encryption": "null",
+# "hidden_key": true,
+# "passphrase": "7hl8FV3lZ6H1mAKpjL47hQ=="
+# }
+# }
+# ],
+# "bfd": {
+# "all_interfaces": true
+# },
+# "fips_restrictions": true,
+# "log_adjacency_changes": {
+# "detail": true
+# },
+# "vrf": "vrf01"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv6",
+# "areas": [
+# {
+# "area_id": "0.0.0.1",
+# "stub": {
+# "set": true
+# }
+# }
+# ],
+# "distance": 200,
+# "fips_restrictions": true,
+# "router_id": "10.17.0.3",
+# "timers": {
+# "out_delay": 10,
+# "spf": {
+# "initial": 56,
+# "max": 56,
+# "min": 56,
+# }
+# }
+# }
+# ],
+# "fips_restrictions": true,
+# "vrf": "vrf02"
+# }
+# ]
+
+# using gathered
+
+# native config
+
+# veos#show running-config | section ospfv3
+# router ospfv3 vrf vrfmerge
+# passive-interface default
+# !
+# address-family ipv4
+# redistribute connected
+# redistribute static route-map MAP01
+# area 0.0.0.3 range 10.1.2.0/24
+# area 0.0.0.3 range 60.1.0.0/16 cost 30
+# !
+# address-family ipv6
+# area 0.0.0.3 range 10.1.2.0/24
+# area 0.0.0.3 range 60.1.0.0/16 cost 30
+# veos#
+
+
+ - arista.eos.eos_ospfv3:
+ state: gathered
+
+# module execution
+
+# "gathered": {
+# "processes": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "areas": [
+# {
+# "area_id": "0.0.0.3",
+# "ranges": [
+# {
+# "address": "10.1.2.0/24"
+# },
+# {
+# "address": "60.1.0.0/16",
+# "cost": 30
+# }
+# ]
+# }
+# ],
+# "redistribute": [
+# {
+# "routes": "connected"
+# },
+# {
+# "route_map": "MAP01",
+# "routes": "static"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "areas": [
+# {
+# "area_id": "0.0.0.3",
+# "ranges": [
+# {
+# "address": "10.1.2.0/24"
+# },
+# {
+# "address": "60.1.0.0/16",
+# "cost": 30
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "passive_interface": true,
+# "vrf": "vrfmerge"
+# }
+# ]
+
+# using rendered
+
+ - arista.eos.eos_ospfv3:
+ config:
+ processes:
+ - address_family:
+ - timers:
+ lsa: 22
+ graceful_restart:
+ grace_period: 35
+ afi: "ipv6"
+ timers:
+ pacing: 55
+ fips_restrictions: True
+ router_id: "2.2.2.2"
+ vrf: "vrfmerge"
+ state: rendered
+
+# module execution
+
+# "rendered": [
+# "router ospfv3 vrf vrfmerge",
+# "address-family ipv6",
+# "graceful-restart grace-period 35",
+# "timers lsa arrival 22",
+# "exit",
+# "timers pacing flood 55",
+# "fips restrictions",
+# "router-id 2.2.2.2",
+# "exit"
+# ]
+
+
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.ospfv3.ospfv3 import (
+ Ospfv3Args,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.ospfv3.ospfv3 import (
+ Ospfv3,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Ospfv3Args.argument_spec,
+ mutually_exclusive=[["config", "running_config"]],
+ required_if=[
+ ["state", "merged", ["config"]],
+ ["state", "replaced", ["config"]],
+ ["state", "overridden", ["config"]],
+ ["state", "rendered", ["config"]],
+ ["state", "parsed", ["running_config"]],
+ ],
+ supports_check_mode=False,
+ )
+
+ result = Ospfv3(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_prefix_lists.py b/ansible_collections/arista/eos/plugins/modules/eos_prefix_lists.py
new file mode 100644
index 000000000..dffd65527
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_prefix_lists.py
@@ -0,0 +1,1197 @@
+#!/usr/bin/python
+# -*- 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)
+
+"""
+The module file for eos_prefix_lists
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+---
+module: eos_prefix_lists
+short_description: Manages Prefix lists resource module
+description: This module configures and manages the attributes of Prefix lists on Arista
+ EOS platforms.
+version_added: 2.2.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,eos_platform_options).
+options:
+ config:
+ description: A list of dictionary of prefix-list options
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description:
+ - The Address Family Indicator (AFI) for the prefix list.
+ type: str
+ required: true
+ choices:
+ - ipv4
+ - ipv6
+ prefix_lists:
+ description:
+ - A list of prefix-lists.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description: Name of the prefix-list
+ type: str
+ required: true
+ entries:
+ description: List of prefix-lists
+ type: list
+ elements: dict
+ suboptions:
+ action:
+ description: action to be performed on the specified path
+ type: str
+ choices: ['deny', 'permit']
+ address:
+ description: ipv4/v6 address in prefix-mask or address-masklen format
+ type: str
+ match:
+ description: match masklen
+ type: dict
+ suboptions:
+ operator:
+ description: equalto/greater than/lesser than
+ type: str
+ choices: ['eq', 'le', 'ge']
+ masklen:
+ description: Mask Length.
+ type: int
+ sequence:
+ description: sequence number
+ type: int
+ resequence:
+ description: Resequence the list.
+ type: dict
+ suboptions:
+ default:
+ description: Resequence with default values (10).
+ type: bool
+ start_seq:
+ description: Starting sequence number.
+ type: int
+ step:
+ description: Step to increment the sequence number.
+ type: int
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section access-list).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices:
+ - deleted
+ - merged
+ - overridden
+ - replaced
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+"""
+EXAMPLES = """
+# Using merged
+# Before state
+# veos#show running-config | section prefix-lists
+# veos#
+
+ - name: Merge provided configuration with device configuration
+ arista.eos.eos_prefix_lists:
+ config:
+ - afi: "ipv4"
+ prefix_lists:
+ - name: "v401"
+ entries:
+ - sequence: 25
+ action: "deny"
+ address: "45.55.4.0/24"
+ - sequence: 100
+ action: "permit"
+ address: "11.11.2.0/24"
+ match:
+ masklen: 32
+ operator: "ge"
+ - name: "v402"
+ entries:
+ - action: "deny"
+ address: "10.1.1.0/24"
+ sequence: 10
+ match:
+ masklen: 32
+ operator: "ge"
+ - afi: "ipv6"
+ prefix_lists:
+ - name: "v601"
+ entries:
+ - sequence: 125
+ action: "deny"
+ address: "5000:1::/64"
+
+# After State
+# veos#
+# veos#show running-config | section prefix-list
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24
+# seq 100 permit 11.11.2.0/24 ge 32
+# !
+# ip prefix-list v402
+# seq 10 deny 10.1.1.0/24 ge 32
+# !
+# ipv6 prefix-list v601
+# seq 125 deny 5000:1::/64
+# veos#
+#
+# Module Execution:
+# "after": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "11.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 100
+# }
+# ],
+# "name": "v401"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 10
+# }
+# ],
+# "name": "v402"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "5000:1::/64",
+# "sequence": 125
+# }
+# ],
+# "name": "v601"
+# }
+# ]
+# }
+# ],
+# "before": {},
+# "changed": true,
+# "commands": [
+# "ipv6 prefix-list v601",
+# "seq 125 deny 5000:1::/64",
+# "ip prefix-list v401",
+# "seq 25 deny 45.55.4.0/24",
+# "seq 100 permit 11.11.2.0/24 ge 32",
+# "ip prefix-list v402",
+# "seq 10 deny 10.1.1.0/24 ge 32"
+# ],
+#
+
+# using merged:
+# Failure scenario : 'merged' should not be used when an existing prefix-list (sequence number)
+# is to be modified.
+
+# Before State:
+# veos#show running-config | section prefix-list
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24
+# seq 100 permit 11.11.2.0/24 ge 32
+# !
+# ip prefix-list v402
+# seq 10 deny 10.1.1.0/24 ge 32
+# !
+# ipv6 prefix-list v601
+# seq 125 deny 5000:1::/64
+# veos#
+
+ - name: Merge provided configuration with device configuration
+ arista.eos.eos_prefix_lists:
+ config:
+ - afi: "ipv4"
+ prefix_lists:
+ - name: "v401"
+ entries:
+ - sequence: 25
+ action: "deny"
+ address: "45.55.4.0/24"
+ match:
+ masklen: 32
+ operator: "ge"
+ - sequence: 100
+ action: "permit"
+ address: "11.11.2.0/24"
+ match:
+ masklen: 32
+ operator: "ge"
+ - name: "v402"
+ entries:
+ - action: "deny"
+ address: "10.1.1.0/24"
+ sequence: 10
+ match:
+ masklen: 32
+ operator: "ge"
+ - afi: "ipv6"
+ prefix_lists:
+ - name: "v601"
+ entries:
+ - sequence: 125
+ action: "deny"
+ address: "5000:1::/64"
+ state: merged
+
+# Module Execution:
+# fatal: [192.168.122.113]: FAILED! => {
+# "changed": false,
+# "invocation": {
+# "module_args": {
+# "config": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "resequence": null,
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "11.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "resequence": null,
+# "sequence": 100
+# }
+# ],
+# "name": "v401"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "resequence": null,
+# "sequence": 10
+# }
+# ],
+# "name": "v402"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "5000:1::/64",
+# "match": null,
+# "resequence": null,
+# "sequence": 125
+# }
+# ],
+# "name": "v601"
+# }
+# ]
+# }
+# ],
+# "running_config": null,
+# "state": "merged"
+# }
+# },
+# "msg": "Sequence number 25 is already present. Use replaced/overridden operation to change the configuration"
+# }
+#
+
+# Using Replaced:
+
+# Before state:
+# veos#show running-config | section prefix-list
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24
+# seq 100 permit 11.11.2.0/24 ge 32
+# !
+# ip prefix-list v402
+# seq 10 deny 10.1.1.0/24 ge 32
+# !
+# ipv6 prefix-list v601
+# seq 125 deny 5000:1::/64
+# veos#
+ - name: Replace
+ arista.eos.eos_prefix_lists:
+ config:
+ - afi: "ipv4"
+ prefix_lists:
+ - name: "v401"
+ entries:
+ - sequence: 25
+ action: "deny"
+ address: "45.55.4.0/24"
+ match:
+ masklen: 32
+ operator: "ge"
+ - sequence: 200
+ action: "permit"
+ address: "200.11.2.0/24"
+ match:
+ masklen: 32
+ operator: "ge"
+ state: replaced
+# After State:
+# veos#show running-config | section prefix-list
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24 ge 32
+# seq 200 permit 200.11.2.0/24 ge 32
+# !
+# ipv6 prefix-list v601
+# seq 125 deny 5000:1::/64
+# veos#
+#
+#
+# Module Execution:
+#
+# "after": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "200.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 200
+# }
+# ],
+# "name": "v401"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "5000:1::/64",
+# "sequence": 125
+# }
+# ],
+# "name": "v601"
+# }
+# ]
+# }
+# ],
+# "before": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "11.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 100
+# }
+# ],
+# "name": "v401"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 10
+# }
+# ],
+# "name": "v402"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "5000:1::/64",
+# "sequence": 125
+# }
+# ],
+# "name": "v601"
+# }
+# ]
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "ip prefix-list v401",
+# "no seq 25",
+# "seq 25 deny 45.55.4.0/24 ge 32",
+# "seq 200 permit 200.11.2.0/24 ge 32",
+# "no seq 100",
+# "no ip prefix-list v402"
+# ],
+
+# Using overridden:
+# Before State:
+
+# veos#show running-config | section prefix-list
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24 ge 32
+# seq 100 permit 11.11.2.0/24 ge 32
+# seq 200 permit 200.11.2.0/24 ge 32
+# !
+# ip prefix-list v402
+# seq 10 deny 10.1.1.0/24 ge 32
+# !
+# ipv6 prefix-list v601
+# seq 125 deny 5000:1::/64
+# veos#
+
+
+ - name: Override
+ arista.eos.eos_prefix_lists:
+ config:
+ - afi: "ipv4"
+ prefix_lists:
+ - name: "v401"
+ entries:
+ - sequence: 25
+ action: "deny"
+ address: "45.55.4.0/24"
+ - sequence: 300
+ action: "permit"
+ address: "30.11.2.0/24"
+ match:
+ masklen: 32
+ operator: "ge"
+ - name: "v403"
+ entries:
+ - action: "deny"
+ address: "10.1.1.0/24"
+ sequence: 10
+ state: overridden
+
+# After State
+# veos#
+# veos#show running-config | section prefix-list
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24 ge 32
+# seq 300 permit 30.11.2.0/24 ge 32
+# !
+# ip prefix-list v403
+# seq 10 deny 10.1.1.0/24
+# veos#
+#
+#
+# Module Execution:
+# "after": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "30.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 300
+# }
+# ],
+# "name": "v401"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "sequence": 10
+# }
+# ],
+# "name": "v403"
+# }
+# ]
+# }
+# ],
+# "before": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "11.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 100
+# },
+# {
+# "action": "permit",
+# "address": "200.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 200
+# }
+# ],
+# "name": "v401"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 10
+# }
+# ],
+# "name": "v402"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "5000:1::/64",
+# "sequence": 125
+# }
+# ],
+# "name": "v601"
+# }
+# ]
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "no ipv6 prefix-list v601",
+# "ip prefix-list v401",
+# "seq 25 deny 45.55.4.0/24",
+# "seq 300 permit 30.11.2.0/24 ge 32",
+# "no seq 100",
+# "no seq 200",
+# "ip prefix-list v403",
+# "seq 10 deny 10.1.1.0/24",
+# "no ip prefix-list v402"
+# ],
+#
+
+# Using deleted:
+# Before State:
+
+# veos#show running-config | section prefix-list
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24 ge 32
+# seq 100 permit 11.11.2.0/24 ge 32
+# seq 300 permit 30.11.2.0/24 ge 32
+# !
+# ip prefix-list v402
+# seq 10 deny 10.1.1.0/24 ge 32
+# !
+# ip prefix-list v403
+# seq 10 deny 10.1.1.0/24
+# !
+# ipv6 prefix-list v601
+# seq 125 deny 5000:1::/64
+# veos#
+
+ - name: Delete device configuration
+ arista.eos.eos_prefix_lists:
+ config:
+ - afi: "ipv6"
+ state: deleted
+
+
+# after State:
+# veos#show running-config | section prefix-list
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24 ge 32
+# seq 100 permit 11.11.2.0/24 ge 32
+# seq 300 permit 30.11.2.0/24 ge 32
+# !
+# ip prefix-list v402
+# seq 10 deny 10.1.1.0/24 ge 32
+# !
+# ip prefix-list v403
+# seq 10 deny 10.1.1.0/24
+#
+#
+# Module Execution:
+# "after": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "11.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 100
+# },
+# {
+# "action": "permit",
+# "address": "30.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 300
+# }
+# ],
+# "name": "v401"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 10
+# }
+# ],
+# "name": "v402"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "sequence": 10
+# }
+# ],
+# "name": "v403"
+# }
+# ]
+# }
+# ],
+# "before": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "11.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 100
+# },
+# {
+# "action": "permit",
+# "address": "30.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 300
+# }
+# ],
+# "name": "v401"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 10
+# }
+# ],
+# "name": "v402"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "sequence": 10
+# }
+# ],
+# "name": "v403"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "5000:1::/64",
+# "sequence": 125
+# }
+# ],
+# "name": "v601"
+# }
+# ]
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "no ipv6 prefix-list v601"
+# ],
+#
+
+# Using deleted
+# Before state:
+
+# veos#show running-config | section prefix-list
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24 ge 32
+# seq 100 permit 11.11.2.0/24 ge 32
+# seq 300 permit 30.11.2.0/24 ge 32
+# !
+# ip prefix-list v402
+# seq 10 deny 10.1.1.0/24 ge 32
+# !
+# ip prefix-list v403
+# seq 10 deny 10.1.1.0/24
+# veos#
+
+ - name: Delete device configuration
+ arista.eos.eos_prefix_lists:
+ state: deleted
+
+# After State:
+# veos#show running-config | section prefix-list
+# veos#
+#
+# Module Execution:
+# "after": {},
+# "before": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "11.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 100
+# },
+# {
+# "action": "permit",
+# "address": "30.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 300
+# }
+# ],
+# "name": "v401"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 10
+# }
+# ],
+# "name": "v402"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "sequence": 10
+# }
+# ],
+# "name": "v403"
+# }
+# ]
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "no ip prefix-list v401",
+# "no ip prefix-list v402",
+# "no ip prefix-list v403"
+# ],
+#
+
+# Using parsed:
+# parse_prefix_lists.cfg
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24
+# seq 100 permit 11.11.2.0/24 ge 32
+# !
+# ip prefix-list v402
+# seq 10 deny 10.1.1.0/24
+# !
+# ipv6 prefix-list v601
+# seq 125 deny 5000:1::/64
+#
+ - name: parse configs
+ arista.eos.eos_prefix_lists:
+ running_config: "{{ lookup('file', './parsed_prefix_lists.cfg') }}"
+ state: parsed
+
+# Module Execution:
+# "parsed": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "11.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 100
+# }
+# ],
+# "name": "v401"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "sequence": 10
+# }
+# ],
+# "name": "v402"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "5000:1::/64",
+# "sequence": 125
+# }
+# ],
+# "name": "v601"
+# }
+# ]
+# }
+# ]
+
+# Using rendered:
+ - name: Render provided configuration
+ arista.eos.eos_prefix_lists:
+ config:
+ - afi: "ipv4"
+ prefix_lists:
+ - name: "v401"
+ entries:
+ - sequence: 25
+ action: "deny"
+ address: "45.55.4.0/24"
+ - sequence: 200
+ action: "permit"
+ address: "200.11.2.0/24"
+ match:
+ masklen: 32
+ operator: "ge"
+ - name: "v403"
+ entries:
+ - action: "deny"
+ address: "10.1.1.0/24"
+ sequence: 10
+ state: rendered
+
+# Module Execution:
+# "rendered": [
+# "ip prefix-list v401",
+# "seq 25 deny 45.55.4.0/24",
+# "seq 200 permit 200.11.2.0/24 ge 32",
+# "ip prefix-list v403",
+# "seq 10 deny 10.1.1.0/24"
+# ]
+#
+
+# using gathered:
+# Device config:
+# veos#show running-config | section prefix-list
+# ip prefix-list v401
+# seq 25 deny 45.55.4.0/24
+# seq 100 permit 11.11.2.0/24 ge 32
+# !
+# ip prefix-list v402
+# seq 10 deny 10.1.1.0/24 ge 32
+# !
+# ipv6 prefix-list v601
+# seq 125 deny 5000:1::/64
+# veos#
+
+ - name: gather configs
+ arista.eos.eos_prefix_lists:
+ state: gathered
+
+# Module Execution:
+#
+# "gathered": [
+# {
+# "afi": "ipv4",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "45.55.4.0/24",
+# "sequence": 25
+# },
+# {
+# "action": "permit",
+# "address": "11.11.2.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 100
+# }
+# ],
+# "name": "v401"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "10.1.1.0/24",
+# "match": {
+# "masklen": 32,
+# "operator": "ge"
+# },
+# "sequence": 10
+# }
+# ],
+# "name": "v402"
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "prefix_lists": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "address": "5000:1::/64",
+# "sequence": 125
+# }
+# ],
+# "name": "v601"
+# }
+# ]
+# }
+# ],
+
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.prefix_lists.prefix_lists import (
+ Prefix_listsArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.prefix_lists.prefix_lists import (
+ Prefix_lists,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Prefix_listsArgs.argument_spec,
+ mutually_exclusive=[["config", "running_config"]],
+ required_if=[
+ ["state", "merged", ["config"]],
+ ["state", "replaced", ["config"]],
+ ["state", "overridden", ["config"]],
+ ["state", "rendered", ["config"]],
+ ["state", "parsed", ["running_config"]],
+ ],
+ supports_check_mode=True,
+ )
+
+ result = Prefix_lists(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_route_maps.py b/ansible_collections/arista/eos/plugins/modules/eos_route_maps.py
new file mode 100644
index 000000000..3b1869547
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_route_maps.py
@@ -0,0 +1,1406 @@
+#!/usr/bin/python
+# -*- 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)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_route_maps
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: eos_route_maps
+short_description: Manages Route Maps resource module
+description: This module configures and manages the attributes of Route Mapd on Arista
+ EOS platforms.
+version_added: 2.1.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,eos_platform_options).
+options:
+ config:
+ description: A list of route-map options
+ type: list
+ elements: dict
+ suboptions:
+ route_map:
+ description: Route map name.
+ type: str
+ entries:
+ description: Route Map entries.
+ type: list
+ elements: dict
+ suboptions:
+ statement:
+ description: statement name
+ type: str
+ source:
+ description: Rename/Copy configuration
+ type: dict
+ suboptions:
+ action:
+ description: rename or copy configuration
+ type: str
+ choices: ["rename", "copy"]
+ source_map_name:
+ description: Source route map name.
+ type: str
+ overwrite:
+ description: if True, overwrite existing config.
+ type: bool
+ action:
+ description: Action for matching routes
+ type: str
+ choices: ["deny", "permit"]
+ sequence:
+ description: Index in the sequence.
+ type: int
+ continue_sequence:
+ description: Route map entry sequence number.
+ type: int
+ description:
+ description: Description for the route map.
+ type: str
+ sub_route_map:
+ description: Sub route map
+ type: dict
+ suboptions:
+ name:
+ description: sub route map name
+ type: str
+ invert_result:
+ description: Invert sub route map result
+ type: bool
+ set:
+ description: set route attributes.
+ type: dict
+ suboptions:
+ as_path:
+ description: Set as-path.
+ type: dict
+ suboptions:
+ match:
+ description: Match the entire as-path.
+ type: dict
+ suboptions:
+ as_number:
+ description: as number to use (includes auto;in csv format)
+ type: str
+ none:
+ description: Remove matching AS numbers
+ type: bool
+ prepend:
+ description: Prepend to the as-path.
+ type: dict
+ suboptions:
+ as_number:
+ description: as number to prepend (includes auto;in csv format)
+ type: str
+ last_as:
+ description: The number of times to prepend the last AS number.
+ type: int
+ bgp:
+ description: BGP AS path multipath weight.
+ type: int
+ community_attributes:
+ description: BGP community attribute.
+ type: dict
+ suboptions:
+ graceful_shutdown:
+ description: Graceful shutdown
+ type: bool
+ community:
+ description: community attributes.
+ type: dict
+ suboptions:
+ number:
+ description: community number (in csv format).
+ type: str
+ list:
+ description: community list name.
+ type: str
+ graceful_shutdown:
+ description: Gracefully shutdown.
+ type: bool
+ additive:
+ description: Add to existing community.
+ type: bool
+ delete:
+ description: Delete matching communities.
+ type: bool
+ internet:
+ description: Internet community
+ type: bool
+ local_as:
+ description: Do not send outside local AS.
+ type: bool
+ no_advertise:
+ description: Do not advertise to any peer.
+ type: bool
+ no_export:
+ description: Do not export to next AS.
+ type: bool
+ none:
+ description: No community attribute.
+ type: bool
+ distance:
+ description: Set protocol independent distance.
+ type: int
+ evpn:
+ description: Keep the next hop when advertising to eBGP peers.
+ type: bool
+ extcommunity:
+ description: BGP extended community attribute.
+ type: dict
+ suboptions:
+ lbw:
+ description: Link bandwith values.
+ type: dict
+ suboptions:
+ value:
+ description: Link Bandwidth extended community value.
+ type: str
+ aggregate:
+ description: Aggregate Link Bandwidth.
+ type: bool
+ divide:
+ description: Divide Link Bandwidth.
+ type: str
+ choices: ["equal", "ration"]
+ none:
+ description: No attribute.
+ type: bool
+ rt:
+ description: Route target extended community
+ type: dict
+ suboptions: &params01
+ vpn:
+ description: VPN extended community.
+ type: str
+ additive:
+ description: Add to the existing community.
+ type: bool
+ delete:
+ description: Delete matching communities.
+ type: bool
+ soo:
+ description: Site-of-Origin extended community.
+ type: dict
+ suboptions: *params01
+ ip:
+ description: Set IP specific information.
+ type: dict
+ suboptions: &params02
+ address:
+ description: next hop address.
+ type: str
+ unchanged:
+ description: Keep the next hop when advertising to eBGP peer
+ type: bool
+ peer_address:
+ description: Use BGP peering addr as next-hop.
+ type: bool
+ ipv6:
+ description: Set IPv6 specific information.
+ type: dict
+ suboptions: *params02
+ isis_level:
+ description: IS-IS level.
+ type: str
+ local_preference:
+ description: BGP local preference.
+ type: int
+ metric:
+ description: Route metric.
+ type: dict
+ suboptions:
+ igp_param:
+ description: IGP parameter
+ type: str
+ choices: ['igp-metric', 'igp-nexthop-cost']
+ add:
+ description: Add igp-metric / igp-nexthop-cost
+ type: str
+ choices: ['igp-metric', 'igp-nexthop-cost']
+ value:
+ description: metric value to add or subtract(with +/- sign).
+ type: str
+ metric_type:
+ description: Route metric type.
+ type: str
+ choices: ["type-1", "type-2"]
+ nexthop:
+ description: Route next hop.
+ type: dict
+ suboptions:
+ value:
+ description: IGP metric value.
+ type: int
+ max_metric:
+ description: Set IGP max metric value.
+ type: bool
+ origin:
+ description: Set bgp origin.
+ type: str
+ choices: ["egp", "igp", "incomplete"]
+ segment_index:
+ description: MPLS Segment-routing Segment Index.
+ type: int
+ tag:
+ description: Route tag
+ type: int
+ weight:
+ description: BGP weight.
+ type: int
+ match:
+ description: Route map match rules.
+ type: dict
+ suboptions:
+ aggregate_role: &params04
+ description: Role in BGP contributor-aggregate relation.
+ type: dict
+ suboptions:
+ contributor:
+ description: BGP aggregate's contributor.
+ type: bool
+ route_map:
+ description: Route map to apply against the aggregate route.
+ type: str
+ as:
+ description: BGP AS number.
+ type: int
+ as_path: &params05
+ description: Set as-path.
+ type: dict
+ suboptions:
+ path_list:
+ description: AS path list name.
+ type: str
+ length:
+ description: Specify as-path length ( with comparison operators like <= 60 and >= 40 ).
+ type: str
+ community: &params06
+ description: BGP community attribute.
+ type: dict
+ suboptions:
+ community_list:
+ description: list of community names (in csv format).
+ type: str
+ exact_match:
+ description: Do exact matching of communities.
+ type: bool
+ instances:
+ description: Match number of community instances ( with comparison operators like <= 60 and >= 40 ).
+ type: str
+ extcommunity: &params07
+ description: extended community list name.
+ type: dict
+ suboptions:
+ community_list:
+ description: list of community names (in csv format).
+ type: str
+ exact_match:
+ description: Do exact matching of communities.
+ type: bool
+ interface:
+ description: interface name.
+ type: str
+ invert_result:
+ description: Invert match result.
+ type: dict
+ suboptions:
+ aggregate_role: *params04
+ as_path: *params05
+ community: *params06
+ extcommunity: *params07
+ large_community: *params07
+ ip:
+ description: Set IP specific information.
+ type: dict
+ suboptions: &params08
+ address:
+ description: next hop destination.
+ type: dict
+ suboptions:
+ access_list:
+ description: ip access-list.
+ type: str
+ dynamic:
+ description: Configure dynamic prefix-list.
+ type: bool
+ prefix_list:
+ description: Prefix list.
+ type: str
+ next_hop:
+ description: next hop prefix list.
+ type: str
+ resolved_next_hop:
+ description: Route resolved prefix list.
+ type: str
+ ipv6:
+ description: Set IPv6 specific information.
+ type: dict
+ suboptions: *params08
+ large_community: *params07
+ isis_level:
+ description: IS-IS level.
+ type: str
+ local_preference:
+ description: BGP local preference.
+ type: int
+ metric:
+ description: Route metric.
+ type: int
+ metric_type:
+ description: Route metric type.
+ type: str
+ choices: ["type-1", "type-2"]
+ route_type:
+ description: Route type
+ type: str
+ router_id:
+ description: Router ID.
+ type: str
+ source_protocol:
+ description: Source routing protocol,
+ type: str
+ tag:
+ description: Route tag
+ type: int
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section route-map).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices:
+ - deleted
+ - merged
+ - overridden
+ - replaced
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+"""
+EXAMPLES = """
+# Using merged
+# Before state
+# veos#show running-config | section route-map
+# veos#
+
+ - name: Merge provided configuration with device configuration
+ arista.eos.eos_route_maps:
+ config:
+ - route_map: "mapmerge"
+ entries:
+ - description: "merged_map"
+ action: "permit"
+ sequence: 10
+ match:
+ router_id: 22
+ - description: "newmap"
+ action: "deny"
+ sequence: 25
+ continue_sequence: 45
+ match:
+ interface: "Ethernet1"
+ - route_map: "mapmerge2"
+ entries:
+ - sub_route_map:
+ name: "mapmerge"
+ action: "deny"
+ sequence: 45
+ set:
+ metric:
+ value: 25
+ add: "igp-metric"
+ as_path:
+ prepend:
+ last_as: 2
+ match:
+ ipv6:
+ resolved_next_hop: "list1"
+ state: merged
+
+# After State:
+
+# veos#show running-config | section route-map
+# route-map mapmerge permit 10
+# description merged_map
+# match router-id prefix-list 22
+# !
+# route-map mapmerge deny 25
+# description newmap
+# match interface Ethernet1
+# continue 45
+# !
+# route-map mapmerge2 deny 45
+# match ipv6 resolved-next-hop prefix-list list1
+# sub-route-map mapmerge
+# set metric 25 +igp-metric
+# set as-path prepend last-as 2
+# !
+# route-map test permit 10
+# veos#
+
+
+# Module Execution:
+
+# "after": [
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "description": "merged_map",
+# "match": {
+# "router_id": "22"
+# },
+# "sequence": 10
+# },
+# {
+# "action": "deny",
+# "continue_sequence": 45,
+# "description": "newmap",
+# "match": {
+# "interface": "Ethernet1"
+# },
+# "sequence": 25
+# }
+# ],
+# "route_map": "mapmerge"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "list1"
+# }
+# },
+# "sequence": 45,
+# "set": {
+# "as_path": {
+# "prepend": {
+# "last_as": 2
+# }
+# },
+# "metric": {
+# "add": "igp-metric",
+# "value": "25"
+# }
+# },
+# "sub_route_map": {
+# "name": "mapmerge"
+# }
+# }
+# ],
+# "route_map": "mapmerge2"
+# }
+# ],
+# "before": {},
+# "changed": true,
+# "commands": [
+# "route-map mapmerge permit 10",
+# "match router-id prefix-list 22",
+# "description merged_map",
+# "route-map mapmerge deny 25",
+# "match interface Ethernet1",
+# "description newmap",
+# "continue 45",
+# "route-map mapmerge2 deny 45",
+# "match ipv6 resolved-next-hop prefix-list list1",
+# "set metric 25 +igp-metric",
+# "set as-path prepend last-as 2",
+# "sub-route-map mapmerge"
+# ],
+#
+
+# Using replaced:
+
+# Before State:
+
+# veos#show running-config | section route-map
+# route-map mapmerge permit 10
+# description merged_map
+# match router-id prefix-list 22
+# !
+# route-map mapmerge deny 25
+# description newmap
+# match interface Ethernet1
+# continue 45
+# !
+# route-map mapmerge2 deny 45
+# match ipv6 resolved-next-hop prefix-list list1
+# sub-route-map mapmerge
+# set metric 25 +igp-metric
+# set as-path prepend last-as 2
+# !
+# veos#
+
+ - name: Replace
+ arista.eos.eos_route_maps:
+ config:
+ - route_map: "mapmerge"
+ entries:
+ - action: "permit"
+ sequence: 10
+ match:
+ ipv6:
+ resolved_next_hop: "listr"
+ - action: "deny"
+ sequence: 90
+ set:
+ extcommunity:
+ rt:
+ vpn: "22:11"
+ delete: True
+ ip:
+ unchanged: True
+ state: replaced
+
+# After State:
+
+# veos#show running-config | section route-map
+# route-map mapmerge permit 10
+# match ipv6 resolved-next-hop prefix-list listr
+# !
+# route-map mapmerge deny 25
+# description newmap
+# match interface Ethernet1
+# continue 45
+# !
+# route-map mapmerge deny 90
+# set ip next-hop unchanged
+# set extcommunity rt 22:11 delete
+# !
+# route-map mapmerge2 deny 45
+# match ipv6 resolved-next-hop prefix-list list1
+# sub-route-map mapmerge
+# set metric 25 +igp-metric
+# set as-path prepend last-as 2
+# !
+#
+# Module Execution:
+#
+# "after": [
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "listr"
+# }
+# },
+# "sequence": 10
+# },
+# {
+# "action": "deny",
+# "continue_sequence": 45,
+# "description": "newmap",
+# "match": {
+# "interface": "Ethernet1"
+# },
+# "sequence": 25
+# },
+# {
+# "action": "deny",
+# "sequence": 90,
+# "set": {
+# "extcommunity": {
+# "rt": {
+# "delete": true,
+# "vpn": "22:11"
+# }
+# },
+# "ip": {
+# "unchanged": true
+# }
+# }
+# }
+# ],
+# "route_map": "mapmerge"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "list1"
+# }
+# },
+# "sequence": 45,
+# "set": {
+# "as_path": {
+# "prepend": {
+# "last_as": 2
+# }
+# },
+# "metric": {
+# "add": "igp-metric",
+# "value": "25"
+# }
+# },
+# "sub_route_map": {
+# "name": "mapmerge"
+# }
+# }
+# ],
+# "route_map": "mapmerge2"
+# },
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "sequence": 10
+# }
+# ],
+# "route_map": "test"
+# }
+# ],
+# "before": [
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "description": "merged_map",
+# "match": {
+# "router_id": "22"
+# },
+# "sequence": 10
+# },
+# {
+# "action": "deny",
+# "continue_sequence": 45,
+# "description": "newmap",
+# "match": {
+# "interface": "Ethernet1"
+# },
+# "sequence": 25
+# }
+# ],
+# "route_map": "mapmerge"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "list1"
+# }
+# },
+# "sequence": 45,
+# "set": {
+# "as_path": {
+# "prepend": {
+# "last_as": 2
+# }
+# },
+# "metric": {
+# "add": "igp-metric",
+# "value": "25"
+# }
+# },
+# "sub_route_map": {
+# "name": "mapmerge"
+# }
+# }
+# ],
+# "route_map": "mapmerge2"
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "route-map mapmerge permit 10",
+# "match ipv6 resolved-next-hop prefix-list listr",
+# "no match router-id prefix-list 22",
+# "no description",
+# "route-map mapmerge deny 90",
+# "set extcommunity rt 22:11 delete",
+# "set ip next-hop unchanged"
+# ],
+#
+#
+# Using Overridden:
+
+# Before state:
+# veos#show running-config | section route-map
+# route-map mapmerge permit 10
+# match ipv6 resolved-next-hop prefix-list listr
+# !
+# route-map mapmerge deny 25
+# description newmap
+# match interface Ethernet1
+# continue 45
+# !
+# route-map mapmerge deny 90
+# set ip next-hop unchanged
+# set extcommunity rt 22:11 delete
+# !
+# route-map mapmerge2 deny 45
+# match ipv6 resolved-next-hop prefix-list list1
+# sub-route-map mapmerge
+# set metric 25 +igp-metric
+# set as-path prepend last-as 2
+# !
+# route-map test permit 10
+# veos#
+
+ - name: Override
+ arista.eos.eos_route_maps:
+ config:
+ - route_map: "mapmerge"
+ entries:
+ - action: "permit"
+ sequence: 10
+ match:
+ ipv6:
+ resolved_next_hop: "listr"
+ - action: "deny"
+ sequence: 90
+ set:
+ metric:
+ igp_param: "igp-nexthop-cost"
+ state: overridden
+
+# After State:
+
+# veos#show running-config | section route-map
+# route-map mapmerge permit 10
+# match ipv6 resolved-next-hop prefix-list listr
+# !
+# route-map mapmerge deny 90
+# set metric igp-nexthop-cost
+# veos#
+#
+#
+# "after": [
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "listr"
+# }
+# },
+# "sequence": 10
+# },
+# {
+# "action": "deny",
+# "sequence": 90,
+# "set": {
+# "metric": {
+# "igp_param": "igp-nexthop-cost"
+# }
+# }
+# }
+# ],
+# "route_map": "mapmerge"
+# }
+# ],
+# "before": [
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "listr"
+# }
+# },
+# "sequence": 10
+# },
+# {
+# "action": "deny",
+# "continue_sequence": 45,
+# "description": "newmap",
+# "match": {
+# "interface": "Ethernet1"
+# },
+# "sequence": 25
+# },
+# {
+# "action": "deny",
+# "sequence": 90,
+# "set": {
+# "extcommunity": {
+# "rt": {
+# "delete": true,
+# "vpn": "22:11"
+# }
+# },
+# "ip": {
+# "unchanged": true
+# }
+# }
+# }
+# ],
+# "route_map": "mapmerge"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "list1"
+# }
+# },
+# "sequence": 45,
+# "set": {
+# "as_path": {
+# "prepend": {
+# "last_as": 2
+# }
+# },
+# "metric": {
+# "add": "igp-metric",
+# "value": "25"
+# }
+# },
+# "sub_route_map": {
+# "name": "mapmerge"
+# }
+# }
+# ],
+# "route_map": "mapmerge2"
+# },
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "sequence": 10
+# }
+# ],
+# "route_map": "test"
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "no route-map mapmerge deny 25",
+# "no route-map mapmerge2 deny 45",
+# "no route-map test permit 10",
+# "route-map mapmerge deny 90",
+# "set metric igp-nexthop-cost",
+# "no set ip next-hop unchanged",
+# "no set extcommunity rt 22:11 delete"
+# ],
+#
+# Using deleted:
+# Before State:
+
+# veos#show running-config | section route-map
+# route-map mapmerge permit 10
+# description merged_map
+# match router-id prefix-list 22
+# match ipv6 resolved-next-hop prefix-list listr
+# !
+# route-map mapmerge deny 25
+# description newmap
+# match interface Ethernet1
+# continue 45
+# !
+# route-map mapmerge deny 90
+# set metric igp-nexthop-cost
+# !
+# route-map mapmerge2 deny 45
+# match ipv6 resolved-next-hop prefix-list list1
+# sub-route-map mapmerge
+# set metric 25 +igp-metric
+# set as-path prepend last-as 2
+# veos#
+
+ - name: Delete route-map
+ arista.eos.eos_route_maps:
+ config:
+ - route_map: "mapmerge"
+ state: deleted
+ become: yes
+ tags:
+ - deleted1
+
+# After State:
+
+# veos#show running-config | section route-map
+# route-map mapmerge2 deny 45
+# match ipv6 resolved-next-hop prefix-list list1
+# sub-route-map mapmerge
+# set metric 25 +igp-metric
+# set as-path prepend last-as 2
+# veos#
+#
+# Module Execution:
+#
+# "after": [
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "list1"
+# }
+# },
+# "sequence": 45,
+# "set": {
+# "as_path": {
+# "prepend": {
+# "last_as": 2
+# }
+# },
+# "metric": {
+# "add": "igp-metric",
+# "value": "25"
+# }
+# },
+# "sub_route_map": {
+# "name": "mapmerge"
+# }
+# }
+# ],
+# "route_map": "mapmerge2"
+# }
+# ],
+# "before": [
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "description": "merged_map",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "listr"
+# },
+# "router_id": "22"
+# },
+# "sequence": 10
+# },
+# {
+# "action": "deny",
+# "continue": 45,
+# "description": "newmap",
+# "match": {
+# "interface": "Ethernet1"
+# },
+# "sequence": 25
+# },
+# {
+# "action": "deny",
+# "sequence": 90,
+# "set": {
+# "metric": {
+# "igp_param": "igp-nexthop-cost"
+# }
+# }
+# }
+# ],
+# "route_map": "mapmerge"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "list1"
+# }
+# },
+# "sequence": 45,
+# "set": {
+# "as_path": {
+# "prepend": {
+# "last_as": 2
+# }
+# },
+# "metric": {
+# "add": "igp-metric",
+# "value": "25"
+# }
+# },
+# "sub_route_map": {
+# "name": "mapmerge"
+# }
+# }
+# ],
+# "route_map": "mapmerge2"
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "no route-map mapmerge"
+# ],
+
+# Using deleted to delete all route-maps:
+
+# Before State:
+
+# veos#show running-config | section route-map
+# route-map mapmerge permit 10
+# description merged_map
+# match router-id prefix-list 22
+# !
+# route-map mapmerge deny 25
+# description newmap
+# match interface Ethernet1
+# continue 45
+# !
+# route-map mapmerge2 deny 45
+# match ipv6 resolved-next-hop prefix-list list1
+# sub-route-map mapmerge
+# set metric 25 +igp-metric
+# set as-path prepend last-as 2
+# veos#
+
+ - name: Delete all route-maps
+ arista.eos.eos_route_maps:
+ state: deleted
+
+# After State:
+# veos#show running-config | section route-map
+# veos#
+#
+# Module Execution:
+#
+# "after": {},
+# "before": [
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "description": "merged_map",
+# "match": {
+# "router_id": "22"
+# },
+# "sequence": 10
+# },
+# {
+# "action": "deny",
+# "continue": 45,
+# "description": "newmap",
+# "match": {
+# "interface": "Ethernet1"
+# },
+# "sequence": 25
+# }
+# ],
+# "route_map": "mapmerge"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "list1"
+# }
+# },
+# "sequence": 45,
+# "set": {
+# "as_path": {
+# "prepend": {
+# "last_as": 2
+# }
+# },
+# "metric": {
+# "add": "igp-metric",
+# "value": "25"
+# }
+# },
+# "sub_route_map": {
+# "name": "mapmerge"
+# }
+# }
+# ],
+# "route_map": "mapmerge2"
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "no route-map mapmerge",
+# "no route-map mapmerge2"
+# ],
+
+# Using gathered:
+
+# Device configs:
+
+# veos#show running-config | section route-map
+# route-map mapmerge permit 10
+# description merged_map
+# match router-id prefix-list 22
+# !
+# route-map mapmerge deny 25
+# description newmap
+# match interface Ethernet1
+# continue 45
+# !
+# route-map mapmerge2 deny 45
+# match ipv6 resolved-next-hop prefix-list list1
+# sub-route-map mapmerge
+# set metric 25 +igp-metric
+# set as-path prepend last-as 2
+# veos#
+
+ - name: gather configs
+ arista.eos.eos_route_maps:
+ state: gathered
+
+# Module Execution:
+# "gathered": [
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "description": "merged_map",
+# "match": {
+# "router_id": "22"
+# },
+# "sequence": 10
+# },
+# {
+# "action": "deny",
+# "continue_sequence": 45,
+# "description": "newmap",
+# "match": {
+# "interface": "Ethernet1"
+# },
+# "sequence": 25
+# }
+# ],
+# "route_map": "mapmerge"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "list1"
+# }
+# },
+# "sequence": 45,
+# "set": {
+# "as_path": {
+# "prepend": {
+# "last_as": 2
+# }
+# },
+# "metric": {
+# "add": "igp-metric",
+# "value": "25"
+# }
+# },
+# "sub_route_map": {
+# "name": "mapmerge"
+# }
+# }
+# ],
+# "route_map": "mapmerge2"
+# }
+# ],
+
+# Using rendered:
+
+ - name: Render provided configuration
+ arista.eos.eos_route_maps:
+ config:
+ - route_map: "mapmerge"
+ entries:
+ - description: "merged_map"
+ action: "permit"
+ sequence: 10
+ match:
+ router_id: 22
+ set:
+ bgp: 20
+ - description: "newmap"
+ action: "deny"
+ sequence: 25
+ continue_sequence: 45
+ match:
+ interface: "Ethernet1"
+ - route_map: "mapmerge2"
+ entries:
+ - sub_route_map:
+ name: "mapmerge"
+ action: "deny"
+ sequence: 45
+ set:
+ metric:
+ value: 25
+ add: "igp-metric"
+ as_path:
+ prepend:
+ last_as: 2
+ match:
+ ipv6:
+ resolved_next_hop: "list1"
+ state: rendered
+
+# Module Execution:
+# "rendered": [
+# "route-map mapmerge permit 10",
+# "match router-id prefix-list 22",
+# "set bgp bestpath as-path weight 20",
+# "description merged_map",
+# "route-map mapmerge deny 25",
+# "match interface Ethernet1",
+# "description newmap",
+# "continue 45",
+# "route-map mapmerge2 deny 45",
+# "match ipv6 resolved-next-hop prefix-list list1",
+# "set metric 25 +igp-metric",
+# "set as-path prepend last-as 2",
+# "sub-route-map mapmerge"
+# ]
+
+# Using parsed:
+
+# parsed.cfg
+# route-map mapmerge permit 10
+# description merged_map
+# match router-id prefix-list 22
+# set bgp bestpath as-path weight 20
+# !
+# route-map mapmerge deny 25
+# description newmap
+# match interface Ethernet1
+# continue 45
+# !
+# route-map mapmerge2 deny 45
+# match ipv6 resolved-next-hop prefix-list list1
+# sub-route-map mapmerge
+# set metric 25 +igp-metric
+# set as-path prepend last-as 2
+
+ - name: parse configs
+ arista.eos.eos_route_maps:
+ running_config: "{{ lookup('file', './parsed.cfg') }}"
+ state: parsed
+
+# Module Execution:
+# "parsed": [
+# {
+# "entries": [
+# {
+# "action": "permit",
+# "description": "merged_map",
+# "match": {
+# "router_id": "22"
+# },
+# "sequence": 10,
+# "set": {
+# "bgp": 20
+# }
+# },
+# {
+# "action": "deny",
+# "continue_sequence": 45,
+# "description": "newmap",
+# "match": {
+# "interface": "Ethernet1"
+# },
+# "sequence": 25
+# }
+# ],
+# "route_map": "mapmerge"
+# },
+# {
+# "entries": [
+# {
+# "action": "deny",
+# "match": {
+# "ipv6": {
+# "resolved_next_hop": "list1"
+# }
+# },
+# "sequence": 45,
+# "set": {
+# "as_path": {
+# "prepend": {
+# "last_as": 2
+# }
+# },
+# "metric": {
+# "add": "igp-metric",
+# "value": "25"
+# }
+# },
+# "sub_route_map": {
+# "name": "mapmerge"
+# }
+# }
+# ],
+# "route_map": "mapmerge2"
+# }
+# ]
+
+
+
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.route_maps.route_maps import (
+ Route_mapsArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.route_maps.route_maps import (
+ Route_maps,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Route_mapsArgs.argument_spec,
+ mutually_exclusive=[],
+ required_if=[],
+ supports_check_mode=False,
+ )
+
+ result = Route_maps(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_snmp_server.py b/ansible_collections/arista/eos/plugins/modules/eos_snmp_server.py
new file mode 100644
index 000000000..b702c8a46
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_snmp_server.py
@@ -0,0 +1,1522 @@
+#!/usr/bin/python
+# -*- 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)
+
+"""
+The module file for eos_snmp_server
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: eos_snmp_server
+short_description: Manages snmp_server resource module
+description: This module configures and manages the attributes of snmp_server on Arista
+ EOS platforms.
+version_added: 3.2.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli) and C(httpapi).
+options:
+ config:
+ description: SNMP server configuration.
+ type: dict
+ suboptions:
+ chassis_id:
+ description: SNMP chassis identifier.
+ type: str
+ communities:
+ description: Community name configuration.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description: Community name
+ type: str
+ acl_v4:
+ description: standard access_list name
+ type: str
+ acl_v6:
+ description: IPv6 access list name.
+ type: str
+ ro:
+ description: Only reads are permitted.
+ type: bool
+ rw:
+ description: Read_write access
+ type: bool
+ view:
+ description: MIB view name
+ type: str
+ contact:
+ description: Person to contact about the syste,.
+ type: str
+ traps:
+ description: Enable traps to all configured recipients.
+ type: dict
+ suboptions:
+ bgp:
+ description: Enable Bgp traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ arista_backward_transition:
+ description: arista_backward_transition
+ type: bool
+ arista_established:
+ description: arista_established
+ type: bool
+ backward_transition:
+ description: backward_transition
+ type: bool
+ established:
+ description: established.
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ bridge:
+ description: Enable Bridge traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ arista_mac_age:
+ description: arista_mac_age
+ type: bool
+ arista_mac_learn:
+ description: arista_mac_learn
+ type: bool
+ arista_mac_move:
+ description: arista_mac_move
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ capacity:
+ description: Enable Capacity traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ arista_hardware_utilization_alert:
+ description: arista_hardware_utilization_alert
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ entity:
+ description: Enable Entity traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ arista_ent_sensor_alarm:
+ description: arista_ent_sensor_alarm
+ type: bool
+ ent_config_change:
+ description: ent_config_change
+ type: bool
+ ent_state_oper:
+ description: ent_state_oper
+ type: bool
+ ent_state_oper_disabled:
+ description: ent_state_oper_disabled.
+ type: bool
+ ent_state_oper_enabled:
+ description: ent_state_oper_enabled.
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ external_alarm:
+ description: Enable external alarm traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ arista_external_alarm_asserted_notif:
+ description: arista_external_alarm_asserted_notif
+ type: bool
+ arista_external_alarm_deasserted_notif:
+ description: arista_external_alarm_deasserted_notif
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ isis:
+ description: Enable isis traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ adjacency_change:
+ description: adjacency_change
+ type: bool
+ area_mismatch:
+ description: area_mismatch
+ type: bool
+ attempt_to_exceed_max_sequence:
+ description: attempt_to_exceed_max_sequence
+ type: bool
+ authentication_type_failure:
+ description: authentication_type_failure.
+ type: bool
+ database_overload:
+ description: database_overload
+ type: bool
+ own_lsp_purge:
+ description: own_lsp_purge
+ type: bool
+ rejected_adjacency:
+ description: rejected_adjacency
+ type: bool
+ sequence_number_skip:
+ description: sequence_number_skip.
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ lldp:
+ description: Enable Lldp traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ rem_tables_change:
+ description: rem_tables_change
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ mpls_ldp:
+ description: Enable mpls_ldp traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ mpls_ldp_session_down:
+ description: mpls_ldp_session_down
+ type: bool
+ mpls_ldp_session_up:
+ description: mpls_ldp_session_up
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ msdp:
+ description: Enable msdp traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ backward_transition:
+ description: backward_transition.
+ type: bool
+ established:
+ description: established.
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ ospf:
+ description: Enable Ospf traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ if_config_error:
+ description: if_config_error
+ type: bool
+ if_auth_failure:
+ description: if_auth_failure
+ type: bool
+ if_state_change:
+ description: if_state_change
+ type: bool
+ nbr_state_change:
+ description: nbr_state_change.
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ ospfv3:
+ description: Enable Ospfv3 traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ if_config_error:
+ description: if_config_error
+ type: bool
+ if_rx_bad_packet:
+ description: if_rx_bad_packet
+ type: bool
+ if_state_change:
+ description: if_state_change
+ type: bool
+ nbr_state_change:
+ description: nbr_state_change.
+ type: bool
+ nbr_restart_helper_status_change:
+ description: Enable ospfv3NbrRestartHelperStatusChange trap
+ type: bool
+ nssa_translator_status_change:
+ description: Enable ospfv3NssaTranslatorStatusChange trap
+ type: bool
+ restart_status_change:
+ description: restart_status_change
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ pim:
+ description: Enable Pim traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ neighbor_loss:
+ description: neighbor_loss
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ snmp:
+ description: Enable snmp traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ authentication:
+ description: authentication
+ type: bool
+ link_down:
+ description: link_down
+ type: bool
+ link_up:
+ description: link_up
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ snmpConfigManEvent:
+ description: Enable snmpConfigManEvent traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ arista_config_man_event:
+ description: arista_config_man_event
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ switchover:
+ description: Enable switchover traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ arista_redundancy_switch_over_notif:
+ description: arista_redundancy_switch_over_notif
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ test:
+ description: Enable test traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ arista_test_notification:
+ description: arista_test_notification
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ vrrp:
+ description: Enable vrrp traps. If set to enabled , all the traps are set.
+ type: dict
+ suboptions:
+ trap_new_master:
+ description: vrrp
+ type: bool
+ enabled:
+ description: All traps are set.
+ type: bool
+ engineid:
+ description: SNMPv3 engine ID configuration.
+ type: dict
+ suboptions:
+ local:
+ description: Local SNMP agent
+ type: str
+ remote:
+ description: Remote SNMP agent
+ type: dict
+ suboptions:
+ host:
+ description: Hostname or IP address of remote SNMP notification host
+ type: str
+ udp_port:
+ description: The remote SNMP notification host's UDP port number.
+ type: int
+ id:
+ description: engine ID octet string
+ type: str
+ extension:
+ description: Configure extension script to serve an OID range
+ type: dict
+ suboptions:
+ root_oid:
+ description: Extension root oid
+ type: str
+ script_location:
+ description: script location
+ type: str
+ oneshot:
+ description: Use inefficient one_shot interface
+ type: bool
+ groups:
+ description: SNMP USM group
+ type: list
+ elements: dict
+ suboptions:
+ group:
+ description: SNMP group for the user
+ type: str
+ version:
+ description: snmp security group version
+ type: str
+ choices: ['v1', 'v3', 'v2c']
+ auth_privacy:
+ description: auth and privacy config. Valid when version = v3.
+ type: str
+ choices: ['auth', 'noauth', 'priv']
+ context:
+ description: Specify a context to associate with the group
+ type: str
+ notify:
+ description: View to restrict notifications
+ type: str
+ read:
+ description: View to restrict read access
+ type: str
+ write:
+ description: View to restrict write access
+ type: str
+ hosts:
+ description: Notification destinations
+ type: list
+ elements: dict
+ suboptions:
+ host:
+ description: Hostname or IP address of SNMP notification host.
+ type: str
+ user:
+ description: Community or user name.
+ type: str
+ udp_port:
+ description: UDP destination port for notification messages.
+ type: int
+ informs:
+ description: Use SNMP inform messages.
+ type: bool
+ traps:
+ description: Use SNMP trap messages
+ type: bool
+ version:
+ description: Notification message SNMP version.
+ type: str
+ choices: ['1', '2c', '3 auth', '3 noauth', '3 priv']
+ vrf:
+ description: Specify the VRF in which the host is configured
+ type: str
+ acls:
+ description: ipv4/ipv6 access_lists
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description: ipv4/ipv6
+ type: str
+ choices: ['ipv4', 'ipv6']
+ acl:
+ description: acl name
+ type: str
+ vrf:
+ description: vrf name
+ type: str
+ local_interface:
+ description: Configure the source interface for SNMP notifications.
+ type: str
+ location:
+ description: The sysLocation string.
+ type: str
+ notification:
+ description: Maximum number of notifications in the log
+ type: int
+ objects:
+ description: when True Disable implementation of a group of objects
+ type: dict
+ suboptions:
+ mac_address_tables:
+ description: dot1dTpFdbTable, dot1qTpFdbTable
+ type: bool
+ route_tables:
+ description: ipCidrRouteTable, ipCidrRouteNumber, aristaFIBStats*
+ type: bool
+ qos:
+ description: Configure QoS parameters.
+ type: int
+ qosmib:
+ description: Set QOS_MIB counter update interval
+ type: int
+ transmit:
+ description: Maximum number of bytes in SNMP message (UDP/TCP payload)
+ type: int
+ transport:
+ description: Enable snmpd transport layer protocol
+ type: str
+ users:
+ description: SNMP user configuration.
+ type: list
+ elements: dict
+ suboptions:
+ user:
+ description: SNMP user name
+ type: str
+ group:
+ description: SNMP group for the user.
+ type: str
+ remote:
+ description: System where an SNMPv3 user is hosted
+ type: str
+ udp_port:
+ description: UDP port used by the remote SNMP system
+ type: int
+ version:
+ description: snmp security version
+ type: str
+ choices: ['v1', 'v2c', 'v3']
+ auth:
+ description: User authentication settings
+ type: dict
+ suboptions:
+ algorithm:
+ description: algorithm for authentication
+ type: str
+ auth_passphrase:
+ description: authentication passphrase hex string
+ type: str
+ encryption:
+ description: algorithm for encryption.
+ type: str
+ priv_passphrase:
+ description: privacy passphrase hexstring
+ type: str
+ localized:
+ description: localized auth and privacy passphrases.
+ type: dict
+ suboptions:
+ engineid:
+ description: Engine id
+ type: str
+ algorithm:
+ description: algorithm for authentication
+ type: str
+ auth_passphrase:
+ description: authentication passphrase hex string
+ type: str
+ encryption:
+ description: algorithm for encryption.
+ type: str
+ priv_passphrase:
+ description: privacy passphrase hexstring
+ type: str
+ views:
+ description: SNMPv2 MIB view configuration
+ type: list
+ elements: dict
+ suboptions:
+ view:
+ description: SNMP view name
+ type: str
+ mib:
+ description: SNMP MIB name
+ type: str
+ action:
+ description: Action to be performed.
+ type: str
+ choices: ['excluded', 'included']
+ vrfs:
+ description: Specify the VRF in which the source address is used
+ type: list
+ elements: dict
+ suboptions:
+ vrf:
+ description: vrf name.
+ type: str
+ local_interface:
+ description: Configure the source interface for SNMP notifications
+ type: str
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running_config | section snmp_server).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ - The states I(replaced) and I(overridden) have identical
+ behaviour for this module.
+ - Please refer to examples for more details.
+ type: str
+ choices: [deleted, merged, overridden, replaced, gathered, rendered, parsed]
+ default: merged
+"""
+EXAMPLES = """
+# Using merged:
+# Before State
+# eos#show running-config | section snmp-server
+# eos#
+
+ - name: merge given snmp_server configuration
+ arista.eos.eos_snmp_server:
+ config:
+ communities:
+ - name: "comm3"
+ acl_v6: "list1"
+ view: "view1"
+ - name: "comm4"
+ acl_v4: "list3"
+ view: "view1"
+ - name: "comm5"
+ acl_v4: "list4"
+ ro: True
+ contact: "admin"
+ engineid:
+ remote:
+ host: 1.1.1.1
+ id: "1234567"
+ groups:
+ - group: "group1"
+ version: "v1"
+ read: "view1"
+ - group: "group2"
+ version: "v3"
+ auth_privacy: "priv"
+ notify: "view1"
+ write: "view2"
+ hosts:
+ - host: "host02"
+ user: "user01"
+ udp_port: 23
+ version: "2c"
+ - host: "host01"
+ user: "user01"
+ udp_port: 23
+ version: "3 priv"
+ traps:
+ capacity:
+ arista_hardware_utilization_alert: True
+ bgp:
+ enabled: True
+ external_alarm:
+ arista_external_alarm_deasserted_notif: True
+ arista_external_alarm_asserted_notif: True
+ vrfs:
+ - vrf: "vrf01"
+ local_interface: "Ethernet1"
+
+# After state
+# eos#show running-config | section snmp-server
+# snmp-server community comm3 view view1 ipv6 list1
+# snmp-server community comm4 view view1 list3
+# snmp-server community comm5 ro list4
+# snmp-server group group1 v1 read view1
+# snmp-server group group2 v3 priv write view2 notify view1
+# snmp-server host host02 version 2c user01 udp-port 23
+# snmp-server host host01 version 3 priv user01 udp-port 23
+# snmp-server vrf vrf01 local-interface Ethernet1
+# snmp-server contact admin
+# snmp-server enable traps bgp
+# snmp-server enable traps capacity arista-hardware-utilization-alert
+# snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif
+#
+# Module Execution
+#
+# "after": {
+# "communities": [
+# {
+# "acl_v6": "list1",
+# "name": "comm3",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list3",
+# "name": "comm4",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list4",
+# "name": "comm5",
+# "ro": true
+# }
+# ],
+# "contact": "admin",
+# "groups": [
+# {
+# "group": "group1",
+# "read": "view1",
+# "version": "v1"
+# },
+# {
+# "auth_privacy": "priv",
+# "group": "group2",
+# "notify": "view1",
+# "version": "v3",
+# "write": "view2"
+# }
+# ],
+# "hosts": [
+# {
+# "host": "host01",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "3 priv"
+# },
+# {
+# "host": "host02",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "2c"
+# }
+# ],
+# "traps": {
+# "bgp": {
+# "enabled": true
+# },
+# "capacity": {
+# "arista_hardware_utilization_alert": true
+# },
+# "external_alarm": {
+# "arista_external_alarm_asserted_notif": true,
+# "arista_external_alarm_deasserted_notif": true
+# }
+# },
+# "vrfs": [
+# {
+# "local_interface": "Ethernet1",
+# "vrf": "vrf01"
+# }
+# ]
+# },
+# "before": {},
+# "changed": true,
+# "commands": [
+# "snmp-server community comm3 view view1 ipv6 list1",
+# "snmp-server community comm4 view view1 list3",
+# "snmp-server community comm5 ro list4",
+# "snmp-server group group1 v1 read view1",
+# "snmp-server group group2 v3 priv write view2 notify view1",
+# "snmp-server host host02 version 2c user01 udp-port 23",
+# "snmp-server host host01 version 3 priv user01 udp-port 23",
+# "snmp-server vrf vrf01 local-interface Ethernet1",
+# "snmp-server contact admin",
+# "snmp-server engineID remote 1.1.1.1 1234567",
+# "snmp-server enable traps bgp",
+# "snmp-server enable traps capacity arista-hardware-utilization-alert",
+# "snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif"
+# ],
+#
+
+# Using replaced:
+# Before State:
+# eos#show running-config | section snmp-server
+# snmp-server community comm3 view view1 ipv6 list1
+# snmp-server community comm4 view view1 list3
+# snmp-server community comm5 ro list4
+# snmp-server group group1 v1 read view1
+# snmp-server group group2 v3 priv write view2 notify view1
+# snmp-server host host02 version 2c user01 udp-port 23
+# snmp-server host host01 version 3 priv user01 udp-port 23
+# snmp-server vrf vrf01 local-interface Ethernet1
+# snmp-server contact admin
+# snmp-server enable traps bgp
+# snmp-server enable traps capacity arista-hardware-utilization-alert
+# snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif
+
+ - name: Replace given snmp_server configuration
+ become: true
+ register: result
+ arista.eos.eos_snmp_server: &replaced
+ state: replaced
+ config:
+ communities:
+ - name: "comm3"
+ acl_v6: "list1"
+ view: "view1"
+ - name: "replacecomm"
+ acl_v4: "list4"
+ extension:
+ root_oid: "123456"
+ script_location: "flash:"
+ traps:
+ test:
+ arista_test_notification: True
+ bgp:
+ enabled: True
+ vrfs:
+ - vrf: "vrf_replace"
+ local_interface: "Ethernet1"
+
+# After State:
+
+# eos#show running-config | section snmp-server
+# snmp-server community comm3 view view1 ipv6 list1
+# snmp-server community replacecomm list4
+# snmp-server vrf vrf_replace local-interface Ethernet1
+# snmp-server extension 123456 flash:
+# snmp-server enable traps test arista-test-notification
+# snmp-server enable traps bgp
+
+# Module Execution:
+# "after": {
+# "communities": [
+# {
+# "acl_v6": "list1",
+# "name": "comm3",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list4",
+# "name": "replacecomm",
+# "ro": true
+# }
+# ],
+# "extension": {
+# "root_oid": "0.123456",
+# "script_location": "flash:"
+# },
+# "traps": {
+# "bgp": {
+# "enabled": true
+# },
+# "test": {
+# "arista_test_notification": true
+# }
+# },
+# "vrfs": [
+# {
+# "local_interface": "Ethernet1",
+# "vrf": "vrf_replace"
+# }
+# ]
+# },
+# "before": {
+# "communities": [
+# {
+# "acl_v6": "list1",
+# "name": "comm3",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list3",
+# "name": "comm4",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list4",
+# "name": "comm5",
+# "ro": true
+# }
+# ],
+# "contact": "admin",
+# "groups": [
+# {
+# "group": "group1",
+# "read": "view1",
+# "version": "v1"
+# },
+# {
+# "auth_privacy": "priv",
+# "group": "group2",
+# "notify": "view1",
+# "version": "v3",
+# "write": "view2"
+# }
+# ],
+# "hosts": [
+# {
+# "host": "host01",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "3 priv"
+# },
+# {
+# "host": "host02",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "2c"
+# }
+# ],
+# "traps": {
+# "bgp": {
+# "enabled": true
+# },
+# "capacity": {
+# "arista_hardware_utilization_alert": true
+# },
+# "external_alarm": {
+# "arista_external_alarm_asserted_notif": true,
+# "arista_external_alarm_deasserted_notif": true
+# }
+# },
+# "vrfs": [
+# {
+# "local_interface": "Ethernet1",
+# "vrf": "vrf01"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "snmp-server community comm3 view view1 ipv6 list1",
+# "snmp-server community replacecomm list4",
+# "no snmp-server community comm4 view view1 ro list3",
+# "no snmp-server community comm5 ro list4",
+# "no snmp-server group group1 v1 read view1",
+# "no snmp-server group group2 v3 priv write view2 notify view1",
+# "no snmp-server host host01 version 3 priv user01 udp-port 23",
+# "no snmp-server host host02 version 2c user01 udp-port 23",
+# "snmp-server vrf vrf_replace local-interface Ethernet1",
+# "no snmp-server vrf vrf01 local-interface Ethernet1",
+# "snmp-server extension 123456 flash:",
+# "default snmp-server enable traps capacity arista-hardware-utilization-alert",
+# "default snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif",
+# "snmp-server enable traps test arista-test-notification",
+# "no snmp-server contact admin"
+# ],
+
+# Using overridden:
+# Before State:
+# eos#show running-config | section snmp-server
+# snmp-server community comm3 view view1 ipv6 list1
+# snmp-server community comm4 view view1 list3
+# snmp-server community comm5 ro list4
+# snmp-server group group1 v1 read view1
+# snmp-server group group2 v3 priv write view2 notify view1
+# snmp-server host host02 version 2c user01 udp-port 23
+# snmp-server host host01 version 3 priv user01 udp-port 23
+# snmp-server vrf vrf01 local-interface Ethernet1
+# snmp-server contact admin
+# snmp-server enable traps bgp
+# snmp-server enable traps capacity arista-hardware-utilization-alert
+# snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif
+
+ - name: Override given snmp_server configuration
+ arista.eos.eos_snmp_server:
+ state: overridden
+ config:
+ communities:
+ - name: "comm3"
+ acl_v6: "list1"
+ view: "view1"
+ - name: "replacecomm"
+ acl_v4: "list4"
+ extension:
+ root_oid: "123456"
+ script_location: "flash:"
+ traps:
+ test:
+ arista_test_notification: True
+ bgp:
+ enabled: True
+ vrfs:
+ - vrf: "vrf_replace"
+ local_interface: "Ethernet1"
+
+# After State:
+
+# eos#show running-config | section snmp-server
+# snmp-server community comm3 view view1 ipv6 list1
+# snmp-server community replacecomm list4
+# snmp-server vrf vrf_replace local-interface Ethernet1
+# snmp-server extension 123456 flash:
+# snmp-server enable traps test arista-test-notification
+# snmp-server enable traps bgp
+
+# Module Execution:
+# "after": {
+# "communities": [
+# {
+# "acl_v6": "list1",
+# "name": "comm3",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list4",
+# "name": "replacecomm",
+# "ro": true
+# }
+# ],
+# "extension": {
+# "root_oid": "0.123456",
+# "script_location": "flash:"
+# },
+# "traps": {
+# "bgp": {
+# "enabled": true
+# },
+# "test": {
+# "arista_test_notification": true
+# }
+# },
+# "vrfs": [
+# {
+# "local_interface": "Ethernet1",
+# "vrf": "vrf_replace"
+# }
+# ]
+# },
+# "before": {
+# "communities": [
+# {
+# "acl_v6": "list1",
+# "name": "comm3",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list3",
+# "name": "comm4",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list4",
+# "name": "comm5",
+# "ro": true
+# }
+# ],
+# "contact": "admin",
+# "groups": [
+# {
+# "group": "group1",
+# "read": "view1",
+# "version": "v1"
+# },
+# {
+# "auth_privacy": "priv",
+# "group": "group2",
+# "notify": "view1",
+# "version": "v3",
+# "write": "view2"
+# }
+# ],
+# "hosts": [
+# {
+# "host": "host01",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "3 priv"
+# },
+# {
+# "host": "host02",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "2c"
+# }
+# ],
+# "traps": {
+# "bgp": {
+# "enabled": true
+# },
+# "capacity": {
+# "arista_hardware_utilization_alert": true
+# },
+# "external_alarm": {
+# "arista_external_alarm_asserted_notif": true,
+# "arista_external_alarm_deasserted_notif": true
+# }
+# },
+# "vrfs": [
+# {
+# "local_interface": "Ethernet1",
+# "vrf": "vrf01"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "snmp-server community comm3 view view1 ipv6 list1",
+# "snmp-server community replacecomm list4",
+# "no snmp-server community comm4 view view1 ro list3",
+# "no snmp-server community comm5 ro list4",
+# "no snmp-server group group1 v1 read view1",
+# "no snmp-server group group2 v3 priv write view2 notify view1",
+# "no snmp-server host host01 version 3 priv user01 udp-port 23",
+# "no snmp-server host host02 version 2c user01 udp-port 23",
+# "snmp-server vrf vrf_replace local-interface Ethernet1",
+# "no snmp-server vrf vrf01 local-interface Ethernet1",
+# "snmp-server extension 123456 flash:",
+# "default snmp-server enable traps capacity arista-hardware-utilization-alert",
+# "default snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif",
+# "snmp-server enable traps test arista-test-notification",
+# "no snmp-server contact admin"
+# ],
+
+# Using deleted:
+# Before State:
+# eos#show running-config | section snmp-server
+# snmp-server community comm3 view view1 ipv6 list1
+# snmp-server community comm4 view view1 list3
+# snmp-server community comm5 ro list4
+# snmp-server group group1 v1 read view1
+# snmp-server group group2 v3 priv write view2 notify view1
+# snmp-server host host02 version 2c user01 udp-port 23
+# snmp-server host host01 version 3 priv user01 udp-port 23
+# snmp-server vrf vrf01 local-interface Ethernet1
+# snmp-server contact admin
+# snmp-server enable traps bgp
+# snmp-server enable traps capacity arista-hardware-utilization-alert
+# snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif
+
+ - name: Delete given snmp_server configuration
+ arista.eos.eos_snmp_server:
+ state: deleted
+
+# After State:
+# eos#show running-config | section snmp-server
+#
+
+# Module Execution:
+# "after": {},
+# "before": {
+# "communities": [
+# {
+# "acl_v6": "list1",
+# "name": "comm3",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list3",
+# "name": "comm4",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list4",
+# "name": "comm5",
+# "ro": true
+# }
+# ],
+# "contact": "admin",
+# "groups": [
+# {
+# "group": "group1",
+# "read": "view1",
+# "version": "v1"
+# },
+# {
+# "auth_privacy": "priv",
+# "group": "group2",
+# "notify": "view1",
+# "version": "v3",
+# "write": "view2"
+# }
+# ],
+# "hosts": [
+# {
+# "host": "host01",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "3 priv"
+# },
+# {
+# "host": "host02",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "2c"
+# }
+# ],
+# "traps": {
+# "bgp": {
+# "enabled": true
+# },
+# "capacity": {
+# "arista_hardware_utilization_alert": true
+# },
+# "external_alarm": {
+# "arista_external_alarm_asserted_notif": true,
+# "arista_external_alarm_deasserted_notif": true
+# }
+# },
+# "vrfs": [
+# {
+# "local_interface": "Ethernet1",
+# "vrf": "vrf01"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "no snmp-server community comm3 view view1 ro ipv6 list1",
+# "no snmp-server community comm4 view view1 ro list3",
+# "no snmp-server community comm5 ro list4",
+# "no snmp-server group group1 v1 read view1",
+# "no snmp-server group group2 v3 priv write view2 notify view1",
+# "no snmp-server host host01 version 3 priv user01 udp-port 23",
+# "no snmp-server host host02 version 2c user01 udp-port 23",
+# "no snmp-server vrf vrf01 local-interface Ethernet1",
+# "no snmp-server contact admin",
+# "default snmp-server enable traps bgp",
+# "default snmp-server enable traps capacity arista-hardware-utilization-alert",
+# "default snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif"
+# ],
+#
+
+# Using parsed:
+
+# _parsed.cfg
+# snmp-server contact admin
+# snmp-server vrf vrf01 local-interface Ethernet1
+# snmp-server community comm3 view view1 ro ipv6 list1
+# snmp-server community comm4 view view1 ro list3
+# snmp-server community comm5 ro list4
+# snmp-server group group1 v1 read view1
+# snmp-server group group2 v3 priv write view2 notify view1
+# snmp-server host host01 version 3 priv user01 udp-port 23
+# snmp-server host host02 version 2c user01 udp-port 23
+# snmp-server enable traps bgp
+# snmp-server enable traps capacity arista-hardware-utilization-alert
+# snmp-server enable traps external-alarm arista-external-alarm-asserted-notif
+# snmp-server enable traps external-alarm arista-external-alarm-deasserted-notif
+
+ - name: Provide the running configuration for parsing (config to be parsed)
+ arista.eos.eos_snmp_server:
+ running_config: "{{ lookup('file', '_parsed.cfg') }}"
+ state: parsed
+
+# Module Execution:
+# "parsed": {
+# "communities": [
+# {
+# "acl_v6": "list1",
+# "name": "comm3",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list3",
+# "name": "comm4",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list4",
+# "name": "comm5",
+# "ro": true
+# }
+# ],
+# "contact": "admin",
+# "groups": [
+# {
+# "group": "group1",
+# "read": "view1",
+# "version": "v1"
+# },
+# {
+# "auth_privacy": "priv",
+# "group": "group2",
+# "notify": "view1",
+# "version": "v3",
+# "write": "view2"
+# }
+# ],
+# "hosts": [
+# {
+# "host": "host01",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "3 priv"
+# },
+# {
+# "host": "host02",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "2c"
+# }
+# ],
+# "traps": {
+# "bgp": {
+# "enabled": true
+# },
+# "capacity": {
+# "arista_hardware_utilization_alert": true
+# },
+# "external_alarm": {
+# "arista_external_alarm_asserted_notif": true,
+# "arista_external_alarm_deasserted_notif": true
+# }
+# },
+# "vrfs": [
+# {
+# "local_interface": "Ethernet1",
+# "vrf": "vrf01"
+# }
+# ]
+# }
+
+# Using rendered:
+ - name: Render given snmp_server configuration
+ arista.eos.eos_snmp_server:
+ state: "rendered"
+ config:
+ communities:
+ - name: "comm3"
+ acl_v6: "list1"
+ view: "view1"
+ - name: "comm4"
+ acl_v4: "list3"
+ view: "view1"
+ - name: "comm5"
+ acl_v4: "list4"
+ ro: True
+ contact: "admin"
+ engineid:
+ remote:
+ host: 1.1.1.1
+ id: "1234567"
+ groups:
+ - group: "group1"
+ version: "v1"
+ read: "view1"
+ - group: "group2"
+ version: "v3"
+ auth_privacy: "priv"
+ notify: "view1"
+ write: "view2"
+ hosts:
+ - host: "host02"
+ user: "user01"
+ udp_port: 23
+ version: "2c"
+ - host: "host01"
+ user: "user01"
+ udp_port: 23
+ version: "3 priv"
+ traps:
+ capacity:
+ arista_hardware_utilization_alert: True
+ bgp:
+ enabled: True
+ external_alarm:
+ arista_external_alarm_deasserted_notif: True
+ arista_external_alarm_asserted_notif: True
+ vrfs:
+ - vrf: "vrf01"
+ local_interface: "Ethernet1"
+
+# Module Execution:
+# "rendered": [
+# "snmp-server community comm3 view view1 ipv6 list1",
+# "snmp-server community comm4 view view1 list3",
+# "snmp-server community comm5 ro list4",
+# "snmp-server group group1 v1 read view1",
+# "snmp-server group group2 v3 priv write view2 notify view1",
+# "snmp-server host host02 version 2c user01 udp-port 23",
+# "snmp-server host host01 version 3 priv user01 udp-port 23",
+# "snmp-server vrf vrf01 local-interface Ethernet1",
+# "snmp-server contact admin",
+# "snmp-server engineID remote 1.1.1.1 1234567",
+# "snmp-server enable traps bgp",
+# "snmp-server enable traps capacity arista-hardware-utilization-alert",
+# "snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif"
+# ]
+
+# using gathered:
+
+# eos#show running-config | section snmp-server
+# snmp-server community comm3 view view1 ipv6 list1
+# snmp-server community comm4 view view1 list3
+# snmp-server community comm5 ro list4
+# snmp-server group group1 v1 read view1
+# snmp-server group group2 v3 priv write view2 notify view1
+# snmp-server host host02 version 2c user01 udp-port 23
+# snmp-server host host01 version 3 priv user01 udp-port 23
+# snmp-server vrf vrf01 local-interface Ethernet1
+# snmp-server contact admin
+# snmp-server enable traps bgp
+# snmp-server enable traps capacity arista-hardware-utilization-alert
+# snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif
+
+ - name: Gathered the provided configuration with the exisiting running configuration
+ arista.eos.eos_snmp_server:
+ config:
+ state: gathered
+
+# Module Execution:
+# "gathered": {
+# "communities": [
+# {
+# "acl_v6": "list1",
+# "name": "comm3",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list3",
+# "name": "comm4",
+# "ro": true,
+# "view": "view1"
+# },
+# {
+# "acl_v4": "list4",
+# "name": "comm5",
+# "ro": true
+# }
+# ],
+# "contact": "admin",
+# "groups": [
+# {
+# "group": "group1",
+# "read": "view1",
+# "version": "v1"
+# },
+# {
+# "auth_privacy": "priv",
+# "group": "group2",
+# "notify": "view1",
+# "version": "v3",
+# "write": "view2"
+# }
+# ],
+# "hosts": [
+# {
+# "host": "host01",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "3 priv"
+# },
+# {
+# "host": "host02",
+# "udp_port": 23,
+# "user": "user01",
+# "version": "2c"
+# }
+# ],
+# "traps": {
+# "bgp": {
+# "enabled": true
+# },
+# "capacity": {
+# "arista_hardware_utilization_alert": true
+# },
+# "external_alarm": {
+# "arista_external_alarm_asserted_notif": true,
+# "arista_external_alarm_deasserted_notif": true
+# }
+# },
+# "vrfs": [
+# {
+# "local_interface": "Ethernet1",
+# "vrf": "vrf01"
+# }
+# ]
+# },
+
+"""
+
+RETURN = """
+before:
+ description: The configuration prior to the module execution.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+after:
+ description: The resulting configuration after module execution.
+ returned: when changed
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: list
+ sample:
+ - "snmp-server community comm3 view view1 ipv6 list1"
+ - "snmp-server community comm4 view view1 list3"
+ - "snmp-server community comm5 ro list4"
+ - "snmp-server group group1 v1 read view1"
+ - "snmp-server group group2 v3 priv write view2 notify view1"
+ - "snmp-server host host02 version 2c user01 udp-port 23"
+ - "snmp-server host host01 version 3 priv user01 udp-port 23"
+ - "snmp-server vrf vrf01 local-interface Ethernet1"
+ - "snmp-server contact admin"
+ - "snmp-server engineID remote 1.1.1.1 1234567"
+ - "snmp-server enable traps bgp"
+ - "snmp-server enable traps capacity arista-hardware-utilization-alert"
+ - "snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif"
+
+rendered:
+ description: The provided configuration in the task rendered in device-native format (offline).
+ returned: when I(state) is C(rendered)
+ type: list
+ sample:
+ - "snmp-server community comm3 view view1 ipv6 list1"
+ - "snmp-server community comm4 view view1 list3"
+ - "snmp-server community comm5 ro list4"
+ - "snmp-server group group1 v1 read view1"
+ - "snmp-server group group2 v3 priv write view2 notify view1"
+ - "snmp-server host host02 version 2c user01 udp-port 23"
+ - "snmp-server host host01 version 3 priv user01 udp-port 23"
+ - "snmp-server vrf vrf01 local-interface Ethernet1"
+ - "snmp-server contact admin"
+ - "snmp-server engineID remote 1.1.1.1 1234567"
+ - "snmp-server enable traps bgp"
+ - "snmp-server enable traps capacity arista-hardware-utilization-alert"
+ - "snmp-server enable traps external-alarm arista-external-alarm-asserted-notif arista-external-alarm-deasserted-notif"
+gathered:
+ description: Facts about the network resource gathered from the remote device as structured data.
+ returned: when I(state) is C(gathered)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+parsed:
+ description: The device native config provided in I(running_config) option parsed into structured data as per module argspec.
+ returned: when I(state) is C(parsed)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.snmp_server.snmp_server import (
+ Snmp_serverArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.snmp_server.snmp_server import (
+ Snmp_server,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Snmp_serverArgs.argument_spec,
+ mutually_exclusive=[["config", "running_config"]],
+ required_if=[
+ ["state", "merged", ["config"]],
+ ["state", "replaced", ["config"]],
+ ["state", "overridden", ["config"]],
+ ["state", "rendered", ["config"]],
+ ["state", "parsed", ["running_config"]],
+ ],
+ supports_check_mode=True,
+ )
+
+ result = Snmp_server(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_static_routes.py b/ansible_collections/arista/eos/plugins/modules/eos_static_routes.py
new file mode 100644
index 000000000..5b291b12d
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_static_routes.py
@@ -0,0 +1,969 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_static_routes
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_static_routes
+short_description: Static routes resource module
+description: This module configures and manages the attributes of static routes on
+ Arista EOS platforms.
+version_added: 1.0.0
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description:
+ - A list of configurations for static routes.
+ type: list
+ elements: dict
+ suboptions:
+ vrf:
+ description:
+ - The VRF to which the static route(s) belong.
+ type: str
+ address_families:
+ description: A dictionary specifying the address family to which the static
+ route(s) belong.
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description:
+ - Specifies the top level address family indicator.
+ type: str
+ choices:
+ - ipv4
+ - ipv6
+ required: true
+ routes:
+ description: A dictionary that specifies the static route configurations.
+ elements: dict
+ type: list
+ suboptions:
+ dest:
+ description:
+ - Destination IPv4 subnet (CIDR or address-mask notation).
+ - The address format is <v4/v6 address>/<mask> or <v4/v6 address>
+ <mask>.
+ - The mask is number in range 0-32 for IPv4 and in range 0-128 for
+ IPv6.
+ type: str
+ required: true
+ next_hops:
+ description:
+ - Details of route to be taken.
+ type: list
+ elements: dict
+ suboptions:
+ forward_router_address:
+ description:
+ - Forwarding router's address on destination interface.
+ type: str
+ interface:
+ description:
+ - Outgoing interface to take. For anything except 'null0', then
+ next hop IP address should also be configured.
+ - IP address of the next hop router or
+ - null0 Null0 interface or
+ - ethernet e_num Ethernet interface or
+ - loopback l_num Loopback interface or
+ - management m_num Management interface or
+ - port-channel p_num
+ - vlan v_num
+ - vxlan vx_num
+ - Nexthop-Group Specify nexthop group name
+ - Tunnel Tunnel interface
+ - vtep Configure VXLAN Tunnel End Points
+ type: str
+ nexthop_grp:
+ description:
+ - Nexthop group
+ type: str
+ admin_distance:
+ description:
+ - Preference or administrative distance of route (range 1-255).
+ type: int
+ description:
+ description:
+ - Name of the static route.
+ type: str
+ tag:
+ description:
+ - Route tag value (ranges from 0 to 4294967295).
+ type: int
+ track:
+ description:
+ - Track value (range 1 - 512). Track must already be configured
+ on the device before adding the route.
+ type: str
+ mpls_label:
+ description:
+ - MPLS label
+ type: int
+ vrf:
+ description:
+ - VRF of the destination.
+ type: str
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | grep routes).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices:
+ - deleted
+ - merged
+ - overridden
+ - replaced
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+
+"""
+EXAMPLES = """
+# Using deleted
+
+# Before State:
+# ------------
+
+# veos(config)#show running-config | grep route
+# ip route vrf testvrf 22.65.1.0/24 Null0 90 name testroute
+# ipv6 route 5222:5::/64 Management1 4312:100::1
+# ipv6 route vrf testvrf 2222:6::/64 Management1 4312:100::1
+# ipv6 route vrf testvrf 2222:6::/64 Ethernet1 55
+# ipv6 route vrf testvrf 2222:6::/64 Null0 90 name testroute1
+# veos(config)#
+
+- name: Delete afi
+ arista.eos.eos_static_routes:
+ config:
+ - vrf: testvrf
+ address_families:
+ - afi: ipv4
+ state: deleted
+
+# "after": [
+# {
+# "address_families": [
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "5222:5::/64",
+# "next_hops": [
+# {
+# "forward_router_address": "4312:100::1",
+# "interface": "Management1"
+# }
+# ]
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "address_families": [
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "2222:6::/64",
+# "next_hops": [
+# {
+# "forward_router_address": "4312:100::1",
+# "interface": "Management1"
+# },
+# {
+# "admin_distance": 55,
+# "interface": "Ethernet1"
+# },
+# {
+# "admin_distance": 90,
+# "description": "testroute1",
+# "interface": "Null0"
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "vrf": "testvrf"
+# }
+# ],
+# "before": [
+# {
+# "address_families": [
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "5222:5::/64",
+# "next_hops": [
+# {
+# "forward_router_address": "4312:100::1",
+# "interface": "Management1"
+# }
+# ]
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "22.65.1.0/24",
+# "next_hops": [
+# {
+# "admin_distance": 90,
+# "description": "testroute",
+# "interface": "Null0"
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "2222:6::/64",
+# "next_hops": [
+# {
+# "forward_router_address": "4312:100::1",
+# "interface": "Management1"
+# },
+# {
+# "admin_distance": 55,
+# "interface": "Ethernet1"
+# },
+# {
+# "admin_distance": 90,
+# "description": "testroute1",
+# "interface": "Null0"
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "vrf": "testvrf"
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "no ip route vrf testvrf 22.65.1.0/24 Null0 90 name testroute"
+# ],
+
+# After State
+# ___________
+
+# veos(config)#show running-config | grep route
+# ipv6 route 5222:5::/64 Management1 4312:100::1
+# ipv6 route vrf testvrf 2222:6::/64 Management1 4312:100::1
+# ipv6 route vrf testvrf 2222:6::/64 Ethernet1 55
+# ipv6 route vrf testvrf 2222:6::/64 Null0 90 name testroute1
+
+#
+# Using merged
+
+# Before : [
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "165.10.1.0/24",
+# "next_hops": [
+# {
+# "admin_distance": 100,
+# "interface": "Ethernet1"
+# }
+# ]
+# },
+# {
+# "dest": "172.17.252.0/24",
+# "next_hops": [
+# {
+# "nexthop_grp": "testgroup"
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "5001::/64",
+# "next_hops": [
+# {
+# "admin_distance": 50,
+# "interface": "Ethernet1"
+# }
+# ]
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "130.1.122.0/24",
+# "next_hops": [
+# {
+# "interface": "Ethernet1",
+# "tag": 50
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "vrf": "testvrf"
+# }
+# ]
+#
+# Before State
+# -------------
+# veos(config)#show running-config | grep "route"
+# ip route 165.10.1.0/24 Ethernet1 100
+# ip route 172.17.252.0/24 Nexthop-Group testgroup
+# ip route vrf testvrf 130.1.122.0/24 Ethernet1 tag 50
+# ipv6 route 5001::/64 Ethernet1 50
+# veos(config)#
+
+- name: Merge new static route configuration
+ arista.eos.eos_static_routes:
+ config:
+ - vrf: testvrf
+ address_families:
+ - afi: ipv6
+ routes:
+ - dest: 2211::0/64
+ next_hop:
+ - forward_router_address: 100:1::2
+ interface: Ethernet1
+ state: merged
+
+# After State
+# -----------
+
+#After [
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "165.10.1.0/24",
+# "next_hops": [
+# {
+# "admin_distance": 100,
+# "interface": "Ethernet1"
+# }
+# ]
+# },
+# {
+# "dest": "172.17.252.0/24",
+# "next_hops": [
+# {
+# "nexthop_grp": "testgroup"
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "5001::/64",
+# "next_hops": [
+# {
+# "admin_distance": 50,
+# "interface": "Ethernet1"
+# }
+# ]
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "130.1.122.0/24",
+# "next_hops": [
+# {
+# "interface": "Ethernet1",
+# "tag": 50
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "2211::0/64",
+# "next_hops": [
+# {
+# "aforward_router_address": 100:1::2
+# "interface": "Ethernet1"
+# }
+# ]
+# }
+# ]
+# }
+
+# ],
+# "vrf": "testvrf"
+# }
+# ]
+#
+# veos(config)#show running-config | grep "route"
+# ip route 165.10.1.0/24 Ethernet1 100
+# ip route 172.17.252.0/24 Nexthop-Group testgroup
+# ip route vrf testvrf 130.1.122.0/24 Ethernet1 tag 50
+# ipv6 route 2211::/64 Ethernet1 100:1::2
+# ipv6 route 5001::/64 Ethernet1 50
+# veos(config)#
+
+
+# Using overridden
+
+
+# Before State
+# -------------
+
+# "before": [
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "165.10.1.0/24",
+# "next_hops": [
+# {
+# "admin_distance": 100,
+# "interface": "Ethernet1"
+# }
+# ]
+# },
+# {
+# "dest": "172.17.252.0/24",
+# "next_hops": [
+# {
+# "nexthop_grp": "testgroup"
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "5001::/64",
+# "next_hops": [
+# {
+# "admin_distance": 50,
+# "interface": "Ethernet1"
+# }
+# ]
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "130.1.122.0/24",
+# "next_hops": [
+# {
+# "interface": "Ethernet1",
+# "tag": 50
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "vrf": "testvrf"
+# }
+# ]
+# veos(config)#show running-config | grep "route"
+# ip route 165.10.1.0/24 Ethernet1 100
+# ip route 172.17.252.0/24 Nexthop-Group testgroup
+# ip route vrf testvrf 130.1.122.0/24 Ethernet1 tag 50
+# ipv6 route 5001::/64 Ethernet1 50
+# veos(config)#
+
+- name: Overridden static route configuration
+ arista.eos.eos_static_routes:
+ config:
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: 10.2.2.0/24
+ next_hop:
+ - interface: Ethernet1
+ state: replaced
+
+# After State
+# -----------
+
+# "after": [
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "10.2.2.0/24",
+# "next_hops": [
+# {
+# "interface": "Ethernet1"
+# }
+# ]
+# }
+# ]
+# }
+# ]
+# }
+# ]
+# veos(config)#show running-config | grep "route"
+# ip route 10.2.2.0/24 Ethernet1
+# veos(config)#
+
+
+# Using replaced
+
+# Before State
+# -------------
+
+# ip route 10.2.2.0/24 Ethernet1
+# ip route 10.2.2.0/24 64.1.1.1 label 17 33
+# ip route 33.33.33.0/24 Nexthop-Group testgrp
+# ip route vrf testvrf 22.65.1.0/24 Null0 90 name testroute
+# ipv6 route 5222:5::/64 Management1 4312:100::1
+# ipv6 route vrf testvrf 2222:6::/64 Management1 4312:100::1
+# ipv6 route vrf testvrf 2222:6::/64 Ethernet1 55
+# ipv6 route vrf testvrf 2222:6::/64 Null0 90 name testroute1
+
+# [
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "10.2.2.0/24",
+# "next_hops": [
+# {
+# "interface": "Ethernet1"
+# },
+# {
+# "admin_distance": 33,
+# "interface": "64.1.1.1",
+# "mpls_label": 17
+# }
+# ]
+# },
+# {
+# "dest": "33.33.33.0/24",
+# "next_hops": [
+# {
+# "nexthop_grp": "testgrp"
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "5222:5::/64",
+# "next_hops": [
+# {
+# "forward_router_address": "4312:100::1",
+# "interface": "Management1"
+# }
+# ]
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "22.65.1.0/24",
+# "next_hops": [
+# {
+# "admin_distance": 90,
+# "description": "testroute",
+# "interface": "Null0"
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "2222:6::/64",
+# "next_hops": [
+# {
+# "forward_router_address": "4312:100::1",
+# "interface": "Management1"
+# },
+# {
+# "admin_distance": 90,
+# "description": "testroute1",
+# "interface": "Null0"
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "vrf": "testvrf"
+# }
+# ]
+
+- name: Replace nexthop
+ arista.eos.eos_static_routes:
+ config:
+ - vrf: testvrf
+ address_families:
+ - afi: ipv6
+ routes:
+ - dest: 2222:6::/64
+ next_hops:
+ - admin_distance: 55
+ interface: Ethernet1
+ state: replaced
+
+# After State
+# -----------
+
+# veos(config)#show running-config | grep route
+# ip route 10.2.2.0/24 Ethernet1
+# ip route 10.2.2.0/24 64.1.1.1 label 17 33
+# ip route 33.33.33.0/24 Nexthop-Group testgrp
+# ip route vrf testvrf 22.65.1.0/24 Null0 90 name testroute
+# ipv6 route 5222:5::/64 Management1 4312:100::1
+# ipv6 route vrf testvrf 2222:6::/64 Ethernet1 55
+
+# "after": [
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "10.2.2.0/24",
+# "next_hops": [
+# {
+# "interface": "Ethernet1"
+# },
+# {
+# "admin_distance": 33,
+# "interface": "64.1.1.1",
+# "mpls_label": 17
+# }
+# ]
+# },
+# {
+# "dest": "33.33.33.0/24",
+# "next_hops": [
+# {
+# "nexthop_grp": "testgrp"
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "5222:5::/64",
+# "next_hops": [
+# {
+# "forward_router_address": "4312:100::1",
+# "interface": "Management1"
+# }
+# ]
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "address_families": [
+# {
+# "afi": "ipv4",
+# "routes": [
+# {
+# "dest": "22.65.1.0/24",
+# "next_hops": [
+# {
+# "admin_distance": 90,
+# "description": "testroute",
+# "interface": "Null0"
+# }
+# ]
+# }
+# ]
+# },
+# {
+# "afi": "ipv6",
+# "routes": [
+# {
+# "dest": "2222:6::/64",
+# "next_hops": [
+# {
+# "admin_distance": 55,
+# "interface": "Ethernet1"
+# }
+# ]
+# }
+# ]
+# }
+# ],
+# "vrf": "testvrf"
+# }
+# ]
+
+# Before State
+# -------------
+# veos(config)#show running-config | grep "route"
+# ip route 165.10.1.0/24 Ethernet1 10.1.1.2 100
+# ipv6 route 5001::/64 Ethernet1
+# veos(config)#
+
+
+- name: Gather the exisitng condiguration
+ arista.eos.eos_static_routes:
+ state: gathered
+
+# returns :
+# arista.eos.eos_static_routes:
+# config:
+# - address_families:
+# - afi: ipv4
+# routes:
+# - dest: 165.10.1.0/24
+# next_hop:
+# - forward_router_address: 10.1.1.2
+# interface: "Ethernet1"
+# admin_distance: 100
+# - afi: ipv6
+# routes:
+# - dest: 5001::/64
+# next_hop:
+# - interface: "Ethernet1"
+
+
+# Using rendered
+
+# arista.eos.eos_static_routes:
+# config:
+# - address_families:
+# - afi: ipv4
+# routes:
+# - dest: 165.10.1.0/24
+# next_hop:
+# - forward_router_address: 10.1.1.2
+# interface: "Ethernet1"
+# admin_distance: 100
+# - afi: ipv6
+# routes:
+# - dest: 5001::/64
+# next_hop:
+# - interface: "Ethernet1"
+
+# returns:
+
+# ip route 165.10.1.0/24 Ethernet1 10.1.1.2 100
+# ipv6 route 5001::/64 Ethernet1
+
+
+"""
+RETURN = """
+before:
+ description: The configuration prior to the model invocation.
+ returned: always
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+after:
+ description: The resulting configuration model invocation.
+ returned: when changed
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample:
+ - ip route vrf vrf1 192.2.2.0/24 125.2.3.1 93
+rendered:
+ description: The set of CLI commands generated from the value in C(config) option
+ returned: When C(state) is I(rendered)
+ type: list
+ sample: >
+ "address_families": [
+ {
+ "afi": "ipv4",
+ "routes": [
+ {
+ "dest": "192.2.2.0/24",
+ "next_hops": [
+ {
+ "admin_distance": 93,
+ "description": null,
+ "forward_router_address": null,
+ "interface": "125.2.3.1",
+ "mpls_label": null,
+ "nexthop_grp": null,
+ "tag": null,
+ "track": null,
+ "vrf": null
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "vrf": "vrf1"
+ }
+ ],
+ "running_config": null,
+ "state": "rendered"
+ }
+gathered:
+ description: The configuration as structured data transformed for the running configuration
+ fetched from remote host
+ returned: When C(state) is I(gathered)
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+parsed:
+ description: The configuration as structured data transformed for the value of
+ C(running_config) option
+ returned: When C(state) is I(parsed)
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.static_routes.static_routes import (
+ Static_routesArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.static_routes.static_routes import (
+ Static_routes,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+
+ module = AnsibleModule(
+ argument_spec=Static_routesArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = Static_routes(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_system.py b/ansible_collections/arista/eos/plugins/modules/eos_system.py
new file mode 100644
index 000000000..9fb1aca9f
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_system.py
@@ -0,0 +1,378 @@
+#!/usr/bin/python
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_system
+author: Peter Sprygada (@privateip)
+short_description: Manage the system attributes on Arista EOS devices
+description:
+- This module provides declarative management of node system attributes on Arista
+ EOS devices. It provides an option to configure host system parameters or remove
+ those parameters from the device active configuration.
+version_added: 1.0.0
+notes:
+- Tested against Arista EOS 4.24.6F
+options:
+ hostname:
+ description:
+ - Configure the device hostname parameter. This option takes an ASCII string value.
+ type: str
+ domain_name:
+ description:
+ - Configure the IP domain name on the remote device to the provided value. Value
+ should be in the dotted name form and will be appended to the C(hostname) to
+ create a fully-qualified domain name.
+ type: str
+ domain_list:
+ description:
+ - Provides the list of domain suffixes to append to the hostname for the purpose
+ of doing name resolution. This argument accepts a list of names and will be
+ reconciled with the current active configuration on the running node.
+ aliases:
+ - domain_search
+ type: list
+ elements: str
+ lookup_source:
+ description:
+ - Provides one or more source interfaces to use for performing DNS lookups. The
+ interface provided in C(lookup_source) can only exist in a single VRF. This
+ argument accepts either a list of interface names or a list of hashes that configure
+ the interface name and VRF name. See examples.
+ elements: raw
+ type: list
+ name_servers:
+ description:
+ - List of DNS name servers by IP address to use to perform name resolution lookups. This
+ 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
+ state:
+ description:
+ - State of the configuration values in the device's current active configuration. When
+ set to I(present), the values should be configured in the device active configuration
+ and when set to I(absent) the values should not be in the device active configuration
+ default: present
+ type: str
+ choices:
+ - present
+ - absent
+"""
+
+EXAMPLES = """
+- name: configure hostname and domain-name
+ arista.eos.eos_system:
+ hostname: eos01
+ domain_name: test.example.com
+
+- name: remove configuration
+ arista.eos.eos_system:
+ state: absent
+
+- name: configure DNS lookup sources
+ arista.eos.eos_system:
+ lookup_source: Management1
+
+- name: configure DNS lookup sources with VRF support
+ arista.eos.eos_system:
+ lookup_source:
+ - interface: Management1
+ vrf: mgmt
+ - interface: Ethernet1
+ vrf: myvrf
+
+- name: configure name servers
+ arista.eos.eos_system:
+ name_servers:
+ - 8.8.8.8
+ - 8.8.4.4
+
+- name: configure name servers with VRF support
+ arista.eos.eos_system:
+ name_servers:
+ - {server: 8.8.8.8, vrf: mgmt}
+ - {server: 8.8.4.4, vrf: mgmt}
+"""
+
+RETURN = """
+commands:
+ description: The list of configuration mode commands to send to the device
+ returned: always
+ type: list
+ sample:
+ - hostname eos01
+ - dns domain test.example.com
+session_name:
+ description: The EOS config session name used to load the configuration
+ returned: changed
+ type: str
+ sample: ansible_1479315771
+"""
+import re
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ ComplexList,
+)
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.eos import (
+ get_config,
+ load_config,
+)
+
+
+_CONFIGURED_VRFS = None
+
+
+def has_vrf(module, vrf):
+ global _CONFIGURED_VRFS
+ if _CONFIGURED_VRFS is not None:
+ return vrf in _CONFIGURED_VRFS
+ config = get_config(module)
+ _CONFIGURED_VRFS = re.findall(r"vrf instance (\S+)", config)
+ _CONFIGURED_VRFS.append("default")
+ return vrf in _CONFIGURED_VRFS
+
+
+def map_obj_to_commands(want, have, module):
+ commands = list()
+ state = module.params["state"]
+
+ def needs_update(x):
+ return want.get(x) and (want.get(x) != have.get(x))
+
+ if state == "absent":
+ if have["domain_name"]:
+ commands.append("no dns domain")
+
+ if have["hostname"] != "localhost":
+ commands.append("no hostname")
+
+ if state == "present":
+ if needs_update("hostname"):
+ commands.append("hostname %s" % want["hostname"])
+
+ if needs_update("domain_name"):
+ commands.append("dns domain %s" % want["domain_name"])
+
+ if want["domain_list"]:
+ # handle domain_list items to be removed
+ for item in set(have["domain_list"]).difference(
+ want["domain_list"],
+ ):
+ commands.append("no ip domain-list %s" % item)
+
+ # handle domain_list items to be added
+ for item in set(want["domain_list"]).difference(
+ have["domain_list"],
+ ):
+ commands.append("ip domain-list %s" % item)
+
+ if want["lookup_source"]:
+ # handle lookup_source items to be removed
+ for item in have["lookup_source"]:
+ if item not in want["lookup_source"]:
+ if item["vrf"]:
+ if not has_vrf(module, item["vrf"]):
+ module.fail_json(
+ msg="vrf %s is not configured" % item["vrf"],
+ )
+ values = (item["vrf"], item["interface"])
+ commands.append(
+ "no ip domain lookup vrf %s source-interface %s"
+ % values,
+ )
+ else:
+ commands.append(
+ "no ip domain lookup source-interface %s"
+ % item["interface"],
+ )
+
+ # handle lookup_source items to be added
+ for item in want["lookup_source"]:
+ if item not in have["lookup_source"]:
+ if item["vrf"]:
+ if not has_vrf(module, item["vrf"]):
+ module.fail_json(
+ msg="vrf %s is not configured" % item["vrf"],
+ )
+ values = (item["vrf"], item["interface"])
+ commands.append(
+ "ip domain lookup vrf %s source-interface %s"
+ % values,
+ )
+ else:
+ commands.append(
+ "ip domain lookup source-interface %s"
+ % item["interface"],
+ )
+
+ if want["name_servers"]:
+ # handle name_servers items to be removed. Order does matter here
+ # since name servers can only be in one vrf at a time
+ for item in have["name_servers"]:
+ if item not in want["name_servers"]:
+ if not has_vrf(module, item["vrf"]):
+ module.fail_json(
+ msg="vrf %s is not configured" % item["vrf"],
+ )
+ if item["vrf"] not in ("default", None):
+ values = (item["vrf"], item["server"])
+ commands.append("no ip name-server vrf %s %s" % values)
+ else:
+ commands.append(
+ "no ip name-server %s" % item["server"],
+ )
+
+ # handle name_servers items to be added
+ for item in want["name_servers"]:
+ if item not in have["name_servers"]:
+ if not has_vrf(module, item["vrf"]):
+ module.fail_json(
+ msg="vrf %s is not configured" % item["vrf"],
+ )
+ if item["vrf"] not in ("default", None):
+ values = (item["vrf"], item["server"])
+ commands.append("ip name-server vrf %s %s" % values)
+ else:
+ commands.append("ip name-server %s" % item["server"])
+
+ return commands
+
+
+def parse_hostname(config):
+ match = re.search(r"^hostname (\S+)", config, re.M)
+ if match:
+ return match.group(1)
+
+
+def parse_domain_name(config):
+ match = re.search(r"^dns domain (\S+)", config, re.M)
+ if match:
+ return match.group(1)
+
+
+def parse_lookup_source(config):
+ objects = list()
+ regex = r"ip domain lookup (?:vrf (\S+) )*source-interface (\S+)"
+ for vrf, intf in re.findall(regex, config, re.M):
+ if len(vrf) == 0:
+ vrf = None
+ objects.append({"interface": intf, "vrf": vrf})
+ return objects
+
+
+def parse_name_servers(config):
+ objects = list()
+ for vrf, addr in re.findall(
+ r"ip name-server vrf (\S+) (\S+)",
+ config,
+ re.M,
+ ):
+ objects.append({"server": addr, "vrf": vrf})
+ return objects
+
+
+def map_config_to_obj(module):
+ config = get_config(module)
+ return {
+ "hostname": parse_hostname(config),
+ "domain_name": parse_domain_name(config),
+ "domain_list": re.findall(r"^ip domain-list (\S+)", config, re.M),
+ "lookup_source": parse_lookup_source(config),
+ "name_servers": parse_name_servers(config),
+ }
+
+
+def map_params_to_obj(module):
+ obj = {
+ "hostname": module.params["hostname"],
+ "domain_name": module.params["domain_name"],
+ "domain_list": module.params["domain_list"],
+ }
+
+ lookup_source = ComplexList(
+ dict(interface=dict(key=True), vrf=dict()),
+ module,
+ )
+
+ name_servers = ComplexList(
+ dict(server=dict(key=True), vrf=dict(default="default")),
+ module,
+ )
+
+ for arg, cast in [
+ ("lookup_source", lookup_source),
+ ("name_servers", name_servers),
+ ]:
+ if module.params[arg] is not None:
+ obj[arg] = cast(module.params[arg])
+ else:
+ obj[arg] = None
+
+ return obj
+
+
+def main():
+ """main entry point for module execution"""
+ argument_spec = dict(
+ hostname=dict(),
+ domain_name=dict(),
+ domain_list=dict(
+ type="list",
+ aliases=["domain_search"],
+ elements="str",
+ ),
+ # { interface: <str>, vrf: <str> }
+ lookup_source=dict(type="list", elements="raw"),
+ # { server: <str>; vrf: <str> }
+ name_servers=dict(type="list", elements="str"),
+ state=dict(default="present", choices=["present", "absent"]),
+ )
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=True,
+ )
+
+ result = {"changed": False}
+
+ want = map_params_to_obj(module)
+ have = map_config_to_obj(module)
+
+ 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_user.py b/ansible_collections/arista/eos/plugins/modules/eos_user.py
new file mode 100644
index 000000000..519892daf
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_user.py
@@ -0,0 +1,491 @@
+#!/usr/bin/python
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_user
+author: Peter Sprygada (@privateip)
+short_description: Manage the collection of local users on EOS devices
+description:
+- This module provides declarative management of the local usernames configured on
+ Arista EOS devices. It allows playbooks to manage either individual usernames or
+ the collection of usernames in the current running config. It also supports purging
+ usernames from the configuration that are not explicitly defined.
+version_added: 1.0.0
+notes:
+- Tested against Arista EOS 4.24.6F
+options:
+ aggregate:
+ description:
+ - The set of username objects to be configured on the remote Arista EOS device. The
+ list entries can either be the username or a hash of username and properties. This
+ argument is mutually exclusive with the C(username) argument.
+ aliases:
+ - users
+ - collection
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - The username to be configured on the remote Arista EOS device. This argument
+ accepts a stringv value and is mutually exclusive with the C(aggregate) argument.
+ type: str
+ configured_password:
+ description:
+ - The password to be configured on the remote Arista EOS device. The password
+ needs to be provided in clear and it will be encrypted on the device.
+ type: str
+ update_password:
+ description:
+ - Since passwords are encrypted in the device running config, this argument will
+ instruct the module when to change the password. When set to C(always), the
+ password will always be updated in the device and when set to C(on_create) the
+ password will be updated only if the username is created.
+ type: str
+ choices:
+ - on_create
+ - always
+ privilege:
+ description:
+ - The C(privilege) argument configures the privilege level of the user when logged
+ into the system. This argument accepts integer values in the range of 1 to
+ 15.
+ type: int
+ role:
+ description:
+ - Configures the role for the username in the device running configuration. The
+ argument accepts a string value defining the role name. This argument does
+ not check if the role has been configured on the device.
+ type: str
+ sshkey:
+ description:
+ - Specifies the SSH public key to configure for the given username. This argument
+ accepts a valid SSH key value.
+ type: str
+ nopassword:
+ description:
+ - Defines the username without assigning a password. This will allow the user
+ to login to the system without being authenticated by a password.
+ type: bool
+ state:
+ description:
+ - Configures the state of the username definition as it relates to the device
+ operational configuration. When set to I(present), the username(s) should be
+ configured in the device active configuration and when set to I(absent) the
+ username(s) should not be in the device active configuration
+ type: str
+ choices:
+ - present
+ - absent
+ name:
+ description:
+ - The username to be configured on the remote Arista EOS device. This argument
+ accepts a stringv value and is mutually exclusive with the C(aggregate) argument.
+ type: str
+ configured_password:
+ description:
+ - The password to be configured on the remote Arista EOS device. The password
+ needs to be provided in clear and it will be encrypted on the device.
+ type: str
+ update_password:
+ description:
+ - Since passwords are encrypted in the device running config, this argument will
+ instruct the module when to change the password. When set to C(always), the
+ password will always be updated in the device and when set to C(on_create) the
+ password will be updated only if the username is created.
+ default: always
+ type: str
+ choices:
+ - on_create
+ - always
+ privilege:
+ description:
+ - The C(privilege) argument configures the privilege level of the user when logged
+ into the system. This argument accepts integer values in the range of 1 to
+ 15.
+ type: int
+ role:
+ description:
+ - Configures the role for the username in the device running configuration. The
+ argument accepts a string value defining the role name. This argument does
+ not check if the role has been configured on the device.
+ type: str
+ sshkey:
+ description:
+ - Specifies the SSH public key to configure for the given username. This argument
+ accepts a valid SSH key value.
+ type: str
+ nopassword:
+ description:
+ - Defines the username without assigning a password. This will allow the user
+ to login to the system without being authenticated by a password.
+ type: bool
+ purge:
+ description:
+ - Instructs the module to consider the resource definition absolute. It will
+ remove any previously configured usernames on the device with the exception
+ of the `admin` user which cannot be deleted per EOS constraints.
+ type: bool
+ default: false
+ state:
+ description:
+ - Configures the state of the username definition as it relates to the device
+ operational configuration. When set to I(present), the username(s) should be
+ configured in the device active configuration and when set to I(absent) the
+ username(s) should not be in the device active configuration
+ type: str
+ default: present
+ choices:
+ - present
+ - absent
+"""
+
+EXAMPLES = """
+- name: create a new user
+ arista.eos.eos_user:
+ name: ansible
+ sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
+ state: present
+
+- name: remove all users except admin
+ arista.eos.eos_user:
+ purge: yes
+
+- name: set multiple users to privilege level 15
+ arista.eos.eos_user:
+ aggregate:
+ - name: netop
+ - name: netend
+ privilege: 15
+ state: present
+
+- name: Change Password for User netop
+ arista.eos.eos_user:
+ username: netop
+ configured_password: '{{ new_password }}'
+ update_password: always
+ state: present
+"""
+
+RETURN = """
+commands:
+ description: The list of configuration mode commands to send to the device
+ returned: always
+ type: list
+ sample:
+ - name ansible secret password
+ - name admin secret admin
+session_name:
+ description: The EOS config session name used to load the configuration
+ returned: when changed is True
+ type: str
+ sample: ansible_1479315771
+"""
+
+import re
+
+from copy import deepcopy
+from functools import partial
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.six import iteritems
+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,
+ run_commands,
+)
+
+
+def validate_privilege(value, module):
+ if not 1 <= value <= 15:
+ module.fail_json(
+ msg="privilege must be between 1 and 15, got %s" % value,
+ )
+
+
+def get_os_version(module):
+ os_version = "4.20.10"
+ response = run_commands(
+ module,
+ 'show version | grep "Software image version"',
+ )
+ version_match = re.search(
+ r"Software image version:\s+([\d\.]+)",
+ response[0],
+ re.M,
+ )
+ if version_match:
+ v = version_match.group(1).split(".")
+ os_version = tuple(int(digit) for digit in v)
+ return os_version
+
+
+def map_obj_to_commands(updates, module):
+ commands = list()
+ update_password = module.params["update_password"]
+
+ for update in updates:
+ want, have = update
+
+ def needs_update(x):
+ return want.get(x) and (want.get(x) != have.get(x))
+
+ def add(x):
+ return commands.append("username %s %s" % (want["name"], x))
+
+ if want["state"] == "absent":
+ commands.append("no username %s" % want["name"])
+ continue
+
+ if needs_update("configured_password"):
+ if update_password == "always" or not have:
+ add("secret %s" % want["configured_password"])
+
+ if needs_update("role"):
+ add("role %s" % want["role"])
+
+ if needs_update("privilege"):
+ add("privilege %s" % want["privilege"])
+
+ if needs_update("sshkey"):
+ ver = get_os_version(module)
+ # compare against image version 4.20.10
+ if ver > (4, 20, 10):
+ add("ssh-key %s" % want["sshkey"])
+ else:
+ add("sshkey %s" % want["sshkey"])
+
+ if needs_update("nopassword"):
+ if want["nopassword"]:
+ add("nopassword")
+ else:
+ add("no username %s nopassword" % want["name"])
+
+ if want.get("state") == "present" and want.get("name"):
+ value = [
+ want.get("configured_password"),
+ want.get("nopassword"),
+ want.get("sshkey"),
+ ]
+ if all(v is None for v in value) is True:
+ module.fail_json(
+ msg="configured_password, sshkey or nopassword should be provided",
+ )
+ return commands
+
+
+def parse_role(data):
+ match = re.search(r"role (\S+)", data, re.M)
+ if match:
+ return match.group(1)
+
+
+def parse_sshkey(data):
+ match = re.search(r"sshkey|ssh-key (.+)$", data, re.M)
+ if match:
+ return match.group(1)
+
+
+def parse_privilege(data):
+ match = re.search(r"privilege (\S+)", data, re.M)
+ if match:
+ return int(match.group(1))
+
+
+def map_config_to_obj(module):
+ data = get_config(module, flags=["section username"])
+
+ match = re.findall(r"^username (\S+)", data, re.M)
+ if not match:
+ return list()
+
+ instances = list()
+
+ for user in set(match):
+ regex = r"username %s .+$" % user
+ cfg = re.findall(regex, data, re.M)
+ cfg = "\n".join(cfg)
+ obj = {
+ "name": user,
+ "state": "present",
+ "nopassword": "nopassword" in cfg,
+ "configured_password": None,
+ "sshkey": parse_sshkey(cfg),
+ "privilege": parse_privilege(cfg),
+ "role": parse_role(cfg),
+ }
+ instances.append(obj)
+
+ return instances
+
+
+def get_param_value(key, item, module):
+ # if key doesn't exist in the item, get it from module.params
+ if not item.get(key):
+ value = module.params[key]
+
+ # if key does exist, do a type check on it to validate it
+ else:
+ value_type = module.argument_spec[key].get("type", "str")
+ type_checker = module._CHECK_ARGUMENT_TYPES_DISPATCHER[value_type]
+ type_checker(item[key])
+ value = item[key]
+
+ # validate the param value (if validator func exists)
+ validator = globals().get("validate_%s" % key)
+ if all((value, validator)):
+ validator(value, module)
+
+ return value
+
+
+def map_params_to_obj(module):
+ aggregate = module.params["aggregate"]
+ if not aggregate:
+ if not module.params["name"] and module.params["purge"]:
+ return list()
+ elif not module.params["name"]:
+ module.fail_json(msg="name is required")
+ else:
+ collection = [{"name": module.params["name"]}]
+ else:
+ collection = list()
+ for item in aggregate:
+ if not isinstance(item, dict):
+ collection.append({"name": item})
+ elif "name" not in item:
+ module.fail_json(msg="name is required")
+ else:
+ collection.append(item)
+
+ objects = list()
+
+ for item in collection:
+ get_value = partial(get_param_value, item=item, module=module)
+ item["configured_password"] = get_value("configured_password")
+ item["nopassword"] = get_value("nopassword")
+ item["privilege"] = get_value("privilege")
+ item["role"] = get_value("role")
+ item["sshkey"] = get_value("sshkey")
+ item["state"] = get_value("state")
+ objects.append(item)
+
+ return objects
+
+
+def update_objects(want, have):
+ updates = list()
+ for entry in want:
+ if "name" in entry:
+ item = next((i for i in have if i["name"] == entry["name"]), None)
+ if all((item is None, entry["state"] == "present")):
+ updates.append((entry, {}))
+ elif item:
+ for key, value in iteritems(entry):
+ if value and value != item[key]:
+ updates.append((entry, item))
+ return updates
+
+
+def main():
+ """main entry point for module execution"""
+ element_spec = dict(
+ name=dict(),
+ configured_password=dict(no_log=True),
+ nopassword=dict(type="bool"),
+ update_password=dict(
+ default="always",
+ choices=["on_create", "always"],
+ ),
+ privilege=dict(type="int"),
+ role=dict(),
+ sshkey=dict(no_log=True),
+ 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)
+
+ argument_spec = dict(
+ aggregate=dict(
+ type="list",
+ elements="dict",
+ options=aggregate_spec,
+ aliases=["collection", "users"],
+ ),
+ purge=dict(type="bool", default=False),
+ )
+
+ argument_spec.update(element_spec)
+ mutually_exclusive = [("name", "aggregate")]
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ mutually_exclusive=mutually_exclusive,
+ supports_check_mode=True,
+ )
+
+ warnings = list()
+
+ result = {"changed": False}
+ if warnings:
+ result["warnings"] = warnings
+
+ want = map_params_to_obj(module)
+ have = map_config_to_obj(module)
+
+ commands = map_obj_to_commands(update_objects(want, have), module)
+
+ if module.params["purge"]:
+ want_users = [x["name"] for x in want]
+ have_users = [x["name"] for x in have]
+ for item in set(have_users).difference(want_users):
+ if item != "admin":
+ commands.append("no username %s" % item)
+
+ result["commands"] = commands
+
+ # the eos cli prevents this by rule so capture it and display
+ # a nice failure message
+ if "no username admin" in commands:
+ module.fail_json(msg="cannot delete the `admin` account")
+
+ 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_vlans.py b/ansible_collections/arista/eos/plugins/modules/eos_vlans.py
new file mode 100644
index 000000000..7c834a3ac
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_vlans.py
@@ -0,0 +1,329 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for eos_vlans
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: eos_vlans
+short_description: VLANs resource module
+description: This module provides declarative management of VLANs on Arista EOS network
+ devices.
+version_added: 1.0.0
+author: Nathaniel Case (@qalthos)
+notes:
+- Tested against Arista EOS 4.24.6F
+- This module works with connection C(network_cli). See the L(EOS Platform Options,../network/user_guide/platform_eos.html).
+options:
+ config:
+ description: A dictionary of VLANs options
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Name of the VLAN.
+ type: str
+ vlan_id:
+ description:
+ - ID of the VLAN. Range 1-4094
+ type: int
+ required: true
+ state:
+ description:
+ - Operational state of the VLAN
+ type: str
+ choices:
+ - active
+ - suspend
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device
+ by executing the command B(show running-config | section vlan).
+ - The state I(parsed) reads the configuration from C(running_config) option
+ and transforms it into Ansible structured data as per the resource module's
+ argspec and the value
+ type: str
+ state:
+ description:
+ - The state of the configuration after module completion
+ type: str
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - rendered
+ - gathered
+ - parsed
+ default: merged
+
+"""
+EXAMPLES = """
+# Using deleted
+
+# Before state:
+# -------------
+#
+# veos(config-vlan-20)#show running-config | section vlan
+# vlan 10
+# name ten
+# !
+# vlan 20
+# name twenty
+
+- name: Delete attributes of the given VLANs.
+ arista.eos.eos_vlans:
+ config:
+ - vlan_id: 20
+ state: deleted
+
+# After state:
+# ------------
+#
+# veos(config-vlan-20)#show running-config | section vlan
+# vlan 10
+# name ten
+
+
+# Using merged
+
+# Before state:
+# -------------
+#
+# veos(config-vlan-20)#show running-config | section vlan
+# vlan 10
+# name ten
+# !
+# vlan 20
+# name twenty
+
+- name: Merge given VLAN attributes with device configuration
+ arista.eos.eos_vlans:
+ config:
+ - vlan_id: 20
+ state: suspend
+ state: merged
+
+# After state:
+# ------------
+#
+# veos(config-vlan-20)#show running-config | section vlan
+# vlan 10
+# name ten
+# !
+# vlan 20
+# name twenty
+# state suspend
+
+
+# Using overridden
+
+# Before state:
+# -------------
+#
+# veos(config-vlan-20)#show running-config | section vlan
+# vlan 10
+# name ten
+# !
+# vlan 20
+# name twenty
+
+- name: Override device configuration of all VLANs with provided configuration
+ arista.eos.eos_vlans:
+ config:
+ - vlan_id: 20
+ state: suspend
+ state: overridden
+
+# After state:
+# ------------
+#
+# veos(config-vlan-20)#show running-config | section vlan
+# vlan 20
+# state suspend
+
+
+# Using replaced
+
+# Before state:
+# -------------
+#
+# veos(config-vlan-20)#show running-config | section vlan
+# vlan 10
+# name ten
+# !
+# vlan 20
+# name twenty
+
+- name: Replace all attributes of specified VLANs with provided configuration
+ arista.eos.eos_vlans:
+ config:
+ - vlan_id: 20
+ state: suspend
+ state: replaced
+
+# After state:
+# ------------
+#
+# veos(config-vlan-20)#show running-config | section vlan
+# vlan 10
+# name ten
+# !
+# vlan 20
+# state suspend
+
+# using parsed
+
+# parsed.cfg
+# vlan 10
+# name ten
+# !
+# vlan 20
+# name twenty
+# state suspend
+
+- name: Use parsed to convert native configs to structured data
+ arista.eos.eos_vlans:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# Output:
+# -------
+# parsed:
+# - vlan_id: 10
+# name: ten
+# - vlan_id: 20
+# state: suspend
+
+# Using rendered:
+
+- name: Use Rendered to convert the structured data to native config
+ arista.eos.eos_vlans:
+ config:
+ - vlan_id: 10
+ name: ten
+ - vlan_id: 20
+ state: suspend
+ state: rendered
+
+# Output:
+# ------
+# rendered:
+# - "vlan 10"
+# - "name ten"
+# - "vlan 20"
+# - "state suspend"
+
+# Using gathered:
+# native_config:
+# vlan 10
+# name ten
+# !
+# vlan 20
+# name twenty
+# state suspend
+
+- name: Gather vlans facts from the device
+ arista.eos.eos_vlans:
+ state: gathered
+
+# Output:
+# ------
+
+# gathered:
+# - vlan_id: 10
+# name: ten
+# - vlan_id: 20
+# state: suspend
+
+"""
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: list
+ sample: >
+ The configuration returned will always be in the same format
+ of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: always
+ type: list
+ sample: ['vlan 10', 'no name', 'vlan 11', 'name Eleven']
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.argspec.vlans.vlans import (
+ VlansArgs,
+)
+from ansible_collections.arista.eos.plugins.module_utils.network.eos.config.vlans.vlans import (
+ Vlans,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+ module = AnsibleModule(
+ argument_spec=VlansArgs.argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
+
+ result = Vlans(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/arista/eos/plugins/modules/eos_vrf.py b/ansible_collections/arista/eos/plugins/modules/eos_vrf.py
new file mode 100644
index 000000000..705796512
--- /dev/null
+++ b/ansible_collections/arista/eos/plugins/modules/eos_vrf.py
@@ -0,0 +1,427 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+# (c) 2017, Ansible by Red Hat, inc
+#
+# This file is part of Ansible by Red Hat
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+
+
+DOCUMENTATION = """
+module: eos_vrf
+author: Ricardo Carrillo Cruz (@rcarrillocruz)
+short_description: Manage VRFs on Arista EOS network devices
+description:
+- This module provides declarative management of VRFs on Arista EOS network devices.
+version_added: 1.0.0
+notes:
+- Tested against Arista EOS 4.24.6F
+options:
+ name:
+ description:
+ - Name of the VRF.
+ type: str
+ rd:
+ description:
+ - Route distinguisher of the VRF
+ type: str
+ interfaces:
+ description:
+ - Identifies the set of interfaces that should be configured in the VRF. Interfaces
+ must be routed interfaces in order to be placed into a VRF. The name of interface
+ should be in expanded format and not abbreviated.
+ type: list
+ elements: str
+ associated_interfaces:
+ description:
+ - This is a intent option and checks the operational state of the for given vrf
+ C(name) for associated interfaces. If the value in the C(associated_interfaces)
+ does not match with the operational state of vrf interfaces on device it will
+ result in failure.
+ type: list
+ elements: str
+ aggregate:
+ description: List of VRFs instances
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Name of the VRF.
+ required: true
+ type: str
+ rd:
+ description:
+ - Route distinguisher of the VRF
+ type: str
+ interfaces:
+ description:
+ - Identifies the set of interfaces that should be configured in the VRF. Interfaces
+ must be routed interfaces in order to be placed into a VRF. The name of interface
+ should be in expanded format and not abbreviated.
+ type: list
+ elements: str
+ associated_interfaces:
+ description:
+ - This is a intent option and checks the operational state of the for given vrf
+ C(name) for associated interfaces. If the value in the C(associated_interfaces)
+ does not match with the operational state of vrf interfaces on device it will
+ result in failure.
+ type: list
+ elements: str
+ delay:
+ description:
+ - Time in seconds to wait before checking for the operational state on remote
+ device. This wait is applicable for operational state arguments.
+ default: 10
+ type: int
+ state:
+ description:
+ - State of the VRF configuration.
+ default: present
+ type: str
+ choices:
+ - present
+ - absent
+ purge:
+ description:
+ - Purge VRFs not defined in the I(aggregate) parameter.
+ default: false
+ type: bool
+ delay:
+ description:
+ - Time in seconds to wait before checking for the operational state on remote
+ device. This wait is applicable for operational state arguments.
+ default: 10
+ type: int
+ state:
+ description:
+ - State of the VRF configuration.
+ default: present
+ type: str
+ choices:
+ - present
+ - absent
+"""
+
+EXAMPLES = """
+- name: Create vrf
+ arista.eos.eos_vrf:
+ name: test
+ rd: 1:200
+ interfaces:
+ - Ethernet2
+ state: present
+
+- name: Delete VRFs
+ arista.eos.eos_vrf:
+ name: test
+ state: absent
+
+- name: Create aggregate of VRFs with purge
+ arista.eos.eos_vrf:
+ aggregate:
+ - name: test4
+ rd: 1:204
+ - name: test5
+ rd: 1:205
+ state: present
+ purge: yes
+
+- name: Delete aggregate of VRFs
+ arista.eos.eos_vrf:
+ aggregate:
+ - name: test2
+ - name: test3
+ - name: test4
+ - name: test5
+ state: absent
+"""
+
+RETURN = """
+commands:
+ description: The list of configuration mode commands to send to the device
+ returned: always
+ type: list
+ sample:
+ - vrf instance test
+ - rd 1:100
+ - interface Ethernet1
+ - vrf test
+"""
+import re
+import time
+
+from copy import deepcopy
+
+from ansible.module_utils.basic import AnsibleModule
+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 (
+ load_config,
+ run_commands,
+)
+
+
+def search_obj_in_list(name, lst):
+ for o in lst:
+ if o["name"] == name:
+ return o
+
+
+def map_obj_to_commands(updates, module):
+ commands = list()
+ want, have = updates
+ state = module.params["state"]
+ purge = module.params["purge"]
+
+ for w in want:
+ name = w["name"]
+ rd = w["rd"]
+
+ obj_in_have = search_obj_in_list(name, have)
+
+ if state == "absent":
+ if obj_in_have:
+ commands.append("no vrf instance %s" % name)
+ elif state == "present":
+ if not obj_in_have:
+ commands.append("vrf instance %s" % name)
+
+ if rd is not None:
+ commands.append("rd %s" % rd)
+
+ if w["interfaces"]:
+ for i in w["interfaces"]:
+ commands.append("interface %s" % i)
+ commands.append("vrf %s" % w["name"])
+ else:
+ if w["rd"] is not None and w["rd"] != obj_in_have["rd"]:
+ commands.append("vrf instance %s" % w["name"])
+ commands.append("rd %s" % w["rd"])
+
+ if w["interfaces"]:
+ if not obj_in_have["interfaces"]:
+ for i in w["interfaces"]:
+ commands.append("interface %s" % i)
+ commands.append("vrf %s" % w["name"])
+ elif set(w["interfaces"]) != obj_in_have["interfaces"]:
+ missing_interfaces = list(
+ set(w["interfaces"])
+ - set(obj_in_have["interfaces"]),
+ )
+
+ for i in missing_interfaces:
+ commands.append("interface %s" % i)
+ commands.append("vrf %s" % w["name"])
+
+ if purge:
+ for h in have:
+ obj_in_want = search_obj_in_list(h["name"], want)
+ if not obj_in_want:
+ commands.append("no vrf instance %s" % h["name"])
+
+ return commands
+
+
+def map_config_to_obj(module):
+ objs = []
+ output = run_commands(module, {"command": "show vrf", "output": "text"})
+
+ lines = output[0].strip().splitlines()[3:]
+
+ out_len = len(lines)
+ index = 0
+ while out_len > index:
+ line = lines[index]
+ if not line:
+ continue
+
+ splitted_line = re.split(r"\s{2,}", line.strip())
+
+ if len(splitted_line) == 1:
+ index += 1
+ continue
+ obj = dict()
+ obj["name"] = splitted_line[0]
+ obj["rd"] = splitted_line[1]
+ obj["interfaces"] = []
+
+ if len(splitted_line) > 4:
+ obj["interfaces"] = []
+ interfaces = splitted_line[4]
+ if interfaces.endswith(","):
+ while interfaces.endswith(","):
+ # gather all comma separated interfaces
+ if out_len <= index:
+ break
+ index += 1
+ line = lines[index]
+ vrf_line = re.split(r"\s{2,}", line.strip())
+ interfaces += vrf_line[-1]
+
+ for i in interfaces.split(","):
+ obj["interfaces"].append(i.strip().lower())
+ index += 1
+ objs.append(obj)
+
+ return objs
+
+
+def map_params_to_obj(module):
+ 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]
+
+ if item.get("interfaces"):
+ item["interfaces"] = [
+ intf.replace(" ", "").lower()
+ for intf in item.get("interfaces")
+ if intf
+ ]
+
+ if item.get("associated_interfaces"):
+ item["associated_interfaces"] = [
+ intf.replace(" ", "").lower()
+ for intf in item.get("associated_interfaces")
+ if intf
+ ]
+
+ obj.append(item.copy())
+ else:
+ obj.append(
+ {
+ "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 [],
+ },
+ )
+
+ return obj
+
+
+def check_declarative_intent_params(want, module, result):
+ have = None
+ is_delay = False
+
+ for w in want:
+ if w.get("associated_interfaces") is None:
+ continue
+
+ if result["changed"] and not is_delay:
+ time.sleep(module.params["delay"])
+ is_delay = True
+
+ if have is None:
+ have = map_config_to_obj(module)
+
+ for i in w["associated_interfaces"]:
+ obj_in_have = search_obj_in_list(w["name"], have)
+
+ if obj_in_have:
+ interfaces = obj_in_have.get("interfaces")
+ if interfaces is not None and i not in interfaces:
+ module.fail_json(
+ msg="Interface %s not configured on vrf %s"
+ % (i, w["name"]),
+ )
+
+
+def main():
+ """main entry point for module execution"""
+ element_spec = dict(
+ name=dict(),
+ interfaces=dict(type="list", elements="str"),
+ associated_interfaces=dict(type="list", elements="str"),
+ delay=dict(default=10, type="int"),
+ rd=dict(),
+ state=dict(default="present", choices=["present", "absent"]),
+ )
+
+ aggregate_spec = deepcopy(element_spec)
+ aggregate_spec["name"] = dict(required=True)
+
+ # remove default in aggregate spec, to handle common arguments
+ remove_default_spec(aggregate_spec)
+ aggregate_spec["state"].update(default="present")
+ aggregate_spec["delay"].update(default=10)
+
+ argument_spec = dict(
+ aggregate=dict(type="list", elements="dict", options=aggregate_spec),
+ purge=dict(default=False, type="bool"),
+ )
+
+ argument_spec.update(element_spec)
+
+ required_one_of = [["name", "aggregate"]]
+ mutually_exclusive = [["name", "aggregate"]]
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ required_one_of=required_one_of,
+ mutually_exclusive=mutually_exclusive,
+ supports_check_mode=True,
+ )
+
+ warnings = list()
+
+ result = {"changed": False}
+
+ if warnings:
+ result["warnings"] = warnings
+
+ want = map_params_to_obj(module)
+ have = map_config_to_obj(module)
+
+ 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
+
+ check_declarative_intent_params(want, module, result)
+
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()