Adds various features and fixes (#39271)

* a refactor of pool member and node modules to be inline with current f5 conventions
* Added priority_group_activation to pools
* various other small convention fixes and bug fixes
pull/39366/head
Tim Rupp 7 years ago committed by GitHub
parent 1c49cc4377
commit fb264281de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -17,7 +17,7 @@ DOCUMENTATION = r'''
module: bigip_monitor_udp module: bigip_monitor_udp
short_description: Manages F5 BIG-IP LTM udp monitors short_description: Manages F5 BIG-IP LTM udp monitors
description: Manages F5 BIG-IP LTM udp monitors. description: Manages F5 BIG-IP LTM udp monitors.
version_added: "2.5" version_added: 2.5
options: options:
name: name:
description: description:
@ -150,30 +150,23 @@ import os
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback from ansible.module_utils.basic import env_fallback
HAS_DEVEL_IMPORTS = False
try: try:
# Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens 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 from library.module_utils.network.f5.common import f5_argument_spec
try: try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError: except ImportError:
HAS_F5SDK = False HAS_F5SDK = False
HAS_DEVEL_IMPORTS = True
except ImportError: except ImportError:
# Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens 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 from ansible.module_utils.network.f5.common import f5_argument_spec
try: try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
@ -208,11 +201,6 @@ class Parameters(AnsibleF5Parameters):
'destination', 'send', 'receive', 'interval', 'timeout', 'time_until_up' 'destination', 'send', 'receive', 'interval', 'timeout', 'time_until_up'
] ]
def _fqdn_name(self, value):
if value is not None and not value.startswith('/'):
return '/{0}/{1}'.format(self.partition, value)
return value
def to_return(self): def to_return(self):
result = {} result = {}
try: try:

@ -18,7 +18,7 @@ module: bigip_node
short_description: Manages F5 BIG-IP LTM nodes short_description: Manages F5 BIG-IP LTM nodes
description: description:
- Manages F5 BIG-IP LTM nodes. - Manages F5 BIG-IP LTM nodes.
version_added: "1.4" version_added: 1.4
options: options:
state: state:
description: description:
@ -59,12 +59,12 @@ options:
quorum: quorum:
description: description:
- Monitor quorum value when C(monitor_type) is C(m_of_n). - Monitor quorum value when C(monitor_type) is C(m_of_n).
version_added: "2.2" version_added: 2.2
monitors: monitors:
description: description:
- Specifies the health monitors that the system currently uses to - Specifies the health monitors that the system currently uses to
monitor this node. monitor this node.
version_added: "2.2" version_added: 2.2
address: address:
description: description:
- IP address of the node. This can be either IPv4 or IPv6. When creating a - IP address of the node. This can be either IPv4 or IPv6. When creating a
@ -73,7 +73,7 @@ options:
aliases: aliases:
- ip - ip
- host - host
version_added: "2.2" version_added: 2.2
fqdn: fqdn:
description: description:
- FQDN name of the node. This can be any name that is a valid RFC 1123 DNS - FQDN name of the node. This can be any name that is a valid RFC 1123 DNS
@ -86,7 +86,7 @@ options:
provided. This parameter cannot be updated after it is set. provided. This parameter cannot be updated after it is set.
aliases: aliases:
- hostname - hostname
version_added: "2.5" version_added: 2.5
description: description:
description: description:
- Specifies descriptive text that identifies the node. - Specifies descriptive text that identifies the node.
@ -97,7 +97,9 @@ options:
version_added: 2.5 version_added: 2.5
notes: notes:
- 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 C(pip install netaddr).
requirements:
- netaddr
extends_documentation_fragment: f5 extends_documentation_fragment: f5
author: author:
- Tim Rupp (@caphrim007) - Tim Rupp (@caphrim007)
@ -216,30 +218,25 @@ import time
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback from ansible.module_utils.basic import env_fallback
HAS_DEVEL_IMPORTS = False
try: try:
# Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens 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 fq_name
from library.module_utils.network.f5.common import f5_argument_spec from library.module_utils.network.f5.common import f5_argument_spec
try: try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError: except ImportError:
HAS_F5SDK = False HAS_F5SDK = False
HAS_DEVEL_IMPORTS = True
except ImportError: except ImportError:
# Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens 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 fq_name
from ansible.module_utils.network.f5.common import f5_argument_spec from ansible.module_utils.network.f5.common import f5_argument_spec
try: try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
@ -291,11 +288,6 @@ class Parameters(AnsibleF5Parameters):
except Exception: except Exception:
return result return result
def _fqdn_name(self, value):
if value is not None and not value.startswith('/'):
return '/{0}/{1}'.format(self.partition, value)
return value
@property @property
def monitors_list(self): def monitors_list(self):
if self._values['monitors'] is None: if self._values['monitors'] is None:
@ -310,13 +302,12 @@ class Parameters(AnsibleF5Parameters):
def monitors(self): def monitors(self):
if self._values['monitors'] is None: if self._values['monitors'] is None:
return None return None
monitors = [self._fqdn_name(x) for x in self.monitors_list] monitors = [fq_name(self.partition, x) for x in self.monitors_list]
if self.monitor_type == 'm_of_n': if self.monitor_type == 'm_of_n':
monitors = ' '.join(monitors) monitors = ' '.join(monitors)
result = 'min %s of { %s }' % (self.quorum, monitors) result = 'min %s of { %s }' % (self.quorum, monitors)
else: else:
result = ' and '.join(monitors).strip() result = ' and '.join(monitors).strip()
return result return result
@property @property

@ -18,7 +18,7 @@ module: bigip_partition
short_description: Manage BIG-IP partitions short_description: Manage BIG-IP partitions
description: description:
- Manage BIG-IP partitions. - Manage BIG-IP partitions.
version_added: "2.5" version_added: 2.5
options: options:
name: name:
description: description:
@ -107,30 +107,23 @@ description:
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
HAS_DEVEL_IMPORTS = False
try: try:
# Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens 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 from library.module_utils.network.f5.common import f5_argument_spec
try: try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError: except ImportError:
HAS_F5SDK = False HAS_F5SDK = False
HAS_DEVEL_IMPORTS = True
except ImportError: except ImportError:
# Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens 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 from ansible.module_utils.network.f5.common import f5_argument_spec
try: try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError

@ -23,7 +23,7 @@ description:
the description, and things unrelated to the policy rules themselves. the description, and things unrelated to the policy rules themselves.
It is also the first module that should be used when creating rules as It is also the first module that should be used when creating rules as
the C(bigip_policy_rule) module requires a policy parameter. the C(bigip_policy_rule) module requires a policy parameter.
version_added: "2.5" version_added: 2.5
options: options:
description: description:
description: description:
@ -168,30 +168,23 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback from ansible.module_utils.basic import env_fallback
from distutils.version import LooseVersion from distutils.version import LooseVersion
HAS_DEVEL_IMPORTS = False
try: try:
# Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens 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 from library.module_utils.network.f5.common import f5_argument_spec
try: try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError: except ImportError:
HAS_F5SDK = False HAS_F5SDK = False
HAS_DEVEL_IMPORTS = True
except ImportError: except ImportError:
# Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens 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 from ansible.module_utils.network.f5.common import f5_argument_spec
try: try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError

@ -41,7 +41,7 @@ options:
- When C(type) is C(ignore), will remove all existing actions from this - When C(type) is C(ignore), will remove all existing actions from this
rule. rule.
required: true required: true
choices: [ 'forward', 'enable', 'ignore' ] choices: ['forward', 'enable', 'ignore']
pool: pool:
description: description:
- Pool that you want to forward traffic to. - Pool that you want to forward traffic to.
@ -77,7 +77,7 @@ options:
list will provide a match. list will provide a match.
- When C(type) is C(all_traffic), will remove all existing conditions from - When C(type) is C(all_traffic), will remove all existing conditions from
this rule. this rule.
required: true required: True
choices: [ 'http_uri', 'all_traffic' ] choices: [ 'http_uri', 'all_traffic' ]
path_begins_with_any: path_begins_with_any:
description: description:
@ -120,6 +120,7 @@ EXAMPLES = r'''
actions: actions:
- type: forward - type: forward
pool: pool-svrs pool: pool-svrs
delegate_to: localhost
- name: Add multiple rules to the new policy - name: Add multiple rules to the new policy
bigip_policy_rule: bigip_policy_rule:
@ -127,6 +128,7 @@ EXAMPLES = r'''
name: "{{ item.name }}" name: "{{ item.name }}"
conditions: "{{ item.conditions }}" conditions: "{{ item.conditions }}"
actions: "{{ item.actions }}" actions: "{{ item.actions }}"
delegate_to: localhost
loop: loop:
- name: rule1 - name: rule1
actions: actions:
@ -151,6 +153,7 @@ EXAMPLES = r'''
- type: all_traffic - type: all_traffic
actions: actions:
- type: ignore - type: ignore
delegate_to: localhost
''' '''
RETURN = r''' RETURN = r'''
@ -197,30 +200,25 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback from ansible.module_utils.basic import env_fallback
from ansible.module_utils.six import iteritems from ansible.module_utils.six import iteritems
HAS_DEVEL_IMPORTS = False
try: try:
# Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens 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 fq_name
from library.module_utils.network.f5.common import f5_argument_spec from library.module_utils.network.f5.common import f5_argument_spec
try: try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError: except ImportError:
HAS_F5SDK = False HAS_F5SDK = False
HAS_DEVEL_IMPORTS = True
except ImportError: except ImportError:
# Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens 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 fq_name
from ansible.module_utils.network.f5.common import f5_argument_spec from ansible.module_utils.network.f5.common import f5_argument_spec
try: try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
@ -241,10 +239,9 @@ class Parameters(AnsibleF5Parameters):
'actions', 'conditions', 'description' 'actions', 'conditions', 'description'
] ]
def _fqdn_name(self, value): returnable = [
if value is not None and not value.startswith('/'): 'description'
return '/{0}/{1}'.format(self.partition, value) ]
return value
@property @property
def name(self): def name(self):
@ -254,13 +251,6 @@ class Parameters(AnsibleF5Parameters):
def description(self): def description(self):
return self._values.get('description', None) return self._values.get('description', None)
@property
def strategy(self):
if self._values['strategy'] is None:
return None
result = self._fqdn_name(self._values['strategy'])
return result
@property @property
def policy(self): def policy(self):
if self._values['policy'] is None: if self._values['policy'] is None:
@ -407,7 +397,7 @@ class ModuleParameters(Parameters):
raise F5ModuleError( raise F5ModuleError(
"A 'pool' must be specified when the 'forward' type is used." "A 'pool' must be specified when the 'forward' type is used."
) )
action['pool'] = self._fqdn_name(item['pool']) action['pool'] = fq_name(self.partition, item['pool'])
def _handle_enable_action(self, action, item): def _handle_enable_action(self, action, item):
"""Handle the nuances of the enable type """Handle the nuances of the enable type
@ -422,7 +412,7 @@ class ModuleParameters(Parameters):
"An 'asm_policy' must be specified when the 'enable' type is used." "An 'asm_policy' must be specified when the 'enable' type is used."
) )
action.update(dict( action.update(dict(
policy=self._fqdn_name(item['asm_policy']), policy=fq_name(self.partition, item['asm_policy']),
asm=True asm=True
)) ))
@ -836,9 +826,9 @@ class ArgumentSpec(object):
'all_traffic' 'all_traffic'
], ],
required=True required=True
) ),
path_begins_with_any=dict()
), ),
path_begins_with_any=dict()
), ),
name=dict(required=True), name=dict(required=True),
policy=dict(required=True), policy=dict(required=True),

@ -23,7 +23,7 @@ options:
description: description:
description: description:
- Specifies descriptive text that identifies the pool. - Specifies descriptive text that identifies the pool.
version_added: "2.3" version_added: 2.3
name: name:
description: description:
- Pool name - Pool name
@ -34,7 +34,7 @@ options:
description: description:
- Load balancing method. When creating a new pool, if this value is not - Load balancing method. When creating a new pool, if this value is not
specified, the default of C(round-robin) will be used. specified, the default of C(round-robin) will be used.
version_added: "1.3" version_added: 1.3
choices: choices:
- dynamic-ratio-member - dynamic-ratio-member
- dynamic-ratio-node - dynamic-ratio-node
@ -54,7 +54,7 @@ options:
- ratio-session - ratio-session
- round-robin - round-robin
- weighted-least-connections-member - weighted-least-connections-member
- weighted-least-connections-nod - weighted-least-connections-node
monitor_type: monitor_type:
description: description:
- Monitor rule type when C(monitors) is specified. - Monitor rule type when C(monitors) is specified.
@ -69,32 +69,32 @@ options:
or already existing on the device. or already existing on the device.
- Both C(single) and C(and_list) are functionally identical since BIG-IP - Both C(single) and C(and_list) are functionally identical since BIG-IP
considers all monitors as "a list". considers all monitors as "a list".
version_added: "1.3" version_added: 1.3
choices: ['and_list', 'm_of_n', 'single'] choices: ['and_list', 'm_of_n', 'single']
quorum: quorum:
description: description:
- Monitor quorum value when C(monitor_type) is C(m_of_n). - Monitor quorum value when C(monitor_type) is C(m_of_n).
- Quorum must be a value of 1 or greater when C(monitor_type) is C(m_of_n). - Quorum must be a value of 1 or greater when C(monitor_type) is C(m_of_n).
version_added: "1.3" version_added: 1.3
monitors: monitors:
description: description:
- Monitor template name list. If the partition is not provided as part of - Monitor template name list. If the partition is not provided as part of
the monitor name, then the C(partition) option will be used instead. the monitor name, then the C(partition) option will be used instead.
version_added: "1.3" version_added: 1.3
slow_ramp_time: slow_ramp_time:
description: description:
- Sets the ramp-up time (in seconds) to gradually ramp up the load on - Sets the ramp-up time (in seconds) to gradually ramp up the load on
newly added or freshly detected up pool members. newly added or freshly detected up pool members.
version_added: "1.3" version_added: 1.3
reselect_tries: reselect_tries:
description: description:
- Sets the number of times the system tries to contact a pool member - Sets the number of times the system tries to contact a pool member
after a passive failure. after a passive failure.
version_added: "2.2" version_added: 2.2
service_down_action: service_down_action:
description: description:
- Sets the action to take when node goes down in pool. - Sets the action to take when node goes down in pool.
version_added: "1.3" version_added: 1.3
choices: choices:
- none - none
- reset - reset
@ -124,6 +124,25 @@ options:
that are numbers. that are numbers.
- Data will be persisted, not ephemeral. - Data will be persisted, not ephemeral.
version_added: 2.5 version_added: 2.5
priority_group_activation:
description:
- Specifies whether the system load balances traffic according to the priority
number assigned to the pool member.
- When creating a new pool, if this parameter is not specified, the default of
C(0) will be used.
- To disable this setting, provide the value C(0).
- Once you enable this setting, you can specify pool member priority when you
create a new pool or on a pool member's properties screen.
- The system treats same-priority pool members as a group.
- To enable priority group activation, provide a number from C(0) to C(65535)
that represents the minimum number of members that must be available in one
priority group before the system directs traffic to members in a lower
priority group.
- When a sufficient number of members become available in the higher priority
group, the system again directs traffic to the higher priority group.
aliases:
- minimum_active_members
version_added: 2.6
notes: notes:
- Requires BIG-IP software version >= 12. - Requires BIG-IP software version >= 12.
- To add members do a pool, use the C(bigip_pool_member) module. Previously, the - To add members do a pool, use the C(bigip_pool_member) module. Previously, the
@ -144,7 +163,7 @@ EXAMPLES = r'''
state: present state: present
name: my-pool name: my-pool
partition: Common partition: Common
lb_method: least-connection-member lb_method: least-connections-member
slow_ramp_time: 120 slow_ramp_time: 120
delegate_to: localhost delegate_to: localhost
@ -307,6 +326,11 @@ metadata:
returned: changed returned: changed
type: dict type: dict
sample: {'key1': 'foo', 'key2': 'bar'} sample: {'key1': 'foo', 'key2': 'bar'}
priority_group_activation:
description: The new minimum number of members to activate the priorty group.
returned: changed
type: int
sample: 10
''' '''
import re import re
@ -315,30 +339,25 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback from ansible.module_utils.basic import env_fallback
from ansible.module_utils.six import iteritems from ansible.module_utils.six import iteritems
HAS_DEVEL_IMPORTS = False
try: try:
# Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens 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 fq_name
from library.module_utils.network.f5.common import f5_argument_spec from library.module_utils.network.f5.common import f5_argument_spec
try: try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError: except ImportError:
HAS_F5SDK = False HAS_F5SDK = False
HAS_DEVEL_IMPORTS = True
except ImportError: except ImportError:
# Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens 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 fq_name
from ansible.module_utils.network.f5.common import f5_argument_spec from ansible.module_utils.network.f5.common import f5_argument_spec
try: try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
@ -358,24 +377,26 @@ class Parameters(AnsibleF5Parameters):
'slowRampTime': 'slow_ramp_time', 'slowRampTime': 'slow_ramp_time',
'reselectTries': 'reselect_tries', 'reselectTries': 'reselect_tries',
'serviceDownAction': 'service_down_action', 'serviceDownAction': 'service_down_action',
'monitor': 'monitors' 'monitor': 'monitors',
'minActiveMembers': 'priority_group_activation'
} }
api_attributes = [ api_attributes = [
'description', 'name', 'loadBalancingMode', 'monitor', 'slowRampTime', 'description', 'name', 'loadBalancingMode', 'monitor', 'slowRampTime',
'reselectTries', 'serviceDownAction', 'metadata' 'reselectTries', 'serviceDownAction', 'metadata', 'minActiveMembers'
] ]
returnables = [ returnables = [
'monitor_type', 'quorum', 'monitors', 'service_down_action', 'monitor_type', 'quorum', 'monitors', 'service_down_action',
'description', 'lb_method', 'slow_ramp_time', 'description', 'lb_method', 'slow_ramp_time',
'reselect_tries', 'monitor', 'name', 'partition', 'metadata' 'reselect_tries', 'monitor', 'name', 'partition', 'metadata',
'priority_group_activation'
] ]
updatables = [ updatables = [
'monitor_type', 'quorum', 'monitors', 'service_down_action', 'monitor_type', 'quorum', 'monitors', 'service_down_action',
'description', 'lb_method', 'slow_ramp_time', 'reselect_tries', 'description', 'lb_method', 'slow_ramp_time', 'reselect_tries',
'metadata' 'metadata', 'priority_group_activation'
] ]
@property @property
@ -389,16 +410,21 @@ class Parameters(AnsibleF5Parameters):
raise F5ModuleError('Provided lb_method is unknown') raise F5ModuleError('Provided lb_method is unknown')
return lb_method return lb_method
def _fqdn_name(self, value): def _verify_quorum_type(self, quorum):
if value is not None and not value.startswith('/'): try:
return '/{0}/{1}'.format(self.partition, value) if quorum is None:
return value return None
return int(quorum)
except ValueError:
raise F5ModuleError(
"The specified 'quorum' must be an integer."
)
@property @property
def monitors(self): def monitors(self):
if self._values['monitors'] is None: if self._values['monitors'] is None:
return None return None
monitors = [self._fqdn_name(x) for x in self.monitors_list] monitors = [fq_name(self.partition, x) for x in self.monitors_list]
if self.monitor_type == 'm_of_n': if self.monitor_type == 'm_of_n':
monitors = ' '.join(monitors) monitors = ' '.join(monitors)
result = 'min %s of { %s }' % (self.quorum, monitors) result = 'min %s of { %s }' % (self.quorum, monitors)
@ -406,15 +432,11 @@ class Parameters(AnsibleF5Parameters):
result = ' and '.join(monitors).strip() result = ' and '.join(monitors).strip()
return result return result
def _verify_quorum_type(self, quorum): @property
try: def priority_group_activation(self):
if quorum is None: if self._values['priority_group_activation'] is None:
return None return None
return int(quorum) return int(self._values['priority_group_activation'])
except ValueError:
raise F5ModuleError(
"The specified 'quorum' must be an integer."
)
class ApiParameters(Parameters): class ApiParameters(Parameters):
@ -447,7 +469,7 @@ class ApiParameters(Parameters):
if self._values['monitors'] is None: if self._values['monitors'] is None:
return [] return []
try: try:
result = re.findall(r'/\w+/[^\s}]+', self._values['monitors']) result = re.findall(r'/[\w-]+/[^\s}]+', self._values['monitors'])
return result return result
except Exception: except Exception:
return self._values['monitors'] return self._values['monitors']
@ -534,7 +556,7 @@ class UsableChanges(Changes):
class ReportableChanges(Changes): class ReportableChanges(Changes):
@property @property
def monitors(self): def monitors(self):
result = sorted(re.findall(r'/\w+/[^\s}]+', self._values['monitors'])) result = sorted(re.findall(r'/[\w-]+/[^\s}]+', self._values['monitors']))
return result return result
@property @property
@ -794,6 +816,8 @@ class ModuleManager(object):
raise F5ModuleError( raise F5ModuleError(
"When using a 'monitor_type' of 'single', only one monitor may be provided" "When using a 'monitor_type' of 'single', only one monitor may be provided"
) )
if self.want.priority_group_activation is None:
self.want.update({'priority_group_activation': 0})
self._set_changed_options() self._set_changed_options()
if self.module.check_mode: if self.module.check_mode:
@ -903,6 +927,10 @@ class ArgumentSpec(object):
partition=dict( partition=dict(
default='Common', default='Common',
fallback=(env_fallback, ['F5_PARTITION']) fallback=(env_fallback, ['F5_PARTITION'])
),
priority_group_activation=dict(
type='int',
aliases=['minimum_active_members']
) )
) )
self.argument_spec = {} self.argument_spec = {}

File diff suppressed because it is too large Load Diff

@ -16,8 +16,9 @@ DOCUMENTATION = r'''
--- ---
module: bigip_profile_client_ssl module: bigip_profile_client_ssl
short_description: Manages client SSL profiles on a BIG-IP short_description: Manages client SSL profiles on a BIG-IP
description: Manages client SSL profiles on a BIG-IP. description:
version_added: "2.5" - Manages client SSL profiles on a BIG-IP.
version_added: 2.5
options: options:
name: name:
description: description:
@ -41,7 +42,8 @@ options:
type of each certificate/key type. This means that you can only have one type of each certificate/key type. This means that you can only have one
RSA, one DSA, and one ECDSA per profile. If you attempt to assign two RSA, one DSA, and one ECDSA per profile. If you attempt to assign two
RSA, DSA, or ECDSA certificate/key combo, the device will reject this. RSA, DSA, or ECDSA certificate/key combo, the device will reject this.
- This list is a complex list that specifies a number of keys. There are several supported keys. - This list is a complex list that specifies a number of keys. There are
several supported keys.
suboptions: suboptions:
cert: cert:
description: description:
@ -131,30 +133,25 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback from ansible.module_utils.basic import env_fallback
from ansible.module_utils.six import iteritems from ansible.module_utils.six import iteritems
HAS_DEVEL_IMPORTS = False
try: try:
# Sideband repository used for dev
from library.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens 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 fq_name
from library.module_utils.network.f5.common import f5_argument_spec from library.module_utils.network.f5.common import f5_argument_spec
try: try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError: except ImportError:
HAS_F5SDK = False HAS_F5SDK = False
HAS_DEVEL_IMPORTS = True
except ImportError: except ImportError:
# Upstream Ansible
from ansible.module_utils.network.f5.bigip import HAS_F5SDK 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.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError 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 AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens 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 fq_name
from ansible.module_utils.network.f5.common import f5_argument_spec from ansible.module_utils.network.f5.common import f5_argument_spec
try: try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
@ -181,11 +178,6 @@ class Parameters(AnsibleF5Parameters):
class ModuleParameters(Parameters): class ModuleParameters(Parameters):
def _fqdn_name(self, value):
if value is not None and not value.startswith('/'):
return '/{0}/{1}'.format(self.partition, value)
return value
def _key_filename(self, name): def _key_filename(self, name):
if name.endswith('.key'): if name.endswith('.key'):
return name return name
@ -202,14 +194,14 @@ class ModuleParameters(Parameters):
if 'chain' not in item or item['chain'] == 'none': if 'chain' not in item or item['chain'] == 'none':
result = 'none' result = 'none'
else: else:
result = self._cert_filename(self._fqdn_name(item['chain'])) result = self._cert_filename(fq_name(self.partition, item['chain']))
return result return result
@property @property
def parent(self): def parent(self):
if self._values['parent'] is None: if self._values['parent'] is None:
return None return None
result = self._fqdn_name(self._values['parent']) result = fq_name(self.partition, self._values['parent'])
return result return result
@property @property
@ -233,8 +225,8 @@ class ModuleParameters(Parameters):
filename, ex = os.path.splitext(name) filename, ex = os.path.splitext(name)
tmp = { tmp = {
'name': filename, 'name': filename,
'cert': self._fqdn_name(cert), 'cert': fq_name(self.partition, cert),
'key': self._fqdn_name(key), 'key': fq_name(self.partition, key),
'chain': chain 'chain': chain
} }
if 'passphrase' in item: if 'passphrase' in item:

@ -1079,7 +1079,6 @@ lib/ansible/modules/network/f5/bigip_iapp_service.py E324
lib/ansible/modules/network/f5/bigip_iapp_service.py E325 lib/ansible/modules/network/f5/bigip_iapp_service.py E325
lib/ansible/modules/network/f5/bigip_monitor_snmp_dca.py E326 lib/ansible/modules/network/f5/bigip_monitor_snmp_dca.py E326
lib/ansible/modules/network/f5/bigip_policy.py E324 lib/ansible/modules/network/f5/bigip_policy.py E324
lib/ansible/modules/network/f5/bigip_pool.py E326
lib/ansible/modules/network/f5/bigip_profile_client_ssl.py E324 lib/ansible/modules/network/f5/bigip_profile_client_ssl.py E324
lib/ansible/modules/network/f5/bigip_selfip.py E324 lib/ansible/modules/network/f5/bigip_selfip.py E324
lib/ansible/modules/network/f5/bigip_sys_global.py E326 lib/ansible/modules/network/f5/bigip_sys_global.py E326

@ -0,0 +1,25 @@
{
"kind": "tm:ltm:node:nodestate",
"name": "foo.bar.com",
"partition": "Common",
"fullPath": "/Common/foo.bar.com",
"generation": 157,
"selfLink": "https://localhost/mgmt/tm/ltm/node/~Common~foo.bar.com?ver=12.0.0",
"address": "any6",
"connectionLimit": 0,
"dynamicRatio": 1,
"ephemeral": "false",
"fqdn": {
"addressFamily": "ipv4",
"autopopulate": "enabled",
"downInterval": 5,
"interval": "3600",
"tmName": "foo.bar.com"
},
"logging": "disabled",
"monitor": "default",
"rateLimit": "disabled",
"ratio": 1,
"session": "user-enabled",
"state": "fqdn-up-no-addr"
}

@ -0,0 +1,24 @@
{
"kind": "tm:ltm:node:nodestate",
"name": "7.3.67.8",
"partition": "Common",
"fullPath": "/Common/7.3.67.8",
"generation": 162,
"selfLink": "https://localhost/mgmt/tm/ltm/node/~Common~7.3.67.8?ver=12.0.0",
"address": "7.3.67.8",
"connectionLimit": 0,
"dynamicRatio": 1,
"ephemeral": "false",
"fqdn": {
"addressFamily": "ipv4",
"autopopulate": "disabled",
"downInterval": 5,
"interval": "3600"
},
"logging": "disabled",
"monitor": "default",
"rateLimit": "disabled",
"ratio": 1,
"session": "user-enabled",
"state": "unchecked"
}

@ -21,9 +21,9 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
try: try:
from library.bigip_monitor_udp import Parameters from library.modules.bigip_monitor_udp import Parameters
from library.bigip_monitor_udp import ModuleManager from library.modules.bigip_monitor_udp import ModuleManager
from library.bigip_monitor_udp import ArgumentSpec from library.modules.bigip_monitor_udp import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError 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

@ -20,9 +20,9 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
try: try:
from library.bigip_node import Parameters from library.modules.bigip_node import Parameters
from library.bigip_node import ModuleManager from library.modules.bigip_node import ModuleManager
from library.bigip_node import ArgumentSpec from library.modules.bigip_node import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError 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

@ -20,9 +20,9 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
try: try:
from library.bigip_partition import Parameters from library.modules.bigip_partition import Parameters
from library.bigip_partition import ModuleManager from library.modules.bigip_partition import ModuleManager
from library.bigip_partition import ArgumentSpec from library.modules.bigip_partition import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError 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

@ -20,11 +20,11 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
try: try:
from library.bigip_policy import Parameters from library.modules.bigip_policy import Parameters
from library.bigip_policy import ModuleManager from library.modules.bigip_policy import ModuleManager
from library.bigip_policy import SimpleManager from library.modules.bigip_policy import SimpleManager
from library.bigip_policy import ComplexManager from library.modules.bigip_policy import ComplexManager
from library.bigip_policy import ArgumentSpec from library.modules.bigip_policy import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError 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

@ -20,11 +20,11 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
try: try:
from library.bigip_policy_rule import Parameters from library.modules.bigip_policy_rule import Parameters
from library.bigip_policy_rule import ModuleParameters from library.modules.bigip_policy_rule import ModuleParameters
from library.bigip_policy_rule import ApiParameters from library.modules.bigip_policy_rule import ApiParameters
from library.bigip_policy_rule import ModuleManager from library.modules.bigip_policy_rule import ModuleManager
from library.bigip_policy_rule import ArgumentSpec from library.modules.bigip_policy_rule import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError 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

@ -21,10 +21,10 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
try: try:
from library.bigip_pool import ApiParameters from library.modules.bigip_pool import ApiParameters
from library.bigip_pool import ModuleParameters from library.modules.bigip_pool import ModuleParameters
from library.bigip_pool import ModuleManager from library.modules.bigip_pool import ModuleManager
from library.bigip_pool import ArgumentSpec from library.modules.bigip_pool import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError 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

@ -0,0 +1,338 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2017 F5 Networks Inc.
# GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
import sys
from nose.plugins.skip import SkipTest
if sys.version_info < (2, 7):
raise SkipTest("F5 Ansible modules require Python >= 2.7")
from ansible.compat.tests import unittest
from ansible.compat.tests.mock import Mock
from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule
try:
from library.modules.bigip_pool_member import ModuleParameters
from library.modules.bigip_pool_member import ApiParameters
from library.modules.bigip_pool_member import NodeApiParameters
from library.modules.bigip_pool_member import ModuleManager
from library.modules.bigip_pool_member import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
from test.unit.modules.utils import set_module_args
except ImportError:
try:
from ansible.modules.network.f5.bigip_pool_member import ModuleParameters
from ansible.modules.network.f5.bigip_pool_member import ApiParameters
from ansible.modules.network.f5.bigip_pool_member import NodeApiParameters
from ansible.modules.network.f5.bigip_pool_member import ModuleManager
from ansible.modules.network.f5.bigip_pool_member import ArgumentSpec
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
except ImportError:
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
fixture_data = {}
def load_fixture(name):
path = os.path.join(fixture_path, name)
if path in fixture_data:
return fixture_data[path]
with open(path) as f:
data = f.read()
try:
data = json.loads(data)
except Exception:
pass
fixture_data[path] = data
return data
class TestParameters(unittest.TestCase):
def test_module_parameters(self):
args = dict(
pool='my-pool',
address='1.2.3.4',
fqdn='fqdn.foo.bar',
name='my-name',
port=2345,
connection_limit=100,
description='this is a description',
rate_limit=70,
ratio=20,
preserve_node=False,
priority_group=10,
state='present',
partition='Common',
fqdn_auto_populate=False,
reuse_nodes=False,
# Deprecated params
# TODO(Remove in 2.7)
session_state='disabled',
monitor_state='disabled',
)
p = ModuleParameters(params=args)
assert p.name == 'my-name'
def test_api_parameters(self):
args = load_fixture('load_net_node_with_fqdn.json')
p = ApiParameters(params=args)
assert p.state == 'present'
class TestManager(unittest.TestCase):
def setUp(self):
self.spec = ArgumentSpec()
def test_create_reuse_node_with_name(self, *args):
# Configure the arguments that would be sent to the Ansible module
set_module_args(dict(
pool='my-pool',
name='my-name',
port=2345,
state='present',
partition='Common',
reuse_nodes=True,
password='password',
server='localhost',
user='admin'
))
current_node = NodeApiParameters(params=load_fixture('load_net_node_with_fqdn.json'))
module = AnsibleModule(
argument_spec=self.spec.argument_spec,
supports_check_mode=self.spec.supports_check_mode
)
mm = ModuleManager(module=module)
# Override methods to force specific logic in the module to happen
mm.exists = Mock(return_value=False)
mm.create_on_device = Mock(return_value=True)
mm.read_current_node_from_device = Mock(return_value=current_node)
results = mm.exec_module()
assert results['changed'] is True
assert results['fqdn_auto_populate'] is True
assert results['fqdn'] == 'foo.bar.com'
assert results['state'] == 'present'
def test_create_reuse_node_with_ipv4_address(self, *args):
# Configure the arguments that would be sent to the Ansible module
set_module_args(dict(
pool='my-pool',
name='7.3.67.8',
port=2345,
state='present',
partition='Common',
reuse_nodes=True,
password='password',
server='localhost',
user='admin'
))
current_node = NodeApiParameters(params=load_fixture('load_net_node_with_ipv4_address.json'))
module = AnsibleModule(
argument_spec=self.spec.argument_spec,
supports_check_mode=self.spec.supports_check_mode
)
mm = ModuleManager(module=module)
# Override methods to force specific logic in the module to happen
mm.exists = Mock(return_value=False)
mm.create_on_device = Mock(return_value=True)
mm.read_current_node_from_device = Mock(return_value=current_node)
results = mm.exec_module()
assert results['changed'] is True
assert results['fqdn_auto_populate'] is False
assert results['address'] == '7.3.67.8'
assert results['state'] == 'present'
def test_create_reuse_node_with_fqdn_auto_populate(self, *args):
# Configure the arguments that would be sent to the Ansible module
set_module_args(dict(
pool='my-pool',
name='my-name',
port=2345,
state='present',
partition='Common',
reuse_nodes=True,
fqdn_auto_populate=False,
password='password',
server='localhost',
user='admin'
))
current_node = NodeApiParameters(params=load_fixture('load_net_node_with_fqdn.json'))
module = AnsibleModule(
argument_spec=self.spec.argument_spec,
supports_check_mode=self.spec.supports_check_mode
)
mm = ModuleManager(module=module)
# Override methods to force specific logic in the module to happen
mm.exists = Mock(return_value=False)
mm.create_on_device = Mock(return_value=True)
mm.read_current_node_from_device = Mock(return_value=current_node)
results = mm.exec_module()
assert results['changed'] is True
assert results['fqdn_auto_populate'] is True
assert results['fqdn'] == 'foo.bar.com'
assert results['state'] == 'present'
class TestLegacyManager(unittest.TestCase):
def setUp(self):
self.spec = ArgumentSpec()
def test_create_name_is_hostname_with_session_and_monitor_enabled(self, *args):
# Configure the arguments that would be sent to the Ansible module
set_module_args(dict(
pool='my-pool',
name='my-name',
port=2345,
state='present',
session_state='enabled',
monitor_state='enabled',
partition='Common',
password='password',
server='localhost',
user='admin'
))
module = AnsibleModule(
argument_spec=self.spec.argument_spec,
supports_check_mode=self.spec.supports_check_mode
)
mm = ModuleManager(module=module)
# Override methods to force specific logic in the module to happen
mm.exists = Mock(return_value=False)
mm.create_on_device = Mock(return_value=True)
results = mm.exec_module()
assert results['changed'] is True
assert results['fqdn_auto_populate'] is False
assert results['fqdn'] == 'my-name'
assert results['state'] == 'present'
def test_create_name_is_address_with_session_and_monitor_enabled(self, *args):
# Configure the arguments that would be sent to the Ansible module
set_module_args(dict(
pool='my-pool',
name='10.10.10.10',
port=2345,
state='present',
session_state='enabled',
monitor_state='enabled',
partition='Common',
password='password',
server='localhost',
user='admin'
))
module = AnsibleModule(
argument_spec=self.spec.argument_spec,
supports_check_mode=self.spec.supports_check_mode
)
mm = ModuleManager(module=module)
# Override methods to force specific logic in the module to happen
mm.exists = Mock(return_value=False)
mm.create_on_device = Mock(return_value=True)
results = mm.exec_module()
assert results['changed'] is True
assert results['fqdn_auto_populate'] is False
assert results['address'] == '10.10.10.10'
assert results['state'] == 'present'
def test_create_name_is_address_with_session_disabled_and_monitor_enabled(self, *args):
# Configure the arguments that would be sent to the Ansible module
set_module_args(dict(
pool='my-pool',
name='10.10.10.10',
port=2345,
state='present',
monitor_state='enabled',
session_state='disabled',
partition='Common',
password='password',
server='localhost',
user='admin'
))
module = AnsibleModule(
argument_spec=self.spec.argument_spec,
supports_check_mode=self.spec.supports_check_mode
)
mm = ModuleManager(module=module)
# Override methods to force specific logic in the module to happen
mm.exists = Mock(return_value=False)
mm.create_on_device = Mock(return_value=True)
results = mm.exec_module()
assert results['changed'] is True
assert results['fqdn_auto_populate'] is False
assert results['address'] == '10.10.10.10'
assert results['state'] == 'disabled'
def test_create_name_is_address_with_session_and_monitor_disabled(self, *args):
# Configure the arguments that would be sent to the Ansible module
set_module_args(dict(
pool='my-pool',
name='10.10.10.10',
port=2345,
state='present',
monitor_state='disabled',
session_state='disabled',
partition='Common',
password='password',
server='localhost',
user='admin'
))
module = AnsibleModule(
argument_spec=self.spec.argument_spec,
supports_check_mode=self.spec.supports_check_mode
)
mm = ModuleManager(module=module)
# Override methods to force specific logic in the module to happen
mm.exists = Mock(return_value=False)
mm.create_on_device = Mock(return_value=True)
results = mm.exec_module()
assert results['changed'] is True
assert results['fqdn_auto_populate'] is False
assert results['address'] == '10.10.10.10'
assert results['state'] == 'forced_offline'

@ -21,10 +21,10 @@ from ansible.compat.tests.mock import patch
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
try: try:
from library.bigip_profile_client_ssl import ModuleParameters from library.modules.bigip_profile_client_ssl import ModuleParameters
from library.bigip_profile_client_ssl import ApiParameters from library.modules.bigip_profile_client_ssl import ApiParameters
from library.bigip_profile_client_ssl import ModuleManager from library.modules.bigip_profile_client_ssl import ModuleManager
from library.bigip_profile_client_ssl import ArgumentSpec from library.modules.bigip_profile_client_ssl import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError 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

Loading…
Cancel
Save