From 457050c6ac79c008d495d72af0dc91b03e998bb1 Mon Sep 17 00:00:00 2001 From: Thomas Woerner <twoerner@redhat.com> Date: Wed, 6 May 2020 16:28:02 +0200 Subject: [PATCH] Do not remove member attributes while updating others Because of a missing check member attributes (for use with action: member) are cleared when a non-member attribute is changed. The fix simply adds a check for None (parameter not set) to gen_add_del_lists in ansible_freeipa_module to make sure that the parameter is only changed if it should be changed. All places where the add and removal lists have been generated manually have been changed to also use gen_add_del_lists. Resolves: #252 (The "Manager" attribute is removed when updating any user attribute) --- .../module_utils/ansible_freeipa_module.py | 4 ++ plugins/modules/ipagroup.py | 28 +++------ plugins/modules/ipahbacrule.py | 58 ++++++------------- plugins/modules/ipahbacsvcgroup.py | 11 ++-- plugins/modules/ipahostgroup.py | 19 ++---- plugins/modules/ipasudocmdgroup.py | 13 ++--- plugins/modules/ipauser.py | 35 ++++------- tests/user/test_user.yml | 4 +- tests/user/test_users.yml | 4 +- 9 files changed, 62 insertions(+), 114 deletions(-) diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py index bf9eca82..af45a6cb 100644 --- a/plugins/module_utils/ansible_freeipa_module.py +++ b/plugins/module_utils/ansible_freeipa_module.py @@ -298,6 +298,10 @@ def api_get_realm(): def gen_add_del_lists(user_list, res_list): """Generate the lists for the addition and removal of members.""" + # The user list is None, therefore the parameter should not be touched + if user_list is None: + return [], [] + add_list = list(set(user_list or []) - set(res_list or [])) del_list = list(set(res_list or []) - set(user_list or [])) diff --git a/plugins/modules/ipagroup.py b/plugins/modules/ipagroup.py index 10a61144..c1ffea3e 100644 --- a/plugins/modules/ipagroup.py +++ b/plugins/modules/ipagroup.py @@ -141,7 +141,7 @@ RETURN = """ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \ - api_check_param, module_params_get + api_check_param, module_params_get, gen_add_del_lists def find_group(module, name): @@ -317,24 +317,14 @@ def main(): if not compare_args_ipa(ansible_module, member_args, res_find): # Generate addition and removal lists - user_add = list( - set(user or []) - - set(res_find.get("member_user", []))) - user_del = list( - set(res_find.get("member_user", [])) - - set(user or [])) - group_add = list( - set(group or []) - - set(res_find.get("member_group", []))) - group_del = list( - set(res_find.get("member_group", [])) - - set(group or [])) - service_add = list( - set(service or []) - - set(res_find.get("member_service", []))) - service_del = list( - set(res_find.get("member_service", [])) - - set(service or [])) + user_add, user_del = gen_add_del_lists( + user, res_find.get("member_user")) + + group_add, group_del = gen_add_del_lists( + group, res_find.get("member_group")) + + service_add, service_del = gen_add_del_lists( + service, res_find.get("member_service")) if has_add_member_service: # Add members diff --git a/plugins/modules/ipahbacrule.py b/plugins/modules/ipahbacrule.py index fd0ce238..452f9f8c 100644 --- a/plugins/modules/ipahbacrule.py +++ b/plugins/modules/ipahbacrule.py @@ -159,7 +159,7 @@ RETURN = """ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \ - module_params_get + module_params_get, gen_add_del_lists def find_hbacrule(module, name): @@ -342,44 +342,24 @@ def main(): res_find = {} # Generate addition and removal lists - host_add = list( - set(host or []) - - set(res_find.get("memberhost_host", []))) - host_del = list( - set(res_find.get("memberhost_host", [])) - - set(host or [])) - hostgroup_add = list( - set(hostgroup or []) - - set(res_find.get("memberhost_hostgroup", []))) - hostgroup_del = list( - set(res_find.get("memberhost_hostgroup", [])) - - set(hostgroup or [])) - - hbacsvc_add = list( - set(hbacsvc or []) - - set(res_find.get("memberservice_hbacsvc", []))) - hbacsvc_del = list( - set(res_find.get("memberservice_hbacsvc", [])) - - set(hbacsvc or [])) - hbacsvcgroup_add = list( - set(hbacsvcgroup or []) - - set(res_find.get("memberservice_hbacsvcgroup", []))) - hbacsvcgroup_del = list( - set(res_find.get("memberservice_hbacsvcgroup", [])) - - set(hbacsvcgroup or [])) - - user_add = list( - set(user or []) - - set(res_find.get("memberuser_user", []))) - user_del = list( - set(res_find.get("memberuser_user", [])) - - set(user or [])) - group_add = list( - set(group or []) - - set(res_find.get("memberuser_group", []))) - group_del = list( - set(res_find.get("memberuser_group", [])) - - set(group or [])) + host_add, host_del = gen_add_del_lists( + host, res_find.get("memberhost_host")) + + hostgroup_add, hostgroup_del = gen_add_del_lists( + hostgroup, res_find.get("memberhost_hostgroup")) + + hbacsvc_add, hbacsvc_del = gen_add_del_lists( + hbacsvc, res_find.get("memberservice_hbacsvc")) + + hbacsvcgroup_add, hbacsvcgroup_del = gen_add_del_lists( + hbacsvcgroup, + res_find.get("memberservice_hbacsvcgroup")) + + user_add, user_del = gen_add_del_lists( + user, res_find.get("memberuser_user")) + + group_add, group_del = gen_add_del_lists( + group, res_find.get("memberuser_group")) # Add hosts and hostgroups if len(host_add) > 0 or len(hostgroup_add) > 0: diff --git a/plugins/modules/ipahbacsvcgroup.py b/plugins/modules/ipahbacsvcgroup.py index 3b9132a0..d55dc138 100644 --- a/plugins/modules/ipahbacsvcgroup.py +++ b/plugins/modules/ipahbacsvcgroup.py @@ -104,7 +104,8 @@ RETURN = """ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_text from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ - temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa + temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \ + gen_add_del_lists def find_hbacsvcgroup(module, name): @@ -249,12 +250,8 @@ def main(): if not compare_args_ipa(ansible_module, member_args, res_find): # Generate addition and removal lists - hbacsvc_add = list( - set(hbacsvc or []) - - set(res_find.get("member_hbacsvc", []))) - hbacsvc_del = list( - set(res_find.get("member_hbacsvc", [])) - - set(hbacsvc or [])) + hbacsvc_add, hbacsvc_del = gen_add_del_lists( + hbacsvc, res_find.get("member_hbacsvc")) # Add members if len(hbacsvc_add) > 0: diff --git a/plugins/modules/ipahostgroup.py b/plugins/modules/ipahostgroup.py index 5fcca1d6..7e1891d3 100644 --- a/plugins/modules/ipahostgroup.py +++ b/plugins/modules/ipahostgroup.py @@ -117,7 +117,7 @@ RETURN = """ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \ - module_params_get + module_params_get, gen_add_del_lists def find_hostgroup(module, name): @@ -268,18 +268,11 @@ def main(): if not compare_args_ipa(ansible_module, member_args, res_find): # Generate addition and removal lists - host_add = list( - set(host or []) - - set(res_find.get("member_host", []))) - host_del = list( - set(res_find.get("member_host", [])) - - set(host or [])) - hostgroup_add = list( - set(hostgroup or []) - - set(res_find.get("member_hostgroup", []))) - hostgroup_del = list( - set(res_find.get("member_hostgroup", [])) - - set(hostgroup or [])) + host_add, host_del = gen_add_del_lists( + host, res_find.get("member_host")) + + hostgroup_add, hostgroup_del = gen_add_del_lists( + hostgroup, res_find.get("member_hostgroup")) # Add members if len(host_add) > 0 or len(hostgroup_add) > 0: diff --git a/plugins/modules/ipasudocmdgroup.py b/plugins/modules/ipasudocmdgroup.py index 3cbb2803..a5b0e4e4 100644 --- a/plugins/modules/ipasudocmdgroup.py +++ b/plugins/modules/ipasudocmdgroup.py @@ -110,7 +110,8 @@ RETURN = """ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_text from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ - temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa + temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \ + gen_add_del_lists def find_sudocmdgroup(module, name): @@ -257,12 +258,10 @@ def main(): if not compare_args_ipa(ansible_module, member_args, res_find): # Generate addition and removal lists - sudocmdgroup_add = list( - set(sudocmdgroup or []) - - set(res_find.get("member_sudocmdgroup", []))) - sudocmdgroup_del = list( - set(res_find.get("member_sudocmdgroup", [])) - - set(sudocmdgroup or [])) + sudocmdgroup_add, sudocmdgroup_del = \ + gen_add_del_lists( + sudocmdgroup, + res_find.get("member_sudocmdgroup")) # Add members if len(sudocmdgroup_add) > 0: diff --git a/plugins/modules/ipauser.py b/plugins/modules/ipauser.py index 1867ea7b..d854ba5a 100644 --- a/plugins/modules/ipauser.py +++ b/plugins/modules/ipauser.py @@ -467,7 +467,7 @@ from ansible.module_utils._text import to_text from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ temp_kdestroy, valid_creds, api_connect, api_command, date_format, \ compare_args_ipa, module_params_get, api_check_param, api_get_realm, \ - api_command_no_name + api_command_no_name, gen_add_del_lists import six @@ -1063,36 +1063,21 @@ def main(): # certmapdata if res_find is not None: # Generate addition and removal lists - manager_add = list( - set(manager or []) - - set(res_find.get("manager", []))) - manager_del = list( - set(res_find.get("manager", [])) - - set(manager or [])) - principal_add = list( - set(principal or []) - - set(res_find.get("krbprincipalname", []))) - principal_del = list( - set(res_find.get("krbprincipalname", [])) - - set(principal or [])) + manager_add, manager_del = gen_add_del_lists( + manager, res_find.get("manager")) + principal_add, principal_del = gen_add_del_lists( + principal, res_find.get("krbprincipalname")) # Principals are not returned as utf8 for IPA using # python2 using user_find, therefore we need to # convert the principals that we should remove. principal_del = [to_text(x) for x in principal_del] - certificate_add = list( - set(certificate or []) - - set(res_find.get("certificate", []))) - certificate_del = list( - set(res_find.get("certificate", [])) - - set(certificate or [])) - certmapdata_add = list( - set(certmapdata or []) - - set(res_find.get("ipaCertMapData", []))) - certmapdata_del = list( - set(res_find.get("ipaCertMapData", [])) - - set(certmapdata or [])) + certificate_add, certificate_del = gen_add_del_lists( + certificate, res_find.get("usercertificate")) + + certmapdata_add, certmapdata_del = gen_add_del_lists( + certmapdata, res_find.get("ipaCertMapData")) else: # Use given managers and principals diff --git a/tests/user/test_user.yml b/tests/user/test_user.yml index 541ea7cf..cca6b489 100644 --- a/tests/user/test_user.yml +++ b/tests/user/test_user.yml @@ -87,8 +87,8 @@ name: pinky first: pinky last: Acme - #manager: manager1,manager2,manager3 - #principal: pa,pa1,pa3 + manager: [] + principal: [] sshpubkey: - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqmVDpEX5gnSjKuv97AyzOhaUMMKz8ahOA3GY77tVC4o68KNgMCmDSEG1/kOIaElngNLaCha3p/2iAcU9Bi1tLKUlm2bbO5NHNwHfRxY/3cJtq+/7D1vxJzqThYwI4F9vr1WxyY2+mMTv3pXbfAJoR8Mu06XaEY5PDetlDKjHLuNWF+/O7ZU8PsULTa1dJZFrtXeFpmUoLoGxQBvlrlcPI1zDciCSU24t27Zan5Py2l5QchyI7yhCyMM77KDtj5+AFVpmkb9+zq50rYJAyFVeyUvwjzErvQrKJzYpA0NyBp7vskWbt36M16/M/LxEK7HA6mkcakO3ESWx5MT1LAjvdlnxbWG3787MxweHXuB8CZU+9bZPFBaJ+VQtOfJ7I8eH0S16moPC4ak8FlcFvOH8ERDPWLFDqfy09yaZ7bVIF0//5ZI7Nf3YDe3S7GrBX5ieYuECyP6UNkTx9BRsAQeVvXEc6otzB7iCSnYBMGUGzCqeigoAWaVQUONsSR3Uatks= pinky@ipaserver.el81.local - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDc8MIjaSrxLYHvu+hduoF4m6NUFSlXZWzYbd3BK4L47/U4eiXoOS6dcfuZJDjmLfOipc7XVp7NADwAgA1yBOAjbeVpXr2tC8w8saZibl75WBOEjDfNroiOh/f/ojrwwHg05QTVSZHs27sU1HBPyCQM/FHVM6EnRfmyiBkEBA/3ca0PJ9UJhWb2XisCaz6y6QcTh4gQnvHzgmEmK31GwiKnmBSEQuj8P5NGCO8RlN3cq3zpRpMDEoBRCjQYicllf/5P43r5OGvS1LhTiAMfyqE37URezNQa7aozBpH1GhIwAmjAtm84jXQjxUgZPYC0aSLuADYErScOP4792r6koH9t/DM5/M+jG2c4PNWynDczUw6Eaxl5E3hU0Ee9UN0Oee7iBnVenS/QMeZNyo5lMA/HXT5lrYiJGTYM0shRjGXXYBbJZhWerguSWDAdUd1gvuGP1nb7/+/Cvb46+HX7zYouS5Ojo0yPzMZ07X142jnKAfx9LnKdMUCwBJzbtoJ91Zc= pinky@ipaserver.el81.local diff --git a/tests/user/test_users.yml b/tests/user/test_users.yml index d66115cb..5b5d4538 100644 --- a/tests/user/test_users.yml +++ b/tests/user/test_users.yml @@ -205,8 +205,8 @@ name: pinky first: pinky last: Acme - #manager: manager1,manager2,manager3 - #principal: pa,pa1,pa3 + manager: [] + principal: [] sshpubkey: - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqmVDpEX5gnSjKuv97AyzOhaUMMKz8ahOA3GY77tVC4o68KNgMCmDSEG1/kOIaElngNLaCha3p/2iAcU9Bi1tLKUlm2bbO5NHNwHfRxY/3cJtq+/7D1vxJzqThYwI4F9vr1WxyY2+mMTv3pXbfAJoR8Mu06XaEY5PDetlDKjHLuNWF+/O7ZU8PsULTa1dJZFrtXeFpmUoLoGxQBvlrlcPI1zDciCSU24t27Zan5Py2l5QchyI7yhCyMM77KDtj5+AFVpmkb9+zq50rYJAyFVeyUvwjzErvQrKJzYpA0NyBp7vskWbt36M16/M/LxEK7HA6mkcakO3ESWx5MT1LAjvdlnxbWG3787MxweHXuB8CZU+9bZPFBaJ+VQtOfJ7I8eH0S16moPC4ak8FlcFvOH8ERDPWLFDqfy09yaZ7bVIF0//5ZI7Nf3YDe3S7GrBX5ieYuECyP6UNkTx9BRsAQeVvXEc6otzB7iCSnYBMGUGzCqeigoAWaVQUONsSR3Uatks= pinky@ipaserver.el81.local - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDc8MIjaSrxLYHvu+hduoF4m6NUFSlXZWzYbd3BK4L47/U4eiXoOS6dcfuZJDjmLfOipc7XVp7NADwAgA1yBOAjbeVpXr2tC8w8saZibl75WBOEjDfNroiOh/f/ojrwwHg05QTVSZHs27sU1HBPyCQM/FHVM6EnRfmyiBkEBA/3ca0PJ9UJhWb2XisCaz6y6QcTh4gQnvHzgmEmK31GwiKnmBSEQuj8P5NGCO8RlN3cq3zpRpMDEoBRCjQYicllf/5P43r5OGvS1LhTiAMfyqE37URezNQa7aozBpH1GhIwAmjAtm84jXQjxUgZPYC0aSLuADYErScOP4792r6koH9t/DM5/M+jG2c4PNWynDczUw6Eaxl5E3hU0Ee9UN0Oee7iBnVenS/QMeZNyo5lMA/HXT5lrYiJGTYM0shRjGXXYBbJZhWerguSWDAdUd1gvuGP1nb7/+/Cvb46+HX7zYouS5Ojo0yPzMZ07X142jnKAfx9LnKdMUCwBJzbtoJ91Zc= pinky@ipaserver.el81.local -- GitLab