Skip to content

Commit cf4a72d

Browse files
committed
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
1 parent 4015073 commit cf4a72d

File tree

3 files changed

+500
-121
lines changed

3 files changed

+500
-121
lines changed

Diff for: plugins/modules/ipahostgroup.py

+111-121
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149

150150
from ansible.module_utils.ansible_freeipa_module import \
151151
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, gen_add_list, \
152-
gen_intersection_list, ListOf, Hostname
152+
gen_intersection_list, CaseInsensitive, Hostname, ListOf
153153

154154

155155
def find_hostgroup(module, name):
@@ -302,6 +302,12 @@ def main():
302302
commands = []
303303

304304
for name in names:
305+
# clean add/del lists
306+
host_add, host_del = [], []
307+
hostgroup_add, hostgroup_del = [], []
308+
membermanager_user_add, membermanager_user_del = [], []
309+
membermanager_group_add, membermanager_group_del = [], []
310+
305311
# Make sure hostgroup exists
306312
res_find = find_hostgroup(ansible_module, name)
307313

@@ -324,63 +330,31 @@ def main():
324330
# Set res_find to empty dict for next step
325331
res_find = {}
326332

327-
member_args = gen_member_args(host, hostgroup)
328-
if not compare_args_ipa(ansible_module, member_args,
329-
res_find):
330-
# Generate addition and removal lists
331-
host_add, host_del = gen_add_del_lists(
332-
host, res_find.get("member_host"))
333-
334-
hostgroup_add, hostgroup_del = gen_add_del_lists(
335-
hostgroup, res_find.get("member_hostgroup"))
336-
337-
# Add members
338-
if len(host_add) > 0 or len(hostgroup_add) > 0:
339-
commands.append([name, "hostgroup_add_member",
340-
{
341-
"host": host_add,
342-
"hostgroup": hostgroup_add,
343-
}])
344-
# Remove members
345-
if len(host_del) > 0 or len(hostgroup_del) > 0:
346-
commands.append([name, "hostgroup_remove_member",
347-
{
348-
"host": host_del,
349-
"hostgroup": hostgroup_del,
350-
}])
351-
352-
membermanager_user_add, membermanager_user_del = \
353-
gen_add_del_lists(
354-
membermanager_user,
355-
res_find.get("membermanager_user")
356-
)
333+
# Generate addition and removal lists
334+
host_add, host_del = gen_add_del_lists(
335+
host, res_find.get("member_host"),
336+
attr_datatype=(
337+
Hostname(ansible_module.ipa_get_domain())),
338+
)
357339

358-
membermanager_group_add, membermanager_group_del = \
359-
gen_add_del_lists(
360-
membermanager_group,
361-
res_find.get("membermanager_group")
362-
)
340+
hostgroup_add, hostgroup_del = gen_add_del_lists(
341+
hostgroup, res_find.get("member_hostgroup"),
342+
attr_datatype=CaseInsensitive(),
343+
)
363344

364345
if has_add_membermanager:
365-
# Add membermanager users and groups
366-
if len(membermanager_user_add) > 0 or \
367-
len(membermanager_group_add) > 0:
368-
commands.append(
369-
[name, "hostgroup_add_member_manager",
370-
{
371-
"user": membermanager_user_add,
372-
"group": membermanager_group_add,
373-
}]
346+
membermanager_user_add, membermanager_user_del = \
347+
gen_add_del_lists(
348+
membermanager_user,
349+
res_find.get("membermanager_user"),
350+
attr_datatype=CaseInsensitive(),
374351
)
375-
# Remove member manager
376-
if len(membermanager_user_del) > 0 or \
377-
len(membermanager_group_del) > 0:
378-
commands.append(
379-
[name, "hostgroup_remove_member_manager",
380-
{
381-
"user": membermanager_user_del,
382-
"group": membermanager_group_del,
383-
}]
352+
353+
membermanager_group_add, membermanager_group_del = \
354+
gen_add_del_lists(
355+
membermanager_group,
356+
res_find.get("membermanager_group"),
357+
attr_datatype=CaseInsensitive(),
384358
)
385359

386360
elif action == "member":
@@ -390,45 +364,30 @@ def main():
390364

391365
# Reduce add lists for member_host and member_hostgroup,
392366
# to new entries only that are not in res_find.
393-
if host is not None and "member_host" in res_find:
394-
host = gen_add_list(host, res_find["member_host"])
395-
if hostgroup is not None \
396-
and "member_hostgroup" in res_find:
397-
hostgroup = gen_add_list(
398-
hostgroup, res_find["member_hostgroup"])
399-
400-
# Ensure members are present
401-
commands.append([name, "hostgroup_add_member",
402-
{
403-
"host": host,
404-
"hostgroup": hostgroup,
405-
}])
367+
host_add = gen_add_list(
368+
host, res_find.get("member_host"),
369+
attr_datatype=(
370+
Hostname(ansible_module.ipa_get_domain())),
371+
)
372+
hostgroup_add = gen_add_list(
373+
hostgroup, res_find.get("member_hostgroup"),
374+
attr_datatype=CaseInsensitive(),
375+
)
406376

407377
if has_add_membermanager:
408378
# Reduce add list for membermanager_user and
409379
# membermanager_group to new entries only that are
410380
# not in res_find.
411-
if membermanager_user is not None \
412-
and "membermanager_user" in res_find:
413-
membermanager_user = gen_add_list(
414-
membermanager_user,
415-
res_find["membermanager_user"])
416-
if membermanager_group is not None \
417-
and "membermanager_group" in res_find:
418-
membermanager_group = gen_add_list(
419-
membermanager_group,
420-
res_find["membermanager_group"])
421-
422-
# Add membermanager users and groups
423-
if membermanager_user is not None or \
424-
membermanager_group is not None:
425-
commands.append(
426-
[name, "hostgroup_add_member_manager",
427-
{
428-
"user": membermanager_user,
429-
"group": membermanager_group,
430-
}]
431-
)
381+
membermanager_user_add = gen_add_list(
382+
membermanager_user,
383+
res_find.get("membermanager_user"),
384+
attr_datatype=CaseInsensitive(),
385+
)
386+
membermanager_group_add = gen_add_list(
387+
membermanager_group,
388+
res_find.get("membermanager_group"),
389+
attr_datatype=CaseInsensitive(),
390+
)
432391

433392
elif state == "renamed":
434393
if res_find is not None:
@@ -459,46 +418,77 @@ def main():
459418
# Reduce del lists of member_host and member_hostgroup,
460419
# to the entries only that are in res_find.
461420
if host is not None:
462-
host = gen_intersection_list(
463-
host, res_find.get("member_host"))
421+
host_del = gen_intersection_list(
422+
host, res_find.get("member_host"),
423+
attr_datatype=(
424+
Hostname(ansible_module.ipa_get_domain())),
425+
)
464426
if hostgroup is not None:
465-
hostgroup = gen_intersection_list(
466-
hostgroup, res_find.get("member_hostgroup"))
467-
468-
# Ensure members are absent
469-
commands.append([name, "hostgroup_remove_member",
470-
{
471-
"host": host,
472-
"hostgroup": hostgroup,
473-
}])
427+
hostgroup_del = gen_intersection_list(
428+
hostgroup, res_find.get("member_hostgroup"),
429+
attr_datatype=CaseInsensitive(),
430+
)
474431

475432
if has_add_membermanager:
476-
# Reduce del lists of membermanager_user and
477-
# membermanager_group to the entries only that are
478-
# in res_find.
479-
if membermanager_user is not None:
480-
membermanager_user = gen_intersection_list(
481-
membermanager_user,
482-
res_find.get("membermanager_user"))
483-
if membermanager_group is not None:
484-
membermanager_group = gen_intersection_list(
485-
membermanager_group,
486-
res_find.get("membermanager_group"))
487-
488-
# Remove membermanager users and groups
489-
if membermanager_user is not None or \
490-
membermanager_group is not None:
491-
commands.append(
492-
[name, "hostgroup_remove_member_manager",
493-
{
494-
"user": membermanager_user,
495-
"group": membermanager_group,
496-
}]
497-
)
433+
# Get lists of membermanager users that exist
434+
# in IPA and should be removed.
435+
membermanager_user_del = gen_intersection_list(
436+
membermanager_user,
437+
res_find.get("membermanager_user"),
438+
attr_datatype=CaseInsensitive(),
439+
)
440+
membermanager_group_del = gen_intersection_list(
441+
membermanager_group,
442+
res_find.get("membermanager_group"),
443+
attr_datatype=CaseInsensitive(),
444+
)
498445

499446
else:
500447
ansible_module.fail_json(msg="Unkown state '%s'" % state)
501448

449+
# Manage members
450+
451+
# Add members
452+
if host_add or hostgroup_add:
453+
commands.append([
454+
name, "hostgroup_add_member",
455+
{
456+
"host": host_add,
457+
"hostgroup": hostgroup_add,
458+
}
459+
])
460+
461+
# Remove members
462+
if host_del or hostgroup_del:
463+
commands.append([
464+
name, "hostgroup_remove_member",
465+
{
466+
"host": host_del,
467+
"hostgroup": hostgroup_del,
468+
}
469+
])
470+
471+
# Manage membermanager users and groups
472+
if has_add_membermanager:
473+
# Add membermanager users and groups
474+
if membermanager_user_add or membermanager_group_add:
475+
commands.append([
476+
name, "hostgroup_add_member_manager",
477+
{
478+
"user": membermanager_user_add,
479+
"group": membermanager_group_add,
480+
}
481+
])
482+
# Remove membermanager users and groups
483+
if membermanager_user_del or membermanager_group_del:
484+
commands.append([
485+
name, "hostgroup_remove_member_manager",
486+
{
487+
"user": membermanager_user_del,
488+
"group": membermanager_group_del,
489+
}
490+
])
491+
502492
# Execute commands
503493

504494
changed = ansible_module.execute_ipa_commands(

0 commit comments

Comments
 (0)