#!/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 nxos_acl_interfaces
"""

from __future__ import absolute_import, division, print_function


__metaclass__ = type


DOCUMENTATION = """
module: nxos_acl_interfaces
short_description: ACL interfaces resource module
description: Add and remove Access Control Lists on interfaces in NX-OS platform
version_added: 1.0.0
author: Adharsh Srivats Rangarajan (@adharshsrivatsr)
notes:
- Tested against NX-OS 7.3.(0)D1(1) on VIRL
- Unsupported for Cisco MDS
options:
  running_config:
    description:
    - This option is used only with state I(parsed).
    - The value of this option should be the output received from the NX-OS 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
  config:
    description: A list of interfaces to be configured with ACLs
    type: list
    elements: dict
    suboptions:
      name:
        description: Name of the interface
        type: str
        required: true
      access_groups:
        description: List of address family indicators with ACLs to be configured
          on the interface
        type: list
        elements: dict
        suboptions:
          afi:
            description: Address Family Indicator of the ACLs to be configured
            type: str
            required: true
            choices:
            - ipv4
            - ipv6
          acls:
            description: List of Access Control Lists for the interface
            type: list
            elements: dict
            suboptions:
              name:
                description: Name of the ACL to be added/removed
                type: str
                required: true
              direction:
                description: Direction to be applied for the ACL
                type: str
                required: true
                choices:
                - in
                - out
              port:
                description: Use ACL as port policy.
                type: bool
  state:
    description: The state the configuration should be left in
    type: str
    choices:
    - deleted
    - gathered
    - merged
    - overridden
    - rendered
    - replaced
    - parsed
    default: merged

"""
EXAMPLES = """
# Using merged

# Before state:
# ------------
#

- name: Merge ACL interfaces configuration
  cisco.nxos.nxos_acl_interfaces:
    config:
    - name: Ethernet1/2
      access_groups:
      - afi: ipv6
        acls:
        - name: ACL1v6
          direction: in

    - name: Eth1/5
      access_groups:
      - afi: ipv4
        acls:
        - name: PortACL
          direction: in
          port: true

        - name: ACL1v4
          direction: out

      - afi: ipv6
        acls:
        - name: ACL1v6
          direction: in
    state: merged

# After state:
# ------------
# interface Ethernet1/2
#   ipv6 traffic-filter ACL1v6 in
# interface Ethernet1/5
#   ip port access-group PortACL in
#   ip access-group ACL1v4 out
#   ipv6 traffic-filter ACL1v6 in

# Using replaced

# Before state:
# ------------
# interface Ethernet1/2
#   ipv6 traffic-filter ACL1v6 in
# interface Ethernet1/5
#   ip port access-group PortACL in
#   ip access-group ACL1v4 out
#   ipv6 traffic-filter ACL1v6 in

- name: Replace interface configuration with given configuration
  cisco.nxos.nxos_acl_interfaces:
    config:
    - name: Eth1/5
      access_groups:
      - afi: ipv4
        acls:
        - name: NewACLv4
          direction: out

    - name: Ethernet1/3
      access_groups:
      - afi: ipv6
        acls:
        - name: NewACLv6
          direction: in
          port: true
    state: replaced

# After state:
# ------------
# interface Ethernet1/2
#   ipv6 traffic-filter ACL1v6 in
# interface Ethernet1/3
#   ipv6 port traffic-filter NewACLv6 in
# interface Ethernet1/5
#   ip access-group NewACLv4 out

# Using overridden

# Before state:
# ------------
# interface Ethernet1/2
#   ipv6 traffic-filter ACL1v6 in
# interface Ethernet1/5
#   ip port access-group PortACL in
#   ip access-group ACL1v4 out
#   ipv6 traffic-filter ACL1v6 in

- name: Override interface configuration with given configuration
  cisco.nxos.nxos_acl_interfaces:
    config:
    - name: Ethernet1/3
      access_groups:
      - afi: ipv4
        acls:
        - name: ACL1v4
          direction: out

        - name: PortACL
          port: true
          direction: in
      - afi: ipv6
        acls:
        - name: NewACLv6
          direction: in
          port: true
    state: overridden

# After state:
# ------------
# interface Ethernet1/3
#   ip access-group ACL1v4 out
#   ip port access-group PortACL in
#   ipv6 port traffic-filter NewACLv6 in

# Using deleted to remove ACL config from specified interfaces

# Before state:
# -------------
# interface Ethernet1/1
#   ip access-group ACL2v4 in
# interface Ethernet1/2
#   ipv6 traffic-filter ACL1v6 in
# interface Ethernet1/5
#   ip port access-group PortACL in
#   ip access-group ACL1v4 out
#   ipv6 traffic-filter ACL1v6 in

- name: Delete ACL configuration on interfaces
  cisco.nxos.nxos_acl_interfaces:
    config:
    - name: Ethernet1/5
    - name: Ethernet1/2
    state: deleted

# After state:
# -------------
# interface Ethernet1/1
#   ip access-group ACL2v4 in
# interface Ethernet1/2
# interface Ethernet1/5

# Using deleted to remove ACL config from all interfaces

# Before state:
# -------------
# interface Ethernet1/1
#   ip access-group ACL2v4 in
# interface Ethernet1/2
#   ipv6 traffic-filter ACL1v6 in
# interface Ethernet1/5
#   ip port access-group PortACL in
#   ip access-group ACL1v4 out
#   ipv6 traffic-filter ACL1v6 in

- name: Delete ACL configuration from all interfaces
  cisco.nxos.nxos_acl_interfaces:
    state: deleted

# After state:
# -------------
# interface Ethernet1/1
# interface Ethernet1/2
# interface Ethernet1/5

# Using parsed

- name: Parse given configuration into structured format
  cisco.nxos.nxos_acl_interfaces:
    running_config: |
      interface Ethernet1/2
      ipv6 traffic-filter ACL1v6 in
      interface Ethernet1/5
      ipv6 traffic-filter ACL1v6 in
      ip access-group ACL1v4 out
      ip port access-group PortACL in
    state: parsed

# returns
# parsed:
#   - name: Ethernet1/2
#     access_groups:
#       - afi: ipv6
#         acls:
#           - name: ACL1v6
#             direction: in
#  - name: Ethernet1/5
#    access_groups:
#      - afi: ipv4
#        acls:
#          - name: PortACL
#            direction: in
#            port: True
#          - name: ACL1v4
#            direction: out
#      - afi: ipv6
#        acls:
#          - name: ACL1v6
#             direction: in


# Using gathered:

# Before state:
# ------------
# interface Ethernet1/2
#   ipv6 traffic-filter ACL1v6 in
# interface Ethernet1/5
#   ipv6 traffic-filter ACL1v6 in
#   ip access-group ACL1v4 out
#   ip port access-group PortACL in

- name: Gather existing configuration from device
  cisco.nxos.nxos_acl_interfaces:
    config:
    state: gathered

# returns
# gathered:
#   - name: Ethernet1/2
#     access_groups:
#       - afi: ipv6
#         acls:
#           - name: ACL1v6
#             direction: in
#  - name: Ethernet1/5
#    access_groups:
#      - afi: ipv4
#        acls:
#          - name: PortACL
#            direction: in
#            port: True
#          - name: ACL1v4
#            direction: out
#      - afi: ipv6
#        acls:
#          - name: ACL1v6
#             direction: in


# Using rendered

- name: Render required configuration to be pushed to the device
  cisco.nxos.nxos_acl_interfaces:
    config:
    - name: Ethernet1/2
      access_groups:
      - afi: ipv6
        acls:
        - name: ACL1v6
          direction: in

    - name: Ethernet1/5
      access_groups:
      - afi: ipv4
        acls:
        - name: PortACL
          direction: in
          port: true
        - name: ACL1v4
          direction: out
      - afi: ipv6
        acls:
        - name: ACL1v6
          direction: in
    state: rendered

# returns
# rendered:
#   interface Ethernet1/2
#   ipv6 traffic-filter ACL1v6 in
#   interface Ethernet1/5
#   ipv6 traffic-filter ACL1v6 in
#   ip access-group ACL1v4 out
#   ip port access-group PortACL in

"""
RETURN = """
before:
  description: The configuration prior to the model invocation.
  returned: always
  type: dict
  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: 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 Ethernet1/2', 'ipv6 traffic-filter ACL1v6 out', 'ip port access-group PortACL in']
"""


from ansible.module_utils.basic import AnsibleModule

from ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.argspec.acl_interfaces.acl_interfaces import (
    Acl_interfacesArgs,
)
from ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.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()
