#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2019 Red Hat Inc.
# 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 ios_l3_interfaces
"""

from __future__ import absolute_import, division, print_function


__metaclass__ = type


DOCUMENTATION = """
module: iosxr_l3_interfaces
short_description: Resource module to configure L3 interfaces.
description: This module provides declarative management of Layer-3 interface on Cisco
  IOS-XR devices.
version_added: 1.0.0
author:
- Sumit Jaiswal (@justjais)
- Rohit Thakur (@rohitthakur2590)
notes:
- This module works with connection C(network_cli). See L(the IOS-XR Platform Options,../network/user_guide/platform_iosxr.html).
options:
  config:
    description: A dictionary of Layer-3 interface options
    type: list
    elements: dict
    suboptions:
      name:
        description:
        - Full name of the interface excluding any logical unit number, i.e. GigabitEthernet0/1.
        type: str
        required: true
      ipv4:
        description:
        - IPv4 address to be set for the Layer-3 interface mentioned in I(name) option.
        - The address format is <ipv4 address>/<mask>, the mask is number in range
          0-32 eg. 192.168.0.1/24
        type: list
        elements: dict
        suboptions:
          address:
            description:
            - Configures the IPv4 address for Interface.
            type: str
          secondary:
            description:
            - Configures the IP address as a secondary address.
            type: bool
      ipv6:
        description:
        - IPv6 address to be set for the Layer-3 interface mentioned in I(name) option.
        - The address format is <ipv6 address>/<mask>, the mask is number in range
          0-128 eg. fd5d:12c9:2201:1::1/64
        type: list
        elements: dict
        suboptions:
          address:
            description:
            - Configures the IPv6 address for Interface.
            type: str
      carrier_delay:
        description:
        - Delay carrier transitions.
        type: dict
        suboptions:
          up:
            description:
            - Delay for carrier-up event in milliseconds.
            type: int
          down:
            description:
            - Delay for carrier-down event in milliseconds.
            type: int
      dampening:
        description:
        - Enable interface dampening to reduce the effects of interface flapping.
        type: dict
        suboptions:
          enabled:
            description:
            - Enable or disable dampening.
            type: bool
          half_life:
            description:
            - The time in minutes after which a penalty is halved if the interface stays up.
            type: int
          reuse_threshold:
            description:
            - The penalty value below which a suppressed interface is unsuppressed.
            type: int
          suppress_threshold:
            description:
            - The penalty value above which an interface is suppressed.
            type: int
          max_suppress_time:
            description:
            - The maximum time in minutes that an interface can be suppressed.
            type: int
          restart_penalty:
            description:
            - The penalty assigned to an interface when it flaps.
            type: int
      load_interval:
        description:
        - Specify the length of time for which data is used to compute load statistics.
        type: int
      flow_control:
        description:
        - Configure flow control for the interface.
        type: str
        choices: ['ingress', 'egress', 'bidirectional']
      flow:
        description:
        - Configure NetFlow monitoring on the interface.
        type: dict
        suboptions:
          ipv4:
            description:
            - Configure NetFlow monitoring for IPv4 traffic.
            type: dict
            suboptions:
              monitor:
                description:
                - Name of the flow monitor to apply.
                type: str
              sampler:
                description:
                - Name of the sampler to apply.
                type: str
              direction:
                description:
                - Direction of the flow monitoring.
                type: str
                choices: ['ingress', 'egress']
          ipv6:
            description:
            - Configure NetFlow monitoring for IPv6 traffic.
            type: dict
            suboptions:
              monitor:
                description:
                - Name of the flow monitor to apply.
                type: str
              sampler:
                description:
                - Name of the sampler to apply.
                type: str
              direction:
                description:
                - Direction of the flow monitoring.
                type: str
                choices: ['ingress', 'egress']
  running_config:
    description:
    - This option is used only with state I(parsed).
    - The value of this option should be the output received from the IOS-XR device
      by executing the command B(show running-config 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:
# -------------
#
# viosxr#show running-config interface
# interface Loopback888
# !
# interface Loopback999
# !
# interface MgmtEth0/RP0/CPU0/0
#  ipv4 address dhcp
# !
# interface preconfigure GigabitEthernet0/0/0/2
# !
# interface preconfigure GigabitEthernet0/0/0/3
# !

- name: Merge provided configuration with device configuration
  cisco.iosxr.iosxr_l3_interfaces:
    config:
      - name: GigabitEthernet0/0/0/2
        ipv4:
          - address: 192.168.0.1/24
      - name: GigabitEthernet0/0/0/3
        ipv4:
          - address: 192.168.2.1/24
            secondary: true
    state: merged

# Task Output
# -----------
#
# before:
# - name: Loopback888
# - name: Loopback999
# - name: GigabitEthernet0/0/0/2
# - name: GigabitEthernet0/0/0/3
# commands:
# - interface GigabitEthernet0/0/0/2
# - ipv4 address 192.168.0.1 255.255.255.0
# - interface GigabitEthernet0/0/0/3
# - ipv4 address 192.168.2.1 255.255.255.0 secondary
# after:
# - name: Loopback888
# - name: Loopback999
# - ipv4:
#   - address: 192.168.0.1/24
#   name: GigabitEthernet0/0/0/2
# - ipv4:
#   - address: 192.168.2.1/24
#     secondary: true
#   name: GigabitEthernet0/0/0/3

# After state:
# ------------
#
# viosxr#show running-config interface
# interface Loopback888
# !
# interface Loopback999
# !
# interface MgmtEth0/RP0/CPU0/0
#  ipv4 address dhcp
# !
# interface preconfigure GigabitEthernet0/0/0/2
#  ipv4 address 192.168.0.1 255.255.255.0
# !
# interface preconfigure GigabitEthernet0/0/0/3
#  ipv4 address 192.168.2.1 255.255.255.0 secondary
# !

# Using overridden

# Before state:
# -------------
#
# viosxr#show running-config interface
# interface Loopback888
# !
# interface Loopback999
# !
# interface MgmtEth0/RP0/CPU0/0
#  ipv4 address dhcp
# !
# interface preconfigure GigabitEthernet0/0/0/2
#  ipv4 address 192.168.0.1 255.255.255.0
# !
# interface preconfigure GigabitEthernet0/0/0/3
#  ipv4 address 192.168.2.1 255.255.255.0 secondary
# !

- name: Override device configuration of all interfaces with provided configuration
  cisco.iosxr.iosxr_l3_interfaces:
    config:
      - name: GigabitEthernet0/0/0/3
        ipv4:
          - address: 192.168.0.2/24
          - address: 192.168.2.1/24
            secondary: true
    state: overridden


# Task Output
# -----------
#
# before:
# - name: Loopback888
# - name: Loopback999
# - ipv4:
#   - address: 192.168.0.1/24
#   name: GigabitEthernet0/0/0/2
# - ipv4:
#   - address: 192.168.2.1/24
#     secondary: true
#   name: GigabitEthernet0/0/0/3
# commands:
# - interface GigabitEthernet0/0/0/2
# - no ipv4 address
# - interface GigabitEthernet0/0/0/3
# - ipv4 address 192.168.0.2 255.255.255.0
# - ipv4 address 192.168.0.1 255.255.255.0
# after:
# - name: Loopback888
# - name: Loopback999
# - name: GigabitEthernet0/0/0/2
# - ipv4:
#   - address: 192.168.0.1/24
#   - address: 192.168.2.1/24
#     secondary: true
#   name: GigabitEthernet0/0/0/3

# After state:
# -------------
#
# viosxr#show running-config interface
# interface Loopback888
# !
# interface Loopback999
# !
# interface MgmtEth0/RP0/CPU0/0
#  ipv4 address dhcp
# !
# interface preconfigure GigabitEthernet0/0/0/2
# !
# interface preconfigure GigabitEthernet0/0/0/3
#  ipv4 address 192.168.0.1 255.255.255.0
#  ipv4 address 192.168.2.1 255.255.255.0 secondary
# !

# Using replaced

# Before state:
# -------------
#
# viosxr#show running-config interface
# interface Loopback888
# !
# interface Loopback999
# !
# interface MgmtEth0/RP0/CPU0/0
#  ipv4 address dhcp
# !
# interface preconfigure GigabitEthernet0/0/0/2
# !
# interface preconfigure GigabitEthernet0/0/0/3
#  ipv4 address 192.168.0.1 255.255.255.0
#  ipv4 address 192.168.2.1 255.255.255.0 secondary
# !

- name: >-
    Replaces device configuration of listed interfaces with provided
    configuration
  cisco.iosxr.iosxr_l3_interfaces:
    config:
      - name: GigabitEthernet0/0/0/3
        ipv6:
          - address: 'fd5d:12c9:2201:1::1/64'
      - name: GigabitEthernet0/0/0/2
        ipv4:
          - address: 192.168.0.2/24
    state: replaced


# Task Output
# -----------
#
# before:
# - name: Loopback888
# - name: Loopback999
# - name: GigabitEthernet0/0/0/2
# - ipv4:
#   - address: 192.168.0.1/24
#   - address: 192.168.2.1/24
#     secondary: true
#   name: GigabitEthernet0/0/0/3
# commands:
# - interface GigabitEthernet0/0/0/3
# - no ipv4 address
# - ipv6 address fd5d:12c9:2201:1::1/64
# - interface GigabitEthernet0/0/0/2
# - ipv4 address 192.168.0.2 255.255.255.0
# after:
# - name: Loopback888
# - name: Loopback999
# - ipv4:
#   - address: 192.168.0.2/24
#   name: GigabitEthernet0/0/0/2
# - ipv6:
#   - address: fd5d:12c9:2201:1::1/64
#   name: GigabitEthernet0/0/0/3

# After state:
# -------------
#
# viosxr#show running-config interface
# interface Loopback888
# !
# interface Loopback999
# !
# interface MgmtEth0/RP0/CPU0/0
#  ipv4 address dhcp
# !
# interface preconfigure GigabitEthernet0/0/0/2
#  ipv4 address 192.168.0.2 255.255.255.0
# !
# interface preconfigure GigabitEthernet0/0/0/3
#  ipv6 address fd5d:12c9:2201:1::1/64
# !

# Using deleted

# Before state:
# -------------
#
# viosxr#show running-config interface
# interface Loopback888
# !
# interface Loopback999
# !
# interface MgmtEth0/RP0/CPU0/0
#  ipv4 address dhcp
# !
# interface preconfigure GigabitEthernet0/0/0/2
#  ipv4 address 192.168.0.2 255.255.255.0
# !
# interface preconfigure GigabitEthernet0/0/0/3
#  ipv6 address fd5d:12c9:2201:1::1/64
# !

- name: Delete attributes for interfaces (This won't delete the interface itself)
  cisco.iosxr.iosxr_l3_interfaces:
    config:
      - name: GigabitEthernet0/0/0/3
      - name: GigabitEthernet0/0/0/4
      - name: GigabitEthernet0/0/0/3.700
    state: deleted


# Task Output
# -----------
#
# before:
# - name: Loopback888
# - name: Loopback999
# - ipv4:
#   - address: 192.168.0.2/24
#   name: GigabitEthernet0/0/0/2
# - ipv6:
#   - address: fd5d:12c9:2201:1::1/64
#   name: GigabitEthernet0/0/0/3
# commands:
# - interface GigabitEthernet0/0/0/3
# - no ipv6 address
# after:
# - name: Loopback888
# - name: Loopback999
# - ipv4:
#   - address: 192.168.0.2/24
#   name: GigabitEthernet0/0/0/2
# - name: GigabitEthernet0/0/0/3

# After state:
# -------------
#
# viosxr#show running-config interface
# interface Loopback888
# !
# interface Loopback999
# !
# interface MgmtEth0/RP0/CPU0/0
#  ipv4 address dhcp
# !
# interface preconfigure GigabitEthernet0/0/0/2
#  ipv4 address 192.168.0.2 255.255.255.0
# !
# interface preconfigure GigabitEthernet0/0/0/3
# !

# Using deleted - will delete all interface configuration and not interface

# Before state:
# -------------
#
# viosxr#show running-config interface
# interface Loopback888
# !
# interface Loopback999
# !
# interface MgmtEth0/RP0/CPU0/0
#  ipv4 address dhcp
# !
# interface preconfigure GigabitEthernet0/0/0/1
#  ipv4 address 192.168.2.1 255.255.255.0
#  shutdown
# !
# interface preconfigure GigabitEthernet0/0/0/2
#  ipv4 address 192.168.3.1 255.255.255.0
#  shutdown
# !
# interface preconfigure GigabitEthernet0/0/0/3
#  ipv4 address 192.168.0.2 255.255.255.0
#  shutdown
# !
# interface preconfigure GigabitEthernet0/0/0/3.700
#  ipv4 address 192.168.0.1 255.255.255.0
# !
# interface preconfigure GigabitEthernet0/0/0/4
#  ipv6 address fd5d:12c9:2201:1::1/64
#  shutdown
# !

- name: "Delete L3 config of all interfaces (This won't delete the interface itself)"
  cisco.iosxr.iosxr_l3_interfaces:
    state: deleted

# Task Output
# -----------
#
# before:
# - name: Loopback888
# - name: Loopback999
# - ipv4:
#   - address: 192.168.2.1/24
#   name: GigabitEthernet0/0/0/1
# - ipv4:
#   - address: 192.168.3.1/24
#   name: GigabitEthernet0/0/0/2
# - ipv4:
#   - address: 192.168.0.2/24
#   name: GigabitEthernet0/0/0/3
# - ipv4:
#   - address: 192.168.0.1/24
#   name: GigabitEthernet0/0/0/3.700
# - ipv6:
#   - address: fd5d:12c9:2201:1::1/64
#   name: GigabitEthernet0/0/0/4
# commands:
# - interface GigabitEthernet0/0/0/1
# - no ipv4 address
# - interface GigabitEthernet0/0/0/2
# - no ipv4 address
# - interface GigabitEthernet0/0/0/3
# - no ipv4 address
# - interface GigabitEthernet0/0/0/3.700
# - no ipv4 address
# - interface GigabitEthernet0/0/0/4
# - no ipv6 address
# after:
# - name: Loopback888
# - name: Loopback999
# - name: GigabitEthernet0/0/0/1
# - name: GigabitEthernet0/0/0/2
# - name: GigabitEthernet0/0/0/3
# - name: GigabitEthernet0/0/0/3.700
# - name: GigabitEthernet0/0/0/4

# After state:
# -------------
#
# viosxr#show running-config interface
# interface Loopback888
# !
# interface Loopback999
# !
# interface MgmtEth0/RP0/CPU0/0
#  ipv4 address dhcp
# !
# interface preconfigure GigabitEthernet0/0/0/1
#  shutdown
# !
# interface preconfigure GigabitEthernet0/0/0/2
#  shutdown
# !
# interface preconfigure GigabitEthernet0/0/0/3
#  shutdown
# !
# interface preconfigure GigabitEthernet0/0/0/3.700
# !
# interface preconfigure GigabitEthernet0/0/0/4
#  shutdown
# !


# Using parsed

# File: parsed.cfg
# ----------------
#
# interface Loopback888
#  description test for ansible
#  shutdown
# !
# interface MgmtEth0/0/CPU0/0
#  ipv4 address 10.8.38.70 255.255.255.0
# !
# interface GigabitEthernet0/0/0/0
#  description Configured and Merged by Ansible-Network
#  mtu 66
#  ipv4 address 192.0.2.1 255.255.255.0
#  ipv4 address 192.0.2.2 255.255.255.0 secondary
#  ipv6 address 2001:db8:0:3::/64
#  duplex half
# !
# interface GigabitEthernet0/0/0/1
#  description Configured and Merged by Ansible-Network
#  mtu 66
#  speed 100
#  duplex full
#  dot1q native vlan 10
#  l2transport
#   l2protocol cdp forward
#   l2protocol pvst tunnel
#   propagate remote-status
#  !
# !
# interface GigabitEthernet0/0/0/3
#  ipv4 address 192.0.22.1 255.255.255.0
#  ipv4 address 192.0.23.1 255.255.255.0
# !

- name: Convert L3 interfaces config to argspec without connecting to the appliance
  cisco.iosxr.iosxr_l3_interfaces:
    running_config: "{{ lookup('file', './parsed.cfg') }}"
    state: parsed

# Task Output
# -----------
#
# parsed:
# - ipv4:
#   - address: 192.0.2.1 255.255.255.0
#   - address: 192.0.2.2 255.255.255.0
#     secondary: true
#   ipv6:
#   - address: 2001:db8:0:3::/64
#   name: GigabitEthernet0/0/0/0
# - name: GigabitEthernet0/0/0/1
# - ipv4:
#   - address: 192.0.22.1 255.255.255.0
#   - address: 192.0.23.1 255.255.255.0
#   name: GigabitEthernet0/0/0/3

# Using rendered

- name: Render platform specific commands from task input using rendered state
  cisco.iosxr.iosxr_l3_interfaces:
    config:
      - name: GigabitEthernet0/0/0/0
        ipv4:
          - address: 198.51.100.1/24
      - name: GigabitEthernet0/0/0/1
        ipv6:
          - address: '2001:db8:0:3::/64'
        ipv4:
          - address: 192.0.2.1/24
          - address: 192.0.2.2/24
            secondary: true
    state: rendered


# Task Output
# -----------
#
# rendered:
# - interface GigabitEthernet0/0/0/0
# - ipv4 address 198.51.100.1 255.255.255.0
# - interface GigabitEthernet0/0/0/1
# - ipv4 address 192.0.2.2 255.255.255.0 secondary
# - ipv4 address 192.0.2.1 255.255.255.0
# - ipv6 address 2001:db8:0:3::/64

# Using gathered

# Before state:
# ------------
#
# RP/0/0/CPU0:an-iosxr-02#show running-config  interface
# interface Loopback888
#  description test for ansible
#  shutdown
# !
# interface MgmtEth0/0/CPU0/0
#  ipv4 address 10.8.38.70 255.255.255.0
# !
# interface GigabitEthernet0/0/0/0
#  description Configured and Merged by Ansible-Network
#  mtu 66
#  ipv4 address 192.0.2.1 255.255.255.0
#  ipv4 address 192.0.2.2 255.255.255.0 secondary
#  ipv6 address 2001:db8:0:3::/64
#  duplex half
# !
# interface GigabitEthernet0/0/0/1
#  description Configured and Merged by Ansible-Network
#  mtu 66
#  speed 100
#  duplex full
#  dot1q native vlan 10
#  l2transport
#   l2protocol cdp forward
#   l2protocol pvst tunnel
#   propagate remote-status
#  !
# !
# interface GigabitEthernet0/0/0/3
#  shutdown
# !
# interface GigabitEthernet0/0/0/4
#  shutdown
#  dot1q native vlan 40
# !

- name: Gather l3 interfaces facts
  cisco.iosxr.iosxr_l3_interfaces:
    config:
    state: gathered

# Task Output
# -----------
#
# gathered:
# - name: Loopback888
# - ipv4:
#   - address: 192.0.2.1 255.255.255.0
#   - address: 192.0.2.2 255.255.255.0
#     secondary: true
#   ipv6:
#   - address: 2001:db8:0:3::/64
#   name: GigabitEthernet0/0/0/0
# - name: GigabitEthernet0/0/0/1
# - name: GigabitEthernet0/0/0/3
# - name: GigabitEthernet0/0/0/4
"""

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 GigabitEthernet0/0/0/1', 'ipv4 address 192.168.0.1 255.255.255.0']
"""


from ansible.module_utils.basic import AnsibleModule

from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.argspec.l3_interfaces.l3_interfaces import (
    L3_InterfacesArgs,
)
from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.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", "rendered", ("config",)),
        ("state", "overridden", ("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()
