Blame plugins/modules/ipagroup.py

Packit Service 0a38ef
# -*- coding: utf-8 -*-
Packit Service 0a38ef
Packit Service 0a38ef
# Authors:
Packit Service 0a38ef
#   Thomas Woerner <twoerner@redhat.com>
Packit Service 0a38ef
#
Packit Service 0a38ef
# Copyright (C) 2019 Red Hat
Packit Service 0a38ef
# see file 'COPYING' for use and warranty information
Packit Service 0a38ef
#
Packit Service 0a38ef
# This program is free software; you can redistribute it and/or modify
Packit Service 0a38ef
# it under the terms of the GNU General Public License as published by
Packit Service 0a38ef
# the Free Software Foundation, either version 3 of the License, or
Packit Service 0a38ef
# (at your option) any later version.
Packit Service 0a38ef
#
Packit Service 0a38ef
# This program is distributed in the hope that it will be useful,
Packit Service 0a38ef
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 0a38ef
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 0a38ef
# GNU General Public License for more details.
Packit Service 0a38ef
#
Packit Service 0a38ef
# You should have received a copy of the GNU General Public License
Packit Service 0a38ef
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit Service 0a38ef
Packit Service 0a38ef
ANSIBLE_METADATA = {
Packit Service 0a38ef
    "metadata_version": "1.0",
Packit Service 0a38ef
    "supported_by": "community",
Packit Service 0a38ef
    "status": ["preview"],
Packit Service 0a38ef
}
Packit Service 0a38ef
Packit Service 0a38ef
DOCUMENTATION = """
Packit Service 0a38ef
---
Packit Service 0a38ef
module: ipagroup
Packit Service 0a38ef
short description: Manage FreeIPA groups
Packit Service 0a38ef
description: Manage FreeIPA groups
Packit Service 0a38ef
options:
Packit Service 0a38ef
  ipaadmin_principal:
Packit Service 0a38ef
    description: The admin principal
Packit Service 0a38ef
    default: admin
Packit Service 0a38ef
  ipaadmin_password:
Packit Service 0a38ef
    description: The admin password
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  name:
Packit Service 0a38ef
    description: The group name
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["cn"]
Packit Service 0a38ef
  description:
Packit Service 0a38ef
    description: The group description
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  gid:
Packit Service 0a38ef
    description: The GID
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["gidnumber"]
Packit Service 0a38ef
  nonposix:
Packit Service 0a38ef
    description: Create as a non-POSIX group
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: bool
Packit Service 0a38ef
  external:
Packit Service 0a38ef
    description: Allow adding external non-IPA members from trusted domains
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: bool
Packit Service a166ed
  posix:
Packit Service a166ed
    description:
Packit Service a166ed
      Create a non-POSIX group or change a non-POSIX to a posix group.
Packit Service a166ed
    required: false
Packit Service a166ed
    type: bool
Packit Service 0a38ef
  nomembers:
Packit Service 0a38ef
    description: Suppress processing of membership attributes
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: bool
Packit Service 0a38ef
  user:
Packit Service 0a38ef
    description: List of user names assigned to this group.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  group:
Packit Service 0a38ef
    description: List of group names assigned to this group.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  service:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
    - List of service names assigned to this group.
Packit Service 0a38ef
    - Only usable with IPA versions 4.7 and up.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  membermanager_user:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
    - List of member manager users assigned to this group.
Packit Service 0a38ef
    - Only usable with IPA versions 4.8.4 and up.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service 0a38ef
  membermanager_group:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
    - List of member manager groups assigned to this group.
Packit Service 0a38ef
    - Only usable with IPA versions 4.8.4 and up.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: list
Packit Service a166ed
  externalmember:
Packit Service a166ed
    description:
Packit Service a166ed
    - List of members of a trusted domain in DOM\\name or name@domain form.
Packit Service a166ed
    required: false
Packit Service a166ed
    type: list
Packit Service a166ed
    ailases: ["ipaexternalmember", "external_member"]
Packit Service 0a38ef
  action:
Packit Service 0a38ef
    description: Work on group or member level
Packit Service 0a38ef
    default: group
Packit Service 0a38ef
    choices: ["member", "group"]
Packit Service 0a38ef
  state:
Packit Service 0a38ef
    description: State to ensure
Packit Service 0a38ef
    default: present
Packit Service 0a38ef
    choices: ["present", "absent"]
Packit Service 0a38ef
author:
Packit Service 0a38ef
    - Thomas Woerner
Packit Service 0a38ef
"""
Packit Service 0a38ef
Packit Service 0a38ef
EXAMPLES = """
Packit Service 0a38ef
# Create group ops with gid 1234
Packit Service 0a38ef
- ipagroup:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: ops
Packit Service 0a38ef
    gidnumber: 1234
Packit Service 0a38ef
Packit Service 0a38ef
# Create group sysops
Packit Service 0a38ef
- ipagroup:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: sysops
Packit Service 0a38ef
Packit Service 0a38ef
# Create group appops
Packit Service 0a38ef
- ipagroup:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: appops
Packit Service 0a38ef
Packit Service 0a38ef
# Add user member pinky to group sysops
Packit Service 0a38ef
- ipagroup:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: sysops
Packit Service 0a38ef
    action: member
Packit Service 0a38ef
    user:
Packit Service 0a38ef
    - pinky
Packit Service 0a38ef
Packit Service 0a38ef
# Add user member brain to group sysops
Packit Service 0a38ef
- ipagroup:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: sysops
Packit Service 0a38ef
    action: member
Packit Service 0a38ef
    user:
Packit Service 0a38ef
    - brain
Packit Service 0a38ef
Packit Service 0a38ef
# Add group members sysops and appops to group sysops
Packit Service 0a38ef
- ipagroup:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: ops
Packit Service 0a38ef
    group:
Packit Service 0a38ef
    - sysops
Packit Service 0a38ef
    - appops
Packit Service 0a38ef
Packit Service a166ed
# Create a non-POSIX group
Packit Service a166ed
- ipagroup:
Packit Service a166ed
    ipaadmin_password: SomeADMINpassword
Packit Service a166ed
    name: nongroup
Packit Service a166ed
    nonposix: yes
Packit Service a166ed
Packit Service a166ed
# Turn a non-POSIX group into a POSIX group.
Packit Service 0a38ef
- ipagroup:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service a166ed
    name: nonposix
Packit Service a166ed
    posix: yes
Packit Service a166ed
Packit Service a166ed
# Create an external group and add members from a trust to it.
Packit Service a166ed
- ipagroup:
Packit Service a166ed
    ipaadmin_password: SomeADMINpassword
Packit Service a166ed
    name: extgroup
Packit Service a166ed
    external: yes
Packit Service a166ed
    externalmember:
Packit Service a166ed
    - WINIPA\\Web Users
Packit Service a166ed
    - WINIPA\\Developers
Packit Service a166ed
Packit Service a166ed
# Remove goups sysops, appops, ops and nongroup
Packit Service a166ed
- ipagroup:
Packit Service a166ed
    ipaadmin_password: SomeADMINpassword
Packit Service a166ed
    name: sysops,appops,ops, nongroup
Packit Service 0a38ef
    state: absent
Packit Service 0a38ef
"""
Packit Service 0a38ef
Packit Service 0a38ef
RETURN = """
Packit Service 0a38ef
"""
Packit Service 0a38ef
Packit Service 0a38ef
from ansible.module_utils.basic import AnsibleModule
Packit Service 0a38ef
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
Packit Service 0a38ef
    temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
Packit Service 0a38ef
    api_check_param, module_params_get, gen_add_del_lists, api_check_command
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def find_group(module, name):
Packit Service 0a38ef
    _args = {
Packit Service 0a38ef
        "all": True,
Packit Service 0a38ef
        "cn": name,
Packit Service 0a38ef
    }
Packit Service 0a38ef
Packit Service 0a38ef
    _result = api_command(module, "group_find", name, _args)
Packit Service 0a38ef
Packit Service 0a38ef
    if len(_result["result"]) > 1:
Packit Service 0a38ef
        module.fail_json(
Packit Service 0a38ef
            msg="There is more than one group '%s'" % (name))
Packit Service 0a38ef
    elif len(_result["result"]) == 1:
Packit Service 0a38ef
        return _result["result"][0]
Packit Service 0a38ef
    else:
Packit Service 0a38ef
        return None
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service a166ed
def gen_args(description, gid, nomembers):
Packit Service 0a38ef
    _args = {}
Packit Service 0a38ef
    if description is not None:
Packit Service 0a38ef
        _args["description"] = description
Packit Service 0a38ef
    if gid is not None:
Packit Service 0a38ef
        _args["gidnumber"] = gid
Packit Service 0a38ef
    if nomembers is not None:
Packit Service 0a38ef
        _args["nomembers"] = nomembers
Packit Service 0a38ef
Packit Service 0a38ef
    return _args
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service a166ed
def gen_member_args(user, group, service, externalmember):
Packit Service 0a38ef
    _args = {}
Packit Service 0a38ef
    if user is not None:
Packit Service 0a38ef
        _args["member_user"] = user
Packit Service 0a38ef
    if group is not None:
Packit Service 0a38ef
        _args["member_group"] = group
Packit Service 0a38ef
    if service is not None:
Packit Service 0a38ef
        _args["member_service"] = service
Packit Service a166ed
    if externalmember is not None:
Packit Service a166ed
        _args["member_external"] = externalmember
Packit Service 0a38ef
Packit Service 0a38ef
    return _args
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service a166ed
def is_external_group(res_find):
Packit Service a166ed
    """Verify if the result group is an external group."""
Packit Service a166ed
    return res_find and 'ipaexternalgroup' in res_find['objectclass']
Packit Service a166ed
Packit Service a166ed
Packit Service a166ed
def is_posix_group(res_find):
Packit Service a166ed
    """Verify if the result group is an external group."""
Packit Service a166ed
    return res_find and 'posixgroup' in res_find['objectclass']
Packit Service a166ed
Packit Service a166ed
Packit Service a166ed
def check_objectclass_args(module, res_find, nonposix, posix, external):
Packit Service a166ed
    if is_posix_group(res_find):
Packit Service a166ed
        if (
Packit Service a166ed
            (posix is not None and posix is False)
Packit Service a166ed
            or nonposix
Packit Service a166ed
            or external
Packit Service a166ed
        ):
Packit Service a166ed
            module.fail_json(
Packit Service a166ed
                msg="Cannot change `POSIX` status of a group "
Packit Service a166ed
                    "to `non-POSIX` or `external`.")
Packit Service a166ed
    # Can't change an existing external group
Packit Service a166ed
    if is_external_group(res_find):
Packit Service a166ed
        if (
Packit Service a166ed
            posix
Packit Service a166ed
            or (nonposix is not None and nonposix is False)
Packit Service a166ed
            or (external is not None and external is False)
Packit Service a166ed
        ):
Packit Service a166ed
            module.fail_json(
Packit Service a166ed
                msg="Cannot change `external` status of group "
Packit Service a166ed
                    "to `POSIX` or `non-external`.")
Packit Service a166ed
Packit Service a166ed
Packit Service a166ed
def should_modify_group(module, res_find, args, nonposix, posix, external):
Packit Service a166ed
    if not compare_args_ipa(module, args, res_find):
Packit Service a166ed
        return True
Packit Service a166ed
    if any([posix, nonposix]):
Packit Service a166ed
        set_posix = posix or (nonposix is not None and not nonposix)
Packit Service a166ed
        if set_posix and not is_posix_group(res_find):
Packit Service a166ed
            return True
Packit Service a166ed
    if not is_external_group(res_find) and external:
Packit Service a166ed
        if not is_posix_group(res_find):
Packit Service a166ed
            return True
Packit Service a166ed
    return False
Packit Service a166ed
Packit Service a166ed
Packit Service 0a38ef
def main():
Packit Service 0a38ef
    ansible_module = AnsibleModule(
Packit Service 0a38ef
        argument_spec=dict(
Packit Service 0a38ef
            # general
Packit Service 0a38ef
            ipaadmin_principal=dict(type="str", default="admin"),
Packit Service 0a38ef
            ipaadmin_password=dict(type="str", required=False, no_log=True),
Packit Service 0a38ef
Packit Service 0a38ef
            name=dict(type="list", aliases=["cn"], default=None,
Packit Service 0a38ef
                      required=True),
Packit Service 0a38ef
            # present
Packit Service 0a38ef
            description=dict(type="str", default=None),
Packit Service 0a38ef
            gid=dict(type="int", aliases=["gidnumber"], default=None),
Packit Service 0a38ef
            nonposix=dict(required=False, type='bool', default=None),
Packit Service 0a38ef
            external=dict(required=False, type='bool', default=None),
Packit Service a166ed
            posix=dict(required=False, type='bool', default=None),
Packit Service 0a38ef
            nomembers=dict(required=False, type='bool', default=None),
Packit Service 0a38ef
            user=dict(required=False, type='list', default=None),
Packit Service 0a38ef
            group=dict(required=False, type='list', default=None),
Packit Service 0a38ef
            service=dict(required=False, type='list', default=None),
Packit Service 0a38ef
            membermanager_user=dict(required=False, type='list', default=None),
Packit Service 0a38ef
            membermanager_group=dict(required=False, type='list',
Packit Service 0a38ef
                                     default=None),
Packit Service a166ed
            externalmember=dict(required=False, type='list', default=None,
Packit Service a166ed
                                aliases=[
Packit Service a166ed
                                    "ipaexternalmember",
Packit Service a166ed
                                    "external_member"
Packit Service a166ed
                                ]),
Packit Service 0a38ef
            action=dict(type="str", default="group",
Packit Service 0a38ef
                        choices=["member", "group"]),
Packit Service 0a38ef
            # state
Packit Service 0a38ef
            state=dict(type="str", default="present",
Packit Service 0a38ef
                       choices=["present", "absent"]),
Packit Service 0a38ef
        ),
Packit Service a166ed
        mutually_exclusive=[['posix', 'nonposix']],
Packit Service 0a38ef
        supports_check_mode=True,
Packit Service 0a38ef
    )
Packit Service 0a38ef
Packit Service 0a38ef
    ansible_module._ansible_debug = True
Packit Service 0a38ef
Packit Service 0a38ef
    # Get parameters
Packit Service 0a38ef
Packit Service 0a38ef
    # general
Packit Service 0a38ef
    ipaadmin_principal = module_params_get(
Packit Service 0a38ef
        ansible_module,
Packit Service 0a38ef
        "ipaadmin_principal",
Packit Service 0a38ef
    )
Packit Service 0a38ef
    ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
Packit Service 0a38ef
    names = module_params_get(ansible_module, "name")
Packit Service 0a38ef
Packit Service 0a38ef
    # present
Packit Service 0a38ef
    description = module_params_get(ansible_module, "description")
Packit Service 0a38ef
    gid = module_params_get(ansible_module, "gid")
Packit Service 0a38ef
    nonposix = module_params_get(ansible_module, "nonposix")
Packit Service 0a38ef
    external = module_params_get(ansible_module, "external")
Packit Service a166ed
    posix = module_params_get(ansible_module, "posix")
Packit Service 0a38ef
    nomembers = module_params_get(ansible_module, "nomembers")
Packit Service 0a38ef
    user = module_params_get(ansible_module, "user")
Packit Service 0a38ef
    group = module_params_get(ansible_module, "group")
Packit Service 0a38ef
    service = module_params_get(ansible_module, "service")
Packit Service 0a38ef
    membermanager_user = module_params_get(ansible_module,
Packit Service 0a38ef
                                           "membermanager_user")
Packit Service 0a38ef
    membermanager_group = module_params_get(ansible_module,
Packit Service 0a38ef
                                            "membermanager_group")
Packit Service a166ed
    externalmember = module_params_get(ansible_module, "externalmember")
Packit Service 0a38ef
    action = module_params_get(ansible_module, "action")
Packit Service 0a38ef
    # state
Packit Service 0a38ef
    state = module_params_get(ansible_module, "state")
Packit Service 0a38ef
Packit Service 0a38ef
    # Check parameters
Packit Service 0a38ef
Packit Service 0a38ef
    if state == "present":
Packit Service 0a38ef
        if len(names) != 1:
Packit Service 0a38ef
            ansible_module.fail_json(
Packit Service 0a38ef
                msg="Only one group can be added at a time.")
Packit Service 0a38ef
        if action == "member":
Packit Service a166ed
            invalid = ["description", "gid", "posix", "nonposix", "external",
Packit Service 0a38ef
                       "nomembers"]
Packit Service 0a38ef
            for x in invalid:
Packit Service 0a38ef
                if vars()[x] is not None:
Packit Service 0a38ef
                    ansible_module.fail_json(
Packit Service 0a38ef
                        msg="Argument '%s' can not be used with action "
Packit Service 0a38ef
                        "'%s'" % (x, action))
Packit Service 0a38ef
Packit Service 0a38ef
    if state == "absent":
Packit Service 0a38ef
        if len(names) < 1:
Packit Service 0a38ef
            ansible_module.fail_json(
Packit Service 0a38ef
                msg="No name given.")
Packit Service a166ed
        invalid = ["description", "gid", "posix", "nonposix", "external",
Packit Service a166ed
                   "nomembers"]
Packit Service 0a38ef
        if action == "group":
Packit Service a166ed
            invalid.extend(["user", "group", "service", "externalmember"])
Packit Service 0a38ef
        for x in invalid:
Packit Service 0a38ef
            if vars()[x] is not None:
Packit Service 0a38ef
                ansible_module.fail_json(
Packit Service 0a38ef
                    msg="Argument '%s' can not be used with state '%s'" %
Packit Service 0a38ef
                    (x, state))
Packit Service 0a38ef
Packit Service 0a38ef
    # Init
Packit Service 0a38ef
Packit Service 0a38ef
    changed = False
Packit Service 0a38ef
    exit_args = {}
Packit Service 0a38ef
    ccache_dir = None
Packit Service 0a38ef
    ccache_name = None
Packit Service 0a38ef
    try:
Packit Service 0a38ef
        if not valid_creds(ansible_module, ipaadmin_principal):
Packit Service 0a38ef
            ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
Packit Service 0a38ef
                                                 ipaadmin_password)
Packit Service 0a38ef
        api_connect()
Packit Service 0a38ef
Packit Service 0a38ef
        has_add_member_service = api_check_param("group_add_member", "service")
Packit Service 0a38ef
        if service is not None and not has_add_member_service:
Packit Service 0a38ef
            ansible_module.fail_json(
Packit Service 0a38ef
                msg="Managing a service as part of a group is not supported "
Packit Service 0a38ef
                "by your IPA version")
Packit Service 0a38ef
Packit Service 0a38ef
        has_add_membermanager = api_check_command("group_add_member_manager")
Packit Service 0a38ef
        if ((membermanager_user is not None or
Packit Service 0a38ef
             membermanager_group is not None) and not has_add_membermanager):
Packit Service 0a38ef
            ansible_module.fail_json(
Packit Service 0a38ef
                msg="Managing a membermanager user or group is not supported "
Packit Service 0a38ef
                "by your IPA version"
Packit Service 0a38ef
            )
Packit Service 0a38ef
Packit Service 0a38ef
        commands = []
Packit Service 0a38ef
Packit Service 0a38ef
        for name in names:
Packit Service 0a38ef
            # Make sure group exists
Packit Service 0a38ef
            res_find = find_group(ansible_module, name)
Packit Service 0a38ef
Packit Service 0a38ef
            # Create command
Packit Service 0a38ef
            if state == "present":
Packit Service a166ed
                # Can't change an existing posix group
Packit Service a166ed
                check_objectclass_args(ansible_module, res_find, nonposix,
Packit Service a166ed
                                       posix, external)
Packit Service a166ed
Packit Service 0a38ef
                # Generate args
Packit Service a166ed
                args = gen_args(description, gid, nomembers)
Packit Service 0a38ef
Packit Service 0a38ef
                if action == "group":
Packit Service 0a38ef
                    # Found the group
Packit Service 0a38ef
                    if res_find is not None:
Packit Service 0a38ef
                        # For all settings is args, check if there are
Packit Service 0a38ef
                        # different settings in the find result.
Packit Service 0a38ef
                        # If yes: modify
Packit Service a166ed
                        if should_modify_group(ansible_module, res_find, args,
Packit Service a166ed
                                               nonposix, posix, external):
Packit Service a166ed
                            if (
Packit Service a166ed
                                posix
Packit Service a166ed
                                or (nonposix is not None and not nonposix)
Packit Service a166ed
                            ):
Packit Service a166ed
                                args['posix'] = True
Packit Service a166ed
                            if external:
Packit Service a166ed
                                args['external'] = True
Packit Service 0a38ef
                            commands.append([name, "group_mod", args])
Packit Service 0a38ef
                    else:
Packit Service a166ed
                        if nonposix or (posix is not None and not posix):
Packit Service a166ed
                            args['nonposix'] = True
Packit Service a166ed
                        if external:
Packit Service a166ed
                            args['external'] = True
Packit Service 0a38ef
                        commands.append([name, "group_add", args])
Packit Service a166ed
                        # Set res_find dict for next step
Packit Service 0a38ef
                        res_find = {}
Packit Service 0a38ef
Packit Service a166ed
                    # if we just created/modified the group, update res_find
Packit Service a166ed
                    res_find.setdefault("objectclass", [])
Packit Service a166ed
                    if external and not is_external_group(res_find):
Packit Service a166ed
                        res_find["objectclass"].append("ipaexternalgroup")
Packit Service a166ed
                    if posix and not is_posix_group(res_find):
Packit Service a166ed
                        res_find["objectclass"].append("posixgroup")
Packit Service a166ed
Packit Service a166ed
                    member_args = gen_member_args(
Packit Service a166ed
                        user, group, service, externalmember
Packit Service a166ed
                    )
Packit Service 0a38ef
                    if not compare_args_ipa(ansible_module, member_args,
Packit Service 0a38ef
                                            res_find):
Packit Service 0a38ef
                        # Generate addition and removal lists
Packit Service 0a38ef
                        user_add, user_del = gen_add_del_lists(
Packit Service 0a38ef
                            user, res_find.get("member_user"))
Packit Service 0a38ef
Packit Service 0a38ef
                        group_add, group_del = gen_add_del_lists(
Packit Service 0a38ef
                            group, res_find.get("member_group"))
Packit Service 0a38ef
Packit Service 0a38ef
                        service_add, service_del = gen_add_del_lists(
Packit Service 0a38ef
                            service, res_find.get("member_service"))
Packit Service 0a38ef
Packit Service a166ed
                        (externalmember_add,
Packit Service a166ed
                         externalmember_del) = gen_add_del_lists(
Packit Service a166ed
                            externalmember, res_find.get("member_external"))
Packit Service a166ed
Packit Service a166ed
                        # setup member args for add/remove members.
Packit Service a166ed
                        add_member_args = {
Packit Service a166ed
                            "user": user_add,
Packit Service a166ed
                            "group": group_add,
Packit Service a166ed
                        }
Packit Service a166ed
                        del_member_args = {
Packit Service a166ed
                            "user": user_del,
Packit Service a166ed
                            "group": group_del,
Packit Service a166ed
                        }
Packit Service 0a38ef
                        if has_add_member_service:
Packit Service a166ed
                            add_member_args["service"] = service_add
Packit Service a166ed
                            del_member_args["service"] = service_del
Packit Service a166ed
Packit Service a166ed
                        if is_external_group(res_find):
Packit Service a166ed
                            add_member_args["ipaexternalmember"] = \
Packit Service a166ed
                                externalmember_add
Packit Service a166ed
                            del_member_args["ipaexternalmember"] = \
Packit Service a166ed
                                externalmember_del
Packit Service a166ed
                        elif externalmember or external:
Packit Service a166ed
                            ansible_module.fail_json(
Packit Service a166ed
                                msg="Cannot add external members to a "
Packit Service a166ed
                                    "non-external group."
Packit Service a166ed
                            )
Packit Service a166ed
Packit Service a166ed
                        # Add members
Packit Service a166ed
                        add_members = any([user_add, group_add,
Packit Service a166ed
                                           service_add, externalmember_add])
Packit Service a166ed
                        if add_members:
Packit Service a166ed
                            commands.append(
Packit Service a166ed
                                [name, "group_add_member", add_member_args]
Packit Service a166ed
                            )
Packit Service a166ed
                        # Remove members
Packit Service a166ed
                        remove_members = any([user_del, group_del,
Packit Service a166ed
                                              service_del, externalmember_del])
Packit Service a166ed
                        if remove_members:
Packit Service a166ed
                            commands.append(
Packit Service a166ed
                                [name, "group_remove_member", del_member_args]
Packit Service a166ed
                            )
Packit Service 0a38ef
Packit Service 0a38ef
                    membermanager_user_add, membermanager_user_del = \
Packit Service 0a38ef
                        gen_add_del_lists(
Packit Service 0a38ef
                            membermanager_user,
Packit Service 0a38ef
                            res_find.get("membermanager_user")
Packit Service 0a38ef
                        )
Packit Service 0a38ef
Packit Service 0a38ef
                    membermanager_group_add, membermanager_group_del = \
Packit Service 0a38ef
                        gen_add_del_lists(
Packit Service 0a38ef
                            membermanager_group,
Packit Service 0a38ef
                            res_find.get("membermanager_group")
Packit Service 0a38ef
                        )
Packit Service 0a38ef
Packit Service 0a38ef
                    if has_add_membermanager:
Packit Service 0a38ef
                        # Add membermanager users and groups
Packit Service 0a38ef
                        if len(membermanager_user_add) > 0 or \
Packit Service 0a38ef
                           len(membermanager_group_add) > 0:
Packit Service 0a38ef
                            commands.append(
Packit Service 0a38ef
                                [name, "group_add_member_manager",
Packit Service 0a38ef
                                 {
Packit Service 0a38ef
                                     "user": membermanager_user_add,
Packit Service 0a38ef
                                     "group": membermanager_group_add,
Packit Service 0a38ef
                                 }]
Packit Service 0a38ef
                            )
Packit Service 0a38ef
                        # Remove member manager
Packit Service 0a38ef
                        if len(membermanager_user_del) > 0 or \
Packit Service 0a38ef
                           len(membermanager_group_del) > 0:
Packit Service 0a38ef
                            commands.append(
Packit Service 0a38ef
                                [name, "group_remove_member_manager",
Packit Service 0a38ef
                                 {
Packit Service 0a38ef
                                     "user": membermanager_user_del,
Packit Service 0a38ef
                                     "group": membermanager_group_del,
Packit Service 0a38ef
                                 }]
Packit Service 0a38ef
                            )
Packit Service 0a38ef
Packit Service 0a38ef
                elif action == "member":
Packit Service 0a38ef
                    if res_find is None:
Packit Service 0a38ef
                        ansible_module.fail_json(msg="No group '%s'" % name)
Packit Service a166ed
Packit Service a166ed
                    add_member_args = {
Packit Service a166ed
                        "user": user,
Packit Service a166ed
                        "group": group,
Packit Service a166ed
                    }
Packit Service 0a38ef
                    if has_add_member_service:
Packit Service a166ed
                        add_member_args["service"] = service
Packit Service a166ed
                    if is_external_group(res_find):
Packit Service a166ed
                        add_member_args["ipaexternalmember"] = externalmember
Packit Service a166ed
                    elif externalmember:
Packit Service a166ed
                        ansible_module.fail_json(
Packit Service a166ed
                            msg="Cannot add external members to a "
Packit Service a166ed
                                "non-external group."
Packit Service a166ed
                        )
Packit Service a166ed
Packit Service a166ed
                    if any([user, group, service, externalmember]):
Packit Service a166ed
                        commands.append(
Packit Service a166ed
                            [name, "group_add_member", add_member_args]
Packit Service a166ed
                        )
Packit Service 0a38ef
Packit Service 0a38ef
                    if has_add_membermanager:
Packit Service 0a38ef
                        # Add membermanager users and groups
Packit Service 0a38ef
                        if membermanager_user is not None or \
Packit Service 0a38ef
                           membermanager_group is not None:
Packit Service 0a38ef
                            commands.append(
Packit Service 0a38ef
                                [name, "group_add_member_manager",
Packit Service 0a38ef
                                 {
Packit Service 0a38ef
                                     "user": membermanager_user,
Packit Service 0a38ef
                                     "group": membermanager_group,
Packit Service 0a38ef
                                 }]
Packit Service 0a38ef
                            )
Packit Service 0a38ef
Packit Service 0a38ef
            elif state == "absent":
Packit Service 0a38ef
                if action == "group":
Packit Service 0a38ef
                    if res_find is not None:
Packit Service 0a38ef
                        commands.append([name, "group_del", {}])
Packit Service 0a38ef
Packit Service 0a38ef
                elif action == "member":
Packit Service 0a38ef
                    if res_find is None:
Packit Service 0a38ef
                        ansible_module.fail_json(msg="No group '%s'" % name)
Packit Service 0a38ef
Packit Service a166ed
                    del_member_args = {
Packit Service a166ed
                        "user": user,
Packit Service a166ed
                        "group": group,
Packit Service a166ed
                    }
Packit Service 0a38ef
                    if has_add_member_service:
Packit Service a166ed
                        del_member_args["service"] = service
Packit Service a166ed
                    if is_external_group(res_find):
Packit Service a166ed
                        del_member_args["ipaexternalmember"] = externalmember
Packit Service a166ed
                    elif externalmember:
Packit Service a166ed
                        ansible_module.fail_json(
Packit Service a166ed
                            msg="Cannot add external members to a "
Packit Service a166ed
                                "non-external group."
Packit Service a166ed
                        )
Packit Service a166ed
Packit Service a166ed
                    if any([user, group, service, externalmember]):
Packit Service a166ed
                        commands.append(
Packit Service a166ed
                            [name, "group_remove_member", del_member_args]
Packit Service a166ed
                        )
Packit Service 0a38ef
Packit Service 0a38ef
                    if has_add_membermanager:
Packit Service 0a38ef
                        # Remove membermanager users and groups
Packit Service 0a38ef
                        if membermanager_user is not None or \
Packit Service 0a38ef
                           membermanager_group is not None:
Packit Service 0a38ef
                            commands.append(
Packit Service 0a38ef
                                [name, "group_remove_member_manager",
Packit Service 0a38ef
                                 {
Packit Service 0a38ef
                                     "user": membermanager_user,
Packit Service 0a38ef
                                     "group": membermanager_group,
Packit Service 0a38ef
                                 }]
Packit Service 0a38ef
                            )
Packit Service 0a38ef
Packit Service 0a38ef
            else:
Packit Service 0a38ef
                ansible_module.fail_json(msg="Unkown state '%s'" % state)
Packit Service 0a38ef
Packit Service 0a38ef
        # Execute commands
Packit Service 0a38ef
Packit Service 0a38ef
        for name, command, args in commands:
Packit Service 0a38ef
            try:
Packit Service 0a38ef
                result = api_command(ansible_module, command, name,
Packit Service 0a38ef
                                     args)
Packit Service 0a38ef
                if "completed" in result:
Packit Service 0a38ef
                    if result["completed"] > 0:
Packit Service 0a38ef
                        changed = True
Packit Service 0a38ef
                else:
Packit Service 0a38ef
                    changed = True
Packit Service 0a38ef
            except Exception as e:
Packit Service 0a38ef
                ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
Packit Service 0a38ef
                                                             str(e)))
Packit Service 0a38ef
            # Get all errors
Packit Service 0a38ef
            # All "already a member" and "not a member" failures in the
Packit Service 0a38ef
            # result are ignored. All others are reported.
Packit Service 0a38ef
            errors = []
Packit Service a166ed
            for failed_item in result.get("failed", []):
Packit Service a166ed
                failed = result["failed"][failed_item]
Packit Service a166ed
                for member_type in failed:
Packit Service a166ed
                    for member, failure in failed[member_type]:
Packit Service a166ed
                        if "already a member" in failure \
Packit Service a166ed
                           or "not a member" in failure:
Packit Service a166ed
                            continue
Packit Service a166ed
                        errors.append("%s: %s %s: %s" % (
Packit Service a166ed
                            command, member_type, member, failure))
Packit Service 0a38ef
            if len(errors) > 0:
Packit Service 0a38ef
                ansible_module.fail_json(msg=", ".join(errors))
Packit Service 0a38ef
Packit Service 0a38ef
    except Exception as e:
Packit Service 0a38ef
        ansible_module.fail_json(msg=str(e))
Packit Service 0a38ef
Packit Service 0a38ef
    finally:
Packit Service 0a38ef
        temp_kdestroy(ccache_dir, ccache_name)
Packit Service 0a38ef
Packit Service 0a38ef
    # Done
Packit Service 0a38ef
Packit Service 0a38ef
    ansible_module.exit_json(changed=changed, **exit_args)
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
if __name__ == "__main__":
Packit Service 0a38ef
    main()