summaryrefslogtreecommitdiff
path: root/lib/ansible/modules/network
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/modules/network')
-rw-r--r--lib/ansible/modules/network/ios/_ios_interface.py495
-rw-r--r--lib/ansible/modules/network/ios/_ios_l2_interface.py499
-rw-r--r--lib/ansible/modules/network/ios/_ios_l3_interface.py327
-rw-r--r--lib/ansible/modules/network/ios/_ios_vlan.py350
-rw-r--r--lib/ansible/modules/network/ios/ios_acl_interfaces.py633
-rw-r--r--lib/ansible/modules/network/ios/ios_acls.py1417
-rw-r--r--lib/ansible/modules/network/ios/ios_banner.py186
-rw-r--r--lib/ansible/modules/network/ios/ios_bgp.py438
-rw-r--r--lib/ansible/modules/network/ios/ios_command.py230
-rw-r--r--lib/ansible/modules/network/ios/ios_config.py567
-rw-r--r--lib/ansible/modules/network/ios/ios_facts.py239
-rw-r--r--lib/ansible/modules/network/ios/ios_interfaces.py405
-rw-r--r--lib/ansible/modules/network/ios/ios_l2_interfaces.py390
-rw-r--r--lib/ansible/modules/network/ios/ios_l3_interfaces.py442
-rw-r--r--lib/ansible/modules/network/ios/ios_lacp.py185
-rw-r--r--lib/ansible/modules/network/ios/ios_lacp_interfaces.py363
-rw-r--r--lib/ansible/modules/network/ios/ios_lag_interfaces.py390
-rw-r--r--lib/ansible/modules/network/ios/ios_linkagg.py318
-rw-r--r--lib/ansible/modules/network/ios/ios_lldp.py112
-rw-r--r--lib/ansible/modules/network/ios/ios_lldp_global.py256
-rw-r--r--lib/ansible/modules/network/ios/ios_lldp_interfaces.py501
-rw-r--r--lib/ansible/modules/network/ios/ios_logging.py429
-rw-r--r--lib/ansible/modules/network/ios/ios_ntp.py308
-rw-r--r--lib/ansible/modules/network/ios/ios_ping.py210
-rw-r--r--lib/ansible/modules/network/ios/ios_static_route.py313
-rw-r--r--lib/ansible/modules/network/ios/ios_static_routes.py710
-rw-r--r--lib/ansible/modules/network/ios/ios_system.py380
-rw-r--r--lib/ansible/modules/network/ios/ios_user.py533
-rw-r--r--lib/ansible/modules/network/ios/ios_vlans.py464
-rw-r--r--lib/ansible/modules/network/ios/ios_vrf.py719
30 files changed, 0 insertions, 12809 deletions
diff --git a/lib/ansible/modules/network/ios/_ios_interface.py b/lib/ansible/modules/network/ios/_ios_interface.py
deleted file mode 100644
index d6241acb16..0000000000
--- a/lib/ansible/modules/network/ios/_ios_interface.py
+++ /dev/null
@@ -1,495 +0,0 @@
-#!/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
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['deprecated'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_interface
-version_added: "2.4"
-author: "Ganesh Nalawade (@ganeshrn)"
-short_description: Manage Interface on Cisco IOS network devices
-description:
- - This module provides declarative management of Interfaces
- on Cisco IOS network devices.
-deprecated:
- removed_in: '2.13'
- alternative: ios_interfaces
- why: Newer and updated modules released with more functionality in Ansible 2.9
-notes:
- - Tested against IOS 15.6
-options:
- name:
- description:
- - Name of the Interface.
- required: true
- description:
- description:
- - Description of Interface.
- enabled:
- description:
- - Interface link status.
- type: bool
- speed:
- description:
- - Interface link speed.
- mtu:
- description:
- - Maximum size of transmit packet.
- duplex:
- description:
- - Interface link status
- default: auto
- choices: ['full', 'half', 'auto']
- tx_rate:
- description:
- - Transmit rate in bits per second (bps).
- - This is state check parameter only.
- - Supports conditionals, see L(Conditionals in Networking Modules,../network/user_guide/network_working_with_command_output.html)
- rx_rate:
- description:
- - Receiver rate in bits per second (bps).
- - This is state check parameter only.
- - Supports conditionals, see L(Conditionals in Networking Modules,../network/user_guide/network_working_with_command_output.html)
- neighbors:
- description:
- - Check the operational state of given interface C(name) for CDP/LLDP neighbor.
- - The following suboptions are available.
- suboptions:
- host:
- description:
- - "CDP/LLDP neighbor host for given interface C(name)."
- port:
- description:
- - "CDP/LLDP neighbor port to which given interface C(name) is connected."
- aggregate:
- description: List of Interfaces definitions.
- delay:
- description:
- - Time in seconds to wait before checking for the operational state on remote
- device. This wait is applicable for operational state argument which are
- I(state) with values C(up)/C(down), I(tx_rate) and I(rx_rate).
- default: 10
- state:
- description:
- - State of the Interface configuration, C(up) means present and
- operationally up and C(down) means present and operationally C(down)
- default: present
- choices: ['present', 'absent', 'up', 'down']
-extends_documentation_fragment: ios
-"""
-
-EXAMPLES = """
-- name: configure interface
- ios_interface:
- name: GigabitEthernet0/2
- description: test-interface
- speed: 100
- duplex: half
- mtu: 512
-
-- name: remove interface
- ios_interface:
- name: Loopback9
- state: absent
-
-- name: make interface up
- ios_interface:
- name: GigabitEthernet0/2
- enabled: True
-
-- name: make interface down
- ios_interface:
- name: GigabitEthernet0/2
- enabled: False
-
-- name: Check intent arguments
- ios_interface:
- name: GigabitEthernet0/2
- state: up
- tx_rate: ge(0)
- rx_rate: le(0)
-
-- name: Check neighbors intent arguments
- ios_interface:
- name: Gi0/0
- neighbors:
- - port: eth0
- host: netdev
-
-- name: Config + intent
- ios_interface:
- name: GigabitEthernet0/2
- enabled: False
- state: down
-
-- name: Add interface using aggregate
- ios_interface:
- aggregate:
- - { name: GigabitEthernet0/1, mtu: 256, description: test-interface-1 }
- - { name: GigabitEthernet0/2, mtu: 516, description: test-interface-2 }
- duplex: full
- speed: 100
- state: present
-
-- name: Delete interface using aggregate
- ios_interface:
- aggregate:
- - name: Loopback9
- - name: Loopback10
- 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:
- - interface GigabitEthernet0/2
- - description test-interface
- - duplex half
- - mtu 512
-"""
-import re
-
-from copy import deepcopy
-from time import sleep
-
-from ansible.module_utils._text import to_text
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.connection import exec_command
-from ansible.module_utils.network.ios.ios import get_config, load_config
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-from ansible.module_utils.network.common.config import NetworkConfig
-from ansible.module_utils.network.common.utils import conditional, remove_default_spec
-
-
-def validate_mtu(value, module):
- if value and not 64 <= int(value) <= 9600:
- module.fail_json(msg='mtu must be between 64 and 9600')
-
-
-def validate_param_values(module, obj, param=None):
- if param is None:
- param = module.params
- for key in obj:
- # validate the param value (if validator func exists)
- validator = globals().get('validate_%s' % key)
- if callable(validator):
- validator(param.get(key), module)
-
-
-def parse_shutdown(configobj, name):
- cfg = configobj['interface %s' % name]
- cfg = '\n'.join(cfg.children)
- match = re.search(r'^shutdown', cfg, re.M)
- if match:
- return True
- else:
- return False
-
-
-def parse_config_argument(configobj, name, arg=None):
- cfg = configobj['interface %s' % name]
- cfg = '\n'.join(cfg.children)
- match = re.search(r'%s (.+)$' % arg, cfg, re.M)
- if match:
- return match.group(1)
-
-
-def search_obj_in_list(name, lst):
- for o in lst:
- if o['name'] == name:
- return o
-
- return None
-
-
-def add_command_to_interface(interface, cmd, commands):
- if interface not in commands:
- commands.append(interface)
- commands.append(cmd)
-
-
-def map_config_to_obj(module):
- config = get_config(module)
- configobj = NetworkConfig(indent=1, contents=config)
-
- match = re.findall(r'^interface (\S+)', config, re.M)
- if not match:
- return list()
-
- instances = list()
-
- for item in set(match):
- obj = {
- 'name': item,
- 'description': parse_config_argument(configobj, item, 'description'),
- 'speed': parse_config_argument(configobj, item, 'speed'),
- 'duplex': parse_config_argument(configobj, item, 'duplex'),
- 'mtu': parse_config_argument(configobj, item, 'mtu'),
- 'disable': True if parse_shutdown(configobj, item) else False,
- 'state': 'present'
- }
- instances.append(obj)
- return instances
-
-
-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]
-
- validate_param_values(module, item, item)
- d = item.copy()
-
- if d['enabled']:
- d['disable'] = False
- else:
- d['disable'] = True
-
- obj.append(d)
-
- else:
- params = {
- 'name': module.params['name'],
- 'description': module.params['description'],
- 'speed': module.params['speed'],
- 'mtu': module.params['mtu'],
- 'duplex': module.params['duplex'],
- 'state': module.params['state'],
- 'delay': module.params['delay'],
- 'tx_rate': module.params['tx_rate'],
- 'rx_rate': module.params['rx_rate'],
- 'neighbors': module.params['neighbors']
- }
-
- validate_param_values(module, params)
- if module.params['enabled']:
- params.update({'disable': False})
- else:
- params.update({'disable': True})
-
- obj.append(params)
- return obj
-
-
-def map_obj_to_commands(updates):
- commands = list()
- want, have = updates
-
- args = ('speed', 'description', 'duplex', 'mtu')
- for w in want:
- name = w['name']
- disable = w['disable']
- state = w['state']
-
- obj_in_have = search_obj_in_list(name, have)
- interface = 'interface ' + name
-
- if state == 'absent' and obj_in_have:
- commands.append('no ' + interface)
-
- elif state in ('present', 'up', 'down'):
- if obj_in_have:
- for item in args:
- candidate = w.get(item)
- running = obj_in_have.get(item)
- if candidate != running:
- if candidate:
- cmd = item + ' ' + str(candidate)
- add_command_to_interface(interface, cmd, commands)
-
- if disable and not obj_in_have.get('disable', False):
- add_command_to_interface(interface, 'shutdown', commands)
- elif not disable and obj_in_have.get('disable', False):
- add_command_to_interface(interface, 'no shutdown', commands)
- else:
- commands.append(interface)
- for item in args:
- value = w.get(item)
- if value:
- commands.append(item + ' ' + str(value))
-
- if disable:
- commands.append('no shutdown')
- return commands
-
-
-def check_declarative_intent_params(module, want, result):
- failed_conditions = []
- have_neighbors_lldp = None
- have_neighbors_cdp = None
- for w in want:
- want_state = w.get('state')
- want_tx_rate = w.get('tx_rate')
- want_rx_rate = w.get('rx_rate')
- want_neighbors = w.get('neighbors')
-
- if want_state not in ('up', 'down') and not want_tx_rate and not want_rx_rate and not want_neighbors:
- continue
-
- if result['changed']:
- sleep(w['delay'])
-
- command = 'show interfaces %s' % w['name']
- rc, out, err = exec_command(module, command)
- if rc != 0:
- module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc)
-
- if want_state in ('up', 'down'):
- match = re.search(r'%s (\w+)' % 'line protocol is', out, re.M)
- have_state = None
- if match:
- have_state = match.group(1)
- if have_state is None or not conditional(want_state, have_state.strip()):
- failed_conditions.append('state ' + 'eq(%s)' % want_state)
-
- if want_tx_rate:
- match = re.search(r'%s (\d+)' % 'output rate', out, re.M)
- have_tx_rate = None
- if match:
- have_tx_rate = match.group(1)
-
- if have_tx_rate is None or not conditional(want_tx_rate, have_tx_rate.strip(), cast=int):
- failed_conditions.append('tx_rate ' + want_tx_rate)
-
- if want_rx_rate:
- match = re.search(r'%s (\d+)' % 'input rate', out, re.M)
- have_rx_rate = None
- if match:
- have_rx_rate = match.group(1)
-
- if have_rx_rate is None or not conditional(want_rx_rate, have_rx_rate.strip(), cast=int):
- failed_conditions.append('rx_rate ' + want_rx_rate)
-
- if want_neighbors:
- have_host = []
- have_port = []
-
- # Process LLDP neighbors
- if have_neighbors_lldp is None:
- rc, have_neighbors_lldp, err = exec_command(module, 'show lldp neighbors detail')
- if rc != 0:
- module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc)
-
- if have_neighbors_lldp:
- lines = have_neighbors_lldp.strip().split('Local Intf: ')
- for line in lines:
- field = line.split('\n')
- if field[0].strip() == w['name']:
- for item in field:
- if item.startswith('System Name:'):
- have_host.append(item.split(':')[1].strip())
- if item.startswith('Port Description:'):
- have_port.append(item.split(':')[1].strip())
-
- # Process CDP neighbors
- if have_neighbors_cdp is None:
- rc, have_neighbors_cdp, err = exec_command(module, 'show cdp neighbors detail')
- if rc != 0:
- module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc)
-
- if have_neighbors_cdp:
- neighbors_cdp = re.findall('Device ID: (.*?)\n.*?Interface: (.*?), Port ID .outgoing port.: (.*?)\n', have_neighbors_cdp, re.S)
- for host, localif, remoteif in neighbors_cdp:
- if localif == w['name']:
- have_host.append(host)
- have_port.append(remoteif)
-
- for item in want_neighbors:
- host = item.get('host')
- port = item.get('port')
- if host and host not in have_host:
- failed_conditions.append('host ' + host)
- if port and port not in have_port:
- failed_conditions.append('port ' + port)
- return failed_conditions
-
-
-def main():
- """ main entry point for module execution
- """
- neighbors_spec = dict(
- host=dict(),
- port=dict()
- )
-
- element_spec = dict(
- name=dict(),
- description=dict(),
- speed=dict(),
- mtu=dict(),
- duplex=dict(choices=['full', 'half', 'auto']),
- enabled=dict(default=True, type='bool'),
- tx_rate=dict(),
- rx_rate=dict(),
- neighbors=dict(type='list', elements='dict', options=neighbors_spec),
- delay=dict(default=10, type='int'),
- state=dict(default='present',
- choices=['present', 'absent', 'up', 'down'])
- )
-
- 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)
-
- argument_spec = dict(
- aggregate=dict(type='list', elements='dict', options=aggregate_spec),
- )
-
- argument_spec.update(element_spec)
- argument_spec.update(ios_argument_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))
- result['commands'] = commands
-
- if commands:
- if not module.check_mode:
- load_config(module, commands)
- result['changed'] = True
-
- failed_conditions = check_declarative_intent_params(module, want, result)
-
- if failed_conditions:
- msg = 'One or more conditional statements have not been satisfied'
- module.fail_json(msg=msg, failed_conditions=failed_conditions)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/_ios_l2_interface.py b/lib/ansible/modules/network/ios/_ios_l2_interface.py
deleted file mode 100644
index 710c435c4e..0000000000
--- a/lib/ansible/modules/network/ios/_ios_l2_interface.py
+++ /dev/null
@@ -1,499 +0,0 @@
-#!/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
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['deprecated'],
- 'supported_by': 'network'}
-
-DOCUMENTATION = """
----
-module: ios_l2_interface
-extends_documentation_fragment: ios
-version_added: "2.5"
-short_description: Manage Layer-2 interface on Cisco IOS devices.
-description:
- - This module provides declarative management of Layer-2 interfaces on
- Cisco IOS devices.
-deprecated:
- removed_in: '2.13'
- alternative: ios_l2_interfaces
- why: Newer and updated modules released with more functionality in Ansible 2.9
-author:
- - Nathaniel Case (@Qalthos)
-options:
- name:
- description:
- - Full name of the interface excluding any logical
- unit number, i.e. GigabitEthernet0/1.
- required: true
- aliases: ['interface']
- mode:
- description:
- - Mode in which interface needs to be configured.
- default: access
- choices: ['access', 'trunk']
- access_vlan:
- description:
- - Configure given VLAN in access port.
- If C(mode=access), used as the access VLAN ID.
- trunk_vlans:
- description:
- - List of VLANs to be configured in trunk port.
- If C(mode=trunk), used as the VLAN range to ADD or REMOVE
- from the trunk.
- native_vlan:
- description:
- - Native VLAN to be configured in trunk port.
- If C(mode=trunk), used as the trunk native VLAN ID.
- trunk_allowed_vlans:
- description:
- - List of allowed VLANs in a given trunk port.
- If C(mode=trunk), these are the only VLANs that will be
- configured on the trunk, i.e. "2-10,15".
- aggregate:
- description:
- - List of Layer-2 interface definitions.
- state:
- description:
- - Manage the state of the Layer-2 Interface configuration.
- default: present
- choices: ['present','absent', 'unconfigured']
-"""
-
-EXAMPLES = """
-- name: Ensure GigabitEthernet0/5 is in its default l2 interface state
- ios_l2_interface:
- name: GigabitEthernet0/5
- state: unconfigured
-- name: Ensure GigabitEthernet0/5 is configured for access vlan 20
- ios_l2_interface:
- name: GigabitEthernet0/5
- mode: access
- access_vlan: 20
-- name: Ensure GigabitEthernet0/5 only has vlans 5-10 as trunk vlans
- ios_l2_interface:
- name: GigabitEthernet0/5
- mode: trunk
- native_vlan: 10
- trunk_allowed_vlans: 5-10
-- name: Ensure GigabitEthernet0/5 is a trunk port and ensure 2-50 are being tagged (doesn't mean others aren't also being tagged)
- ios_l2_interface:
- name: GigabitEthernet0/5
- mode: trunk
- native_vlan: 10
- trunk_vlans: 2-50
-- name: Ensure these VLANs are not being tagged on the trunk
- ios_l2_interface:
- name: GigabitEthernet0/5
- mode: trunk
- trunk_vlans: 51-4094
- 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:
- - interface GigabitEthernet0/5
- - switchport access vlan 20
-"""
-
-import re
-from copy import deepcopy
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.common.utils import remove_default_spec
-from ansible.module_utils.network.ios.ios import load_config, run_commands
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-
-
-def get_interface_type(interface):
- intf_type = 'unknown'
- if interface.upper()[:2] in ('ET', 'GI', 'FA', 'TE', 'FO', 'HU', 'TWE', 'TW'):
- intf_type = 'ethernet'
- elif interface.upper().startswith('VL'):
- intf_type = 'svi'
- elif interface.upper().startswith('LO'):
- intf_type = 'loopback'
- elif interface.upper()[:2] in ('MG', 'MA'):
- intf_type = 'management'
- elif interface.upper().startswith('PO'):
- intf_type = 'portchannel'
- elif interface.upper().startswith('NV'):
- intf_type = 'nve'
-
- return intf_type
-
-
-def is_switchport(name, module):
- intf_type = get_interface_type(name)
-
- if intf_type in ('ethernet', 'portchannel'):
- config = run_commands(module, ['show interface {0} switchport'.format(name)])[0]
- match = re.search(r'Switchport: Enabled', config)
- return bool(match)
- return False
-
-
-def interface_is_portchannel(name, module):
- if get_interface_type(name) == 'ethernet':
- config = run_commands(module, ['show run interface {0}'.format(name)])[0]
- if any(c in config for c in ['channel group', 'channel-group']):
- return True
- return False
-
-
-def get_switchport(name, module):
- config = run_commands(module, ['show interface {0} switchport'.format(name)])[0]
- mode = re.search(r'Administrative Mode: (?:.* )?(\w+)$', config, re.M)
- access = re.search(r'Access Mode VLAN: (\d+)', config)
- native = re.search(r'Trunking Native Mode VLAN: (\d+)', config)
- trunk = re.search(r'Trunking VLANs Enabled: (.+)$', config, re.M)
- if mode:
- mode = mode.group(1)
- if access:
- access = access.group(1)
- if native:
- native = native.group(1)
- if trunk:
- trunk = trunk.group(1)
- if trunk == 'ALL':
- trunk = '1-4094'
-
- switchport_config = {
- "interface": name,
- "mode": mode,
- "access_vlan": access,
- "native_vlan": native,
- "trunk_vlans": trunk,
- }
-
- return switchport_config
-
-
-def remove_switchport_config_commands(name, existing, proposed, module):
- mode = proposed.get('mode')
- commands = []
- command = None
-
- if mode == 'access':
- av_check = existing.get('access_vlan') == proposed.get('access_vlan')
- if av_check:
- command = 'no switchport access vlan {0}'.format(existing.get('access_vlan'))
- commands.append(command)
-
- elif mode == 'trunk':
- # Supported Remove Scenarios for trunk_vlans_list
- # 1) Existing: 1,2,3 Proposed: 1,2,3 - Remove all
- # 2) Existing: 1,2,3 Proposed: 1,2 - Remove 1,2 Leave 3
- # 3) Existing: 1,2,3 Proposed: 2,3 - Remove 2,3 Leave 1
- # 4) Existing: 1,2,3 Proposed: 4,5,6 - None removed.
- # 5) Existing: None Proposed: 1,2,3 - None removed.
- existing_vlans = existing.get('trunk_vlans_list')
- proposed_vlans = proposed.get('trunk_vlans_list')
- vlans_to_remove = set(proposed_vlans).intersection(existing_vlans)
-
- if vlans_to_remove:
- proposed_allowed_vlans = proposed.get('trunk_allowed_vlans')
- remove_trunk_allowed_vlans = proposed.get('trunk_vlans', proposed_allowed_vlans)
- command = 'switchport trunk allowed vlan remove {0}'.format(remove_trunk_allowed_vlans)
- commands.append(command)
-
- native_check = existing.get('native_vlan') == proposed.get('native_vlan')
- if native_check and proposed.get('native_vlan'):
- command = 'no switchport trunk native vlan {0}'.format(existing.get('native_vlan'))
- commands.append(command)
-
- if commands:
- commands.insert(0, 'interface ' + name)
- return commands
-
-
-def get_switchport_config_commands(name, existing, proposed, module):
- """Gets commands required to config a given switchport interface
- """
-
- proposed_mode = proposed.get('mode')
- existing_mode = existing.get('mode')
- commands = []
- command = None
-
- if proposed_mode != existing_mode:
- if proposed_mode == 'trunk':
- command = 'switchport mode trunk'
- elif proposed_mode == 'access':
- command = 'switchport mode access'
-
- if command:
- commands.append(command)
-
- if proposed_mode == 'access':
- av_check = str(existing.get('access_vlan')) == str(proposed.get('access_vlan'))
- if not av_check:
- command = 'switchport access vlan {0}'.format(proposed.get('access_vlan'))
- commands.append(command)
-
- elif proposed_mode == 'trunk':
- tv_check = existing.get('trunk_vlans_list') == proposed.get('trunk_vlans_list')
-
- if not tv_check:
- if proposed.get('allowed'):
- command = 'switchport trunk allowed vlan {0}'.format(proposed.get('trunk_allowed_vlans'))
- commands.append(command)
-
- else:
- existing_vlans = existing.get('trunk_vlans_list')
- proposed_vlans = proposed.get('trunk_vlans_list')
- vlans_to_add = set(proposed_vlans).difference(existing_vlans)
- if vlans_to_add:
- command = 'switchport trunk allowed vlan add {0}'.format(proposed.get('trunk_vlans'))
- commands.append(command)
-
- native_check = str(existing.get('native_vlan')) == str(proposed.get('native_vlan'))
- if not native_check and proposed.get('native_vlan'):
- command = 'switchport trunk native vlan {0}'.format(proposed.get('native_vlan'))
- commands.append(command)
-
- if commands:
- commands.insert(0, 'interface ' + name)
- return commands
-
-
-def is_switchport_default(existing):
- """Determines if switchport has a default config based on mode
- Args:
- existing (dict): existing switchport configuration from Ansible mod
- Returns:
- boolean: True if switchport has OOB Layer 2 config, i.e.
- vlan 1 and trunk all and mode is access
- """
-
- c1 = str(existing['access_vlan']) == '1'
- c2 = str(existing['native_vlan']) == '1'
- c3 = existing['trunk_vlans'] == '1-4094'
- c4 = existing['mode'] == 'access'
-
- default = c1 and c2 and c3 and c4
-
- return default
-
-
-def default_switchport_config(name):
- commands = []
- commands.append('interface ' + name)
- commands.append('switchport mode access')
- commands.append('switch access vlan 1')
- commands.append('switchport trunk native vlan 1')
- commands.append('switchport trunk allowed vlan all')
- return commands
-
-
-def vlan_range_to_list(vlans):
- result = []
- if vlans:
- for part in vlans.split(','):
- if part.lower() == 'none':
- break
- if part:
- if '-' in part:
- start, stop = (int(i) for i in part.split('-'))
- result.extend(range(start, stop + 1))
- else:
- result.append(int(part))
- return sorted(result)
-
-
-def get_list_of_vlans(module):
- config = run_commands(module, ['show vlan'])[0]
- vlans = set()
-
- lines = config.strip().splitlines()
- for line in lines:
- line_parts = line.split()
- if line_parts:
- try:
- int(line_parts[0])
- except ValueError:
- continue
- vlans.add(line_parts[0])
-
- return list(vlans)
-
-
-def flatten_list(commands):
- flat_list = []
- for command in commands:
- if isinstance(command, list):
- flat_list.extend(command)
- else:
- flat_list.append(command)
- return flat_list
-
-
-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]
-
- obj.append(item.copy())
- else:
- obj.append({
- 'name': module.params['name'],
- 'mode': module.params['mode'],
- 'access_vlan': module.params['access_vlan'],
- 'native_vlan': module.params['native_vlan'],
- 'trunk_vlans': module.params['trunk_vlans'],
- 'trunk_allowed_vlans': module.params['trunk_allowed_vlans'],
- 'state': module.params['state']
- })
-
- return obj
-
-
-def main():
- """ main entry point for module execution
- """
- element_spec = dict(
- name=dict(type='str', aliases=['interface']),
- mode=dict(choices=['access', 'trunk']),
- access_vlan=dict(type='str'),
- native_vlan=dict(type='str'),
- trunk_vlans=dict(type='str'),
- trunk_allowed_vlans=dict(type='str'),
- state=dict(choices=['absent', 'present', 'unconfigured'], default='present')
- )
-
- 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),
- )
-
- argument_spec.update(element_spec)
- argument_spec.update(ios_argument_spec)
-
- module = AnsibleModule(argument_spec=argument_spec,
- mutually_exclusive=[['access_vlan', 'trunk_vlans'],
- ['access_vlan', 'native_vlan'],
- ['access_vlan', 'trunk_allowed_vlans']],
- supports_check_mode=True)
-
- warnings = list()
- commands = []
- result = {'changed': False, 'warnings': warnings}
-
- want = map_params_to_obj(module)
- for w in want:
- name = w['name']
- mode = w['mode']
- access_vlan = w['access_vlan']
- state = w['state']
- trunk_vlans = w['trunk_vlans']
- native_vlan = w['native_vlan']
- trunk_allowed_vlans = w['trunk_allowed_vlans']
-
- args = dict(name=name, mode=mode, access_vlan=access_vlan,
- native_vlan=native_vlan, trunk_vlans=trunk_vlans,
- trunk_allowed_vlans=trunk_allowed_vlans)
-
- proposed = dict((k, v) for k, v in args.items() if v is not None)
-
- name = name.lower()
-
- if mode == 'access' and state == 'present' and not access_vlan:
- module.fail_json(msg='access_vlan param is required when mode=access && state=present')
-
- if mode == 'trunk' and access_vlan:
- module.fail_json(msg='access_vlan param not supported when using mode=trunk')
-
- if not is_switchport(name, module):
- module.fail_json(msg='Ensure interface is configured to be a L2'
- '\nport first before using this module. You can use'
- '\nthe ios_interface module for this.')
-
- if interface_is_portchannel(name, module):
- module.fail_json(msg='Cannot change L2 config on physical '
- '\nport because it is in a portchannel. '
- '\nYou should update the portchannel config.')
-
- # existing will never be null for Eth intfs as there is always a default
- existing = get_switchport(name, module)
-
- # Safeguard check
- # If there isn't an existing, something is wrong per previous comment
- if not existing:
- module.fail_json(msg='Make sure you are using the FULL interface name')
-
- if trunk_vlans or trunk_allowed_vlans:
- if trunk_vlans:
- trunk_vlans_list = vlan_range_to_list(trunk_vlans)
- elif trunk_allowed_vlans:
- trunk_vlans_list = vlan_range_to_list(trunk_allowed_vlans)
- proposed['allowed'] = True
-
- existing_trunks_list = vlan_range_to_list((existing['trunk_vlans']))
-
- existing['trunk_vlans_list'] = existing_trunks_list
- proposed['trunk_vlans_list'] = trunk_vlans_list
-
- current_vlans = get_list_of_vlans(module)
-
- if state == 'present':
- if access_vlan and access_vlan not in current_vlans:
- module.fail_json(msg='You are trying to configure a VLAN'
- ' on an interface that\ndoes not exist on the '
- ' switch yet!', vlan=access_vlan)
- elif native_vlan and native_vlan not in current_vlans:
- module.fail_json(msg='You are trying to configure a VLAN'
- ' on an interface that\ndoes not exist on the '
- ' switch yet!', vlan=native_vlan)
- else:
- command = get_switchport_config_commands(name, existing, proposed, module)
- commands.append(command)
- elif state == 'unconfigured':
- is_default = is_switchport_default(existing)
- if not is_default:
- command = default_switchport_config(name)
- commands.append(command)
- elif state == 'absent':
- command = remove_switchport_config_commands(name, existing, proposed, module)
- commands.append(command)
-
- if trunk_vlans or trunk_allowed_vlans:
- existing.pop('trunk_vlans_list')
- proposed.pop('trunk_vlans_list')
-
- cmds = flatten_list(commands)
- if cmds:
- if module.check_mode:
- module.exit_json(changed=True, commands=cmds)
- else:
- result['changed'] = True
- load_config(module, cmds)
- if 'configure' in cmds:
- cmds.pop(0)
-
- result['commands'] = cmds
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/_ios_l3_interface.py b/lib/ansible/modules/network/ios/_ios_l3_interface.py
deleted file mode 100644
index 8435720240..0000000000
--- a/lib/ansible/modules/network/ios/_ios_l3_interface.py
+++ /dev/null
@@ -1,327 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# 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)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['deprecated'],
- 'supported_by': 'network'}
-
-DOCUMENTATION = """
----
-module: ios_l3_interface
-version_added: "2.5"
-author: "Ganesh Nalawade (@ganeshrn)"
-short_description: Manage Layer-3 interfaces on Cisco IOS network devices.
-description:
- - This module provides declarative management of Layer-3 interfaces
- on IOS network devices.
-deprecated:
- removed_in: '2.13'
- alternative: ios_l3_interfaces
- why: Newer and updated modules released with more functionality in Ansible 2.9
-notes:
- - Tested against IOS 15.2
-options:
- name:
- description:
- - Name of the Layer-3 interface to be configured eg. GigabitEthernet0/2
- 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
- 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
- aggregate:
- description:
- - List of Layer-3 interfaces definitions. Each of the entry in aggregate list should
- define name of interface C(name) and a optional C(ipv4) or C(ipv6) address.
- state:
- description:
- - State of the Layer-3 interface configuration. It indicates if the configuration should
- be present or absent on remote device.
- default: present
- choices: ['present', 'absent']
-extends_documentation_fragment: ios
-"""
-
-EXAMPLES = """
-- name: Remove GigabitEthernet0/3 IPv4 and IPv6 address
- ios_l3_interface:
- name: GigabitEthernet0/3
- state: absent
-- name: Set GigabitEthernet0/3 IPv4 address
- ios_l3_interface:
- name: GigabitEthernet0/3
- ipv4: 192.168.0.1/24
-- name: Set GigabitEthernet0/3 IPv6 address
- ios_l3_interface:
- name: GigabitEthernet0/3
- ipv6: "fd5d:12c9:2201:1::1/64"
-- name: Set GigabitEthernet0/3 in dhcp
- ios_l3_interface:
- name: GigabitEthernet0/3
- ipv4: dhcp
- ipv6: dhcp
-- name: Set interface Vlan1 (SVI) IPv4 address
- ios_l3_interface:
- name: Vlan1
- ipv4: 192.168.0.5/24
-- name: Set IP addresses on aggregate
- ios_l3_interface:
- aggregate:
- - { name: GigabitEthernet0/3, ipv4: 192.168.2.10/24 }
- - { name: GigabitEthernet0/3, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
-- name: Remove IP addresses on aggregate
- ios_l3_interface:
- aggregate:
- - { name: GigabitEthernet0/3, ipv4: 192.168.2.10/24 }
- - { name: GigabitEthernet0/3, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
- 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:
- - interface GigabitEthernet0/2
- - ip address 192.168.0.1 255.255.255.0
- - ipv6 address fd5d:12c9:2201:1::1/64
-"""
-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.network.ios.ios import get_config, load_config
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-from ansible.module_utils.network.common.config import NetworkConfig
-from ansible.module_utils.network.common.utils import remove_default_spec
-from ansible.module_utils.network.common.utils import is_netmask, is_masklen, to_netmask, to_masklen
-
-
-def validate_ipv4(value, module):
- if value:
- address = value.split('/')
- if len(address) != 2:
- module.fail_json(msg='address format is <ipv4 address>/<mask>, got invalid format %s' % value)
-
- if not is_masklen(address[1]):
- module.fail_json(msg='invalid value for mask: %s, mask should be in range 0-32' % address[1])
-
-
-def validate_ipv6(value, module):
- if value:
- address = value.split('/')
- if len(address) != 2:
- module.fail_json(msg='address format is <ipv6 address>/<mask>, got invalid format %s' % value)
- else:
- if not 0 <= int(address[1]) <= 128:
- module.fail_json(msg='invalid value for mask: %s, mask should be in range 0-128' % address[1])
-
-
-def validate_param_values(module, obj, param=None):
- if param is None:
- param = module.params
- for key in obj:
- # validate the param value (if validator func exists)
- validator = globals().get('validate_%s' % key)
- if callable(validator):
- validator(param.get(key), module)
-
-
-def parse_config_argument(configobj, name, arg=None):
- cfg = configobj['interface %s' % name]
- cfg = '\n'.join(cfg.children)
-
- values = []
- matches = re.finditer(r'%s (.+)$' % arg, cfg, re.M)
- for match in matches:
- match_str = match.group(1).strip()
- if arg == 'ipv6 address':
- values.append(match_str)
- else:
- values = match_str
- break
-
- return values or None
-
-
-def search_obj_in_list(name, lst):
- for o in lst:
- if o['name'] == name:
- return o
-
- return None
-
-
-def map_obj_to_commands(updates, module):
- commands = list()
- want, have = updates
- for w in want:
- name = w['name']
- ipv4 = w['ipv4']
- ipv6 = w['ipv6']
- state = w['state']
-
- interface = 'interface ' + name
- commands.append(interface)
-
- obj_in_have = search_obj_in_list(name, have)
- if state == 'absent' and obj_in_have:
- if obj_in_have['ipv4']:
- if ipv4:
- address = ipv4.split('/')
- if len(address) == 2:
- ipv4 = '{0} {1}'.format(address[0], to_netmask(address[1]))
- commands.append('no ip address {0}'.format(ipv4))
- else:
- commands.append('no ip address')
- if obj_in_have['ipv6']:
- if ipv6:
- commands.append('no ipv6 address {0}'.format(ipv6))
- else:
- commands.append('no ipv6 address')
- if 'dhcp' in obj_in_have['ipv6']:
- commands.append('no ipv6 address dhcp')
-
- elif state == 'present':
- if ipv4:
- if obj_in_have is None or obj_in_have.get('ipv4') is None or ipv4 != obj_in_have['ipv4']:
- address = ipv4.split('/')
- if len(address) == 2:
- ipv4 = '{0} {1}'.format(address[0], to_netmask(address[1]))
- commands.append('ip address {0}'.format(ipv4))
-
- if ipv6:
- if obj_in_have is None or obj_in_have.get('ipv6') is None or ipv6.lower() not in [addr.lower() for addr in obj_in_have['ipv6']]:
- commands.append('ipv6 address {0}'.format(ipv6))
-
- if commands[-1] == interface:
- commands.pop(-1)
-
- return commands
-
-
-def map_config_to_obj(module):
- config = get_config(module)
- configobj = NetworkConfig(indent=1, contents=config)
-
- match = re.findall(r'^interface (\S+)', config, re.M)
- if not match:
- return list()
-
- instances = list()
-
- for item in set(match):
- ipv4 = parse_config_argument(configobj, item, 'ip address')
- if ipv4:
- # eg. 192.168.2.10 255.255.255.0 -> 192.168.2.10/24
- address = ipv4.strip().split(' ')
- if len(address) == 2 and is_netmask(address[1]):
- ipv4 = '{0}/{1}'.format(address[0], to_text(to_masklen(address[1])))
-
- obj = {
- 'name': item,
- 'ipv4': ipv4,
- 'ipv6': parse_config_argument(configobj, item, 'ipv6 address'),
- 'state': 'present'
- }
- instances.append(obj)
-
- return instances
-
-
-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]
-
- validate_param_values(module, item, item)
- obj.append(item.copy())
- else:
- obj.append({
- 'name': module.params['name'],
- 'ipv4': module.params['ipv4'],
- 'ipv6': module.params['ipv6'],
- 'state': module.params['state']
- })
-
- validate_param_values(module, obj)
-
- return obj
-
-
-def main():
- """ main entry point for module execution
- """
- element_spec = dict(
- name=dict(),
- ipv4=dict(),
- ipv6=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)
-
- argument_spec = dict(
- aggregate=dict(type='list', elements='dict', options=aggregate_spec),
- )
-
- argument_spec.update(element_spec)
- argument_spec.update(ios_argument_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}
-
- 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:
- if not module.check_mode:
- resp = load_config(module, commands)
- warnings.extend((out for out in resp if out))
-
- result['changed'] = True
-
- if warnings:
- result['warnings'] = warnings
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/_ios_vlan.py b/lib/ansible/modules/network/ios/_ios_vlan.py
deleted file mode 100644
index d2b3dcf043..0000000000
--- a/lib/ansible/modules/network/ios/_ios_vlan.py
+++ /dev/null
@@ -1,350 +0,0 @@
-#!/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
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['deprecated'],
- 'supported_by': 'network'}
-
-DOCUMENTATION = """
----
-module: ios_vlan
-version_added: "2.5"
-author: "Trishna Guha (@trishnaguha)"
-short_description: Manage VLANs on IOS network devices
-description:
- - This module provides declarative management of VLANs
- on Cisco IOS network devices.
-deprecated:
- removed_in: '2.13'
- alternative: ios_vlans
- why: Newer and updated modules released with more functionality in Ansible 2.9
-notes:
- - Tested against IOS 15.2
-options:
- name:
- description:
- - Name of the VLAN.
- vlan_id:
- description:
- - ID of the VLAN. Range 1-4094.
- required: true
- interfaces:
- description:
- - List of interfaces that should be associated to the VLAN.
- required: true
- associated_interfaces:
- description:
- - This is a intent option and checks the operational state of the for given vlan C(name)
- for associated interfaces. If the value in the C(associated_interfaces) does not match with
- the operational state of vlan interfaces on device it will result in failure.
- version_added: "2.5"
- delay:
- description:
- - Delay the play should wait to check for declarative intent params values.
- default: 10
- aggregate:
- description: List of VLANs definitions.
- purge:
- description:
- - Purge VLANs not defined in the I(aggregate) parameter.
- default: no
- type: bool
- state:
- description:
- - State of the VLAN configuration.
- default: present
- choices: ['present', 'absent', 'active', 'suspend']
-extends_documentation_fragment: ios
-"""
-
-EXAMPLES = """
-- name: Create vlan
- ios_vlan:
- vlan_id: 100
- name: test-vlan
- state: present
-
-- name: Add interfaces to VLAN
- ios_vlan:
- vlan_id: 100
- interfaces:
- - GigabitEthernet0/0
- - GigabitEthernet0/1
-
-- name: Check if interfaces is assigned to VLAN
- ios_vlan:
- vlan_id: 100
- associated_interfaces:
- - GigabitEthernet0/0
- - GigabitEthernet0/1
-
-- name: Delete vlan
- ios_vlan:
- vlan_id: 100
- state: absent
-
-- name: Add vlan using aggregate
- ios_vlan:
- aggregate:
- - { vlan_id: 100, name: test-vlan, interfaces: [GigabitEthernet0/1, GigabitEthernet0/2], delay: 15, state: suspend }
- - { vlan_id: 101, name: test-vlan, interfaces: GigabitEthernet0/3 }
-
-- name: Move interfaces to a different VLAN
- ios_vlan:
- vlan_id: 102
- interfaces:
- - GigabitEthernet0/0
- - GigabitEthernet0/1
-"""
-
-RETURN = """
-commands:
- description: The list of configuration mode commands to send to the device
- returned: always
- type: list
- sample:
- - vlan 100
- - name test-vlan
-"""
-
-import re
-import time
-
-from copy import deepcopy
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.common.utils import remove_default_spec
-from ansible.module_utils.network.ios.ios import load_config, run_commands, normalize_interface
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-
-
-def search_obj_in_list(vlan_id, lst):
- for o in lst:
- if o['vlan_id'] == vlan_id:
- return o
-
-
-def map_obj_to_commands(updates, module):
- commands = list()
- want, have = updates
- purge = module.params['purge']
-
- for w in want:
- vlan_id = w['vlan_id']
- name = w['name']
- interfaces = w['interfaces']
- state = w['state']
-
- obj_in_have = search_obj_in_list(vlan_id, have)
-
- if state == 'absent':
- if obj_in_have:
- commands.append('no vlan {0}'.format(vlan_id))
-
- elif state == 'present':
- if not obj_in_have:
- commands.append('vlan {0}'.format(vlan_id))
- if name:
- commands.append('name {0}'.format(name))
-
- if interfaces:
- for i in interfaces:
- commands.append('interface {0}'.format(i))
- commands.append('switchport mode access')
- commands.append('switchport access vlan {0}'.format(vlan_id))
-
- else:
- if name:
- if name != obj_in_have['name']:
- commands.append('vlan {0}'.format(vlan_id))
- commands.append('name {0}'.format(name))
-
- if interfaces:
- if not obj_in_have['interfaces']:
- for i in interfaces:
- commands.append('vlan {0}'.format(vlan_id))
- commands.append('interface {0}'.format(i))
- commands.append('switchport mode access')
- commands.append('switchport access vlan {0}'.format(vlan_id))
-
- elif set(interfaces) != set(obj_in_have['interfaces']):
- missing_interfaces = list(set(interfaces) - set(obj_in_have['interfaces']))
- for i in missing_interfaces:
- commands.append('vlan {0}'.format(vlan_id))
- commands.append('interface {0}'.format(i))
- commands.append('switchport mode access')
- commands.append('switchport access vlan {0}'.format(vlan_id))
-
- superfluous_interfaces = list(set(obj_in_have['interfaces']) - set(interfaces))
- for i in superfluous_interfaces:
- commands.append('vlan {0}'.format(vlan_id))
- commands.append('interface {0}'.format(i))
- commands.append('switchport mode access')
- commands.append('no switchport access vlan {0}'.format(vlan_id))
- else:
- commands.append('vlan {0}'.format(vlan_id))
- if name:
- commands.append('name {0}'.format(name))
- commands.append('state {0}'.format(state))
-
- if purge:
- for h in have:
- obj_in_want = search_obj_in_list(h['vlan_id'], want)
- if not obj_in_want and h['vlan_id'] != '1':
- commands.append('no vlan {0}'.format(h['vlan_id']))
-
- return commands
-
-
-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]
-
- d = item.copy()
- d['vlan_id'] = str(d['vlan_id'])
-
- obj.append(d)
- else:
- obj.append({
- 'vlan_id': str(module.params['vlan_id']),
- 'name': module.params['name'],
- 'interfaces': module.params['interfaces'],
- 'associated_interfaces': module.params['associated_interfaces'],
- 'state': module.params['state']
- })
-
- return obj
-
-
-def parse_to_logical_rows(out):
- started_yielding = False
- cur_row = []
- for l in out.splitlines()[2:]:
- if not l:
- """Skip empty lines."""
- continue
- if '0' < l[0] <= '9':
- """Line starting with a number."""
- if started_yielding:
- yield cur_row
- cur_row = [] # Reset it to hold a next chunk
- started_yielding = True
- cur_row.append(l)
-
- # Return the rest of it:
- yield cur_row
-
-
-def map_ports_str_to_list(ports_str):
- return list(filter(bool, (normalize_interface(p.strip()) for p in ports_str.split(', '))))
-
-
-def parse_to_obj(logical_rows):
- first_row = logical_rows[0]
- rest_rows = logical_rows[1:]
- obj = re.match(r'(?P<vlan_id>\d+)\s+(?P<name>[^\s]+)\s+(?P<state>[^\s]+)\s*(?P<interfaces>.*)', first_row).groupdict()
- if obj['state'] == 'suspended':
- obj['state'] = 'suspend'
- obj['interfaces'] = map_ports_str_to_list(obj['interfaces'])
- obj['interfaces'].extend(prts_r for prts in rest_rows for prts_r in map_ports_str_to_list(prts))
- return obj
-
-
-def parse_vlan_brief(vlan_out):
- return [parse_to_obj(r) for r in parse_to_logical_rows(vlan_out)]
-
-
-def map_config_to_obj(module):
- return parse_vlan_brief(run_commands(module, ['show vlan brief'])[0])
-
-
-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['vlan_id'], have)
- if obj_in_have and 'interfaces' in obj_in_have and i not in obj_in_have['interfaces']:
- module.fail_json(msg="Interface %s not configured on vlan %s" % (i, w['vlan_id']))
-
-
-def main():
- """ main entry point for module execution
- """
- element_spec = dict(
- vlan_id=dict(type='int'),
- name=dict(),
- interfaces=dict(type='list'),
- associated_interfaces=dict(type='list'),
- delay=dict(default=10, type='int'),
- state=dict(default='present',
- choices=['present', 'absent', 'active', 'suspend'])
- )
-
- aggregate_spec = deepcopy(element_spec)
- aggregate_spec['vlan_id'] = dict(required=True)
-
- # 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),
- purge=dict(default=False, type='bool')
- )
-
- argument_spec.update(element_spec)
- argument_spec.update(ios_argument_spec)
-
- required_one_of = [['vlan_id', 'aggregate']]
- mutually_exclusive = [['vlan_id', '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:
- if not module.check_mode:
- load_config(module, commands)
- result['changed'] = True
-
- check_declarative_intent_params(want, module, result)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_acl_interfaces.py b/lib/ansible/modules/network/ios/ios_acl_interfaces.py
deleted file mode 100644
index 7286ac45a8..0000000000
--- a/lib/ansible/modules/network/ios/ios_acl_interfaces.py
+++ /dev/null
@@ -1,633 +0,0 @@
-#!/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 ios_acl_interfaces
-"""
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-DOCUMENTATION = """
----
-module: ios_acl_interfaces
-version_added: '2.10'
-short_description: Configure and manage access-control (ACL) attributes of interfaces on IOS devices.
-description: This module configures and manages the access-control (ACL) attributes of interfaces on IOS platforms.
-author: Sumit Jaiswal (@justjais)
-notes:
- - Tested against Cisco IOSv Version 15.2 on VIRL
- - This module works with connection C(network_cli).
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: A dictionary of ACL interfaces 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
- access_groups:
- description: Specify access-group for IP access list (standard or extended).
- type: list
- elements: dict
- suboptions:
- afi:
- description: Specifies the AFI for the ACLs to be configured on this interface.
- type: str
- required: True
- choices:
- - ipv4
- - ipv6
- acls:
- description: Specifies the ACLs for the provided AFI.
- type: list
- 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.
- - With one direction already assigned, other acl direction cannot be same.
- type: str
- required: True
- choices:
- - in
- - out
- 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:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# interface GigabitEthernet0/2
-# ip access-group 123 out
-
-- name: "Merge module attributes of given access-groups"
- ios_acl_interfaces:
- config:
- - name: GigabitEthernet0/1
- access_groups:
- - afi: ipv4
- acls:
- - name: 110
- direction: in
- - name: 123
- direction: out
- - afi: ipv6
- acls:
- - name: test_v6
- direction: out
- - name: temp_v6
- direction: in
- - name: GigabitEthernet0/2
- access_groups:
- - afi: ipv4
- acls:
- - name: 100
- direction: in
- state: merged
-
-# Commands Fired:
-# ---------------
-#
-# interface GigabitEthernet0/1
-# ip access-group 110 in
-# ip access-group 123 out
-# ipv6 traffic-filter test_v6 out
-# ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# ip access-group 100 in
-# ip access-group 123 out
-
-
-# After state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ip access-group 110 in
-# ip access-group 123 out
-# ipv6 traffic-filter test_v6 out
-# ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-# Using Replaced
-
-# Before state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ip access-group 110 in
-# ip access-group 123 out
-# ipv6 traffic-filter test_v6 out
-# ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-- name: "Replace module attributes of given access-groups"
- ios_acl_interfaces:
- config:
- - name: GigabitEthernet0/1
- access_groups:
- - afi: ipv4
- acls:
- - name: 100
- direction: out
- - name: 110
- direction: in
- state: replaced
-
-# Commands Fired:
-# ---------------
-#
-# interface GigabitEthernet0/1
-# no ip access-group 123 out
-# no ipv6 traffic-filter temp_v6 in
-# no ipv6 traffic-filter test_v6 out
-# ip access-group 100 out
-
-# After state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ip access-group 100 out
-# ip access-group 110 in
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-# Using Overridden
-
-# Before state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ip access-group 110 in
-# ip access-group 123 out
-# ipv6 traffic-filter test_v6 out
-# ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-- name: "Overridden module attributes of given access-groups"
- ios_acl_interfaces:
- config:
- - name: GigabitEthernet0/1
- access_groups:
- - afi: ipv4
- acls:
- - name: 100
- direction: out
- - name: 110
- direction: in
- state: overridden
-
-# Commands Fired:
-# ---------------
-#
-# interface GigabitEthernet0/1
-# no ip access-group 123 out
-# no ipv6 traffic-filter test_v6 out
-# no ipv6 traffic-filter temp_v6 in
-# ip access-group 100 out
-# interface GigabitEthernet0/2
-# no ip access-group 110 in
-# no ip access-group 123 out
-
-# After state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ip access-group 100 out
-# ip access-group 110 in
-# interface GigabitEthernet0/2
-
-# Using Deleted
-
-# Before state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ip access-group 110 in
-# ip access-group 123 out
-# ipv6 traffic-filter test_v6 out
-# ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-- name: "Delete module attributes of given Interface"
- ios_acl_interfaces:
- config:
- - name: GigabitEthernet0/1
- state: deleted
-
-# Commands Fired:
-# ---------------
-#
-# interface GigabitEthernet0/1
-# no ip access-group 110 in
-# no ip access-group 123 out
-# no ipv6 traffic-filter test_v6 out
-# no ipv6 traffic-filter temp_v6 in
-
-# After state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-# Before state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ip access-group 110 in
-# ip access-group 123 out
-# ipv6 traffic-filter test_v6 out
-# ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-- name: "Delete module attributes of given Interface based on AFI"
- ios_acl_interfaces:
- config:
- - name: GigabitEthernet0/1
- access_groups:
- - afi: ipv4
- state: deleted
-
-# Commands Fired:
-# ---------------
-#
-# interface GigabitEthernet0/1
-# no ip access-group 110 in
-# no ip access-group 123 out
-
-# After state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ipv6 traffic-filter test_v6 out
-# ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-# Using DELETED without any config passed
-#"(NOTE: This will delete all of configured resource module attributes from each configured interface)"
-
-# Before state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ip access-group 110 in
-# ip access-group 123 out
-# ipv6 traffic-filter test_v6 out
-# ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-- name: "Delete module attributes of given access-groups from ALL Interfaces"
- ios_acl_interfaces:
- config:
- state: deleted
-
-# Commands Fired:
-# ---------------
-#
-# interface GigabitEthernet0/1
-# no ip access-group 110 in
-# no ip access-group 123 out
-# no ipv6 traffic-filter test_v6 out
-# no ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# no ip access-group 110 out
-# no ip access-group 123 out
-
-# After state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# interface GigabitEthernet0/2
-
-# Using Gathered
-
-# Before state:
-# -------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ip access-group 110 in
-# ip access-group 123 out
-# ipv6 traffic-filter test_v6 out
-# ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-- name: Gather listed acl interfaces with provided configurations
- ios_acl_interfaces:
- config:
- state: gathered
-
-# Module Execution Result:
-# ------------------------
-#
-# "gathered": [
-# {
-# "name": "Loopback888"
-# },
-# {
-# "name": "GigabitEthernet0/0"
-# },
-# {
-# "access_groups": [
-# {
-# "acls": [
-# {
-# "direction": "in",
-# "name": "110"
-# },
-# {
-# "direction": "out",
-# "name": "123"
-# }
-# ],
-# "afi": "ipv4"
-# },
-# {
-# "acls": [
-# {
-# "direction": "in",
-# "name": "temp_v6"
-# },
-# {
-# "direction": "out",
-# "name": "test_v6"
-# }
-# ],
-# "afi": "ipv6"
-# }
-# ],
-# "name": "GigabitEthernet0/1"
-# },
-# {
-# "access_groups": [
-# {
-# "acls": [
-# {
-# "direction": "in",
-# "name": "100"
-# },
-# {
-# "direction": "out",
-# "name": "123"
-# }
-# ],
-# "afi": "ipv4"
-# }
-# ],
-# "name": "GigabitEthernet0/2"
-# }
-# ]
-
-# After state:
-# ------------
-#
-# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter
-# interface Loopback888
-# interface GigabitEthernet0/0
-# interface GigabitEthernet0/1
-# ip access-group 110 in
-# ip access-group 123 out
-# ipv6 traffic-filter test_v6 out
-# ipv6 traffic-filter temp_v6 in
-# interface GigabitEthernet0/2
-# ip access-group 110 in
-# ip access-group 123 out
-
-# Using Rendered
-
-- name: Render the commands for provided configuration
- ios_acl_interfaces:
- config:
- - name: GigabitEthernet0/1
- access_groups:
- - afi: ipv4
- acls:
- - name: 110
- direction: in
- - name: 123
- direction: out
- - afi: ipv6
- acls:
- - name: test_v6
- direction: out
- - name: temp_v6
- direction: in
- state: rendered
-
-# Module Execution Result:
-# ------------------------
-#
-# "rendered": [
-# "interface GigabitEthernet0/1",
-# "ip access-group 110 in",
-# "ip access-group 123 out",
-# "ipv6 traffic-filter temp_v6 in",
-# "ipv6 traffic-filter test_v6 out"
-# ]
-
-# Using Parsed
-
-- name: Parse the commands for provided configuration
- ios_acl_interfaces:
- running_config:
- "interface GigabitEthernet0/1
- ip access-group 110 in
- ip access-group 123 out
- ipv6 traffic-filter temp_v6 in
- ipv6 traffic-filter test_v6 out"
- state: parsed
-
-# Module Execution Result:
-# ------------------------
-#
-# "parsed": [
-# {
-# "access_groups": [
-# {
-# "acls": [
-# {
-# "direction": "in",
-# "name": "110"
-# }
-# ],
-# "afi": "ipv4"
-# },
-# {
-# "acls": [
-# {
-# "direction": "in",
-# "name": "temp_v6"
-# }
-# ],
-# "afi": "ipv6"
-# }
-# ],
-# "name": "GigabitEthernet0/1"
-# }
-# ]
-
-"""
-
-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/1', 'ip access-group 110 in', 'ipv6 traffic-filter test_v6 out']
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.acl_interfaces.acl_interfaces import Acl_InterfacesArgs
-from ansible.module_utils.network.ios.config.acl_interfaces.acl_interfaces import Acl_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=Acl_InterfacesArgs.argument_spec,
- required_if=required_if,
- mutually_exclusive=mutually_exclusive,
- supports_check_mode=True)
-
- result = Acl_Interfaces(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_acls.py b/lib/ansible/modules/network/ios/ios_acls.py
deleted file mode 100644
index a05214d8e1..0000000000
--- a/lib/ansible/modules/network/ios/ios_acls.py
+++ /dev/null
@@ -1,1417 +0,0 @@
-#!/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 ios_acls
-"""
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_acls
-version_added: '2.10'
-short_description: Manages named or numbered ACLs on IOS devices.
-description: This module configures and manages the named or numbered ACLs on IOS platforms.
-author: Sumit Jaiswal (@justjais)
-notes:
-- Tested against Cisco IOSv Version 15.2 on VIRL
-- This module works with connection C(network_cli).
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: A dictionary of ACL options.
- type: list
- elements: dict
- suboptions:
- afi:
- description:
- - The Address Family Indicator (AFI) for the Access Control Lists (ACL).
- required: true
- type: str
- choices:
- - ipv4
- - ipv6
- acls:
- description:
- - A list of Access Control Lists (ACL).
- type: list
- elements: dict
- suboptions:
- name:
- description: The name or the number of the ACL.
- required: true
- type: str
- acl_type:
- description:
- - ACL type
- - Note, it's mandatory and required for Named ACL, but for
- Numbered ACL it's not mandatory.
- type: str
- choices:
- - extended
- - standard
- aces:
- description: The entries within the ACL.
- elements: dict
- type: list
- suboptions:
- grant:
- description: Specify the action.
- type: str
- choices:
- - permit
- - deny
- sequence:
- description:
- - Sequence Number for the Access Control Entry(ACE).
- - Refer to vendor documentation for valid values.
- type: int
- protocol:
- description:
- - Specify the protocol to match.
- - Refer to vendor documentation for valid values.
- type: str
- protocol_options:
- description: protocol type.
- type: dict
- suboptions:
- protocol_number:
- description: An IP protocol number
- type: int
- ahp:
- description: Authentication Header Protocol.
- type: bool
- eigrp:
- description: Cisco's EIGRP routing protocol.
- type: bool
- esp:
- description: Encapsulation Security Payload.
- type: bool
- gre:
- description: Cisco's GRE tunneling.
- type: bool
- hbh:
- description: Hop by Hop options header. Valid for IPV6
- type: bool
- icmp:
- description: Internet Control Message Protocol.
- 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_request
- type: bool
- 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
- igmp:
- description: Internet Gateway Message Protocol.
- type: dict
- suboptions:
- dvmrp:
- description: Distance Vector Multicast Routing Protocol(2)
- type: bool
- host_query:
- description: IGMP Membership Query(0)
- type: bool
- mtrace_resp:
- description: Multicast Traceroute Response(7)
- type: bool
- mtrace_route:
- description: Multicast Traceroute(8)
- type: bool
- pim:
- description: Protocol Independent Multicast(3)
- type: bool
- trace:
- description: Multicast trace(4)
- type: bool
- v1host_report:
- description: IGMPv1 Membership Report(1)
- type: bool
- v2host_report:
- description: IGMPv2 Membership Report(5)
- type: bool
- v2leave_group:
- description: IGMPv2 Leave Group(6)
- type: bool
- v3host_report:
- description: IGMPv3 Membership Report(9)
- type: bool
- ip:
- description: Any Internet Protocol.
- type: bool
- ipv6:
- description: Any IPv6.
- type: bool
- ipinip:
- description: IP in IP tunneling.
- type: bool
- nos:
- description: KA9Q NOS compatible IP over IP tunneling.
- type: bool
- ospf:
- description: OSPF routing protocol.
- type: bool
- pcp:
- description: Payload Compression Protocol.
- type: bool
- pim:
- description: Protocol Independent Multicast.
- type: bool
- sctp:
- description: Stream Control Transmission Protocol.
- type: bool
- udp:
- description: User Datagram Protocol.
- type: bool
- tcp:
- 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
- source:
- description: Specify the packet source.
- type: dict
- suboptions:
- address:
- description: Source network address.
- type: str
- wildcard_bits:
- description: Destination wildcard bits, valid with IPV4 address.
- type: str
- any:
- description: Match any source address.
- type: bool
- host:
- description: A single source host
- type: str
- port_protocol:
- description:
- - Specify the destination port along with protocol.
- - Note, Valid with TCP/UDP protocol_options
- type: dict
- suboptions:
- eq:
- description: Match only packets on a given port number.
- type: str
- gt:
- description: Match only packets with a greater port number.
- type: str
- lt:
- description: Match only packets with a lower port number.
- type: str
- neq:
- description: Match only packets not on a given port number.
- type: str
- range:
- description: Port group.
- type: dict
- suboptions:
- start:
- description: Specify the start of the port range.
- type: int
- end:
- description: Specify the end of the port range.
- type: int
- destination:
- description: Specify the packet destination.
- type: dict
- suboptions:
- address:
- description: Host address to match, or any single host address.
- type: str
- wildcard_bits:
- description: Destination wildcard bits, valid with IPV4 address.
- type: str
- any:
- description: Match any source address.
- type: bool
- host:
- description: A single destination host
- type: str
- port_protocol:
- description:
- - Specify the destination port along with protocol.
- - Note, Valid with TCP/UDP protocol_options
- type: dict
- suboptions:
- eq:
- description: Match only packets on a given port number.
- type: str
- gt:
- description: Match only packets with a greater port number.
- type: str
- lt:
- description: Match only packets with a lower port number.
- type: str
- neq:
- description: Match only packets not on a given port number.
- type: str
- range:
- description: Port group.
- type: dict
- suboptions:
- start:
- description: Specify the start of the port range.
- type: int
- end:
- description: Specify the end of the port range.
- type: int
- dscp:
- description: Match packets with given dscp value.
- type: str
- fragments:
- description: Check non-initial fragments.
- type: str
- log:
- description: Log matches against this entry.
- type: str
- log_input:
- description: Log matches against this entry, including input interface.
- type: str
- option:
- description:
- - Match packets with given IP Options value.
- - Valid only for named acls.
- type: dict
- suboptions:
- add_ext:
- description: Match packets with Address Extension Option (147).
- type: bool
- any_options:
- description: Match packets with ANY Option.
- type: bool
- com_security:
- description: Match packets with Commercial Security Option (134).
- type: bool
- dps:
- description: Match packets with Dynamic Packet State Option (151).
- type: bool
- encode:
- description: Match packets with Encode Option (15).
- type: bool
- eool:
- description: Match packets with End of Options (0).
- type: bool
- ext_ip:
- description: Match packets with Extended IP Option (145).
- type: bool
- ext_security:
- description: Match packets with Extended Security Option (133).
- type: bool
- finn:
- description: Match packets with Experimental Flow Control Option (205).
- type: bool
- imitd:
- description: Match packets with IMI Traffic Desriptor Option (144).
- type: bool
- lsr:
- description: Match packets with Loose Source Route Option (131).
- type: bool
- mtup:
- description: Match packets with MTU Probe Option (11).
- type: bool
- mtur:
- description: Match packets with MTU Reply Option (12).
- type: bool
- no_op:
- description: Match packets with No Operation Option (1).
- type: bool
- nsapa:
- description: Match packets with NSAP Addresses Option (150).
- type: bool
- record_route:
- description: Match packets with Record Route Option (7).
- type: bool
- router_alert:
- description: Match packets with Router Alert Option (148).
- type: bool
- sdb:
- description: Match packets with Selective Directed Broadcast Option (149).
- type: bool
- security:
- description: Match packets with Basic Security Option (130).
- type: bool
- ssr:
- description: Match packets with Strict Source Routing Option (137).
- type: bool
- stream_id:
- description: Match packets with Stream ID Option (136).
- type: bool
- timestamp:
- description: Match packets with Time Stamp Option (68).
- type: bool
- traceroute:
- description: Match packets with Trace Route Option (82).
- type: bool
- ump:
- description: Match packets with Upstream Multicast Packet Option (152).
- type: bool
- visa:
- description: Match packets with Experimental Access Control Option (142).
- type: bool
- zsu:
- description: Match packets with Experimental Measurement Option (10).
- type: bool
- precedence:
- description: Match packets with given precedence value.
- type: int
- time_range:
- description: Specify a time-range.
- type: str
- tos:
- description:
- - Match packets with given TOS value.
- - Note, DSCP and TOS are mutually exclusive
- type: dict
- suboptions:
- service_value:
- description: Type of service value
- type: int
- max_reliability:
- description: Match packets with max reliable TOS (2).
- type: bool
- max_throughput:
- description: Match packets with max throughput TOS (4).
- type: bool
- min_delay :
- description: Match packets with min delay TOS (8).
- type: bool
- min_monetary_cost:
- description: Match packets with min monetary cost TOS (1).
- type: bool
- normal:
- description: Match packets with normal TOS (0).
- type: bool
- ttl:
- description: Match packets with given TTL value.
- type: dict
- suboptions:
- eq:
- description: Match only packets on a given TTL number.
- type: int
- gt:
- description: Match only packets with a greater TTL number.
- type: int
- lt:
- description: Match only packets with a lower TTL number.
- type: int
- neq:
- description: Match only packets not on a given TTL number.
- type: int
- range:
- description: Match only packets in the range of TTLs.
- type: dict
- suboptions:
- start:
- description: Specify the start of the port range.
- type: int
- end:
- description: Specify the end of the port range.
- type: int
- 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.
- type: str
- state:
- choices:
- - merged
- - replaced
- - overridden
- - deleted
- - gathered
- - rendered
- - parsed
- default: merged
- description:
- - The state of the configuration after module completion
- type: str
-"""
-
-EXAMPLES = """
----
-
-# Using merged
-
-# Before state:
-# -------------
-#
-# vios#sh access-lists
-# Extended IP access list 110
-# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10
-
-- name: Merge provided configuration with device configuration
- ios_acl:
- config:
- - afi: ipv4
- acls:
- - name: std_acl
- acl_type: standard
- aces:
- - grant: deny
- source:
- address: 192.168.1.200
- - grant: deny
- source:
- address: 192.168.2.0
- wildcard_bits: 0.0.0.255
- - name: 110
- aces:
- - grant: deny
- sequence: 10
- protocol_options:
- icmp:
- traceroute: true
- source:
- address: 192.0.2.0
- wildcard_bits: 0.0.0.255
- destination:
- address: 192.0.3.0
- wildcard_bits: 0.0.0.255
- dscp: ef
- ttl:
- eq: 10
- - grant: deny
- protocol_options:
- tcp:
- ack: true
- source:
- host: 198.51.100.0
- destination:
- host: 198.51.110.0
- port_protocol:
- eq: telnet
- - name: test
- acl_type: extended
- aces:
- - grant: deny
- protocol_options:
- tcp:
- fin: true
- source:
- address: 192.0.2.0
- wildcard_bits: 0.0.0.255
- destination:
- address: 192.0.3.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: www
- option:
- traceroute: true
- ttl:
- eq: 10
- - name: 123
- aces:
- - grant: deny
- protocol_options:
- tcp:
- ack: true
- source:
- address: 198.51.100.0
- wildcard_bits: 0.0.0.255
- destination:
- address: 198.51.101.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: telnet
- tos:
- service_value: 12
- - grant: deny
- protocol_options:
- tcp:
- ack: true
- source:
- address: 192.0.3.0
- wildcard_bits: 0.0.0.255
- destination:
- address: 192.0.4.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: www
- dscp: ef
- ttl:
- lt: 20
- - afi: ipv6
- acls:
- - name: R1_TRAFFIC
- aces:
- - grant: deny
- protocol_options:
- tcp:
- ack: true
- source:
- any: true
- port_protocol:
- eq: www
- destination:
- any: true
- port_protocol:
- eq: telnet
- dscp: af11
- state: merged
-
-# Commands fired:
-# ---------------
-#
-# - ip access-list standard std_acl
-# - deny 192.168.1.200
-# - deny 192.168.2.0 0.0.0.255
-# - ip access-list extended 110
-# - no 10
-# - 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
-# - deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
-# - ip access-list extended test
-# - deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
-# - ip access-list extended 123
-# - deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
-# - deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
-# - ipv6 access-list R1_TRAFFIC
-# - deny tcp any eq www any eq telnet ack dscp af11
-
-# After state:
-# ------------
-#
-# vios#sh access-lists
-# Standard IP access list std_acl
-# 10 deny 192.168.1.200
-# 20 deny 192.168.2.0, wildcard bits 0.0.0.255
-# Extended IP access list 110
-# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
-# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
-# Extended IP access list 123
-# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
-# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
-# Extended IP access list test
-# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
-# IPv6 access list R1_TRAFFIC
-# deny tcp any eq www any eq telnet ack dscp af11 sequence 10
-
-
-# Using replaced
-
-# Before state:
-# -------------
-#
-# vios#sh access-lists
-# Standard IP access list std_acl
-# 10 deny 192.168.1.200
-# 20 deny 192.168.2.0, wildcard bits 0.0.0.255
-# Extended IP access list 110
-# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
-# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
-# Extended IP access list 123
-# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
-# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
-# Extended IP access list test
-# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
-# IPv6 access list R1_TRAFFIC
-# deny tcp any eq www any eq telnet ack dscp af11 sequence 10
-
-
-- name: Replaces device configuration of listed acls with provided configuration
- ios_acl:
- config:
- - afi: ipv4
- acls:
- - name: 110
- aces:
- - grant: deny
- protocol_options:
- tcp:
- syn: true
- source:
- address: 192.0.2.0
- wildcard_bits: 0.0.0.255
- destination:
- address: 192.0.3.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: www
- dscp: ef
- ttl:
- eq: 10
- - name: 150
- aces:
- - grant: deny
- sequence: 20
- protocol_options:
- tcp:
- syn: true
- source:
- address: 198.51.100.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: telnet
- destination:
- address: 198.51.110.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: telnet
- dscp: ef
- ttl:
- eq: 10
- state: replaced
-
-# Commands fired:
-# ---------------
-#
-# - no ip access-list extended 110
-# - ip access-list extended 110
-# - deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10
-# - ip access-list extended 150
-# - 20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10
-
-# After state:
-# -------------
-#
-# vios#sh access-lists
-# Standard IP access list std_acl
-# 10 deny 192.168.1.200
-# 20 deny 192.168.2.0, wildcard bits 0.0.0.255
-# Extended IP access list 110
-# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10
-# Extended IP access list 123
-# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
-# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
-# Extended IP access list 150
-# 20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10
-# Extended IP access list test
-# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
-# IPv6 access list R1_TRAFFIC
-# deny tcp any eq www any eq telnet ack dscp af11 sequence 10
-
-# Using overridden
-
-# Before state:
-# -------------
-#
-# vios#sh access-lists
-# Standard IP access list std_acl
-# 10 deny 192.168.1.200
-# 20 deny 192.168.2.0, wildcard bits 0.0.0.255
-# Extended IP access list 110
-# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
-# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
-# Extended IP access list 123
-# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
-# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
-# Extended IP access list test
-# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
-# IPv6 access list R1_TRAFFIC
-# deny tcp any eq www any eq telnet ack dscp af11 sequence 10
-
-- name: Override device configuration of all acls with provided configuration
- ios_acl:
- config:
- - afi: ipv4
- acls:
- - name: 110
- aces:
- - grant: deny
- sequence: 20
- protocol_options:
- tcp:
- ack: true
- source:
- address: 198.51.100.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: telnet
- destination:
- address: 198.51.110.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: www
- dscp: ef
- ttl:
- eq: 10
- - name: 150
- aces:
- - grant: deny
- sequence: 10
- protocol_options:
- tcp:
- syn: true
- source:
- address: 198.51.100.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: telnet
- destination:
- address: 198.51.110.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: telnet
- dscp: ef
- ttl:
- eq: 10
- state: overridden
-
-# Commands fired:
-# ---------------
-#
-# - no ip access-list standard std_acl
-# - no ip access-list extended 110
-# - no ip access-list extended 123
-# - no ip access-list extended 150
-# - no ip access-list extended test
-# - no ipv6 access-list R1_TRAFFIC
-# - ip access-list extended 150
-# - 10 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10
-# - ip access-list extended 110
-# - 20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq www ack dscp ef ttl eq 10
-
-# After state:
-# -------------
-#
-# vios#sh access-lists
-# Extended IP access list 110
-# 20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq www ack dscp ef ttl eq 10
-# Extended IP access list 150
-# 10 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10
-
-# Using Deleted
-
-# Before state:
-# -------------
-#
-# vios#sh access-lists
-# Standard IP access list std_acl
-# 10 deny 192.168.1.200
-# 20 deny 192.168.2.0, wildcard bits 0.0.0.255
-# Extended IP access list 110
-# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
-# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
-# Extended IP access list 123
-# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
-# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
-# Extended IP access list test
-# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
-# IPv6 access list R1_TRAFFIC
-# deny tcp any eq www any eq telnet ack dscp af11 sequence 10
-
-- name: "Delete module attributes of given acls (Note: This won't delete the interface itself)"
- ios_acl:
- config:
- - afi: ipv4
- acls:
- - name: test
- acl_type: extended
- - name: 110
- - name: 123
- aces:
- - sequence: 10
- - afi: ipv6
- acls:
- - name: R1_TRAFFIC
- state: deleted
-
-# Commands fired:
-# ---------------
-#
-# - no ip access-list extended test
-# - no ip access-list extended 110
-# - ip access-list extended 123
-# - no 10
-# - no ipv6 access-list R1_TRAFFIC
-
-# After state:
-# -------------
-#
-# vios#sh access-lists
-# Standard IP access list std_acl
-# 10 deny 192.168.1.200
-# 20 deny 192.168.2.0, wildcard bits 0.0.0.255
-# Extended IP access list 123
-# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
-
-# Before state:
-# -------------
-#
-# vios#sh access-lists
-# Standard IP access list std_acl
-# 10 deny 192.168.1.200
-# 20 deny 192.168.2.0, wildcard bits 0.0.0.255
-# Extended IP access list 110
-# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
-# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
-# Extended IP access list 123
-# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
-# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
-# Extended IP access list test
-# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
-# IPv6 access list R1_TRAFFIC
-# deny tcp any eq www any eq telnet ack dscp af11 sequence 10
-
-- name: "Delete module attributes of given ACL based on AFI (Note: This won't delete the interface itself)"
- ios_acl:
- config:
- - afi: ipv4
- state: deleted
-
-# Commands fired:
-# ---------------
-#
-# - no ip access-list standard std_acl
-# - no ip access-list extended test
-# - no ip access-list extended 110
-# - no ip access-list extended 123
-
-# After state:
-# -------------
-#
-# vios#sh access-lists
-# IPv6 access list R1_TRAFFIC
-# deny tcp any eq www any eq telnet ack dscp af11 sequence 10
-
-# Using Deleted without any config passed
-#"(NOTE: This will delete all of configured resource module attributes from each configured interface)"
-
-# Before state:
-# -------------
-#
-# vios#sh access-lists
-# Standard IP access list std_acl
-# 10 deny 192.168.1.200
-# 20 deny 192.168.2.0, wildcard bits 0.0.0.255
-# Extended IP access list 110
-# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
-# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
-# Extended IP access list 123
-# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
-# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
-# Extended IP access list test
-# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
-# IPv6 access list R1_TRAFFIC
-# deny tcp any eq www any eq telnet ack dscp af11 sequence 10
-
-- name: "Delete module attributes of all acls (Note: This won't delete the interface itself)"
- ios_acl:
- state: deleted
-
-# Commands fired:
-# ---------------
-#
-# - no ip access-list extended test
-# - no ip access-list extended 110
-# - no ip access-list extended 123
-# - no ip access-list extended test
-# - no ipv6 access-list R1_TRAFFIC
-
-# After state:
-# -------------
-#
-# vios#sh access-lists
-
-# Using Gathered
-
-# Before state:
-# -------------
-#
-# vios#sh access-lists
-# Standard IP access list std_acl
-# 10 deny 192.168.1.200
-# 20 deny 192.168.2.0, wildcard bits 0.0.0.255
-# Extended IP access list 110
-# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
-# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
-# Extended IP access list 123
-# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
-# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
-# Extended IP access list test
-# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
-# IPv6 access list R1_TRAFFIC
-# deny tcp any eq www any eq telnet ack dscp af11 sequence 10
-
-- name: Gather listed acls interfaces with provided configurations
- ios_acl_interfaces:
- config:
- state: gathered
-
-# Module Execution Result:
-# ------------------------
-#
-# "gathered": [
-# {
-# "acls": [
-# {
-# "aces": [
-# {
-# "destination": {
-# "address": "192.0.3.0",
-# "wildcard_bits": "0.0.0.255"
-# },
-# "dscp": "ef",
-# "grant": "deny",
-# "protocol_options": {
-# "icmp": {
-# "echo": true
-# }
-# },
-# "sequence": 10,
-# "source": {
-# "address": "192.0.2.0",
-# "wildcard_bits": "0.0.0.255"
-# },
-# "ttl": {
-# "eq": 10
-# }
-# }
-# ],
-# "acl_type": "extended",
-# "name": "110"
-# },
-# {
-# "aces": [
-# {
-# "destination": {
-# "address": "198.51.101.0",
-# "port_protocol": {
-# "eq": "telnet"
-# },
-# "wildcard_bits": "0.0.0.255"
-# },
-# "grant": "deny",
-# "protocol_options": {
-# "tcp": {
-# "ack": true
-# }
-# },
-# "sequence": 10,
-# "source": {
-# "address": "198.51.100.0",
-# "wildcard_bits": "0.0.0.255"
-# },
-# "tos": {
-# "service_value": 12
-# }
-# },
-# {
-# "destination": {
-# "address": "192.0.4.0",
-# "port_protocol": {
-# "eq": "www"
-# },
-# "wildcard_bits": "0.0.0.255"
-# },
-# "dscp": "ef",
-# "grant": "deny",
-# "protocol_options": {
-# "tcp": {
-# "ack": true
-# }
-# },
-# "sequence": 20,
-# "source": {
-# "address": "192.0.3.0",
-# "wildcard_bits": "0.0.0.255"
-# },
-# "ttl": {
-# "lt": 20
-# }
-# }
-# ],
-# "acl_type": "extended",
-# "name": "123"
-# },
-# {
-# "aces": [
-# {
-# "destination": {
-# "address": "192.0.3.0",
-# "port_protocol": {
-# "eq": "www"
-# },
-# "wildcard_bits": "0.0.0.255"
-# },
-# "grant": "deny",
-# "option": {
-# "traceroute": true
-# },
-# "protocol_options": {
-# "tcp": {
-# "fin": true
-# }
-# },
-# "sequence": 10,
-# "source": {
-# "address": "192.0.2.0",
-# "wildcard_bits": "0.0.0.255"
-# },
-# "ttl": {
-# "eq": 10
-# }
-# }
-# ],
-# "acl_type": "extended",
-# "name": "test_acl"
-# }
-# ],
-# "afi": "ipv4"
-# },
-# {
-# "acls": [
-# {
-# "aces": [
-# {
-# "destination": {
-# "any": true,
-# "port_protocol": {
-# "eq": "telnet"
-# }
-# },
-# "dscp": "af11",
-# "grant": "deny",
-# "protocol_options": {
-# "tcp": {
-# "ack": true
-# }
-# },
-# "sequence": 10,
-# "source": {
-# "any": true,
-# "port_protocol": {
-# "eq": "www"
-# }
-# }
-# }
-# ],
-# "name": "R1_TRAFFIC"
-# }
-# ],
-# "afi": "ipv6"
-# }
-# ]
-
-# Using Rendered
-
-- name: Rendered the provided configuration with the exisiting running configuration
- ios_acl:
- config:
- - afi: ipv4
- acls:
- - name: 110
- aces:
- - grant: deny
- sequence: 10
- protocol_options:
- tcp:
- syn: true
- source:
- address: 192.0.2.0
- wildcard_bits: 0.0.0.255
- destination:
- address: 192.0.3.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: www
- dscp: ef
- ttl:
- eq: 10
- - name: 150
- aces:
- - grant: deny
- protocol_options:
- tcp:
- syn: true
- source:
- address: 198.51.100.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: telnet
- destination:
- address: 198.51.110.0
- wildcard_bits: 0.0.0.255
- port_protocol:
- eq: telnet
- dscp: ef
- ttl:
- eq: 10
- state: rendered
-
-# Module Execution Result:
-# ------------------------
-#
-# "rendered": [
-# "ip access-list extended 110",
-# "10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10",
-# "ip access-list extended 150",
-# "deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10"
-# ]
-
-# Using Parsed
-
-- name: Parse the commands for provided configuration
- ios_acl:
- running_config:
- "ipv6 access-list R1_TRAFFIC
- deny tcp any eq www any eq telnet ack dscp af11"
- state: parsed
-
-# Module Execution Result:
-# ------------------------
-#
-# "parsed": [
-# {
-# "acls": [
-# {
-# "aces": [
-# {
-# "destination": {
-# "any": true,
-# "port_protocol": {
-# "eq": "telnet"
-# }
-# },
-# "dscp": "af11",
-# "grant": "deny",
-# "protocol_options": {
-# "tcp": {
-# "ack": true
-# }
-# },
-# "source": {
-# "any": true,
-# "port_protocol": {
-# "eq": "www"
-# }
-# }
-# }
-# ],
-# "name": "R1_TRAFFIC"
-# }
-# ],
-# "afi": "ipv6"
-# }
-# ]
-
-"""
-
-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: ['ip access-list extended 110', 'deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10']
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.acls.acls import AclsArgs
-from ansible.module_utils.network.ios.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,
- mutually_exclusive=mutually_exclusive,
- supports_check_mode=True)
-
- result = Acls(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_banner.py b/lib/ansible/modules/network/ios/ios_banner.py
deleted file mode 100644
index c28838407c..0000000000
--- a/lib/ansible/modules/network/ios/ios_banner.py
+++ /dev/null
@@ -1,186 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_banner
-version_added: "2.3"
-author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
-short_description: Manage multiline banners on Cisco IOS devices
-description:
- - This will configure both login and motd banners on remote devices
- running Cisco IOS. It allows playbooks to add or remote
- banner text from the active running configuration.
-extends_documentation_fragment: ios
-notes:
- - Tested against IOS 15.6
-options:
- banner:
- description:
- - Specifies which banner should be configured on the remote device.
- In Ansible 2.4 and earlier only I(login) and I(motd) were supported.
- required: true
- choices: ['login', 'motd', 'exec', 'incoming', 'slip-ppp']
- text:
- description:
- - The banner text that should be
- present in the remote device running configuration. This argument
- accepts a multiline string, with no empty lines. Requires I(state=present).
- state:
- description:
- - Specifies whether or not the configuration is
- present in the current devices active running configuration.
- default: present
- choices: ['present', 'absent']
-"""
-
-EXAMPLES = """
-- name: configure the login banner
- ios_banner:
- banner: login
- text: |
- this is my login banner
- that contains a multiline
- string
- state: present
-
-- name: remove the motd banner
- ios_banner:
- banner: motd
- state: absent
-
-- name: Configure banner from file
- ios_banner:
- banner: motd
- text: "{{ lookup('file', './config_partial/raw_banner.cfg') }}"
- state: present
-
-"""
-
-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
-"""
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.ios import get_config, load_config
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-from re import search, M
-
-
-def map_obj_to_commands(updates, module):
- commands = list()
- want, have = updates
- state = module.params['state']
-
- if state == 'absent' and 'text' in have.keys() and have['text']:
- commands.append('no banner %s' % module.params['banner'])
-
- elif state == 'present':
- if want['text'] and (want['text'] != have.get('text')):
- banner_cmd = 'banner %s' % module.params['banner']
- banner_cmd += ' @\n'
- banner_cmd += want['text'].strip('\n')
- banner_cmd += '\n@'
- commands.append(banner_cmd)
-
- return commands
-
-
-def map_config_to_obj(module):
- """
- This function gets the banner config without stripping any whitespaces,
- and then fetches the required banner from it.
- :param module:
- :return: banner config dict object.
- """
- out = get_config(module, flags='| begin banner %s' % module.params['banner'])
- if out:
- regex = 'banner ' + module.params['banner'] + ' ^C\n'
- if search('banner ' + module.params['banner'], out, M):
- output = str((out.split(regex))[1].split("^C\n")[0])
- else:
- output = None
- else:
- output = None
- obj = {'banner': module.params['banner'], 'state': 'absent'}
- if output:
- obj['text'] = output
- obj['state'] = 'present'
- return obj
-
-
-def map_params_to_obj(module):
- text = module.params['text']
- 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', 'exec', 'incoming', 'slip-ppp']),
- text=dict(),
- state=dict(default='present', choices=['present', 'absent'])
- )
-
- argument_spec.update(ios_argument_spec)
-
- 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:
- if not module.check_mode:
- load_config(module, commands)
-
- result['changed'] = True
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_bgp.py b/lib/ansible/modules/network/ios/ios_bgp.py
deleted file mode 100644
index 88fe29a12c..0000000000
--- a/lib/ansible/modules/network/ios/ios_bgp.py
+++ /dev/null
@@ -1,438 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2019, Ansible by Red Hat, inc
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-#
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_bgp
-version_added: "2.8"
-author: "Nilashish Chakraborty (@NilashishC)"
-short_description: Configure global BGP protocol settings on Cisco IOS.
-description:
- - This module provides configuration management of global BGP parameters
- on devices running Cisco IOS
-notes:
- - Tested against Cisco IOS Version 15.6(3)M2
-options:
- config:
- description:
- - Specifies the BGP related configuration.
- 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.
- default: null
- log_neighbor_changes:
- description:
- - Enable/disable logging neighbor up/down and reset reason.
- type: bool
- neighbors:
- description:
- - Specifies BGP neighbor related configurations.
- suboptions:
- neighbor:
- description:
- - Neighbor router address.
- required: True
- remote_as:
- description:
- - Remote AS of the BGP neighbor to configure.
- type: int
- required: True
- update_source:
- description:
- - Source of the routing updates.
- password:
- description:
- - Password to authenticate the BGP peer connection.
- enabled:
- description:
- - Administratively shutdown or enable a neighbor.
- type: bool
- description:
- description:
- - Neighbor specific description.
- 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.
- timers:
- description:
- - Specifies BGP neighbor timer related configurations.
- suboptions:
- keepalive:
- description:
- - Frequency (in seconds) with which the device sends keepalive messages to its peer.
- - The range is from 0 to 65535.
- type: int
- required: True
- holdtime:
- description:
- - Interval (in seconds) after not receiving a keepalive message that IOS declares a peer dead.
- - The range is from 0 to 65535.
- type: int
- required: True
- min_neighbor_holdtime:
- description:
- - Interval (in seconds) specifying the minimum acceptable hold-time from a BGP neighbor.
- - The minimum acceptable hold-time must be less than, or equal to, the interval specified in the holdtime argument.
- - The range is from 0 to 65535.
- type: int
- local_as:
- description:
- - The local AS number for the neighbor.
- type: int
- 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.
- suboptions:
- prefix:
- description:
- - Network ID to announce via BGP.
- required: True
- masklen:
- description:
- - Subnet mask length for the Network to announce(e.g, 8, 16, 24, etc.).
- route_map:
- description:
- - Route map to modify the attributes.
- address_family:
- description:
- - Specifies BGP address family related configurations.
- suboptions:
- afi:
- description:
- - Type of address family to configure.
- choices:
- - ipv4
- - ipv6
- required: True
- safi:
- description:
- - Specifies the type of cast for the address family.
- choices:
- - flowspec
- - unicast
- - multicast
- - labeled-unicast
- default: unicast
- synchronization:
- description:
- - Enable/disable IGP synchronization.
- type: bool
- auto_summary:
- description:
- - Enable/disable automatic network number summarization.
- type: bool
- redistribute:
- description:
- - Specifies the redistribute information from another routing protocol.
- suboptions:
- protocol:
- description:
- - Specifies the protocol for configuring redistribute information.
- choices: ['ospf', 'ospfv3', 'eigrp', 'isis', 'static', 'connected', 'odr', 'lisp', 'mobile', 'rip']
- required: True
- id:
- description:
- - Identifier for the routing protocol for configuring redistribute information.
- - Valid for protocols 'ospf', 'ospfv3' and 'eigrp'.
- metric:
- description:
- - Specifies the metric for redistributed routes.
- route_map:
- description:
- - Specifies the route map reference.
- networks:
- description:
- - Specify Networks to announce via BGP.
- - For operation replace, this option is mutually exclusive with root level networks option.
- suboptions:
- prefix:
- description:
- - Network ID to announce via BGP.
- required: True
- masklen:
- description:
- - Subnet mask length for the Network to announce(e.g, 8, 16, 24, etc.).
- route_map:
- description:
- - Route map to modify the attributes.
- neighbors:
- description:
- - Specifies BGP neighbor related configurations in Address Family configuration mode.
- suboptions:
- neighbor:
- description:
- - Neighbor router address.
- required: True
- advertisement_interval:
- description:
- - Minimum interval between sending BGP routing updates for this neighbor.
- type: int
- route_reflector_client:
- description:
- - Specify a neighbor as a route reflector client.
- type: bool
- route_server_client:
- description:
- - Specify a neighbor as a route server client.
- type: bool
- activate:
- description:
- - Enable the Address Family for this Neighbor.
- type: bool
- remove_private_as:
- description:
- - Remove the private AS number from outbound updates.
- type: bool
- next_hop_self:
- description:
- - Enable/disable the next hop calculation for this neighbor.
- type: bool
- next_hop_unchanged:
- description:
- - Propagate next hop unchanged for iBGP paths to this neighbor.
- type: bool
- maximum_prefix:
- description:
- - Maximum number of prefixes to accept from this peer.
- - The range is from 1 to 2147483647.
- type: int
- prefix_list_in:
- description:
- - Name of ip prefix-list to apply to incoming prefixes.
- prefix_list_out:
- description:
- - Name of ip prefix-list to apply to outgoing prefixes.
- 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.
- default: merge
- choices: ['merge', 'replace', 'override', 'delete']
-"""
-
-EXAMPLES = """
-- name: configure global bgp as 64496
- ios_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
- min_neighbor_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: ospf
- id: 223
- metric: 10
- operation: merge
-
-- name: Configure BGP neighbors
- ios_bgp:
- config:
- bgp_as: 64496
- neighbors:
- - neighbor: 192.0.2.10
- remote_as: 64496
- password: ansible
- description: IBGP_NBR_1
- ebgp_multihop: 100
- timers:
- keepalive: 300
- holdtime: 360
- min_neighbor_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
- ios_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
- ios_bgp:
- config:
- bgp_as: 64496
- address_family:
- - afi: ipv4
- safi: unicast
- neighbors:
- - neighbor: 203.0.113.10
- activate: yes
- maximum_prefix: 250
- advertisement_interval: 120
- - neighbor: 192.0.2.15
- activate: yes
- route_reflector_client: True
- operation: merge
-
-- name: remove bgp as 64496 from config
- ios_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 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 ospf 223 metric 70
- - exit-address-family
-"""
-from ansible.module_utils._text import to_text
-from ansible.module_utils.network.ios.providers.module import NetworkModule
-from ansible.module_utils.network.ios.providers.cli.config.bgp.process import REDISTRIBUTE_PROTOCOLS
-
-
-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=REDISTRIBUTE_PROTOCOLS, required=True),
- 'id': dict(),
- 'metric': dict(type='int'),
- 'route_map': dict(),
- }
-
- timer_spec = {
- 'keepalive': dict(type='int', required=True),
- 'holdtime': dict(type='int', required=True),
- 'min_neighbor_holdtime': dict(type='int'),
- }
-
- neighbor_spec = {
- 'neighbor': dict(required=True),
- 'remote_as': dict(type='int', required=True),
- 'local_as': dict(type='int'),
- '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(),
- }
-
- af_neighbor_spec = {
- 'neighbor': dict(required=True),
- 'activate': dict(type='bool'),
- 'advertisement_interval': dict(type='int'),
- 'remove_private_as': dict(type='bool'),
- 'next_hop_self': dict(type='bool'),
- 'route_reflector_client': dict(type='bool'),
- 'route_server_client': dict(type='bool'),
- 'maximum_prefix': dict(type='int'),
- 'prefix_list_in': dict(),
- 'prefix_list_out': dict()
- }
-
- address_family_spec = {
- 'afi': dict(choices=['ipv4', 'ipv6'], required=True),
- 'safi': dict(choices=['flowspec', 'labeled-unicast', 'multicast', 'unicast'], default='unicast'),
- 'auto_summary': dict(type='bool'),
- 'synchronization': dict(type='bool'),
- '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),
- '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 ^router bgp')
- except Exception as exc:
- module.fail_json(msg=to_text(exc))
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_command.py b/lib/ansible/modules/network/ios/ios_command.py
deleted file mode 100644
index 59ea254b2d..0000000000
--- a/lib/ansible/modules/network/ios/ios_command.py
+++ /dev/null
@@ -1,230 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_command
-version_added: "2.1"
-author: "Peter Sprygada (@privateip)"
-short_description: Run commands on remote devices running Cisco IOS
-description:
- - Sends arbitrary commands to an ios 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.
- - This module does not support running commands in configuration mode.
- Please use M(ios_config) to configure IOS devices.
-extends_documentation_fragment: ios
-notes:
- - Tested against IOS 15.6
-options:
- commands:
- description:
- - List of commands to send to the remote ios device over the
- configured provider. 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 retries has expired. If a command sent to the
- device requires answering a prompt, it is possible to pass
- a dict containing I(command), I(answer) and I(prompt).
- Common answers are 'y' or "\\r" (carriage return, must be
- double quotes). See examples.
- required: true
- wait_for:
- description:
- - List of conditions to evaluate against the output of the
- command. The task will wait for each condition to be true
- before moving forward. If the conditional is not true
- within the configured number of retries, the task fails.
- See examples.
- aliases: ['waitfor']
- version_added: "2.2"
- 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 wait_for must be satisfied. If
- the value is set to C(any) then only one of the values must be
- satisfied.
- default: all
- choices: ['any', 'all']
- version_added: "2.2"
- retries:
- description:
- - Specifies the number of retries a command should by tried
- before it is considered failed. The command is run on the
- target device every retry and evaluated against the
- I(wait_for) conditions.
- default: 10
- interval:
- description:
- - Configures the interval in seconds to wait between retries
- of the command. If the command does not pass the specified
- conditions, the interval indicates how long to wait before
- trying the command again.
- default: 1
-"""
-
-EXAMPLES = r"""
-tasks:
- - name: run show version on remote devices
- ios_command:
- commands: show version
-
- - name: run show version and check to see if output contains IOS
- ios_command:
- commands: show version
- wait_for: result[0] contains IOS
-
- - name: run multiple commands on remote nodes
- ios_command:
- commands:
- - show version
- - show interfaces
-
- - name: run multiple commands and evaluate the output
- ios_command:
- commands:
- - show version
- - show interfaces
- wait_for:
- - result[0] contains IOS
- - result[1] contains Loopback0
-
- - name: run commands that require answering a prompt
- ios_command:
- commands:
- - command: 'clear counters GigabitEthernet0/1'
- prompt: 'Clear "show interface" counters on this interface \[confirm\]'
- answer: 'y'
- - command: 'clear counters GigabitEthernet0/2'
- prompt: '[confirm]'
- answer: "\r"
-"""
-
-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.module_utils.network.common.parsing import Conditional
-from ansible.module_utils.network.common.utils import transform_commands, to_lines
-from ansible.module_utils.network.ios.ios import run_commands
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-
-
-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 main():
- """main entry point for module execution
- """
- argument_spec = dict(
- commands=dict(type='list', required=True),
-
- wait_for=dict(type='list', aliases=['waitfor']),
- match=dict(default='all', choices=['all', 'any']),
-
- retries=dict(default=10, type='int'),
- interval=dict(default=1, type='int')
- )
-
- argument_spec.update(ios_argument_spec)
-
- 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/lib/ansible/modules/network/ios/ios_config.py b/lib/ansible/modules/network/ios/ios_config.py
deleted file mode 100644
index b359c9cc78..0000000000
--- a/lib/ansible/modules/network/ios/ios_config.py
+++ /dev/null
@@ -1,567 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_config
-version_added: "2.1"
-author: "Peter Sprygada (@privateip)"
-short_description: Manage Cisco IOS configuration sections
-description:
- - Cisco IOS configurations use a simple block indent file syntax
- for segmenting configuration into sections. This module provides
- an implementation for working with IOS configuration sections in
- a deterministic way.
-extends_documentation_fragment: ios
-notes:
- - Tested against IOS 15.6
- - 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).
-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. Be sure to note the configuration
- command syntax as some commands are automatically modified by the
- device config parser.
- aliases: ['commands']
- 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.
- src:
- description:
- - Specifies the source path to the file that contains the configuration
- or configuration template to load. The path to the source file can
- either be the full path on the Ansible control host or a relative
- path from the playbook or role root directory. This argument is mutually
- exclusive with I(lines), I(parents).
- version_added: "2.2"
- 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.
- 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.
- 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.
- choices: ['line', 'strict', 'exact', 'none']
- default: line
- 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.
- default: line
- choices: ['line', 'block']
- multiline_delimiter:
- description:
- - This argument is used when pushing a multiline configuration
- element to the IOS device. It specifies the character to use
- as the delimiting character. This only applies to the
- configuration action.
- default: "@"
- version_added: "2.3"
- 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'
- version_added: "2.2"
- 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.
- aliases: ['config']
- version_added: "2.4"
- defaults:
- description:
- - This argument specifies whether or not to collect all defaults
- when getting the remote device running config. When enabled,
- the module will get the current config by issuing the command
- C(show running-config all).
- type: bool
- default: 'no'
- version_added: "2.2"
- 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
- choices: ['always', 'never', 'modified', 'changed']
- version_added: "2.4"
- 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.
- choices: ['running', 'startup', 'intended']
- version_added: "2.4"
- 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.
- version_added: "2.4"
- 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).
- version_added: "2.4"
- 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>
- 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
- version_added: "2.8"
-"""
-
-EXAMPLES = """
-- name: configure top level configuration
- ios_config:
- lines: hostname {{ inventory_hostname }}
-
-- name: configure interface settings
- ios_config:
- lines:
- - description test interface
- - ip address 172.31.1.1 255.255.255.0
- parents: interface Ethernet1
-
-- name: configure ip helpers on multiple interfaces
- ios_config:
- lines:
- - ip helper-address 172.26.1.10
- - ip helper-address 172.26.3.8
- parents: "{{ item }}"
- with_items:
- - interface Ethernet1
- - interface Ethernet2
- - interface GigabitEthernet1
-
-- name: configure policer in Scavenger class
- ios_config:
- lines:
- - conform-action transmit
- - exceed-action drop
- parents:
- - policy-map Foo
- - class Scavenger
- - police cir 64000
-
-- name: load new acl into device
- ios_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
- - 50 permit ip host 192.0.2.5 any log
- parents: ip access-list extended test
- before: no ip access-list extended test
- match: exact
-
-- name: check the running-config against master config
- ios_config:
- diff_against: intended
- intended_config: "{{ lookup('file', 'master.cfg') }}"
-
-- name: check the startup-config against the running-config
- ios_config:
- diff_against: startup
- diff_ignore_lines:
- - ntp clock .*
-
-- name: save running to startup when modified
- ios_config:
- save_when: modified
-
-- name: for idempotency, use full-form commands
- ios_config:
- lines:
- # - shut
- - shutdown
- # parents: int gig1/0/11
- parents: interface GigabitEthernet1/0/11
-
-# Set boot image based on comparison to a group_var (version) and the version
-# that is returned from the `ios_facts` module
-- name: SETTING BOOT IMAGE
- ios_config:
- lines:
- - no boot system
- - boot system flash bootflash:{{new_image}}
- host: "{{ inventory_hostname }}"
- when: ansible_net_version != version
-
-- name: render a Jinja2 template onto an IOS device
- ios_config:
- backup: yes
- src: ios_template.j2
-
-- name: configurable backup path
- ios_config:
- src: ios_template.j2
- backup: yes
- backup_options:
- filename: backup.cfg
- dir_path: /home/user
-"""
-
-RETURN = """
-updates:
- description: The set of commands that will be pushed to the remote device
- returned: always
- type: list
- sample: ['hostname foo', 'router ospf 1', 'router-id 192.0.2.1']
-commands:
- description: The set of commands that will be pushed to the remote device
- returned: always
- type: list
- sample: ['hostname foo', 'router ospf 1', 'router-id 192.0.2.1']
-backup_path:
- description: The full path to the backup file
- returned: when backup is yes
- type: str
- sample: /playbooks/ansible/backup/ios_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: ios_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/ios_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"
-"""
-import json
-
-from ansible.module_utils._text import to_text
-from ansible.module_utils.connection import ConnectionError
-from ansible.module_utils.network.ios.ios import run_commands, get_config
-from ansible.module_utils.network.ios.ios import get_defaults_flag, get_connection
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.common.config import NetworkConfig, dumps
-
-
-def check_args(module, warnings):
- if module.params['multiline_delimiter']:
- if len(module.params['multiline_delimiter']) != 1:
- module.fail_json(msg='multiline_delimiter value can only be a '
- 'single character')
-
-
-def edit_config_or_macro(connection, commands):
- # only catch the macro configuration command,
- # not negated 'no' variation.
- if commands[0].startswith("macro name"):
- connection.edit_macro(candidate=commands)
- else:
- connection.edit_config(candidate=commands)
-
-
-def get_candidate_config(module):
- candidate = ''
- if module.params['src']:
- candidate = module.params['src']
-
- elif module.params['lines']:
- candidate_obj = NetworkConfig(indent=1)
- 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, current_config=None, flags=None):
- running = module.params['running_config']
- if not running:
- if not module.params['defaults'] and current_config:
- running = current_config
- else:
- running = get_config(module, flags=flags)
-
- return running
-
-
-def save_config(module, result):
- result['changed'] = True
- if not module.check_mode:
- run_commands(module, 'copy running-config startup-config\r')
- 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'),
- parents=dict(type='list'),
-
- before=dict(type='list'),
- after=dict(type='list'),
-
- match=dict(default='line', choices=['line', 'strict', 'exact', 'none']),
- replace=dict(default='line', choices=['line', 'block']),
- multiline_delimiter=dict(default='@'),
-
- running_config=dict(aliases=['config']),
- intended_config=dict(),
-
- 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', 'intended', 'running']),
- diff_ignore_lines=dict(type='list'),
- )
-
- argument_spec.update(ios_argument_spec)
-
- mutually_exclusive = [('lines', 'src'),
- ('parents', 'src')]
-
- required_if = [('match', 'strict', ['lines']),
- ('match', 'exact', ['lines']),
- ('replace', 'block', ['lines']),
- ('diff_against', 'intended', ['intended_config'])]
-
- module = AnsibleModule(argument_spec=argument_spec,
- mutually_exclusive=mutually_exclusive,
- required_if=required_if,
- supports_check_mode=True)
-
- result = {'changed': False}
-
- warnings = list()
- check_args(module, warnings)
- result['warnings'] = warnings
-
- diff_ignore_lines = module.params['diff_ignore_lines']
- config = None
- contents = None
- flags = get_defaults_flag(module) if module.params['defaults'] else []
- connection = get_connection(module)
-
- 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['lines'], module.params['src'])):
- match = module.params['match']
- replace = module.params['replace']
- path = module.params['parents']
-
- candidate = get_candidate_config(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']
- banner_diff = response['banner_diff']
-
- if config_diff or banner_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
- result['banners'] = banner_diff
-
- # send the configuration commands to the device and merge
- # them with the current running config
- if not module.check_mode:
- if commands:
- edit_config_or_macro(connection, commands)
- if banner_diff:
- connection.edit_banner(candidate=json.dumps(banner_diff), multiline_delimiter=module.params['multiline_delimiter'])
-
- result['changed'] = True
-
- 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, ['show running-config', 'show startup-config'])
-
- running_config = NetworkConfig(indent=1, contents=output[0], ignore_lines=diff_ignore_lines)
- startup_config = NetworkConfig(indent=1, 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, 'show running-config')
- contents = output[0]
- else:
- contents = running_config
-
- # recreate the object in order to process diff_ignore_lines
- running_config = NetworkConfig(indent=1, 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, 'show startup-config')
- contents = output[0]
- else:
- contents = startup_config.config_text
-
- elif module.params['diff_against'] == 'intended':
- contents = module.params['intended_config']
-
- if contents is not None:
- base_config = NetworkConfig(indent=1, contents=contents, ignore_lines=diff_ignore_lines)
-
- if running_config.sha1 != base_config.sha1:
- 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
-
- result.update({
- 'changed': True,
- 'diff': {'before': str(before), 'after': str(after)}
- })
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_facts.py b/lib/ansible/modules/network/ios/ios_facts.py
deleted file mode 100644
index e2f147e669..0000000000
--- a/lib/ansible/modules/network/ios/ios_facts.py
+++ /dev/null
@@ -1,239 +0,0 @@
-#!/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/>.
-#
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_facts
-version_added: "2.2"
-author:
- - "Peter Sprygada (@privateip)"
- - "Sumit Jaiswal (@justjais)"
-short_description: Collect facts from remote devices running Cisco IOS
-description:
- - Collects a base set of device facts from a remote device that
- is running IOS. This module prepends all of the
- base network fact keys with C(ansible_net_<fact>). The facts
- module will always collect a base set of facts from the device
- and can enable or disable collection of additional facts.
-extends_documentation_fragment: ios
-notes:
- - Tested against IOS 15.6
-options:
- gather_subset:
- description:
- - When supplied, this argument restricts the facts collected
- to a given subset.
- - Possible values for this argument include
- C(all), C(min), C(hardware), C(config), and C(interfaces).
- - Specify a list of values to include a larger subset.
- - Use a value with an initial C(!) to collect all facts except that subset.
- required: false
- default: '!config'
- 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(M(!)) to specify that
- a specific subset should not be collected.
- Valid subsets are 'all', 'interfaces', 'l2_interfaces', 'vlans',
- 'lag_interfaces', 'lacp', 'lacp_interfaces', 'lldp_global',
- 'lldp_interfaces', 'l3_interfaces', 'acl_interfaces', 'static_routes', 'acls'.
- version_added: "2.9"
-"""
-
-EXAMPLES = """
-- name: Gather all legacy facts
- ios_facts:
- gather_subset: all
-
-- name: Gather only the config and default facts
- ios_facts:
- gather_subset:
- - config
-
-- name: Do not gather hardware facts
- ios_facts:
- gather_subset:
- - "!hardware"
-
-- name: Gather legacy and resource facts
- ios_facts:
- gather_subset: all
- gather_network_resources: all
-
-- name: Gather only the interfaces resource facts and no legacy facts
- ios_facts:
- gather_subset:
- - '!all'
- - '!min'
- gather_network_resources:
- - interfaces
-
-- name: Gather interfaces resource and minimal legacy facts
- ios_facts:
- gather_subset: min
- gather_network_resources: interfaces
-
-- name: Gather L2 interfaces resource and minimal legacy facts
- ios_facts:
- gather_subset: min
- gather_network_resources: l2_interfaces
-
-- name: Gather L3 interfaces resource and minimal legacy facts
- ios_facts:
- gather_subset: min
- gather_network_resources: l3_interfaces
-
-"""
-
-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_iostype:
- description: The operating system type (IOS or IOS-XE) 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_stacked_models:
- description: The model names of each device in the stack
- returned: when multiple devices are configured in a stack
- type: list
-ansible_net_stacked_serialnums:
- description: The serial numbers of each device in the stack
- returned: when multiple devices are configured in a stack
- type: list
-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_filesystems_info:
- description: A hash of all file systems containing info about each file system (e.g. free and total space)
- returned: when hardware is configured
- type: dict
-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 CDP and LLDP neighbors from the remote device. If both,
- CDP and LLDP neighbor data is present on one port, CDP is preferred.
- returned: when interfaces is configured
- type: dict
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.facts.facts import FactsArgs
-from ansible.module_utils.network.ios.facts.facts import Facts
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-
-
-def main():
- """
- Main entry point for module execution
-
- :returns: ansible_facts
- """
- argument_spec = FactsArgs.argument_spec
- argument_spec.update(ios_argument_spec)
-
- module = AnsibleModule(argument_spec=argument_spec,
- supports_check_mode=True)
-
- warnings = []
- if module.params["gather_subset"] == "!config":
- warnings.append('default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards')
-
- result = Facts(module).get_facts()
-
- ansible_facts, additional_warnings = result
- warnings.extend(additional_warnings)
-
- module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_interfaces.py b/lib/ansible/modules/network/ios/ios_interfaces.py
deleted file mode 100644
index 4988f029be..0000000000
--- a/lib/ansible/modules/network/ios/ios_interfaces.py
+++ /dev/null
@@ -1,405 +0,0 @@
-#!/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 ios_interfaces
-"""
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_interfaces
-version_added: 2.9
-short_description: Manages interface attributes of Cisco IOS network devices
-description: This module manages the interface attributes of Cisco IOS network devices.
-author: Sumit Jaiswal (@justjais)
-notes:
-- Tested against Cisco IOSv Version 15.2 on VIRL
-- This module works with connection C(network_cli).
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: A dictionary of interface options
- type: list
- suboptions:
- name:
- description:
- - Full name of interface, e.g. GigabitEthernet0/2, loopback999.
- type: str
- required: True
- description:
- description:
- - Interface description.
- type: str
- enabled:
- 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
- default: True
- speed:
- description:
- - Interface link speed. Applicable for Ethernet interfaces only.
- type: str
- mtu:
- description:
- - MTU for a specific interface. Applicable for Ethernet interfaces only.
- - Refer to vendor documentation for valid values.
- type: int
- duplex:
- description:
- - Interface link status. Applicable for Ethernet interfaces only, either in half duplex,
- full duplex or in automatic state which negotiates the duplex automatically.
- type: str
- choices: ['full', 'half', 'auto']
- state:
- choices:
- - merged
- - replaced
- - overridden
- - deleted
- default: merged
- description:
- - The state of the configuration after module completion
- type: str
-"""
-
-EXAMPLES = """
----
-
-# Using merged
-
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description This is test
-# no ip address
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# no ip address
-# duplex auto
-# speed auto
-
-- name: Merge provided configuration with device configuration
- ios_interfaces:
- config:
- - name: GigabitEthernet0/2
- description: 'Configured and Merged by Ansible Network'
- enabled: True
- - name: GigabitEthernet0/3
- description: 'Configured and Merged by Ansible Network'
- mtu: 2800
- enabled: False
- speed: 100
- duplex: full
- state: merged
-
-# After state:
-# ------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description Configured and Merged by Ansible Network
-# no ip address
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured and Merged by Ansible Network
-# mtu 2800
-# no ip address
-# shutdown
-# duplex full
-# speed 100
-
-# Using replaced
-
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description Configured by Ansible Network
-# no ip address
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# mtu 2000
-# no ip address
-# shutdown
-# duplex full
-# speed 100
-
-- name: Replaces device configuration of listed interfaces with provided configuration
- ios_interfaces:
- config:
- - name: GigabitEthernet0/3
- description: 'Configured and Replaced by Ansible Network'
- enabled: False
- duplex: auto
- mtu: 2500
- speed: 1000
- state: replaced
-
-# After state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description Configured by Ansible Network
-# no ip address
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured and Replaced by Ansible Network
-# mtu 2500
-# no ip address
-# shutdown
-# duplex full
-# speed 1000
-
-# Using overridden
-
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface#
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description This is test
-# no ip address
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured by Ansible
-# mtu 2800
-# no ip address
-# shutdown
-# duplex full
-# speed 100
-
-- name: Override device configuration of all interfaces with provided configuration
- ios_interfaces:
- config:
- - name: GigabitEthernet0/2
- description: 'Configured and Overridden by Ansible Network'
- speed: 1000
- - name: GigabitEthernet0/3
- description: 'Configured and Overridden by Ansible Network'
- enabled: False
- duplex: full
- mtu: 2000
- state: overridden
-
-# After state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description Configured and Overridden by Ansible Network
-# no ip address
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured and Overridden by Ansible Network
-# mtu 2000
-# no ip address
-# shutdown
-# duplex full
-# speed 100
-
-# Using Deleted
-
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description Configured by Ansible Network
-# no ip address
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# mtu 2500
-# no ip address
-# shutdown
-# duplex full
-# speed 1000
-
-- name: "Delete module attributes of given interfaces (Note: This won't delete the interface itself)"
- ios_interfaces:
- config:
- - name: GigabitEthernet0/2
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# mtu 2500
-# no ip address
-# shutdown
-# duplex full
-# speed 1000
-
-# Using Deleted without any config passed
-#"(NOTE: This will delete all of configured resource module attributes from each configured interface)"
-
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description Configured by Ansible Network
-# no ip address
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# mtu 2500
-# no ip address
-# shutdown
-# duplex full
-# speed 1000
-
-- name: "Delete module attributes of all interfaces (Note: This won't delete the interface itself)"
- ios_interfaces:
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/3
-# no ip address
-# duplex auto
-# speed auto
-
-"""
-
-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 GigabitEthernet 0/1', 'description This is test', 'speed 100']
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.interfaces.interfaces import InterfacesArgs
-from ansible.module_utils.network.ios.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',))]
-
- module = AnsibleModule(argument_spec=InterfacesArgs.argument_spec,
- required_if=required_if,
- supports_check_mode=True)
-
- result = Interfaces(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_l2_interfaces.py b/lib/ansible/modules/network/ios/ios_l2_interfaces.py
deleted file mode 100644
index 19eadb8426..0000000000
--- a/lib/ansible/modules/network/ios/ios_l2_interfaces.py
+++ /dev/null
@@ -1,390 +0,0 @@
-#!/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 ios_l2_interfaces
-"""
-
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-DOCUMENTATION = """
----
-module: ios_l2_interfaces
-version_added: 2.9
-short_description: Manage Layer-2 interface on Cisco IOS devices.
-description: This module provides declarative management of Layer-2 interface on Cisco IOS devices.
-author: Sumit Jaiswal (@justjais)
-notes:
- - Tested against Cisco IOSv Version 15.2 on VIRL
- - This module works with connection C(network_cli).
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: A dictionary of Layer-2 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
- 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
- voice:
- description:
- - Switchport mode voice command to configure the interface with a voice vlan.
- type: dict
- suboptions:
- vlan:
- description:
- - Configure given voice VLAN on access port. It's used as the voice VLAN ID.
- type: int
- trunk:
- description:
- - Switchport mode trunk command to configure the interface as a Layer 2 trunk.
- Note The encapsulation is always set to dot1q.
- type: dict
- suboptions:
- 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
- native_vlan:
- description:
- - Native VLAN to be configured in trunk port. It's used as the trunk native VLAN ID.
- type: int
- encapsulation:
- description:
- - Trunking encapsulation when interface is in trunking mode.
- choices: ['dot1q','isl','negotiate']
- type: str
- pruning_vlans:
- description:
- - Pruning VLAN to be configured in trunk port. It's used as the trunk pruning VLAN ID.
- type: list
- mode:
- description:
- - Mode in which interface needs to be configured.
- - An interface whose trunk encapsulation is "Auto" can not be configured to "trunk" mode.
- version_added: '2.10'
- type: str
- choices: ['access', 'trunk']
- state:
- choices:
- - merged
- - replaced
- - overridden
- - deleted
- default: merged
- description:
- - The state of the configuration after module completion
- type: str
-"""
-
-EXAMPLES = """
----
-
-# Using merged
-
-# Before state:
-# -------------
-#
-# viosl2#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# negotiation auto
-# interface GigabitEthernet0/2
-# description This is test
-# switchport access vlan 20
-# media-type rj45
-# negotiation auto
-
-- name: Merge provided configuration with device configuration
- ios_l2_interfaces:
- config:
- - name: GigabitEthernet0/1
- mode: access
- access:
- vlan: 10
- voice:
- vlan: 40
- - name: GigabitEthernet0/2
- mode: trunk
- trunk:
- allowed_vlans: 10-20,40
- native_vlan: 20
- pruning_vlans: 10,20
- encapsulation: dot1q
- state: merged
-
-# After state:
-# ------------
-#
-# viosl2#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# switchport access vlan 10
-# switchport access vlan 40
-# switchport mode access
-# negotiation auto
-# interface GigabitEthernet0/2
-# description This is test
-# switchport trunk allowed vlan 10-20,40
-# switchport trunk encapsulation dot1q
-# switchport trunk native vlan 20
-# switchport trunk pruning vlan 10,20
-# switchport mode trunk
-# media-type rj45
-# negotiation auto
-
-# Using replaced
-
-# Before state:
-# -------------
-#
-# viosl2#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# switchport access vlan 20
-# negotiation auto
-# interface GigabitEthernet0/2
-# description This is test
-# switchport access vlan 20
-# media-type rj45
-# negotiation auto
-
-- name: Replaces device configuration of listed l2 interfaces with provided configuration
- ios_l2_interfaces:
- config:
- - name: GigabitEthernet0/2
- trunk:
- - allowed_vlans: 20-25,40
- native_vlan: 20
- pruning_vlans: 10
- encapsulation: isl
- state: replaced
-
-# After state:
-# -------------
-#
-# viosl2#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# switchport access vlan 20
-# negotiation auto
-# interface GigabitEthernet0/2
-# description This is test
-# switchport trunk allowed vlan 20-25,40
-# switchport trunk encapsulation isl
-# switchport trunk native vlan 20
-# switchport trunk pruning vlan 10
-# media-type rj45
-# negotiation auto
-
-# Using overridden
-
-# Before state:
-# -------------
-#
-# viosl2#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# switchport trunk encapsulation dot1q
-# switchport trunk native vlan 20
-# negotiation auto
-# interface GigabitEthernet0/2
-# description This is test
-# switchport access vlan 20
-# switchport trunk encapsulation dot1q
-# switchport trunk native vlan 20
-# media-type rj45
-# negotiation auto
-
-- name: Override device configuration of all l2 interfaces with provided configuration
- ios_l2_interfaces:
- config:
- - name: GigabitEthernet0/2
- access:
- vlan: 20
- voice:
- vlan: 40
- state: overridden
-
-# After state:
-# -------------
-#
-# viosl2#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# negotiation auto
-# interface GigabitEthernet0/2
-# description This is test
-# switchport access vlan 20
-# switchport voice vlan 40
-# media-type rj45
-# negotiation auto
-
-# Using Deleted
-
-# Before state:
-# -------------
-#
-# viosl2#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# switchport access vlan 20
-# negotiation auto
-# interface GigabitEthernet0/2
-# description This is test
-# switchport access vlan 20
-# switchport trunk allowed vlan 20-40,60,80
-# switchport trunk encapsulation dot1q
-# switchport trunk native vlan 10
-# switchport trunk pruning vlan 10
-# media-type rj45
-# negotiation auto
-
-- name: Delete IOS L2 interfaces as in given arguments
- ios_l2_interfaces:
- config:
- - name: GigabitEthernet0/1
- state: deleted
-
-# After state:
-# -------------
-#
-# viosl2#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# negotiation auto
-# interface GigabitEthernet0/2
-# description This is test
-# switchport access vlan 20
-# switchport trunk allowed vlan 20-40,60,80
-# switchport trunk encapsulation dot1q
-# switchport trunk native vlan 10
-# switchport trunk pruning vlan 10
-# media-type rj45
-# negotiation auto
-
-
-# Using Deleted without any config passed
-#"(NOTE: This will delete all of configured resource module attributes from each configured interface)"
-
-# Before state:
-# -------------
-#
-# viosl2#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# switchport access vlan 20
-# negotiation auto
-# interface GigabitEthernet0/2
-# description This is test
-# switchport access vlan 20
-# switchport trunk allowed vlan 20-40,60,80
-# switchport trunk encapsulation dot1q
-# switchport trunk native vlan 10
-# switchport trunk pruning vlan 10
-# media-type rj45
-# negotiation auto
-
-- name: Delete IOS L2 interfaces as in given arguments
- ios_l2_interfaces:
- state: deleted
-
-# After state:
-# -------------
-#
-# viosl2#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# negotiation auto
-# interface GigabitEthernet0/2
-# description This is test
-# media-type rj45
-# negotiation auto
-
-"""
-
-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/1', 'switchport access vlan 20']
-"""
-
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.l2_interfaces.l2_interfaces import L2_InterfacesArgs
-from ansible.module_utils.network.ios.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',))]
-
- module = AnsibleModule(argument_spec=L2_InterfacesArgs.argument_spec,
- required_if=required_if,
- supports_check_mode=True)
-
- result = L2_Interfaces(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_l3_interfaces.py b/lib/ansible/modules/network/ios/ios_l3_interfaces.py
deleted file mode 100644
index 9fd054ef75..0000000000
--- a/lib/ansible/modules/network/ios/ios_l3_interfaces.py
+++ /dev/null
@@ -1,442 +0,0 @@
-#!/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
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_l3_interfaces
-version_added: 2.9
-short_description: Manage Layer-3 interface on Cisco IOS devices.
-description:
-- This module provides declarative management of Layer-3 interface
- on Cisco IOS devices.
-author: Sumit Jaiswal (@justjais)
-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
- dhcp_client:
- description:
- - Configures and specifies client-id to use over DHCP ip.
- Note, This option shall work only when dhcp is configured
- as IP.
- - GigabitEthernet interface number
- type: int
- dhcp_hostname:
- description:
- - Configures and specifies value for hostname option over
- DHCP ip. Note, This option shall work only when dhcp is
- configured as IP.
- type: str
- 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
- state:
- choices:
- - merged
- - replaced
- - overridden
- - deleted
- default: merged
- description:
- - The state of the configuration after module completion
- type: str
-"""
-
-EXAMPLES = """
----
-# Using merged
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# ip address 10.1.1.1 255.255.255.0
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description This is test
-# no ip address
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# no ip address
-# interface GigabitEthernet0/3.100
-# encapsulation dot1Q 20
-
-- name: Merge provided configuration with device configuration
- ios_l3_interfaces:
- config:
- - name: GigabitEthernet0/1
- ipv4:
- - address: 192.168.0.1/24
- secondary: True
- - name: GigabitEthernet0/2
- ipv4:
- - address: 192.168.0.2/24
- - name: GigabitEthernet0/3
- ipv6:
- - address: fd5d:12c9:2201:1::1/64
- - name: GigabitEthernet0/3.100
- ipv4:
- - address: 192.168.0.3/24
- state: merged
-
-# After state:
-# ------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# ip address 10.1.1.1 255.255.255.0
-# ip address 192.168.0.1 255.255.255.0 secondary
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description This is test
-# ip address 192.168.0.2 255.255.255.0
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# ipv6 address FD5D:12C9:2201:1::1/64
-# interface GigabitEthernet0/3.100
-# encapsulation dot1Q 20
-# ip address 192.168.0.3 255.255.255.0
-
-# Using replaced
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# ip address 10.1.1.1 255.255.255.0
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description This is test
-# no ip address
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# ip address 192.168.2.0 255.255.255.0
-# interface GigabitEthernet0/3.100
-# encapsulation dot1Q 20
-# ip address 192.168.0.2 255.255.255.0
-
-- name: Replaces device configuration of listed interfaces with provided configuration
- ios_l3_interfaces:
- config:
- - name: GigabitEthernet0/2
- ipv4:
- - address: 192.168.2.0/24
- - name: GigabitEthernet0/3
- ipv4:
- - address: dhcp
- dhcp_client: 2
- dhcp_hostname: test.com
- - name: GigabitEthernet0/3.100
- ipv4:
- - address: 192.168.0.3/24
- secondary: True
- state: replaced
-
-# After state:
-# ------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# ip address 10.1.1.1 255.255.255.0
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description This is test
-# ip address 192.168.2.1 255.255.255.0
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# ip address dhcp client-id GigabitEthernet0/2 hostname test.com
-# interface GigabitEthernet0/3.100
-# encapsulation dot1Q 20
-# ip address 192.168.0.2 255.255.255.0
-# ip address 192.168.0.3 255.255.255.0 secondary
-
-# Using overridden
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# ip address 10.1.1.1 255.255.255.0
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description This is test
-# ip address 192.168.2.1 255.255.255.0
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# ipv6 address FD5D:12C9:2201:1::1/64
-# interface GigabitEthernet0/3.100
-# encapsulation dot1Q 20
-# ip address 192.168.0.2 255.255.255.0
-
-- name: Override device configuration of all interfaces with provided configuration
- ios_l3_interfaces:
- config:
- - name: GigabitEthernet0/2
- ipv4:
- - address: 192.168.0.1/24
- - name: GigabitEthernet0/3.100
- ipv6:
- - address: autoconfig
- state: overridden
-
-# After state:
-# ------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# description Configured by Ansible
-# no ip address
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description This is test
-# ip address 192.168.0.1 255.255.255.0
-# duplex auto
-# speed 1000
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# interface GigabitEthernet0/3.100
-# encapsulation dot1Q 20
-# ipv6 address autoconfig
-
-# Using Deleted
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# ip address 192.0.2.10 255.255.255.0
-# shutdown
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description Configured by Ansible Network
-# ip address 192.168.1.0 255.255.255.0
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# ip address 192.168.0.1 255.255.255.0
-# shutdown
-# duplex full
-# speed 10
-# ipv6 address FD5D:12C9:2201:1::1/64
-# interface GigabitEthernet0/3.100
-# encapsulation dot1Q 20
-# ip address 192.168.0.2 255.255.255.0
-
-- name: "Delete attributes of given interfaces (NOTE: This won't delete the interface itself)"
- ios_l3_interfaces:
- config:
- - name: GigabitEthernet0/2
- - name: GigabitEthernet0/3.100
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# no ip address
-# shutdown
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description Configured by Ansible Network
-# no ip address
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# ip address 192.168.0.1 255.255.255.0
-# shutdown
-# duplex full
-# speed 10
-# ipv6 address FD5D:12C9:2201:1::1/64
-# interface GigabitEthernet0/3.100
-# encapsulation dot1Q 20
-
-# Using Deleted without any config passed
-#"(NOTE: This will delete all of configured L3 resource module attributes from each configured interface)"
-
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# ip address 192.0.2.10 255.255.255.0
-# shutdown
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description Configured by Ansible Network
-# ip address 192.168.1.0 255.255.255.0
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# ip address 192.168.0.1 255.255.255.0
-# shutdown
-# duplex full
-# speed 10
-# ipv6 address FD5D:12C9:2201:1::1/64
-# interface GigabitEthernet0/3.100
-# encapsulation dot1Q 20
-# ip address 192.168.0.2 255.255.255.0
-
-- name: "Delete L3 attributes of ALL interfaces together (NOTE: This won't delete the interface itself)"
- ios_l3_interfaces:
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface GigabitEthernet0/1
-# no ip address
-# shutdown
-# duplex auto
-# speed auto
-# interface GigabitEthernet0/2
-# description Configured by Ansible Network
-# no ip address
-# interface GigabitEthernet0/3
-# description Configured by Ansible Network
-# shutdown
-# duplex full
-# speed 10
-# interface GigabitEthernet0/3.100
-# encapsulation dot1Q 20
-
-"""
-
-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/1', 'ip address 192.168.0.2 255.255.255.0']
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.l3_interfaces.l3_interfaces import L3_InterfacesArgs
-from ansible.module_utils.network.ios.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',))]
-
- module = AnsibleModule(argument_spec=L3_InterfacesArgs.argument_spec,
- required_if=required_if,
- supports_check_mode=True)
-
- result = L3_Interfaces(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_lacp.py b/lib/ansible/modules/network/ios/ios_lacp.py
deleted file mode 100644
index 1ebe3b3cef..0000000000
--- a/lib/ansible/modules/network/ios/ios_lacp.py
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/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 ios_lacp
-"""
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {
- 'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'
-}
-
-DOCUMENTATION = """
----
-module: ios_lacp
-version_added: 2.9
-short_description: Manage Global Link Aggregation Control Protocol (LACP) on Cisco IOS devices.
-description: This module provides declarative management of Global LACP on Cisco IOS network devices.
-author: Sumit Jaiswal (@justjais)
-notes:
- - Tested against Cisco IOSv Version 15.2 on VIRL
- - This module works with connection C(network_cli),
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: The provided configurations.
- type: dict
- suboptions:
- system:
- description: This option sets the default system parameters for LACP.
- type: dict
- suboptions:
- priority:
- description:
- - LACP priority for the system.
- - Refer to vendor documentation for valid values.
- type: int
- required: True
- state:
- description:
- - The state of the configuration after module completion
- type: str
- choices:
- - merged
- - replaced
- - deleted
- default: merged
-"""
-
-EXAMPLES = """
-
-# Using merged
-#
-# Before state:
-# -------------
-#
-# vios#show lacp sys-id
-# 32768, 5e00.0000.8000
-
-- name: Merge provided configuration with device configuration
- ios_lacp:
- config:
- system:
- priority: 123
- state: merged
-
-# After state:
-# ------------
-#
-# vios#show lacp sys-id
-# 123, 5e00.0000.8000
-
-# Using replaced
-#
-# Before state:
-# -------------
-#
-# vios#show lacp sys-id
-# 500, 5e00.0000.8000
-
-- name: Replaces Global LACP configuration
- ios_lacp:
- config:
- system:
- priority: 123
- state: replaced
-
-# After state:
-# ------------
-#
-# vios#show lacp sys-id
-# 123, 5e00.0000.8000
-
-# Using Deleted
-#
-# Before state:
-# -------------
-#
-# vios#show lacp sys-id
-# 500, 5e00.0000.8000
-
-- name: Delete Global LACP attribute
- ios_lacp:
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show lacp sys-id
-# 32768, 5e00.0000.8000
-
-"""
-
-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: ['lacp system-priority 10']
-"""
-
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.lacp.lacp import LacpArgs
-from ansible.module_utils.network.ios.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',))]
-
- module = AnsibleModule(argument_spec=LacpArgs.argument_spec,
- required_if=required_if,
- supports_check_mode=True)
-
- result = Lacp(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_lacp_interfaces.py b/lib/ansible/modules/network/ios/ios_lacp_interfaces.py
deleted file mode 100644
index d9e52e39cf..0000000000
--- a/lib/ansible/modules/network/ios/ios_lacp_interfaces.py
+++ /dev/null
@@ -1,363 +0,0 @@
-#!/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 ios_lacp_interfaces
-"""
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {
- 'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'
-}
-
-
-DOCUMENTATION = """
----
-module: ios_lacp_interfaces
-version_added: 2.9
-short_description: Manage Link Aggregation Control Protocol (LACP) on Cisco IOS devices interface.
-description: This module provides declarative management of LACP on Cisco IOS network devices lacp_interfaces.
-author: Sumit Jaiswal (@justjais)
-notes:
- - Tested against Cisco IOSv Version 15.2 on VIRL.
- - This module works with connection C(network_cli),
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: A dictionary of LACP lacp_interfaces option
- type: list
- elements: dict
- suboptions:
- name:
- description:
- - Name of the Interface for configuring LACP.
- type: str
- required: True
- port_priority:
- description:
- - LACP priority on this interface.
- - Refer to vendor documentation for valid port values.
- type: int
- fast_switchover:
- description:
- - LACP fast switchover supported on this port channel.
- type: bool
- max_bundle:
- description:
- - LACP maximum number of ports to bundle in this port channel.
- - Refer to vendor documentation for valid port values.
- type: int
- state:
- description:
- - The state of the configuration after module completion
- type: str
- choices:
- - merged
- - replaced
- - overridden
- - deleted
- default: merged
-"""
-
-EXAMPLES = """
-
-# Using merged
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# interface GigabitEthernet0/2
-# shutdown
-# interface GigabitEthernet0/3
-# shutdown
-
-- name: Merge provided configuration with device configuration
- ios_lacp_interfaces:
- config:
- - name: GigabitEthernet0/1
- port_priority: 10
- - name: GigabitEthernet0/2
- port_priority: 20
- - name: GigabitEthernet0/3
- port_priority: 30
- - name: Port-channel10
- fast_switchover: True
- max_bundle: 5
- state: merged
-
-# After state:
-# ------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# lacp fast-switchover
-# lacp max-bundle 5
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# lacp port-priority 10
-# interface GigabitEthernet0/2
-# shutdown
-# lacp port-priority 20
-# interface GigabitEthernet0/3
-# shutdown
-# lacp port-priority 30
-
-# Using overridden
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# lacp fast-switchover
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# lacp port-priority 10
-# interface GigabitEthernet0/2
-# shutdown
-# lacp port-priority 20
-# interface GigabitEthernet0/3
-# shutdown
-# lacp port-priority 30
-
-- name: Override device configuration of all lacp_interfaces with provided configuration
- ios_lacp_interfaces:
- config:
- - name: GigabitEthernet0/1
- port_priority: 20
- - name: Port-channel10
- max_bundle: 2
- state: overridden
-
-# After state:
-# ------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# lacp max-bundle 2
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# lacp port-priority 20
-# interface GigabitEthernet0/2
-# shutdown
-# interface GigabitEthernet0/3
-# shutdown
-
-# Using replaced
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# lacp max-bundle 5
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# lacp port-priority 10
-# interface GigabitEthernet0/2
-# shutdown
-# lacp port-priority 20
-# interface GigabitEthernet0/3
-# shutdown
-# lacp port-priority 30
-
-- name: Replaces device configuration of listed lacp_interfaces with provided configuration
- ios_lacp_interfaces:
- config:
- - name: GigabitEthernet0/3
- port_priority: 40
- - name: Port-channel10
- fast_switchover: True
- max_bundle: 2
- state: replaced
-
-# After state:
-# ------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# lacp fast-switchover
-# lacp max-bundle 2
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# lacp port-priority 10
-# interface GigabitEthernet0/2
-# shutdown
-# lacp port-priority 20
-# interface GigabitEthernet0/3
-# shutdown
-# lacp port-priority 40
-
-# Using Deleted
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# flowcontrol receive on
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# lacp port-priority 10
-# interface GigabitEthernet0/2
-# shutdown
-# lacp port-priority 20
-# interface GigabitEthernet0/3
-# shutdown
-# lacp port-priority 30
-
-- name: "Delete LACP attributes of given interfaces (Note: This won't delete the interface itself)"
- ios_lacp_interfaces:
- config:
- - name: GigabitEthernet0/1
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# interface GigabitEthernet0/2
-# shutdown
-# lacp port-priority 20
-# interface GigabitEthernet0/3
-# shutdown
-# lacp port-priority 30
-
-# Using Deleted without any config passed
-# "(NOTE: This will delete all of configured LLDP module attributes)"
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# lacp fast-switchover
-# interface Port-channel20
-# lacp max-bundle 2
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# lacp port-priority 10
-# interface GigabitEthernet0/2
-# shutdown
-# lacp port-priority 20
-# interface GigabitEthernet0/3
-# shutdown
-# lacp port-priority 30
-
-- name: "Delete LACP attributes for all configured interfaces (Note: This won't delete the interface itself)"
- ios_lacp_interfaces:
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# interface GigabitEthernet0/2
-# shutdown
-# interface GigabitEthernet0/3
-# shutdown
-
-"""
-
-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 GigabitEthernet 0/1', 'lacp port-priority 30']
-"""
-
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.lacp_interfaces.lacp_interfaces import Lacp_InterfacesArgs
-from ansible.module_utils.network.ios.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',))]
-
- module = AnsibleModule(argument_spec=Lacp_InterfacesArgs.argument_spec,
- required_if=required_if,
- supports_check_mode=True)
-
- result = Lacp_Interfaces(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_lag_interfaces.py b/lib/ansible/modules/network/ios/ios_lag_interfaces.py
deleted file mode 100644
index b5351c6dd8..0000000000
--- a/lib/ansible/modules/network/ios/ios_lag_interfaces.py
+++ /dev/null
@@ -1,390 +0,0 @@
-#!/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
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_lag_interfaces
-version_added: 2.9
-short_description: Manage Link Aggregation on Cisco IOS devices.
-description: This module manages properties of Link Aggregation Group on Cisco IOS devices.
-author: Sumit Jaiswal (@justjais)
-notes:
- - Tested against Cisco IOSv Version 15.2 on VIRL
- - This module works with connection C(network_cli).
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: A list of link aggregation group configurations.
- type: list
- elements: dict
- suboptions:
- name:
- description:
- - ID of Ethernet Channel of interfaces.
- - Refer to vendor documentation for valid port values.
- type: str
- required: True
- members:
- description:
- - Interface options for the link aggregation group.
- type: list
- suboptions:
- member:
- description:
- - Interface member of the link aggregation group.
- type: str
- mode:
- description:
- - Etherchannel Mode of the interface for link aggregation.
- type: str
- choices:
- - 'auto'
- - 'on'
- - 'desirable'
- - 'active'
- - 'passive'
- link:
- description:
- - Assign a link identifier used for load-balancing.
- - Refer to vendor documentation for valid values.
- - NOTE, parameter only supported on Cisco IOS XE platform.
- type: int
- state:
- description:
- - The state of the configuration after module completion
- type: str
- choices:
- - merged
- - replaced
- - overridden
- - deleted
- default: merged
-"""
-
-EXAMPLES = """
----
-# Using merged
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface GigabitEthernet0/1
-# shutdown
-# interface GigabitEthernet0/2
-# shutdown
-# interface GigabitEthernet0/3
-# shutdown
-# interface GigabitEthernet0/4
-# shutdown
-
-- name: Merge provided configuration with device configuration
- ios_lag_interfaces:
- config:
- - name: 10
- members:
- - member: GigabitEthernet0/1
- mode: auto
- - member: GigabitEthernet0/2
- mode: auto
- - name: 20
- members:
- - member: GigabitEthernet0/3
- mode: on
- - name: 30
- members:
- - member: GigabitEthernet0/4
- mode: active
- state: merged
-
-# After state:
-# ------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/2
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/3
-# shutdown
-# channel-group 20 mode on
-# interface GigabitEthernet0/4
-# shutdown
-# channel-group 30 mode active
-
-# Using overridden
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/2
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/3
-# shutdown
-# channel-group 20 mode on
-# interface GigabitEthernet0/4
-# shutdown
-# channel-group 30 mode active
-
-- name: Override device configuration of all interfaces with provided configuration
- ios_lag_interfaces:
- config:
- - name: 20
- members:
- - member: GigabitEthernet0/2
- mode: auto
- - member: GigabitEthernet0/3
- mode: auto
- state: overridden
-
-# After state:
-# ------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# interface GigabitEthernet0/2
-# shutdown
-# channel-group 20 mode auto
-# interface GigabitEthernet0/3
-# shutdown
-# channel-group 20 mode auto
-# interface GigabitEthernet0/4
-# shutdown
-
-# Using replaced
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/2
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/3
-# shutdown
-# channel-group 20 mode on
-# interface GigabitEthernet0/4
-# shutdown
-# channel-group 30 mode active
-
-- name: Replaces device configuration of listed interfaces with provided configuration
- ios_lag_interfaces:
- config:
- - name: 40
- members:
- - member: GigabitEthernet0/3
- mode: auto
- state: replaced
-
-# After state:
-# ------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface Port-channel40
-# interface GigabitEthernet0/1
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/2
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/3
-# shutdown
-# channel-group 40 mode on
-# interface GigabitEthernet0/4
-# shutdown
-# channel-group 30 mode active
-
-# Using Deleted
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/2
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/3
-# shutdown
-# channel-group 20 mode on
-# interface GigabitEthernet0/4
-# shutdown
-# channel-group 30 mode active
-
-- name: "Delete LAG attributes of given interfaces (Note: This won't delete the interface itself)"
- ios_lag_interfaces:
- config:
- - name: 10
- - name: 20
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# interface GigabitEthernet0/2
-# shutdown
-# interface GigabitEthernet0/3
-# shutdown
-# interface GigabitEthernet0/4
-# shutdown
-# channel-group 30 mode active
-
-# Using Deleted without any config passed
-#"(NOTE: This will delete all of configured LLDP module attributes)"
-
-#
-# Before state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/2
-# shutdown
-# channel-group 10 mode auto
-# interface GigabitEthernet0/3
-# shutdown
-# channel-group 20 mode on
-# interface GigabitEthernet0/4
-# shutdown
-# channel-group 30 mode active
-
-- name: "Delete all configured LAG attributes for interfaces (Note: This won't delete the interface itself)"
- ios_lag_interfaces:
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show running-config | section ^interface
-# interface Port-channel10
-# interface Port-channel20
-# interface Port-channel30
-# interface GigabitEthernet0/1
-# shutdown
-# interface GigabitEthernet0/2
-# shutdown
-# interface GigabitEthernet0/3
-# shutdown
-# interface GigabitEthernet0/4
-# shutdown
-"""
-
-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/1', 'channel-group 1 mode active']
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.lag_interfaces.lag_interfaces import Lag_interfacesArgs
-from ansible.module_utils.network.ios.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',))]
-
- module = AnsibleModule(argument_spec=Lag_interfacesArgs.argument_spec,
- required_if=required_if,
- supports_check_mode=True)
-
- result = Lag_interfaces(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_linkagg.py b/lib/ansible/modules/network/ios/ios_linkagg.py
deleted file mode 100644
index 61620e6b57..0000000000
--- a/lib/ansible/modules/network/ios/ios_linkagg.py
+++ /dev/null
@@ -1,318 +0,0 @@
-#!/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
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-DOCUMENTATION = """
----
-module: ios_linkagg
-version_added: "2.5"
-author: "Trishna Guha (@trishnaguha)"
-short_description: Manage link aggregation groups on Cisco IOS network devices
-description:
- - This module provides declarative management of link aggregation groups
- on Cisco IOS network devices.
-notes:
- - Tested against IOS 15.2
-options:
- group:
- description:
- - Channel-group number for the port-channel
- Link aggregation group. Range 1-255.
- mode:
- description:
- - Mode of the link aggregation group.
- choices: ['active', 'on', 'passive', 'auto', 'desirable']
- members:
- description:
- - List of members of the link aggregation group.
- aggregate:
- description: List of link aggregation definitions.
- state:
- description:
- - State of the link aggregation group.
- default: present
- choices: ['present', 'absent']
- purge:
- description:
- - Purge links not defined in the I(aggregate) parameter.
- default: no
- type: bool
-extends_documentation_fragment: ios
-"""
-
-EXAMPLES = """
-- name: create link aggregation group
- ios_linkagg:
- group: 10
- state: present
-
-- name: delete link aggregation group
- ios_linkagg:
- group: 10
- state: absent
-
-- name: set link aggregation group to members
- ios_linkagg:
- group: 200
- mode: active
- members:
- - GigabitEthernet0/0
- - GigabitEthernet0/1
-
-- name: remove link aggregation group from GigabitEthernet0/0
- ios_linkagg:
- group: 200
- mode: active
- members:
- - GigabitEthernet0/1
-
-- name: Create aggregate of linkagg definitions
- ios_linkagg:
- aggregate:
- - { group: 3, mode: on, members: [GigabitEthernet0/1] }
- - { group: 100, mode: passive, members: [GigabitEthernet0/2] }
-"""
-
-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:
- - interface port-channel 30
- - interface GigabitEthernet0/3
- - channel-group 30 mode on
- - no interface port-channel 30
-"""
-
-import re
-from copy import deepcopy
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.common.config import CustomNetworkConfig
-from ansible.module_utils.network.common.utils import remove_default_spec
-from ansible.module_utils.network.ios.ios import get_config, load_config
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-
-
-def search_obj_in_list(group, lst):
- for o in lst:
- if o['group'] == group:
- return o
-
-
-def map_obj_to_commands(updates, module):
- commands = list()
- want, have = updates
- purge = module.params['purge']
-
- for w in want:
- group = w['group']
- mode = w['mode']
- members = w.get('members') or []
- state = w['state']
- del w['state']
-
- obj_in_have = search_obj_in_list(group, have)
-
- if state == 'absent':
- if obj_in_have:
- commands.append('no interface port-channel {0}'.format(group))
-
- elif state == 'present':
- cmd = ['interface port-channel {0}'.format(group),
- 'end']
- if not obj_in_have:
- if not group:
- module.fail_json(msg='group is a required option')
- commands.extend(cmd)
-
- if members:
- for m in members:
- commands.append('interface {0}'.format(m))
- commands.append('channel-group {0} mode {1}'.format(group, mode))
-
- else:
- if members:
- if 'members' not in obj_in_have.keys():
- for m in members:
- commands.extend(cmd)
- commands.append('interface {0}'.format(m))
- commands.append('channel-group {0} mode {1}'.format(group, mode))
-
- elif set(members) != set(obj_in_have['members']):
- missing_members = list(set(members) - set(obj_in_have['members']))
- for m in missing_members:
- commands.extend(cmd)
- commands.append('interface {0}'.format(m))
- commands.append('channel-group {0} mode {1}'.format(group, mode))
-
- superfluous_members = list(set(obj_in_have['members']) - set(members))
- for m in superfluous_members:
- commands.extend(cmd)
- commands.append('interface {0}'.format(m))
- commands.append('no channel-group {0} mode {1}'.format(group, mode))
-
- if purge:
- for h in have:
- obj_in_want = search_obj_in_list(h['group'], want)
- if not obj_in_want:
- commands.append('no interface port-channel {0}'.format(h['group']))
-
- return commands
-
-
-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]
-
- d = item.copy()
- d['group'] = str(d['group'])
-
- obj.append(d)
- else:
- obj.append({
- 'group': str(module.params['group']),
- 'mode': module.params['mode'],
- 'members': module.params['members'],
- 'state': module.params['state']
- })
-
- return obj
-
-
-def parse_mode(module, config, group, member):
- mode = None
- netcfg = CustomNetworkConfig(indent=1, contents=config)
- parents = ['interface {0}'.format(member)]
- body = netcfg.get_section(parents)
-
- match_int = re.findall(r'interface {0}\n'.format(member), body, re.M)
- if match_int:
- match = re.search(r'channel-group {0} mode (\S+)'.format(group), body, re.M)
- if match:
- mode = match.group(1)
-
- return mode
-
-
-def parse_members(module, config, group):
- members = []
-
- for line in config.strip().split('!'):
- l = line.strip()
- if l.startswith('interface'):
- match_group = re.findall(r'channel-group {0} mode'.format(group), l, re.M)
- if match_group:
- match = re.search(r'interface (\S+)', l, re.M)
- if match:
- members.append(match.group(1))
-
- return members
-
-
-def get_channel(module, config, group):
- match = re.findall(r'^interface (\S+)', config, re.M)
-
- if not match:
- return {}
-
- channel = {}
- for item in set(match):
- member = item
- channel['mode'] = parse_mode(module, config, group, member)
- channel['members'] = parse_members(module, config, group)
-
- return channel
-
-
-def map_config_to_obj(module):
- objs = list()
- config = get_config(module)
-
- for line in config.split('\n'):
- l = line.strip()
- match = re.search(r'interface Port-channel(\S+)', l, re.M)
- if match:
- obj = {}
- group = match.group(1)
- obj['group'] = group
- obj.update(get_channel(module, config, group))
- objs.append(obj)
-
- return objs
-
-
-def main():
- """ main entry point for module execution
- """
- element_spec = dict(
- group=dict(type='int'),
- mode=dict(choices=['active', 'on', 'passive', 'auto', 'desirable']),
- members=dict(type='list'),
- state=dict(default='present',
- choices=['present', 'absent'])
- )
-
- aggregate_spec = deepcopy(element_spec)
- aggregate_spec['group'] = dict(required=True)
-
- required_one_of = [['group', 'aggregate']]
- required_together = [['members', 'mode']]
- mutually_exclusive = [['group', 'aggregate']]
-
- # 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,
- required_together=required_together),
- purge=dict(default=False, type='bool')
- )
-
- argument_spec.update(element_spec)
- argument_spec.update(ios_argument_spec)
-
- module = AnsibleModule(argument_spec=argument_spec,
- required_one_of=required_one_of,
- required_together=required_together,
- 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:
- if not module.check_mode:
- load_config(module, commands)
- result['changed'] = True
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_lldp.py b/lib/ansible/modules/network/ios/ios_lldp.py
deleted file mode 100644
index 7ba7bf385a..0000000000
--- a/lib/ansible/modules/network/ios/ios_lldp.py
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/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
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_lldp
-version_added: "2.5"
-author: "Ganesh Nalawade (@ganeshrn)"
-short_description: Manage LLDP configuration on Cisco IOS network devices.
-description:
- - This module provides declarative management of LLDP service
- on Cisco IOS network devices.
-notes:
- - Tested against IOS 15.2
-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
- choices: ['present', 'absent']
-extends_documentation_fragment: ios
-"""
-
-EXAMPLES = """
-- name: Enable LLDP service
- ios_lldp:
- state: present
-
-- name: Disable LLDP service
- ios_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.module_utils.network.ios.ios import load_config, run_commands
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-
-
-def has_lldp(module):
- output = run_commands(module, ['show lldp'])
-
- is_lldp_enable = False
- if len(output) > 0 and "LLDP is not enabled" not in output[0]:
- 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'])
- )
-
- argument_spec.update(ios_argument_spec)
-
- 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:
- if not module.check_mode:
- load_config(module, commands)
-
- result['changed'] = True
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_lldp_global.py b/lib/ansible/modules/network/ios/ios_lldp_global.py
deleted file mode 100644
index 49c146f8d2..0000000000
--- a/lib/ansible/modules/network/ios/ios_lldp_global.py
+++ /dev/null
@@ -1,256 +0,0 @@
-#!/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 ios_lldp_global
-"""
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_lldp_global
-version_added: 2.9
-short_description: Configure and manage Link Layer Discovery Protocol(LLDP) attributes on IOS platforms.
-description: This module configures and manages the Link Layer Discovery Protocol(LLDP) attributes on IOS platforms.
-author: Sumit Jaiswal (@justjais)
-notes:
- - Tested against Cisco IOSv Version 15.2 on VIRL
- - This module works with connection C(network_cli),
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: A dictionary of LLDP options
- type: dict
- suboptions:
- holdtime:
- description:
- - LLDP holdtime (in sec) to be sent in packets.
- - Refer to vendor documentation for valid values.
- type: int
- reinit:
- description:
- - Specify the delay (in secs) for LLDP to initialize.
- - Refer to vendor documentation for valid values.
- - NOTE, if LLDP reinit is configured with a starting
- value, idempotency won't be maintained as the Cisco
- device doesn't record the starting reinit configured
- value. As such, Ansible cannot verify if the respective
- starting reinit value is already configured or not from
- the device side. If you try to apply starting reinit
- value in every play run, Ansible will show changed as True.
- For any other reinit value, idempotency will be maintained
- since any other reinit value is recorded in the Cisco device.
- type: int
- enabled:
- description:
- - Enable LLDP
- type: bool
- timer:
- description:
- - Specify the rate at which LLDP packets are sent (in sec).
- - Refer to vendor documentation for valid values.
- type: int
- tlv_select:
- description:
- - Selection of LLDP TLVs i.e. type-length-value to send
- - NOTE, if tlv-select is configured idempotency won't be maintained
- as Cisco device doesn't record configured tlv-select options. As
- such, Ansible cannot verify if the respective tlv-select options is
- already configured or not from the device side. If you try to apply
- tlv-select option in every play run, Ansible will show changed as True.
- type: dict
- suboptions:
- four_wire_power_management:
- description:
- - Cisco 4-wire Power via MDI TLV
- type: bool
- mac_phy_cfg:
- description:
- - IEEE 802.3 MAC/Phy Configuration/status TLV
- type: bool
- management_address:
- description:
- - Management Address TLV
- type: bool
- port_description:
- description:
- - Port Description TLV
- type: bool
- port_vlan:
- description:
- - Port VLAN ID TLV
- type: bool
- power_management:
- description:
- - IEEE 802.3 DTE Power via MDI TLV
- type: bool
- system_capabilities:
- description:
- - System Capabilities TLV
- type: bool
- system_description:
- description:
- - System Description TLV
- type: bool
- system_name:
- description:
- - System Name TLV
- type: bool
- state:
- description:
- - The state of the configuration after module completion
- type: str
- choices:
- - merged
- - replaced
- - deleted
- default: merged
-"""
-
-EXAMPLES = """
----
-
-# Using merged
-
-# Before state:
-# -------------
-# vios#sh running-config | section ^lldp
-# vios1#
-
-
-- name: Merge provided configuration with device configuration
- ios_lldp_global:
- config:
- holdtime: 10
- enabled: True
- reinit: 3
- timer: 10
- state: merged
-
-# After state:
-# ------------
-# vios#sh running-config | section ^lldp
-# lldp timer 10
-# lldp holdtime 10
-# lldp reinit 3
-# lldp run
-
-
-# Using replaced
-
-# Before state:
-# -------------
-# vios#sh running-config | section ^lldp
-# lldp timer 10
-# lldp holdtime 10
-# lldp reinit 3
-# lldp run
-
-
-- name: Replaces LLDP device configuration with provided configuration
- ios_lldp_global:
- config:
- holdtime: 20
- reinit: 5
- state: replaced
-
-# After state:
-# -------------
-# vios#sh running-config | section ^lldp
-# lldp holdtime 20
-# lldp reinit 5
-
-
-# Using Deleted without any config passed
-#"(NOTE: This will delete all of configured LLDP module attributes)"
-
-# Before state:
-# -------------
-# vios#sh running-config | section ^lldp
-# lldp timer 10
-# lldp holdtime 10
-# lldp reinit 3
-# lldp run
-
-
-- name: "Delete LLDP attributes (Note: This won't delete the interface itself)"
- ios_lldp_global:
- state: deleted
-
-# After state:
-# -------------
-# vios#sh running-config | section ^lldp
-# vios1#
-
-"""
-
-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 10', 'lldp run', 'lldp timer 10']
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.lldp_global.lldp_global import Lldp_globalArgs
-from ansible.module_utils.network.ios.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',))]
-
- module = AnsibleModule(argument_spec=Lldp_globalArgs.argument_spec,
- required_if=required_if,
- supports_check_mode=True)
-
- result = Lldp_global(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_lldp_interfaces.py b/lib/ansible/modules/network/ios/ios_lldp_interfaces.py
deleted file mode 100644
index c1bbc274e4..0000000000
--- a/lib/ansible/modules/network/ios/ios_lldp_interfaces.py
+++ /dev/null
@@ -1,501 +0,0 @@
-#!/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 ios_lldp_interfaces
-"""
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {
- 'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'
-}
-
-
-DOCUMENTATION = """
----
-module: ios_lldp_interfaces
-version_added: 2.9
-short_description: Manage link layer discovery protocol (LLDP) attributes of interfaces on Cisco IOS devices.
-description: This module manages link layer discovery protocol (LLDP) attributes of interfaces on Cisco IOS devices.
-author: Sumit Jaiswal (@justjais)
-notes:
- - Tested against Cisco IOSv Version 15.2 on VIRL
- - This module works with connection C(network_cli),
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: A dictionary of LLDP 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
- receive:
- description:
- - Enable LLDP reception on interface.
- type: bool
- transmit:
- description:
- - Enable LLDP transmission on interface.
- type: bool
- med_tlv_select:
- description:
- - Selection of LLDP MED TLVs to send
- - NOTE, if med-tlv-select is configured idempotency won't be maintained
- as Cisco device doesn't record configured med-tlv-select options. As
- such, Ansible cannot verify if the respective med-tlv-select options is
- already configured or not from the device side. If you try to apply
- med-tlv-select option in every play run, Ansible will show changed as
- True.
- type: dict
- suboptions:
- inventory_management:
- description:
- - LLDP MED Inventory Management TLV
- type: bool
- tlv_select:
- description:
- - Selection of LLDP type-length-value i.e. TLVs to send
- - NOTE, if tlv-select is configured idempotency won't be maintained
- as Cisco device doesn't record configured tlv-select options. As
- such, Ansible cannot verify if the respective tlv-select options is
- already configured or not from the device side. If you try to apply
- tlv-select option in every play run, Ansible will show changed as True.
- type: dict
- suboptions:
- power_management:
- description:
- - IEEE 802.3 DTE Power via MDI TLV
- type: bool
- state:
- description:
- - The state of the configuration after module completion
- type: str
- choices:
- - merged
- - replaced
- - overridden
- - deleted
- default: merged
-"""
-
-EXAMPLES = """
-
-# Using merged
-#
-# Before state:
-# -------------
-#
-# vios#sh lldp interface
-# GigabitEthernet0/0:
-# Tx: enabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/1:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/2:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: INIT
-#
-# GigabitEthernet0/3:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-
-- name: Merge provided configuration with device configuration
- ios_lldp_interfaces:
- config:
- - name: GigabitEthernet0/1
- receive: True
- transmit: True
- - name: GigabitEthernet0/2
- receive: True
- - name: GigabitEthernet0/3
- transmit: True
- state: merged
-
-# After state:
-# ------------
-#
-# vios#sh lldp interface
-# GigabitEthernet0/0:
-# Tx: enabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/1:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/2:
-# Tx: disabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: INIT
-#
-# GigabitEthernet0/3:
-# Tx: enabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-
-# Using overridden
-#
-# Before state:
-# -------------
-#
-# vios#sh lldp interface
-# GigabitEthernet0/0:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/1:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/2:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: INIT
-#
-# GigabitEthernet0/3:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-
-- name: Override device configuration of all lldp_interfaces with provided configuration
- ios_lldp_interfaces:
- config:
- - name: GigabitEthernet0/2
- receive: True
- transmit: True
- state: overridden
-
-# After state:
-# ------------
-#
-# vios#sh lldp interface
-# GigabitEthernet0/0:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/1:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/2:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: INIT
-#
-# GigabitEthernet0/3:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-
-# Using replaced
-#
-# Before state:
-# -------------
-#
-# vios#sh lldp interface
-# GigabitEthernet0/0:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/1:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/2:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: INIT
-#
-# GigabitEthernet0/3:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-
-- name: Replaces device configuration of listed lldp_interfaces with provided configuration
- ios_lldp_interfaces:
- config:
- - name: GigabitEthernet0/2
- receive: True
- transmit: True
- - name: GigabitEthernet0/3
- receive: True
- state: replaced
-
-# After state:
-# ------------
-#
-# vios#sh lldp interface
-# GigabitEthernet0/0:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/1:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/2:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: INIT
-#
-# GigabitEthernet0/3:
-# Tx: disabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-
-# Using Deleted
-#
-# Before state:
-# -------------
-#
-# vios#sh lldp interface
-# GigabitEthernet0/0:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/1:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/2:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: INIT
-#
-# GigabitEthernet0/3:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-
-- name: "Delete LLDP attributes of given interfaces (Note: This won't delete the interface itself)"
- ios_lldp_interfaces:
- config:
- - name: GigabitEthernet0/1
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#sh lldp interface
-# GigabitEthernet0/0:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/1:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/2:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: INIT
-#
-# GigabitEthernet0/3:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-
-# Using Deleted without any config passed
-# "(NOTE: This will delete all of configured LLDP module attributes)"
-#
-# Before state:
-# -------------
-#
-# vios#sh lldp interface
-# GigabitEthernet0/0:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/1:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/2:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: INIT
-#
-# GigabitEthernet0/3:
-# Tx: enabled
-# Rx: enabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-
-- name: "Delete LLDP attributes for all configured interfaces (Note: This won't delete the interface itself)"
- ios_lldp_interfaces:
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#sh lldp interface
-# GigabitEthernet0/0:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/1:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-# GigabitEthernet0/2:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: INIT
-#
-# GigabitEthernet0/3:
-# Tx: disabled
-# Rx: disabled
-# Tx state: IDLE
-# Rx state: WAIT FOR FRAME
-#
-
-"""
-
-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 GigabitEthernet 0/1', 'lldp transmit', 'lldp receive']
-"""
-
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.lldp_interfaces.lldp_interfaces import Lldp_InterfacesArgs
-from ansible.module_utils.network.ios.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',))]
-
- module = AnsibleModule(argument_spec=Lldp_InterfacesArgs.argument_spec,
- required_if=required_if,
- supports_check_mode=True)
-
- result = Lldp_Interfaces(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_logging.py b/lib/ansible/modules/network/ios/ios_logging.py
deleted file mode 100644
index b91f3ff2b9..0000000000
--- a/lib/ansible/modules/network/ios/ios_logging.py
+++ /dev/null
@@ -1,429 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# (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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-DOCUMENTATION = """
----
-module: ios_logging
-version_added: "2.4"
-author: "Trishna Guha (@trishnaguha)"
-short_description: Manage logging on network devices
-description:
- - This module provides declarative management of logging
- on Cisco Ios devices.
-notes:
- - Tested against IOS 15.6
-options:
- dest:
- description:
- - Destination of the logs.
- choices: ['on', 'host', 'console', 'monitor', 'buffered', 'trap']
- name:
- description:
- - The hostname or IP address of the destination.
- - Required when I(dest=host).
- size:
- description:
- - Size of buffer. The acceptable value is in range from 4096 to
- 4294967295 bytes.
- default: 4096
- facility:
- description:
- - Set logging facility.
- level:
- description:
- - Set logging severity levels.
- default: debugging
- choices: ['emergencies', 'alerts', 'critical', 'errors', 'warnings', 'notifications', 'informational', 'debugging']
- aggregate:
- description: List of logging definitions.
- state:
- description:
- - State of the logging configuration.
- default: present
- choices: ['present', 'absent']
-extends_documentation_fragment: ios
-"""
-
-EXAMPLES = """
-- name: configure host logging
- ios_logging:
- dest: host
- name: 172.16.0.1
- state: present
-
-- name: remove host logging configuration
- ios_logging:
- dest: host
- name: 172.16.0.1
- state: absent
-
-- name: configure console logging level and facility
- ios_logging:
- dest: console
- facility: local7
- level: debugging
- state: present
-
-- name: enable logging to all
- ios_logging:
- dest : on
-
-- name: configure buffer size
- ios_logging:
- dest: buffered
- size: 5000
-
-- name: Configure logging using aggregate
- ios_logging:
- aggregate:
- - { dest: console, level: notifications }
- - { dest: buffered, size: 9000 }
-
-- name: remove logging using aggregate
- ios_logging:
- aggregate:
- - { dest: console, level: notifications }
- - { dest: buffered, size: 9000 }
- state: absent
-"""
-
-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.basic import AnsibleModule
-from ansible.module_utils.network.common.utils import remove_default_spec, validate_ip_address
-from ansible.module_utils.network.ios.ios import get_config, load_config
-from ansible.module_utils.network.ios.ios import get_capabilities
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-
-
-def validate_size(value, module):
- if value:
- if not int(4096) <= int(value) <= int(4294967295):
- module.fail_json(msg='size must be between 4096 and 4294967295')
- else:
- return value
-
-
-def map_obj_to_commands(updates, module, os_version):
- dest_group = ('console', 'monitor', 'buffered', 'on', 'trap')
- 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 facility:
- w['dest'] = 'facility'
-
- if state == 'absent' and w in have:
- if dest:
- if dest == 'host':
- if '12.' in os_version:
- commands.append('no logging {0}'.format(name))
- else:
- 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, trap')
-
- if facility:
- commands.append('no logging facility {0}'.format(facility))
-
- if state == 'present' and w not in have:
- if facility:
- present = False
-
- for entry in have:
- if entry['dest'] == 'facility' and entry['facility'] == facility:
- present = True
-
- if not present:
- commands.append('logging facility {0}'.format(facility))
-
- if dest == 'host':
- if '12.' in os_version:
- commands.append('logging {0}'.format(name))
- else:
- commands.append('logging host {0}'.format(name))
-
- elif dest == 'on':
- commands.append('logging on')
-
- elif dest == 'buffered' and size:
- present = False
-
- for entry in have:
- if entry['dest'] == 'buffered' and entry['size'] == size and entry['level'] == level:
- present = True
-
- if not present:
- if level and level != 'debugging':
- 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, dest):
- facility = None
- if dest == 'facility':
- 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(?: (\d+))?(?: [a-z]+)?', line, re.M)
- if match:
- if match.group(1) is not None:
- size = match.group(1)
- else:
- size = "4096"
-
- return size
-
-
-def parse_name(line, dest):
- if dest == 'host':
- match = re.search(r'logging host (\S+)', line, re.M)
- if match:
- name = match.group(1)
- else:
- name = None
-
- return name
-
-
-def parse_level(line, dest):
- level_group = ('emergencies', 'alerts', 'critical', 'errors', 'warnings',
- 'notifications', 'informational', 'debugging')
-
- if dest == 'host':
- level = 'debugging'
-
- else:
- if dest == 'buffered':
- match = re.search(r'logging buffered(?: \d+)?(?: ([a-z]+))?', line, re.M)
- else:
- match = re.search(r'logging {0} (\S+)'.format(dest), line, re.M)
-
- if match and match.group(1) in level_group:
- level = match.group(1)
- else:
- level = 'debugging'
-
- return level
-
-
-def map_config_to_obj(module):
- obj = []
- dest_group = ('console', 'host', 'monitor', 'buffered', 'on', 'facility', 'trap')
-
- data = get_config(module, flags=['| include 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)
-
- obj.append({
- 'dest': dest,
- 'name': parse_name(line, dest),
- 'size': parse_size(line, dest),
- 'facility': parse_facility(line, dest),
- 'level': parse_level(line, dest)
- })
- elif validate_ip_address(match.group(1)):
- dest = 'host'
- obj.append({
- 'dest': dest,
- 'name': match.group(1),
- 'size': parse_size(line, dest),
- 'facility': parse_facility(line, dest),
- 'level': parse_level(line, dest)
- })
- else:
- ip_match = re.search(r'\d+\.\d+\.\d+\.\d+', match.group(1), re.M)
- if ip_match:
- dest = 'host'
- obj.append({
- 'dest': dest,
- 'name': match.group(1),
- 'size': parse_size(line, dest),
- 'facility': parse_facility(line, dest),
- 'level': parse_level(line, dest)
- })
- 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]
-
- module._check_required_if(required_if, item)
-
- 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(4096)
- 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(4096)
- else:
- module.params['size'] = None
-
- 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 main():
- """ main entry point for module execution
- """
- element_spec = dict(
- dest=dict(type='str', choices=['on', 'host', 'console', 'monitor', 'buffered', 'trap']),
- name=dict(type='str'),
- size=dict(type='int'),
- facility=dict(type='str'),
- level=dict(type='str', default='debugging', choices=['emergencies', 'alerts', 'critical', 'errors', 'warnings',
- 'notifications', 'informational', 'debugging']),
- 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),
- )
-
- argument_spec.update(element_spec)
- argument_spec.update(ios_argument_spec)
-
- required_if = [('dest', 'host', ['name'])]
-
- module = AnsibleModule(argument_spec=argument_spec,
- required_if=required_if,
- supports_check_mode=True)
-
- device_info = get_capabilities(module)
- os_version = device_info['device_info']['network_os_version']
-
- warnings = list()
-
- result = {'changed': False}
- if warnings:
- result['warnings'] = warnings
-
- want = map_params_to_obj(module, required_if=required_if)
- have = map_config_to_obj(module)
-
- commands = map_obj_to_commands((want, have), module, os_version)
- result['commands'] = commands
-
- if commands:
- if not module.check_mode:
- load_config(module, commands)
- result['changed'] = True
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_ntp.py b/lib/ansible/modules/network/ios/ios_ntp.py
deleted file mode 100644
index 682140c375..0000000000
--- a/lib/ansible/modules/network/ios/ios_ntp.py
+++ /dev/null
@@ -1,308 +0,0 @@
-#!/usr/bin/python
-# Copyright: Ansible Project
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: ios_ntp
-extends_documentation_fragment: ios
-version_added: "2.8"
-short_description: Manages core NTP configuration.
-description:
- - Manages core NTP configuration.
-author:
- - Federico Olivieri (@Federico87)
-options:
- server:
- description:
- - Network address of NTP server.
- source_int:
- description:
- - Source interface for NTP packets.
- acl:
- description:
- - ACL for peer/server access restricition.
- logging:
- description:
- - Enable NTP logs. Data type boolean.
- type: bool
- default: False
- auth:
- description:
- - Enable NTP authentication. Data type boolean.
- type: bool
- default: False
- auth_key:
- description:
- - md5 NTP authentication key of tye 7.
- key_id:
- description:
- - auth_key id. Data type string
- state:
- description:
- - Manage the state of the resource.
- default: present
- choices: ['present', 'absent']
-'''
-
-EXAMPLES = '''
-# Set new NTP server and source interface
-- ios_ntp:
- server: 10.0.255.10
- source_int: Loopback0
- logging: false
- state: present
-
-# Remove NTP ACL and logging
-- ios_ntp:
- acl: NTP_ACL
- logging: true
- state: absent
-
-# Set NTP authentication
-- ios_ntp:
- key_id: 10
- auth_key: 15435A030726242723273C21181319000A
- auth: true
- state: present
-
-# Set new NTP configuration
-- ios_ntp:
- server: 10.0.255.10
- source_int: Loopback0
- acl: NTP_ACL
- logging: true
- key_id: 10
- auth_key: 15435A030726242723273C21181319000A
- auth: true
- state: present
-'''
-
-RETURN = '''
-commands:
- description: command sent to the device
- returned: always
- type: list
- sample: ["no ntp server 10.0.255.10", "no ntp source Loopback0"]
-'''
-import re
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.ios import get_config, load_config
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-
-
-def parse_server(line, dest):
- if dest == 'server':
- match = re.search(r'(ntp server )(\d+\.\d+\.\d+\.\d+)', line, re.M)
- if match:
- server = match.group(2)
- return server
-
-
-def parse_source_int(line, dest):
- if dest == 'source':
- match = re.search(r'(ntp source )(\S+)', line, re.M)
- if match:
- source = match.group(2)
- return source
-
-
-def parse_acl(line, dest):
- if dest == 'access-group':
- match = re.search(r'ntp access-group (?:peer|serve)(?:\s+)(\S+)', line, re.M)
- if match:
- acl = match.group(1)
- return acl
-
-
-def parse_logging(line, dest):
- if dest == 'logging':
- logging = dest
- return logging
-
-
-def parse_auth_key(line, dest):
- if dest == 'authentication-key':
- match = re.search(r'(ntp authentication-key \d+ md5 )(\w+)', line, re.M)
- if match:
- auth_key = match.group(2)
- return auth_key
-
-
-def parse_key_id(line, dest):
- if dest == 'trusted-key':
- match = re.search(r'(ntp trusted-key )(\d+)', line, re.M)
- if match:
- auth_key = match.group(2)
- return auth_key
-
-
-def parse_auth(dest):
- if dest == 'authenticate':
- return dest
-
-
-def map_config_to_obj(module):
-
- obj_dict = {}
- obj = []
- server_list = []
-
- config = get_config(module, flags=['| include ntp'])
-
- for line in config.splitlines():
- match = re.search(r'ntp (\S+)', line, re.M)
- if match:
- dest = match.group(1)
-
- server = parse_server(line, dest)
- source_int = parse_source_int(line, dest)
- acl = parse_acl(line, dest)
- logging = parse_logging(line, dest)
- auth = parse_auth(dest)
- auth_key = parse_auth_key(line, dest)
- key_id = parse_key_id(line, dest)
-
- if server:
- server_list.append(server)
- if source_int:
- obj_dict['source_int'] = source_int
- if acl:
- obj_dict['acl'] = acl
- if logging:
- obj_dict['logging'] = True
- if auth:
- obj_dict['auth'] = True
- if auth_key:
- obj_dict['auth_key'] = auth_key
- if key_id:
- obj_dict['key_id'] = key_id
-
- obj_dict['server'] = server_list
- obj.append(obj_dict)
-
- return obj
-
-
-def map_params_to_obj(module):
- obj = []
- obj.append({
- 'state': module.params['state'],
- 'server': module.params['server'],
- 'source_int': module.params['source_int'],
- 'logging': module.params['logging'],
- 'acl': module.params['acl'],
- 'auth': module.params['auth'],
- 'auth_key': module.params['auth_key'],
- 'key_id': module.params['key_id']
- })
-
- return obj
-
-
-def map_obj_to_commands(want, have, module):
-
- commands = list()
-
- server_have = have[0].get('server', None)
- source_int_have = have[0].get('source_int', None)
- acl_have = have[0].get('acl', None)
- logging_have = have[0].get('logging', None)
- auth_have = have[0].get('auth', None)
- auth_key_have = have[0].get('auth_key', None)
- key_id_have = have[0].get('key_id', None)
-
- for w in want:
- server = w['server']
- source_int = w['source_int']
- acl = w['acl']
- logging = w['logging']
- state = w['state']
- auth = w['auth']
- auth_key = w['auth_key']
- key_id = w['key_id']
-
- if state == 'absent':
- if server_have and server in server_have:
- commands.append('no ntp server {0}'.format(server))
- if source_int and source_int_have:
- commands.append('no ntp source {0}'.format(source_int))
- if acl and acl_have:
- commands.append('no ntp access-group peer {0}'.format(acl))
- if logging is True and logging_have:
- commands.append('no ntp logging')
- if auth is True and auth_have:
- commands.append('no ntp authenticate')
- if key_id and key_id_have:
- commands.append('no ntp trusted-key {0}'.format(key_id))
- if auth_key and auth_key_have:
- if key_id and key_id_have:
- commands.append('no ntp authentication-key {0} md5 {1} 7'.format(key_id, auth_key))
-
- elif state == 'present':
- if server is not None and server not in server_have:
- commands.append('ntp server {0}'.format(server))
- if source_int is not None and source_int != source_int_have:
- commands.append('ntp source {0}'.format(source_int))
- if acl is not None and acl != acl_have:
- commands.append('ntp access-group peer {0}'.format(acl))
- if logging is not None and logging != logging_have and logging is not False:
- commands.append('ntp logging')
- if auth is not None and auth != auth_have and auth is not False:
- commands.append('ntp authenticate')
- if key_id is not None and key_id != key_id_have:
- commands.append('ntp trusted-key {0}'.format(key_id))
- if auth_key is not None and auth_key != auth_key_have:
- if key_id is not None:
- commands.append('ntp authentication-key {0} md5 {1} 7'.format(key_id, auth_key))
-
- return commands
-
-
-def main():
-
- argument_spec = dict(
- server=dict(),
- source_int=dict(),
- acl=dict(),
- logging=dict(type='bool', default=False),
- auth=dict(type='bool', default=False),
- auth_key=dict(),
- key_id=dict(),
- state=dict(choices=['absent', 'present'], default='present')
- )
-
- argument_spec.update(ios_argument_spec)
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True
- )
-
- result = {'changed': False}
-
- warnings = list()
- 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:
- if not module.check_mode:
- load_config(module, commands)
- result['changed'] = True
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_ping.py b/lib/ansible/modules/network/ios/ios_ping.py
deleted file mode 100644
index 6b7fca9261..0000000000
--- a/lib/ansible/modules/network/ios/ios_ping.py
+++ /dev/null
@@ -1,210 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# 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
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = r'''
----
-module: ios_ping
-short_description: Tests reachability using ping from Cisco IOS network devices
-description:
-- Tests reachability using ping from switch to a remote destination.
-- For a general purpose network module, see the M(net_ping) module.
-- For Windows targets, use the M(win_ping) module instead.
-- For targets running Python, use the M(ping) module instead.
-author:
-- Jacob McGill (@jmcgill298)
-version_added: '2.4'
-extends_documentation_fragment: ios
-options:
- count:
- description:
- - Number of packets to send.
- default: 5
- dest:
- description:
- - The IP Address or hostname (resolvable by switch) of the remote node.
- required: true
- source:
- description:
- - The source IP Address.
- state:
- description:
- - Determines if the expected result is success or fail.
- choices: [ absent, present ]
- default: present
- vrf:
- description:
- - The VRF to use for forwarding.
- default: default
-notes:
- - For a general purpose network module, see the M(net_ping) module.
- - For Windows targets, use the M(win_ping) module instead.
- - For targets running Python, use the M(ping) module instead.
-'''
-
-EXAMPLES = r'''
-- name: Test reachability to 10.10.10.10 using default vrf
- ios_ping:
- dest: 10.10.10.10
-
-- name: Test reachability to 10.20.20.20 using prod vrf
- ios_ping:
- dest: 10.20.20.20
- vrf: prod
-
-- name: Test unreachability to 10.30.30.30 using default vrf
- ios_ping:
- dest: 10.30.30.30
- state: absent
-
-- name: Test reachability to 10.40.40.40 using prod vrf and setting count and source
- ios_ping:
- dest: 10.40.40.40
- source: loopback0
- vrf: prod
- count: 20
-'''
-
-RETURN = '''
-commands:
- description: Show the command sent.
- returned: always
- type: list
- sample: ["ping vrf prod 10.40.40.40 count 20 source loopback0"]
-packet_loss:
- description: Percentage of packets lost.
- returned: always
- type: str
- sample: "0%"
-packets_rx:
- description: Packets successfully received.
- returned: always
- type: int
- sample: 20
-packets_tx:
- description: Packets successfully transmitted.
- returned: always
- type: int
- sample: 20
-rtt:
- description: Show RTT stats.
- returned: always
- type: dict
- sample: {"avg": 2, "max": 8, "min": 1}
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.ios import run_commands
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-import re
-
-
-def main():
- """ main entry point for module execution
- """
- argument_spec = dict(
- count=dict(type="int"),
- dest=dict(type="str", required=True),
- source=dict(type="str"),
- state=dict(type="str", choices=["absent", "present"], default="present"),
- vrf=dict(type="str")
- )
-
- argument_spec.update(ios_argument_spec)
-
- module = AnsibleModule(argument_spec=argument_spec)
-
- count = module.params["count"]
- dest = module.params["dest"]
- source = module.params["source"]
- vrf = module.params["vrf"]
-
- warnings = list()
-
- results = {}
- if warnings:
- results["warnings"] = warnings
-
- results["commands"] = [build_ping(dest, count, source, vrf)]
-
- ping_results = run_commands(module, commands=results["commands"])
- ping_results_list = ping_results[0].split("\n")
-
- stats = ""
- for line in ping_results_list:
- if line.startswith('Success'):
- stats = line
-
- success, rx, tx, rtt = parse_ping(stats)
- loss = abs(100 - int(success))
- results["packet_loss"] = str(loss) + "%"
- results["packets_rx"] = int(rx)
- results["packets_tx"] = int(tx)
-
- # Convert rtt values to int
- for k, v in rtt.items():
- if rtt[k] is not None:
- rtt[k] = int(v)
-
- results["rtt"] = rtt
-
- validate_results(module, loss, results)
-
- module.exit_json(**results)
-
-
-def build_ping(dest, count=None, source=None, vrf=None):
- """
- Function to build the command to send to the terminal for the switch
- to execute. All args come from the module's unique params.
- """
- if vrf is not None:
- cmd = "ping vrf {0} {1}".format(vrf, dest)
- else:
- cmd = "ping {0}".format(dest)
-
- if count is not None:
- cmd += " repeat {0}".format(str(count))
-
- if source is not None:
- cmd += " source {0}".format(source)
-
- return cmd
-
-
-def parse_ping(ping_stats):
- """
- Function used to parse the statistical information from the ping response.
- Example: "Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/8 ms"
- Returns the percent of packet loss, received packets, transmitted packets, and RTT dict.
- """
- rate_re = re.compile(r"^\w+\s+\w+\s+\w+\s+(?P<pct>\d+)\s+\w+\s+\((?P<rx>\d+)/(?P<tx>\d+)\)")
- rtt_re = re.compile(r".*,\s+\S+\s+\S+\s+=\s+(?P<min>\d+)/(?P<avg>\d+)/(?P<max>\d+)\s+\w+\s*$|.*\s*$")
-
- rate = rate_re.match(ping_stats)
- rtt = rtt_re.match(ping_stats)
-
- return rate.group("pct"), rate.group("rx"), rate.group("tx"), rtt.groupdict()
-
-
-def validate_results(module, loss, results):
- """
- This function is used to validate whether the ping results were unexpected per "state" param.
- """
- state = module.params["state"]
- if state == "present" and loss == 100:
- module.fail_json(msg="Ping failed unexpectedly", **results)
- elif state == "absent" and loss < 100:
- module.fail_json(msg="Ping succeeded unexpectedly", **results)
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/ios/ios_static_route.py b/lib/ansible/modules/network/ios/ios_static_route.py
deleted file mode 100644
index 541a76a0c1..0000000000
--- a/lib/ansible/modules/network/ios/ios_static_route.py
+++ /dev/null
@@ -1,313 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# (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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_static_route
-version_added: "2.4"
-author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
-short_description: Manage static IP routes on Cisco IOS network devices
-description:
- - This module provides declarative management of static
- IP routes on Cisco IOS network devices.
-notes:
- - Tested against IOS 15.6
-options:
- prefix:
- description:
- - Network prefix of the static route.
- mask:
- description:
- - Network prefix mask of the static route.
- next_hop:
- description:
- - Next hop IP of the static route.
- vrf:
- description:
- - VRF of the static route.
- version_added: "2.8"
- interface:
- description:
- - Interface of the static route.
- version_added: "2.8"
- name:
- description:
- - Name of the static route
- aliases: ['description']
- version_added: "2.8"
- admin_distance:
- description:
- - Admin distance of the static route.
- tag:
- description:
- - Set tag of the static route.
- version_added: "2.8"
- track:
- description:
- - Tracked item to depend on for the static route.
- version_added: "2.8"
- aggregate:
- description: List of static route definitions.
- state:
- description:
- - State of the static route configuration.
- default: present
- choices: ['present', 'absent']
-extends_documentation_fragment: ios
-"""
-
-EXAMPLES = """
-- name: configure static route
- ios_static_route:
- prefix: 192.168.2.0
- mask: 255.255.255.0
- next_hop: 10.0.0.1
-
-- name: configure black hole in vrf blue depending on tracked item 10
- ios_static_route:
- prefix: 192.168.2.0
- mask: 255.255.255.0
- vrf: blue
- interface: null0
- track: 10
-
-- name: configure ultimate route with name and tag
- ios_static_route:
- prefix: 192.168.2.0
- mask: 255.255.255.0
- interface: GigabitEthernet1
- name: hello world
- tag: 100
-
-- name: remove configuration
- ios_static_route:
- prefix: 192.168.2.0
- mask: 255.255.255.0
- next_hop: 10.0.0.1
- state: absent
-
-- name: Add static route aggregates
- ios_static_route:
- aggregate:
- - { prefix: 172.16.32.0, mask: 255.255.255.0, next_hop: 10.0.0.8 }
- - { prefix: 172.16.33.0, mask: 255.255.255.0, next_hop: 10.0.0.8 }
-
-- name: Remove static route aggregates
- ios_static_route:
- aggregate:
- - { prefix: 172.16.32.0, mask: 255.255.255.0, next_hop: 10.0.0.8 }
- - { prefix: 172.16.33.0, mask: 255.255.255.0, next_hop: 10.0.0.8 }
- state: absent
-"""
-
-RETURN = """
-commands:
- description: The list of configuration mode commands to send to the device
- returned: always
- type: list
- sample:
- - ip route 192.168.2.0 255.255.255.0 10.0.0.1
-"""
-from copy import deepcopy
-from re import findall
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.common.utils import remove_default_spec, validate_ip_address
-from ansible.module_utils.network.ios.ios import get_config, load_config
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-
-
-def map_obj_to_commands(want, have):
- commands = list()
-
- for w in want:
- state = w['state']
- del w['state']
- # Try to match an existing config with the desired config
- for h in have:
- # To delete admin_distance param from have if not it want before comparing both fields
- if not w.get('admin_distance') and h.get('admin_distance'):
- del h['admin_distance']
- diff = list(set(w.items()) ^ set(h.items()))
- if not diff:
- break
- # if route is present with name or name already starts with wanted name it will not change
- elif len(diff) == 2 and diff[0][0] == diff[1][0] == 'name' and (not w['name'] or h['name'].startswith(w['name'])):
- break
- # If no matches found, clear `h`
- else:
- h = None
-
- command = 'ip route'
- prefix = w['prefix']
- mask = w['mask']
- vrf = w.get('vrf')
- if vrf:
- command = ' '.join((command, 'vrf', vrf, prefix, mask))
- else:
- command = ' '.join((command, prefix, mask))
-
- for key in ['interface', 'next_hop', 'admin_distance', 'tag', 'name', 'track']:
- if w.get(key):
- if key == 'name' and len(w.get(key).split()) > 1:
- command = ' '.join((command, key, '"%s"' % w.get(key))) # name with multiple words needs to be quoted
- elif key in ('name', 'tag', 'track'):
- command = ' '.join((command, key, w.get(key)))
- else:
- command = ' '.join((command, w.get(key)))
-
- if state == 'absent' and h:
- commands.append('no %s' % command)
- elif state == 'present' and not h:
- commands.append(command)
-
- return commands
-
-
-def map_config_to_obj(module):
- obj = []
-
- out = get_config(module, flags='| include ip route')
-
- for line in out.splitlines():
- splitted_line = findall(r'[^"\s]\S*|".+?"', line) # Split by whitespace but do not split quotes, needed for name parameter
-
- if splitted_line[2] == 'vrf':
- route = {'vrf': splitted_line[3]}
- del splitted_line[:4] # Removes the words ip route vrf vrf_name
- else:
- route = {}
- del splitted_line[:2] # Removes the words ip route
-
- prefix = splitted_line[0]
- mask = splitted_line[1]
- route.update({'prefix': prefix, 'mask': mask, 'admin_distance': '1'})
-
- next_word = None
- for word in splitted_line[2:]:
- if next_word:
- route[next_word] = word.strip('"') # Remove quotes which is needed for name
- next_word = None
- elif validate_ip_address(word):
- route.update(next_hop=word)
- elif word.isdigit():
- route.update(admin_distance=word)
- elif word in ('tag', 'name', 'track'):
- next_word = word
- else:
- route.update(interface=word)
-
- obj.append(route)
-
- return obj
-
-
-def map_params_to_obj(module, required_together=None):
- keys = ['prefix', 'mask', 'state', 'next_hop', 'vrf', 'interface', 'name', 'admin_distance', 'track', 'tag']
- obj = []
-
- aggregate = module.params.get('aggregate')
- if aggregate:
- for item in aggregate:
- route = item.copy()
- for key in keys:
- if route.get(key) is None:
- route[key] = module.params.get(key)
-
- route = dict((k, v) for k, v in route.items() if v is not None)
- module._check_required_together(required_together, route)
- obj.append(route)
- else:
- module._check_required_together(required_together, module.params)
- route = dict()
- for key in keys:
- if module.params.get(key) is not None:
- route[key] = module.params.get(key)
- obj.append(route)
-
- return obj
-
-
-def main():
- """ main entry point for module execution
- """
- element_spec = dict(
- prefix=dict(type='str'),
- mask=dict(type='str'),
- next_hop=dict(type='str'),
- vrf=dict(type='str'),
- interface=dict(type='str'),
- name=dict(type='str', aliases=['description']),
- admin_distance=dict(type='str'),
- track=dict(type='str'),
- tag=dict(type='str'),
- state=dict(default='present', choices=['present', 'absent'])
- )
-
- aggregate_spec = deepcopy(element_spec)
- aggregate_spec['prefix'] = dict(required=True)
-
- # 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),
- )
-
- argument_spec.update(element_spec)
- argument_spec.update(ios_argument_spec)
-
- required_one_of = [['aggregate', 'prefix']]
- required_together = [['prefix', 'mask']]
- mutually_exclusive = [['aggregate', 'prefix']]
-
- 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, required_together=required_together)
- have = map_config_to_obj(module)
-
- commands = map_obj_to_commands(want, have)
- result['commands'] = commands
-
- if commands:
- if not module.check_mode:
- load_config(module, commands)
-
- result['changed'] = True
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_static_routes.py b/lib/ansible/modules/network/ios/ios_static_routes.py
deleted file mode 100644
index dc76d04ffe..0000000000
--- a/lib/ansible/modules/network/ios/ios_static_routes.py
+++ /dev/null
@@ -1,710 +0,0 @@
-#!/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 ios_static_routes
-"""
-
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-DOCUMENTATION = """
----
-module: ios_static_routes
-version_added: "2.10"
-short_description: Configure and manage static routes on IOS devices.
-description: This module configures and manages the static routes on IOS platforms.
-author: Sumit Jaiswal (@justjais)
-notes:
-- Tested against Cisco IOSv Version 15.2 on VIRL
-- This module works with connection C(network_cli).
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: A dictionary of static route options
- type: list
- elements: dict
- suboptions:
- vrf:
- description:
- - IP VPN Routing/Forwarding instance name.
- - NOTE, In case of IPV4/IPV6 VRF routing table should pre-exist before
- configuring.
- - NOTE, if the vrf information is not provided then the routes shall be
- configured under global vrf.
- type: str
- address_families:
- elements: dict
- description:
- - Address family to use for the static routes
- type: list
- suboptions:
- afi:
- description:
- - Top level address family indicator.
- required: true
- type: str
- choices:
- - ipv4
- - ipv6
- routes:
- description: Configuring static route
- type: list
- elements: dict
- suboptions:
- dest:
- description: Destination prefix with its subnet mask
- type: str
- required: true
- topology:
- description:
- - Configure static route for a Topology Routing/Forwarding instance
- - NOTE, VRF and Topology can be used together only with Multicast and
- Topology should pre-exist before it can be used
- type: str
- next_hops:
- description:
- - next hop address or interface
- type: list
- elements: dict
- suboptions:
- forward_router_address:
- description: Forwarding router's address
- type: str
- interface:
- description: Interface for directly connected static routes
- type: str
- dhcp:
- description: Default gateway obtained from DHCP
- type: bool
- distance_metric:
- description: Distance metric for this route
- type: int
- global:
- description: Next hop address is global
- type: bool
- name:
- description: Specify name of the next hop
- type: str
- multicast:
- description: multicast route
- type: bool
- permanent:
- description: permanent route
- type: bool
- tag:
- description:
- - Set tag for this route
- - Refer to vendor documentation for valid values.
- type: int
- track:
- description:
- - Install route depending on tracked item with tracked object number.
- - Tracking does not support multicast
- - Refer to vendor documentation for valid values.
- type: int
- 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
- C(show configuration commands | grep 'static route')
- 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 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 | include ip route|ipv6 route)
- executed on device. For state I(parsed) active connection to remote host is not required.
- type: str
- choices:
- - merged
- - replaced
- - overridden
- - deleted
- - gathered
- - rendered
- - parsed
- default: merged
-"""
-
-EXAMPLES = """
----
-
-# Using merged
-
-# Before state:
-# -------------
-#
-# vios#show running-config | include ip route|ipv6 route
-
-- name: Merge provided configuration with device configuration
- ios_static_routes:
- config:
- - vrf: blue
- address_families:
- - afi: ipv4
- routes:
- - dest: 192.0.2.0/24
- next_hops:
- - forward_router_address: 192.0.2.1
- name: merged_blue
- tag: 50
- track: 150
- - address_families:
- - afi: ipv4
- routes:
- - dest: 198.51.100.0/24
- next_hops:
- - forward_router_address: 198.51.101.1
- name: merged_route_1
- distance_metric: 110
- tag: 40
- multicast: True
- - forward_router_address: 198.51.101.2
- name: merged_route_2
- distance_metric: 30
- - forward_router_address: 198.51.101.3
- name: merged_route_3
- - afi: ipv6
- routes:
- - dest: 2001:DB8:0:3::/64
- next_hops:
- - forward_router_address: 2001:DB8:0:3::2
- name: merged_v6
- tag: 105
- state: merged
-
-# Commands fired:
-# ---------------
-# ip route vrf blue 192.0.2.0 255.255.255.0 10.0.0.8 name merged_blue track 150 tag 50
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name merged_route_1 tag 40
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name merged_route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name merged_route_3
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name merged_v6 tag 105
-
-# After state:
-# ------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf blue 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name merged_blue track 150
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name merged_route_3
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name merged_route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name merged_route_1 multicast
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name merged_v6
-
-# Using replaced
-
-# Before state:
-# -------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105
-
-- name: Replace provided configuration with device configuration
- ios_static_routes:
- config:
- - address_families:
- - afi: ipv4
- routes:
- - dest: 198.51.100.0/24
- next_hops:
- - forward_router_address: 198.51.101.1
- name: replaced_route
- distance_metric: 175
- tag: 70
- multicast: True
- state: replaced
-
-# Commands fired:
-# ---------------
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 175 name replaced_route track 150 tag 70
-
-# After state:
-# ------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 175 name replaced_route track 150 tag 70
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6
-
-# Using overridden
-
-# Before state:
-# -------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105
-
-- name: Override provided configuration with device configuration
- ios_static_routes:
- config:
- - vrf: blue
- address_families:
- - afi: ipv4
- routes:
- - dest: 192.0.2.0/24
- next_hops:
- - forward_router_address: 192.0.2.1
- name: override_vrf
- tag: 50
- track: 150
- state: overridden
-
-# Commands fired:
-# ---------------
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 198.51.101.8 name test_vrf track 150 tag 50
-# no ipv6 route FD5D:12C9:2201:1::/64 FD5D:12C9:2202::2 name test_v6 tag 105
-# ip route vrf blue 192.0.2.0 255.255.255.0 198.51.101.4 name override_vrf track 150 tag 50
-
-# After state:
-# ------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf blue 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name override_vrf track 150
-
-# Using Deleted
-
-# Example 1:
-# ----------
-# To delete the exact static routes, with all the static routes explicitly mentioned in want
-
-# Before state:
-# -------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105
-
-- name: Delete provided configuration from the device configuration
- ios_static_routes:
- config:
- - vrf: ansible_temp_vrf
- address_families:
- - afi: ipv4
- routes:
- - dest: 192.0.2.0/24
- next_hops:
- - forward_router_address: 192.0.2.1
- name: test_vrf
- tag: 50
- track: 150
- - address_families:
- - afi: ipv4
- routes:
- - dest: 198.51.100.0/24
- next_hops:
- - forward_router_address: 198.51.101.1
- name: route_1
- distance_metric: 110
- tag: 40
- multicast: True
- - forward_router_address: 198.51.101.2
- name: route_2
- distance_metric: 30
- - forward_router_address: 198.51.101.3
- name: route_3
- - afi: ipv6
- routes:
- - dest: 2001:DB8:0:3::/64
- next_hops:
- - forward_router_address: 2001:DB8:0:3::2
- name: test_v6
- tag: 105
- state: deleted
-
-# Commands fired:
-# ---------------
-# no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 198.51.101.8 name test_vrf track 150 tag 50
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# no ipv6 route FD5D:12C9:2201:1::/64 FD5D:12C9:2202::2 name test_v6 tag 105
-
-# After state:
-# ------------
-#
-# vios#show running-config | include ip route|ipv6 route
-
-# Example 2:
-# ----------
-# To delete the destination specific static routes
-
-# Before state:
-# -------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105
-
-- name: Delete provided configuration from the device configuration
- ios_static_routes:
- config:
- - address_families:
- - afi: ipv4
- routes:
- - dest: 198.51.100.0/24
- state: deleted
-
-# Commands fired:
-# ---------------
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name route_1 multicast
-
-# After state:
-# ------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name test_vrf track 150
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6
-
-
-# Example 3:
-# ----------
-# To delete the vrf specific static routes
-
-# Before state:
-# -------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105
-
-- name: Delete provided configuration from the device configuration
- ios_static_routes:
- config:
- - vrf: ansible_temp_vrf
- state: deleted
-
-# Commands fired:
-# ---------------
-# no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50
-
-# After state:
-# ------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name route_1 multicast
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6
-
-# Using Deleted without any config passed
-#"(NOTE: This will delete all of configured resource module attributes from each configured interface)"
-
-# Before state:
-# -------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105
-
-- name: Delete ALL configured IOS static routes
- ios_static_routes:
- state: deleted
-
-# Commands fired:
-# ---------------
-# no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name test_vrf track 150
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name route_1 multicast
-# no ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6
-
-# After state:
-# -------------
-#
-# vios#show running-config | include ip route|ipv6 route
-#
-
-# Using gathered
-
-# Before state:
-# -------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105
-
-- name: Gather listed static routes with provided configurations
- ios_static_routes:
- config:
- state: gathered
-
-# Module Execution Result:
-# ------------------------
-#
-# "gathered": [
-# {
-# "address_families": [
-# {
-# "afi": "ipv4",
-# "routes": [
-# {
-# "dest": "192.0.2.0/24",
-# "next_hops": [
-# {
-# "forward_router_address": "192.0.2.1",
-# "name": "test_vrf",
-# "tag": 50,
-# "track": 150
-# }
-# ]
-# }
-# ]
-# }
-# ],
-# "vrf": "ansible_temp_vrf"
-# },
-# {
-# "address_families": [
-# {
-# "afi": "ipv6",
-# "routes": [
-# {
-# "dest": "2001:DB8:0:3::/64",
-# "next_hops": [
-# {
-# "forward_router_address": "2001:DB8:0:3::2",
-# "name": "test_v6",
-# "tag": 105
-# }
-# ]
-# }
-# ]
-# },
-# {
-# "afi": "ipv4",
-# "routes": [
-# {
-# "dest": "198.51.100.0/24",
-# "next_hops": [
-# {
-# "distance_metric": 110,
-# "forward_router_address": "198.51.101.1",
-# "multicast": true,
-# "name": "route_1",
-# "tag": 40
-# },
-# {
-# "distance_metric": 30,
-# "forward_router_address": "198.51.101.2",
-# "name": "route_2"
-# },
-# {
-# "forward_router_address": "198.51.101.3",
-# "name": "route_3"
-# }
-# ]
-# }
-# ]
-# }
-# ]
-# }
-# ]
-
-# After state:
-# ------------
-#
-# vios#show running-config | include ip route|ipv6 route
-# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50
-# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40
-# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2
-# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3
-# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105
-
-# Using rendered
-
-- name: Render the commands for provided configuration
- ios_static_routes:
- config:
- - vrf: ansible_temp_vrf
- address_families:
- - afi: ipv4
- routes:
- - dest: 192.0.2.0/24
- next_hops:
- - forward_router_address: 192.0.2.1
- name: test_vrf
- tag: 50
- track: 150
- - address_families:
- - afi: ipv4
- routes:
- - dest: 198.51.100.0/24
- next_hops:
- - forward_router_address: 198.51.101.1
- name: route_1
- distance_metric: 110
- tag: 40
- multicast: True
- - forward_router_address: 198.51.101.2
- name: route_2
- distance_metric: 30
- - forward_router_address: 198.51.101.3
- name: route_3
- - afi: ipv6
- routes:
- - dest: 2001:DB8:0:3::/64
- next_hops:
- - forward_router_address: 2001:DB8:0:3::2
- name: test_v6
- tag: 105
- state: rendered
-
-# Module Execution Result:
-# ------------------------
-#
-# "rendered": [
-# "ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50",
-# "ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40",
-# "ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2",
-# "ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3",
-# "ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105"
-# ]
-
-"""
-
-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: ['ip route vrf test 172.31.10.0 255.255.255.0 10.10.10.2 name new_test multicast']
-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: ['interface Ethernet1/1', 'mtu 1800']
-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.module_utils.network.ios.argspec.static_routes.static_routes import Static_RoutesArgs
-from ansible.module_utils.network.ios.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', 'rendered', ('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/lib/ansible/modules/network/ios/ios_system.py b/lib/ansible/modules/network/ios/ios_system.py
deleted file mode 100644
index cb1d7824c6..0000000000
--- a/lib/ansible/modules/network/ios/ios_system.py
+++ /dev/null
@@ -1,380 +0,0 @@
-#!/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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_system
-version_added: "2.3"
-author: "Peter Sprygada (@privateip)"
-short_description: Manage the system attributes on Cisco IOS devices
-description:
- - This module provides declarative management of node system attributes
- on Cisco IOS devices. It provides an option to configure host system
- parameters or remove those parameters from the device active
- configuration.
-extends_documentation_fragment: ios
-notes:
- - Tested against IOS 15.6
-options:
- hostname:
- description:
- - Configure the device hostname parameter. This option takes an ASCII string value.
- 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.
- domain_search:
- 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.
- lookup_source:
- description:
- - Provides one or more source
- interfaces to use for performing DNS lookups. The interface
- provided in C(lookup_source) must be a valid interface configured
- on the device.
- lookup_enabled:
- description:
- - Administrative control
- for enabling or disabling DNS lookups. When this argument is
- set to True, lookups are performed and when it is set to False,
- lookups are not performed.
- type: bool
- 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 See
- examples.
- 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
- choices: ['present', 'absent']
-"""
-
-EXAMPLES = """
-- name: configure hostname and domain name
- ios_system:
- hostname: ios01
- domain_name: test.example.com
- domain_search:
- - ansible.com
- - redhat.com
- - cisco.com
-
-- name: remove configuration
- ios_system:
- state: absent
-
-- name: configure DNS lookup sources
- ios_system:
- lookup_source: MgmtEth0/0/CPU0/0
- lookup_enabled: yes
-
-- name: configure name servers
- ios_system:
- name_servers:
- - 8.8.8.8
- - 8.8.4.4
-"""
-
-RETURN = """
-commands:
- description: The list of configuration mode commands to send to the device
- returned: always
- type: list
- sample:
- - hostname ios01
- - ip domain name test.example.com
-"""
-import re
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.ios import get_config, load_config
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-from ansible.module_utils.network.common.utils import ComplexList
-
-_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 definition (\S+)', config)
- return vrf in _CONFIGURED_VRFS
-
-
-def requires_vrf(module, vrf):
- if not has_vrf(module, vrf):
- module.fail_json(msg='vrf %s is not configured' % vrf)
-
-
-def diff_list(want, have):
- adds = [w for w in want if w not in have]
- removes = [h for h in have if h not in want]
- return (adds, removes)
-
-
-def map_obj_to_commands(want, have, module):
- commands = list()
- state = module.params['state']
-
- def needs_update(x):
- return want.get(x) is not None and (want.get(x) != have.get(x))
-
- if state == 'absent':
- if have['hostname'] != 'Router':
- commands.append('no hostname')
-
- if have['lookup_source']:
- commands.append('no ip domain lookup source-interface %s' % have['lookup_source'])
-
- if have['lookup_enabled'] is False:
- commands.append('ip domain lookup')
-
- vrfs = set()
- for item in have['domain_name']:
- if item['vrf'] and item['vrf'] not in vrfs:
- vrfs.add(item['vrf'])
- commands.append('no ip domain name vrf %s' % item['vrf'])
- elif None not in vrfs:
- vrfs.add(None)
- commands.append('no ip domain name')
-
- vrfs = set()
- for item in have['domain_search']:
- if item['vrf'] and item['vrf'] not in vrfs:
- vrfs.add(item['vrf'])
- commands.append('no ip domain list vrf %s' % item['vrf'])
- elif None not in vrfs:
- vrfs.add(None)
- commands.append('no ip domain list')
-
- vrfs = set()
- for item in have['name_servers']:
- if item['vrf'] and item['vrf'] not in vrfs:
- vrfs.add(item['vrf'])
- commands.append('no ip name-server vrf %s' % item['vrf'])
- elif None not in vrfs:
- vrfs.add(None)
- commands.append('no ip name-server')
-
- elif state == 'present':
- if needs_update('hostname'):
- commands.append('hostname %s' % want['hostname'])
-
- if needs_update('lookup_source'):
- commands.append('ip domain lookup source-interface %s' % want['lookup_source'])
-
- if needs_update('lookup_enabled'):
- cmd = 'ip domain lookup'
- if want['lookup_enabled'] is False:
- cmd = 'no %s' % cmd
- commands.append(cmd)
-
- if want['domain_name']:
- adds, removes = diff_list(want['domain_name'], have['domain_name'])
- for item in removes:
- if item['vrf']:
- commands.append('no ip domain name vrf %s %s' % (item['vrf'], item['name']))
- else:
- commands.append('no ip domain name %s' % item['name'])
- for item in adds:
- if item['vrf']:
- requires_vrf(module, item['vrf'])
- commands.append('ip domain name vrf %s %s' % (item['vrf'], item['name']))
- else:
- commands.append('ip domain name %s' % item['name'])
-
- if want['domain_search']:
- adds, removes = diff_list(want['domain_search'], have['domain_search'])
- for item in removes:
- if item['vrf']:
- commands.append('no ip domain list vrf %s %s' % (item['vrf'], item['name']))
- else:
- commands.append('no ip domain list %s' % item['name'])
- for item in adds:
- if item['vrf']:
- requires_vrf(module, item['vrf'])
- commands.append('ip domain list vrf %s %s' % (item['vrf'], item['name']))
- else:
- commands.append('ip domain list %s' % item['name'])
-
- if want['name_servers']:
- adds, removes = diff_list(want['name_servers'], have['name_servers'])
- for item in removes:
- if item['vrf']:
- commands.append('no ip name-server vrf %s %s' % (item['vrf'], item['server']))
- else:
- commands.append('no ip name-server %s' % item['server'])
- for item in adds:
- if item['vrf']:
- requires_vrf(module, item['vrf'])
- commands.append('ip name-server vrf %s %s' % (item['vrf'], item['server']))
- else:
- commands.append('ip name-server %s' % item['server'])
-
- return commands
-
-
-def parse_hostname(config):
- match = re.search(r'^hostname (\S+)', config, re.M)
- return match.group(1)
-
-
-def parse_domain_name(config):
- match = re.findall(r'^ip domain[- ]name (?:vrf (\S+) )*(\S+)', config, re.M)
- matches = list()
- for vrf, name in match:
- if not vrf:
- vrf = None
- matches.append({'name': name, 'vrf': vrf})
- return matches
-
-
-def parse_domain_search(config):
- match = re.findall(r'^ip domain[- ]list (?:vrf (\S+) )*(\S+)', config, re.M)
- matches = list()
- for vrf, name in match:
- if not vrf:
- vrf = None
- matches.append({'name': name, 'vrf': vrf})
- return matches
-
-
-def parse_name_servers(config):
- match = re.findall(r'^ip name-server (?:vrf (\S+) )*(.*)', config, re.M)
- matches = list()
- for vrf, servers in match:
- if not vrf:
- vrf = None
- for server in servers.split():
- matches.append({'server': server, 'vrf': vrf})
- return matches
-
-
-def parse_lookup_source(config):
- match = re.search(r'ip domain[- ]lookup source-interface (\S+)', config, re.M)
- if match:
- return match.group(1)
-
-
-def map_config_to_obj(module):
- config = get_config(module)
- return {
- 'hostname': parse_hostname(config),
- 'domain_name': parse_domain_name(config),
- 'domain_search': parse_domain_search(config),
- 'lookup_source': parse_lookup_source(config),
- 'lookup_enabled': 'no ip domain lookup' not in config and 'no ip domain-lookup' not in config,
- 'name_servers': parse_name_servers(config)
- }
-
-
-def map_params_to_obj(module):
- obj = {
- 'hostname': module.params['hostname'],
- 'lookup_source': module.params['lookup_source'],
- 'lookup_enabled': module.params['lookup_enabled'],
- }
-
- domain_name = ComplexList(dict(
- name=dict(key=True),
- vrf=dict()
- ), module)
-
- domain_search = ComplexList(dict(
- name=dict(key=True),
- vrf=dict()
- ), module)
-
- name_servers = ComplexList(dict(
- server=dict(key=True),
- vrf=dict()
- ), module)
-
- for arg, cast in [('domain_name', domain_name),
- ('domain_search', domain_search),
- ('name_servers', name_servers)]:
-
- if module.params[arg]:
- obj[arg] = cast(module.params[arg])
- else:
- obj[arg] = None
-
- return obj
-
-
-def main():
- """ Main entry point for Ansible module execution
- """
- argument_spec = dict(
- hostname=dict(),
-
- domain_name=dict(type='list'),
- domain_search=dict(type='list'),
- name_servers=dict(type='list'),
-
- lookup_source=dict(),
- lookup_enabled=dict(type='bool'),
-
- state=dict(choices=['present', 'absent'], default='present')
- )
-
- argument_spec.update(ios_argument_spec)
-
- module = AnsibleModule(argument_spec=argument_spec,
- supports_check_mode=True)
-
- result = {'changed': False}
-
- warnings = list()
- 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:
- if not module.check_mode:
- load_config(module, commands)
- result['changed'] = True
-
- module.exit_json(**result)
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/ios/ios_user.py b/lib/ansible/modules/network/ios/ios_user.py
deleted file mode 100644
index 37afe741dd..0000000000
--- a/lib/ansible/modules/network/ios/ios_user.py
+++ /dev/null
@@ -1,533 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# (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/>.
-#
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-DOCUMENTATION = """
----
-module: ios_user
-version_added: "2.4"
-author: "Trishna Guha (@trishnaguha)"
-short_description: Manage the aggregate of local users on Cisco IOS device
-description:
- - This module provides declarative management of the local usernames
- configured on network devices. It allows playbooks to manage
- either individual usernames or the aggregate of usernames in the
- current running config. It also supports purging usernames from the
- configuration that are not explicitly defined.
-notes:
- - Tested against IOS 15.6
-options:
- aggregate:
- description:
- - The set of username objects to be configured on the remote
- Cisco IOS device. The list entries can either be the username
- or a hash of username and properties. This argument is mutually
- exclusive with the C(name) argument.
- aliases: ['users', 'collection']
- name:
- description:
- - The username to be configured on the Cisco IOS device.
- This argument accepts a string value and is mutually exclusive
- with the C(aggregate) argument.
- Please note that this option is not same as C(provider username).
- configured_password:
- description:
- - The password to be configured on the Cisco IOS device. The
- password needs to be provided in clear and it will be encrypted
- on the device.
- Please note that this option is not same as C(provider password).
- 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
- choices: ['on_create', 'always']
- password_type:
- description:
- - This argument determines whether a 'password' or 'secret' will be
- configured.
- default: secret
- choices: ['secret', 'password']
- version_added: "2.8"
- hashed_password:
- description:
- - This option allows configuring hashed passwords on Cisco IOS devices.
- suboptions:
- type:
- description:
- - Specifies the type of hash (e.g., 5 for MD5, 8 for PBKDF2, etc.)
- - For this to work, the device needs to support the desired hash type
- type: int
- required: True
- value:
- description:
- - The actual hashed password to be configured on the device
- required: True
- version_added: "2.8"
- 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.
- view:
- description:
- - Configures the view for the username in the
- device running configuration. The argument accepts a string value
- defining the view name. This argument does not check if the view
- has been configured on the device.
- aliases: ['role']
- sshkey:
- description:
- - Specifies one or more SSH public key(s) to configure
- for the given username.
- - This argument accepts a valid SSH key value.
- version_added: "2.7"
- 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 (the current defined set of users).
- 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
- default: present
- choices: ['present', 'absent']
-extends_documentation_fragment: ios
-"""
-
-EXAMPLES = """
-- name: create a new user
- ios_user:
- name: ansible
- nopassword: True
- sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- state: present
-
-- name: create a new user with multiple keys
- ios_user:
- name: ansible
- sshkey:
- - "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- - "{{ lookup('file', '~/path/to/public_key') }}"
- state: present
-
-- name: remove all users except admin
- ios_user:
- purge: yes
-
-- name: remove all users except admin and these listed users
- ios_user:
- aggregate:
- - name: testuser1
- - name: testuser2
- - name: testuser3
- purge: yes
-
-- name: set multiple users to privilege level 15
- ios_user:
- aggregate:
- - name: netop
- - name: netend
- privilege: 15
- state: present
-
-- name: set user view/role
- ios_user:
- name: netop
- view: network-operator
- state: present
-
-- name: Change Password for User netop
- ios_user:
- name: netop
- configured_password: "{{ new_password }}"
- update_password: always
- state: present
-
-- name: Aggregate of users
- ios_user:
- aggregate:
- - name: ansibletest2
- - name: ansibletest3
- view: network-admin
-
-- name: Add a user specifying password type
- ios_user:
- name: ansibletest4
- configured_password: "{{ new_password }}"
- password_type: password
-
-- name: Add a user with MD5 hashed password
- ios_user:
- name: ansibletest5
- hashed_password:
- type: 5
- value: $3$8JcDilcYgFZi.yz4ApaqkHG2.8/
-
-- name: Delete users with aggregate
- ios_user:
- aggregate:
- - name: ansibletest1
- - name: ansibletest2
- - name: ansibletest3
- state: absent
-"""
-
-RETURN = """
-commands:
- description: The list of configuration mode commands to send to the device
- returned: always
- type: list
- sample:
- - username ansible secret password
- - username admin secret admin
-"""
-import base64
-import hashlib
-import re
-from copy import deepcopy
-from functools import partial
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.common.utils import remove_default_spec
-from ansible.module_utils.network.ios.ios import get_config, load_config
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-from ansible.module_utils.six import iteritems
-
-
-def validate_privilege(value, module):
- if value and not 1 <= value <= 15:
- module.fail_json(msg='privilege must be between 1 and 15, got %s' % value)
-
-
-def user_del_cmd(username):
- return {
- 'command': 'no username %s' % username,
- 'prompt': 'This operation will remove all username related configurations with same name',
- 'answer': 'y',
- 'newline': False,
- }
-
-
-def sshkey_fingerprint(sshkey):
- # IOS will accept a MD5 fingerprint of the public key
- # and is easier to configure in a single line
- # we calculate this fingerprint here
- if not sshkey:
- return None
- if ' ' in sshkey:
- # ssh-rsa AAA...== comment
- keyparts = sshkey.split(' ')
- keyparts[1] = hashlib.md5(base64.b64decode(keyparts[1])).hexdigest().upper()
- return ' '.join(keyparts)
- else:
- # just the key, assume rsa type
- return 'ssh-rsa %s' % hashlib.md5(base64.b64decode(sshkey)).hexdigest().upper()
-
-
-def map_obj_to_commands(updates, module):
- commands = list()
- update_password = module.params['update_password']
- password_type = module.params['password_type']
-
- def needs_update(want, have, x):
- return want.get(x) and (want.get(x) != have.get(x))
-
- def add(command, want, x):
- command.append('username %s %s' % (want['name'], x))
-
- def add_hashed_password(command, want, x):
- command.append('username %s secret %s %s' % (want['name'], x.get('type'),
- x.get('value')))
-
- def add_ssh(command, want, x=None):
- command.append('ip ssh pubkey-chain')
- if x:
- command.append('username %s' % want['name'])
- for item in x:
- command.append('key-hash %s' % item)
- command.append('exit')
- else:
- command.append('no username %s' % want['name'])
- command.append('exit')
-
- for update in updates:
- want, have = update
-
- if want['state'] == 'absent':
- if have['sshkey']:
- add_ssh(commands, want)
- else:
- commands.append(user_del_cmd(want['name']))
-
- if needs_update(want, have, 'view'):
- add(commands, want, 'view %s' % want['view'])
-
- if needs_update(want, have, 'privilege'):
- add(commands, want, 'privilege %s' % want['privilege'])
-
- if needs_update(want, have, 'sshkey'):
- add_ssh(commands, want, want['sshkey'])
-
- if needs_update(want, have, 'configured_password'):
- if update_password == 'always' or not have:
- if have and password_type != have['password_type']:
- module.fail_json(msg='Can not have both a user password and a user secret.' +
- ' Please choose one or the other.')
- add(commands, want, '%s %s' % (password_type, want['configured_password']))
-
- if needs_update(want, have, 'hashed_password'):
- add_hashed_password(commands, want, want['hashed_password'])
-
- if needs_update(want, have, 'nopassword'):
- if want['nopassword']:
- add(commands, want, 'nopassword')
- else:
- add(commands, want, user_del_cmd(want['name']))
-
- return commands
-
-
-def parse_view(data):
- match = re.search(r'view (\S+)', data, re.M)
- if match:
- return match.group(1)
-
-
-def parse_sshkey(data, user):
- sshregex = r'username %s(\n\s+key-hash .+$)+' % user
- sshcfg = re.search(sshregex, data, re.M)
- key_list = []
- if sshcfg:
- match = re.findall(r'key-hash (\S+ \S+(?: .+)?)$', sshcfg.group(), re.M)
- if match:
- key_list = match
- return key_list
-
-
-def parse_privilege(data):
- match = re.search(r'privilege (\S+)', data, re.M)
- if match:
- return int(match.group(1))
-
-
-def parse_password_type(data):
- type = None
- if data and data.split()[-3] in ['password', 'secret']:
- type = data.split()[-3]
- return type
-
-
-def map_config_to_obj(module):
- data = get_config(module, flags=['| section username'])
-
- match = re.findall(r'(?:^(?:u|\s{2}u))sername (\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,
- 'hashed_password': None,
- 'password_type': parse_password_type(cfg),
- 'sshkey': parse_sshkey(data, user),
- 'privilege': parse_privilege(cfg),
- 'view': parse_view(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):
- users = module.params['aggregate']
- if not users:
- if not module.params['name'] and module.params['purge']:
- return list()
- elif not module.params['name']:
- module.fail_json(msg='username is required')
- else:
- aggregate = [{'name': module.params['name']}]
- else:
- aggregate = list()
- for item in users:
- if not isinstance(item, dict):
- aggregate.append({'name': item})
- elif 'name' not in item:
- module.fail_json(msg='name is required')
- else:
- aggregate.append(item)
-
- objects = list()
-
- for item in aggregate:
- get_value = partial(get_param_value, item=item, module=module)
- item['configured_password'] = get_value('configured_password')
- item['hashed_password'] = get_value('hashed_password')
- item['nopassword'] = get_value('nopassword')
- item['privilege'] = get_value('privilege')
- item['view'] = get_value('view')
- item['sshkey'] = render_key_list(get_value('sshkey'))
- item['state'] = get_value('state')
- objects.append(item)
-
- return objects
-
-
-def render_key_list(ssh_keys):
- key_list = []
- if ssh_keys:
- for item in ssh_keys:
- key_list.append(sshkey_fingerprint(item))
- return key_list
-
-
-def update_objects(want, have):
- updates = list()
- for entry in want:
- 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
- """
- hashed_password_spec = dict(
- type=dict(type='int', required=True),
- value=dict(no_log=True, required=True)
- )
-
- element_spec = dict(
- name=dict(),
-
- configured_password=dict(no_log=True),
- hashed_password=dict(no_log=True, type='dict', options=hashed_password_spec),
- nopassword=dict(type='bool'),
- update_password=dict(default='always', choices=['on_create', 'always']),
- password_type=dict(default='secret', choices=['secret', 'password']),
-
- privilege=dict(type='int'),
- view=dict(aliases=['role']),
-
- sshkey=dict(type='list'),
-
- 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)
-
- argument_spec = dict(
- aggregate=dict(type='list', elements='dict', options=aggregate_spec, aliases=['users', 'collection']),
- purge=dict(type='bool', default=False)
- )
-
- argument_spec.update(element_spec)
- argument_spec.update(ios_argument_spec)
-
- mutually_exclusive = [('name', 'aggregate'), ('nopassword', 'hashed_password', 'configured_password')]
-
- module = AnsibleModule(argument_spec=argument_spec,
- mutually_exclusive=mutually_exclusive,
- supports_check_mode=True)
-
- warnings = list()
- result = {'changed': False, '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(user_del_cmd(item))
-
- result['commands'] = commands
-
- if commands:
- if not module.check_mode:
- load_config(module, commands)
- result['changed'] = True
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_vlans.py b/lib/ansible/modules/network/ios/ios_vlans.py
deleted file mode 100644
index 7de87dbb52..0000000000
--- a/lib/ansible/modules/network/ios/ios_vlans.py
+++ /dev/null
@@ -1,464 +0,0 @@
-#!/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 ios_vlans
-"""
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {
- 'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'
-}
-
-DOCUMENTATION = """
-module: ios_vlans
-version_added: 2.9
-short_description: Manage VLANs on Cisco IOS devices.
-description: This module provides declarative management of VLANs on Cisco IOS network devices.
-author: Sumit Jaiswal (@justjais)
-notes:
- - Tested against Cisco IOSv Version 15.2 on VIRL
- - This module works with connection C(network_cli).
- See L(IOS Platform Options,../network/user_guide/platform_ios.html).
-options:
- config:
- description: A dictionary of VLANs options
- type: list
- elements: dict
- suboptions:
- name:
- description:
- - Ascii name of the VLAN.
- - NOTE, I(name) should not be named/appended with I(default) as it is reserved for device default vlans.
- type: str
- vlan_id:
- description:
- - ID of the VLAN. Range 1-4094
- type: int
- required: True
- mtu:
- description:
- - VLAN Maximum Transmission Unit.
- - Refer to vendor documentation for valid values.
- type: int
- state:
- description:
- - Operational state of the VLAN
- type: str
- choices:
- - active
- - suspend
- remote_span:
- description:
- - Configure as Remote SPAN VLAN
- type: bool
- shutdown:
- description:
- - Shutdown VLAN switching.
- type: str
- choices:
- - enabled
- - disabled
- state:
- description:
- - The state of the configuration after module completion
- type: str
- choices:
- - merged
- - replaced
- - overridden
- - deleted
- default: merged
-"""
-EXAMPLES = """
----
-# Using merged
-
-# Before state:
-# -------------
-#
-# vios#show vlan
-# VLAN Name Status Ports
-# ---- -------------------------------- --------- -------------------------------
-# 1 default active Gi0/1, Gi0/2
-# 1002 fddi-default act/unsup
-# 1003 token-ring-default act/unsup
-# 1004 fddinet-default act/unsup
-# 1005 trnet-default act/unsup
-#
-# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2
-# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
-# 1 enet 100001 1500 - - - - - 0 0
-# 1002 fddi 101002 1500 - - - - - 0 0
-# 1003 tr 101003 1500 - - - - - 0 0
-# 1004 fdnet 101004 1500 - - - ieee - 0 0
-# 1005 trnet 101005 1500 - - - ibm - 0 0
-
-- name: Merge provided configuration with device configuration
- ios_vlans:
- config:
- - name: Vlan_10
- vlan_id: 10
- state: active
- shutdown: disabled
- remote_span: 10
- - name: Vlan_20
- vlan_id: 20
- mtu: 610
- state: active
- shutdown: enabled
- - name: Vlan_30
- vlan_id: 30
- state: suspend
- shutdown: enabled
- state: merged
-
-# After state:
-# ------------
-#
-# vios#show vlan
-# VLAN Name Status Ports
-# ---- -------------------------------- --------- -------------------------------
-# 1 default active Gi0/1, Gi0/2
-# 10 vlan_10 active
-# 20 vlan_20 act/lshut
-# 30 vlan_30 sus/lshut
-# 1002 fddi-default act/unsup
-# 1003 token-ring-default act/unsup
-# 1004 fddinet-default act/unsup
-# 1005 trnet-default act/unsup
-#
-# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2
-# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
-# 1 enet 100001 1500 - - - - - 0 0
-# 10 enet 100010 1500 - - - - - 0 0
-# 20 enet 100020 610 - - - - - 0 0
-# 30 enet 100030 1500 - - - - - 0 0
-# 1002 fddi 101002 1500 - - - - - 0 0
-# 1003 tr 101003 1500 - - - - - 0 0
-# 1004 fdnet 101004 1500 - - - ieee - 0 0
-# 1005 trnet 101005 1500 - - - ibm - 0 0
-#
-# Remote SPAN VLANs
-# ------------------------------------------------------------------------------
-# 10
-
-# Using overridden
-
-# Before state:
-# -------------
-#
-# vios#show vlan
-# VLAN Name Status Ports
-# ---- -------------------------------- --------- -------------------------------
-# 1 default active Gi0/1, Gi0/2
-# 10 vlan_10 active
-# 20 vlan_20 act/lshut
-# 30 vlan_30 sus/lshut
-# 1002 fddi-default act/unsup
-# 1003 token-ring-default act/unsup
-# 1004 fddinet-default act/unsup
-# 1005 trnet-default act/unsup
-#
-# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2
-# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
-# 1 enet 100001 1500 - - - - - 0 0
-# 10 enet 100010 1500 - - - - - 0 0
-# 20 enet 100020 610 - - - - - 0 0
-# 30 enet 100030 1500 - - - - - 0 0
-# 1002 fddi 101002 1500 - - - - - 0 0
-# 1003 tr 101003 1500 - - - - - 0 0
-# 1004 fdnet 101004 1500 - - - ieee - 0 0
-# 1005 trnet 101005 1500 - - - ibm - 0 0
-#
-# Remote SPAN VLANs
-# ------------------------------------------------------------------------------
-# 10
-
-- name: Override device configuration of all VLANs with provided configuration
- ios_vlans:
- config:
- - name: Vlan_10
- vlan_id: 10
- mtu: 1000
- state: overridden
-
-# After state:
-# ------------
-#
-# vios#show vlan
-# VLAN Name Status Ports
-# ---- -------------------------------- --------- -------------------------------
-# 10 Vlan_10 active
-#
-# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2
-# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
-# 10 enet 100010 1000 - - - - - 0 0
-
-# Using replaced
-
-# Before state:
-# -------------
-#
-# vios#show vlan
-# VLAN Name Status Ports
-# ---- -------------------------------- --------- -------------------------------
-# 1 default active Gi0/1, Gi0/2
-# 10 vlan_10 active
-# 20 vlan_20 act/lshut
-# 30 vlan_30 sus/lshut
-# 1002 fddi-default act/unsup
-# 1003 token-ring-default act/unsup
-# 1004 fddinet-default act/unsup
-# 1005 trnet-default act/unsup
-#
-# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2
-# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
-# 1 enet 100001 1500 - - - - - 0 0
-# 10 enet 100010 1500 - - - - - 0 0
-# 20 enet 100020 610 - - - - - 0 0
-# 30 enet 100030 1500 - - - - - 0 0
-# 1002 fddi 101002 1500 - - - - - 0 0
-# 1003 tr 101003 1500 - - - - - 0 0
-# 1004 fdnet 101004 1500 - - - ieee - 0 0
-# 1005 trnet 101005 1500 - - - ibm - 0 0
-#
-# Remote SPAN VLANs
-# ------------------------------------------------------------------------------
-# 10
-
-- name: Replaces device configuration of listed VLANs with provided configuration
- ios_vlans:
- config:
- - vlan_id: 20
- name: Test_VLAN20
- mtu: 700
- shutdown: disabled
- - vlan_id: 30
- name: Test_VLAN30
- mtu: 1000
- state: replaced
-
-# After state:
-# ------------
-#
-# vios#show vlan
-# VLAN Name Status Ports
-# ---- -------------------------------- --------- -------------------------------
-# 1 default active Gi0/1, Gi0/2
-# 10 vlan_10 active
-# 20 Test_VLAN20 active
-# 30 Test_VLAN30 sus/lshut
-# 1002 fddi-default act/unsup
-# 1003 token-ring-default act/unsup
-# 1004 fddinet-default act/unsup
-# 1005 trnet-default act/unsup
-#
-# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2
-# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
-# 1 enet 100001 1500 - - - - - 0 0
-# 10 enet 100010 1500 - - - - - 0 0
-# 20 enet 100020 700 - - - - - 0 0
-# 30 enet 100030 1000 - - - - - 0 0
-# 1002 fddi 101002 1500 - - - - - 0 0
-# 1003 tr 101003 1500 - - - - - 0 0
-# 1004 fdnet 101004 1500 - - - ieee - 0 0
-# 1005 trnet 101005 1500 - - - ibm - 0 0
-#
-# Remote SPAN VLANs
-# ------------------------------------------------------------------------------
-# 10
-
-# Using deleted
-
-# Before state:
-# -------------
-#
-# vios#show vlan
-# VLAN Name Status Ports
-# ---- -------------------------------- --------- -------------------------------
-# 1 default active Gi0/1, Gi0/2
-# 10 vlan_10 active
-# 20 vlan_20 act/lshut
-# 30 vlan_30 sus/lshut
-# 1002 fddi-default act/unsup
-# 1003 token-ring-default act/unsup
-# 1004 fddinet-default act/unsup
-# 1005 trnet-default act/unsup
-#
-# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2
-# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
-# 1 enet 100001 1500 - - - - - 0 0
-# 10 enet 100010 1500 - - - - - 0 0
-# 20 enet 100020 610 - - - - - 0 0
-# 30 enet 100030 1500 - - - - - 0 0
-# 1002 fddi 101002 1500 - - - - - 0 0
-# 1003 tr 101003 1500 - - - - - 0 0
-# 1004 fdnet 101004 1500 - - - ieee - 0 0
-# 1005 trnet 101005 1500 - - - ibm - 0 0
-#
-# Remote SPAN VLANs
-# ------------------------------------------------------------------------------
-# 10
-
-- name: Delete attributes of given VLANs
- ios_vlans:
- config:
- - vlan_id: 10
- - vlan_id: 20
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show vlan
-# VLAN Name Status Ports
-# ---- -------------------------------- --------- -------------------------------
-# 1 default active Gi0/1, Gi0/2
-# 30 vlan_30 sus/lshut
-# 1002 fddi-default act/unsup
-# 1003 token-ring-default act/unsup
-# 1004 fddinet-default act/unsup
-# 1005 trnet-default act/unsup
-#
-# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2
-# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
-# 1 enet 100001 1500 - - - - - 0 0
-# 30 enet 100030 1500 - - - - - 0 0
-# 1002 fddi 101002 1500 - - - - - 0 0
-# 1003 tr 101003 1500 - - - - - 0 0
-# 1004 fdnet 101004 1500 - - - ieee - 0 0
-# 1005 trnet 101005 1500 - - - ibm - 0 0
-
-# Using Deleted without any config passed
-#"(NOTE: This will delete all of configured vlans attributes)"
-
-# Before state:
-# -------------
-#
-# vios#show vlan
-# VLAN Name Status Ports
-# ---- -------------------------------- --------- -------------------------------
-# 1 default active Gi0/1, Gi0/2
-# 10 vlan_10 active
-# 20 vlan_20 act/lshut
-# 30 vlan_30 sus/lshut
-# 1002 fddi-default act/unsup
-# 1003 token-ring-default act/unsup
-# 1004 fddinet-default act/unsup
-# 1005 trnet-default act/unsup
-#
-# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2
-# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
-# 1 enet 100001 1500 - - - - - 0 0
-# 10 enet 100010 1500 - - - - - 0 0
-# 20 enet 100020 610 - - - - - 0 0
-# 30 enet 100030 1500 - - - - - 0 0
-# 1002 fddi 101002 1500 - - - - - 0 0
-# 1003 tr 101003 1500 - - - - - 0 0
-# 1004 fdnet 101004 1500 - - - ieee - 0 0
-# 1005 trnet 101005 1500 - - - ibm - 0 0
-#
-# Remote SPAN VLANs
-# ------------------------------------------------------------------------------
-# 10
-
-- name: Delete attributes of ALL VLANs
- ios_vlans:
- state: deleted
-
-# After state:
-# -------------
-#
-# vios#show vlan
-# VLAN Name Status Ports
-# ---- -------------------------------- --------- -------------------------------
-# 1 default active Gi0/1, Gi0/2
-# 1002 fddi-default act/unsup
-# 1003 token-ring-default act/unsup
-# 1004 fddinet-default act/unsup
-# 1005 trnet-default act/unsup
-#
-# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2
-# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
-# 1 enet 100001 1500 - - - - - 0 0
-# 1002 fddi 101002 1500 - - - - - 0 0
-# 1003 tr 101003 1500 - - - - - 0 0
-# 1004 fdnet 101004 1500 - - - ieee - 0 0
-# 1005 trnet 101005 1500 - - - ibm - 0 0
-
-"""
-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 20', 'name vlan_20', 'mtu 600', 'remote-span']
-"""
-
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.ios.argspec.vlans.vlans import VlansArgs
-from ansible.module_utils.network.ios.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',))]
-
- module = AnsibleModule(argument_spec=VlansArgs.argument_spec,
- required_if=required_if,
- supports_check_mode=True)
-
- result = Vlans(module).execute_module()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/ios/ios_vrf.py b/lib/ansible/modules/network/ios/ios_vrf.py
deleted file mode 100644
index 1ac01e1339..0000000000
--- a/lib/ansible/modules/network/ios/ios_vrf.py
+++ /dev/null
@@ -1,719 +0,0 @@
-#!/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/>.
-#
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'network'}
-
-
-DOCUMENTATION = """
----
-module: ios_vrf
-version_added: "2.3"
-author: "Peter Sprygada (@privateip)"
-short_description: Manage the collection of VRF definitions on Cisco IOS devices
-description:
- - This module provides declarative management of VRF definitions on
- Cisco IOS devices. It allows playbooks to manage individual or
- the entire VRF collection. It also supports purging VRF definitions from
- the configuration that are not explicitly defined.
-extends_documentation_fragment: ios
-notes:
- - Tested against IOS 15.6
-options:
- vrfs:
- description:
- - The set of VRF definition objects to be configured on the remote
- IOS device. Ths list entries can either be the VRF name or a hash
- of VRF definitions and attributes. This argument is mutually
- exclusive with the C(name) argument.
- name:
- description:
- - The name of the VRF definition to be managed on the remote IOS
- device. The VRF definition name is an ASCII string name used
- to uniquely identify the VRF. This argument is mutually exclusive
- with the C(vrfs) argument
- description:
- description:
- - Provides a short description of the VRF definition in the
- current active configuration. The VRF definition value accepts
- alphanumeric characters used to provide additional information
- about the VRF.
- rd:
- description:
- - The router-distinguisher value uniquely identifies the VRF to
- routing processes on the remote IOS system. The RD value takes
- the form of C(A:B) where C(A) and C(B) are both numeric values.
- 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.
- 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.
- version_added: "2.5"
- delay:
- description:
- - Time in seconds to wait before checking for the operational state on remote
- device.
- version_added: "2.4"
- default: 10
- purge:
- description:
- - Instructs the module to consider the
- VRF definition absolute. It will remove any previously configured
- VRFs on the device.
- default: false
- type: bool
- state:
- description:
- - Configures the state of the VRF definition
- as it relates to the device operational configuration. When set
- to I(present), the VRF should be configured in the device active
- configuration and when set to I(absent) the VRF should not be
- in the device active configuration
- default: present
- choices: ['present', 'absent']
- route_both:
- description:
- - Adds an export and import list of extended route target communities to the VRF.
- version_added: "2.5"
- route_export:
- description:
- - Adds an export list of extended route target communities to the VRF.
- version_added: "2.5"
- route_import:
- description:
- - Adds an import list of extended route target communities to the VRF.
- version_added: "2.5"
- route_both_ipv4:
- description:
- - Adds an export and import list of extended route target communities in address-family configuration submode to the VRF.
- version_added: "2.7"
- route_export_ipv4:
- description:
- - Adds an export list of extended route target communities in address-family configuration submode to the VRF.
- version_added: "2.7"
- route_import_ipv4:
- description:
- - Adds an import list of extended route target communities in address-family configuration submode to the VRF.
- version_added: "2.7"
- route_both_ipv6:
- description:
- - Adds an export and import list of extended route target communities in address-family configuration submode to the VRF.
- version_added: "2.7"
- route_export_ipv6:
- description:
- - Adds an export list of extended route target communities in address-family configuration submode to the VRF.
- version_added: "2.7"
- route_import_ipv6:
- description:
- - Adds an import list of extended route target communities in address-family configuration submode to the VRF.
- version_added: "2.7"
-
-"""
-EXAMPLES = """
-- name: configure a vrf named management
- ios_vrf:
- name: management
- description: oob mgmt vrf
- interfaces:
- - Management1
-
-- name: remove a vrf named test
- ios_vrf:
- name: test
- state: absent
-
-- name: configure set of VRFs and purge any others
- ios_vrf:
- vrfs:
- - red
- - blue
- - green
- purge: yes
-
-- name: Creates a list of import RTs for the VRF with the same parameters
- ios_vrf:
- name: test_import
- rd: 1:100
- route_import:
- - 1:100
- - 3:100
-
-- name: Creates a list of import RTs in address-family configuration submode for the VRF with the same parameters
- ios_vrf:
- name: test_import_ipv4
- rd: 1:100
- route_import_ipv4:
- - 1:100
- - 3:100
-
-- name: Creates a list of import RTs in address-family configuration submode for the VRF with the same parameters
- ios_vrf:
- name: test_import_ipv6
- rd: 1:100
- route_import_ipv6:
- - 1:100
- - 3:100
-
-- name: Creates a list of export RTs for the VRF with the same parameters
- ios_vrf:
- name: test_export
- rd: 1:100
- route_export:
- - 1:100
- - 3:100
-
-- name: Creates a list of export RTs in address-family configuration submode for the VRF with the same parameters
- ios_vrf:
- name: test_export_ipv4
- rd: 1:100
- route_export_ipv4:
- - 1:100
- - 3:100
-
-- name: Creates a list of export RTs in address-family configuration submode for the VRF with the same parameters
- ios_vrf:
- name: test_export_ipv6
- rd: 1:100
- route_export_ipv6:
- - 1:100
- - 3:100
-
-- name: Creates a list of import and export route targets for the VRF with the same parameters
- ios_vrf:
- name: test_both
- rd: 1:100
- route_both:
- - 1:100
- - 3:100
-
-- name: Creates a list of import and export route targets in address-family configuration submode for the VRF with the same parameters
- ios_vrf:
- name: test_both_ipv4
- rd: 1:100
- route_both_ipv4:
- - 1:100
- - 3:100
-
-- name: Creates a list of import and export route targets in address-family configuration submode for the VRF with the same parameters
- ios_vrf:
- name: test_both_ipv6
- rd: 1:100
- route_both_ipv6:
- - 1:100
- - 3:100
-
-"""
-
-RETURN = """
-commands:
- description: The list of configuration mode commands to send to the device
- returned: always
- type: list
- sample:
- - vrf definition ansible
- - description management vrf
- - rd: 1:100
-start:
- description: The time the job started
- returned: always
- type: str
- sample: "2016-11-16 10:38:15.126146"
-end:
- description: The time the job ended
- returned: always
- type: str
- sample: "2016-11-16 10:38:25.595612"
-delta:
- description: The time elapsed to perform all operations
- returned: always
- type: str
- sample: "0:00:10.469466"
-"""
-import re
-import time
-from functools import partial
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.connection import exec_command
-from ansible.module_utils.network.ios.ios import load_config, get_config
-from ansible.module_utils.network.ios.ios import ios_argument_spec
-from ansible.module_utils.network.common.config import NetworkConfig
-from ansible.module_utils.six import iteritems
-
-
-def get_interface_type(interface):
-
- if interface.upper().startswith('ET'):
- return 'ethernet'
- elif interface.upper().startswith('VL'):
- return 'svi'
- elif interface.upper().startswith('LO'):
- return 'loopback'
- elif interface.upper().startswith('MG'):
- return 'management'
- elif interface.upper().startswith('MA'):
- return 'management'
- elif interface.upper().startswith('PO'):
- return 'portchannel'
- elif interface.upper().startswith('NV'):
- return 'nve'
- else:
- return 'unknown'
-
-
-def add_command_to_vrf(name, cmd, commands):
- if 'vrf definition %s' % name not in commands:
- commands.extend(['vrf definition %s' % name])
- commands.append(cmd)
-
-
-def map_obj_to_commands(updates, module):
- commands = list()
-
- for update in updates:
- want, have = update
-
- def needs_update(want, have, x):
- if isinstance(want.get(x), list) and isinstance(have.get(x), list):
- return want.get(x) and (want.get(x) != have.get(x)) and not all(elem in have.get(x) for elem in want.get(x))
- return want.get(x) and (want.get(x) != have.get(x))
-
- if want['state'] == 'absent':
- commands.append('no vrf definition %s' % want['name'])
- continue
-
- if not have.get('state'):
- commands.extend(['vrf definition %s' % want['name']])
- ipv6 = len([k for k, v in module.params.items() if (k.endswith('_ipv6') or k.endswith('_both')) and v]) != 0
- ipv4 = len([k for k, v in module.params.items() if (k.endswith('_ipv4') or k.endswith('_both')) and v]) != 0
- if ipv4:
- commands.extend(['address-family ipv4', 'exit'])
- if ipv6:
- commands.extend(['address-family ipv6', 'exit'])
-
- if needs_update(want, have, 'description'):
- cmd = 'description %s' % want['description']
- add_command_to_vrf(want['name'], cmd, commands)
-
- if needs_update(want, have, 'rd'):
- cmd = 'rd %s' % want['rd']
- add_command_to_vrf(want['name'], cmd, commands)
-
- if needs_update(want, have, 'route_import'):
- for route in want['route_import']:
- cmd = 'route-target import %s' % route
- add_command_to_vrf(want['name'], cmd, commands)
-
- if needs_update(want, have, 'route_export'):
- for route in want['route_export']:
- cmd = 'route-target export %s' % route
- add_command_to_vrf(want['name'], cmd, commands)
-
- if needs_update(want, have, 'route_import_ipv4'):
- cmd = 'address-family ipv4'
- add_command_to_vrf(want['name'], cmd, commands)
- for route in want['route_import_ipv4']:
- cmd = 'route-target import %s' % route
- add_command_to_vrf(want['name'], cmd, commands)
- cmd = 'exit-address-family'
- add_command_to_vrf(want['name'], cmd, commands)
-
- if needs_update(want, have, 'route_export_ipv4'):
- cmd = 'address-family ipv4'
- add_command_to_vrf(want['name'], cmd, commands)
- for route in want['route_export_ipv4']:
- cmd = 'route-target export %s' % route
- add_command_to_vrf(want['name'], cmd, commands)
- cmd = 'exit-address-family'
- add_command_to_vrf(want['name'], cmd, commands)
-
- if needs_update(want, have, 'route_import_ipv6'):
- cmd = 'address-family ipv6'
- add_command_to_vrf(want['name'], cmd, commands)
- for route in want['route_import_ipv6']:
- cmd = 'route-target import %s' % route
- add_command_to_vrf(want['name'], cmd, commands)
- cmd = 'exit-address-family'
- add_command_to_vrf(want['name'], cmd, commands)
-
- if needs_update(want, have, 'route_export_ipv6'):
- cmd = 'address-family ipv6'
- add_command_to_vrf(want['name'], cmd, commands)
- for route in want['route_export_ipv6']:
- cmd = 'route-target export %s' % route
- add_command_to_vrf(want['name'], cmd, commands)
- cmd = 'exit-address-family'
- add_command_to_vrf(want['name'], cmd, commands)
-
- if want['interfaces'] is not None:
- # handle the deletes
- for intf in set(have.get('interfaces', [])).difference(want['interfaces']):
- commands.extend(['interface %s' % intf,
- 'no vrf forwarding %s' % want['name']])
-
- # handle the adds
- for intf in set(want['interfaces']).difference(have.get('interfaces', [])):
- cfg = get_config(module)
- configobj = NetworkConfig(indent=1, contents=cfg)
- children = configobj['interface %s' % intf].children
- intf_config = '\n'.join(children)
-
- commands.extend(['interface %s' % intf,
- 'vrf forwarding %s' % want['name']])
-
- match = re.search('ip address .+', intf_config, re.M)
- if match:
- commands.append(match.group())
-
- return commands
-
-
-def parse_description(configobj, name):
- cfg = configobj['vrf definition %s' % name]
- cfg = '\n'.join(cfg.children)
- match = re.search(r'description (.+)$', cfg, re.M)
- if match:
- return match.group(1)
-
-
-def parse_rd(configobj, name):
- cfg = configobj['vrf definition %s' % name]
- cfg = '\n'.join(cfg.children)
- match = re.search(r'rd (.+)$', cfg, re.M)
- if match:
- return match.group(1)
-
-
-def parse_interfaces(configobj):
- vrf_cfg = 'vrf forwarding'
- interfaces = dict()
- for intf in set(re.findall('^interface .+', str(configobj), re.M)):
- for line in configobj[intf].children:
- if vrf_cfg in line:
- try:
- interfaces[line.split()[-1]].append(intf.split(' ')[1])
- except KeyError:
- interfaces[line.split()[-1]] = [intf.split(' ')[1]]
- return interfaces
-
-
-def parse_import(configobj, name):
- cfg = configobj['vrf definition %s' % name]
- cfg = '\n'.join(cfg.children)
- matches = re.findall(r'route-target\s+import\s+(.+)', cfg, re.M)
- return matches
-
-
-def parse_export(configobj, name):
- cfg = configobj['vrf definition %s' % name]
- cfg = '\n'.join(cfg.children)
- matches = re.findall(r'route-target\s+export\s+(.+)', cfg, re.M)
- return matches
-
-
-def parse_both(configobj, name, address_family='global'):
- rd_pattern = re.compile('(?P<rd>.+:.+)')
- matches = list()
- export_match = None
- import_match = None
- if address_family == "global":
- export_match = parse_export(configobj, name)
- import_match = parse_import(configobj, name)
- elif address_family == "ipv4":
- export_match = parse_export_ipv4(configobj, name)
- import_match = parse_import_ipv4(configobj, name)
- elif address_family == "ipv6":
- export_match = parse_export_ipv6(configobj, name)
- import_match = parse_import_ipv6(configobj, name)
- if import_match and export_match:
- for ex in export_match:
- exrd = rd_pattern.search(ex)
- exrd = exrd.groupdict().get('rd')
- for im in import_match:
- imrd = rd_pattern.search(im)
- imrd = imrd.groupdict().get('rd')
- if exrd == imrd:
- matches.extend([exrd]) if exrd not in matches else None
- matches.extend([imrd]) if imrd not in matches else None
- return matches
-
-
-def parse_import_ipv4(configobj, name):
- cfg = configobj['vrf definition %s' % name]
- try:
- subcfg = cfg['address-family ipv4']
- subcfg = '\n'.join(subcfg.children)
- matches = re.findall(r'route-target\s+import\s+(.+)', subcfg, re.M)
- return matches
- except KeyError:
- pass
-
-
-def parse_export_ipv4(configobj, name):
- cfg = configobj['vrf definition %s' % name]
- try:
- subcfg = cfg['address-family ipv4']
- subcfg = '\n'.join(subcfg.children)
- matches = re.findall(r'route-target\s+export\s+(.+)', subcfg, re.M)
- return matches
- except KeyError:
- pass
-
-
-def parse_import_ipv6(configobj, name):
- cfg = configobj['vrf definition %s' % name]
- try:
- subcfg = cfg['address-family ipv6']
- subcfg = '\n'.join(subcfg.children)
- matches = re.findall(r'route-target\s+import\s+(.+)', subcfg, re.M)
- return matches
- except KeyError:
- pass
-
-
-def parse_export_ipv6(configobj, name):
- cfg = configobj['vrf definition %s' % name]
- try:
- subcfg = cfg['address-family ipv6']
- subcfg = '\n'.join(subcfg.children)
- matches = re.findall(r'route-target\s+export\s+(.+)', subcfg, re.M)
- return matches
- except KeyError:
- pass
-
-
-def map_config_to_obj(module):
- config = get_config(module)
- configobj = NetworkConfig(indent=1, contents=config)
- match = re.findall(r'^vrf definition (\S+)', config, re.M)
- if not match:
- return list()
-
- instances = list()
-
- interfaces = parse_interfaces(configobj)
-
- for item in set(match):
- obj = {
- 'name': item,
- 'state': 'present',
- 'description': parse_description(configobj, item),
- 'rd': parse_rd(configobj, item),
- 'interfaces': interfaces.get(item),
- 'route_import': parse_import(configobj, item),
- 'route_export': parse_export(configobj, item),
- 'route_both': parse_both(configobj, item),
- 'route_import_ipv4': parse_import_ipv4(configobj, item),
- 'route_export_ipv4': parse_export_ipv4(configobj, item),
- 'route_both_ipv4': parse_both(configobj, item, address_family='ipv4'),
- 'route_import_ipv6': parse_import_ipv6(configobj, item),
- 'route_export_ipv6': parse_export_ipv6(configobj, item),
- 'route_both_ipv6': parse_both(configobj, item, address_family='ipv6'),
- }
- 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 validator:
- validator(value, module)
-
- return value
-
-
-def map_params_to_obj(module):
- vrfs = module.params.get('vrfs')
- if not vrfs:
- if not module.params['name'] and module.params['purge']:
- return list()
- elif not module.params['name']:
- module.fail_json(msg='name is required')
- collection = [{'name': module.params['name']}]
- else:
- collection = list()
- for item in vrfs:
- 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['description'] = get_value('description')
- item['rd'] = get_value('rd')
- item['interfaces'] = get_value('interfaces')
- item['state'] = get_value('state')
- item['route_import'] = get_value('route_import')
- item['route_export'] = get_value('route_export')
- item['route_both'] = get_value('route_both')
- item['route_import_ipv4'] = get_value('route_import_ipv4')
- item['route_export_ipv4'] = get_value('route_export_ipv4')
- item['route_both_ipv4'] = get_value('route_both_ipv4')
- item['route_import_ipv6'] = get_value('route_import_ipv6')
- item['route_export_ipv6'] = get_value('route_export_ipv6')
- item['route_both_ipv6'] = get_value('route_both_ipv6')
- both_addresses_family = ["", "_ipv6", "_ipv4"]
- for address_family in both_addresses_family:
- if item["route_both%s" % address_family]:
- if not item["route_export%s" % address_family]:
- item["route_export%s" % address_family] = list()
- if not item["route_import%s" % address_family]:
- item["route_import%s" % address_family] = list()
- item["route_export%s" % address_family].extend(get_value("route_both%s" % address_family))
- item["route_import%s" % address_family].extend(get_value("route_both%s" % address_family))
- item['associated_interfaces'] = get_value('associated_interfaces')
- objects.append(item)
-
- return objects
-
-
-def update_objects(want, have):
- updates = list()
- for entry in want:
- item = next((i for i in have if i['name'] == entry['name']), None)
- if all((item is None, entry['state'] == 'present')):
- updates.append((entry, {}))
- else:
- for key, value in iteritems(entry):
- if value:
- try:
- if isinstance(value, list):
- if sorted(value) != sorted(item[key]):
- if (entry, item) not in updates:
- updates.append((entry, item))
- elif value != item[key]:
- if (entry, item) not in updates:
- updates.append((entry, item))
- except TypeError:
- pass
- return updates
-
-
-def check_declarative_intent_params(want, module, result):
- if module.params['associated_interfaces']:
-
- if result['changed']:
- time.sleep(module.params['delay'])
-
- name = module.params['name']
- rc, out, err = exec_command(module, 'show vrf | include {0}'.format(name))
-
- if rc == 0:
- data = out.strip().split()
- # data will be empty if the vrf was just added
- if not data:
- return
- vrf = data[0]
- interface = data[-1]
-
- for w in want:
- if w['name'] == vrf:
- if w.get('associated_interfaces') is None:
- continue
- for i in w['associated_interfaces']:
- if get_interface_type(i) is not get_interface_type(interface):
- module.fail_json(msg="Interface %s not configured on vrf %s" % (interface, name))
-
-
-def main():
- """ main entry point for module execution
- """
- argument_spec = dict(
- vrfs=dict(type='list'),
-
- name=dict(),
- description=dict(),
- rd=dict(),
- route_export=dict(type='list'),
- route_import=dict(type='list'),
- route_both=dict(type='list'),
- route_export_ipv4=dict(type='list'),
- route_import_ipv4=dict(type='list'),
- route_both_ipv4=dict(type='list'),
- route_export_ipv6=dict(type='list'),
- route_import_ipv6=dict(type='list'),
- route_both_ipv6=dict(type='list'),
-
-
- interfaces=dict(type='list'),
- associated_interfaces=dict(type='list'),
-
- delay=dict(default=10, type='int'),
- purge=dict(type='bool', default=False),
- state=dict(default='present', choices=['present', 'absent'])
- )
-
- argument_spec.update(ios_argument_spec)
-
- mutually_exclusive = [('name', 'vrfs')]
- module = AnsibleModule(argument_spec=argument_spec,
- mutually_exclusive=mutually_exclusive,
- supports_check_mode=True)
-
- result = {'changed': False}
-
- warnings = list()
- 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_vrfs = [x['name'] for x in want]
- have_vrfs = [x['name'] for x in have]
- for item in set(have_vrfs).difference(want_vrfs):
- cmd = 'no vrf definition %s' % item
- if cmd not in commands:
- commands.append(cmd)
-
- result['commands'] = commands
-
- if commands:
- if not module.check_mode:
- load_config(module, commands)
- result['changed'] = True
-
- check_declarative_intent_params(want, module, result)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()