diff --git a/lib/ansible/modules/network/nxos/nxos_switchport.py b/lib/ansible/modules/network/nxos/nxos_switchport.py
index 3fc3837394..a629370d58 100644
--- a/lib/ansible/modules/network/nxos/nxos_switchport.py
+++ b/lib/ansible/modules/network/nxos/nxos_switchport.py
@@ -16,10 +16,10 @@
# along with Ansible. If not, see .
#
-ANSIBLE_METADATA = {'metadata_version': '1.0',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
+ANSIBLE_METADATA = {
+ 'metadata_version': '1.0',
+ 'status': ['preview'],
+ 'supported_by': 'community'}
DOCUMENTATION = '''
---
@@ -28,74 +28,73 @@ extends_documentation_fragment: nxos
version_added: "2.1"
short_description: Manages Layer 2 switchport interfaces.
description:
- - Manages Layer 2 interfaces
+ - Manages Layer 2 interfaces
author: Jason Edelman (@jedelman8)
notes:
- - When C(state=absent), VLANs can be added/removed from trunk links and
- the existing access VLAN can be 'unconfigured' to just having VLAN 1
- on that interface.
- - When working with trunks VLANs the keywords add/remove are always sent
- in the `switchport trunk allowed vlan` command. Use verbose mode to see
- commands sent.
- - When C(state=unconfigured), the interface will result with having a default
- Layer 2 interface, i.e. vlan 1 in access mode.
+ - When C(state=absent), VLANs can be added/removed from trunk links and
+ the existing access VLAN can be 'unconfigured' to just having VLAN 1
+ on that interface.
+ - When working with trunks VLANs the keywords add/remove are always sent
+ in the `switchport trunk allowed vlan` command. Use verbose mode to see
+ commands sent.
+ - When C(state=unconfigured), the interface will result with having a default
+ Layer 2 interface, i.e. vlan 1 in access mode.
options:
- interface:
- description:
- - Full name of the interface, i.e. Ethernet1/1.
- required: true
- default: null
- mode:
- description:
- - Mode for the Layer 2 port.
- required: false
- default: null
- choices: ['access','trunk']
- access_vlan:
- description:
- - If C(mode=access), used as the access VLAN ID.
- required: false
- default: null
- native_vlan:
- description:
- - If C(mode=trunk), used as the trunk native VLAN ID.
- required: false
- default: null
- trunk_vlans:
- description:
- - If C(mode=trunk), used as the VLAN range to ADD or REMOVE
- from the trunk.
- aliases:
- - trunk_add_vlans
- required: false
- default: null
- state:
- description:
- - Manage the state of the resource.
- required: false
- default: present
- choices: ['present','absent', 'unconfigured']
- trunk_allowed_vlans:
- description:
- - if C(mode=trunk), these are the only VLANs that will be
- configured on the trunk, i.e. "2-10,15".
- required: false
- version_added: 2.2
- default: null
+ interface:
+ description:
+ - Full name of the interface, i.e. Ethernet1/1.
+ required: true
+ default: null
+ mode:
+ description:
+ - Mode for the Layer 2 port.
+ required: false
+ default: null
+ choices: ['access','trunk']
+ access_vlan:
+ description:
+ - If C(mode=access), used as the access VLAN ID.
+ required: false
+ default: null
+ native_vlan:
+ description:
+ - If C(mode=trunk), used as the trunk native VLAN ID.
+ required: false
+ default: null
+ trunk_vlans:
+ description:
+ - If C(mode=trunk), used as the VLAN range to ADD or REMOVE
+ from the trunk.
+ aliases:
+ - trunk_add_vlans
+ required: false
+ default: null
+ state:
+ description:
+ - Manage the state of the resource.
+ required: false
+ default: present
+ choices: ['present','absent', 'unconfigured']
+ trunk_allowed_vlans:
+ description:
+ - if C(mode=trunk), these are the only VLANs that will be
+ configured on the trunk, i.e. "2-10,15".
+ required: false
+ version_added: 2.2
+ default: null
'''
+
EXAMPLES = '''
- name: Ensure Eth1/5 is in its default switchport state
nxos_switchport:
interface: eth1/5
state: unconfigured
- host: "{{ inventory_hostname }}"
- name: Ensure Eth1/5 is configured for access vlan 20
nxos_switchport:
interface: eth1/5
mode: access
access_vlan: 20
- host: "{{ inventory_hostname }}"
- name: Ensure Eth1/5 only has vlans 5-10 as trunk vlans
nxos_switchport:
@@ -103,7 +102,6 @@ EXAMPLES = '''
mode: trunk
native_vlan: 10
trunk_vlans: 5-10
- host: "{{ inventory_hostname }}"
- name: Ensure eth1/5 is a trunk port and ensure 2-50 are being tagged (doesn't mean others aren't also being tagged)
nxos_switchport:
@@ -111,59 +109,28 @@ EXAMPLES = '''
mode: trunk
native_vlan: 10
trunk_vlans: 2-50
- host: "{{ inventory_hostname }}"
- name: Ensure these VLANs are not being tagged on the trunk
nxos_switchport:
interface: eth1/5
mode: trunk
trunk_vlans: 51-4094
- host: "{{ inventory_hostname }} "
state: absent
'''
RETURN = '''
-proposed:
- description: k/v pairs of parameters passed into module
- returned: always
- type: dict
- sample: {"access_vlan": "10", "interface": "eth1/5", "mode": "access"}
-existing:
- description: k/v pairs of existing switchport
- returned: always
- type: dict
- sample: {"access_vlan": "10", "access_vlan_name": "VLAN0010",
- "interface": "Ethernet1/5", "mode": "access",
- "native_vlan": "1", "native_vlan_name": "default",
- "switchport": "Enabled", "trunk_vlans": "1-4094"}
-end_state:
- description: k/v pairs of switchport after module execution
- returned: always
- type: dict
- sample: {"access_vlan": "10", "access_vlan_name": "VLAN0010",
- "interface": "Ethernet1/5", "mode": "access",
- "native_vlan": "1", "native_vlan_name": "default",
- "switchport": "Enabled", "trunk_vlans": "1-4094"}
-updates:
+commands:
description: command string sent to the device
returned: always
type: list
sample: ["interface eth1/5", "switchport access vlan 20"]
-changed:
- description: check to see if a change was made on the device
- returned: always
- type: boolean
- sample: true
'''
-from ansible.module_utils.nxos import get_config, load_config, run_commands
+from ansible.module_utils.nxos import load_config, run_commands
from ansible.module_utils.nxos import nxos_argument_spec, check_args
from ansible.module_utils.basic import AnsibleModule
-import re
-import re
-
def get_interface_type(interface):
"""Gets the type of interface
Args:
@@ -201,12 +168,12 @@ def get_interface_mode(interface, module):
"""
command = 'show interface ' + interface
intf_type = get_interface_type(interface)
- body = execute_show_command(command, module)
mode = 'unknown'
interface_table = {}
try:
- interface_table = body[0]['TABLE_interface']['ROW_interface']
+ body = execute_show_command(command, module)[0]
+ interface_table = body['TABLE_interface']['ROW_interface']
except (KeyError, AttributeError, IndexError):
return mode
@@ -231,11 +198,12 @@ def interface_is_portchannel(interface, module):
True/False based on if interface is a member of a portchannel bundle
"""
intf_type = get_interface_type(interface)
+
if intf_type == 'ethernet':
command = 'show interface ' + interface
- body = execute_show_command(command, module)
try:
- interface_table = body[0]['TABLE_interface']['ROW_interface']
+ body = execute_show_command(command, module)[0]
+ interface_table = body['TABLE_interface']['ROW_interface']
except (KeyError, AttributeError, IndexError):
interface_table = None
@@ -261,14 +229,13 @@ def get_switchport(port, module):
command = 'show interface {0} switchport'.format(port)
- body = execute_show_command(command, module)
-
try:
body = execute_show_command(command, module)[0]
- except IndexError:
- body = []
+ sp_table = body['TABLE_interface']['ROW_interface']
+ except (KeyError, AttributeError, IndexError):
+ sp_table = None
- if body:
+ if sp_table:
key_map = {
"interface": "interface",
"oper_mode": "mode",
@@ -279,12 +246,9 @@ def get_switchport(port, module):
"native_vlan_name": "native_vlan_name",
"trunk_vlans": "trunk_vlans"
}
-
- sp_table = body['TABLE_interface']['ROW_interface']
-
sp = apply_key_map(key_map, sp_table)
-
return sp
+
else:
return {}
@@ -293,28 +257,32 @@ def remove_switchport_config_commands(interface, 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'))
+ command = 'no switchport access vlan {0}'.format(existing.get('access_vlan'))
commands.append(command)
+
elif mode == 'trunk':
tv_check = existing.get('trunk_vlans_list') == proposed.get('trunk_vlans_list')
+
if not tv_check:
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:
- command = 'switchport trunk allowed vlan remove {0}'.format(
- proposed.get('trunk_vlans', proposed.get('trunk_allowed_vlans')))
+ 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')
+
+ 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'))
+ command = 'no switchport trunk native vlan {0}'.format(existing.get('native_vlan'))
commands.append(command)
+
if commands:
commands.insert(0, 'interface ' + interface)
return commands
@@ -326,29 +294,32 @@ def get_switchport_config_commands(interface, existing, proposed, module):
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 = existing.get('access_vlan') == proposed.get('access_vlan')
if not av_check:
- command = 'switchport access vlan {0}'.format(
- proposed.get('access_vlan'))
+ 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')
@@ -357,12 +328,11 @@ def get_switchport_config_commands(interface, existing, proposed, module):
command = 'switchport trunk allowed vlan add {0}'.format(proposed.get('trunk_vlans'))
commands.append(command)
- native_check = existing.get(
- 'native_vlan') == proposed.get('native_vlan')
+ native_check = existing.get('native_vlan') == proposed.get('native_vlan')
if not native_check and proposed.get('native_vlan'):
- command = 'switchport trunk native vlan {0}'.format(
- proposed.get('native_vlan'))
+ command = 'switchport trunk native vlan {0}'.format(proposed.get('native_vlan'))
commands.append(command)
+
if commands:
commands.insert(0, 'interface ' + interface)
return commands
@@ -417,9 +387,13 @@ def vlan_range_to_list(vlans):
def get_list_of_vlans(module):
command = 'show vlan'
- body = execute_show_command(command, module)
vlan_list = []
- vlan_table = body[0].get('TABLE_vlanbrief')['ROW_vlanbrief']
+
+ try:
+ body = execute_show_command(command, module)[0]
+ vlan_table = body['TABLE_vlanbrief']['ROW_vlanbrief']
+ except (KeyError, AttributeError, IndexError):
+ return []
if isinstance(vlan_table, list):
for vlan in vlan_table:
@@ -449,7 +423,7 @@ def apply_key_map(key_map, table):
for key, value in table.items():
new_key = key_map.get(key)
if new_key:
- new_dict[new_key] = str(value)
+ new_dict[new_key] = value
return new_dict
@@ -461,8 +435,7 @@ def apply_value_map(value_map, resource):
def execute_show_command(command, module, command_type='cli_show'):
if module.params['transport'] == 'cli':
- if 'status' not in command:
- command += ' | json'
+ command += ' | json'
cmds = [command]
body = run_commands(module, cmds)
elif module.params['transport'] == 'nxapi':
@@ -491,22 +464,22 @@ def main():
native_vlan=dict(type='str', required=False),
trunk_vlans=dict(type='str', aliases=['trunk_add_vlans'], required=False),
trunk_allowed_vlans=dict(type='str', required=False),
- state=dict(choices=['absent', 'present', 'unconfigured'],
- default='present')
+ state=dict(choices=['absent', 'present', 'unconfigured'], default='present')
)
argument_spec.update(nxos_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)
+ mutually_exclusive=[['access_vlan', 'trunk_vlans'],
+ ['access_vlan', 'native_vlan'],
+ ['access_vlan', 'trunk_allowed_vlans']],
+ supports_check_mode=True)
warnings = list()
+ commands = []
+ results = {'changed': False}
check_args(module, warnings)
-
interface = module.params['interface']
mode = module.params['mode']
access_vlan = module.params['access_vlan']
@@ -524,12 +497,10 @@ def main():
interface = interface.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')
+ 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')
+ module.fail_json(msg='access_vlan param not supported when using mode=trunk')
current_mode = get_interface_mode(interface, module)
@@ -552,6 +523,18 @@ def main():
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':
@@ -563,65 +546,37 @@ def main():
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)
-
- 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
-
- changed = False
-
- commands = []
- if state == 'present':
- command = get_switchport_config_commands(interface, existing, proposed, module)
- commands.append(command)
+ else:
+ command = get_switchport_config_commands(interface, existing, proposed, module)
+ commands.append(command)
elif state == 'unconfigured':
is_default = is_switchport_default(existing)
if not is_default:
command = default_switchport_config(interface)
commands.append(command)
elif state == 'absent':
- command = remove_switchport_config_commands(interface, existing,
- proposed, module)
+ command = remove_switchport_config_commands(interface, existing, proposed, module)
commands.append(command)
if trunk_vlans or trunk_allowed_vlans:
existing.pop('trunk_vlans_list')
proposed.pop('trunk_vlans_list')
- end_state = existing
-
cmds = flatten_list(commands)
if cmds:
if module.check_mode:
module.exit_json(changed=True, commands=cmds)
else:
- changed = True
+ results['changed'] = True
load_config(module, cmds)
- end_state = get_switchport(interface, module)
if 'configure' in cmds:
cmds.pop(0)
- results = {}
- results['proposed'] = proposed
- results['existing'] = existing
- results['end_state'] = end_state
- results['updates'] = cmds
- results['changed'] = changed
+ results['commands'] = cmds
results['warnings'] = warnings
module.exit_json(**results)
if __name__ == '__main__':
main()
-
diff --git a/test/sanity/pep8/legacy-files.txt b/test/sanity/pep8/legacy-files.txt
index 425a976b41..8527486b28 100644
--- a/test/sanity/pep8/legacy-files.txt
+++ b/test/sanity/pep8/legacy-files.txt
@@ -378,7 +378,6 @@ lib/ansible/modules/network/nxos/nxos_snmp_location.py
lib/ansible/modules/network/nxos/nxos_snmp_traps.py
lib/ansible/modules/network/nxos/nxos_snmp_user.py
lib/ansible/modules/network/nxos/nxos_static_route.py
-lib/ansible/modules/network/nxos/nxos_switchport.py
lib/ansible/modules/network/nxos/nxos_system.py
lib/ansible/modules/network/nxos/nxos_udld.py
lib/ansible/modules/network/nxos/nxos_udld_interface.py
diff --git a/test/units/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet b/test/units/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet
new file mode 100644
index 0000000000..60e729b2c3
--- /dev/null
+++ b/test/units/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet
@@ -0,0 +1,97 @@
+{
+ "TABLE_interface": {
+ "ROW_interface": {
+ "interface": "Ethernet2/1",
+ "state": "up",
+ "admin_state": "up",
+ "share_state": "Dedicated",
+ "eth_hw_desc": "Ethernet",
+ "eth_hw_addr": "fa16.3e00.0001",
+ "eth_bia_addr": "fa16.3e27.f279",
+ "desc": "to nxos03",
+ "eth_ip_addr": "10.0.0.45",
+ "eth_ip_mask": 30,
+ "eth_ip_prefix": "10.0.0.44",
+ "eth_mtu": "1500",
+ "eth_bw": 1000000,
+ "eth_dly": 10,
+ "eth_reliability": "255",
+ "eth_txload": "1",
+ "eth_rxload": "1",
+ "medium": "broadcast",
+ "eth_mode": "access",
+ "eth_bundle": 0,
+ "eth_duplex": "full",
+ "eth_speed": "1000 Mb/s",
+ "eth_beacon": "off",
+ "eth_autoneg": "off",
+ "eth_in_flowctrl": "off",
+ "eth_out_flowctrl": "off",
+ "eth_mdix": "off",
+ "eth_swt_monitor": "off",
+ "eth_ethertype": "0x8100",
+ "eth_eee_state": "n/a",
+ "eth_link_flapped": "13week(s) 0day(s)",
+ "eth_clear_counters": "never",
+ "eth_reset_cntr": 1,
+ "eth_load_interval1_rx": 0,
+ "eth_inrate1_bits": 0,
+ "eth_inrate1_pkts": 0,
+ "eth_load_interval1_tx": 0,
+ "eth_outrate1_bits": 0,
+ "eth_outrate1_pkts": 0,
+ "eth_inrate1_summary_bits": "0 bps",
+ "eth_inrate1_summary_pkts": "0 pps",
+ "eth_outrate1_summary_bits": "0 bps",
+ "eth_outrate1_summary_pkts": "0 pps",
+ "eth_load_interval2_rx": 0,
+ "eth_inrate2_bits": 0,
+ "eth_inrate2_pkts": 0,
+ "eth_load_interval2_tx": 0,
+ "eth_outrate2_bits": 0,
+ "eth_outrate2_pkts": 0,
+ "eth_inrate2_summary_bits": "0 bps",
+ "eth_inrate2_summary_pkts": "0 pps",
+ "eth_outrate2_summary_bits": "0 bps",
+ "eth_outrate2_summary_pkts": "0 pps",
+ "eth_inucast": 0,
+ "eth_inmcast": 0,
+ "eth_inbcast": 0,
+ "eth_inpkts": 0,
+ "eth_inbytes": 0,
+ "eth_jumbo_inpkts": 0,
+ "eth_storm_supp": 0,
+ "eth_runts": 0,
+ "eth_giants": 0,
+ "eth_crc": 0,
+ "eth_nobuf": 0,
+ "eth_inerr": 0,
+ "eth_frame": 0,
+ "eth_overrun": 0,
+ "eth_underrun": 0,
+ "eth_ignored": 0,
+ "eth_watchdog": 0,
+ "eth_bad_eth": 0,
+ "eth_bad_proto": 0,
+ "eth_in_ifdown_drops": 0,
+ "eth_dribble": 0,
+ "eth_indiscard": 0,
+ "eth_inpause": 0,
+ "eth_outucast": 0,
+ "eth_outmcast": 0,
+ "eth_outbcast": 0,
+ "eth_outpkts": 0,
+ "eth_outbytes": 0,
+ "eth_jumbo_outpkts": 0,
+ "eth_outerr": 0,
+ "eth_coll": 0,
+ "eth_deferred": 0,
+ "eth_latecoll": 0,
+ "eth_lostcarrier": 0,
+ "eth_nocarrier": 0,
+ "eth_babbles": 0,
+ "eth_outdiscard": 0,
+ "eth_outpause": 0
+ }
+ }
+}
diff --git a/test/units/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet_switchport b/test/units/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet_switchport
new file mode 100644
index 0000000000..352da5e7a3
--- /dev/null
+++ b/test/units/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet_switchport
@@ -0,0 +1,14 @@
+{
+ "TABLE_interface": {
+ "ROW_interface": {
+ "interface": "Ethernet2/1",
+ "oper_mode": "access",
+ "switchport": "Enabled",
+ "access_vlan": 2,
+ "access_vlan_name": "VLAN2",
+ "native_vlan": 10,
+ "native_vlan_name": "VLAN10",
+ "trunk_vlans": "1-50"
+ }
+ }
+}
diff --git a/test/units/modules/network/nxos/fixtures/nxos_switchport/show_vlan b/test/units/modules/network/nxos/fixtures/nxos_switchport/show_vlan
new file mode 100644
index 0000000000..407267bb00
--- /dev/null
+++ b/test/units/modules/network/nxos/fixtures/nxos_switchport/show_vlan
@@ -0,0 +1,18 @@
+{
+ "TABLE_vlanbrief": {
+ "ROW_vlanbrief": {
+ "vlanshowbr-vlanid": 1,
+ "vlanshowbr-vlanid-utf": 1,
+ "vlanshowbr-vlanname": "VLAN1",
+ "vlanshowbr-vlanstate": "active",
+ "vlanshowbr-shutstate": "noshutdown"
+ }
+ },
+ "TABLE_mtuinfo": {
+ "ROW_mtuinfo": {
+ "vlanshowinfo-vlanid": 1,
+ "vlanshowinfo-media-type": "enet",
+ "vlanshowinfo-vlanmode": "ce-vlan"
+ }
+ }
+}
diff --git a/test/units/modules/network/nxos/test_nxos_switchport.py b/test/units/modules/network/nxos/test_nxos_switchport.py
new file mode 100644
index 0000000000..de302f3ff4
--- /dev/null
+++ b/test/units/modules/network/nxos/test_nxos_switchport.py
@@ -0,0 +1,74 @@
+# (c) 2016 Red Hat Inc.
+#
+# 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 .
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import os
+
+from ansible.compat.tests.mock import patch
+from ansible.modules.network.nxos import nxos_switchport
+from .nxos_module import TestNxosModule, load_fixture, set_module_args
+
+
+class TestNxosSwitchportModule(TestNxosModule):
+
+ module = nxos_switchport
+
+ def setUp(self):
+ self.mock_run_commands = patch('ansible.modules.network.nxos.nxos_switchport.run_commands')
+ self.run_commands = self.mock_run_commands.start()
+
+ self.mock_load_config = patch('ansible.modules.network.nxos.nxos_switchport.load_config')
+ self.load_config = self.mock_load_config.start()
+
+ def tearDown(self):
+ self.mock_run_commands.stop()
+ self.mock_load_config.stop()
+
+ def load_fixtures(self, commands=None, device=''):
+ def load_from_file(*args, **kwargs):
+ module, commands = args
+ output = list()
+ for command in commands:
+ filename = str(command).split(' | ')[0].replace(' ', '_')
+ filename = filename.replace('2/1', '')
+ output.append(load_fixture('nxos_switchport', filename))
+ return output
+
+ self.run_commands.side_effect = load_from_file
+ self.load_config.return_value = None
+
+ def test_nxos_switchport_present(self):
+ set_module_args(dict(interface='Ethernet2/1', mode='access', access_vlan=1, state='present'))
+ result = self.execute_module(changed=True)
+ self.assertEqual(result['commands'], ['interface ethernet2/1', 'switchport access vlan 1'])
+
+ def test_nxos_switchport_unconfigured(self):
+ set_module_args(dict(interface='Ethernet2/1', state='unconfigured'))
+ result = self.execute_module(changed=True)
+ self.assertEqual(result['commands'], ['interface ethernet2/1',
+ 'switchport mode access',
+ 'switch access vlan 1',
+ 'switchport trunk native vlan 1',
+ 'switchport trunk allowed vlan all'])
+
+ def test_nxos_switchport_absent(self):
+ set_module_args(dict(interface='Ethernet2/1', mode='access', access_vlan=3, state='absent'))
+ result = self.execute_module(changed=False)
+ self.assertEqual(result['commands'], [])