diff --git a/lib/ansible/module_utils/network/mlnxos/mlnxos.py b/lib/ansible/module_utils/network/mlnxos/mlnxos.py
index 7c461e63861..b389d35fbf8 100644
--- a/lib/ansible/module_utils/network/mlnxos/mlnxos.py
+++ b/lib/ansible/module_utils/network/mlnxos/mlnxos.py
@@ -17,9 +17,9 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see .
#
+import json
from ansible.module_utils._text import to_text
-from ansible.module_utils.basic import env_fallback
from ansible.module_utils.connection import Connection, ConnectionError
from ansible.module_utils.network.common.utils import to_list, EntityCollection
@@ -77,3 +77,153 @@ def load_config(module, config):
conn.edit_config(config)
except ConnectionError as exc:
module.fail_json(msg=to_text(exc))
+
+
+def _parse_json_output(out):
+ out_list = out.split('\n')
+ first_index = 0
+ opening_char = None
+ lines_count = len(out_list)
+ while first_index < lines_count:
+ first_line = out_list[first_index].strip()
+ if not first_line or first_line[0] not in ("[", "{"):
+ first_index += 1
+ continue
+ opening_char = first_line[0]
+ break
+ if not opening_char:
+ return "null"
+ closing_char = ']' if opening_char == '[' else '}'
+ last_index = lines_count - 1
+ found = False
+ while last_index > first_index:
+ last_line = out_list[last_index].strip()
+ if not last_line or last_line[0] != closing_char:
+ last_index -= 1
+ continue
+ found = True
+ break
+ if not found:
+ return opening_char + closing_char
+ return "".join(out_list[first_index:last_index + 1])
+
+
+def show_cmd(module, cmd, json_fmt=True, fail_on_error=True):
+ if json_fmt:
+ cmd += " | json-print"
+ conn = get_connection(module)
+ command_obj = to_commands(module, to_list(cmd))[0]
+ try:
+ out = conn.get(**command_obj)
+ except ConnectionError:
+ if fail_on_error:
+ raise
+ return None
+
+ if json_fmt:
+ out = _parse_json_output(out)
+ try:
+ cfg = json.loads(out)
+ except ValueError:
+ module.fail_json(
+ msg="got invalid json",
+ stderr=to_text(out, errors='surrogate_then_replace'))
+ else:
+ cfg = to_text(out, errors='surrogate_then_replace').strip()
+ return cfg
+
+
+def get_interfaces_config(module, interface_type, flags=None, json_fmt=True):
+ cmd = "show interfaces %s" % interface_type
+ if flags:
+ cmd += " %s" % flags
+ return show_cmd(module, cmd, json_fmt)
+
+
+def get_bgp_summary(module):
+ cmd = "show ip bgp summary"
+ return show_cmd(module, cmd, json_fmt=False, fail_on_error=False)
+
+
+class BaseMlnxosModule(object):
+
+ def __init__(self):
+ self._module = None
+ self._commands = list()
+ self._current_config = None
+ self._required_config = None
+
+ def init_module(self):
+ pass
+
+ def load_current_config(self):
+ pass
+
+ def get_required_config(self):
+ pass
+
+ # pylint: disable=unused-argument
+ def check_declarative_intent_params(self, result):
+ return None
+
+ def validate_param_values(self, obj, param=None):
+ if param is None:
+ param = self._module.params
+ for key in obj:
+ # validate the param value (if validator func exists)
+ try:
+ validator = getattr(self, 'validate_%s' % key)
+ if callable(validator):
+ validator(param.get(key))
+ except AttributeError:
+ pass
+
+ @classmethod
+ def get_config_attr(cls, item, arg):
+ return item.get(arg)
+
+ @classmethod
+ def get_mtu(cls, item):
+ mtu = cls.get_config_attr(item, "MTU")
+ mtu_parts = mtu.split()
+ try:
+ return int(mtu_parts[0])
+ except ValueError:
+ return None
+
+ def validate_mtu(self, value):
+ if value and not 1500 <= int(value) <= 9612:
+ self._module.fail_json(msg='mtu must be between 1500 and 9612')
+
+ def generate_commands(self):
+ pass
+
+ def run(self):
+ self.init_module()
+
+ result = {'changed': False}
+
+ self.get_required_config()
+ self.load_current_config()
+
+ self.generate_commands()
+ result['commands'] = self._commands
+
+ if self._commands:
+ if not self._module.check_mode:
+ load_config(self._module, self._commands)
+ result['changed'] = True
+
+ failed_conditions = self.check_declarative_intent_params(result)
+
+ if failed_conditions:
+ msg = 'One or more conditional statements have not been satisfied'
+ self._module.fail_json(msg=msg,
+ failed_conditions=failed_conditions)
+
+ self._module.exit_json(**result)
+
+ @classmethod
+ def main(cls):
+ app = cls()
+ app.run()
diff --git a/lib/ansible/modules/network/mlnxos/mlnxos_interface.py b/lib/ansible/modules/network/mlnxos/mlnxos_interface.py
new file mode 100644
index 00000000000..3d84a7b0664
--- /dev/null
+++ b/lib/ansible/modules/network/mlnxos/mlnxos_interface.py
@@ -0,0 +1,404 @@
+#!/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 .
+#
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'network'}
+
+DOCUMENTATION = """
+---
+module: mlnxos_interface
+version_added: "2.5"
+author: "Samer Deeb (@samerd)"
+short_description: Manage Interfaces on Mellanox MLNX-OS network devices
+description:
+ - This module provides declarative management of Interfaces
+ on Mellanox MLNX-OS network devices.
+notes:
+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.
+ choices: ['1G', '10G', '25G', '40G', '50G', '56G', '100G']
+ mtu:
+ description:
+ - Maximum size of transmit packet.
+ aggregate:
+ description: List of Interfaces definitions.
+ duplex:
+ description:
+ - Interface link status
+ default: auto
+ choices: ['full', 'half', 'auto']
+ tx_rate:
+ description:
+ - Transmit rate in bits per second (bps).
+ rx_rate:
+ description:
+ - Receiver rate in bits per second (bps).
+ 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).
+ default: 10
+ purge:
+ description:
+ - Purge Interfaces not defined in the aggregate parameter.
+ This applies only for logical interface.
+ default: no
+ 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']
+"""
+
+EXAMPLES = """
+- name: configure interface
+ mlnxos_interface:
+ name: Eth1/2
+ description: test-interface
+ speed: 100 GB
+ mtu: 512
+
+- name: make interface up
+ mlnxos_interface:
+ name: Eth1/2
+ enabled: True
+
+- name: make interface down
+ mlnxos_interface:
+ name: Eth1/2
+ enabled: False
+
+- name: Check intent arguments
+ mlnxos_interface:
+ name: Eth1/2
+ state: up
+
+- name: Config + intent
+ mlnxos_interface:
+ name: Eth1/2
+ enabled: False
+ state: down
+"""
+
+RETURN = """
+commands:
+ description: The list of configuration mode commands to send to the device.
+ returned: always
+ type: list
+ sample:
+ - interface Eth1/2
+ - description test-interface
+ - mtu 512
+"""
+
+from copy import deepcopy
+import re
+from time import sleep
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.network.common.utils import conditional, \
+ remove_default_spec
+
+from ansible.module_utils.network.mlnxos.mlnxos import BaseMlnxosModule, \
+ get_interfaces_config
+
+
+class MlnxosInterfaceModule(BaseMlnxosModule):
+ ETH_IF_NAME_REGEX = re.compile(r'^Eth(\d\/\d+(|\/\d))$')
+
+ @classmethod
+ def _get_element_spec(cls):
+ return dict(
+ name=dict(type='str'),
+ description=dict(),
+ speed=dict(choices=['1G', '10G', '25G', '40G', '50G', '56G', '100G']),
+ mtu=dict(type='int'),
+ enabled=dict(default=True, type='bool'),
+ delay=dict(default=10, type='int'),
+ state=dict(default='present',
+ choices=['present', 'absent', 'up', 'down']),
+ tx_rate=dict(),
+ rx_rate=dict(),
+ )
+
+ @classmethod
+ def _get_aggregate_spec(cls, element_spec):
+ 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)
+ return aggregate_spec
+
+ def init_module(self):
+ """ main entry point for module execution
+ """
+ element_spec = self._get_element_spec()
+ aggregate_spec = self._get_aggregate_spec(element_spec)
+ if aggregate_spec:
+ argument_spec = dict(
+ aggregate=dict(type='list', elements='dict',
+ options=aggregate_spec),
+ purge=dict(default=False, type='bool'),
+ )
+ else:
+ argument_spec = dict()
+ argument_spec.update(element_spec)
+ required_one_of = [['name', 'aggregate']]
+ mutually_exclusive = [['name', 'aggregate']]
+ self._module = AnsibleModule(
+ argument_spec=argument_spec,
+ required_one_of=required_one_of,
+ mutually_exclusive=mutually_exclusive,
+ supports_check_mode=True)
+
+ def validate_name(self, value):
+ if not self.ETH_IF_NAME_REGEX.match(value):
+ self._module.fail_json(msg='Invalid interface name!')
+
+ def validate_purge(self, value):
+ if value:
+ self._module.fail_json(
+ msg='Purge is not supported for ethernet interfaces!')
+
+ def validate_duplex(self, value):
+ if value != 'auto':
+ self._module.fail_json(
+ msg='Duplex is not supported for ethernet interfaces')
+
+ def validate_state(self, value):
+ if value == 'absent':
+ self._module.fail_json(
+ msg='Cannot remove physical interfaces')
+
+ def get_required_config(self):
+ self._required_config = list()
+ module_params = self._module.params
+ 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]
+
+ self.validate_param_values(item, item)
+ req_item = item.copy()
+ self._required_config.append(req_item)
+
+ else:
+ params = {
+ 'name': module_params['name'],
+ 'description': module_params['description'],
+ 'speed': module_params['speed'],
+ 'mtu': module_params['mtu'],
+ 'state': module_params['state'],
+ 'delay': module_params['delay'],
+ 'enabled': module_params['enabled'],
+ 'tx_rate': module_params['tx_rate'],
+ 'rx_rate': module_params['rx_rate'],
+ }
+
+ self.validate_param_values(params)
+ self._required_config.append(params)
+
+ @classmethod
+ def get_if_name(cls, item):
+ return cls.get_config_attr(item, "header")
+
+ @classmethod
+ def get_if_cmd(cls, if_name):
+ return if_name.replace("Eth", "interface ethernet ")
+
+ @classmethod
+ def get_admin_state(cls, item):
+ admin_state = cls.get_config_attr(item, "Admin state")
+ return str(admin_state).lower() == "enabled"
+
+ @classmethod
+ def get_oper_state(cls, item):
+ oper_state = cls.get_config_attr(item, "Operational state")
+ return str(oper_state).lower()
+
+ def add_command_to_interface(self, interface, cmd):
+ if interface not in self._commands:
+ self._commands.append(interface)
+ self._commands.append(cmd)
+
+ def get_speed(self, item):
+ speed = self.get_config_attr(item, 'Actual speed')
+ try:
+ speed = int(speed.split()[0])
+ return "%dG" % speed
+ except ValueError:
+ return None
+
+ def _create_if_data(self, name, item):
+ return {
+ 'name': name,
+ 'description': self.get_config_attr(item, 'Description'),
+ 'speed': self.get_speed(item),
+ 'mtu': self.get_mtu(item),
+ 'enabled': self.get_admin_state(item),
+ 'state': self.get_oper_state(item)
+ }
+
+ def _get_interfaces_config(self):
+ return get_interfaces_config(self._module, "ethernet")
+
+ def load_current_config(self):
+ self._current_config = dict()
+ config = self._get_interfaces_config()
+
+ for item in config:
+ name = self.get_if_name(item)
+ self._current_config[name] = self._create_if_data(name, item)
+
+ def generate_commands(self):
+ for req_if in self._required_config:
+ name = req_if['name']
+ curr_if = self._current_config.get(name)
+ if not curr_if:
+ self._module.fail_json(
+ msg='could not find interface %s' % name)
+ continue
+ self._generate_if_commands(name, req_if, curr_if)
+
+ def _generate_if_commands(self, name, req_if, curr_if):
+ args = ('speed', 'description', 'mtu')
+ enabled = req_if['enabled']
+ add_exit = False
+ interface_prefix = self.get_if_cmd(name)
+
+ for attr_name in args:
+ candidate = req_if.get(attr_name)
+ running = curr_if.get(attr_name)
+ if candidate != running:
+ if candidate:
+ cmd = attr_name + ' ' + str(candidate)
+ if attr_name in ('mtu', 'speed'):
+ cmd = cmd + ' ' + 'force'
+ self.add_command_to_interface(interface_prefix, cmd)
+ add_exit = True
+ curr_enabled = curr_if.get('enabled', False)
+ if enabled != curr_enabled:
+ cmd = 'shutdown'
+ if enabled:
+ cmd = "no %s" % cmd
+ self.add_command_to_interface(interface_prefix, cmd)
+ add_exit = True
+ if add_exit:
+ self._commands.append('exit')
+
+ def _get_interfaces_rates(self):
+ return get_interfaces_config(self._module, "ethernet", "rates")
+
+ def _get_interfaces_status(self):
+ return get_interfaces_config(self._module, "ethernet", "status")
+
+ def check_declarative_intent_params(self, result):
+ failed_conditions = []
+ delay_called = False
+ rates = None
+ statuses = None
+ for req_if in self._required_config:
+ want_state = req_if.get('state')
+ want_tx_rate = req_if.get('tx_rate')
+ want_rx_rate = req_if.get('rx_rate')
+ name = req_if['name']
+ if want_state not in ('up', 'down') and not want_tx_rate and not \
+ want_rx_rate:
+ continue
+ if not delay_called and result['changed']:
+ delay_called = True
+ delay = req_if['delay']
+ if delay > 0:
+ sleep(delay)
+ if want_state in ('up', 'down'):
+ if not statuses:
+ statuses = self._get_interfaces_status()
+ curr_if = statuses.get(name)
+ curr_state = None
+ if curr_if:
+ curr_if = curr_if[0]
+ curr_state = self.get_oper_state(curr_if)
+ if curr_state is None or not \
+ conditional(want_state, curr_state.strip()):
+ failed_conditions.append(
+ 'state ' + 'eq(%s)' % want_state)
+ if_rates = None
+ if want_tx_rate or want_rx_rate:
+ if not rates:
+ rates = self._get_interfaces_rates()
+ if_rates = rates.get(name)
+ if if_rates:
+ if_rates = if_rates[0]
+ if want_tx_rate:
+ have_tx_rate = None
+ if if_rates:
+ have_tx_rate = if_rates.get('egress rate')
+ if have_tx_rate:
+ have_tx_rate = have_tx_rate.split()[0]
+ 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:
+ have_rx_rate = None
+ if if_rates:
+ have_rx_rate = if_rates.get('ingress rate')
+ if have_rx_rate:
+ have_rx_rate = have_rx_rate.split()[0]
+ 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)
+
+ return failed_conditions
+
+
+def main():
+ """ main entry point for module execution
+ """
+ MlnxosInterfaceModule.main()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/units/modules/network/mlnxos/fixtures/mlnxos_interfaces_rates.cfg b/test/units/modules/network/mlnxos/fixtures/mlnxos_interfaces_rates.cfg
new file mode 100644
index 00000000000..11131cc5e5e
--- /dev/null
+++ b/test/units/modules/network/mlnxos/fixtures/mlnxos_interfaces_rates.cfg
@@ -0,0 +1,10 @@
+{
+ "Eth1/1": [
+ {
+ "ingress rate": "9000 b/s",
+ "egress pkts/sec": "10",
+ "egress rate": "10000 b/s",
+ "ingress pkts/sec": "10"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test/units/modules/network/mlnxos/fixtures/mlnxos_interfaces_show.cfg b/test/units/modules/network/mlnxos/fixtures/mlnxos_interfaces_show.cfg
new file mode 100644
index 00000000000..1ba7bf93d3e
--- /dev/null
+++ b/test/units/modules/network/mlnxos/fixtures/mlnxos_interfaces_show.cfg
@@ -0,0 +1,44 @@
+[
+ {
+ "Fec": "auto",
+ "Mac address": "7c:fe:90:f0:54:fc",
+ "60 seconds ingress rate": "0 bits/sec, 0 bytes/sec, 0 packets/sec",
+ "Last clearing of \"show interface\" counters": "Never",
+ "Actual speed": "40 Gbps",
+ "MTU": "1500 bytes(Maximum packet size 1522 bytes)",
+ "header": "Eth1/1",
+ "Telemetry threshold": "Disabled\t TCs: N\\A",
+ "Telemetry threshold level": "N\\A",
+ "Flow-control": "receive off send off",
+ "Forwarding mode": "inherited cut-through",
+ "60 seconds egress rate": "0 bits/sec, 0 bytes/sec, 0 packets/sec",
+ "Last change in operational status": "Never",
+ "Boot delay time": "0 sec",
+ "Description": "N\\A",
+ "Admin state": "Enabled",
+ "Telemetry sampling": "Disabled\t TCs: N\\A",
+ "Operational state": "Down",
+ "Width reduction mode": "Not supported",
+ "Tx": {
+ "error packets": "0",
+ "packets": "0",
+ "bytes": "0",
+ "multicast packets": "0",
+ "unicast packets": "0",
+ "discard packets": "0",
+ "hoq discard packets": "0",
+ "broadcast packets": "0"
+ },
+ "MAC learning mode": "Enabled",
+ "Switchport mode": "access",
+ "Rx": {
+ "error packets": "0",
+ "packets": "0",
+ "bytes": "0",
+ "multicast packets": "0",
+ "unicast packets": "0",
+ "discard packets": "0",
+ "broadcast packets": "0"
+ }
+ }
+]
diff --git a/test/units/modules/network/mlnxos/fixtures/mlnxos_interfaces_status.cfg b/test/units/modules/network/mlnxos/fixtures/mlnxos_interfaces_status.cfg
new file mode 100644
index 00000000000..4946f940e78
--- /dev/null
+++ b/test/units/modules/network/mlnxos/fixtures/mlnxos_interfaces_status.cfg
@@ -0,0 +1,9 @@
+{
+ "Eth1/1": [
+ {
+ "Negotiation": "No-Negotiation",
+ "Operational state": "Down",
+ "Speed": "100 Gbps"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test/units/modules/network/mlnxos/test_mlnxos_interface.py b/test/units/modules/network/mlnxos/test_mlnxos_interface.py
new file mode 100644
index 00000000000..a3bd7dc7695
--- /dev/null
+++ b/test/units/modules/network/mlnxos/test_mlnxos_interface.py
@@ -0,0 +1,114 @@
+#
+# (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 json
+
+from ansible.compat.tests.mock import patch
+from ansible.modules.network.mlnxos import mlnxos_interface
+from ansible.module_utils.network.mlnxos import mlnxos as mlnxos_utils
+from units.modules.utils import set_module_args
+from .mlnxos_module import TestMlnxosModule, load_fixture
+
+
+class TestMlnxosInterfaceModule(TestMlnxosModule):
+
+ module = mlnxos_interface
+
+ def setUp(self):
+ super(TestMlnxosInterfaceModule, self).setUp()
+ self.mock_get_config = patch.object(
+ mlnxos_interface.MlnxosInterfaceModule, "_get_interfaces_config")
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_get_interfaces_status = patch.object(
+ mlnxos_interface.MlnxosInterfaceModule, "_get_interfaces_status")
+ self.get_interfaces_status = self.mock_get_interfaces_status.start()
+
+ self.mock_get_interfaces_rates = patch.object(
+ mlnxos_interface.MlnxosInterfaceModule, "_get_interfaces_rates")
+ self.get_interfaces_rates = self.mock_get_interfaces_rates.start()
+
+ self.mock_load_config = patch(
+ 'ansible.module_utils.network.mlnxos.mlnxos.load_config')
+ self.load_config = self.mock_load_config.start()
+
+ def tearDown(self):
+ super(TestMlnxosInterfaceModule, self).tearDown()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+
+ def load_fixtures(self, commands=None, transport='cli'):
+ config_file = 'mlnxos_interfaces_show.cfg'
+ self.get_config.return_value = load_fixture(config_file)
+ self.load_config.return_value = None
+
+ def test_mtu_no_change(self):
+ set_module_args(dict(name='Eth1/1', mtu=1500))
+ self.execute_module(changed=False)
+
+ def test_mtu_change(self):
+ set_module_args(dict(name='Eth1/1', mtu=1522))
+ commands = ['interface ethernet 1/1', 'mtu 1522 force', 'exit']
+ self.execute_module(changed=True, commands=commands)
+
+ def test_speed_no_change(self):
+ set_module_args(dict(name='Eth1/1', speed='40G'))
+ self.execute_module(changed=False)
+
+ def test_speed_change(self):
+ set_module_args(dict(name='Eth1/1', speed='100G'))
+ commands = ['interface ethernet 1/1', 'speed 100G force', 'exit']
+ self.execute_module(changed=True, commands=commands)
+
+ def test_mtu_speed_change(self):
+ set_module_args(dict(name='Eth1/1', speed='100G', mtu=1522))
+ commands = ['interface ethernet 1/1', 'speed 100G force',
+ 'mtu 1522 force', 'exit']
+ self.execute_module(changed=True, commands=commands)
+
+ def test_admin_state_no_change(self):
+ set_module_args(dict(name='Eth1/1', enabled=True))
+ self.execute_module(changed=False)
+
+ def test_admin_state_change(self):
+ set_module_args(dict(name='Eth1/1', enabled=False))
+ commands = ['interface ethernet 1/1', 'shutdown', 'exit']
+ self.execute_module(changed=True, commands=commands)
+
+ def test_oper_state_check(self):
+ set_module_args(dict(name='Eth1/1', enabled=True, state='down'))
+ config_file = 'mlnxos_interfaces_status.cfg'
+ self.get_interfaces_status.return_value = load_fixture(config_file)
+ commands = ['interface ethernet 1/1', 'shutdown', 'exit']
+ self.execute_module(changed=False)
+
+ def test_rx_rate_check(self):
+ set_module_args(dict(name='Eth1/1', enabled=True, rx_rate='ge(9000)'))
+ config_file = 'mlnxos_interfaces_rates.cfg'
+ self.get_interfaces_rates.return_value = load_fixture(config_file)
+ self.execute_module(changed=False)
+
+ def test_tx_rate_check(self):
+ set_module_args(dict(name='Eth1/1', enabled=True, tx_rate='ge(10000)'))
+ config_file = 'mlnxos_interfaces_rates.cfg'
+ self.get_interfaces_rates.return_value = load_fixture(config_file)
+ self.execute_module(changed=False)