diff --git a/lib/ansible/module_utils/network/ios/argspec/l2_interfaces/l2_interfaces.py b/lib/ansible/module_utils/network/ios/argspec/l2_interfaces/l2_interfaces.py index 6d7e406107e..0c25758a911 100644 --- a/lib/ansible/module_utils/network/ios/argspec/l2_interfaces/l2_interfaces.py +++ b/lib/ansible/module_utils/network/ios/argspec/l2_interfaces/l2_interfaces.py @@ -39,6 +39,9 @@ class L2_InterfacesArgs(object): 'access': {'type': 'dict', 'options': {'vlan': {'type': 'int'}} }, + 'voice': {'type': 'dict', + 'options': {'vlan': {'type': 'int'}} + }, 'trunk': {'type': 'dict', 'options': {'allowed_vlans': {'type': 'list'}, 'encapsulation': {'type': 'str', diff --git a/lib/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py b/lib/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py index ec96aef13f9..552d2974bb6 100644 --- a/lib/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py +++ b/lib/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py @@ -36,6 +36,7 @@ class L2_Interfaces(ConfigBase): ] access_cmds = {'access_vlan': 'switchport access vlan'} + voice_cmds = {'voice_vlan': 'switchport voice vlan'} trunk_cmds = {'encapsulation': 'switchport trunk encapsulation', 'pruning_vlans': 'switchport trunk pruning vlan', 'native_vlan': 'switchport trunk native vlan', 'allowed_vlans': 'switchport trunk allowed vlan'} @@ -250,6 +251,10 @@ class L2_Interfaces(ConfigBase): cmd = 'switchport access vlan {0}'.format(diff.get('access')[0][1]) add_command_to_config_list(interface, cmd, commands) + if diff.get('voice'): + cmd = 'switchport voice vlan {0}'.format(diff.get('voice')[0][1]) + add_command_to_config_list(interface, cmd, commands) + if want_trunk: if diff.get('trunk'): diff = dict(diff.get('trunk')) @@ -287,6 +292,12 @@ class L2_Interfaces(ConfigBase): if have.get('access').get('vlan') != want.get('access').get('vlan'): remove_command_from_config_list(interface, L2_Interfaces.access_cmds['access_vlan'], commands) + if have.get('voice') and want.get('voice') is None: + remove_command_from_config_list(interface, L2_Interfaces.voice_cmds['voice_vlan'], commands) + elif have.get('voice') and want.get('voice'): + if have.get('voice').get('vlan') != want.get('voice').get('vlan'): + remove_command_from_config_list(interface, L2_Interfaces.voice_cmds['voice_vlan'], commands) + if have.get('trunk') and want.get('trunk') is None: # Check when no config is passed if have.get('trunk').get('encapsulation'): diff --git a/lib/ansible/module_utils/network/ios/facts/l2_interfaces/l2_interfaces.py b/lib/ansible/module_utils/network/ios/facts/l2_interfaces/l2_interfaces.py index bddb273badb..27a3b03dca0 100644 --- a/lib/ansible/module_utils/network/ios/facts/l2_interfaces/l2_interfaces.py +++ b/lib/ansible/module_utils/network/ios/facts/l2_interfaces/l2_interfaces.py @@ -91,6 +91,10 @@ class L2_InterfacesFacts(object): if has_access: config["access"] = {"vlan": int(has_access)} + has_voice = utils.parse_conf_arg(conf, 'switchport voice vlan') + if has_voice: + config["voice"] = {"vlan": int(has_voice)} + trunk = dict() trunk["encapsulation"] = utils.parse_conf_arg(conf, 'encapsulation') native_vlan = utils.parse_conf_arg(conf, 'native vlan') diff --git a/lib/ansible/modules/network/ios/ios_l2_interfaces.py b/lib/ansible/modules/network/ios/ios_l2_interfaces.py index c64b5f006eb..80e79471d2b 100644 --- a/lib/ansible/modules/network/ios/ios_l2_interfaces.py +++ b/lib/ansible/modules/network/ios/ios_l2_interfaces.py @@ -66,6 +66,15 @@ options: 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. @@ -126,6 +135,8 @@ EXAMPLES = """ - name: GigabitEthernet0/1 access: vlan: 10 + voice: + vlan: 40 - name: GigabitEthernet0/2 trunk: allowed_vlans: 10-20,40 @@ -141,6 +152,7 @@ EXAMPLES = """ # interface GigabitEthernet0/1 # description Configured by Ansible # switchport access vlan 10 +# switchport access vlan 40 # negotiation auto # interface GigabitEthernet0/2 # description This is test @@ -220,6 +232,8 @@ EXAMPLES = """ - name: GigabitEthernet0/2 access: vlan: 20 + voice: + vlan: 40 state: overridden # After state: @@ -232,6 +246,7 @@ EXAMPLES = """ # interface GigabitEthernet0/2 # description This is test # switchport access vlan 20 +# switchport voice vlan 40 # media-type rj45 # negotiation auto diff --git a/test/integration/targets/ios_l2_interfaces/vars/main.yaml b/test/integration/targets/ios_l2_interfaces/vars/main.yaml index 6d195bb5334..77222118807 100644 --- a/test/integration/targets/ios_l2_interfaces/vars/main.yaml +++ b/test/integration/targets/ios_l2_interfaces/vars/main.yaml @@ -8,6 +8,7 @@ merged: commands: - "interface GigabitEthernet0/1" - "switchport access vlan 30" + - "switchport voice vlan 40" - "interface GigabitEthernet0/2" - "switchport trunk encapsulation dot1q" - "switchport trunk native vlan 20" @@ -18,38 +19,43 @@ merged: - name: GigabitEthernet0/0 - access: vlan: 30 + voice: + vlan: 40 name: GigabitEthernet0/1 - name: GigabitEthernet0/2 trunk: allowed_vlans: - - 15-20 - - '40' + - 15-20 + - "40" encapsulation: dot1q native_vlan: 20 pruning_vlans: - - '10' - - '20' + - "10" + - "20" replaced: before: - - name: GigabitEthernet0/0 - - access: - vlan: 10 - name: GigabitEthernet0/1 - - name: GigabitEthernet0/2 - trunk: - allowed_vlans: - - 10-20 - - '40' - encapsulation: dot1q - native_vlan: 10 - pruning_vlans: - - '10' - - '20' + - name: GigabitEthernet0/0 + - access: + vlan: 10 + voice: + vlan: 40 + name: GigabitEthernet0/1 + - name: GigabitEthernet0/2 + trunk: + allowed_vlans: + - 10-20 + - "40" + encapsulation: dot1q + native_vlan: 10 + pruning_vlans: + - "10" + - "20" commands: - "interface GigabitEthernet0/1" - "switchport access vlan 40" + - "switchport voice vlan 20" - "interface GigabitEthernet0/2" - "no switchport trunk allowed vlan" - "switchport trunk native vlan 20" @@ -59,35 +65,40 @@ replaced: - name: GigabitEthernet0/0 - access: vlan: 40 + voice: + vlan: 20 name: GigabitEthernet0/1 - name: GigabitEthernet0/2 trunk: encapsulation: dot1q native_vlan: 20 pruning_vlans: - - 10-20 - - '30' + - 10-20 + - "30" overridden: before: - name: GigabitEthernet0/0 - access: vlan: 10 + voice: + vlan: 40 name: GigabitEthernet0/1 - name: GigabitEthernet0/2 trunk: allowed_vlans: - - 10-20 - - '40' + - 10-20 + - "40" encapsulation: dot1q native_vlan: 10 pruning_vlans: - - '10' - - '20' + - "10" + - "20" commands: - "interface GigabitEthernet0/1" - "no switchport access vlan" + - "no switchport voice vlan" - "interface GigabitEthernet0/2" - "no switchport trunk pruning vlan" - "switchport trunk encapsulation isl" @@ -100,8 +111,8 @@ overridden: - name: GigabitEthernet0/2 trunk: allowed_vlans: - - 30-35 - - '40' + - 30-35 + - "40" encapsulation: isl native_vlan: 30 @@ -110,21 +121,24 @@ deleted: - name: GigabitEthernet0/0 - access: vlan: 10 + voice: + vlan: 40 name: GigabitEthernet0/1 - name: GigabitEthernet0/2 trunk: allowed_vlans: - - 10-20 - - '40' + - 10-20 + - "40" encapsulation: dot1q native_vlan: 10 pruning_vlans: - - '10' - - '20' + - "10" + - "20" commands: - "interface GigabitEthernet0/1" - "no switchport access vlan" + - "no switch voice vlan" - "interface GigabitEthernet0/2" - "no switchport trunk encapsulation" - "no switchport trunk native vlan"