ipahostgroup: Fix idempotence issues due to capitalization

ipahostgroup parameters 'host', 'hostgroup', 'membermanager_user' and
'membermanager_group' must be compared in a case insensitive manner
and stored as lower case strings.

This patch fixes the comparison and storage of this parameters, and
change the handling of members to use the same structure as in newer
modules.

Two new tests files were added:

    tests/hostgroup/test_hostgroup_case_insensitive.yml
    tests/hostgroup/test_hostgroup_membermanager_case_insensitive.yml
This commit is contained in:
Rafael Guterres Jeffman
2023-12-28 18:08:52 -03:00
parent 4321478cf0
commit 22401d18d6
3 changed files with 427 additions and 135 deletions

View File

@@ -181,16 +181,6 @@ def gen_args(description, nomembers, rename):
return _args
def gen_member_args(host, hostgroup):
_args = {}
if host is not None:
_args["member_host"] = host
if hostgroup is not None:
_args["member_hostgroup"] = hostgroup
return _args
def main():
ansible_module = IPAAnsibleModule(
argument_spec=dict(
@@ -224,16 +214,20 @@ def main():
# Get parameters
# general
names = ansible_module.params_get("name")
names = ansible_module.params_get_lowercase("name")
# present
description = ansible_module.params_get("description")
nomembers = ansible_module.params_get("nomembers")
host = ansible_module.params_get("host")
hostgroup = ansible_module.params_get("hostgroup")
membermanager_user = ansible_module.params_get("membermanager_user")
membermanager_group = ansible_module.params_get("membermanager_group")
rename = ansible_module.params_get("rename")
hostgroup = ansible_module.params_get_lowercase("hostgroup")
membermanager_user = ansible_module.params_get_lowercase(
"membermanager_user"
)
membermanager_group = ansible_module.params_get_lowercase(
"membermanager_group"
)
rename = ansible_module.params_get_lowercase("rename")
action = ansible_module.params_get("action")
# state
state = ansible_module.params_get("state")
@@ -306,6 +300,12 @@ def main():
commands = []
for name in names:
# clean add/del lists
host_add, host_del = [], []
hostgroup_add, hostgroup_del = [], []
membermanager_user_add, membermanager_user_del = [], []
membermanager_group_add, membermanager_group_del = [], []
# Make sure hostgroup exists
res_find = find_hostgroup(ansible_module, name)
@@ -328,63 +328,26 @@ def main():
# Set res_find to empty dict for next step
res_find = {}
member_args = gen_member_args(host, hostgroup)
if not compare_args_ipa(ansible_module, member_args,
res_find):
# Generate addition and removal lists
host_add, host_del = gen_add_del_lists(
host, res_find.get("member_host"))
# Generate addition and removal lists
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:
commands.append([name, "hostgroup_add_member",
{
"host": host_add,
"hostgroup": hostgroup_add,
}])
# Remove members
if len(host_del) > 0 or len(hostgroup_del) > 0:
commands.append([name, "hostgroup_remove_member",
{
"host": host_del,
"hostgroup": hostgroup_del,
}])
membermanager_user_add, membermanager_user_del = \
gen_add_del_lists(
membermanager_user,
res_find.get("membermanager_user")
)
membermanager_group_add, membermanager_group_del = \
gen_add_del_lists(
membermanager_group,
res_find.get("membermanager_group")
)
hostgroup_add, hostgroup_del = gen_add_del_lists(
hostgroup, res_find.get("member_hostgroup")
)
if has_add_membermanager:
# Add membermanager users and groups
if len(membermanager_user_add) > 0 or \
len(membermanager_group_add) > 0:
commands.append(
[name, "hostgroup_add_member_manager",
{
"user": membermanager_user_add,
"group": membermanager_group_add,
}]
membermanager_user_add, membermanager_user_del = \
gen_add_del_lists(
membermanager_user,
res_find.get("membermanager_user")
)
# Remove member manager
if len(membermanager_user_del) > 0 or \
len(membermanager_group_del) > 0:
commands.append(
[name, "hostgroup_remove_member_manager",
{
"user": membermanager_user_del,
"group": membermanager_group_del,
}]
membermanager_group_add, membermanager_group_del = \
gen_add_del_lists(
membermanager_group,
res_find.get("membermanager_group")
)
elif action == "member":
@@ -394,45 +357,25 @@ def main():
# Reduce add lists for member_host and member_hostgroup,
# to new entries only that are not in res_find.
if host is not None and "member_host" in res_find:
host = gen_add_list(host, res_find["member_host"])
if hostgroup is not None \
and "member_hostgroup" in res_find:
hostgroup = gen_add_list(
hostgroup, res_find["member_hostgroup"])
# Ensure members are present
commands.append([name, "hostgroup_add_member",
{
"host": host,
"hostgroup": hostgroup,
}])
host_add = gen_add_list(
host, res_find.get("member_host")
)
hostgroup_add = gen_add_list(
hostgroup, res_find.get("member_hostgroup")
)
if has_add_membermanager:
# Reduce add list for membermanager_user and
# membermanager_group to new entries only that are
# not in res_find.
if membermanager_user is not None \
and "membermanager_user" in res_find:
membermanager_user = gen_add_list(
membermanager_user,
res_find["membermanager_user"])
if membermanager_group is not None \
and "membermanager_group" in res_find:
membermanager_group = gen_add_list(
membermanager_group,
res_find["membermanager_group"])
# Add membermanager users and groups
if membermanager_user is not None or \
membermanager_group is not None:
commands.append(
[name, "hostgroup_add_member_manager",
{
"user": membermanager_user,
"group": membermanager_group,
}]
)
membermanager_user_add = gen_add_list(
membermanager_user,
res_find.get("membermanager_user")
)
membermanager_group_add = gen_add_list(
membermanager_group,
res_find.get("membermanager_group")
)
elif state == "renamed":
if res_find is not None:
@@ -463,46 +406,72 @@ def main():
# Reduce del lists of member_host and member_hostgroup,
# to the entries only that are in res_find.
if host is not None:
host = gen_intersection_list(
host, res_find.get("member_host"))
host_del = gen_intersection_list(
host, res_find.get("member_host")
)
if hostgroup is not None:
hostgroup = gen_intersection_list(
hostgroup, res_find.get("member_hostgroup"))
# Ensure members are absent
commands.append([name, "hostgroup_remove_member",
{
"host": host,
"hostgroup": hostgroup,
}])
hostgroup_del = gen_intersection_list(
hostgroup, res_find.get("member_hostgroup")
)
if has_add_membermanager:
# Reduce del lists of membermanager_user and
# membermanager_group to the entries only that are
# in res_find.
if membermanager_user is not None:
membermanager_user = gen_intersection_list(
membermanager_user,
res_find.get("membermanager_user"))
if membermanager_group is not None:
membermanager_group = gen_intersection_list(
membermanager_group,
res_find.get("membermanager_group"))
# Remove membermanager users and groups
if membermanager_user is not None or \
membermanager_group is not None:
commands.append(
[name, "hostgroup_remove_member_manager",
{
"user": membermanager_user,
"group": membermanager_group,
}]
)
# Get lists of membermanager users that exist
# in IPA and should be removed.
membermanager_user_del = gen_intersection_list(
membermanager_user,
res_find.get("membermanager_user")
)
membermanager_group_del = gen_intersection_list(
membermanager_group,
res_find.get("membermanager_group")
)
else:
ansible_module.fail_json(msg="Unkown state '%s'" % state)
# Manage members
# Add members
if host_add or hostgroup_add:
commands.append([
name, "hostgroup_add_member",
{
"host": host_add,
"hostgroup": hostgroup_add,
}
])
# Remove members
if host_del or hostgroup_del:
commands.append([
name, "hostgroup_remove_member",
{
"host": host_del,
"hostgroup": hostgroup_del,
}
])
# Manage membermanager users and groups
if has_add_membermanager:
# Add membermanager users and groups
if membermanager_user_add or membermanager_group_add:
commands.append([
name, "hostgroup_add_member_manager",
{
"user": membermanager_user_add,
"group": membermanager_group_add,
}
])
# Remove membermanager users and groups
if membermanager_user_del or membermanager_group_del:
commands.append([
name, "hostgroup_remove_member_manager",
{
"user": membermanager_user_del,
"group": membermanager_group_del,
}
])
# Execute commands
changed = ansible_module.execute_ipa_commands(