From a6864b4c4d5059c742ed3310bc7a24befd37ab48 Mon Sep 17 00:00:00 2001 From: Jake Reynolds Date: Thu, 7 Jan 2021 17:15:04 +0000 Subject: [PATCH] Rework to satisfy comments on #392 --- plugins/modules/ipaautomember.py | 179 ++++++++++++++++++++++--------- 1 file changed, 126 insertions(+), 53 deletions(-) diff --git a/plugins/modules/ipaautomember.py b/plugins/modules/ipaautomember.py index b895e39fde..7723746c31 100644 --- a/plugins/modules/ipaautomember.py +++ b/plugins/modules/ipaautomember.py @@ -23,8 +23,10 @@ from ansible.module_utils._text import to_text from ansible.module_utils.ansible_freeipa_module import (api_command, + api_command_no_name, api_connect, compare_args_ipa, + gen_add_del_lists, temp_kdestroy, temp_kinit, valid_creds) @@ -75,6 +77,10 @@ type: list elements: dict aliases: ["automemberinclusiveregex"] + action: + description: Work on service or member level + default: service + choices: ["member", "service"] state: description: State to ensure default: present @@ -120,8 +126,8 @@ def find_automember(module, name, grouping): def gen_condition_args(grouping, key, - inclusiveregex, - exclusiveregex): + inclusiveregex=None, + exclusiveregex=None): _args = {} if grouping is not None: _args['type'] = to_text(grouping) @@ -191,8 +197,10 @@ def main(): description=dict(type="str", default=None), type=dict(type='str', required=True, choices=['group', 'hostgroup']), + action=dict(type="str", default="service", + choices=["member", "service"]), state=dict(type="str", default="present", - choices=["present", "absent"]), + choices=["present", "absent", "rebuild"]), ), supports_check_mode=True, ) @@ -213,6 +221,8 @@ def main(): inclusive = ansible_module.params.get("inclusive") exclusive = ansible_module.params.get("exclusive") + # action + action = ansible_module.params.get("action") # state state = ansible_module.params.get("state") @@ -242,63 +252,126 @@ def main(): if state == 'present': args = gen_args(description, grouping) - if res_find is not None: - if not compare_args_ipa(ansible_module, - args, res_find, ['type']): - commands.append([name, 'automember_mod', args]) - else: - commands.append([name, 'automember_add', args]) - res_find = {} + if action == "service": + if res_find is not None: + if not compare_args_ipa(ansible_module, + args, + res_find, + ignore=['type']): + commands.append([name, 'automember_mod', args]) + else: + commands.append([name, 'automember_add', args]) + res_find = {} + + inclusive_add, inclusive_del = gen_add_del_lists( + transform_conditions(inclusive or []), + res_find.get("automemberinclusiveregex", []) + ) + + exclusive_add, exclusive_del = gen_add_del_lists( + transform_conditions(exclusive or []), + res_find.get("automemberexclusiveregex", []) + ) + + elif action == "member": + if res_find is None: + ansible_module.fail_json(msg="No service '%s'" % name) + + inclusive_add = transform_conditions(inclusive or []) + inclusive_del = [] + exclusive_add = transform_conditions(exclusive or []) + exclusive_del = [] if inclusive is not None: + for _inclusive in inclusive_add: + key, regex = _inclusive.split("=") + condition_args = gen_condition_args( + grouping, key, inclusiveregex=regex) + commands.append([name, 'automember_add_condition', + condition_args]) + + for _inclusive in inclusive_del: + key, regex = _inclusive.split("=") + condition_args = gen_condition_args( + grouping, key, inclusiveregex=regex) + commands.append([name, 'automember_remove_condition', + condition_args]) + + if exclusive is not None: + for _exclusive in exclusive_add: + key, regex = _exclusive.split("=") + condition_args = gen_condition_args( + grouping, key, exclusiveregex=regex) + commands.append([name, 'automember_add_condition', + condition_args]) + + for _exclusive in exclusive_del: + key, regex = _exclusive.split("=") + condition_args = gen_condition_args( + grouping, key, exclusiveregex=regex) + commands.append([name, 'automember_remove_condition', + condition_args]) - # Get the conditions from the module - module_conditions = transform_conditions(inclusive) - - # Get the conditions from the existing automember rule. - current_conditions = res_find.get( - 'automemberinclusiveregex', []) - - # Append the commands to the list - commands.extend(gen_condition_commands( - name, grouping, module_conditions, current_conditions)) - - if exclusive is not None and False: - - # Get the conditions from the module - module_conditions = transform_conditions(exclusive) - - # Get the conditions from the existing automember rule. - current_conditions = res_find.get( - 'automemberexclusiveregex', []) - - # Append the commands to the list - commands.extend(gen_condition_commands( - name, grouping, module_conditions, current_conditions)) elif state == 'absent': - if res_find is not None: - commands.append( - [name, 'automember_del', {'type': to_text(grouping)}]) - + if action == "service": + if res_find is not None: + commands.append([name, 'automember_del', + {'type': to_text(grouping)}]) + + elif action == "member": + if res_find is None: + ansible_module.fail_json(msg="No service '%s'" % name) + + if inclusive is not None: + for _inclusive in inclusive: + key, regex = _inclusive.split("=") + condition_args = gen_condition_args( + grouping, key, inclusiveregex=regex) + commands.append( + [name, 'automember_remove_condition', + condition_args]) + + if exclusive is not None: + for _exclusive in exclusive: + key, regex = _exclusive.split("=") + condition_args = gen_condition_args( + grouping, key, exclusiveregex=regex) + commands.append([name, + 'automember_remove_condition', + condition_args]) + + elif state == "rebuild": + if res_find is None: + ansible_module.fail_json(msg="No service '%s'" % name) + commands.append([None, 'automember_rebuild', + {"type": to_text(grouping)}]) + + errors = [] for name, command, args in commands: try: - result = api_command( - ansible_module, command, to_text(name), args) - - # Check if any changes were made by any command - if command in ('automember_del', - 'automember_remove_condition'): - changed |= "Deleted" in result['summary'] - - elif command in ('automember_add', - 'automember_add_condition'): - changed |= "Added" in result['summary'] - - elif command == 'automember_mod': - changed |= "Modified" in result['summary'] + if name is None: + result = api_command_no_name(ansible_module, command, args) + else: + result = api_command(ansible_module, command, name, args) - except Exception as e: - ansible_module.fail_json(msg=str(e)) + if "completed" in result: + if result["completed"] > 0: + changed = True + else: + changed = True + except Exception as ex: + ansible_module.fail_json(msg="%s: %s: %s" % (command, name, + str(ex))) + # Get all errors + if "failed" in result and len(result["failed"]) > 0: + for item in result["failed"]: + failed_item = result["failed"][item] + for member_type in failed_item: + for member, failure in failed_item[member_type]: + errors.append("%s: %s %s: %s" % ( + command, member_type, member, failure)) + if len(errors) > 0: + ansible_module.fail_json(msg=", ".join(errors)) except Exception as e: ansible_module.fail_json(msg=str(e))