1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Remove unnecessary if, and Fix Documentation (#34413)

* Remove unnecessary if, and Fix Documentation

Signed-off-by: Samer Deeb <samerd@mellanox.com>

* Fix aggregate spec for l2 interface

Signed-off-by: Samer Deeb <samerd@mellanox.com>

* Add aggregste test for l2 interface

Signed-off-by: Samer Deeb <samerd@mellanox.com>

* Fix MAC address case

Signed-off-by: Samer Deeb <samerd@mellanox.com>
This commit is contained in:
Samer Deeb 2018-01-07 00:35:50 -08:00 committed by John R Barker
parent 2916ff0a1a
commit 5edb800b6d
12 changed files with 107 additions and 162 deletions

View file

@ -1,27 +1,14 @@
#!/usr/bin/python #!/usr/bin/python
# #
# This file is part of Ansible # Copyright: Ansible Project
# # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# 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/>.
#
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1', ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'], 'status': ['preview'],
'supported_by': 'network'} 'supported_by': 'community'}
DOCUMENTATION = """ DOCUMENTATION = """
--- ---
@ -31,21 +18,18 @@ version_added: "2.5"
author: "Samer Deeb (@samerd)" author: "Samer Deeb (@samerd)"
short_description: Run commands on remote devices running Mellanox MLNX-OS short_description: Run commands on remote devices running Mellanox MLNX-OS
description: description:
- >- - Sends arbitrary commands to an Mellanox MLNX-OS network device and returns
Sends arbitrary commands to an mlnxos node and returns the results the results read from the device. This module includes an
read from the device. This module includes an
argument that will cause the module to wait for a specific condition argument that will cause the module to wait for a specific condition
before returning or timing out if the condition is not met. before returning or timing out if the condition is not met.
- >- - This module does not support running commands in configuration mode.
This module does not support running commands in configuration mode.
Please use M(mlnxos_config) to configure Mellanox MLNX-OS devices. Please use M(mlnxos_config) to configure Mellanox MLNX-OS devices.
notes: notes:
- tested on Mellanox OS 3.6.4000 - Tested on MLNX-OS 3.6.4000
options: options:
commands: commands:
description: description:
- >- - List of commands to send to the remote mlnxos device over the
List of commands to send to the remote mlnxos device over the
configured provider. The resulting output from the command configured provider. The resulting output from the command
is returned. If the I(wait_for) argument is provided, the is returned. If the I(wait_for) argument is provided, the
module is not returned until the condition is satisfied or module is not returned until the condition is satisfied or
@ -53,43 +37,34 @@ options:
required: true required: true
wait_for: wait_for:
description: description:
- >- - List of conditions to evaluate against the output of the
List of conditions to evaluate against the output of the
command. The task will wait for each condition to be true command. The task will wait for each condition to be true
before moving forward. If the conditional is not true before moving forward. If the conditional is not true
within the configured number of retries, the task fails. within the configured number of retries, the task fails.
See examples. See examples.
required: false
default: null
match: match:
description: description:
- >- - The I(match) argument is used in conjunction with the
The I(match) argument is used in conjunction with the
I(wait_for) argument to specify the match policy. Valid 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) 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 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 the value is set to C(any) then only one of the values must be
satisfied. satisfied.
required: false
default: all default: all
choices: ['any', 'all'] choices: ['any', 'all']
retries: retries:
description: description:
- >- - Specifies the number of retries a command should by tried
Specifies the number of retries a command should by tried
before it is considered failed. The command is run on the before it is considered failed. The command is run on the
target device every retry and evaluated against the target device every retry and evaluated against the
I(wait_for) conditions. I(wait_for) conditions.
required: false
default: 10 default: 10
interval: interval:
description: description:
- >- - Configures the interval in seconds to wait between retries
Configures the interval in seconds to wait between retries
of the command. If the command does not pass the specified of the command. If the command does not pass the specified
conditions, the interval indicates how long to wait before conditions, the interval indicates how long to wait before
trying the command again. trying the command again.
required: false
default: 1 default: 1
""" """

View file

@ -20,7 +20,7 @@ short_description: Manage Mellanox MLNX-OS configuration sections
description: description:
- Mellanox MLNX-OS configurations uses a simple block indent file syntax - Mellanox MLNX-OS configurations uses a simple block indent file syntax
for segmenting configuration into sections. This module provides for segmenting configuration into sections. This module provides
an implementation for working with MLNXOS configuration sections in an implementation for working with MLNX-OS configuration sections in
a deterministic way. a deterministic way.
options: options:
lines: lines:
@ -30,8 +30,6 @@ options:
in the device running-config. Be sure to note the configuration in the device running-config. Be sure to note the configuration
command syntax as some commands are automatically modified by the command syntax as some commands are automatically modified by the
device config parser. device config parser.
required: false
default: null
aliases: ['commands'] aliases: ['commands']
parents: parents:
description: description:
@ -39,8 +37,6 @@ options:
the commands should be checked against. If the parents argument the commands should be checked against. If the parents argument
is omitted, the commands are checked against the set of top is omitted, the commands are checked against the set of top
level or global commands. level or global commands.
required: false
default: null
src: src:
description: description:
- Specifies the source path to the file that contains the configuration - Specifies the source path to the file that contains the configuration
@ -48,8 +44,6 @@ options:
either be the full path on the Ansible control host or a relative 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 path from the playbook or role root directory. This argument is mutually
exclusive with I(lines), I(parents). exclusive with I(lines), I(parents).
required: false
default: null
before: before:
description: description:
- The ordered set of commands to push on to the command stack if - The ordered set of commands to push on to the command stack if
@ -57,16 +51,12 @@ options:
the opportunity to perform configuration commands prior to pushing the opportunity to perform configuration commands prior to pushing
any changes without affecting how the set of commands are matched any changes without affecting how the set of commands are matched
against the system. against the system.
required: false
default: null
after: after:
description: description:
- The ordered set of commands to append to the end of the command - 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 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 allows the playbook designer to append a set of commands to be
executed after the command set. executed after the command set.
required: false
default: null
match: match:
description: description:
- Instructs the module on the way to perform the matching of - Instructs the module on the way to perform the matching of
@ -77,7 +67,6 @@ options:
must be an equal match. Finally, if match is set to I(none), the must be an equal match. Finally, if match is set to I(none), the
module will not attempt to compare the source configuration with module will not attempt to compare the source configuration with
the running configuration on the remote device. the running configuration on the remote device.
required: false
default: line default: line
choices: ['line', 'strict', 'exact', 'none'] choices: ['line', 'strict', 'exact', 'none']
replace: replace:
@ -88,7 +77,6 @@ options:
mode. If the replace argument is set to I(block) then the entire 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 command block is pushed to the device in configuration mode if any
line is not correct line is not correct
required: false
default: line default: line
choices: ['line', 'block'] choices: ['line', 'block']
backup: backup:
@ -98,7 +86,6 @@ options:
changes are made. The backup file is written to the C(backup) changes are made. The backup file is written to the C(backup)
folder in the playbook root directory. If the directory does not folder in the playbook root directory. If the directory does not
exist, it is created. exist, it is created.
required: false
default: no default: no
choices: ['yes', 'no'] choices: ['yes', 'no']
config: config:
@ -107,35 +94,21 @@ options:
the base configuration to be used to validate configuration the base configuration to be used to validate configuration
changes necessary. If this argument is provided, the module changes necessary. If this argument is provided, the module
will not download the running-config from the remote node. will not download the running-config from the remote node.
required: false
default: null
save: save:
description: description:
- The C(save) argument instructs the module to save the running- - The C(save) argument instructs the module to save the running-
config to the startup-config at the conclusion of the module config to the startup-config at the conclusion of the module
running. If check mode is specified, this argument is ignored. running. If check mode is specified, this argument is ignored.
required: false
default: no default: no
choices: ['yes', 'no'] choices: ['yes', 'no']
""" """
EXAMPLES = """ EXAMPLES = """
# Note: examples below use the following provider dict to handle
# transport and authentication to the node.
---
vars:
cli:
host: "{{ inventory_hostname }}"
username: admin
password: admin
authorize: yes
--- ---
- mlnxos_config: - mlnxos_config:
lines: lines:
- snmp-server community - snmp-server community
- snmp-server host 10.2.2.2 traps version 2c - snmp-server host 10.2.2.2 traps version 2c
provider: "{{ cli }}"
""" """
RETURN = """ RETURN = """
@ -154,8 +127,9 @@ backup_path:
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.common.config import NetworkConfig, dumps from ansible.module_utils.network.common.config import NetworkConfig, dumps
from ansible.module_utils.network.mlnxos.mlnxos import get_config, \ from ansible.module_utils.network.mlnxos.mlnxos import get_config
load_config, run_commands from ansible.module_utils.network.mlnxos.mlnxos import load_config
from ansible.module_utils.network.mlnxos.mlnxos import run_commands
def get_candidate(module): def get_candidate(module):

View file

@ -62,7 +62,8 @@ options:
description: description:
- Purge Interfaces not defined in the aggregate parameter. - Purge Interfaces not defined in the aggregate parameter.
This applies only for logical interface. This applies only for logical interface.
default: no default: false
type: bool
state: state:
description: description:
- State of the Interface configuration, C(up) means present and - State of the Interface configuration, C(up) means present and
@ -179,18 +180,15 @@ class MlnxosInterfaceModule(BaseMlnxosModule):
return aggregate_spec return aggregate_spec
def init_module(self): def init_module(self):
""" main entry point for module execution """ module initialization
""" """
element_spec = self._get_element_spec() element_spec = self._get_element_spec()
aggregate_spec = self._get_aggregate_spec(element_spec) aggregate_spec = self._get_aggregate_spec(element_spec)
if aggregate_spec:
argument_spec = dict( argument_spec = dict(
aggregate=dict(type='list', elements='dict', aggregate=dict(type='list', elements='dict',
options=aggregate_spec), options=aggregate_spec),
purge=dict(default=False, type='bool'), purge=dict(default=False, type='bool'),
) )
else:
argument_spec = dict()
argument_spec.update(element_spec) argument_spec.update(element_spec)
required_one_of = [['name', 'aggregate']] required_one_of = [['name', 'aggregate']]
mutually_exclusive = [['name', 'aggregate']] mutually_exclusive = [['name', 'aggregate']]

View file

@ -47,23 +47,23 @@ options:
EXAMPLES = """ EXAMPLES = """
- name: configure Layer-2 interface - name: configure Layer-2 interface
mlnxos_l2_interface: mlnxos_l2_interface:
name: gigabitethernet0/0/1 name: Eth1/1
mode: access mode: access
access_vlan: 30 access_vlan: 30
- name: remove Layer-2 interface configuration - name: remove Layer-2 interface configuration
mlnxos_l2_interface: mlnxos_l2_interface:
name: gigabitethernet0/0/1 name: Eth1/1
state: absent state: absent
""" """
RETURN = """ RETURN = """
commands: commands:
description: The list of configuration mode commands to send to the device 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. returned: always.
type: list type: list
sample: sample:
- interface gigabitethernet0/0/1 - interface ethernet 1/1
- switchport mode access - switchport mode access
- switchport access vlan 30 - switchport access vlan 30
""" """
@ -74,8 +74,8 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import iteritems from ansible.module_utils.six import iteritems
from ansible.module_utils.network.common.utils import remove_default_spec from ansible.module_utils.network.common.utils import remove_default_spec
from ansible.module_utils.network.mlnxos.mlnxos import BaseMlnxosModule, \ from ansible.module_utils.network.mlnxos.mlnxos import BaseMlnxosModule
get_interfaces_config from ansible.module_utils.network.mlnxos.mlnxos import get_interfaces_config
class MlnxosL2InterfaceModule(BaseMlnxosModule): class MlnxosL2InterfaceModule(BaseMlnxosModule):
@ -96,7 +96,7 @@ class MlnxosL2InterfaceModule(BaseMlnxosModule):
@classmethod @classmethod
def _get_aggregate_spec(cls, element_spec): def _get_aggregate_spec(cls, element_spec):
aggregate_spec = deepcopy(element_spec) aggregate_spec = deepcopy(element_spec)
aggregate_spec['vlan_id'] = dict(required=True) aggregate_spec['name'] = dict(required=True)
# remove default in aggregate spec, to handle common arguments # remove default in aggregate spec, to handle common arguments
remove_default_spec(aggregate_spec) remove_default_spec(aggregate_spec)
@ -107,13 +107,10 @@ class MlnxosL2InterfaceModule(BaseMlnxosModule):
""" """
element_spec = self._get_element_spec() element_spec = self._get_element_spec()
aggregate_spec = self._get_aggregate_spec(element_spec) aggregate_spec = self._get_aggregate_spec(element_spec)
if aggregate_spec:
argument_spec = dict( argument_spec = dict(
aggregate=dict(type='list', elements='dict', aggregate=dict(type='list', elements='dict',
options=aggregate_spec), options=aggregate_spec),
) )
else:
argument_spec = dict()
argument_spec.update(element_spec) argument_spec.update(element_spec)
required_one_of = [['name', 'aggregate']] required_one_of = [['name', 'aggregate']]
mutually_exclusive = [['name', 'aggregate']] mutually_exclusive = [['name', 'aggregate']]

View file

@ -134,14 +134,11 @@ class MlnxosL3InterfaceModule(BaseMlnxosModule):
""" """
element_spec = self._get_element_spec() element_spec = self._get_element_spec()
aggregate_spec = self._get_aggregate_spec(element_spec) aggregate_spec = self._get_aggregate_spec(element_spec)
if aggregate_spec:
argument_spec = dict( argument_spec = dict(
aggregate=dict(type='list', elements='dict', aggregate=dict(type='list', elements='dict',
options=aggregate_spec), options=aggregate_spec),
purge=dict(default=False, type='bool'), purge=dict(default=False, type='bool'),
) )
else:
argument_spec = dict()
argument_spec.update(element_spec) argument_spec.update(element_spec)
required_one_of = [['name', 'aggregate']] required_one_of = [['name', 'aggregate']]
mutually_exclusive = [['name', 'aggregate']] mutually_exclusive = [['name', 'aggregate']]

View file

@ -42,7 +42,8 @@ options:
purge: purge:
description: description:
- Purge link aggregation groups not defined in the I(aggregate) parameter. - Purge link aggregation groups not defined in the I(aggregate) parameter.
default: no default: false
type: bool
state: state:
description: description:
- State of the link aggregation group. - State of the link aggregation group.
@ -142,14 +143,11 @@ class MlnxosLinkAggModule(BaseMlnxosModule):
""" """
element_spec = self._get_element_spec() element_spec = self._get_element_spec()
aggregate_spec = self._get_aggregate_spec(element_spec) aggregate_spec = self._get_aggregate_spec(element_spec)
if aggregate_spec:
argument_spec = dict( argument_spec = dict(
aggregate=dict(type='list', elements='dict', aggregate=dict(type='list', elements='dict',
options=aggregate_spec), options=aggregate_spec),
purge=dict(default=False, type='bool'), purge=dict(default=False, type='bool'),
) )
else:
argument_spec = dict()
argument_spec.update(element_spec) argument_spec.update(element_spec)
required_one_of = [['name', 'aggregate']] required_one_of = [['name', 'aggregate']]
mutually_exclusive = [['name', 'aggregate']] mutually_exclusive = [['name', 'aggregate']]

View file

@ -63,7 +63,7 @@ class MlnxosLldpModule(BaseMlnxosModule):
) )
def init_module(self): def init_module(self):
""" main entry point for module execution """ module initialization
""" """
element_spec = self._get_element_spec() element_spec = self._get_element_spec()
argument_spec = dict() argument_spec = dict()

View file

@ -119,14 +119,11 @@ class MlnxosLldpInterfaceModule(BaseMlnxosModule):
""" """
element_spec = self._get_element_spec() element_spec = self._get_element_spec()
aggregate_spec = self._get_aggregate_spec(element_spec) aggregate_spec = self._get_aggregate_spec(element_spec)
if aggregate_spec:
argument_spec = dict( argument_spec = dict(
aggregate=dict(type='list', elements='dict', aggregate=dict(type='list', elements='dict',
options=aggregate_spec), options=aggregate_spec),
purge=dict(default=False, type='bool'), purge=dict(default=False, type='bool'),
) )
else:
argument_spec = dict()
argument_spec.update(element_spec) argument_spec.update(element_spec)
required_one_of = [['name', 'aggregate']] required_one_of = [['name', 'aggregate']]
mutually_exclusive = [['name', 'aggregate']] mutually_exclusive = [['name', 'aggregate']]

View file

@ -15,12 +15,12 @@ DOCUMENTATION = """
module: mlnxos_magp module: mlnxos_magp
version_added: "2.5" version_added: "2.5"
author: "Samer Deeb (@samerd)" author: "Samer Deeb (@samerd)"
short_description: Manage MAGP protocol on MLNX-OS network devices short_description: Manage MAGP protocol on Mellanox MLNX-OS network devices
description: description:
- This module provides declarative management of MAGP protocol on vlan - This module provides declarative management of MAGP protocol on vlan
interface of MLNX-OS network devices. interface of Mellanox MLNX-OS network devices.
notes: notes:
- tested on Mellanox OS 3.6.4000 - Tested on MLNX-OS 3.6.4000
options: options:
magp_id: magp_id:
description: description:
@ -32,15 +32,15 @@ options:
required: true required: true
state: state:
description: description:
- vlan interface state - MAGP state.
default: present default: present
choices: ['present', 'absent', 'enabled', 'disabled'] choices: ['present', 'absent', 'enabled', 'disabled']
router_ip: router_ip:
description: description:
- MAGP router ip address - MAGP router IP address.
router_mac: router_mac:
description: description:
- MAGP router MAC address - MAGP router MAC address.
""" """
EXAMPLES = """ EXAMPLES = """
@ -188,7 +188,10 @@ class MlnxosMagpModule(BaseMlnxosModule):
self._commands.append(cmd) self._commands.append(cmd)
req_router_mac = self._required_config['router_mac'] req_router_mac = self._required_config['router_mac']
curr_router_mac = curr_magp_data.get('router_mac') curr_router_mac = curr_magp_data.get('router_mac')
if curr_router_mac:
curr_router_mac = curr_router_mac.lower()
if req_router_mac: if req_router_mac:
req_router_mac = req_router_mac.lower()
if curr_router_mac != req_router_mac or create_new_magp: if curr_router_mac != req_router_mac or create_new_magp:
cmd = '%s ip virtual-router mac-address %s' % ( cmd = '%s ip virtual-router mac-address %s' % (
magp_prefix, req_router_mac) magp_prefix, req_router_mac)

View file

@ -15,12 +15,12 @@ DOCUMENTATION = """
module: mlnxos_mlag_ipl module: mlnxos_mlag_ipl
version_added: "2.5" version_added: "2.5"
author: "Samer Deeb (@samerd)" author: "Samer Deeb (@samerd)"
short_description: Manage IPL (inter-peer link) on MLNX-OS network devices short_description: Manage IPL (inter-peer link) on Mellanox MLNX-OS network devices
description: description:
- This module provides declarative management of IPL (inter-peer link) - This module provides declarative management of IPL (inter-peer link)
management on MLNX-OS network devices. management on Mellanox MLNX-OS network devices.
notes: notes:
- tested on Mellanox OS 3.6.4000 - Tested on MLNX-OS 3.6.4000
options: options:
name: name:
description: description:
@ -31,12 +31,12 @@ options:
- Name of the IPL vlan interface. - Name of the IPL vlan interface.
state: state:
description: description:
- IPL state - IPL state.
default: present default: present
choices: ['present', 'absent'] choices: ['present', 'absent']
peer_address: peer_address:
description: description:
- IPL peer IP address - IPL peer IP address.
""" """
EXAMPLES = """ EXAMPLES = """
@ -84,7 +84,7 @@ class MlnxosMlagIplModule(BaseMlnxosModule):
) )
def init_module(self): def init_module(self):
""" main entry point for module execution """ module initialization
""" """
element_spec = self._get_element_spec() element_spec = self._get_element_spec()
argument_spec = dict() argument_spec = dict()

View file

@ -96,14 +96,11 @@ class MlnxosVlanModule(BaseMlnxosModule):
""" """
element_spec = self._get_element_spec() element_spec = self._get_element_spec()
aggregate_spec = self._get_aggregate_spec(element_spec) aggregate_spec = self._get_aggregate_spec(element_spec)
if aggregate_spec:
argument_spec = dict( argument_spec = dict(
aggregate=dict(type='list', elements='dict', aggregate=dict(type='list', elements='dict',
options=aggregate_spec), options=aggregate_spec),
purge=dict(default=False, type='bool'), purge=dict(default=False, type='bool'),
) )
else:
argument_spec = dict()
argument_spec.update(element_spec) argument_spec.update(element_spec)
required_one_of = [['vlan_id', 'aggregate']] required_one_of = [['vlan_id', 'aggregate']]
mutually_exclusive = [['vlan_id', 'aggregate']] mutually_exclusive = [['vlan_id', 'aggregate']]

View file

@ -20,11 +20,8 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import json
from ansible.compat.tests.mock import patch from ansible.compat.tests.mock import patch
from ansible.modules.network.mlnxos import mlnxos_l2_interface from ansible.modules.network.mlnxos import mlnxos_l2_interface
from ansible.module_utils.network.mlnxos import mlnxos as mlnxos_utils
from units.modules.utils import set_module_args from units.modules.utils import set_module_args
from .mlnxos_module import TestMlnxosModule, load_fixture from .mlnxos_module import TestMlnxosModule, load_fixture
@ -103,3 +100,15 @@ class TestMlnxosInterfaceModule(TestMlnxosModule):
'switchport access vlan 10', 'switchport access vlan 10',
'switchport hybrid allowed-vlan add 11', 'exit'] 'switchport hybrid allowed-vlan add 11', 'exit']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_aggregate(self):
aggregate = list()
aggregate.append(dict(name='Eth1/10'))
aggregate.append(dict(name='Eth1/12'))
set_module_args(dict(aggregate=aggregate, access_vlan=10))
commands = ['interface ethernet 1/10', 'switchport mode access',
'switchport access vlan 10', 'exit',
'interface ethernet 1/12', 'switchport mode access',
'switchport access vlan 10', 'exit']
self.execute_module(changed=True, commands=commands, sort=False)