Various fixes and changes for F5 (#34817)
Primarily, this patch contains refactors to remove tracebacks that are generated when libraries are missing. There is also, * Removed re-def of cleanup_tokens. * Changed parameter args to be keywords. * Changed imports to include new module_util locations. * Imports also include developing (sideband) module_util locations. * Changed to using F5Client and plain AnsibleModule to prevent tracebacks caused by missing libraries. * Removed init and update methods from most Parameter classes (optimization) as its now included in module_utils. * Changed module and module param references to take into account the new self.module arg. Minor bug fixes made during this refactor.
This commit is contained in:
parent
085a250575
commit
eace686044
21 changed files with 860 additions and 958 deletions
|
@ -44,19 +44,18 @@ options:
|
||||||
the virtual address and enables it. If C(enabled), enable the virtual
|
the virtual address and enables it. If C(enabled), enable the virtual
|
||||||
address if it exists. If C(disabled), create the virtual address if
|
address if it exists. If C(disabled), create the virtual address if
|
||||||
needed, and set state to C(disabled).
|
needed, and set state to C(disabled).
|
||||||
required: False
|
|
||||||
default: present
|
default: present
|
||||||
choices:
|
choices:
|
||||||
- present
|
- present
|
||||||
- absent
|
- absent
|
||||||
- enabled
|
- enabled
|
||||||
- disabled
|
- disabled
|
||||||
notes:
|
partition:
|
||||||
- Requires the f5-sdk Python package on the host. This is as easy as
|
description:
|
||||||
pip install f5-sdk.
|
- Device partition to manage resources on.
|
||||||
|
default: Common
|
||||||
|
version_added: 2.5
|
||||||
extends_documentation_fragment: f5
|
extends_documentation_fragment: f5
|
||||||
requirements:
|
|
||||||
- f5-sdk
|
|
||||||
author:
|
author:
|
||||||
- Tim Rupp (@caphrim007)
|
- Tim Rupp (@caphrim007)
|
||||||
'''
|
'''
|
||||||
|
@ -105,15 +104,38 @@ location:
|
||||||
sample: 222 West 23rd
|
sample: 222 West 23rd
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Parameters
|
from ansible.module_utils.basic import env_fallback
|
||||||
from ansible.module_utils.f5_utils import HAS_F5SDK
|
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
HAS_DEVEL_IMPORTS = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
# 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:
|
except ImportError:
|
||||||
HAS_F5SDK = False
|
# 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:
|
||||||
|
HAS_F5SDK = False
|
||||||
|
|
||||||
|
|
||||||
class Parameters(AnsibleF5Parameters):
|
class Parameters(AnsibleF5Parameters):
|
||||||
|
@ -258,9 +280,10 @@ class Difference(object):
|
||||||
|
|
||||||
|
|
||||||
class ModuleManager(object):
|
class ModuleManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.pop('module', None)
|
||||||
self.want = ModuleParameters(params=self.client.module.params)
|
self.client = kwargs.pop('client', None)
|
||||||
|
self.want = ModuleParameters(params=self.module.params)
|
||||||
self.have = ApiParameters()
|
self.have = ApiParameters()
|
||||||
self.changes = UsableChanges()
|
self.changes = UsableChanges()
|
||||||
|
|
||||||
|
@ -277,7 +300,7 @@ class ModuleManager(object):
|
||||||
except iControlUnexpectedHTTPError as e:
|
except iControlUnexpectedHTTPError as e:
|
||||||
raise F5ModuleError(str(e))
|
raise F5ModuleError(str(e))
|
||||||
|
|
||||||
reportable = ReportableChanges(self.changes.to_return())
|
reportable = ReportableChanges(params=self.changes.to_return())
|
||||||
changes = reportable.to_return()
|
changes = reportable.to_return()
|
||||||
result.update(**changes)
|
result.update(**changes)
|
||||||
result.update(dict(changed=changed))
|
result.update(dict(changed=changed))
|
||||||
|
@ -287,7 +310,7 @@ class ModuleManager(object):
|
||||||
def _announce_deprecations(self, result):
|
def _announce_deprecations(self, result):
|
||||||
warnings = result.pop('__warnings', [])
|
warnings = result.pop('__warnings', [])
|
||||||
for warning in warnings:
|
for warning in warnings:
|
||||||
self.client.module.deprecate(
|
self.module.deprecate(
|
||||||
msg=warning['msg'],
|
msg=warning['msg'],
|
||||||
version=warning['version']
|
version=warning['version']
|
||||||
)
|
)
|
||||||
|
@ -306,7 +329,7 @@ class ModuleManager(object):
|
||||||
else:
|
else:
|
||||||
changed[k] = change
|
changed[k] = change
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = UsableChanges(changed)
|
self.changes = UsableChanges(params=changed)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -334,7 +357,7 @@ class ModuleManager(object):
|
||||||
partition=self.want.partition
|
partition=self.want.partition
|
||||||
)
|
)
|
||||||
result = resource.attrs
|
result = resource.attrs
|
||||||
return ApiParameters(result)
|
return ApiParameters(params=result)
|
||||||
|
|
||||||
def exists(self):
|
def exists(self):
|
||||||
result = self.client.api.tm.gtm.datacenters.datacenter.exists(
|
result = self.client.api.tm.gtm.datacenters.datacenter.exists(
|
||||||
|
@ -347,7 +370,7 @@ class ModuleManager(object):
|
||||||
self.have = self.read_current_from_device()
|
self.have = self.read_current_from_device()
|
||||||
if not self.should_update():
|
if not self.should_update():
|
||||||
return False
|
return False
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.update_on_device()
|
self.update_on_device()
|
||||||
return True
|
return True
|
||||||
|
@ -363,7 +386,7 @@ class ModuleManager(object):
|
||||||
def create(self):
|
def create(self):
|
||||||
self.have = ApiParameters()
|
self.have = ApiParameters()
|
||||||
self.should_update()
|
self.should_update()
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.create_on_device()
|
self.create_on_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -380,7 +403,7 @@ class ModuleManager(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.remove_from_device()
|
self.remove_from_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -398,50 +421,44 @@ class ModuleManager(object):
|
||||||
class ArgumentSpec(object):
|
class ArgumentSpec(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.supports_check_mode = True
|
self.supports_check_mode = True
|
||||||
self.argument_spec = dict(
|
argument_spec = dict(
|
||||||
contact=dict(),
|
contact=dict(),
|
||||||
description=dict(),
|
description=dict(),
|
||||||
location=dict(),
|
location=dict(),
|
||||||
name=dict(required=True),
|
name=dict(required=True),
|
||||||
state=dict(
|
state=dict(
|
||||||
type='str',
|
|
||||||
default='present',
|
default='present',
|
||||||
choices=['present', 'absent', 'disabled', 'enabled']
|
choices=['present', 'absent', 'disabled', 'enabled']
|
||||||
|
),
|
||||||
|
partition=dict(
|
||||||
|
default='Common',
|
||||||
|
fallback=(env_fallback, ['F5_PARTITION'])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.f5_product_name = 'bigip'
|
self.argument_spec = {}
|
||||||
|
self.argument_spec.update(f5_argument_spec)
|
||||||
|
self.argument_spec.update(argument_spec)
|
||||||
def cleanup_tokens(client):
|
|
||||||
try:
|
|
||||||
resource = client.api.shared.authz.tokens_s.token.load(
|
|
||||||
name=client.api.icrs.token
|
|
||||||
)
|
|
||||||
resource.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not HAS_F5SDK:
|
|
||||||
raise F5ModuleError("The python f5-sdk module is required")
|
|
||||||
|
|
||||||
spec = ArgumentSpec()
|
spec = ArgumentSpec()
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
argument_spec=spec.argument_spec,
|
||||||
supports_check_mode=spec.supports_check_mode,
|
supports_check_mode=spec.supports_check_mode
|
||||||
f5_product_name=spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
if not HAS_F5SDK:
|
||||||
|
module.fail_json(msg="The python f5-sdk module is required")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mm = ModuleManager(client)
|
client = F5Client(**module.params)
|
||||||
|
mm = ModuleManager(module=module, client=client)
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.exit_json(**results)
|
module.exit_json(**results)
|
||||||
except F5ModuleError as e:
|
except F5ModuleError as ex:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.fail_json(msg=str(e))
|
module.fail_json(msg=str(ex))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -33,12 +33,7 @@ options:
|
||||||
- Perform regex filter of response. Filtering is done on the name of
|
- Perform regex filter of response. Filtering is done on the name of
|
||||||
the resource. Valid filters are anything that can be provided to
|
the resource. Valid filters are anything that can be provided to
|
||||||
Python's C(re) module.
|
Python's C(re) module.
|
||||||
notes:
|
|
||||||
- Requires the f5-sdk Python package on the host. This is as easy as
|
|
||||||
pip install f5-sdk
|
|
||||||
extends_documentation_fragment: f5
|
extends_documentation_fragment: f5
|
||||||
requirements:
|
|
||||||
- f5-sdk
|
|
||||||
author:
|
author:
|
||||||
- Tim Rupp (@caphrim007)
|
- Tim Rupp (@caphrim007)
|
||||||
'''
|
'''
|
||||||
|
@ -173,18 +168,45 @@ virtual_server:
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
|
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:
|
||||||
|
HAS_F5SDK = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import json
|
import json
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Parameters
|
|
||||||
from ansible.module_utils.f5_utils import HAS_F5SDK
|
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
|
||||||
from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE
|
from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE
|
||||||
from ansible.module_utils.six import iteritems
|
from ansible.module_utils.six import iteritems
|
||||||
from collections import defaultdict
|
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -195,8 +217,11 @@ except ImportError:
|
||||||
|
|
||||||
|
|
||||||
class BaseManager(object):
|
class BaseManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
|
self.client = kwargs.get('client', None)
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
self.types = dict(
|
self.types = dict(
|
||||||
a_s='a',
|
a_s='a',
|
||||||
aaaas='aaaa',
|
aaaas='aaaa',
|
||||||
|
@ -269,10 +294,6 @@ class TypedManager(BaseManager):
|
||||||
|
|
||||||
|
|
||||||
class Parameters(AnsibleF5Parameters):
|
class Parameters(AnsibleF5Parameters):
|
||||||
def __init__(self, params=None):
|
|
||||||
super(Parameters, self).__init__(params)
|
|
||||||
self._values['__warnings'] = []
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def include(self):
|
def include(self):
|
||||||
requested = self._values['include']
|
requested = self._values['include']
|
||||||
|
@ -296,36 +317,7 @@ class Parameters(AnsibleF5Parameters):
|
||||||
return requested
|
return requested
|
||||||
|
|
||||||
|
|
||||||
class BaseParameters(AnsibleF5Parameters):
|
class BaseParameters(Parameters):
|
||||||
def __init__(self, params=None):
|
|
||||||
self._values = defaultdict(lambda: None)
|
|
||||||
if params:
|
|
||||||
self.update(params=params)
|
|
||||||
self._values['__warnings'] = []
|
|
||||||
|
|
||||||
def update(self, params=None):
|
|
||||||
if params:
|
|
||||||
for k, v in iteritems(params):
|
|
||||||
if self.api_map is not None and k in self.api_map:
|
|
||||||
map_key = self.api_map[k]
|
|
||||||
else:
|
|
||||||
map_key = k
|
|
||||||
|
|
||||||
# Handle weird API parameters like `dns.proxy.__iter__` by
|
|
||||||
# using a map provided by the module developer
|
|
||||||
class_attr = getattr(type(self), map_key, None)
|
|
||||||
if isinstance(class_attr, property):
|
|
||||||
# There is a mapped value for the api_map key
|
|
||||||
if class_attr.fset is None:
|
|
||||||
# If the mapped value does not have an associated setter
|
|
||||||
self._values[map_key] = v
|
|
||||||
else:
|
|
||||||
# The mapped value has a setter
|
|
||||||
setattr(self, map_key, v)
|
|
||||||
else:
|
|
||||||
# If the mapped value is not a @property
|
|
||||||
self._values[map_key] = v
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def enabled(self):
|
def enabled(self):
|
||||||
if self._values['enabled'] is None:
|
if self._values['enabled'] is None:
|
||||||
|
@ -697,6 +689,12 @@ class ServerParameters(BaseParameters):
|
||||||
|
|
||||||
|
|
||||||
class PoolFactManager(BaseManager):
|
class PoolFactManager(BaseManager):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.module = kwargs.get('module', None)
|
||||||
|
self.client = kwargs.get('client', None)
|
||||||
|
super(PoolFactManager, self).__init__(**kwargs)
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
def exec_module(self):
|
def exec_module(self):
|
||||||
if self.version_is_less_than_12():
|
if self.version_is_less_than_12():
|
||||||
manager = self.get_manager('untyped')
|
manager = self.get_manager('untyped')
|
||||||
|
@ -708,15 +706,17 @@ class PoolFactManager(BaseManager):
|
||||||
|
|
||||||
def get_manager(self, type):
|
def get_manager(self, type):
|
||||||
if type == 'typed':
|
if type == 'typed':
|
||||||
return TypedPoolFactManager(self.client)
|
return TypedPoolFactManager(**self.kwargs)
|
||||||
elif type == 'untyped':
|
elif type == 'untyped':
|
||||||
return UntypedPoolFactManager(self.client)
|
return UntypedPoolFactManager(**self.kwargs)
|
||||||
|
|
||||||
|
|
||||||
class TypedPoolFactManager(TypedManager):
|
class TypedPoolFactManager(TypedManager):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
super(TypedPoolFactManager, self).__init__(client)
|
self.module = kwargs.get('module', None)
|
||||||
self.want = PoolParameters(self.client.module.params)
|
self.client = kwargs.get('client', None)
|
||||||
|
super(TypedPoolFactManager, self).__init__(**kwargs)
|
||||||
|
self.want = PoolParameters(params=self.module.params)
|
||||||
|
|
||||||
def read_facts(self, collection):
|
def read_facts(self, collection):
|
||||||
results = []
|
results = []
|
||||||
|
@ -740,9 +740,11 @@ class TypedPoolFactManager(TypedManager):
|
||||||
|
|
||||||
|
|
||||||
class UntypedPoolFactManager(UntypedManager):
|
class UntypedPoolFactManager(UntypedManager):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
super(UntypedPoolFactManager, self).__init__(client)
|
self.client = kwargs.get('client', None)
|
||||||
self.want = PoolParameters(self.client.module.params)
|
self.module = kwargs.get('module', None)
|
||||||
|
super(UntypedPoolFactManager, self).__init__(**kwargs)
|
||||||
|
self.want = PoolParameters(params=self.module.params)
|
||||||
|
|
||||||
def read_facts(self):
|
def read_facts(self):
|
||||||
results = []
|
results = []
|
||||||
|
@ -775,15 +777,17 @@ class WideIpFactManager(BaseManager):
|
||||||
|
|
||||||
def get_manager(self, type):
|
def get_manager(self, type):
|
||||||
if type == 'typed':
|
if type == 'typed':
|
||||||
return TypedWideIpFactManager(self.client)
|
return TypedWideIpFactManager(**self.kwargs)
|
||||||
elif type == 'untyped':
|
elif type == 'untyped':
|
||||||
return UntypedWideIpFactManager(self.client)
|
return UntypedWideIpFactManager(**self.kwargs)
|
||||||
|
|
||||||
|
|
||||||
class TypedWideIpFactManager(TypedManager):
|
class TypedWideIpFactManager(TypedManager):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
super(TypedWideIpFactManager, self).__init__(client)
|
self.client = kwargs.get('client', None)
|
||||||
self.want = WideIpParameters(self.client.module.params)
|
self.module = kwargs.get('module', None)
|
||||||
|
super(TypedWideIpFactManager, self).__init__(**kwargs)
|
||||||
|
self.want = WideIpParameters(params=self.module.params)
|
||||||
|
|
||||||
def read_facts(self, collection):
|
def read_facts(self, collection):
|
||||||
results = []
|
results = []
|
||||||
|
@ -806,9 +810,11 @@ class TypedWideIpFactManager(TypedManager):
|
||||||
|
|
||||||
|
|
||||||
class UntypedWideIpFactManager(UntypedManager):
|
class UntypedWideIpFactManager(UntypedManager):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
super(UntypedWideIpFactManager, self).__init__(client)
|
self.client = kwargs.get('client', None)
|
||||||
self.want = WideIpParameters(self.client.module.params)
|
self.module = kwargs.get('module', None)
|
||||||
|
super(UntypedWideIpFactManager, self).__init__(**kwargs)
|
||||||
|
self.want = WideIpParameters(params=self.module.params)
|
||||||
|
|
||||||
def read_facts(self):
|
def read_facts(self):
|
||||||
results = []
|
results = []
|
||||||
|
@ -829,9 +835,11 @@ class UntypedWideIpFactManager(UntypedManager):
|
||||||
|
|
||||||
|
|
||||||
class ServerFactManager(UntypedManager):
|
class ServerFactManager(UntypedManager):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
super(ServerFactManager, self).__init__(client)
|
self.client = kwargs.get('client', None)
|
||||||
self.want = ServerParameters(self.client.module.params)
|
self.module = kwargs.get('module', None)
|
||||||
|
super(ServerFactManager, self).__init__(**kwargs)
|
||||||
|
self.want = ServerParameters(params=self.module.params)
|
||||||
|
|
||||||
def exec_module(self):
|
def exec_module(self):
|
||||||
facts = super(ServerFactManager, self).exec_module()
|
facts = super(ServerFactManager, self).exec_module()
|
||||||
|
@ -857,9 +865,11 @@ class ServerFactManager(UntypedManager):
|
||||||
|
|
||||||
|
|
||||||
class ModuleManager(object):
|
class ModuleManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
self.want = Parameters(self.client.module.params)
|
self.client = kwargs.get('client', None)
|
||||||
|
self.kwargs = kwargs
|
||||||
|
self.want = Parameters(params=self.module.params)
|
||||||
|
|
||||||
def exec_module(self):
|
def exec_module(self):
|
||||||
if not self.gtm_provisioned():
|
if not self.gtm_provisioned():
|
||||||
|
@ -889,7 +899,7 @@ class ModuleManager(object):
|
||||||
if self.want:
|
if self.want:
|
||||||
warnings += self.want._values.get('__warnings', [])
|
warnings += self.want._values.get('__warnings', [])
|
||||||
for warning in warnings:
|
for warning in warnings:
|
||||||
self.client.module.deprecate(
|
self.module.deprecate(
|
||||||
msg=warning['msg'],
|
msg=warning['msg'],
|
||||||
version=warning['version']
|
version=warning['version']
|
||||||
)
|
)
|
||||||
|
@ -903,11 +913,11 @@ class ModuleManager(object):
|
||||||
|
|
||||||
def get_manager(self, which):
|
def get_manager(self, which):
|
||||||
if 'pool' == which:
|
if 'pool' == which:
|
||||||
return PoolFactManager(self.client)
|
return PoolFactManager(**self.kwargs)
|
||||||
if 'wide_ip' == which:
|
if 'wide_ip' == which:
|
||||||
return WideIpFactManager(self.client)
|
return WideIpFactManager(**self.kwargs)
|
||||||
if 'server' == which:
|
if 'server' == which:
|
||||||
return ServerFactManager(self.client)
|
return ServerFactManager(**self.kwargs)
|
||||||
|
|
||||||
def gtm_provisioned(self):
|
def gtm_provisioned(self):
|
||||||
resource = self.client.api.tm.sys.dbs.db.load(
|
resource = self.client.api.tm.sys.dbs.db.load(
|
||||||
|
@ -921,43 +931,34 @@ class ModuleManager(object):
|
||||||
class ArgumentSpec(object):
|
class ArgumentSpec(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.supports_check_mode = False
|
self.supports_check_mode = False
|
||||||
self.argument_spec = dict(
|
argument_spec = dict(
|
||||||
include=dict(type='list', required=True),
|
include=dict(type='list', required=True),
|
||||||
filter=dict(type='str', required=False)
|
filter=dict()
|
||||||
)
|
)
|
||||||
self.f5_product_name = 'bigip'
|
self.argument_spec = {}
|
||||||
|
self.argument_spec.update(f5_argument_spec)
|
||||||
|
self.argument_spec.update(argument_spec)
|
||||||
def cleanup_tokens(client):
|
|
||||||
try:
|
|
||||||
resource = client.api.shared.authz.tokens_s.token.load(
|
|
||||||
name=client.api.icrs.token
|
|
||||||
)
|
|
||||||
resource.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not HAS_F5SDK:
|
|
||||||
raise F5ModuleError("The python f5-sdk module is required")
|
|
||||||
|
|
||||||
spec = ArgumentSpec()
|
spec = ArgumentSpec()
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
argument_spec=spec.argument_spec,
|
||||||
supports_check_mode=spec.supports_check_mode,
|
supports_check_mode=spec.supports_check_mode
|
||||||
f5_product_name=spec.f5_product_name,
|
|
||||||
)
|
)
|
||||||
|
if not HAS_F5SDK:
|
||||||
|
module.fail_json(msg="The python f5-sdk module is required")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mm = ModuleManager(client)
|
client = F5Client(**module.params)
|
||||||
|
mm = ModuleManager(module=module, client=client)
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.exit_json(**results)
|
module.exit_json(**results)
|
||||||
except F5ModuleError as e:
|
except F5ModuleError as ex:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.fail_json(msg=str(e))
|
module.fail_json(msg=str(ex))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -123,13 +123,10 @@ options:
|
||||||
default: Common
|
default: Common
|
||||||
version_added: 2.5
|
version_added: 2.5
|
||||||
notes:
|
notes:
|
||||||
- Requires the f5-sdk Python package on the host. This is as easy as
|
|
||||||
pip install f5-sdk.
|
|
||||||
- Requires the netaddr Python package on the host. This is as easy as
|
- Requires the netaddr Python package on the host. This is as easy as
|
||||||
pip install netaddr.
|
pip install netaddr.
|
||||||
extends_documentation_fragment: f5
|
extends_documentation_fragment: f5
|
||||||
requirements:
|
requirements:
|
||||||
- f5-sdk
|
|
||||||
- netaddr
|
- netaddr
|
||||||
author:
|
author:
|
||||||
- Tim Rupp (@caphrim007)
|
- Tim Rupp (@caphrim007)
|
||||||
|
@ -177,19 +174,39 @@ EXAMPLES = r'''
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Parameters
|
|
||||||
from ansible.module_utils.f5_utils import HAS_F5SDK
|
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
|
||||||
from ansible.module_utils.six import iteritems
|
|
||||||
from collections import defaultdict
|
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.basic import env_fallback
|
||||||
|
|
||||||
|
HAS_DEVEL_IMPORTS = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
# 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:
|
except ImportError:
|
||||||
HAS_F5SDK = False
|
# 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:
|
||||||
|
HAS_F5SDK = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from netaddr import IPAddress, AddrFormatError
|
from netaddr import IPAddress, AddrFormatError
|
||||||
|
@ -223,36 +240,6 @@ class Parameters(AnsibleF5Parameters):
|
||||||
'fallbackIpv4', 'fallbackIpv6', 'fallbackIp', 'enabled', 'disabled'
|
'fallbackIpv4', 'fallbackIpv6', 'fallbackIp', 'enabled', 'disabled'
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, params=None):
|
|
||||||
self._values = defaultdict(lambda: None)
|
|
||||||
self._values['__warnings'] = []
|
|
||||||
if params:
|
|
||||||
self.update(params=params)
|
|
||||||
|
|
||||||
def update(self, params=None):
|
|
||||||
if params:
|
|
||||||
for k, v in iteritems(params):
|
|
||||||
if self.api_map is not None and k in self.api_map:
|
|
||||||
map_key = self.api_map[k]
|
|
||||||
else:
|
|
||||||
map_key = k
|
|
||||||
|
|
||||||
# Handle weird API parameters like `dns.proxy.__iter__` by
|
|
||||||
# using a map provided by the module developer
|
|
||||||
class_attr = getattr(type(self), map_key, None)
|
|
||||||
if isinstance(class_attr, property):
|
|
||||||
# There is a mapped value for the api_map key
|
|
||||||
if class_attr.fset is None:
|
|
||||||
# If the mapped value does not have
|
|
||||||
# an associated setter
|
|
||||||
self._values[map_key] = v
|
|
||||||
else:
|
|
||||||
# The mapped value has a setter
|
|
||||||
setattr(self, map_key, v)
|
|
||||||
else:
|
|
||||||
# If the mapped value is not a @property
|
|
||||||
self._values[map_key] = v
|
|
||||||
|
|
||||||
def to_return(self):
|
def to_return(self):
|
||||||
result = {}
|
result = {}
|
||||||
for returnable in self.returnables:
|
for returnable in self.returnables:
|
||||||
|
@ -260,16 +247,6 @@ class Parameters(AnsibleF5Parameters):
|
||||||
result = self._filter_params(result)
|
result = self._filter_params(result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def api_params(self):
|
|
||||||
result = {}
|
|
||||||
for api_attribute in self.api_attributes:
|
|
||||||
if self.api_map is not None and api_attribute in self.api_map:
|
|
||||||
result[api_attribute] = getattr(self, self.api_map[api_attribute])
|
|
||||||
else:
|
|
||||||
result[api_attribute] = getattr(self, api_attribute)
|
|
||||||
result = self._filter_params(result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def collection(self):
|
def collection(self):
|
||||||
type_map = dict(
|
type_map = dict(
|
||||||
|
@ -377,8 +354,9 @@ class Difference(object):
|
||||||
|
|
||||||
|
|
||||||
class ModuleManager(object):
|
class ModuleManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.kwargs = kwargs
|
||||||
|
self.client = kwargs.get('client', None)
|
||||||
|
|
||||||
def exec_module(self):
|
def exec_module(self):
|
||||||
if not self.gtm_provisioned():
|
if not self.gtm_provisioned():
|
||||||
|
@ -393,9 +371,9 @@ class ModuleManager(object):
|
||||||
|
|
||||||
def get_manager(self, type):
|
def get_manager(self, type):
|
||||||
if type == 'typed':
|
if type == 'typed':
|
||||||
return TypedManager(self.client)
|
return TypedManager(**self.kwargs)
|
||||||
elif type == 'untyped':
|
elif type == 'untyped':
|
||||||
return UntypedManager(self.client)
|
return UntypedManager(**self.kwargs)
|
||||||
|
|
||||||
def version_is_less_than_12(self):
|
def version_is_less_than_12(self):
|
||||||
version = self.client.api.tmos_version
|
version = self.client.api.tmos_version
|
||||||
|
@ -414,10 +392,11 @@ class ModuleManager(object):
|
||||||
|
|
||||||
|
|
||||||
class BaseManager(object):
|
class BaseManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
|
self.client = kwargs.get('client', None)
|
||||||
self.have = None
|
self.have = None
|
||||||
self.want = Parameters(self.client.module.params)
|
self.want = Parameters(params=self.module.params)
|
||||||
self.changes = Changes()
|
self.changes = Changes()
|
||||||
|
|
||||||
def _set_changed_options(self):
|
def _set_changed_options(self):
|
||||||
|
@ -426,7 +405,7 @@ class BaseManager(object):
|
||||||
if getattr(self.want, key) is not None:
|
if getattr(self.want, key) is not None:
|
||||||
changed[key] = getattr(self.want, key)
|
changed[key] = getattr(self.want, key)
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = Changes(changed)
|
self.changes = Changes(params=changed)
|
||||||
|
|
||||||
def _update_changed_options(self):
|
def _update_changed_options(self):
|
||||||
diff = Difference(self.want, self.have)
|
diff = Difference(self.want, self.have)
|
||||||
|
@ -442,7 +421,7 @@ class BaseManager(object):
|
||||||
else:
|
else:
|
||||||
changed[k] = change
|
changed[k] = change
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = Changes(changed)
|
self.changes = Changes(params=changed)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -485,7 +464,7 @@ class BaseManager(object):
|
||||||
self.have = self.read_current_from_device()
|
self.have = self.read_current_from_device()
|
||||||
if not self.should_update():
|
if not self.should_update():
|
||||||
return False
|
return False
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.update_on_device()
|
self.update_on_device()
|
||||||
return True
|
return True
|
||||||
|
@ -496,7 +475,7 @@ class BaseManager(object):
|
||||||
elif self.want.state in ['present', 'enabled']:
|
elif self.want.state in ['present', 'enabled']:
|
||||||
self.want.update({'enabled': True})
|
self.want.update({'enabled': True})
|
||||||
self._set_changed_options()
|
self._set_changed_options()
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.create_on_device()
|
self.create_on_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -505,7 +484,7 @@ class BaseManager(object):
|
||||||
raise F5ModuleError("Failed to create the GTM pool")
|
raise F5ModuleError("Failed to create the GTM pool")
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.remove_from_device()
|
self.remove_from_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -514,8 +493,8 @@ class BaseManager(object):
|
||||||
|
|
||||||
|
|
||||||
class TypedManager(BaseManager):
|
class TypedManager(BaseManager):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
super(TypedManager, self).__init__(client)
|
super(TypedManager, self).__init__(**kwargs)
|
||||||
if self.want.type is None:
|
if self.want.type is None:
|
||||||
raise F5ModuleError(
|
raise F5ModuleError(
|
||||||
"The 'type' option is required for BIG-IP instances "
|
"The 'type' option is required for BIG-IP instances "
|
||||||
|
@ -567,7 +546,7 @@ class TypedManager(BaseManager):
|
||||||
partition=self.want.partition
|
partition=self.want.partition
|
||||||
)
|
)
|
||||||
result = result.attrs
|
result = result.attrs
|
||||||
return Parameters(result)
|
return Parameters(params=result)
|
||||||
|
|
||||||
def create_on_device(self):
|
def create_on_device(self):
|
||||||
params = self.want.api_params()
|
params = self.want.api_params()
|
||||||
|
@ -614,7 +593,7 @@ class UntypedManager(BaseManager):
|
||||||
partition=self.want.partition
|
partition=self.want.partition
|
||||||
)
|
)
|
||||||
result = resource.attrs
|
result = resource.attrs
|
||||||
return Parameters(result)
|
return Parameters(params=result)
|
||||||
|
|
||||||
def create_on_device(self):
|
def create_on_device(self):
|
||||||
params = self.want.api_params()
|
params = self.want.api_params()
|
||||||
|
@ -655,7 +634,7 @@ class ArgumentSpec(object):
|
||||||
'a', 'aaaa', 'cname', 'mx', 'naptr', 'srv'
|
'a', 'aaaa', 'cname', 'mx', 'naptr', 'srv'
|
||||||
]
|
]
|
||||||
self.supports_check_mode = True
|
self.supports_check_mode = True
|
||||||
self.argument_spec = dict(
|
argument_spec = dict(
|
||||||
name=dict(required=True),
|
name=dict(required=True),
|
||||||
state=dict(
|
state=dict(
|
||||||
default='present',
|
default='present',
|
||||||
|
@ -673,50 +652,44 @@ class ArgumentSpec(object):
|
||||||
fallback_ip=dict(),
|
fallback_ip=dict(),
|
||||||
type=dict(
|
type=dict(
|
||||||
choices=self.types
|
choices=self.types
|
||||||
|
),
|
||||||
|
partition=dict(
|
||||||
|
default='Common',
|
||||||
|
fallback=(env_fallback, ['F5_PARTITION'])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
self.argument_spec = {}
|
||||||
|
self.argument_spec.update(f5_argument_spec)
|
||||||
|
self.argument_spec.update(argument_spec)
|
||||||
self.required_if = [
|
self.required_if = [
|
||||||
['preferred_lb_method', 'fallback-ip', ['fallback_ip']],
|
['preferred_lb_method', 'fallback-ip', ['fallback_ip']],
|
||||||
['fallback_lb_method', 'fallback-ip', ['fallback_ip']],
|
['fallback_lb_method', 'fallback-ip', ['fallback_ip']],
|
||||||
['alternate_lb_method', 'fallback-ip', ['fallback_ip']]
|
['alternate_lb_method', 'fallback-ip', ['fallback_ip']]
|
||||||
]
|
]
|
||||||
self.f5_product_name = 'bigip'
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup_tokens(client):
|
|
||||||
try:
|
|
||||||
resource = client.api.shared.authz.tokens_s.token.load(
|
|
||||||
name=client.api.icrs.token
|
|
||||||
)
|
|
||||||
resource.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not HAS_F5SDK:
|
|
||||||
raise F5ModuleError("The python f5-sdk module is required")
|
|
||||||
|
|
||||||
if not HAS_NETADDR:
|
|
||||||
raise F5ModuleError("The python netaddr module is required")
|
|
||||||
|
|
||||||
spec = ArgumentSpec()
|
spec = ArgumentSpec()
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
argument_spec=spec.argument_spec,
|
||||||
supports_check_mode=spec.supports_check_mode,
|
supports_check_mode=spec.supports_check_mode,
|
||||||
f5_product_name=spec.f5_product_name,
|
|
||||||
required_if=spec.required_if
|
required_if=spec.required_if
|
||||||
)
|
)
|
||||||
|
if not HAS_F5SDK:
|
||||||
|
module.fail_json(msg="The python f5-sdk module is required")
|
||||||
|
if not HAS_NETADDR:
|
||||||
|
module.fail_json(msg="The python netaddr module is required")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mm = ModuleManager(client)
|
client = F5Client(**module.params)
|
||||||
|
mm = ModuleManager(module=module, client=client)
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.exit_json(**results)
|
module.exit_json(**results)
|
||||||
except F5ModuleError as e:
|
except F5ModuleError as ex:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.fail_json(msg=str(e))
|
module.fail_json(msg=str(ex))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -102,15 +102,9 @@ options:
|
||||||
partition:
|
partition:
|
||||||
description:
|
description:
|
||||||
- Device partition to manage resources on.
|
- Device partition to manage resources on.
|
||||||
required: False
|
default: Common
|
||||||
default: 'Common'
|
|
||||||
version_added: 2.5
|
version_added: 2.5
|
||||||
notes:
|
|
||||||
- Requires the f5-sdk Python package on the host. This is as easy as
|
|
||||||
pip install f5-sdk.
|
|
||||||
extends_documentation_fragment: f5
|
extends_documentation_fragment: f5
|
||||||
requirements:
|
|
||||||
- f5-sdk
|
|
||||||
author:
|
author:
|
||||||
- Robert Teller
|
- Robert Teller
|
||||||
- Tim Rupp (@caphrim007)
|
- Tim Rupp (@caphrim007)
|
||||||
|
@ -188,14 +182,41 @@ datacenter:
|
||||||
sample: datacenter01
|
sample: datacenter01
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Parameters
|
|
||||||
from ansible.module_utils.f5_utils import HAS_F5SDK
|
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
|
||||||
from ansible.module_utils.six import iteritems
|
|
||||||
from collections import defaultdict
|
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
|
||||||
|
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:
|
||||||
|
HAS_F5SDK = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -204,11 +225,6 @@ except ImportError:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
|
||||||
except ImportError:
|
|
||||||
HAS_F5SDK = False
|
|
||||||
|
|
||||||
|
|
||||||
class Parameters(AnsibleF5Parameters):
|
class Parameters(AnsibleF5Parameters):
|
||||||
api_map = {
|
api_map = {
|
||||||
|
@ -233,47 +249,6 @@ class Parameters(AnsibleF5Parameters):
|
||||||
'datacenter', 'enabled', 'disabled'
|
'datacenter', 'enabled', 'disabled'
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, params=None):
|
|
||||||
self._values = defaultdict(lambda: None)
|
|
||||||
self._values['__warnings'] = []
|
|
||||||
if params:
|
|
||||||
self.update(params=params)
|
|
||||||
|
|
||||||
def update(self, params=None):
|
|
||||||
if params:
|
|
||||||
for k, v in iteritems(params):
|
|
||||||
if self.api_map is not None and k in self.api_map:
|
|
||||||
map_key = self.api_map[k]
|
|
||||||
else:
|
|
||||||
map_key = k
|
|
||||||
|
|
||||||
# Handle weird API parameters like `dns.proxy.__iter__` by
|
|
||||||
# using a map provided by the module developer
|
|
||||||
class_attr = getattr(type(self), map_key, None)
|
|
||||||
if isinstance(class_attr, property):
|
|
||||||
# There is a mapped value for the api_map key
|
|
||||||
if class_attr.fset is None:
|
|
||||||
# If the mapped value does not have
|
|
||||||
# an associated setter
|
|
||||||
self._values[map_key] = v
|
|
||||||
else:
|
|
||||||
# The mapped value has a setter
|
|
||||||
setattr(self, map_key, v)
|
|
||||||
else:
|
|
||||||
# If the mapped value is not a @property
|
|
||||||
self._values[map_key] = v
|
|
||||||
|
|
||||||
def api_params(self):
|
|
||||||
result = {}
|
|
||||||
for api_attribute in self.api_attributes:
|
|
||||||
if api_attribute in self.api_map:
|
|
||||||
result[api_attribute] = getattr(
|
|
||||||
self, self.api_map[api_attribute])
|
|
||||||
else:
|
|
||||||
result[api_attribute] = getattr(self, api_attribute)
|
|
||||||
result = self._filter_params(result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _fqdn_name(self, value):
|
def _fqdn_name(self, value):
|
||||||
if value is not None and not value.startswith('/'):
|
if value is not None and not value.startswith('/'):
|
||||||
return '/{0}/{1}'.format(self.partition, value)
|
return '/{0}/{1}'.format(self.partition, value)
|
||||||
|
@ -549,8 +524,10 @@ class Difference(object):
|
||||||
|
|
||||||
|
|
||||||
class ModuleManager(object):
|
class ModuleManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
|
self.client = kwargs.get('client', None)
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
def exec_module(self):
|
def exec_module(self):
|
||||||
if not self.gtm_provisioned():
|
if not self.gtm_provisioned():
|
||||||
|
@ -565,9 +542,9 @@ class ModuleManager(object):
|
||||||
|
|
||||||
def get_manager(self, type):
|
def get_manager(self, type):
|
||||||
if type == 'v1':
|
if type == 'v1':
|
||||||
return V1Manager(self.client)
|
return V1Manager(**self.kwargs)
|
||||||
elif type == 'v2':
|
elif type == 'v2':
|
||||||
return V2Manager(self.client)
|
return V2Manager(**self.kwargs)
|
||||||
|
|
||||||
def version_is_less_than(self, version):
|
def version_is_less_than(self, version):
|
||||||
tmos_version = self.client.api.tmos_version
|
tmos_version = self.client.api.tmos_version
|
||||||
|
@ -586,10 +563,11 @@ class ModuleManager(object):
|
||||||
|
|
||||||
|
|
||||||
class BaseManager(object):
|
class BaseManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
self.want = ModuleParameters(params=self.client.module.params)
|
self.client = kwargs.get('client', None)
|
||||||
self.want.update(dict(client=client))
|
self.want = ModuleParameters(params=self.module.params)
|
||||||
|
self.want.update(dict(client=self.client))
|
||||||
self.have = ApiParameters()
|
self.have = ApiParameters()
|
||||||
self.changes = UsableChanges()
|
self.changes = UsableChanges()
|
||||||
|
|
||||||
|
@ -599,7 +577,7 @@ class BaseManager(object):
|
||||||
if getattr(self.want, key) is not None:
|
if getattr(self.want, key) is not None:
|
||||||
changed[key] = getattr(self.want, key)
|
changed[key] = getattr(self.want, key)
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = UsableChanges(changed)
|
self.changes = UsableChanges(params=changed)
|
||||||
|
|
||||||
def _update_changed_options(self):
|
def _update_changed_options(self):
|
||||||
diff = Difference(self.want, self.have)
|
diff = Difference(self.want, self.have)
|
||||||
|
@ -616,7 +594,7 @@ class BaseManager(object):
|
||||||
else:
|
else:
|
||||||
changed[k] = change
|
changed[k] = change
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = UsableChanges(changed)
|
self.changes = UsableChanges(params=changed)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -633,7 +611,7 @@ class BaseManager(object):
|
||||||
except iControlUnexpectedHTTPError as e:
|
except iControlUnexpectedHTTPError as e:
|
||||||
raise F5ModuleError(str(e))
|
raise F5ModuleError(str(e))
|
||||||
|
|
||||||
reportable = ReportableChanges(self.changes.to_return())
|
reportable = ReportableChanges(params=self.changes.to_return())
|
||||||
changes = reportable.to_return()
|
changes = reportable.to_return()
|
||||||
result.update(**changes)
|
result.update(**changes)
|
||||||
result.update(dict(changed=changed))
|
result.update(dict(changed=changed))
|
||||||
|
@ -643,7 +621,7 @@ class BaseManager(object):
|
||||||
def _announce_deprecations(self, result):
|
def _announce_deprecations(self, result):
|
||||||
warnings = result.pop('__warnings', [])
|
warnings = result.pop('__warnings', [])
|
||||||
for warning in warnings:
|
for warning in warnings:
|
||||||
self.client.module.deprecate(
|
self.module.deprecate(
|
||||||
msg=warning['msg'],
|
msg=warning['msg'],
|
||||||
version=warning['version']
|
version=warning['version']
|
||||||
)
|
)
|
||||||
|
@ -673,7 +651,7 @@ class BaseManager(object):
|
||||||
)
|
)
|
||||||
self._assign_creation_defaults()
|
self._assign_creation_defaults()
|
||||||
|
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.create_on_device()
|
self.create_on_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -693,7 +671,7 @@ class BaseManager(object):
|
||||||
self.have = self.read_current_from_device()
|
self.have = self.read_current_from_device()
|
||||||
if not self.should_update():
|
if not self.should_update():
|
||||||
return False
|
return False
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.update_on_device()
|
self.update_on_device()
|
||||||
return True
|
return True
|
||||||
|
@ -704,7 +682,7 @@ class BaseManager(object):
|
||||||
partition=self.want.partition
|
partition=self.want.partition
|
||||||
)
|
)
|
||||||
result = resource.attrs
|
result = resource.attrs
|
||||||
return ApiParameters(result)
|
return ApiParameters(params=result)
|
||||||
|
|
||||||
def should_update(self):
|
def should_update(self):
|
||||||
result = self._update_changed_options()
|
result = self._update_changed_options()
|
||||||
|
@ -727,7 +705,7 @@ class BaseManager(object):
|
||||||
return changed
|
return changed
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.remove_from_device()
|
self.remove_from_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -795,7 +773,7 @@ class ArgumentSpec(object):
|
||||||
'redundant-bigip', 'windows-2000-server'
|
'redundant-bigip', 'windows-2000-server'
|
||||||
]
|
]
|
||||||
self.supports_check_mode = True
|
self.supports_check_mode = True
|
||||||
self.argument_spec = dict(
|
argument_spec = dict(
|
||||||
state=dict(
|
state=dict(
|
||||||
default='present',
|
default='present',
|
||||||
choices=self.states,
|
choices=self.states,
|
||||||
|
@ -814,39 +792,36 @@ class ArgumentSpec(object):
|
||||||
),
|
),
|
||||||
devices=dict(
|
devices=dict(
|
||||||
type='list'
|
type='list'
|
||||||
|
),
|
||||||
|
partition=dict(
|
||||||
|
default='Common',
|
||||||
|
fallback=(env_fallback, ['F5_PARTITION'])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.f5_product_name = 'bigip'
|
self.argument_spec = {}
|
||||||
|
self.argument_spec.update(f5_argument_spec)
|
||||||
|
self.argument_spec.update(argument_spec)
|
||||||
def cleanup_tokens(client):
|
|
||||||
try:
|
|
||||||
resource = client.api.shared.authz.tokens_s.token.load(
|
|
||||||
name=client.api.icrs.token
|
|
||||||
)
|
|
||||||
resource.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not HAS_F5SDK:
|
|
||||||
raise F5ModuleError("The python f5-sdk module is required")
|
|
||||||
|
|
||||||
spec = ArgumentSpec()
|
spec = ArgumentSpec()
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
argument_spec=spec.argument_spec,
|
||||||
supports_check_mode=spec.supports_check_mode,
|
supports_check_mode=spec.supports_check_mode
|
||||||
f5_product_name=spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
if not HAS_F5SDK:
|
||||||
|
module.fail_json(msg="The python f5-sdk module is required")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mm = ModuleManager(client)
|
client = F5Client(**module.params)
|
||||||
|
mm = ModuleManager(module=module, client=client)
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
client.module.exit_json(**results)
|
cleanup_tokens(client)
|
||||||
except F5ModuleError as e:
|
module.exit_json(**results)
|
||||||
client.module.fail_json(msg=str(e))
|
except F5ModuleError as ex:
|
||||||
|
cleanup_tokens(client)
|
||||||
|
module.fail_json(msg=str(ex))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -87,17 +87,11 @@ options:
|
||||||
- Ratio for the pool.
|
- Ratio for the pool.
|
||||||
- The system uses this number with the Ratio load balancing method.
|
- The system uses this number with the Ratio load balancing method.
|
||||||
version_added: 2.5
|
version_added: 2.5
|
||||||
notes:
|
|
||||||
- Requires the f5-sdk Python package on the host. This is as easy as pip
|
|
||||||
install f5-sdk.
|
|
||||||
extends_documentation_fragment: f5
|
extends_documentation_fragment: f5
|
||||||
requirements:
|
|
||||||
- f5-sdk
|
|
||||||
author:
|
author:
|
||||||
- Tim Rupp (@caphrim007)
|
- Tim Rupp (@caphrim007)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- name: Set lb method
|
- name: Set lb method
|
||||||
bigip_gtm_wide_ip:
|
bigip_gtm_wide_ip:
|
||||||
|
@ -124,17 +118,41 @@ state:
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Parameters
|
|
||||||
from ansible.module_utils.f5_utils import HAS_F5SDK
|
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
|
||||||
from ansible.module_utils.six import iteritems
|
from ansible.module_utils.six import iteritems
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.basic import env_fallback
|
||||||
|
|
||||||
|
HAS_DEVEL_IMPORTS = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
# 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:
|
except ImportError:
|
||||||
HAS_F5SDK = False
|
# 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:
|
||||||
|
HAS_F5SDK = False
|
||||||
|
|
||||||
|
|
||||||
class Parameters(AnsibleF5Parameters):
|
class Parameters(AnsibleF5Parameters):
|
||||||
|
@ -145,16 +163,6 @@ class Parameters(AnsibleF5Parameters):
|
||||||
returnables = ['name', 'pool_lb_method', 'state', 'pools']
|
returnables = ['name', 'pool_lb_method', 'state', 'pools']
|
||||||
api_attributes = ['poolLbMode', 'enabled', 'disabled', 'pools']
|
api_attributes = ['poolLbMode', 'enabled', 'disabled', 'pools']
|
||||||
|
|
||||||
def api_params(self):
|
|
||||||
result = {}
|
|
||||||
for api_attribute in self.api_attributes:
|
|
||||||
if self.api_map is not None and api_attribute in self.api_map:
|
|
||||||
result[api_attribute] = getattr(self, self.api_map[api_attribute])
|
|
||||||
else:
|
|
||||||
result[api_attribute] = getattr(self, api_attribute)
|
|
||||||
result = self._filter_params(result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _fqdn_name(self, value):
|
def _fqdn_name(self, value):
|
||||||
if value is not None and not value.startswith('/'):
|
if value is not None and not value.startswith('/'):
|
||||||
return '/{0}/{1}'.format(self.partition, value)
|
return '/{0}/{1}'.format(self.partition, value)
|
||||||
|
@ -369,8 +377,10 @@ class Difference(object):
|
||||||
|
|
||||||
|
|
||||||
class ModuleManager(object):
|
class ModuleManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
|
self.client = kwargs.get('client', None)
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
def exec_module(self):
|
def exec_module(self):
|
||||||
if self.version_is_less_than_12():
|
if self.version_is_less_than_12():
|
||||||
|
@ -381,9 +391,9 @@ class ModuleManager(object):
|
||||||
|
|
||||||
def get_manager(self, type):
|
def get_manager(self, type):
|
||||||
if type == 'typed':
|
if type == 'typed':
|
||||||
return TypedManager(self.client)
|
return TypedManager(**self.kwargs)
|
||||||
elif type == 'untyped':
|
elif type == 'untyped':
|
||||||
return UntypedManager(self.client)
|
return UntypedManager(**self.kwargs)
|
||||||
|
|
||||||
def version_is_less_than_12(self):
|
def version_is_less_than_12(self):
|
||||||
version = self.client.api.tmos_version
|
version = self.client.api.tmos_version
|
||||||
|
@ -394,9 +404,10 @@ class ModuleManager(object):
|
||||||
|
|
||||||
|
|
||||||
class BaseManager(object):
|
class BaseManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
self.want = ModuleParameters(params=self.client.module.params)
|
self.client = kwargs.get('client', None)
|
||||||
|
self.want = ModuleParameters(params=self.module.params)
|
||||||
self.have = ApiParameters()
|
self.have = ApiParameters()
|
||||||
self.changes = UsableChanges()
|
self.changes = UsableChanges()
|
||||||
|
|
||||||
|
@ -406,7 +417,7 @@ class BaseManager(object):
|
||||||
if getattr(self.want, key) is not None:
|
if getattr(self.want, key) is not None:
|
||||||
changed[key] = getattr(self.want, key)
|
changed[key] = getattr(self.want, key)
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = UsableChanges(changed)
|
self.changes = UsableChanges(params=changed)
|
||||||
|
|
||||||
def _update_changed_options(self):
|
def _update_changed_options(self):
|
||||||
diff = Difference(self.want, self.have)
|
diff = Difference(self.want, self.have)
|
||||||
|
@ -422,7 +433,7 @@ class BaseManager(object):
|
||||||
else:
|
else:
|
||||||
changed[k] = change
|
changed[k] = change
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = UsableChanges(changed)
|
self.changes = UsableChanges(params=changed)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -439,7 +450,7 @@ class BaseManager(object):
|
||||||
except iControlUnexpectedHTTPError as e:
|
except iControlUnexpectedHTTPError as e:
|
||||||
raise F5ModuleError(str(e))
|
raise F5ModuleError(str(e))
|
||||||
|
|
||||||
reportable = ReportableChanges(self.changes.to_return())
|
reportable = ReportableChanges(params=self.changes.to_return())
|
||||||
changes = reportable.to_return()
|
changes = reportable.to_return()
|
||||||
result.update(**changes)
|
result.update(**changes)
|
||||||
result.update(dict(changed=changed))
|
result.update(dict(changed=changed))
|
||||||
|
@ -449,7 +460,7 @@ class BaseManager(object):
|
||||||
def _announce_deprecations(self, result):
|
def _announce_deprecations(self, result):
|
||||||
warnings = result.pop('__warnings', [])
|
warnings = result.pop('__warnings', [])
|
||||||
for warning in warnings:
|
for warning in warnings:
|
||||||
self.client.module.deprecate(
|
self.module.deprecate(
|
||||||
msg=warning['msg'],
|
msg=warning['msg'],
|
||||||
version=warning['version']
|
version=warning['version']
|
||||||
)
|
)
|
||||||
|
@ -466,7 +477,7 @@ class BaseManager(object):
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
self._set_changed_options()
|
self._set_changed_options()
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.create_on_device()
|
self.create_on_device()
|
||||||
return True
|
return True
|
||||||
|
@ -481,7 +492,7 @@ class BaseManager(object):
|
||||||
self.have = self.read_current_from_device()
|
self.have = self.read_current_from_device()
|
||||||
if not self.should_update():
|
if not self.should_update():
|
||||||
return False
|
return False
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.update_on_device()
|
self.update_on_device()
|
||||||
return True
|
return True
|
||||||
|
@ -492,7 +503,7 @@ class BaseManager(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.remove_from_device()
|
self.remove_from_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -521,7 +532,7 @@ class UntypedManager(BaseManager):
|
||||||
partition=self.want.partition
|
partition=self.want.partition
|
||||||
)
|
)
|
||||||
result = resource.attrs
|
result = resource.attrs
|
||||||
return ApiParameters(result)
|
return ApiParameters(params=result)
|
||||||
|
|
||||||
def create_on_device(self):
|
def create_on_device(self):
|
||||||
params = self.want.api_params()
|
params = self.want.api_params()
|
||||||
|
@ -541,8 +552,8 @@ class UntypedManager(BaseManager):
|
||||||
|
|
||||||
|
|
||||||
class TypedManager(BaseManager):
|
class TypedManager(BaseManager):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
super(TypedManager, self).__init__(client)
|
super(TypedManager, self).__init__(**kwargs)
|
||||||
if self.want.type is None:
|
if self.want.type is None:
|
||||||
raise F5ModuleError(
|
raise F5ModuleError(
|
||||||
"The 'type' option is required for BIG-IP instances "
|
"The 'type' option is required for BIG-IP instances "
|
||||||
|
@ -588,7 +599,7 @@ class TypedManager(BaseManager):
|
||||||
partition=self.want.partition
|
partition=self.want.partition
|
||||||
)
|
)
|
||||||
result = result.attrs
|
result = result.attrs
|
||||||
return ApiParameters(result)
|
return ApiParameters(params=result)
|
||||||
|
|
||||||
def create_on_device(self):
|
def create_on_device(self):
|
||||||
params = self.want.api_params()
|
params = self.want.api_params()
|
||||||
|
@ -626,7 +637,7 @@ class ArgumentSpec(object):
|
||||||
]
|
]
|
||||||
lb_method_choices = deprecated + supported
|
lb_method_choices = deprecated + supported
|
||||||
self.supports_check_mode = True
|
self.supports_check_mode = True
|
||||||
self.argument_spec = dict(
|
argument_spec = dict(
|
||||||
pool_lb_method=dict(
|
pool_lb_method=dict(
|
||||||
choices=lb_method_choices,
|
choices=lb_method_choices,
|
||||||
aliases=['lb_method']
|
aliases=['lb_method']
|
||||||
|
@ -650,41 +661,36 @@ class ArgumentSpec(object):
|
||||||
name=dict(required=True),
|
name=dict(required=True),
|
||||||
ratio=dict(type='int')
|
ratio=dict(type='int')
|
||||||
)
|
)
|
||||||
|
),
|
||||||
|
partition=dict(
|
||||||
|
default='Common',
|
||||||
|
fallback=(env_fallback, ['F5_PARTITION'])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.f5_product_name = 'bigip'
|
self.argument_spec = {}
|
||||||
|
self.argument_spec.update(f5_argument_spec)
|
||||||
|
self.argument_spec.update(argument_spec)
|
||||||
def cleanup_tokens(client):
|
|
||||||
try:
|
|
||||||
resource = client.api.shared.authz.tokens_s.token.load(
|
|
||||||
name=client.api.icrs.token
|
|
||||||
)
|
|
||||||
resource.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not HAS_F5SDK:
|
|
||||||
raise F5ModuleError("The python f5-sdk module is required")
|
|
||||||
|
|
||||||
spec = ArgumentSpec()
|
spec = ArgumentSpec()
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
argument_spec=spec.argument_spec,
|
||||||
supports_check_mode=spec.supports_check_mode,
|
supports_check_mode=spec.supports_check_mode
|
||||||
f5_product_name=spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
if not HAS_F5SDK:
|
||||||
|
module.fail_json(msg="The python f5-sdk module is required")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mm = ModuleManager(client)
|
client = F5Client(**module.params)
|
||||||
|
mm = ModuleManager(module=module, client=client)
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.exit_json(**results)
|
module.exit_json(**results)
|
||||||
except F5ModuleError as e:
|
except F5ModuleError as e:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.fail_json(msg=str(e))
|
module.fail_json(msg=str(e))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -24,12 +24,7 @@ options:
|
||||||
description:
|
description:
|
||||||
- Hostname of the BIG-IP host.
|
- Hostname of the BIG-IP host.
|
||||||
required: True
|
required: True
|
||||||
notes:
|
|
||||||
- Requires the f5-sdk Python package on the host. This is as easy as pip
|
|
||||||
install f5-sdk.
|
|
||||||
extends_documentation_fragment: f5
|
extends_documentation_fragment: f5
|
||||||
requirements:
|
|
||||||
- f5-sdk
|
|
||||||
author:
|
author:
|
||||||
- Tim Rupp (@caphrim007)
|
- Tim Rupp (@caphrim007)
|
||||||
- Matthew Lam (@mryanlam)
|
- Matthew Lam (@mryanlam)
|
||||||
|
@ -53,15 +48,37 @@ hostname:
|
||||||
sample: big-ip01.internal
|
sample: big-ip01.internal
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Parameters
|
|
||||||
from ansible.module_utils.f5_utils import HAS_F5SDK
|
HAS_DEVEL_IMPORTS = False
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
# 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:
|
except ImportError:
|
||||||
HAS_F5SDK = False
|
# 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:
|
||||||
|
HAS_F5SDK = False
|
||||||
|
|
||||||
|
|
||||||
class Parameters(AnsibleF5Parameters):
|
class Parameters(AnsibleF5Parameters):
|
||||||
|
@ -76,16 +93,6 @@ class Parameters(AnsibleF5Parameters):
|
||||||
result = self._filter_params(result)
|
result = self._filter_params(result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def api_params(self):
|
|
||||||
result = {}
|
|
||||||
for api_attribute in self.api_attributes:
|
|
||||||
if self.api_map is not None and api_attribute in self.api_map:
|
|
||||||
result[api_attribute] = getattr(self, self.api_map[api_attribute])
|
|
||||||
else:
|
|
||||||
result[api_attribute] = getattr(self, api_attribute)
|
|
||||||
result = self._filter_params(result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hostname(self):
|
def hostname(self):
|
||||||
if self._values['hostname'] is None:
|
if self._values['hostname'] is None:
|
||||||
|
@ -94,10 +101,11 @@ class Parameters(AnsibleF5Parameters):
|
||||||
|
|
||||||
|
|
||||||
class ModuleManager(object):
|
class ModuleManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
|
self.client = kwargs.get('client', None)
|
||||||
self.have = None
|
self.have = None
|
||||||
self.want = Parameters(self.client.module.params)
|
self.want = Parameters(params=self.module.params)
|
||||||
self.changes = Parameters()
|
self.changes = Parameters()
|
||||||
|
|
||||||
def _set_changed_options(self):
|
def _set_changed_options(self):
|
||||||
|
@ -106,7 +114,7 @@ class ModuleManager(object):
|
||||||
if getattr(self.want, key) is not None:
|
if getattr(self.want, key) is not None:
|
||||||
changed[key] = getattr(self.want, key)
|
changed[key] = getattr(self.want, key)
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = Parameters(changed)
|
self.changes = Parameters(params=changed)
|
||||||
|
|
||||||
def _update_changed_options(self):
|
def _update_changed_options(self):
|
||||||
changed = {}
|
changed = {}
|
||||||
|
@ -116,7 +124,7 @@ class ModuleManager(object):
|
||||||
attr2 = getattr(self.have, key)
|
attr2 = getattr(self.have, key)
|
||||||
if attr1 != attr2:
|
if attr1 != attr2:
|
||||||
changed[key] = attr1
|
changed[key] = attr1
|
||||||
self.changes = Parameters(changed)
|
self.changes = Parameters(params=changed)
|
||||||
if changed:
|
if changed:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -137,13 +145,13 @@ class ModuleManager(object):
|
||||||
def read_current_from_device(self):
|
def read_current_from_device(self):
|
||||||
resource = self.client.api.tm.sys.global_settings.load()
|
resource = self.client.api.tm.sys.global_settings.load()
|
||||||
result = resource.attrs
|
result = resource.attrs
|
||||||
return Parameters(result)
|
return Parameters(params=result)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.have = self.read_current_from_device()
|
self.have = self.read_current_from_device()
|
||||||
if not self.should_update():
|
if not self.should_update():
|
||||||
return False
|
return False
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.update_on_device()
|
self.update_on_device()
|
||||||
return True
|
return True
|
||||||
|
@ -166,46 +174,35 @@ class ModuleManager(object):
|
||||||
class ArgumentSpec(object):
|
class ArgumentSpec(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.supports_check_mode = True
|
self.supports_check_mode = True
|
||||||
self.argument_spec = dict(
|
argument_spec = dict(
|
||||||
hostname=dict(
|
hostname=dict(
|
||||||
required=True,
|
required=True
|
||||||
default=None,
|
|
||||||
type='str'
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.f5_product_name = 'bigip'
|
self.argument_spec = {}
|
||||||
|
self.argument_spec.update(f5_argument_spec)
|
||||||
|
self.argument_spec.update(argument_spec)
|
||||||
def cleanup_tokens(client):
|
|
||||||
try:
|
|
||||||
resource = client.api.shared.authz.tokens_s.token.load(
|
|
||||||
name=client.api.icrs.token
|
|
||||||
)
|
|
||||||
resource.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not HAS_F5SDK:
|
|
||||||
raise F5ModuleError("The python f5-sdk module is required")
|
|
||||||
|
|
||||||
spec = ArgumentSpec()
|
spec = ArgumentSpec()
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
argument_spec=spec.argument_spec,
|
||||||
supports_check_mode=spec.supports_check_mode,
|
supports_check_mode=spec.supports_check_mode
|
||||||
f5_product_name=spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
if not HAS_F5SDK:
|
||||||
|
module.fail_json(msg="The python f5-sdk module is required")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mm = ModuleManager(client)
|
client = F5Client(**module.params)
|
||||||
|
mm = ModuleManager(module=module, client=client)
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.exit_json(**results)
|
module.exit_json(**results)
|
||||||
except F5ModuleError as e:
|
except F5ModuleError as e:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.fail_json(msg=str(e))
|
module.fail_json(msg=str(e))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -82,11 +82,6 @@ options:
|
||||||
over any similar setting in the iApp Server payload that you provide in
|
over any similar setting in the iApp Server payload that you provide in
|
||||||
the C(parameters) field.
|
the C(parameters) field.
|
||||||
version_added: 2.5
|
version_added: 2.5
|
||||||
notes:
|
|
||||||
- Requires the f5-sdk Python package on the host. This is as easy as pip
|
|
||||||
install f5-sdk.
|
|
||||||
requirements:
|
|
||||||
- f5-sdk
|
|
||||||
extends_documentation_fragment: f5
|
extends_documentation_fragment: f5
|
||||||
author:
|
author:
|
||||||
- Tim Rupp (@caphrim007)
|
- Tim Rupp (@caphrim007)
|
||||||
|
@ -215,17 +210,39 @@ RETURN = r'''
|
||||||
# only common fields returned
|
# only common fields returned
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Parameters
|
from ansible.module_utils.basic import env_fallback
|
||||||
from ansible.module_utils.f5_utils import HAS_F5SDK
|
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
|
||||||
from ansible.module_utils.six import iteritems
|
from ansible.module_utils.six import iteritems
|
||||||
from collections import defaultdict
|
|
||||||
|
HAS_DEVEL_IMPORTS = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
# 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:
|
except ImportError:
|
||||||
HAS_F5SDK = False
|
# 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:
|
||||||
|
HAS_F5SDK = False
|
||||||
|
|
||||||
|
|
||||||
class Parameters(AnsibleF5Parameters):
|
class Parameters(AnsibleF5Parameters):
|
||||||
|
@ -241,35 +258,6 @@ class Parameters(AnsibleF5Parameters):
|
||||||
]
|
]
|
||||||
updatables = ['tables', 'variables', 'lists', 'strict_updates', 'traffic_group']
|
updatables = ['tables', 'variables', 'lists', 'strict_updates', 'traffic_group']
|
||||||
|
|
||||||
def __init__(self, params=None):
|
|
||||||
self._values = defaultdict(lambda: None)
|
|
||||||
if params:
|
|
||||||
self.update(params=params)
|
|
||||||
self._values['__warnings'] = []
|
|
||||||
|
|
||||||
def update(self, params=None):
|
|
||||||
if params:
|
|
||||||
for k, v in iteritems(params):
|
|
||||||
if self.api_map is not None and k in self.api_map:
|
|
||||||
map_key = self.api_map[k]
|
|
||||||
else:
|
|
||||||
map_key = k
|
|
||||||
|
|
||||||
# Handle weird API parameters like `dns.proxy.__iter__` by
|
|
||||||
# using a map provided by the module developer
|
|
||||||
class_attr = getattr(type(self), map_key, None)
|
|
||||||
if isinstance(class_attr, property):
|
|
||||||
# There is a mapped value for the api_map key
|
|
||||||
if class_attr.fset is None:
|
|
||||||
# If the mapped value does not have an associated setter
|
|
||||||
self._values[map_key] = v
|
|
||||||
else:
|
|
||||||
# The mapped value has a setter
|
|
||||||
setattr(self, map_key, v)
|
|
||||||
else:
|
|
||||||
# If the mapped value is not a @property
|
|
||||||
self._values[map_key] = v
|
|
||||||
|
|
||||||
def _fqdn_name(self, value):
|
def _fqdn_name(self, value):
|
||||||
if value is not None and not value.startswith('/'):
|
if value is not None and not value.startswith('/'):
|
||||||
return '/{0}/{1}'.format(self.partition, value)
|
return '/{0}/{1}'.format(self.partition, value)
|
||||||
|
@ -282,16 +270,6 @@ class Parameters(AnsibleF5Parameters):
|
||||||
result = self._filter_params(result)
|
result = self._filter_params(result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def api_params(self):
|
|
||||||
result = {}
|
|
||||||
for api_attribute in self.api_attributes:
|
|
||||||
if self.api_map is not None and api_attribute in self.api_map:
|
|
||||||
result[api_attribute] = getattr(self, self.api_map[api_attribute])
|
|
||||||
else:
|
|
||||||
result[api_attribute] = getattr(self, api_attribute)
|
|
||||||
result = self._filter_params(result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tables(self):
|
def tables(self):
|
||||||
result = []
|
result = []
|
||||||
|
@ -489,10 +467,11 @@ class Difference(object):
|
||||||
|
|
||||||
|
|
||||||
class ModuleManager(object):
|
class ModuleManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
|
self.client = kwargs.get('client', None)
|
||||||
self.have = None
|
self.have = None
|
||||||
self.want = Parameters(self.client.module.params)
|
self.want = Parameters(params=self.module.params)
|
||||||
self.changes = Changes()
|
self.changes = Changes()
|
||||||
|
|
||||||
def _set_changed_options(self):
|
def _set_changed_options(self):
|
||||||
|
@ -501,7 +480,7 @@ class ModuleManager(object):
|
||||||
if getattr(self.want, key) is not None:
|
if getattr(self.want, key) is not None:
|
||||||
changed[key] = getattr(self.want, key)
|
changed[key] = getattr(self.want, key)
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = Changes(changed)
|
self.changes = Changes(params=changed)
|
||||||
|
|
||||||
def _update_changed_options(self):
|
def _update_changed_options(self):
|
||||||
diff = Difference(self.want, self.have)
|
diff = Difference(self.want, self.have)
|
||||||
|
@ -517,7 +496,7 @@ class ModuleManager(object):
|
||||||
else:
|
else:
|
||||||
changed[k] = change
|
changed[k] = change
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = Changes(changed)
|
self.changes = Changes(params=changed)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -556,7 +535,7 @@ class ModuleManager(object):
|
||||||
self._set_changed_options()
|
self._set_changed_options()
|
||||||
if self.want.traffic_group is None and self.want.trafficGroup is None:
|
if self.want.traffic_group is None and self.want.trafficGroup is None:
|
||||||
self.want.update({'traffic_group': '/Common/traffic-group-1'})
|
self.want.update({'traffic_group': '/Common/traffic-group-1'})
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.create_on_device()
|
self.create_on_device()
|
||||||
return True
|
return True
|
||||||
|
@ -565,7 +544,7 @@ class ModuleManager(object):
|
||||||
self.have = self.read_current_from_device()
|
self.have = self.read_current_from_device()
|
||||||
if not self.should_update() and not self.want.force:
|
if not self.should_update() and not self.want.force:
|
||||||
return False
|
return False
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.update_on_device()
|
self.update_on_device()
|
||||||
return True
|
return True
|
||||||
|
@ -591,7 +570,7 @@ class ModuleManager(object):
|
||||||
partition=self.want.partition
|
partition=self.want.partition
|
||||||
).to_dict()
|
).to_dict()
|
||||||
result.pop('_meta_data', None)
|
result.pop('_meta_data', None)
|
||||||
return Parameters(result)
|
return Parameters(params=result)
|
||||||
|
|
||||||
def create_on_device(self):
|
def create_on_device(self):
|
||||||
params = self.want.api_params()
|
params = self.want.api_params()
|
||||||
|
@ -607,7 +586,7 @@ class ModuleManager(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.remove_from_device()
|
self.remove_from_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -626,7 +605,7 @@ class ModuleManager(object):
|
||||||
class ArgumentSpec(object):
|
class ArgumentSpec(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.supports_check_mode = True
|
self.supports_check_mode = True
|
||||||
self.argument_spec = dict(
|
argument_spec = dict(
|
||||||
name=dict(required=True),
|
name=dict(required=True),
|
||||||
template=dict(),
|
template=dict(),
|
||||||
parameters=dict(
|
parameters=dict(
|
||||||
|
@ -643,41 +622,36 @@ class ArgumentSpec(object):
|
||||||
strict_updates=dict(
|
strict_updates=dict(
|
||||||
type='bool'
|
type='bool'
|
||||||
),
|
),
|
||||||
traffic_group=dict()
|
traffic_group=dict(),
|
||||||
|
partition=dict(
|
||||||
|
default='Common',
|
||||||
|
fallback=(env_fallback, ['F5_PARTITION'])
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.f5_product_name = 'bigip'
|
self.argument_spec = {}
|
||||||
|
self.argument_spec.update(f5_argument_spec)
|
||||||
|
self.argument_spec.update(argument_spec)
|
||||||
def cleanup_tokens(client):
|
|
||||||
try:
|
|
||||||
resource = client.api.shared.authz.tokens_s.token.load(
|
|
||||||
name=client.api.icrs.token
|
|
||||||
)
|
|
||||||
resource.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
spec = ArgumentSpec()
|
spec = ArgumentSpec()
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
argument_spec=spec.argument_spec,
|
||||||
supports_check_mode=spec.supports_check_mode,
|
supports_check_mode=spec.supports_check_mode
|
||||||
f5_product_name=spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
if not HAS_F5SDK:
|
||||||
|
module.fail_json(msg="The python f5-sdk module is required")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not HAS_F5SDK:
|
client = F5Client(**module.params)
|
||||||
raise F5ModuleError("The python f5-sdk module is required")
|
mm = ModuleManager(module=module, client=client)
|
||||||
|
|
||||||
mm = ModuleManager(client)
|
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.exit_json(**results)
|
module.exit_json(**results)
|
||||||
except F5ModuleError as e:
|
except F5ModuleError as e:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.fail_json(msg=str(e))
|
module.fail_json(msg=str(e))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -39,9 +39,7 @@ options:
|
||||||
using it. This will not update the running service though. Use
|
using it. This will not update the running service though. Use
|
||||||
C(bigip_iapp_service) to do that. When C(no), will update the iApp
|
C(bigip_iapp_service) to do that. When C(no), will update the iApp
|
||||||
only if there are no iApp services using the template.
|
only if there are no iApp services using the template.
|
||||||
choices:
|
type: bool
|
||||||
- yes
|
|
||||||
- no
|
|
||||||
name:
|
name:
|
||||||
description:
|
description:
|
||||||
- The name of the iApp template that you want to delete. This option
|
- The name of the iApp template that you want to delete. This option
|
||||||
|
@ -65,9 +63,6 @@ options:
|
||||||
description:
|
description:
|
||||||
- Device partition to manage resources on.
|
- Device partition to manage resources on.
|
||||||
default: Common
|
default: Common
|
||||||
notes:
|
|
||||||
- Requires the f5-sdk Python package on the host. This is as easy as pip
|
|
||||||
install f5-sdk.
|
|
||||||
extends_documentation_fragment: f5
|
extends_documentation_fragment: f5
|
||||||
author:
|
author:
|
||||||
- Tim Rupp (@caphrim007)
|
- Tim Rupp (@caphrim007)
|
||||||
|
@ -110,15 +105,40 @@ RETURN = r'''
|
||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Parameters
|
from ansible.module_utils.basic import env_fallback
|
||||||
from ansible.module_utils.f5_utils import HAS_F5SDK
|
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
HAS_DEVEL_IMPORTS = False
|
||||||
from ansible.module_utils.six import iteritems
|
|
||||||
from collections import defaultdict
|
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:
|
||||||
|
HAS_F5SDK = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
|
||||||
from f5.utils.iapp_parser import NonextantTemplateNameException
|
from f5.utils.iapp_parser import NonextantTemplateNameException
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_F5SDK = False
|
HAS_F5SDK = False
|
||||||
|
@ -133,34 +153,6 @@ class Parameters(AnsibleF5Parameters):
|
||||||
api_attributes = []
|
api_attributes = []
|
||||||
returnables = []
|
returnables = []
|
||||||
|
|
||||||
def __init__(self, params=None):
|
|
||||||
self._values = defaultdict(lambda: None)
|
|
||||||
if params:
|
|
||||||
self.update(params=params)
|
|
||||||
|
|
||||||
def update(self, params=None):
|
|
||||||
if params:
|
|
||||||
for k, v in iteritems(params):
|
|
||||||
if self.api_map is not None and k in self.api_map:
|
|
||||||
map_key = self.api_map[k]
|
|
||||||
else:
|
|
||||||
map_key = k
|
|
||||||
|
|
||||||
# Handle weird API parameters like `dns.proxy.__iter__` by
|
|
||||||
# using a map provided by the module developer
|
|
||||||
class_attr = getattr(type(self), map_key, None)
|
|
||||||
if isinstance(class_attr, property):
|
|
||||||
# There is a mapped value for the api_map key
|
|
||||||
if class_attr.fset is None:
|
|
||||||
# If the mapped value does not have an associated setter
|
|
||||||
self._values[map_key] = v
|
|
||||||
else:
|
|
||||||
# The mapped value has a setter
|
|
||||||
setattr(self, map_key, v)
|
|
||||||
else:
|
|
||||||
# If the mapped value is not a @property
|
|
||||||
self._values[map_key] = v
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
if self._values['name']:
|
if self._values['name']:
|
||||||
|
@ -198,16 +190,6 @@ class Parameters(AnsibleF5Parameters):
|
||||||
pass
|
pass
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def api_params(self):
|
|
||||||
result = {}
|
|
||||||
for api_attribute in self.api_attributes:
|
|
||||||
if self.api_map is not None and api_attribute in self.api_map:
|
|
||||||
result[api_attribute] = getattr(self, self.api_map[api_attribute])
|
|
||||||
else:
|
|
||||||
result[api_attribute] = getattr(self, api_attribute)
|
|
||||||
result = self._filter_params(result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _squash_template_name_prefix(self):
|
def _squash_template_name_prefix(self):
|
||||||
"""Removes the template name prefix
|
"""Removes the template name prefix
|
||||||
|
|
||||||
|
@ -252,9 +234,11 @@ class Parameters(AnsibleF5Parameters):
|
||||||
|
|
||||||
|
|
||||||
class ModuleManager(object):
|
class ModuleManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
self.want = Parameters(self.client.module.params)
|
self.client = kwargs.get('client', None)
|
||||||
|
self.have = None
|
||||||
|
self.want = Parameters(params=self.module.params)
|
||||||
self.changes = Parameters()
|
self.changes = Parameters()
|
||||||
|
|
||||||
def exec_module(self):
|
def exec_module(self):
|
||||||
|
@ -290,7 +274,7 @@ class ModuleManager(object):
|
||||||
if not self.want.force and self.template_in_use():
|
if not self.want.force and self.template_in_use():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
self._remove_iapp_checksum()
|
self._remove_iapp_checksum()
|
||||||
|
@ -314,7 +298,7 @@ class ModuleManager(object):
|
||||||
partition=self.want.partition
|
partition=self.want.partition
|
||||||
)
|
)
|
||||||
result = resource.attrs
|
result = resource.attrs
|
||||||
return Parameters(result)
|
return Parameters(params=result)
|
||||||
|
|
||||||
def absent(self):
|
def absent(self):
|
||||||
changed = False
|
changed = False
|
||||||
|
@ -392,7 +376,7 @@ class ModuleManager(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.create_on_device()
|
self.create_on_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -419,7 +403,7 @@ class ModuleManager(object):
|
||||||
raise F5ModuleError(output.commandResult)
|
raise F5ModuleError(output.commandResult)
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.remove_from_device()
|
self.remove_from_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -437,7 +421,7 @@ class ModuleManager(object):
|
||||||
class ArgumentSpec(object):
|
class ArgumentSpec(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.supports_check_mode = True
|
self.supports_check_mode = True
|
||||||
self.argument_spec = dict(
|
argument_spec = dict(
|
||||||
name=dict(),
|
name=dict(),
|
||||||
state=dict(
|
state=dict(
|
||||||
default='present',
|
default='present',
|
||||||
|
@ -446,41 +430,36 @@ class ArgumentSpec(object):
|
||||||
force=dict(
|
force=dict(
|
||||||
type='bool'
|
type='bool'
|
||||||
),
|
),
|
||||||
content=dict()
|
content=dict(),
|
||||||
|
partition=dict(
|
||||||
|
default='Common',
|
||||||
|
fallback=(env_fallback, ['F5_PARTITION'])
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.f5_product_name = 'bigip'
|
self.argument_spec = {}
|
||||||
|
self.argument_spec.update(f5_argument_spec)
|
||||||
|
self.argument_spec.update(argument_spec)
|
||||||
def cleanup_tokens(client):
|
|
||||||
try:
|
|
||||||
resource = client.api.shared.authz.tokens_s.token.load(
|
|
||||||
name=client.api.icrs.token
|
|
||||||
)
|
|
||||||
resource.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
spec = ArgumentSpec()
|
spec = ArgumentSpec()
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
argument_spec=spec.argument_spec,
|
||||||
supports_check_mode=spec.supports_check_mode,
|
supports_check_mode=spec.supports_check_mode
|
||||||
f5_product_name=spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
if not HAS_F5SDK:
|
||||||
|
module.fail_json(msg="The python f5-sdk module is required")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not HAS_F5SDK:
|
client = F5Client(**module.params)
|
||||||
raise F5ModuleError("The python f5-sdk module is required")
|
mm = ModuleManager(module=module, client=client)
|
||||||
|
|
||||||
mm = ModuleManager(client)
|
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.exit_json(**results)
|
module.exit_json(**results)
|
||||||
except F5ModuleError as e:
|
except F5ModuleError as e:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.fail_json(msg=str(e))
|
module.fail_json(msg=str(e))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -37,8 +37,6 @@ options:
|
||||||
- present
|
- present
|
||||||
- absent
|
- absent
|
||||||
notes:
|
notes:
|
||||||
- Requires the f5-sdk Python package on the host. This is as easy as pip
|
|
||||||
install f5-sdk.
|
|
||||||
- Requires the rpm tool be installed on the host. This can be accomplished through
|
- Requires the rpm tool be installed on the host. This can be accomplished through
|
||||||
different ways on each platform. On Debian based systems with C(apt);
|
different ways on each platform. On Debian based systems with C(apt);
|
||||||
C(apt-get install rpm). On Mac with C(brew); C(brew install rpm).
|
C(apt-get install rpm). On Mac with C(brew); C(brew install rpm).
|
||||||
|
@ -46,7 +44,6 @@ notes:
|
||||||
- Requires BIG-IP >= 12.1.0 because the required functionality is missing
|
- Requires BIG-IP >= 12.1.0 because the required functionality is missing
|
||||||
on versions earlier than that.
|
on versions earlier than that.
|
||||||
requirements:
|
requirements:
|
||||||
- f5-sdk >= 2.2.3
|
|
||||||
- Requires BIG-IP >= 12.1.0
|
- Requires BIG-IP >= 12.1.0
|
||||||
- The 'rpm' tool installed on the Ansible controller
|
- The 'rpm' tool installed on the Ansible controller
|
||||||
extends_documentation_fragment: f5
|
extends_documentation_fragment: f5
|
||||||
|
@ -91,16 +88,38 @@ import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Parameters
|
|
||||||
from ansible.module_utils.f5_utils import HAS_F5SDK
|
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
|
HAS_DEVEL_IMPORTS = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
# 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:
|
except ImportError:
|
||||||
HAS_F5SDK = False
|
# 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:
|
||||||
|
HAS_F5SDK = False
|
||||||
|
|
||||||
|
|
||||||
class Parameters(AnsibleF5Parameters):
|
class Parameters(AnsibleF5Parameters):
|
||||||
|
@ -162,9 +181,10 @@ class Parameters(AnsibleF5Parameters):
|
||||||
|
|
||||||
|
|
||||||
class ModuleManager(object):
|
class ModuleManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
self.want = Parameters(self.client.module.params)
|
self.client = kwargs.get('client', None)
|
||||||
|
self.want = Parameters(params=self.module.params)
|
||||||
self.changes = Parameters()
|
self.changes = Parameters()
|
||||||
|
|
||||||
def exec_module(self):
|
def exec_module(self):
|
||||||
|
@ -230,12 +250,17 @@ class ModuleManager(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
if not os.path.exists(self.want.package):
|
if not os.path.exists(self.want.package):
|
||||||
raise F5ModuleError(
|
if self.want.package.startswith('/'):
|
||||||
"The specified iAppLX package was not found."
|
raise F5ModuleError(
|
||||||
)
|
"The specified iAppLX package was not found at {0}.".format(self.want.package)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise F5ModuleError(
|
||||||
|
"The specified iAppLX package was not found in {0}.".format(os.getcwd())
|
||||||
|
)
|
||||||
self.upload_to_device()
|
self.upload_to_device()
|
||||||
self.create_on_device()
|
self.create_on_device()
|
||||||
self.enable_iapplx_on_device()
|
self.enable_iapplx_on_device()
|
||||||
|
@ -271,7 +296,7 @@ class ModuleManager(object):
|
||||||
raise F5ModuleError(task.errorMessage)
|
raise F5ModuleError(task.errorMessage)
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.remove_from_device()
|
self.remove_from_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -307,50 +332,42 @@ class ModuleManager(object):
|
||||||
class ArgumentSpec(object):
|
class ArgumentSpec(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.supports_check_mode = True
|
self.supports_check_mode = True
|
||||||
self.argument_spec = dict(
|
argument_spec = dict(
|
||||||
state=dict(
|
state=dict(
|
||||||
default='present',
|
default='present',
|
||||||
choices=['present', 'absent']
|
choices=['present', 'absent']
|
||||||
),
|
),
|
||||||
package=dict()
|
package=dict()
|
||||||
)
|
)
|
||||||
self.f5_product_name = 'bigip'
|
self.argument_spec = {}
|
||||||
|
self.argument_spec.update(f5_argument_spec)
|
||||||
|
self.argument_spec.update(argument_spec)
|
||||||
self.required_if = [
|
self.required_if = [
|
||||||
['state', 'present', ['package']]
|
['state', 'present', ['package']]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def cleanup_tokens(client):
|
|
||||||
try:
|
|
||||||
resource = client.api.shared.authz.tokens_s.token.load(
|
|
||||||
name=client.api.icrs.token
|
|
||||||
)
|
|
||||||
resource.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not HAS_F5SDK:
|
|
||||||
raise F5ModuleError("The python f5-sdk module is required")
|
|
||||||
|
|
||||||
spec = ArgumentSpec()
|
spec = ArgumentSpec()
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
argument_spec=spec.argument_spec,
|
||||||
supports_check_mode=spec.supports_check_mode,
|
supports_check_mode=spec.supports_check_mode,
|
||||||
f5_product_name=spec.f5_product_name,
|
|
||||||
required_if=spec.required_if
|
required_if=spec.required_if
|
||||||
)
|
)
|
||||||
|
if not HAS_F5SDK:
|
||||||
|
module.fail_json(msg="The python f5-sdk module is required")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mm = ModuleManager(client)
|
client = F5Client(**module.params)
|
||||||
|
mm = ModuleManager(module=module, client=client)
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.exit_json(**results)
|
module.exit_json(**results)
|
||||||
except F5ModuleError as e:
|
except F5ModuleError as e:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.fail_json(msg=str(e))
|
module.fail_json(msg=str(e))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -54,12 +54,7 @@ options:
|
||||||
- Device partition to manage resources on.
|
- Device partition to manage resources on.
|
||||||
default: Common
|
default: Common
|
||||||
version_added: 2.5
|
version_added: 2.5
|
||||||
notes:
|
|
||||||
- Requires the f5-sdk Python package on the host. This is as easy as
|
|
||||||
pip install f5-sdk.
|
|
||||||
extends_documentation_fragment: f5
|
extends_documentation_fragment: f5
|
||||||
requirements:
|
|
||||||
- f5-sdk
|
|
||||||
author:
|
author:
|
||||||
- Tim Rupp (@caphrim007)
|
- Tim Rupp (@caphrim007)
|
||||||
'''
|
'''
|
||||||
|
@ -108,15 +103,38 @@ content:
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Parameters
|
from ansible.module_utils.basic import env_fallback
|
||||||
from ansible.module_utils.f5_utils import HAS_F5SDK
|
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
HAS_DEVEL_IMPORTS = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
# 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:
|
except ImportError:
|
||||||
HAS_F5SDK = False
|
# 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:
|
||||||
|
HAS_F5SDK = False
|
||||||
|
|
||||||
|
|
||||||
class Parameters(AnsibleF5Parameters):
|
class Parameters(AnsibleF5Parameters):
|
||||||
|
@ -146,16 +164,6 @@ class Parameters(AnsibleF5Parameters):
|
||||||
pass
|
pass
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def api_params(self):
|
|
||||||
result = {}
|
|
||||||
for api_attribute in self.api_attributes:
|
|
||||||
if self.api_map is not None and api_attribute in self.api_map:
|
|
||||||
result[api_attribute] = getattr(self, self.api_map[api_attribute])
|
|
||||||
else:
|
|
||||||
result[api_attribute] = getattr(self, api_attribute)
|
|
||||||
result = self._filter_params(result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def content(self):
|
def content(self):
|
||||||
if self._values['content'] is None:
|
if self._values['content'] is None:
|
||||||
|
@ -183,13 +191,15 @@ class Parameters(AnsibleF5Parameters):
|
||||||
|
|
||||||
|
|
||||||
class ModuleManager(object):
|
class ModuleManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.client = kwargs.get('client', None)
|
||||||
|
self.module = kwargs.get('module', None)
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
def exec_module(self):
|
def exec_module(self):
|
||||||
if self.client.module.params['module'] == 'ltm':
|
if self.module.params['module'] == 'ltm':
|
||||||
manager = self.get_manager('ltm')
|
manager = self.get_manager('ltm')
|
||||||
elif self.client.module.params['module'] == 'gtm':
|
elif self.module.params['module'] == 'gtm':
|
||||||
manager = self.get_manager('gtm')
|
manager = self.get_manager('gtm')
|
||||||
else:
|
else:
|
||||||
raise F5ModuleError(
|
raise F5ModuleError(
|
||||||
|
@ -199,15 +209,16 @@ class ModuleManager(object):
|
||||||
|
|
||||||
def get_manager(self, type):
|
def get_manager(self, type):
|
||||||
if type == 'ltm':
|
if type == 'ltm':
|
||||||
return LtmManager(self.client)
|
return LtmManager(**self.kwargs)
|
||||||
elif type == 'gtm':
|
elif type == 'gtm':
|
||||||
return GtmManager(self.client)
|
return GtmManager(**self.kwargs)
|
||||||
|
|
||||||
|
|
||||||
class BaseManager(object):
|
class BaseManager(object):
|
||||||
def __init__(self, client):
|
def __init__(self, *args, **kwargs):
|
||||||
self.client = client
|
self.module = kwargs.get('module', None)
|
||||||
self.want = Parameters(self.client.module.params)
|
self.client = kwargs.get('client', None)
|
||||||
|
self.want = Parameters(params=self.module.params)
|
||||||
self.changes = Parameters()
|
self.changes = Parameters()
|
||||||
|
|
||||||
def exec_module(self):
|
def exec_module(self):
|
||||||
|
@ -234,7 +245,7 @@ class BaseManager(object):
|
||||||
if getattr(self.want, key) is not None:
|
if getattr(self.want, key) is not None:
|
||||||
changed[key] = getattr(self.want, key)
|
changed[key] = getattr(self.want, key)
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = Parameters(changed)
|
self.changes = Parameters(params=changed)
|
||||||
|
|
||||||
def _update_changed_options(self):
|
def _update_changed_options(self):
|
||||||
changed = {}
|
changed = {}
|
||||||
|
@ -245,7 +256,7 @@ class BaseManager(object):
|
||||||
if attr1 != attr2:
|
if attr1 != attr2:
|
||||||
changed[key] = attr1
|
changed[key] = attr1
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = Parameters(changed)
|
self.changes = Parameters(params=changed)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -261,7 +272,7 @@ class BaseManager(object):
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
self._set_changed_options()
|
self._set_changed_options()
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.create_on_device()
|
self.create_on_device()
|
||||||
if not self.exists():
|
if not self.exists():
|
||||||
|
@ -278,7 +289,7 @@ class BaseManager(object):
|
||||||
self.have = self.read_current_from_device()
|
self.have = self.read_current_from_device()
|
||||||
if not self.should_update():
|
if not self.should_update():
|
||||||
return False
|
return False
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.update_on_device()
|
self.update_on_device()
|
||||||
return True
|
return True
|
||||||
|
@ -289,7 +300,7 @@ class BaseManager(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
if self.client.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.remove_from_device()
|
self.remove_from_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -328,7 +339,7 @@ class LtmManager(BaseManager):
|
||||||
partition=self.want.partition
|
partition=self.want.partition
|
||||||
)
|
)
|
||||||
result = resource.attrs
|
result = resource.attrs
|
||||||
return Parameters(result)
|
return Parameters(params=result)
|
||||||
|
|
||||||
def remove_from_device(self):
|
def remove_from_device(self):
|
||||||
resource = self.client.api.tm.ltm.rules.rule.load(
|
resource = self.client.api.tm.ltm.rules.rule.load(
|
||||||
|
@ -345,7 +356,7 @@ class GtmManager(BaseManager):
|
||||||
partition=self.want.partition
|
partition=self.want.partition
|
||||||
)
|
)
|
||||||
result = resource.attrs
|
result = resource.attrs
|
||||||
return Parameters(result)
|
return Parameters(params=result)
|
||||||
|
|
||||||
def remove_from_device(self):
|
def remove_from_device(self):
|
||||||
resource = self.client.api.tm.gtm.rules.rule.load(
|
resource = self.client.api.tm.gtm.rules.rule.load(
|
||||||
|
@ -382,7 +393,7 @@ class GtmManager(BaseManager):
|
||||||
class ArgumentSpec(object):
|
class ArgumentSpec(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.supports_check_mode = True
|
self.supports_check_mode = True
|
||||||
self.argument_spec = dict(
|
argument_spec = dict(
|
||||||
content=dict(
|
content=dict(
|
||||||
required=False,
|
required=False,
|
||||||
default=None
|
default=None
|
||||||
|
@ -395,45 +406,44 @@ class ArgumentSpec(object):
|
||||||
module=dict(
|
module=dict(
|
||||||
required=True,
|
required=True,
|
||||||
choices=['gtm', 'ltm']
|
choices=['gtm', 'ltm']
|
||||||
|
),
|
||||||
|
state=dict(
|
||||||
|
default='present',
|
||||||
|
choices=['present', 'absent']
|
||||||
|
),
|
||||||
|
partition=dict(
|
||||||
|
default='Common',
|
||||||
|
fallback=(env_fallback, ['F5_PARTITION'])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
self.argument_spec = {}
|
||||||
|
self.argument_spec.update(f5_argument_spec)
|
||||||
|
self.argument_spec.update(argument_spec)
|
||||||
self.mutually_exclusive = [
|
self.mutually_exclusive = [
|
||||||
['content', 'src']
|
['content', 'src']
|
||||||
]
|
]
|
||||||
self.f5_product_name = 'bigip'
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup_tokens(client):
|
|
||||||
try:
|
|
||||||
resource = client.api.shared.authz.tokens_s.token.load(
|
|
||||||
name=client.api.icrs.token
|
|
||||||
)
|
|
||||||
resource.delete()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
spec = ArgumentSpec()
|
spec = ArgumentSpec()
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
argument_spec=spec.argument_spec,
|
||||||
supports_check_mode=spec.supports_check_mode,
|
supports_check_mode=spec.supports_check_mode,
|
||||||
f5_product_name=spec.f5_product_name,
|
mutually_exclusive=spec.mutually_exclusive
|
||||||
mutually_exclusive=spec.mutually_exclusive,
|
|
||||||
)
|
)
|
||||||
|
if not HAS_F5SDK:
|
||||||
|
module.fail_json(msg="The python f5-sdk module is required")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not HAS_F5SDK:
|
client = F5Client(**module.params)
|
||||||
raise F5ModuleError("The python f5-sdk module is required")
|
mm = ModuleManager(module=module, client=client)
|
||||||
|
|
||||||
mm = ModuleManager(client)
|
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.exit_json(**results)
|
module.exit_json(**results)
|
||||||
except F5ModuleError as e:
|
except F5ModuleError as e:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
client.module.fail_json(msg=str(e))
|
module.fail_json(msg=str(e))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -41,13 +41,6 @@ lib/ansible/modules/net_tools/cloudflare_dns.py E317
|
||||||
lib/ansible/modules/net_tools/haproxy.py E317
|
lib/ansible/modules/net_tools/haproxy.py E317
|
||||||
lib/ansible/modules/net_tools/omapi_host.py E317
|
lib/ansible/modules/net_tools/omapi_host.py E317
|
||||||
lib/ansible/modules/network/cloudengine/ce_reboot.py E317
|
lib/ansible/modules/network/cloudengine/ce_reboot.py E317
|
||||||
lib/ansible/modules/network/f5/bigip_gtm_datacenter.py E321
|
|
||||||
lib/ansible/modules/network/f5/bigip_gtm_facts.py E321
|
|
||||||
lib/ansible/modules/network/f5/bigip_gtm_pool.py E321
|
|
||||||
lib/ansible/modules/network/f5/bigip_gtm_server.py E321
|
|
||||||
lib/ansible/modules/network/f5/bigip_gtm_wide_ip.py E321
|
|
||||||
lib/ansible/modules/network/f5/bigip_hostname.py E317
|
|
||||||
lib/ansible/modules/network/f5/bigip_iapplx_package.py E321
|
|
||||||
lib/ansible/modules/network/f5/bigip_partition.py E321
|
lib/ansible/modules/network/f5/bigip_partition.py E321
|
||||||
lib/ansible/modules/network/f5/bigip_policy.py E321
|
lib/ansible/modules/network/f5/bigip_policy.py E321
|
||||||
lib/ansible/modules/network/f5/bigip_policy_rule.py E321
|
lib/ansible/modules/network/f5/bigip_policy_rule.py E321
|
||||||
|
|
|
@ -17,14 +17,15 @@ if sys.version_info < (2, 7):
|
||||||
from ansible.compat.tests import unittest
|
from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import Mock
|
from ansible.compat.tests.mock import Mock
|
||||||
from ansible.compat.tests.mock import patch
|
from ansible.compat.tests.mock import patch
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from library.bigip_gtm_datacenter import ApiParameters
|
from library.bigip_gtm_datacenter import ApiParameters
|
||||||
from library.bigip_gtm_datacenter import ModuleParameters
|
from library.bigip_gtm_datacenter import ModuleParameters
|
||||||
from library.bigip_gtm_datacenter import ModuleManager
|
from library.bigip_gtm_datacenter import ModuleManager
|
||||||
from library.bigip_gtm_datacenter import ArgumentSpec
|
from library.bigip_gtm_datacenter import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
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
|
from test.unit.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
|
@ -32,7 +33,8 @@ except ImportError:
|
||||||
from ansible.modules.network.f5.bigip_gtm_datacenter import ModuleParameters
|
from ansible.modules.network.f5.bigip_gtm_datacenter import ModuleParameters
|
||||||
from ansible.modules.network.f5.bigip_gtm_datacenter import ModuleManager
|
from ansible.modules.network.f5.bigip_gtm_datacenter import ModuleManager
|
||||||
from ansible.modules.network.f5.bigip_gtm_datacenter import ArgumentSpec
|
from ansible.modules.network.f5.bigip_gtm_datacenter import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from units.modules.utils import set_module_args
|
from units.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
||||||
|
@ -68,19 +70,19 @@ class TestParameters(unittest.TestCase):
|
||||||
location='baz',
|
location='baz',
|
||||||
name='datacenter'
|
name='datacenter'
|
||||||
)
|
)
|
||||||
p = ModuleParameters(args)
|
p = ModuleParameters(params=args)
|
||||||
assert p.state == 'present'
|
assert p.state == 'present'
|
||||||
|
|
||||||
def test_api_parameters(self):
|
def test_api_parameters(self):
|
||||||
args = load_fixture('load_gtm_datacenter_default.json')
|
args = load_fixture('load_gtm_datacenter_default.json')
|
||||||
p = ApiParameters(args)
|
p = ApiParameters(params=args)
|
||||||
assert p.name == 'asd'
|
assert p.name == 'asd'
|
||||||
|
|
||||||
def test_module_parameters_state_present(self):
|
def test_module_parameters_state_present(self):
|
||||||
args = dict(
|
args = dict(
|
||||||
state='present'
|
state='present'
|
||||||
)
|
)
|
||||||
p = ModuleParameters(args)
|
p = ModuleParameters(params=args)
|
||||||
assert p.state == 'present'
|
assert p.state == 'present'
|
||||||
assert p.enabled is True
|
assert p.enabled is True
|
||||||
|
|
||||||
|
@ -88,14 +90,14 @@ class TestParameters(unittest.TestCase):
|
||||||
args = dict(
|
args = dict(
|
||||||
state='absent'
|
state='absent'
|
||||||
)
|
)
|
||||||
p = ModuleParameters(args)
|
p = ModuleParameters(params=args)
|
||||||
assert p.state == 'absent'
|
assert p.state == 'absent'
|
||||||
|
|
||||||
def test_module_parameters_state_enabled(self):
|
def test_module_parameters_state_enabled(self):
|
||||||
args = dict(
|
args = dict(
|
||||||
state='enabled'
|
state='enabled'
|
||||||
)
|
)
|
||||||
p = ModuleParameters(args)
|
p = ModuleParameters(params=args)
|
||||||
assert p.state == 'enabled'
|
assert p.state == 'enabled'
|
||||||
assert p.enabled is True
|
assert p.enabled is True
|
||||||
assert p.disabled is None
|
assert p.disabled is None
|
||||||
|
@ -104,14 +106,12 @@ class TestParameters(unittest.TestCase):
|
||||||
args = dict(
|
args = dict(
|
||||||
state='disabled'
|
state='disabled'
|
||||||
)
|
)
|
||||||
p = ModuleParameters(args)
|
p = ModuleParameters(params=args)
|
||||||
assert p.state == 'disabled'
|
assert p.state == 'disabled'
|
||||||
assert p.enabled is None
|
assert p.enabled is None
|
||||||
assert p.disabled is True
|
assert p.disabled is True
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestManager(unittest.TestCase):
|
class TestManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -126,12 +126,11 @@ class TestManager(unittest.TestCase):
|
||||||
name='foo'
|
name='foo'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(side_effect=[False, True])
|
mm.exists = Mock(side_effect=[False, True])
|
||||||
|
@ -150,12 +149,11 @@ class TestManager(unittest.TestCase):
|
||||||
name='foo'
|
name='foo'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(side_effect=[False, True])
|
mm.exists = Mock(side_effect=[False, True])
|
||||||
|
@ -175,12 +173,11 @@ class TestManager(unittest.TestCase):
|
||||||
name='foo'
|
name='foo'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(side_effect=[False, True])
|
mm.exists = Mock(side_effect=[False, True])
|
||||||
|
@ -200,15 +197,14 @@ class TestManager(unittest.TestCase):
|
||||||
name='foo'
|
name='foo'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
current = ApiParameters(load_fixture('load_gtm_datacenter_disabled.json'))
|
current = ApiParameters(params=load_fixture('load_gtm_datacenter_disabled.json'))
|
||||||
|
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(return_value=True)
|
mm.exists = Mock(return_value=True)
|
||||||
|
|
|
@ -17,7 +17,7 @@ if sys.version_info < (2, 7):
|
||||||
from ansible.compat.tests import unittest
|
from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import Mock
|
from ansible.compat.tests.mock import Mock
|
||||||
from ansible.compat.tests.mock import patch
|
from ansible.compat.tests.mock import patch
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.six import iteritems
|
from ansible.module_utils.six import iteritems
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -34,7 +34,8 @@ try:
|
||||||
from library.bigip_gtm_facts import TypedWideIpFactManager
|
from library.bigip_gtm_facts import TypedWideIpFactManager
|
||||||
from library.bigip_gtm_facts import UntypedWideIpFactManager
|
from library.bigip_gtm_facts import UntypedWideIpFactManager
|
||||||
from library.bigip_gtm_facts import ArgumentSpec
|
from library.bigip_gtm_facts import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from library.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from f5.bigip.tm.gtm.pool import A
|
from f5.bigip.tm.gtm.pool import A
|
||||||
from f5.utils.responses.handlers import Stats
|
from f5.utils.responses.handlers import Stats
|
||||||
from test.unit.modules.utils import set_module_args
|
from test.unit.modules.utils import set_module_args
|
||||||
|
@ -53,7 +54,8 @@ except ImportError:
|
||||||
from ansible.modules.network.f5.bigip_gtm_pool import TypedWideIpFactManager
|
from ansible.modules.network.f5.bigip_gtm_pool import TypedWideIpFactManager
|
||||||
from ansible.modules.network.f5.bigip_gtm_pool import UntypedWideIpFactManager
|
from ansible.modules.network.f5.bigip_gtm_pool import UntypedWideIpFactManager
|
||||||
from ansible.modules.network.f5.bigip_gtm_pool import ArgumentSpec
|
from ansible.modules.network.f5.bigip_gtm_pool import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from f5.bigip.tm.gtm.pool import A
|
from f5.bigip.tm.gtm.pool import A
|
||||||
from f5.utils.responses.handlers import Stats
|
from f5.utils.responses.handlers import Stats
|
||||||
from units.modules.utils import set_module_args
|
from units.modules.utils import set_module_args
|
||||||
|
@ -100,13 +102,11 @@ class TestParameters(unittest.TestCase):
|
||||||
include=['pool'],
|
include=['pool'],
|
||||||
filter='name.*'
|
filter='name.*'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.include == ['pool']
|
assert p.include == ['pool']
|
||||||
assert p.filter == 'name.*'
|
assert p.filter == 'name.*'
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestManager(unittest.TestCase):
|
class TestManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -125,23 +125,22 @@ class TestManager(unittest.TestCase):
|
||||||
collection = [FakeARecord(attrs=x) for x in fixture1['items']]
|
collection = [FakeARecord(attrs=x) for x in fixture1['items']]
|
||||||
stats = Stats(FakeStatResource(fixture2['entries']))
|
stats = Stats(FakeStatResource(fixture2['entries']))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tfm = TypedPoolFactManager(client)
|
tfm = TypedPoolFactManager(module=module)
|
||||||
tfm.read_collection_from_device = Mock(return_value=collection)
|
tfm.read_collection_from_device = Mock(return_value=collection)
|
||||||
tfm.read_stats_from_device = Mock(return_value=stats.stat)
|
tfm.read_stats_from_device = Mock(return_value=stats.stat)
|
||||||
|
|
||||||
tm = PoolFactManager(client)
|
tm = PoolFactManager(module=module)
|
||||||
tm.version_is_less_than_12 = Mock(return_value=False)
|
tm.version_is_less_than_12 = Mock(return_value=False)
|
||||||
tm.get_manager = Mock(return_value=tfm)
|
tm.get_manager = Mock(return_value=tfm)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
mm.gtm_provisioned = Mock(return_value=True)
|
mm.gtm_provisioned = Mock(return_value=True)
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ if sys.version_info < (2, 7):
|
||||||
from ansible.compat.tests import unittest
|
from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import Mock
|
from ansible.compat.tests.mock import Mock
|
||||||
from ansible.compat.tests.mock import patch
|
from ansible.compat.tests.mock import patch
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from library.bigip_gtm_pool import Parameters
|
from library.bigip_gtm_pool import Parameters
|
||||||
|
@ -25,7 +25,8 @@ try:
|
||||||
from library.bigip_gtm_pool import ArgumentSpec
|
from library.bigip_gtm_pool import ArgumentSpec
|
||||||
from library.bigip_gtm_pool import UntypedManager
|
from library.bigip_gtm_pool import UntypedManager
|
||||||
from library.bigip_gtm_pool import TypedManager
|
from library.bigip_gtm_pool import TypedManager
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
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
|
from test.unit.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
|
@ -34,7 +35,8 @@ except ImportError:
|
||||||
from ansible.modules.network.f5.bigip_gtm_pool import ArgumentSpec
|
from ansible.modules.network.f5.bigip_gtm_pool import ArgumentSpec
|
||||||
from ansible.modules.network.f5.bigip_gtm_pool import UntypedManager
|
from ansible.modules.network.f5.bigip_gtm_pool import UntypedManager
|
||||||
from ansible.modules.network.f5.bigip_gtm_pool import TypedManager
|
from ansible.modules.network.f5.bigip_gtm_pool import TypedManager
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from units.modules.utils import set_module_args
|
from units.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
||||||
|
@ -71,7 +73,7 @@ class TestParameters(unittest.TestCase):
|
||||||
fallback_ip='10.10.10.10',
|
fallback_ip='10.10.10.10',
|
||||||
type='a'
|
type='a'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.name == 'foo'
|
assert p.name == 'foo'
|
||||||
assert p.preferred_lb_method == 'topology'
|
assert p.preferred_lb_method == 'topology'
|
||||||
assert p.alternate_lb_method == 'ratio'
|
assert p.alternate_lb_method == 'ratio'
|
||||||
|
@ -87,7 +89,7 @@ class TestParameters(unittest.TestCase):
|
||||||
fallbackMode='fewest-hops',
|
fallbackMode='fewest-hops',
|
||||||
fallbackIp='10.10.10.10'
|
fallbackIp='10.10.10.10'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.name == 'foo'
|
assert p.name == 'foo'
|
||||||
assert p.preferred_lb_method == 'topology'
|
assert p.preferred_lb_method == 'topology'
|
||||||
assert p.alternate_lb_method == 'ratio'
|
assert p.alternate_lb_method == 'ratio'
|
||||||
|
@ -95,8 +97,6 @@ class TestParameters(unittest.TestCase):
|
||||||
assert p.fallback_ip == '10.10.10.10'
|
assert p.fallback_ip == '10.10.10.10'
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestUntypedManager(unittest.TestCase):
|
class TestUntypedManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -111,19 +111,18 @@ class TestUntypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = UntypedManager(client)
|
tm = UntypedManager(module=module)
|
||||||
tm.exists = Mock(side_effect=[False, True])
|
tm.exists = Mock(side_effect=[False, True])
|
||||||
tm.create_on_device = Mock(return_value=True)
|
tm.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=True)
|
mm.version_is_less_than_12 = Mock(return_value=True)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
mm.gtm_provisioned = Mock(return_value=True)
|
mm.gtm_provisioned = Mock(return_value=True)
|
||||||
|
@ -144,22 +143,21 @@ class TestUntypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
current = Parameters(load_fixture('load_gtm_pool_untyped_default.json'))
|
current = Parameters(params=load_fixture('load_gtm_pool_untyped_default.json'))
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = UntypedManager(client)
|
tm = UntypedManager(module=module)
|
||||||
tm.exists = Mock(side_effect=[True, True])
|
tm.exists = Mock(side_effect=[True, True])
|
||||||
tm.update_on_device = Mock(return_value=True)
|
tm.update_on_device = Mock(return_value=True)
|
||||||
tm.read_current_from_device = Mock(return_value=current)
|
tm.read_current_from_device = Mock(return_value=current)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=True)
|
mm.version_is_less_than_12 = Mock(return_value=True)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
mm.gtm_provisioned = Mock(return_value=True)
|
mm.gtm_provisioned = Mock(return_value=True)
|
||||||
|
@ -180,19 +178,18 @@ class TestUntypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = UntypedManager(client)
|
tm = UntypedManager(module=module)
|
||||||
tm.exists = Mock(side_effect=[True, False])
|
tm.exists = Mock(side_effect=[True, False])
|
||||||
tm.remove_from_device = Mock(return_value=True)
|
tm.remove_from_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=True)
|
mm.version_is_less_than_12 = Mock(return_value=True)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
mm.gtm_provisioned = Mock(return_value=True)
|
mm.gtm_provisioned = Mock(return_value=True)
|
||||||
|
@ -202,8 +199,6 @@ class TestUntypedManager(unittest.TestCase):
|
||||||
assert results['changed'] is True
|
assert results['changed'] is True
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestTypedManager(unittest.TestCase):
|
class TestTypedManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -219,19 +214,18 @@ class TestTypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = TypedManager(client)
|
tm = TypedManager(module=module)
|
||||||
tm.exists = Mock(side_effect=[False, True])
|
tm.exists = Mock(side_effect=[False, True])
|
||||||
tm.create_on_device = Mock(return_value=True)
|
tm.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=False)
|
mm.version_is_less_than_12 = Mock(return_value=False)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
mm.gtm_provisioned = Mock(return_value=True)
|
mm.gtm_provisioned = Mock(return_value=True)
|
||||||
|
@ -253,22 +247,21 @@ class TestTypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
current = Parameters(load_fixture('load_gtm_pool_a_default.json'))
|
current = Parameters(params=load_fixture('load_gtm_pool_a_default.json'))
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = TypedManager(client)
|
tm = TypedManager(module=module)
|
||||||
tm.exists = Mock(side_effect=[True, True])
|
tm.exists = Mock(side_effect=[True, True])
|
||||||
tm.update_on_device = Mock(return_value=True)
|
tm.update_on_device = Mock(return_value=True)
|
||||||
tm.read_current_from_device = Mock(return_value=current)
|
tm.read_current_from_device = Mock(return_value=current)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=False)
|
mm.version_is_less_than_12 = Mock(return_value=False)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
mm.gtm_provisioned = Mock(return_value=True)
|
mm.gtm_provisioned = Mock(return_value=True)
|
||||||
|
@ -290,19 +283,18 @@ class TestTypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = TypedManager(client)
|
tm = TypedManager(module=module)
|
||||||
tm.exists = Mock(side_effect=[True, False])
|
tm.exists = Mock(side_effect=[True, False])
|
||||||
tm.remove_from_device = Mock(return_value=True)
|
tm.remove_from_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=False)
|
mm.version_is_less_than_12 = Mock(return_value=False)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
mm.gtm_provisioned = Mock(return_value=True)
|
mm.gtm_provisioned = Mock(return_value=True)
|
||||||
|
|
|
@ -18,8 +18,7 @@ if sys.version_info < (2, 7):
|
||||||
from ansible.compat.tests import unittest
|
from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import Mock
|
from ansible.compat.tests.mock import Mock
|
||||||
from ansible.compat.tests.mock import patch
|
from ansible.compat.tests.mock import patch
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from library.bigip_gtm_server import ApiParameters
|
from library.bigip_gtm_server import ApiParameters
|
||||||
|
@ -28,7 +27,8 @@ try:
|
||||||
from library.bigip_gtm_server import V1Manager
|
from library.bigip_gtm_server import V1Manager
|
||||||
from library.bigip_gtm_server import V2Manager
|
from library.bigip_gtm_server import V2Manager
|
||||||
from library.bigip_gtm_server import ArgumentSpec
|
from library.bigip_gtm_server import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
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
|
from test.unit.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
|
@ -38,7 +38,8 @@ except ImportError:
|
||||||
from ansible.modules.network.f5.bigip_gtm_server import V1Manager
|
from ansible.modules.network.f5.bigip_gtm_server import V1Manager
|
||||||
from ansible.modules.network.f5.bigip_gtm_server import V2Manager
|
from ansible.modules.network.f5.bigip_gtm_server import V2Manager
|
||||||
from ansible.modules.network.f5.bigip_gtm_server import ArgumentSpec
|
from ansible.modules.network.f5.bigip_gtm_server import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from units.modules.utils import set_module_args
|
from units.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
||||||
|
@ -114,7 +115,7 @@ class TestParameters(unittest.TestCase):
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
p = ModuleParameters(args)
|
p = ModuleParameters(params=args)
|
||||||
assert p.name == 'GTM_Server'
|
assert p.name == 'GTM_Server'
|
||||||
assert p.datacenter == '/Common/New York'
|
assert p.datacenter == '/Common/New York'
|
||||||
assert p.server_type == 'bigip'
|
assert p.server_type == 'bigip'
|
||||||
|
@ -124,7 +125,7 @@ class TestParameters(unittest.TestCase):
|
||||||
def test_api_parameters(self):
|
def test_api_parameters(self):
|
||||||
args = load_fixture('load_gtm_server_1.json')
|
args = load_fixture('load_gtm_server_1.json')
|
||||||
|
|
||||||
p = ApiParameters(args)
|
p = ApiParameters(params=args)
|
||||||
assert p.name == 'baz'
|
assert p.name == 'baz'
|
||||||
assert p.datacenter == '/Common/foo'
|
assert p.datacenter == '/Common/foo'
|
||||||
assert p.server_type == 'bigip'
|
assert p.server_type == 'bigip'
|
||||||
|
@ -132,8 +133,6 @@ class TestParameters(unittest.TestCase):
|
||||||
assert p.virtual_server_discovery == 'disabled'
|
assert p.virtual_server_discovery == 'disabled'
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestV1Manager(unittest.TestCase):
|
class TestV1Manager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -189,18 +188,17 @@ class TestV1Manager(unittest.TestCase):
|
||||||
]
|
]
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
m1 = V1Manager(client)
|
m1 = V1Manager(module=module, params=module.params)
|
||||||
m1.exists = Mock(side_effect=[False, True])
|
m1.exists = Mock(side_effect=[False, True])
|
||||||
m1.create_on_device = Mock(return_value=True)
|
m1.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.get_manager = Mock(return_value=m1)
|
mm.get_manager = Mock(return_value=m1)
|
||||||
mm.version_is_less_than = Mock(return_value=True)
|
mm.version_is_less_than = Mock(return_value=True)
|
||||||
mm.gtm_provisioned = Mock(return_value=True)
|
mm.gtm_provisioned = Mock(return_value=True)
|
||||||
|
@ -211,8 +209,6 @@ class TestV1Manager(unittest.TestCase):
|
||||||
assert results['server_type'] == 'bigip'
|
assert results['server_type'] == 'bigip'
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestV2Manager(unittest.TestCase):
|
class TestV2Manager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -268,18 +264,17 @@ class TestV2Manager(unittest.TestCase):
|
||||||
]
|
]
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
m1 = V2Manager(client)
|
m1 = V2Manager(module=module)
|
||||||
m1.exists = Mock(side_effect=[False, True])
|
m1.exists = Mock(side_effect=[False, True])
|
||||||
m1.create_on_device = Mock(return_value=True)
|
m1.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.get_manager = Mock(return_value=m1)
|
mm.get_manager = Mock(return_value=m1)
|
||||||
mm.version_is_less_than = Mock(return_value=False)
|
mm.version_is_less_than = Mock(return_value=False)
|
||||||
mm.gtm_provisioned = Mock(return_value=True)
|
mm.gtm_provisioned = Mock(return_value=True)
|
||||||
|
|
|
@ -18,8 +18,7 @@ if sys.version_info < (2, 7):
|
||||||
from ansible.compat.tests import unittest
|
from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import Mock
|
from ansible.compat.tests.mock import Mock
|
||||||
from ansible.compat.tests.mock import patch
|
from ansible.compat.tests.mock import patch
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.f5_utils import F5ModuleError
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from library.bigip_gtm_wide_ip import ApiParameters
|
from library.bigip_gtm_wide_ip import ApiParameters
|
||||||
|
@ -28,7 +27,8 @@ try:
|
||||||
from library.bigip_gtm_wide_ip import ArgumentSpec
|
from library.bigip_gtm_wide_ip import ArgumentSpec
|
||||||
from library.bigip_gtm_wide_ip import UntypedManager
|
from library.bigip_gtm_wide_ip import UntypedManager
|
||||||
from library.bigip_gtm_wide_ip import TypedManager
|
from library.bigip_gtm_wide_ip import TypedManager
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
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
|
from test.unit.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
|
@ -38,7 +38,8 @@ except ImportError:
|
||||||
from ansible.modules.network.f5.bigip_gtm_wide_ip import ArgumentSpec
|
from ansible.modules.network.f5.bigip_gtm_wide_ip import ArgumentSpec
|
||||||
from ansible.modules.network.f5.bigip_gtm_wide_ip import UntypedManager
|
from ansible.modules.network.f5.bigip_gtm_wide_ip import UntypedManager
|
||||||
from ansible.modules.network.f5.bigip_gtm_wide_ip import TypedManager
|
from ansible.modules.network.f5.bigip_gtm_wide_ip import TypedManager
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from units.modules.utils import set_module_args
|
from units.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
||||||
|
@ -71,7 +72,7 @@ class TestParameters(unittest.TestCase):
|
||||||
name='foo.baz.bar',
|
name='foo.baz.bar',
|
||||||
lb_method='round-robin',
|
lb_method='round-robin',
|
||||||
)
|
)
|
||||||
p = ModuleParameters(args)
|
p = ModuleParameters(params=args)
|
||||||
assert p.name == 'foo.baz.bar'
|
assert p.name == 'foo.baz.bar'
|
||||||
assert p.pool_lb_method == 'round-robin'
|
assert p.pool_lb_method == 'round-robin'
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ class TestParameters(unittest.TestCase):
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
p = ModuleParameters(args)
|
p = ModuleParameters(params=args)
|
||||||
assert len(p.pools) == 1
|
assert len(p.pools) == 1
|
||||||
|
|
||||||
def test_api_parameters(self):
|
def test_api_parameters(self):
|
||||||
|
@ -92,13 +93,13 @@ class TestParameters(unittest.TestCase):
|
||||||
name='foo.baz.bar',
|
name='foo.baz.bar',
|
||||||
poolLbMode='round-robin'
|
poolLbMode='round-robin'
|
||||||
)
|
)
|
||||||
p = ApiParameters(args)
|
p = ApiParameters(params=args)
|
||||||
assert p.name == 'foo.baz.bar'
|
assert p.name == 'foo.baz.bar'
|
||||||
assert p.pool_lb_method == 'round-robin'
|
assert p.pool_lb_method == 'round-robin'
|
||||||
|
|
||||||
def test_api_pools(self):
|
def test_api_pools(self):
|
||||||
args = load_fixture('load_gtm_wide_ip_with_pools.json')
|
args = load_fixture('load_gtm_wide_ip_with_pools.json')
|
||||||
p = ApiParameters(args)
|
p = ApiParameters(params=args)
|
||||||
assert len(p.pools) == 1
|
assert len(p.pools) == 1
|
||||||
assert 'name' in p.pools[0]
|
assert 'name' in p.pools[0]
|
||||||
assert 'ratio' in p.pools[0]
|
assert 'ratio' in p.pools[0]
|
||||||
|
@ -111,13 +112,11 @@ class TestParameters(unittest.TestCase):
|
||||||
lb_method='round-robin'
|
lb_method='round-robin'
|
||||||
)
|
)
|
||||||
with pytest.raises(F5ModuleError) as excinfo:
|
with pytest.raises(F5ModuleError) as excinfo:
|
||||||
p = ModuleParameters(args)
|
p = ModuleParameters(params=args)
|
||||||
assert p.name == 'foo.baz'
|
assert p.name == 'foo.baz'
|
||||||
assert 'The provided name must be a valid FQDN' in str(excinfo)
|
assert 'The provided name must be a valid FQDN' in str(excinfo)
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestUntypedManager(unittest.TestCase):
|
class TestUntypedManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -132,19 +131,18 @@ class TestUntypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = UntypedManager(client)
|
tm = UntypedManager(module=module, params=module.params)
|
||||||
tm.exists = Mock(return_value=False)
|
tm.exists = Mock(return_value=False)
|
||||||
tm.create_on_device = Mock(return_value=True)
|
tm.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=True)
|
mm.version_is_less_than_12 = Mock(return_value=True)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
|
|
||||||
|
@ -156,8 +154,6 @@ class TestUntypedManager(unittest.TestCase):
|
||||||
assert results['lb_method'] == 'round-robin'
|
assert results['lb_method'] == 'round-robin'
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestTypedManager(unittest.TestCase):
|
class TestTypedManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -173,19 +169,18 @@ class TestTypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = TypedManager(client)
|
tm = TypedManager(module=module, params=module.params)
|
||||||
tm.exists = Mock(return_value=False)
|
tm.exists = Mock(return_value=False)
|
||||||
tm.create_on_device = Mock(return_value=True)
|
tm.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=False)
|
mm.version_is_less_than_12 = Mock(return_value=False)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
|
|
||||||
|
@ -206,19 +201,18 @@ class TestTypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = TypedManager(client)
|
tm = TypedManager(module=module, params=module.params)
|
||||||
tm.exists = Mock(return_value=False)
|
tm.exists = Mock(return_value=False)
|
||||||
tm.create_on_device = Mock(return_value=True)
|
tm.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=False)
|
mm.version_is_less_than_12 = Mock(return_value=False)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
|
|
||||||
|
@ -239,19 +233,18 @@ class TestTypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = TypedManager(client)
|
tm = TypedManager(module=module, params=module.params)
|
||||||
tm.exists = Mock(return_value=False)
|
tm.exists = Mock(return_value=False)
|
||||||
tm.create_on_device = Mock(return_value=True)
|
tm.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=False)
|
mm.version_is_less_than_12 = Mock(return_value=False)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
|
|
||||||
|
@ -278,19 +271,18 @@ class TestTypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = TypedManager(client)
|
tm = TypedManager(module=module, params=module.params)
|
||||||
tm.exists = Mock(return_value=False)
|
tm.exists = Mock(return_value=False)
|
||||||
tm.create_on_device = Mock(return_value=True)
|
tm.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=False)
|
mm.version_is_less_than_12 = Mock(return_value=False)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
|
|
||||||
|
@ -317,20 +309,19 @@ class TestTypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
current = ApiParameters(load_fixture('load_gtm_wide_ip_with_pools.json'))
|
current = ApiParameters(params=load_fixture('load_gtm_wide_ip_with_pools.json'))
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = TypedManager(client)
|
tm = TypedManager(module=module, params=module.params)
|
||||||
tm.exists = Mock(return_value=True)
|
tm.exists = Mock(return_value=True)
|
||||||
tm.read_current_from_device = Mock(return_value=current)
|
tm.read_current_from_device = Mock(return_value=current)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=False)
|
mm.version_is_less_than_12 = Mock(return_value=False)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
|
|
||||||
|
@ -358,21 +349,20 @@ class TestTypedManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
current = ApiParameters(load_fixture('load_gtm_wide_ip_with_pools.json'))
|
current = ApiParameters(params=load_fixture('load_gtm_wide_ip_with_pools.json'))
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = TypedManager(client)
|
tm = TypedManager(module=module, params=module.params)
|
||||||
tm.exists = Mock(return_value=True)
|
tm.exists = Mock(return_value=True)
|
||||||
tm.read_current_from_device = Mock(return_value=current)
|
tm.read_current_from_device = Mock(return_value=current)
|
||||||
tm.update_on_device = Mock(return_value=True)
|
tm.update_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.version_is_less_than_12 = Mock(return_value=False)
|
mm.version_is_less_than_12 = Mock(return_value=False)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
|
|
||||||
|
|
|
@ -17,20 +17,22 @@ if sys.version_info < (2, 7):
|
||||||
from ansible.compat.tests import unittest
|
from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import Mock
|
from ansible.compat.tests.mock import Mock
|
||||||
from ansible.compat.tests.mock import patch
|
from ansible.compat.tests.mock import patch
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from library.bigip_hostname import Parameters
|
from library.bigip_hostname import Parameters
|
||||||
from library.bigip_hostname import ModuleManager
|
from library.bigip_hostname import ModuleManager
|
||||||
from library.bigip_hostname import ArgumentSpec
|
from library.bigip_hostname import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
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
|
from test.unit.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from ansible.modules.network.f5.bigip_hostname import Parameters
|
from ansible.modules.network.f5.bigip_hostname import Parameters
|
||||||
from ansible.modules.network.f5.bigip_hostname import ModuleManager
|
from ansible.modules.network.f5.bigip_hostname import ModuleManager
|
||||||
from ansible.modules.network.f5.bigip_hostname import ArgumentSpec
|
from ansible.modules.network.f5.bigip_hostname import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from units.modules.utils import set_module_args
|
from units.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
||||||
|
@ -62,12 +64,10 @@ class TestParameters(unittest.TestCase):
|
||||||
args = dict(
|
args = dict(
|
||||||
hostname='foo.internal.com'
|
hostname='foo.internal.com'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.hostname == 'foo.internal.com'
|
assert p.hostname == 'foo.internal.com'
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestManager(unittest.TestCase):
|
class TestManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -88,14 +88,13 @@ class TestManager(unittest.TestCase):
|
||||||
hostname='foo.internal.com'
|
hostname='foo.internal.com'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.update_on_device = Mock(return_value=True)
|
mm.update_on_device = Mock(return_value=True)
|
||||||
mm.read_current_from_device = Mock(return_value=current)
|
mm.read_current_from_device = Mock(return_value=current)
|
||||||
|
|
||||||
|
|
|
@ -17,20 +17,22 @@ if sys.version_info < (2, 7):
|
||||||
from ansible.compat.tests import unittest
|
from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import Mock
|
from ansible.compat.tests.mock import Mock
|
||||||
from ansible.compat.tests.mock import patch
|
from ansible.compat.tests.mock import patch
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from library.bigip_iapp_service import Parameters
|
from library.bigip_iapp_service import Parameters
|
||||||
from library.bigip_iapp_service import ModuleManager
|
from library.bigip_iapp_service import ModuleManager
|
||||||
from library.bigip_iapp_service import ArgumentSpec
|
from library.bigip_iapp_service import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
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
|
from test.unit.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from ansible.modules.network.f5.bigip_iapp_service import Parameters
|
from ansible.modules.network.f5.bigip_iapp_service import Parameters
|
||||||
from ansible.modules.network.f5.bigip_iapp_service import ModuleManager
|
from ansible.modules.network.f5.bigip_iapp_service import ModuleManager
|
||||||
from ansible.modules.network.f5.bigip_iapp_service import ArgumentSpec
|
from ansible.modules.network.f5.bigip_iapp_service import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from units.modules.utils import set_module_args
|
from units.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
||||||
|
@ -61,7 +63,7 @@ class TestParameters(unittest.TestCase):
|
||||||
|
|
||||||
def test_module_parameters_keys(self):
|
def test_module_parameters_keys(self):
|
||||||
args = load_fixture('create_iapp_service_parameters_f5_http.json')
|
args = load_fixture('create_iapp_service_parameters_f5_http.json')
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
|
|
||||||
# Assert the top-level keys
|
# Assert the top-level keys
|
||||||
assert p.name == 'http_example'
|
assert p.name == 'http_example'
|
||||||
|
@ -74,7 +76,7 @@ class TestParameters(unittest.TestCase):
|
||||||
|
|
||||||
def test_module_parameters_lists(self):
|
def test_module_parameters_lists(self):
|
||||||
args = load_fixture('create_iapp_service_parameters_f5_http.json')
|
args = load_fixture('create_iapp_service_parameters_f5_http.json')
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
|
|
||||||
assert 'lists' in p._values
|
assert 'lists' in p._values
|
||||||
|
|
||||||
|
@ -90,7 +92,7 @@ class TestParameters(unittest.TestCase):
|
||||||
|
|
||||||
def test_module_parameters_tables(self):
|
def test_module_parameters_tables(self):
|
||||||
args = load_fixture('create_iapp_service_parameters_f5_http.json')
|
args = load_fixture('create_iapp_service_parameters_f5_http.json')
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
|
|
||||||
assert 'tables' in p._values
|
assert 'tables' in p._values
|
||||||
|
|
||||||
|
@ -117,7 +119,7 @@ class TestParameters(unittest.TestCase):
|
||||||
|
|
||||||
def test_module_parameters_variables(self):
|
def test_module_parameters_variables(self):
|
||||||
args = load_fixture('create_iapp_service_parameters_f5_http.json')
|
args = load_fixture('create_iapp_service_parameters_f5_http.json')
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
|
|
||||||
assert 'variables' in p._values
|
assert 'variables' in p._values
|
||||||
assert len(p.variables) == 34
|
assert len(p.variables) == 34
|
||||||
|
@ -140,13 +142,13 @@ class TestParameters(unittest.TestCase):
|
||||||
args = dict(
|
args = dict(
|
||||||
strict_updates=True
|
strict_updates=True
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.strict_updates == 'enabled'
|
assert p.strict_updates == 'enabled'
|
||||||
|
|
||||||
args = dict(
|
args = dict(
|
||||||
strict_updates=False
|
strict_updates=False
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.strict_updates == 'disabled'
|
assert p.strict_updates == 'disabled'
|
||||||
|
|
||||||
def test_module_strict_updates_override_from_top_level(self):
|
def test_module_strict_updates_override_from_top_level(self):
|
||||||
|
@ -156,7 +158,7 @@ class TestParameters(unittest.TestCase):
|
||||||
strictUpdates='disabled'
|
strictUpdates='disabled'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.strict_updates == 'enabled'
|
assert p.strict_updates == 'enabled'
|
||||||
|
|
||||||
args = dict(
|
args = dict(
|
||||||
|
@ -165,7 +167,7 @@ class TestParameters(unittest.TestCase):
|
||||||
strictUpdates='enabled'
|
strictUpdates='enabled'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.strict_updates == 'disabled'
|
assert p.strict_updates == 'disabled'
|
||||||
|
|
||||||
def test_module_strict_updates_only_parameters(self):
|
def test_module_strict_updates_only_parameters(self):
|
||||||
|
@ -174,7 +176,7 @@ class TestParameters(unittest.TestCase):
|
||||||
strictUpdates='disabled'
|
strictUpdates='disabled'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.strict_updates == 'disabled'
|
assert p.strict_updates == 'disabled'
|
||||||
|
|
||||||
args = dict(
|
args = dict(
|
||||||
|
@ -182,20 +184,20 @@ class TestParameters(unittest.TestCase):
|
||||||
strictUpdates='enabled'
|
strictUpdates='enabled'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.strict_updates == 'enabled'
|
assert p.strict_updates == 'enabled'
|
||||||
|
|
||||||
def test_api_strict_updates_from_top_level(self):
|
def test_api_strict_updates_from_top_level(self):
|
||||||
args = dict(
|
args = dict(
|
||||||
strictUpdates='enabled'
|
strictUpdates='enabled'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.strict_updates == 'enabled'
|
assert p.strict_updates == 'enabled'
|
||||||
|
|
||||||
args = dict(
|
args = dict(
|
||||||
strictUpdates='disabled'
|
strictUpdates='disabled'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.strict_updates == 'disabled'
|
assert p.strict_updates == 'disabled'
|
||||||
|
|
||||||
def test_api_parameters_variables(self):
|
def test_api_parameters_variables(self):
|
||||||
|
@ -208,7 +210,7 @@ class TestParameters(unittest.TestCase):
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.variables[0]['name'] == 'client__http_compression'
|
assert p.variables[0]['name'] == 'client__http_compression'
|
||||||
|
|
||||||
def test_api_parameters_tables(self):
|
def test_api_parameters_tables(self):
|
||||||
|
@ -240,7 +242,7 @@ class TestParameters(unittest.TestCase):
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.tables[0]['name'] == 'pool__members'
|
assert p.tables[0]['name'] == 'pool__members'
|
||||||
assert p.tables[0]['columnNames'] == ['addr', 'port', 'connection_limit']
|
assert p.tables[0]['columnNames'] == ['addr', 'port', 'connection_limit']
|
||||||
assert len(p.tables[0]['rows']) == 2
|
assert len(p.tables[0]['rows']) == 2
|
||||||
|
@ -253,28 +255,28 @@ class TestParameters(unittest.TestCase):
|
||||||
args = dict(
|
args = dict(
|
||||||
deviceGroup='none'
|
deviceGroup='none'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.deviceGroup == 'none'
|
assert p.deviceGroup == 'none'
|
||||||
|
|
||||||
def test_api_parameters_inherited_traffic_group(self):
|
def test_api_parameters_inherited_traffic_group(self):
|
||||||
args = dict(
|
args = dict(
|
||||||
inheritedTrafficGroup='true'
|
inheritedTrafficGroup='true'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.inheritedTrafficGroup == 'true'
|
assert p.inheritedTrafficGroup == 'true'
|
||||||
|
|
||||||
def test_api_parameters_inherited_devicegroup(self):
|
def test_api_parameters_inherited_devicegroup(self):
|
||||||
args = dict(
|
args = dict(
|
||||||
inheritedDevicegroup='true'
|
inheritedDevicegroup='true'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.inheritedDevicegroup == 'true'
|
assert p.inheritedDevicegroup == 'true'
|
||||||
|
|
||||||
def test_api_parameters_traffic_group(self):
|
def test_api_parameters_traffic_group(self):
|
||||||
args = dict(
|
args = dict(
|
||||||
trafficGroup='/Common/traffic-group-local-only'
|
trafficGroup='/Common/traffic-group-local-only'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.traffic_group == '/Common/traffic-group-local-only'
|
assert p.traffic_group == '/Common/traffic-group-local-only'
|
||||||
|
|
||||||
def test_module_template_same_partition(self):
|
def test_module_template_same_partition(self):
|
||||||
|
@ -282,7 +284,7 @@ class TestParameters(unittest.TestCase):
|
||||||
template='foo',
|
template='foo',
|
||||||
partition='bar'
|
partition='bar'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.template == '/bar/foo'
|
assert p.template == '/bar/foo'
|
||||||
|
|
||||||
def test_module_template_same_partition_full_path(self):
|
def test_module_template_same_partition_full_path(self):
|
||||||
|
@ -290,7 +292,7 @@ class TestParameters(unittest.TestCase):
|
||||||
template='/bar/foo',
|
template='/bar/foo',
|
||||||
partition='bar'
|
partition='bar'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.template == '/bar/foo'
|
assert p.template == '/bar/foo'
|
||||||
|
|
||||||
def test_module_template_different_partition_full_path(self):
|
def test_module_template_different_partition_full_path(self):
|
||||||
|
@ -298,12 +300,10 @@ class TestParameters(unittest.TestCase):
|
||||||
template='/Common/foo',
|
template='/Common/foo',
|
||||||
partition='bar'
|
partition='bar'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.template == '/Common/foo'
|
assert p.template == '/Common/foo'
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestManager(unittest.TestCase):
|
class TestManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -321,12 +321,11 @@ class TestManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(return_value=False)
|
mm.exists = Mock(return_value=False)
|
||||||
|
@ -352,12 +351,11 @@ class TestManager(unittest.TestCase):
|
||||||
parameters = load_fixture('create_iapp_service_parameters_f5_http.json')
|
parameters = load_fixture('create_iapp_service_parameters_f5_http.json')
|
||||||
current = Parameters(parameters)
|
current = Parameters(parameters)
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(return_value=True)
|
mm.exists = Mock(return_value=True)
|
||||||
|
|
|
@ -17,20 +17,22 @@ if sys.version_info < (2, 7):
|
||||||
from ansible.compat.tests import unittest
|
from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import Mock
|
from ansible.compat.tests.mock import Mock
|
||||||
from ansible.compat.tests.mock import patch
|
from ansible.compat.tests.mock import patch
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from library.bigip_iapp_template import Parameters
|
from library.bigip_iapp_template import Parameters
|
||||||
from library.bigip_iapp_template import ModuleManager
|
from library.bigip_iapp_template import ModuleManager
|
||||||
from library.bigip_iapp_template import ArgumentSpec
|
from library.bigip_iapp_template import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
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
|
from test.unit.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from ansible.modules.network.f5.bigip_iapp_template import Parameters
|
from ansible.modules.network.f5.bigip_iapp_template import Parameters
|
||||||
from ansible.modules.network.f5.bigip_iapp_template import ArgumentSpec
|
from ansible.modules.network.f5.bigip_iapp_template import ArgumentSpec
|
||||||
from ansible.modules.network.f5.bigip_iapp_template import ModuleManager
|
from ansible.modules.network.f5.bigip_iapp_template import ModuleManager
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from units.modules.utils import set_module_args
|
from units.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
||||||
|
@ -63,12 +65,10 @@ class TestParameters(unittest.TestCase):
|
||||||
args = dict(
|
args = dict(
|
||||||
content=iapp
|
content=iapp
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.name == 'foo.iapp'
|
assert p.name == 'foo.iapp'
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestManager(unittest.TestCase):
|
class TestManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -83,12 +83,11 @@ class TestManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(side_effect=[False, True])
|
mm.exists = Mock(side_effect=[False, True])
|
||||||
|
@ -107,14 +106,13 @@ class TestManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
current1 = Parameters(load_fixture('load_sys_application_template_w_new_checksum.json'))
|
current1 = Parameters(params=load_fixture('load_sys_application_template_w_new_checksum.json'))
|
||||||
current2 = Parameters(load_fixture('load_sys_application_template_w_old_checksum.json'))
|
current2 = Parameters(params=load_fixture('load_sys_application_template_w_old_checksum.json'))
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(side_effect=[True, True])
|
mm.exists = Mock(side_effect=[True, True])
|
||||||
|
@ -138,12 +136,11 @@ class TestManager(unittest.TestCase):
|
||||||
state='absent'
|
state='absent'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(side_effect=[True, False])
|
mm.exists = Mock(side_effect=[True, False])
|
||||||
|
@ -162,12 +159,11 @@ class TestManager(unittest.TestCase):
|
||||||
state='absent'
|
state='absent'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(side_effect=[False, False])
|
mm.exists = Mock(side_effect=[False, False])
|
||||||
|
|
|
@ -17,20 +17,22 @@ if sys.version_info < (2, 7):
|
||||||
from ansible.compat.tests import unittest
|
from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import Mock
|
from ansible.compat.tests.mock import Mock
|
||||||
from ansible.compat.tests.mock import patch
|
from ansible.compat.tests.mock import patch
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from library.bigip_iapp_template import Parameters
|
from library.bigip_iapp_template import Parameters
|
||||||
from library.bigip_iapp_template import ModuleManager
|
from library.bigip_iapp_template import ModuleManager
|
||||||
from library.bigip_iapp_template import ArgumentSpec
|
from library.bigip_iapp_template import ArgumentSpec
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
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
|
from test.unit.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from ansible.modules.network.f5.bigip_iapp_template import Parameters
|
from ansible.modules.network.f5.bigip_iapp_template import Parameters
|
||||||
from ansible.modules.network.f5.bigip_iapp_template import ArgumentSpec
|
from ansible.modules.network.f5.bigip_iapp_template import ArgumentSpec
|
||||||
from ansible.modules.network.f5.bigip_iapp_template import ModuleManager
|
from ansible.modules.network.f5.bigip_iapp_template import ModuleManager
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from units.modules.utils import set_module_args
|
from units.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
||||||
|
@ -63,12 +65,10 @@ class TestParameters(unittest.TestCase):
|
||||||
package='MyApp-0.1.0-0001.noarch.rpm',
|
package='MyApp-0.1.0-0001.noarch.rpm',
|
||||||
state='present'
|
state='present'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.package == 'MyApp-0.1.0-0001.noarch.rpm'
|
assert p.package == 'MyApp-0.1.0-0001.noarch.rpm'
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestManager(unittest.TestCase):
|
class TestManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -84,12 +84,11 @@ class TestManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode
|
||||||
f5_product_name=self.spec.f5_product_name
|
|
||||||
)
|
)
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm.exists = Mock(side_effect=[False, True])
|
mm.exists = Mock(side_effect=[False, True])
|
||||||
|
|
|
@ -18,7 +18,7 @@ from ansible.compat.tests import unittest
|
||||||
from ansible.compat.tests.mock import Mock
|
from ansible.compat.tests.mock import Mock
|
||||||
from ansible.compat.tests.mock import patch
|
from ansible.compat.tests.mock import patch
|
||||||
from ansible.compat.tests.mock import mock_open
|
from ansible.compat.tests.mock import mock_open
|
||||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.six import PY3
|
from ansible.module_utils.six import PY3
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -27,7 +27,8 @@ try:
|
||||||
from library.bigip_irule import ArgumentSpec
|
from library.bigip_irule import ArgumentSpec
|
||||||
from library.bigip_irule import GtmManager
|
from library.bigip_irule import GtmManager
|
||||||
from library.bigip_irule import LtmManager
|
from library.bigip_irule import LtmManager
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
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
|
from test.unit.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
|
@ -36,7 +37,8 @@ except ImportError:
|
||||||
from ansible.modules.network.f5.bigip_irule import ArgumentSpec
|
from ansible.modules.network.f5.bigip_irule import ArgumentSpec
|
||||||
from ansible.modules.network.f5.bigip_irule import GtmManager
|
from ansible.modules.network.f5.bigip_irule import GtmManager
|
||||||
from ansible.modules.network.f5.bigip_irule import LtmManager
|
from ansible.modules.network.f5.bigip_irule import LtmManager
|
||||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import F5ModuleError
|
||||||
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
from units.modules.utils import set_module_args
|
from units.modules.utils import set_module_args
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
||||||
|
@ -77,7 +79,7 @@ class TestParameters(unittest.TestCase):
|
||||||
name='foo',
|
name='foo',
|
||||||
state='present'
|
state='present'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.content == content.strip()
|
assert p.content == content.strip()
|
||||||
|
|
||||||
def test_module_parameters_gtm(self):
|
def test_module_parameters_gtm(self):
|
||||||
|
@ -88,7 +90,7 @@ class TestParameters(unittest.TestCase):
|
||||||
name='foo',
|
name='foo',
|
||||||
state='present'
|
state='present'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.content == content.strip()
|
assert p.content == content.strip()
|
||||||
|
|
||||||
def test_api_parameters_ltm(self):
|
def test_api_parameters_ltm(self):
|
||||||
|
@ -96,7 +98,7 @@ class TestParameters(unittest.TestCase):
|
||||||
args = dict(
|
args = dict(
|
||||||
apiAnonymous=content
|
apiAnonymous=content
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
assert p.content == content.strip()
|
assert p.content == content.strip()
|
||||||
|
|
||||||
def test_return_api_params(self):
|
def test_return_api_params(self):
|
||||||
|
@ -107,14 +109,12 @@ class TestParameters(unittest.TestCase):
|
||||||
name='foo',
|
name='foo',
|
||||||
state='present'
|
state='present'
|
||||||
)
|
)
|
||||||
p = Parameters(args)
|
p = Parameters(params=args)
|
||||||
params = p.api_params()
|
params = p.api_params()
|
||||||
|
|
||||||
assert 'apiAnonymous' in params
|
assert 'apiAnonymous' in params
|
||||||
|
|
||||||
|
|
||||||
@patch('ansible.module_utils.f5_utils.AnsibleF5Client._get_mgmt_root',
|
|
||||||
return_value=True)
|
|
||||||
class TestManager(unittest.TestCase):
|
class TestManager(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -141,20 +141,19 @@ class TestManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode,
|
||||||
f5_product_name=self.spec.f5_product_name,
|
|
||||||
mutually_exclusive=self.spec.mutually_exclusive,
|
mutually_exclusive=self.spec.mutually_exclusive,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = LtmManager(client)
|
tm = LtmManager(module=module, params=module.params)
|
||||||
tm.exists = Mock(side_effect=[False, True])
|
tm.exists = Mock(side_effect=[False, True])
|
||||||
tm.create_on_device = Mock(return_value=True)
|
tm.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
|
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
|
@ -173,20 +172,19 @@ class TestManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode,
|
||||||
f5_product_name=self.spec.f5_product_name,
|
|
||||||
mutually_exclusive=self.spec.mutually_exclusive,
|
mutually_exclusive=self.spec.mutually_exclusive,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = GtmManager(client)
|
tm = GtmManager(module=module, params=module.params)
|
||||||
tm.exists = Mock(side_effect=[False, True])
|
tm.exists = Mock(side_effect=[False, True])
|
||||||
tm.create_on_device = Mock(return_value=True)
|
tm.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
|
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
|
@ -205,10 +203,9 @@ class TestManager(unittest.TestCase):
|
||||||
user='admin'
|
user='admin'
|
||||||
))
|
))
|
||||||
|
|
||||||
client = AnsibleF5Client(
|
module = AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode,
|
||||||
f5_product_name=self.spec.f5_product_name,
|
|
||||||
mutually_exclusive=self.spec.mutually_exclusive,
|
mutually_exclusive=self.spec.mutually_exclusive,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -219,12 +216,12 @@ class TestManager(unittest.TestCase):
|
||||||
|
|
||||||
with patch(builtins_name + '.open', mock_open(read_data='this is my content'), create=True):
|
with patch(builtins_name + '.open', mock_open(read_data='this is my content'), create=True):
|
||||||
# Override methods in the specific type of manager
|
# Override methods in the specific type of manager
|
||||||
tm = GtmManager(client)
|
tm = GtmManager(module=module, params=module.params)
|
||||||
tm.exists = Mock(side_effect=[False, True])
|
tm.exists = Mock(side_effect=[False, True])
|
||||||
tm.create_on_device = Mock(return_value=True)
|
tm.create_on_device = Mock(return_value=True)
|
||||||
|
|
||||||
# Override methods to force specific logic in the module to happen
|
# Override methods to force specific logic in the module to happen
|
||||||
mm = ModuleManager(client)
|
mm = ModuleManager(module=module)
|
||||||
mm.get_manager = Mock(return_value=tm)
|
mm.get_manager = Mock(return_value=tm)
|
||||||
|
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
|
@ -249,10 +246,9 @@ class TestManager(unittest.TestCase):
|
||||||
))
|
))
|
||||||
|
|
||||||
with patch('ansible.module_utils.basic.AnsibleModule.fail_json', unsafe=True) as mo:
|
with patch('ansible.module_utils.basic.AnsibleModule.fail_json', unsafe=True) as mo:
|
||||||
AnsibleF5Client(
|
AnsibleModule(
|
||||||
argument_spec=self.spec.argument_spec,
|
argument_spec=self.spec.argument_spec,
|
||||||
supports_check_mode=self.spec.supports_check_mode,
|
supports_check_mode=self.spec.supports_check_mode,
|
||||||
f5_product_name=self.spec.f5_product_name,
|
|
||||||
mutually_exclusive=self.spec.mutually_exclusive,
|
mutually_exclusive=self.spec.mutually_exclusive,
|
||||||
)
|
)
|
||||||
mo.assert_called_once()
|
mo.assert_called_once()
|
||||||
|
|
Loading…
Reference in a new issue