do not overwrite properties with defaults

This commit is contained in:
Serge van Ginderachter 2013-09-05 15:34:12 +02:00
parent f8e40583f2
commit 62d7b1a62f

View file

@ -82,34 +82,36 @@ options:
description: description:
- The send string for the monitor call - The send string for the monitor call
required: true required: true
default: '' default: none
receive: receive:
description: description:
- The receive string for the monitor call - The receive string for the monitor call
required: true required: true
default: '' default: none
receive_disable: receive_disable:
description: description:
- The receive disable string for the monitor call - The receive disable string for the monitor call
required: true required: true
default: '' default: none
ip: ip:
description: description:
- IP address part of the ipport definition - IP address part of the ipport definition. The default API setting
is "0.0.0.0".
required: false required: false
default: '0.0.0.0' default: none
port: port:
description: description:
- port address part op the ipport definition - port address part op the ipport definition. Tyhe default API
setting is 0.
required: false required: false
default: 0 default: none
interval: interval:
description: description:
- The interval specifying how frequently the monitor instance - The interval specifying how frequently the monitor instance
of this template will run. By default, this interval is used for up and of this template will run. By default, this interval is used for up and
down states down states. The default API setting is 5.
required: false required: false
default: 5 default: none
timeout: timeout:
description: description:
- The number of seconds in which the node or service must respond to - The number of seconds in which the node or service must respond to
@ -117,17 +119,18 @@ options:
period, it is considered up. If the target does not respond within period, it is considered up. If the target does not respond within
the set time period, it is considered down. You can change this the set time period, it is considered down. You can change this
number to any number you want, however, it should be 3 times the number to any number you want, however, it should be 3 times the
interval number of seconds plus 1 second. interval number of seconds plus 1 second. The default API setting
is 16.
required: false required: false
default: 16 default: none
time_until_up: time_until_up:
description: description:
- Specifies the amount of time in seconds after the first successful - Specifies the amount of time in seconds after the first successful
response before a node will be marked up. A value of 0 will cause a response before a node will be marked up. A value of 0 will cause a
node to be marked up immediately after a valid response is received node to be marked up immediately after a valid response is received
from the node. The default setting is 0. from the node. The default API setting is 0.
required: false required: false
default: 0 default: none
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -156,7 +159,7 @@ def bigip_api(bigip, user, password):
return api return api
def monitor_exists(module, api, monitor, parent): def check_monitor_exists(module, api, monitor, parent):
# hack to determine if monitor exists # hack to determine if monitor exists
result = False result = False
@ -202,6 +205,7 @@ def delete_monitor(api, monitor):
raise raise
return True return True
def check_string_property(api, monitor, str_property): def check_string_property(api, monitor, str_property):
return str_property == api.LocalLB.Monitor.get_template_string_property([monitor], [str_property['type']])[0] return str_property == api.LocalLB.Monitor.get_template_string_property([monitor], [str_property['type']])[0]
@ -221,9 +225,32 @@ def set_integer_property(api, monitor, int_property):
api.LocalLB.Monitor.set_template_int_property(template_names=[monitor], values=[int_property]) api.LocalLB.Monitor.set_template_int_property(template_names=[monitor], values=[int_property])
def check_ipport(api, monitor, ipport):
return [ipport] == api.LocalLB.Monitor.get_template_destination(template_names=[monitor]) def update_monitor_properties(api, module, monitor, template_string_properties, template_integer_properties):
changed = False
for str_property in template_string_properties:
if str_property['value'] is not None and not check_string_property(api, monitor, str_property):
if not module.check_mode:
set_string_property(api, monitor, str_property)
changed = True
for int_property in template_integer_properties:
if int_property['value'] is not None and not check_integer_property(api, monitor, int_property):
if not module.check_mode:
set_integer_property(api, monitor, int_property)
changed = True
return changed
# ===========================================
# monitor specific function
#
def get_ipport(api, monitor):
return api.LocalLB.Monitor.get_template_destination(template_names=[monitor])[0]
def set_ipport(api, monitor, ipport): def set_ipport(api, monitor, ipport):
@ -242,10 +269,11 @@ def set_ipport(api, monitor, ipport):
# main loop # main loop
# #
# writing a module for other monitor types should # writing a module for other monitor types should
# only need an updated main() # only need an updated main() (and monitor specific functions)
def main(): def main():
# monitor specific stuff
module = AnsibleModule( module = AnsibleModule(
argument_spec = dict( argument_spec = dict(
@ -257,21 +285,18 @@ def main():
name = dict(required=True), name = dict(required=True),
parent = dict(default=DEFAULT_PARENT_TYPE), parent = dict(default=DEFAULT_PARENT_TYPE),
parent_partition = dict(default='Common'), parent_partition = dict(default='Common'),
send = dict(required=True, default=''), send = dict(required=False),
receive = dict(required=True, default=''), receive = dict(required=False),
receive_disable = dict(required=True, default=''), receive_disable = dict(required=False),
ip = dict(required=False, default='0.0.0.0'), ip = dict(required=False),
port = dict(required=False, type='int', default=0), port = dict(required=False, type='int'),
interval = dict(required=False, type='int', default=5), interval = dict(required=False, type='int'),
timeout = dict(required=False, type='int', default=16) timeout = dict(required=False, type='int'),
time_until_up = dict(required=False, type='int', default=0) time_until_up = dict(required=False, type='int', default=0)
), ),
supports_check_mode=True supports_check_mode=True
) )
if not bigsuds_found:
module.fail_json(msg="the python bigsuds module is required")
server = module.params['server'] server = module.params['server']
user = module.params['user'] user = module.params['user']
password = module.params['password'] password = module.params['password']
@ -291,6 +316,27 @@ def main():
time_until_up = module.params['time_until_up'] time_until_up = module.params['time_until_up']
if not bigsuds_found:
module.fail_json(msg="the python bigsuds module is required")
api = bigip_api(server, user, password)
monitor_exists = check_monitor_exists(module, api, monitor, parent)
# ipport is a special setting
if monitor_exists: # make sure to not update current settings if not asked
cur_ipport = get_ipport(api, monitor)
if ip is None:
ip = cur_ipport['ipport']['address']
if port is None:
port = cur_ipport['ipport']['port']
else: # use API defaults if not defined to create it
if ip is None: ip = '0.0.0.0'
if port is None: port = 0
if send is None: send = ''
if receive is None: reveive = ''
if receive_disable is None: receive_disable = ''
# define and set address type
if ip == '0.0.0.0' and port == 0: if ip == '0.0.0.0' and port == 0:
address_type = 'ATYPE_STAR_ADDRESS_STAR_PORT' address_type = 'ATYPE_STAR_ADDRESS_STAR_PORT'
elif ip == '0.0.0.0' and port != 0: elif ip == '0.0.0.0' and port != 0:
@ -300,11 +346,33 @@ def main():
else: else:
address_type = 'ATYPE_UNSET' address_type = 'ATYPE_UNSET'
ipport = {'address_type': address_type,
'ipport': {'address': ip,
'port': port}}
# main logic template_attributes = {'parent_template': parent,
'dest_ipport': ipport,
'is_read_only': False,
'is_directly_usable': True}
template_string_properties = [{'type': 'STYPE_SEND',
'value': send},
{'type': 'STYPE_RECEIVE',
'value': receive},
{'type': 'STYPE_RECEIVE_DRAIN',
'value': receive_disable}]
template_integer_properties = [{'type': 'ITYPE_INTERVAL',
'value': interval},
{'type': 'ITYPE_TIMEOUT',
'value': timeout},
{'type': 'ITYPE_TIME_UNTIL_UP',
'value': interval}]
# monitor specific stuff END
# main logic, mostly monitor generic
try: try:
api = bigip_api(server, user, password)
result = {'changed': False} # default result = {'changed': False} # default
@ -313,62 +381,33 @@ def main():
if not module.check_mode: if not module.check_mode:
# possible race condition if same task # possible race condition if same task
# on other node deleted it first # on other node deleted it first
result['changed'] = delete_monitor(api, monitor) result['changed'] |= delete_monitor(api, monitor)
else: else:
result['changed'] = True result['changed'] |= True
else: # state present
if not monitor_exists: # create it
if not module.check_mode:
# again, check changed status here b/c race conditions
# if other task already created it
result['changed'] |= create_monitor(api, monitor, template_attributes)
else: else:
ipport = {'address_type': address_type, result['changed'] |= True
'ipport': {'address': ip,
'port': port}}
template_attributes = {'parent_template': parent, # whether it already existed, or was just created, now update
'dest_ipport': ipport, # attributes and properties
'interval': interval, # the update functions need to check for check mode
'timeout': timeout, result['changed'] |= update_monitor_properties(api, module, monitor,
'is_read_only': False, template_string_properties,
'is_directly_usable': True template_integer_properties)
}
template_string_properties = [{'type': 'STYPE_SEND',
'value': send},
{'type': 'STYPE_RECEIVE',
'value': receive}
{'type': 'STYPE_RECEIVE_DRAIN',
'value': receive_disable}]
template_integer_properties = [{'type': 'ITYPE_INTERVAL',
'value': interval},
{'type': 'ITYPE_TIMEOUT',
'value': timeout},
{'type': 'ITYPE_TIME_UNTIL_UP',
'value': interval}]
if monitor_exists(module, api, monitor, parent):
for str_property in template_string_properties:
if not check_string_property(api, monitor, str_property):
if not module.check_mode:
set_string_property(api, monitor, str_property)
result['changed'] = True
for int_property in template_integer_properties:
if not check_integer_property(api, monitor, int_property):
if not module.check_mode:
set_integer_property(api, monitor, int_property)
result['changed'] = True
if not check_ipport(api, monitor, ipport):
if not module.check_mode:
res, msg = set_ipport(api, monitor, ipport)
if not res:
module.fail_json(msg=msg)
result['changed'] = True
elif not module.check_mode: # monitor specific stuff
# possible race condition if same task # we just have to update the ipport if monitor already exists and it's different
# on other node deleted it first if monitor_exists and cur_ipport != ipport:
result['changed'] = create_monitor(api, monitor, template_attributes) if not monitor_exists:
for str_property in template_string_properties: set_ipport(api, monitor, ipport)
set_string_property(api, monitor, str_property) result['changed'] |= True
for int_property in template_integer_properties: # monitor specific stuff
set_integer_property(api, monitor, int_property)
else: # monitor does not exist and check mode
result['changed'] = True
except Exception, e: except Exception, e: