diff --git a/lib/ansible/modules/network/f5/bigip_traffic_group.py b/lib/ansible/modules/network/f5/bigip_traffic_group.py index 89e9e6c7f00..9b4a4066c76 100644 --- a/lib/ansible/modules/network/f5/bigip_traffic_group.py +++ b/lib/ansible/modules/network/f5/bigip_traffic_group.py @@ -18,7 +18,7 @@ module: bigip_traffic_group short_description: Manages traffic groups on BIG-IP description: - Supports managing traffic groups and their attributes on a BIG-IP. -version_added: "2.5" +version_added: 2.5 options: name: description: @@ -28,7 +28,6 @@ options: description: - Device partition to manage resources on. default: Common - version_added: 2.5 state: description: - When C(present), ensures that the traffic group exists. @@ -37,7 +36,18 @@ options: choices: - present - absent - version_added: 2.5 + mac_address: + description: + - Specifies the floating Media Access Control (MAC) address associated with the floating IP addresses + defined for a traffic group. + - Primarily, a MAC masquerade address minimizes ARP communications or dropped packets as a result of failover. + - A MAC masquerade address ensures that any traffic destined for a specific traffic group reaches an available + device after failover, which happens because along with the traffic group, the MAC masquerade address floats + to the available device. + - Without a MAC masquerade address, the sending host must learn the MAC address for a newly-active device, + either by sending an ARP request or by relying on the gratuitous ARP from the newly-active device. + - To unset the MAC address, specify an empty value (C("")) to this parameter. + version_added: 2.6 extends_documentation_fragment: f5 author: - Tim Rupp (@caphrim007) @@ -61,31 +71,26 @@ RETURN = r''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import env_fallback -HAS_DEVEL_IMPORTS = False - try: - # Sideband repository used for dev from library.module_utils.network.f5.bigip import HAS_F5SDK from library.module_utils.network.f5.bigip import F5Client from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import AnsibleF5Parameters from library.module_utils.network.f5.common import cleanup_tokens - from library.module_utils.network.f5.common import fqdn_name from library.module_utils.network.f5.common import f5_argument_spec + try: from library.module_utils.network.f5.common import iControlUnexpectedHTTPError except ImportError: HAS_F5SDK = False - HAS_DEVEL_IMPORTS = True except ImportError: - # Upstream Ansible from ansible.module_utils.network.f5.bigip import HAS_F5SDK from ansible.module_utils.network.f5.bigip import F5Client from ansible.module_utils.network.f5.common import F5ModuleError from ansible.module_utils.network.f5.common import AnsibleF5Parameters from ansible.module_utils.network.f5.common import cleanup_tokens - from ansible.module_utils.network.f5.common import fqdn_name from ansible.module_utils.network.f5.common import f5_argument_spec + try: from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError except ImportError: @@ -94,19 +99,19 @@ except ImportError: class Parameters(AnsibleF5Parameters): api_map = { - + 'mac': 'mac_address' } api_attributes = [ - + 'mac' ] returnables = [ - + 'mac_address' ] updatables = [ - + 'mac_address' ] def to_return(self): @@ -120,6 +125,20 @@ class Parameters(AnsibleF5Parameters): return result +class ApiParameters(Parameters): + pass + + +class ModuleParameters(Parameters): + @property + def mac_address(self): + if self._values['mac_address'] is None: + return None + if self._values['mac_address'] == '': + return 'none' + return self._values['mac_address'] + + class Changes(Parameters): pass @@ -156,7 +175,7 @@ class ModuleManager(object): def __init__(self, *args, **kwargs): self.module = kwargs.get('module', None) self.client = kwargs.get('client', None) - self.want = Parameters(params=self.module.params) + self.want = ModuleParameters(params=self.module.params) self.changes = Changes() def _set_changed_options(self): @@ -294,7 +313,7 @@ class ModuleManager(object): partition=self.want.partition ) result = resource.attrs - return Parameters(params=result) + return ApiParameters(params=result) class ArgumentSpec(object): @@ -306,7 +325,8 @@ class ArgumentSpec(object): partition=dict( default='Common', fallback=(env_fallback, ['F5_PARTITION']) - ) + ), + mac_address=dict() ) self.argument_spec = {} self.argument_spec.update(f5_argument_spec) diff --git a/lib/ansible/modules/network/f5/bigip_ucs.py b/lib/ansible/modules/network/f5/bigip_ucs.py index b1a9268ad3a..b6f936aeefe 100644 --- a/lib/ansible/modules/network/f5/bigip_ucs.py +++ b/lib/ansible/modules/network/f5/bigip_ucs.py @@ -18,16 +18,14 @@ module: bigip_ucs short_description: Manage upload, installation and removal of UCS files description: - Manage upload, installation and removal of UCS files. -version_added: "2.4" +version_added: 2.4 options: include_chassis_level_config: description: - During restore of the UCS file, include chassis level configuration that is shared among boot volume sets. For example, cluster default configuration. - choices: - - yes - - no + type: bool ucs: description: - The path to the UCS file to install. The parameter must be @@ -42,38 +40,29 @@ options: device. If C(no), the file will only be uploaded if it does not already exist. Generally should be C(yes) only in cases where you have reason to believe that the image was corrupted during upload. - choices: - - yes - - no + type: bool + default: no no_license: description: - Performs a full restore of the UCS file and all the files it contains, with the exception of the license file. The option must be used to restore a UCS on RMA devices (Returned Materials Authorization). - choices: - - yes - - no + type: bool no_platform_check: description: - Bypasses the platform check and allows a UCS that was created using a different platform to be installed. By default (without this option), a UCS created from a different platform is not allowed to be installed. - choices: - - yes - - no + type: bool passphrase: description: - Specifies the passphrase that is necessary to load the specified UCS file. - choices: - - yes - - no + type: bool reset_trust: description: - When specified, the device and trust domain certs and keys are not loaded from the UCS. Instead, a new set is regenerated. - choices: - - yes - - no + type: bool state: description: - When C(installed), ensures that the UCS is uploaded and installed, @@ -184,30 +173,23 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six import iteritems from distutils.version import LooseVersion -HAS_DEVEL_IMPORTS = False - try: - # Sideband repository used for dev from library.module_utils.network.f5.bigip import HAS_F5SDK from library.module_utils.network.f5.bigip import F5Client from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import AnsibleF5Parameters from library.module_utils.network.f5.common import cleanup_tokens - from library.module_utils.network.f5.common import fqdn_name from library.module_utils.network.f5.common import f5_argument_spec try: from library.module_utils.network.f5.common import iControlUnexpectedHTTPError except ImportError: HAS_F5SDK = False - HAS_DEVEL_IMPORTS = True except ImportError: - # Upstream Ansible from ansible.module_utils.network.f5.bigip import HAS_F5SDK from ansible.module_utils.network.f5.bigip import F5Client from ansible.module_utils.network.f5.common import F5ModuleError from ansible.module_utils.network.f5.common import AnsibleF5Parameters from ansible.module_utils.network.f5.common import cleanup_tokens - from ansible.module_utils.network.f5.common import fqdn_name from ansible.module_utils.network.f5.common import f5_argument_spec try: from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError diff --git a/lib/ansible/modules/network/f5/bigip_ucs_fetch.py b/lib/ansible/modules/network/f5/bigip_ucs_fetch.py index ddfc6cb1d85..ae91a089c56 100644 --- a/lib/ansible/modules/network/f5/bigip_ucs_fetch.py +++ b/lib/ansible/modules/network/f5/bigip_ucs_fetch.py @@ -145,30 +145,23 @@ import tempfile from ansible.module_utils.basic import AnsibleModule from distutils.version import LooseVersion -HAS_DEVEL_IMPORTS = False - try: - # Sideband repository used for dev from library.module_utils.network.f5.bigip import HAS_F5SDK from library.module_utils.network.f5.bigip import F5Client from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import AnsibleF5Parameters from library.module_utils.network.f5.common import cleanup_tokens - from library.module_utils.network.f5.common import fqdn_name from library.module_utils.network.f5.common import f5_argument_spec try: from library.module_utils.network.f5.common import iControlUnexpectedHTTPError except ImportError: HAS_F5SDK = False - HAS_DEVEL_IMPORTS = True except ImportError: - # Upstream Ansible from ansible.module_utils.network.f5.bigip import HAS_F5SDK from ansible.module_utils.network.f5.bigip import F5Client from ansible.module_utils.network.f5.common import F5ModuleError from ansible.module_utils.network.f5.common import AnsibleF5Parameters from ansible.module_utils.network.f5.common import cleanup_tokens - from ansible.module_utils.network.f5.common import fqdn_name from ansible.module_utils.network.f5.common import f5_argument_spec try: from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError diff --git a/test/sanity/validate-modules/ignore.txt b/test/sanity/validate-modules/ignore.txt index b146f25ab8e..5cb61b7e6d2 100644 --- a/test/sanity/validate-modules/ignore.txt +++ b/test/sanity/validate-modules/ignore.txt @@ -1166,8 +1166,6 @@ lib/ansible/modules/network/f5/bigip_routedomain.py E326 lib/ansible/modules/network/f5/bigip_selfip.py E324 lib/ansible/modules/network/f5/bigip_static_route.py E325 lib/ansible/modules/network/f5/bigip_sys_global.py E326 -lib/ansible/modules/network/f5/bigip_ucs.py E325 -lib/ansible/modules/network/f5/bigip_ucs.py E326 lib/ansible/modules/network/f5/bigip_virtual_server.py E326 lib/ansible/modules/network/f5/bigiq_regkey_license.py E325 lib/ansible/modules/network/fortimanager/fmgr_script.py E324 diff --git a/test/units/modules/network/f5/fixtures/load_net_timer_policy_1.json b/test/units/modules/network/f5/fixtures/load_net_timer_policy_1.json new file mode 100644 index 00000000000..4b6f550a588 --- /dev/null +++ b/test/units/modules/network/f5/fixtures/load_net_timer_policy_1.json @@ -0,0 +1,9 @@ +{ + "kind": "tm:net:timer-policy:timer-policystate", + "name": "timer1", + "partition": "Common", + "fullPath": "/Common/timer1", + "generation": 148, + "selfLink": "https://localhost/mgmt/tm/net/timer-policy/~Common~timer1?ver=13.1.0.4", + "description": "my description" +} diff --git a/test/units/modules/network/f5/fixtures/load_tm_cm_traffic_group_1.json b/test/units/modules/network/f5/fixtures/load_tm_cm_traffic_group_1.json new file mode 100644 index 00000000000..dbbb1907250 --- /dev/null +++ b/test/units/modules/network/f5/fixtures/load_tm_cm_traffic_group_1.json @@ -0,0 +1,16 @@ +{ + "kind": "tm:cm:traffic-group:traffic-groupstate", + "name": "traffic-group-1", + "partition": "Common", + "fullPath": "/Common/traffic-group-1", + "generation": 1, + "selfLink": "https://localhost/mgmt/tm/cm/traffic-group/~Common~traffic-group-1?ver=13.0.0", + "autoFailbackEnabled": "false", + "autoFailbackTime": 60, + "failoverMethod": "ha-order", + "haLoadFactor": 1, + "isFloating": "true", + "mac": "none", + "monitor": {}, + "unitId": 1 +} diff --git a/test/units/modules/network/f5/fixtures/load_tm_cm_traffic_group_2.json b/test/units/modules/network/f5/fixtures/load_tm_cm_traffic_group_2.json new file mode 100644 index 00000000000..3b93cdae9ae --- /dev/null +++ b/test/units/modules/network/f5/fixtures/load_tm_cm_traffic_group_2.json @@ -0,0 +1,16 @@ +{ + "kind": "tm:cm:traffic-group:traffic-groupstate", + "name": "asd", + "partition": "Common", + "fullPath": "/Common/asd", + "generation": 176, + "selfLink": "https://localhost/mgmt/tm/cm/traffic-group/~Common~asd?ver=13.0.0", + "autoFailbackEnabled": "false", + "autoFailbackTime": 60, + "failoverMethod": "ha-order", + "haLoadFactor": 1, + "isFloating": "true", + "mac": "00:00:00:00:00:02", + "monitor": {}, + "unitId": 2 +} diff --git a/test/units/modules/network/f5/fixtures/load_tm_net_trunk_1.json b/test/units/modules/network/f5/fixtures/load_tm_net_trunk_1.json new file mode 100644 index 00000000000..af312d49f93 --- /dev/null +++ b/test/units/modules/network/f5/fixtures/load_tm_net_trunk_1.json @@ -0,0 +1,29 @@ +{ + "kind": "tm:net:trunk:trunkstate", + "name": "foo", + "fullPath": "foo", + "generation": 79, + "selfLink": "https://localhost/mgmt/tm/net/trunk/foo?ver=13.1.0.4", + "bandwidth": 10000, + "cfgMbrCount": 1, + "distributionHash": "dst-mac", + "id": 0, + "lacp": "disabled", + "lacpMode": "active", + "lacpTimeout": "long", + "linkSelectPolicy": "maximum-bandwidth", + "macAddress": "08:00:27:ea:18:52", + "media": "10000", + "qinqEthertype": "0x8100", + "stp": "enabled", + "type": "normal", + "workingMbrCount": 1, + "interfaces": [ + "1.3" + ], + "interfacesReference": [ + { + "link": "https://localhost/mgmt/tm/net/interface/1.3?ver=13.1.0.4" + } + ] +} diff --git a/test/units/modules/network/f5/test_bigip_traffic_group.py b/test/units/modules/network/f5/test_bigip_traffic_group.py index d068d51980f..9c3caa73417 100644 --- a/test/units/modules/network/f5/test_bigip_traffic_group.py +++ b/test/units/modules/network/f5/test_bigip_traffic_group.py @@ -21,15 +21,17 @@ from ansible.compat.tests.mock import patch from ansible.module_utils.basic import AnsibleModule try: - from library.bigip_traffic_group import Parameters - from library.bigip_traffic_group import ModuleManager - from library.bigip_traffic_group import ArgumentSpec + from library.modules.bigip_traffic_group import ApiParameters + from library.modules.bigip_traffic_group import ModuleParameters + from library.modules.bigip_traffic_group import ModuleManager + from library.modules.bigip_traffic_group import ArgumentSpec from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from test.unit.modules.utils import set_module_args except ImportError: try: - from ansible.modules.network.f5.bigip_traffic_group import Parameters + from ansible.modules.network.f5.bigip_traffic_group import ApiParameters + from ansible.modules.network.f5.bigip_traffic_group import ModuleParameters from ansible.modules.network.f5.bigip_traffic_group import ModuleManager from ansible.modules.network.f5.bigip_traffic_group import ArgumentSpec from ansible.module_utils.network.f5.common import F5ModuleError @@ -61,13 +63,35 @@ def load_fixture(name): class TestParameters(unittest.TestCase): - def test_module_parameters(self): + def test_module_parameters_1(self): args = dict( - name='foo' + name='foo', + mac_address='' ) - p = Parameters(params=args) + p = ModuleParameters(params=args) assert p.name == 'foo' + assert p.mac_address == 'none' + + def test_module_parameters_2(self): + args = dict( + mac_address='00:00:00:00:00:02' + ) + + p = ModuleParameters(params=args) + assert p.mac_address == '00:00:00:00:00:02' + + def test_api_parameters_1(self): + args = load_fixture('load_tm_cm_traffic_group_1.json') + + p = ApiParameters(params=args) + assert p.mac_address == 'none' + + def test_api_parameters_2(self): + args = load_fixture('load_tm_cm_traffic_group_2.json') + + p = ApiParameters(params=args) + assert p.mac_address == '00:00:00:00:00:02' class TestManager(unittest.TestCase): diff --git a/test/units/modules/network/f5/test_bigip_ucs.py b/test/units/modules/network/f5/test_bigip_ucs.py index d445f02ec4c..21fba92ae61 100644 --- a/test/units/modules/network/f5/test_bigip_ucs.py +++ b/test/units/modules/network/f5/test_bigip_ucs.py @@ -21,11 +21,11 @@ from ansible.compat.tests.mock import patch from ansible.module_utils.basic import AnsibleModule try: - from library.bigip_ucs import Parameters - from library.bigip_ucs import ModuleManager - from library.bigip_ucs import ArgumentSpec - from library.bigip_ucs import V1Manager - from library.bigip_ucs import V2Manager + from library.modules.bigip_ucs import Parameters + from library.modules.bigip_ucs import ModuleManager + from library.modules.bigip_ucs import ArgumentSpec + from library.modules.bigip_ucs import V1Manager + from library.modules.bigip_ucs import V2Manager from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from test.unit.modules.utils import set_module_args diff --git a/test/units/modules/network/f5/test_bigip_ucs_fetch.py b/test/units/modules/network/f5/test_bigip_ucs_fetch.py index 7f649aa323b..4de4b8f3a75 100644 --- a/test/units/modules/network/f5/test_bigip_ucs_fetch.py +++ b/test/units/modules/network/f5/test_bigip_ucs_fetch.py @@ -20,11 +20,11 @@ from ansible.compat.tests.mock import patch from ansible.module_utils.basic import AnsibleModule try: - from library.bigip_ucs_fetch import Parameters - from library.bigip_ucs_fetch import ModuleManager - from library.bigip_ucs_fetch import V1Manager - from library.bigip_ucs_fetch import V2Manager - from library.bigip_ucs_fetch import ArgumentSpec + from library.modules.bigip_ucs_fetch import Parameters + from library.modules.bigip_ucs_fetch import ModuleManager + from library.modules.bigip_ucs_fetch import V1Manager + from library.modules.bigip_ucs_fetch import V2Manager + from library.modules.bigip_ucs_fetch import ArgumentSpec from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from test.unit.modules.utils import set_module_args