diff --git a/network/f5/bigip_node.py b/network/f5/bigip_node.py index bc209af6ae6..3f57251218a 100644 --- a/network/f5/bigip_node.py +++ b/network/f5/bigip_node.py @@ -99,6 +99,30 @@ options: required: false default: null choices: [] + monitor_type: + description: + - Monitor rule type when monitors > 1 + version_added: "2.2" + required: False + default: null + choices: ['and_list', 'm_of_n'] + aliases: [] + quorum: + description: + - Monitor quorum value when monitor_type is m_of_n + version_added: "2.2" + required: False + default: null + choices: [] + aliases: [] + monitors: + description: + - Monitor template name list. Always use the full path to the monitor. + version_added: "2.2" + required: False + default: null + choices: [] + aliases: [] host: description: - "Node IP. Required when state=present and node does not exist. Error when state=absent." @@ -141,6 +165,18 @@ EXAMPLES = ''' # Alternatively, you could have specified a name with the # name parameter when state=present. + - name: Add node with a single 'ping' monitor + bigip_node: + server: lb.mydomain.com + user: admin + password: mysecret + state: present + partition: Common + host: "{{ ansible_default_ipv4["address"] }}" + name: mytestserver + monitors: + - /Common/icmp + - name: Modify node description local_action: > bigip_node @@ -261,15 +297,32 @@ def get_node_monitor_status(api, name): result = result.split("MONITOR_STATUS_")[-1].lower() return result +def get_monitors(api, name): + result = api.LocalLB.NodeAddressV2.get_monitor_rule(nodes=[name])[0] + monitor_type = result['type'].split("MONITOR_RULE_TYPE_")[-1].lower() + quorum = result['quorum'] + monitor_templates = result['monitor_templates'] + return (monitor_type, quorum, monitor_templates) + +def set_monitors(api, name, monitor_type, quorum, monitor_templates): + monitor_type = "MONITOR_RULE_TYPE_%s" % monitor_type.strip().upper() + monitor_rule = {'type': monitor_type, 'quorum': quorum, 'monitor_templates': monitor_templates} + api.LocalLB.NodeAddressV2.set_monitor_rule(nodes=[name], + monitor_rules=[monitor_rule]) def main(): + monitor_type_choices = ['and_list', 'm_of_n'] + argument_spec=f5_argument_spec() argument_spec.update(dict( session_state = dict(type='str', choices=['enabled', 'disabled']), monitor_state = dict(type='str', choices=['enabled', 'disabled']), name = dict(type='str', required=True), host = dict(type='str', aliases=['address', 'ip']), - description = dict(type='str') + description = dict(type='str'), + monitor_type = dict(type='str', choices=monitor_type_choices), + quorum = dict(type='int'), + monitors = dict(type='list') ) ) @@ -299,10 +352,40 @@ def main(): name = module.params['name'] address = fq_name(partition, name) description = module.params['description'] + monitor_type = module.params['monitor_type'] + if monitor_type: + monitor_type = monitor_type.lower() + quorum = module.params['quorum'] + monitors = module.params['monitors'] + if monitors: + monitors = [] + for monitor in module.params['monitors']: + monitors.append(fq_name(partition, monitor)) + + # sanity check user supplied values if state == 'absent' and host is not None: module.fail_json(msg="host parameter invalid when state=absent") + if monitors: + if len(monitors) == 1: + # set default required values for single monitor + quorum = 0 + monitor_type = 'single' + elif len(monitors) > 1: + if not monitor_type: + module.fail_json(msg="monitor_type required for monitors > 1") + if monitor_type == 'm_of_n' and not quorum: + module.fail_json(msg="quorum value required for monitor_type m_of_n") + if monitor_type != 'm_of_n': + quorum = 0 + elif monitor_type: + # no monitors specified but monitor_type exists + module.fail_json(msg="monitor_type require monitors parameter") + elif quorum is not None: + # no monitors specified but quorum exists + module.fail_json(msg="quorum requires monitors parameter") + try: api = bigip_api(server, user, password, validate_certs) result = {'changed': False} # default @@ -340,6 +423,8 @@ def main(): if description is not None: set_node_description(api, address, description) result = {'changed': True} + if monitors: + set_monitors(api, address, monitor_type, quorum, monitors) else: # check-mode return value result = {'changed': True} @@ -383,6 +468,12 @@ def main(): if not module.check_mode: set_node_description(api, address, description) result = {'changed': True} + if monitors: + t_monitor_type, t_quorum, t_monitor_templates = get_monitors(api, address) + if (t_monitor_type != monitor_type) or (t_quorum != quorum) or (set(t_monitor_templates) != set(monitors)): + if not module.check_mode: + set_monitors(api, address, monitor_type, quorum, monitors) + result = {'changed': True} except Exception, e: module.fail_json(msg="received exception: %s" % e)