Blame plugins/modules/ipahost.py

Packit 8cb997
#!/usr/bin/python
Packit 8cb997
# -*- coding: utf-8 -*-
Packit 8cb997
Packit 8cb997
# Authors:
Packit 8cb997
#   Thomas Woerner <twoerner@redhat.com>
Packit 8cb997
#
Packit 8cb997
# Copyright (C) 2019 Red Hat
Packit 8cb997
# see file 'COPYING' for use and warranty information
Packit 8cb997
#
Packit 8cb997
# This program is free software; you can redistribute it and/or modify
Packit 8cb997
# it under the terms of the GNU General Public License as published by
Packit 8cb997
# the Free Software Foundation, either version 3 of the License, or
Packit 8cb997
# (at your option) any later version.
Packit 8cb997
#
Packit 8cb997
# This program is distributed in the hope that it will be useful,
Packit 8cb997
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8cb997
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8cb997
# GNU General Public License for more details.
Packit 8cb997
#
Packit 8cb997
# You should have received a copy of the GNU General Public License
Packit 8cb997
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit 8cb997
Packit 8cb997
ANSIBLE_METADATA = {
Packit 8cb997
    "metadata_version": "1.0",
Packit 8cb997
    "supported_by": "community",
Packit 8cb997
    "status": ["preview"],
Packit 8cb997
}
Packit 8cb997
Packit 8cb997
DOCUMENTATION = """
Packit 8cb997
---
Packit 8cb997
module: ipahost
Packit 8cb997
short description: Manage FreeIPA hosts
Packit 8cb997
description: Manage FreeIPA hosts
Packit 8cb997
options:
Packit 8cb997
  ipaadmin_principal:
Packit 8cb997
    description: The admin principal
Packit 8cb997
    default: admin
Packit 8cb997
  ipaadmin_password:
Packit 8cb997
    description: The admin password
Packit 8cb997
    required: false
Packit 8cb997
  name:
Packit 8cb997
    description: The full qualified domain name.
Packit 8cb997
    aliases: ["fqdn"]
Packit 8cb997
    required: true
Packit 8cb997
Packit 8cb997
  hosts:
Packit 8cb997
    description: The list of user host dicts
Packit 8cb997
    required: false
Packit 8cb997
    options:
Packit 8cb997
      name:
Packit 8cb997
        description: The host (internally uid).
Packit 8cb997
        aliases: ["fqdn"]
Packit 8cb997
        required: true
Packit 8cb997
      description:
Packit 8cb997
        description: The host description
Packit 8cb997
        required: false
Packit 8cb997
      locality:
Packit 8cb997
        description: Host locality (e.g. "Baltimore, MD")
Packit 8cb997
        required: false
Packit 8cb997
      location:
Packit 8cb997
        description: Host location (e.g. "Lab 2")
Packit 8cb997
        aliases: ["ns_host_location"]
Packit 8cb997
        required: false
Packit 8cb997
      platform:
Packit 8cb997
        description: Host hardware platform (e.g. "Lenovo T61")
Packit 8cb997
        aliases: ["ns_hardware_platform"]
Packit 8cb997
        required: false
Packit 8cb997
      os:
Packit 8cb997
        description: Host operating system and version (e.g. "Fedora 9")
Packit 8cb997
        aliases: ["ns_os_version"]
Packit 8cb997
        required: false
Packit 8cb997
      password:
Packit 8cb997
        description: Password used in bulk enrollment
Packit 8cb997
        aliases: ["user_password", "userpassword"]
Packit 8cb997
        required: false
Packit 8cb997
      random:
Packit 8cb997
        description:
Packit 8cb997
          Initiate the generation of a random password to be used in bulk
Packit 8cb997
          enrollment
Packit 8cb997
        aliases: ["random_password"]
Packit 8cb997
        required: false
Packit 8cb997
      certificate:
Packit 8cb997
        description: List of base-64 encoded host certificates
Packit 8cb997
        type: list
Packit 8cb997
        aliases: ["usercertificate"]
Packit 8cb997
        required: false
Packit 8cb997
      managedby_host:
Packit 8cb997
        description: List of hosts that can manage this host
Packit 8cb997
        type: list
Packit 8cb997
        aliases: ["principalname", "krbprincipalname"]
Packit 8cb997
        required: false
Packit 8cb997
      principal:
Packit 8cb997
        description: List of principal aliases for this host
Packit 8cb997
        type: list
Packit 8cb997
        aliases: ["principalname", "krbprincipalname"]
Packit 8cb997
        required: false
Packit 8cb997
      allow_create_keytab_user:
Packit 8cb997
        description: Users allowed to create a keytab of this host
Packit 8cb997
        aliases: ["ipaallowedtoperform_write_keys_user"]
Packit 8cb997
        required: false
Packit 8cb997
      allow_create_keytab_group:
Packit 8cb997
        description: Groups allowed to create a keytab of this host
Packit 8cb997
        aliases: ["ipaallowedtoperform_write_keys_group"]
Packit 8cb997
        required: false
Packit 8cb997
      allow_create_keytab_host:
Packit 8cb997
        description: Hosts allowed to create a keytab of this host
Packit 8cb997
        aliases: ["ipaallowedtoperform_write_keys_host"]
Packit 8cb997
        required: false
Packit 8cb997
      allow_create_keytab_hostgroup:
Packit 8cb997
        description: Hostgroups allowed to create a keytab of this host
Packit 8cb997
        aliases: ["ipaallowedtoperform_write_keys_hostgroup"]
Packit 8cb997
        required: false
Packit 8cb997
      allow_retrieve_keytab_user:
Packit 8cb997
        description: Users allowed to retrieve a keytab of this host
Packit 8cb997
        aliases: ["ipaallowedtoperform_read_keys_user"]
Packit 8cb997
        required: false
Packit 8cb997
      allow_retrieve_keytab_group:
Packit 8cb997
        description: Groups allowed to retrieve a keytab of this host
Packit 8cb997
        aliases: ["ipaallowedtoperform_read_keys_group"]
Packit 8cb997
        required: false
Packit 8cb997
      allow_retrieve_keytab_host:
Packit 8cb997
        description: Hosts allowed to retrieve a keytab of this host
Packit 8cb997
        aliases: ["ipaallowedtoperform_read_keys_host"]
Packit 8cb997
        required: false
Packit 8cb997
      allow_retrieve_keytab_hostgroup:
Packit 8cb997
        description: Hostgroups allowed to retrieve a keytab of this host
Packit 8cb997
        aliases: ["ipaallowedtoperform_read_keys_hostgroup"]
Packit 8cb997
        required: false
Packit 8cb997
      mac_address:
Packit 8cb997
        description: List of hardware MAC addresses.
Packit 8cb997
        type: list
Packit 8cb997
        aliases: ["macaddress"]
Packit 8cb997
        required: false
Packit 8cb997
      sshpubkey:
Packit 8cb997
        description: List of SSH public keys
Packit 8cb997
        type: list
Packit 8cb997
        aliases: ["ipasshpubkey"]
Packit 8cb997
        required: false
Packit 8cb997
      userclass:
Packit 8cb997
        description:
Packit 8cb997
          Host category (semantics placed on this attribute are for local
Packit 8cb997
          interpretation)
Packit 8cb997
        aliases: ["class"]
Packit 8cb997
        required: false
Packit 8cb997
      auth_ind:
Packit 8cb997
        description:
Packit 8cb997
          Defines a whitelist for Authentication Indicators. Use 'otp' to allow
Packit 8cb997
          OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA
Packit 8cb997
          authentications. Other values may be used for custom configurations.
Packit 98a68e
          Use empty string to reset auth_ind to the initial value.
Packit 8cb997
        type: list
Packit 8cb997
        aliases: ["krbprincipalauthind"]
Packit 98a68e
        choices: ["radius", "otp", "pkinit", "hardened", ""]
Packit 8cb997
        required: false
Packit 8cb997
      requires_pre_auth:
Packit 8cb997
        description: Pre-authentication is required for the service
Packit 8cb997
        type: bool
Packit 8cb997
        aliases: ["ipakrbrequirespreauth"]
Packit 8cb997
        required: false
Packit 8cb997
      ok_as_delegate:
Packit 8cb997
        description: Client credentials may be delegated to the service
Packit 8cb997
        type: bool
Packit 8cb997
        aliases: ["ipakrbokasdelegate"]
Packit 8cb997
        required: false
Packit 8cb997
      ok_to_auth_as_delegate:
Packit 8cb997
        description:
Packit 8cb997
          The service is allowed to authenticate on behalf of a client
Packit 8cb997
        type: bool
Packit 8cb997
        aliases: ["ipakrboktoauthasdelegate"]
Packit 8cb997
        required: false
Packit 8cb997
      force:
Packit 8cb997
        description: Force host name even if not in DNS
Packit 8cb997
        required: false
Packit 8cb997
      reverse:
Packit 8cb997
        description: Reverse DNS detection
Packit 8cb997
        default: true
Packit 8cb997
        required: false
Packit 8cb997
      ip_address:
Packit 8cb997
        description: The host IP address
Packit 8cb997
        aliases: ["ipaddress"]
Packit 8cb997
        required: false
Packit 8cb997
      update_dns:
Packit 8cb997
        description: Update DNS entries
Packit 8cb997
        required: false
Packit 8cb997
  description:
Packit 8cb997
    description: The host description
Packit 8cb997
    required: false
Packit 8cb997
  locality:
Packit 8cb997
    description: Host locality (e.g. "Baltimore, MD")
Packit 8cb997
    required: false
Packit 8cb997
  location:
Packit 8cb997
    description: Host location (e.g. "Lab 2")
Packit 8cb997
    aliases: ["ns_host_location"]
Packit 8cb997
    required: false
Packit 8cb997
  platform:
Packit 8cb997
    description: Host hardware platform (e.g. "Lenovo T61")
Packit 8cb997
    aliases: ["ns_hardware_platform"]
Packit 8cb997
    required: false
Packit 8cb997
  os:
Packit 8cb997
    description: Host operating system and version (e.g. "Fedora 9")
Packit 8cb997
    aliases: ["ns_os_version"]
Packit 8cb997
    required: false
Packit 8cb997
  password:
Packit 8cb997
    description: Password used in bulk enrollment
Packit 8cb997
    aliases: ["user_password", "userpassword"]
Packit 8cb997
    required: false
Packit 8cb997
  random:
Packit 8cb997
    description:
Packit 8cb997
      Initiate the generation of a random password to be used in bulk
Packit 8cb997
      enrollment
Packit 8cb997
    aliases: ["random_password"]
Packit 8cb997
    required: false
Packit 8cb997
  certificate:
Packit 8cb997
    description: List of base-64 encoded host certificates
Packit 8cb997
    type: list
Packit 8cb997
    aliases: ["usercertificate"]
Packit 8cb997
    required: false
Packit 8cb997
  managedby_host:
Packit 8cb997
    description: List of hosts that can manage this host
Packit 8cb997
    type: list
Packit 8cb997
    aliases: ["principalname", "krbprincipalname"]
Packit 8cb997
    required: false
Packit 8cb997
  principal:
Packit 8cb997
    description: List of principal aliases for this host
Packit 8cb997
    type: list
Packit 8cb997
    aliases: ["principalname", "krbprincipalname"]
Packit 8cb997
    required: false
Packit 8cb997
  allow_create_keytab_user:
Packit 8cb997
    description: Users allowed to create a keytab of this host
Packit 8cb997
    aliases: ["ipaallowedtoperform_write_keys_user"]
Packit 8cb997
    required: false
Packit 8cb997
  allow_create_keytab_group:
Packit 8cb997
    description: Groups allowed to create a keytab of this host
Packit 8cb997
    aliases: ["ipaallowedtoperform_write_keys_group"]
Packit 8cb997
    required: false
Packit 8cb997
  allow_create_keytab_host:
Packit 8cb997
    description: Hosts allowed to create a keytab of this host
Packit 8cb997
    aliases: ["ipaallowedtoperform_write_keys_host"]
Packit 8cb997
    required: false
Packit 8cb997
  allow_create_keytab_hostgroup:
Packit 8cb997
    description: Hostgroups allowed to create a keytab of this host
Packit 8cb997
    aliases: ["ipaallowedtoperform_write_keys_hostgroup"]
Packit 8cb997
    required: false
Packit 8cb997
  allow_retrieve_keytab_user:
Packit 8cb997
    description: Users allowed to retrieve a keytab of this host
Packit 8cb997
    aliases: ["ipaallowedtoperform_read_keys_user"]
Packit 8cb997
    required: false
Packit 8cb997
  allow_retrieve_keytab_group:
Packit 8cb997
    description: Groups allowed to retrieve a keytab of this host
Packit 8cb997
    aliases: ["ipaallowedtoperform_read_keys_group"]
Packit 8cb997
    required: false
Packit 8cb997
  allow_retrieve_keytab_host:
Packit 8cb997
    description: Hosts allowed to retrieve a keytab of this host
Packit 8cb997
    aliases: ["ipaallowedtoperform_read_keys_host"]
Packit 8cb997
    required: false
Packit 8cb997
  allow_retrieve_keytab_hostgroup:
Packit 8cb997
    description: Hostgroups allowed to retrieve a keytab of this host
Packit 8cb997
    aliases: ["ipaallowedtoperform_read_keys_hostgroup"]
Packit 8cb997
    required: false
Packit 8cb997
  mac_address:
Packit 8cb997
    description: List of hardware MAC addresses.
Packit 8cb997
    type: list
Packit 8cb997
    aliases: ["macaddress"]
Packit 8cb997
    required: false
Packit 8cb997
  sshpubkey:
Packit 8cb997
    description: List of SSH public keys
Packit 8cb997
    type: list
Packit 8cb997
    aliases: ["ipasshpubkey"]
Packit 8cb997
    required: false
Packit 8cb997
  userclass:
Packit 8cb997
    description:
Packit 8cb997
      Host category (semantics placed on this attribute are for local
Packit 8cb997
      interpretation)
Packit 8cb997
    aliases: ["class"]
Packit 8cb997
    required: false
Packit 8cb997
  auth_ind:
Packit 8cb997
    description:
Packit 8cb997
      Defines a whitelist for Authentication Indicators. Use 'otp' to allow
Packit 8cb997
      OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA
Packit 8cb997
      authentications. Other values may be used for custom configurations.
Packit 98a68e
      Use empty string to reset auth_ind to the initial value.
Packit 8cb997
    type: list
Packit 8cb997
    aliases: ["krbprincipalauthind"]
Packit 98a68e
    choices: ["radius", "otp", "pkinit", "hardened", ""]
Packit 8cb997
    required: false
Packit 8cb997
  requires_pre_auth:
Packit 8cb997
    description: Pre-authentication is required for the service
Packit 8cb997
    type: bool
Packit 8cb997
    aliases: ["ipakrbrequirespreauth"]
Packit 8cb997
    required: false
Packit 8cb997
  ok_as_delegate:
Packit 8cb997
    description: Client credentials may be delegated to the service
Packit 8cb997
    type: bool
Packit 8cb997
    aliases: ["ipakrbokasdelegate"]
Packit 8cb997
    required: false
Packit 8cb997
  ok_to_auth_as_delegate:
Packit 8cb997
    description: The service is allowed to authenticate on behalf of a client
Packit 8cb997
    type: bool
Packit 8cb997
    aliases: ["ipakrboktoauthasdelegate"]
Packit 8cb997
    required: false
Packit 8cb997
  force:
Packit 8cb997
    description: Force host name even if not in DNS
Packit 8cb997
    required: false
Packit 8cb997
  reverse:
Packit 8cb997
    description: Reverse DNS detection
Packit 8cb997
    default: true
Packit 8cb997
    required: false
Packit 8cb997
  ip_address:
Packit 8cb997
    description: The host IP address
Packit 8cb997
    aliases: ["ipaddress"]
Packit 8cb997
    required: false
Packit 8cb997
  update_dns:
Packit 8cb997
    description: Update DNS entries
Packit 8cb997
    required: false
Packit 8cb997
  update_password:
Packit 8cb997
    description:
Packit 8cb997
      Set password for a host in present state only on creation or always
Packit 8cb997
    default: 'always'
Packit 8cb997
    choices: ["always", "on_create"]
Packit 8cb997
  action:
Packit 8cb997
    description: Work on host or member level
Packit 8cb997
    default: "host"
Packit 8cb997
    choices: ["member", "host"]
Packit 8cb997
  state:
Packit 8cb997
    description: State to ensure
Packit 8cb997
    default: present
Packit 8cb997
    choices: ["present", "absent",
Packit 8cb997
              "disabled"]
Packit 8cb997
author:
Packit 8cb997
    - Thomas Woerner
Packit 8cb997
"""
Packit 8cb997
Packit 8cb997
EXAMPLES = """
Packit 8cb997
# Ensure host is present
Packit 8cb997
- ipahost:
Packit 8cb997
    ipaadmin_password: MyPassword123
Packit 8cb997
    name: host01.example.com
Packit 8cb997
    description: Example host
Packit 8cb997
    ip_address: 192.168.0.123
Packit 8cb997
    locality: Lab
Packit 8cb997
    ns_host_location: Lab
Packit 8cb997
    ns_os_version: CentOS 7
Packit 8cb997
    ns_hardware_platform: Lenovo T61
Packit 8cb997
    mac_address:
Packit 8cb997
    - "08:00:27:E3:B1:2D"
Packit 8cb997
    - "52:54:00:BD:97:1E"
Packit 8cb997
    state: present
Packit 8cb997
Packit 8cb997
# Ensure host is present without DNS
Packit 8cb997
- ipahost:
Packit 8cb997
    ipaadmin_password: MyPassword123
Packit 8cb997
    name: host02.example.com
Packit 8cb997
    description: Example host
Packit 8cb997
    force: yes
Packit 8cb997
Packit 8cb997
# Initiate generation of a random password for the host
Packit 8cb997
- ipahost:
Packit 8cb997
    ipaadmin_password: MyPassword123
Packit 8cb997
    name: host01.example.com
Packit 8cb997
    description: Example host
Packit 8cb997
    ip_address: 192.168.0.123
Packit 8cb997
    random: yes
Packit 8cb997
Packit 8cb997
# Ensure host is disabled
Packit 8cb997
- ipahost:
Packit 8cb997
    ipaadmin_password: MyPassword123
Packit 8cb997
    name: host01.example.com
Packit 8cb997
    update_dns: yes
Packit 8cb997
    state: disabled
Packit 8cb997
Packit 8cb997
# Ensure host is absent
Packit 8cb997
- ipahost:
Packit 8cb997
    ipaadmin_password: password1
Packit 8cb997
    name: host01.example.com
Packit 8cb997
    state: absent
Packit 8cb997
"""
Packit 8cb997
Packit 8cb997
RETURN = """
Packit 8cb997
host:
Packit 8cb997
  description: Host dict with random password
Packit 8cb997
  returned: If random is yes and user did not exist or update_password is yes
Packit 8cb997
  type: dict
Packit 8cb997
  options:
Packit 8cb997
    randompassword:
Packit 8cb997
      description: The generated random password
Packit 8cb997
      returned: If only one user is handled by the module
Packit 8cb997
    name:
Packit 8cb997
      description: The user name of the user that got a new random password
Packit 8cb997
      returned: If several users are handled by the module
Packit 8cb997
      type: dict
Packit 8cb997
      options:
Packit 8cb997
        randompassword:
Packit 8cb997
          description: The generated random password
Packit 8cb997
          returned: always
Packit 8cb997
"""
Packit 8cb997
Packit 8cb997
from ansible.module_utils.basic import AnsibleModule
Packit 8cb997
from ansible.module_utils._text import to_text
Packit 8cb997
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
Packit 8cb997
    temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
Packit 8cb997
    module_params_get, gen_add_del_lists, encode_certificate, api_get_realm
Packit 8cb997
import six
Packit 8cb997
Packit 8cb997
Packit 8cb997
if six.PY3:
Packit 8cb997
    unicode = str
Packit 8cb997
Packit 8cb997
Packit 8cb997
def find_host(module, name):
Packit 8cb997
    _args = {
Packit 8cb997
        "all": True,
Packit 8cb997
        "fqdn": to_text(name),
Packit 8cb997
    }
Packit 8cb997
Packit 8cb997
    _result = api_command(module, "host_find", to_text(name), _args)
Packit 8cb997
Packit 8cb997
    if len(_result["result"]) > 1:
Packit 8cb997
        module.fail_json(
Packit 8cb997
            msg="There is more than one host '%s'" % (name))
Packit 8cb997
    elif len(_result["result"]) == 1:
Packit 8cb997
        _res = _result["result"][0]
Packit 8cb997
        certs = _res.get("usercertificate")
Packit 8cb997
        if certs is not None:
Packit 8cb997
            _res["usercertificate"] = [encode_certificate(cert) for
Packit 8cb997
                                       cert in certs]
Packit 8cb997
        return _res
Packit 8cb997
    else:
Packit 8cb997
        return None
Packit 8cb997
Packit 8cb997
Packit 8cb997
def show_host(module, name):
Packit 8cb997
    _result = api_command(module, "host_show", to_text(name), {})
Packit 8cb997
    return _result["result"]
Packit 8cb997
Packit 8cb997
Packit 8cb997
def gen_args(description, locality, location, platform, os, password, random,
Packit 8cb997
             mac_address, sshpubkey, userclass, auth_ind, requires_pre_auth,
Packit 8cb997
             ok_as_delegate, ok_to_auth_as_delegate, force, reverse,
Packit 8cb997
             ip_address, update_dns):
Packit 8cb997
    # certificate, managedby_host, principal, create_keytab_* and
Packit 8cb997
    # allow_retrieve_keytab_* are not handled here
Packit 8cb997
    _args = {}
Packit 8cb997
    if description is not None:
Packit 8cb997
        _args["description"] = description
Packit 8cb997
    if locality is not None:
Packit 8cb997
        _args["l"] = locality
Packit 8cb997
    if location is not None:
Packit 8cb997
        _args["nshostlocation"] = location
Packit 8cb997
    if platform is not None:
Packit 8cb997
        _args["nshardwareplatform"] = platform
Packit 8cb997
    if os is not None:
Packit 8cb997
        _args["nsosversion"] = os
Packit 8cb997
    if password is not None:
Packit 8cb997
        _args["userpassword"] = password
Packit 8cb997
    if random is not None:
Packit 8cb997
        _args["random"] = random
Packit 8cb997
    if mac_address is not None:
Packit 8cb997
        _args["macaddress"] = mac_address
Packit 8cb997
    if sshpubkey is not None:
Packit 8cb997
        _args["ipasshpubkey"] = sshpubkey
Packit 8cb997
    if userclass is not None:
Packit 8cb997
        _args["userclass"] = userclass
Packit 8cb997
    if auth_ind is not None:
Packit 8cb997
        _args["krbprincipalauthind"] = auth_ind
Packit 8cb997
    if requires_pre_auth is not None:
Packit 8cb997
        _args["ipakrbrequirespreauth"] = requires_pre_auth
Packit 8cb997
    if ok_as_delegate is not None:
Packit 8cb997
        _args["ipakrbokasdelegate"] = ok_as_delegate
Packit 8cb997
    if ok_to_auth_as_delegate is not None:
Packit 8cb997
        _args["ipakrboktoauthasdelegate"] = ok_to_auth_as_delegate
Packit 8cb997
    if force is not None:
Packit 8cb997
        _args["force"] = force
Packit 8cb997
    if reverse is not None:
Packit 8cb997
        _args["no_reverse"] = not reverse
Packit 8cb997
    if ip_address is not None:
Packit 8cb997
        _args["ip_address"] = ip_address
Packit 8cb997
    if update_dns is not None:
Packit 8cb997
        _args["updatedns"] = update_dns
Packit 8cb997
Packit 8cb997
    return _args
Packit 8cb997
Packit 8cb997
Packit 8cb997
def check_parameters(
Packit 8cb997
        module, state, action,
Packit 8cb997
        description, locality, location, platform, os, password, random,
Packit 8cb997
        certificate, managedby_host, principal, allow_create_keytab_user,
Packit 8cb997
        allow_create_keytab_group, allow_create_keytab_host,
Packit 8cb997
        allow_create_keytab_hostgroup, allow_retrieve_keytab_user,
Packit 8cb997
        allow_retrieve_keytab_group, allow_retrieve_keytab_host,
Packit 8cb997
        allow_retrieve_keytab_hostgroup, mac_address, sshpubkey,
Packit 8cb997
        userclass, auth_ind, requires_pre_auth, ok_as_delegate,
Packit 8cb997
        ok_to_auth_as_delegate, force, reverse, ip_address, update_dns,
Packit 8cb997
        update_password):
Packit 8cb997
    if state == "present":
Packit 8cb997
        if action == "member":
Packit 8cb997
            # certificate, managedby_host, principal,
Packit 8cb997
            # allow_create_keytab_*, allow_retrieve_keytab_*,
Packit 8cb997
            invalid = ["description", "locality", "location", "platform",
Packit 8cb997
                       "os", "password", "random", "mac_address", "sshpubkey",
Packit 8cb997
                       "userclass", "auth_ind", "requires_pre_auth",
Packit 8cb997
                       "ok_as_delegate", "ok_to_auth_as_delegate", "force",
Packit 8cb997
                       "reverse", "ip_address", "update_dns",
Packit 8cb997
                       "update_password"]
Packit 8cb997
            for x in invalid:
Packit 8cb997
                if vars()[x] is not None:
Packit 8cb997
                    module.fail_json(
Packit 8cb997
                        msg="Argument '%s' can not be used with action "
Packit 8cb997
                        "'%s'" % (x, action))
Packit 8cb997
Packit 8cb997
    if state == "absent":
Packit 8cb997
        invalid = ["description", "locality", "location", "platform", "os",
Packit 8cb997
                   "password", "random", "mac_address", "sshpubkey",
Packit 8cb997
                   "userclass", "auth_ind", "requires_pre_auth",
Packit 8cb997
                   "ok_as_delegate", "ok_to_auth_as_delegate", "force",
Packit 8cb997
                   "reverse", "ip_address", "update_password"]
Packit 3b2dd7
        for x in invalid:
Packit 3b2dd7
            if vars()[x] is not None:
Packit 3b2dd7
                module.fail_json(
Packit 3b2dd7
                    msg="Argument '%s' can not be used with state '%s'" %
Packit 3b2dd7
                    (x, state))
Packit 8cb997
        if action == "host":
Packit 3b2dd7
            invalid = [
Packit 8cb997
                "certificate", "managedby_host", "principal",
Packit 8cb997
                "allow_create_keytab_user", "allow_create_keytab_group",
Packit 8cb997
                "allow_create_keytab_host", "allow_create_keytab_hostgroup",
Packit 8cb997
                "allow_retrieve_keytab_user", "allow_retrieve_keytab_group",
Packit 8cb997
                "allow_retrieve_keytab_host",
Packit 3b2dd7
                "allow_retrieve_keytab_hostgroup"
Packit 3b2dd7
            ]
Packit 3b2dd7
            for x in invalid:
Packit 3b2dd7
                if vars()[x] is not None:
Packit 3b2dd7
                    module.fail_json(
Packit 3b2dd7
                        msg="Argument '%s' can only be used with action "
Packit 3b2dd7
                        "'member' for state '%s'" % (x, state))
Packit 8cb997
Packit 8cb997
Packit 8cb997
def main():
Packit 8cb997
    host_spec = dict(
Packit 8cb997
        # present
Packit 8cb997
        description=dict(type="str", default=None),
Packit 8cb997
        locality=dict(type="str", default=None),
Packit 8cb997
        location=dict(type="str", aliases=["ns_host_location"],
Packit 8cb997
                      default=None),
Packit 8cb997
        platform=dict(type="str", aliases=["ns_hardware_platform"],
Packit 8cb997
                      default=None),
Packit 8cb997
        os=dict(type="str", aliases=["ns_os_version"], default=None),
Packit 8cb997
        password=dict(type="str",
Packit 8cb997
                      aliases=["user_password", "userpassword"],
Packit 8cb997
                      default=None, no_log=True),
Packit 8cb997
        random=dict(type="bool", aliases=["random_password"],
Packit 8cb997
                    default=None),
Packit 8cb997
Packit 8cb997
Packit 8cb997
Packit 8cb997
        certificate=dict(type="list", aliases=["usercertificate"],
Packit 8cb997
                         default=None),
Packit 8cb997
        managedby_host=dict(type="list",
Packit 8cb997
                            default=None),
Packit 8cb997
        principal=dict(type="list", aliases=["krbprincipalname"],
Packit 8cb997
                       default=None),
Packit 8cb997
        allow_create_keytab_user=dict(
Packit 8cb997
            type="list",
Packit 8cb997
            aliases=["ipaallowedtoperform_write_keys_user"],
Packit 8cb997
            default=None),
Packit 8cb997
        allow_create_keytab_group=dict(
Packit 8cb997
            type="list",
Packit 8cb997
            aliases=["ipaallowedtoperform_write_keys_group"],
Packit 8cb997
            default=None),
Packit 8cb997
        allow_create_keytab_host=dict(
Packit 8cb997
            type="list",
Packit 8cb997
            aliases=["ipaallowedtoperform_write_keys_host"],
Packit 8cb997
            default=None),
Packit 8cb997
        allow_create_keytab_hostgroup=dict(
Packit 8cb997
            type="list",
Packit 8cb997
            aliases=["ipaallowedtoperform_write_keys_hostgroup"],
Packit 8cb997
            default=None),
Packit 8cb997
        allow_retrieve_keytab_user=dict(
Packit 8cb997
            type="list",
Packit 8cb997
            aliases=["ipaallowedtoperform_write_keys_user"],
Packit 8cb997
            default=None),
Packit 8cb997
        allow_retrieve_keytab_group=dict(
Packit 8cb997
            type="list",
Packit 8cb997
            aliases=["ipaallowedtoperform_write_keys_group"],
Packit 8cb997
            default=None),
Packit 8cb997
        allow_retrieve_keytab_host=dict(
Packit 8cb997
            type="list",
Packit 8cb997
            aliases=["ipaallowedtoperform_write_keys_host"],
Packit 8cb997
            default=None),
Packit 8cb997
        allow_retrieve_keytab_hostgroup=dict(
Packit 8cb997
            type="list",
Packit 8cb997
            aliases=["ipaallowedtoperform_write_keys_hostgroup"],
Packit 8cb997
            default=None),
Packit 8cb997
        mac_address=dict(type="list", aliases=["macaddress"],
Packit 8cb997
                         default=None),
Packit 8cb997
        sshpubkey=dict(type="str", aliases=["ipasshpubkey"],
Packit 8cb997
                       default=None),
Packit 8cb997
        userclass=dict(type="list", aliases=["class"],
Packit 8cb997
                       default=None),
Packit 8cb997
        auth_ind=dict(type='list', aliases=["krbprincipalauthind"],
Packit 8cb997
                      default=None,
Packit 98a68e
                      choices=['radius', 'otp', 'pkinit', 'hardened', '']),
Packit 8cb997
        requires_pre_auth=dict(type="bool", aliases=["ipakrbrequirespreauth"],
Packit 8cb997
                               default=None),
Packit 8cb997
        ok_as_delegate=dict(type="bool", aliases=["ipakrbokasdelegate"],
Packit 8cb997
                            default=None),
Packit 8cb997
        ok_to_auth_as_delegate=dict(type="bool",
Packit 8cb997
                                    aliases=["ipakrboktoauthasdelegate"],
Packit 8cb997
                                    default=None),
Packit 8cb997
        force=dict(type='bool', default=None),
Packit 8cb997
        reverse=dict(type='bool', default=None),
Packit 8cb997
        ip_address=dict(type="str", aliases=["ipaddress"],
Packit 8cb997
                        default=None),
Packit 8cb997
        update_dns=dict(type="bool", aliases=["updatedns"],
Packit 8cb997
                        default=None),
Packit 8cb997
        # no_members
Packit 8cb997
Packit 8cb997
        # for update:
Packit 8cb997
        # krbprincipalname
Packit 8cb997
    )
Packit 8cb997
Packit 8cb997
    ansible_module = AnsibleModule(
Packit 8cb997
        argument_spec=dict(
Packit 8cb997
            # general
Packit 8cb997
            ipaadmin_principal=dict(type="str", default="admin"),
Packit 8cb997
            ipaadmin_password=dict(type="str", no_log=True),
Packit 8cb997
Packit 8cb997
            name=dict(type="list", aliases=["fqdn"], default=None,
Packit 8cb997
                      required=False),
Packit 8cb997
Packit 8cb997
            hosts=dict(type="list", default=None,
Packit 8cb997
                       options=dict(
Packit 8cb997
                           # Here name is a simple string
Packit 8cb997
                           name=dict(type="str", aliases=["fqdn"],
Packit 8cb997
                                     required=True),
Packit 8cb997
                           # Add host specific parameters
Packit 8cb997
                           **host_spec
Packit 8cb997
                       ),
Packit 8cb997
                       elements='dict', required=False),
Packit 8cb997
Packit 8cb997
            # mod
Packit 8cb997
            update_password=dict(type='str', default=None,
Packit 8cb997
                                 choices=['always', 'on_create']),
Packit 8cb997
Packit 8cb997
            # general
Packit 8cb997
            action=dict(type="str", default="host",
Packit 8cb997
                        choices=["member", "host"]),
Packit 8cb997
            state=dict(type="str", default="present",
Packit 8cb997
                       choices=["present", "absent", "disabled"]),
Packit 8cb997
Packit 8cb997
            # Add host specific parameters for simple use case
Packit 8cb997
            **host_spec
Packit 8cb997
        ),
Packit 8cb997
        mutually_exclusive=[["name", "hosts"]],
Packit 8cb997
        required_one_of=[["name", "hosts"]],
Packit 8cb997
        supports_check_mode=True,
Packit 8cb997
    )
Packit 8cb997
Packit 8cb997
    ansible_module._ansible_debug = True
Packit 8cb997
Packit 8cb997
    # Get parameters
Packit 8cb997
Packit 8cb997
    # general
Packit 8cb997
    ipaadmin_principal = module_params_get(ansible_module,
Packit 8cb997
                                           "ipaadmin_principal")
Packit 8cb997
    ipaadmin_password = module_params_get(ansible_module,
Packit 8cb997
                                          "ipaadmin_password")
Packit 8cb997
    names = module_params_get(ansible_module, "name")
Packit 8cb997
    hosts = module_params_get(ansible_module, "hosts")
Packit 8cb997
Packit 8cb997
    # present
Packit 8cb997
    description = module_params_get(ansible_module, "description")
Packit 8cb997
    locality = module_params_get(ansible_module, "locality")
Packit 8cb997
    location = module_params_get(ansible_module, "location")
Packit 8cb997
    platform = module_params_get(ansible_module, "platform")
Packit 8cb997
    os = module_params_get(ansible_module, "os")
Packit 8cb997
    password = module_params_get(ansible_module, "password")
Packit 8cb997
    random = module_params_get(ansible_module, "random")
Packit 8cb997
    certificate = module_params_get(ansible_module, "certificate")
Packit 8cb997
    managedby_host = module_params_get(ansible_module, "managedby_host")
Packit 8cb997
    principal = module_params_get(ansible_module, "principal")
Packit 8cb997
    allow_create_keytab_user = module_params_get(
Packit 8cb997
        ansible_module, "allow_create_keytab_user")
Packit 8cb997
    allow_create_keytab_group = module_params_get(
Packit 8cb997
        ansible_module, "allow_create_keytab_group")
Packit 8cb997
    allow_create_keytab_host = module_params_get(
Packit 8cb997
        ansible_module, "allow_create_keytab_host")
Packit 8cb997
    allow_create_keytab_hostgroup = module_params_get(
Packit 8cb997
        ansible_module, "allow_create_keytab_hostgroup")
Packit 8cb997
    allow_retrieve_keytab_user = module_params_get(
Packit 8cb997
        ansible_module, "allow_retrieve_keytab_user")
Packit 8cb997
    allow_retrieve_keytab_group = module_params_get(
Packit 8cb997
        ansible_module, "allow_retrieve_keytab_group")
Packit 8cb997
    allow_retrieve_keytab_host = module_params_get(
Packit 8cb997
        ansible_module, "allow_retrieve_keytab_host")
Packit 8cb997
    allow_retrieve_keytab_hostgroup = module_params_get(
Packit 8cb997
        ansible_module, "allow_retrieve_keytab_hostgroup")
Packit 8cb997
    mac_address = module_params_get(ansible_module, "mac_address")
Packit 8cb997
    sshpubkey = module_params_get(ansible_module, "sshpubkey")
Packit 8cb997
    userclass = module_params_get(ansible_module, "userclass")
Packit 8cb997
    auth_ind = module_params_get(ansible_module, "auth_ind")
Packit 8cb997
    requires_pre_auth = module_params_get(ansible_module, "requires_pre_auth")
Packit 8cb997
    ok_as_delegate = module_params_get(ansible_module, "ok_as_delegate")
Packit 8cb997
    ok_to_auth_as_delegate = module_params_get(ansible_module,
Packit 8cb997
                                               "ok_to_auth_as_delegate")
Packit 8cb997
    force = module_params_get(ansible_module, "force")
Packit 8cb997
    reverse = module_params_get(ansible_module, "reverse")
Packit 8cb997
    ip_address = module_params_get(ansible_module, "ip_address")
Packit 8cb997
    update_dns = module_params_get(ansible_module, "update_dns")
Packit 8cb997
    update_password = module_params_get(ansible_module, "update_password")
Packit 8cb997
    # general
Packit 8cb997
    action = module_params_get(ansible_module, "action")
Packit 8cb997
    state = module_params_get(ansible_module, "state")
Packit 8cb997
Packit 8cb997
    # Check parameters
Packit 8cb997
Packit 8cb997
    if (names is None or len(names) < 1) and \
Packit 8cb997
       (hosts is None or len(hosts) < 1):
Packit 8cb997
        ansible_module.fail_json(msg="One of name and hosts is required")
Packit 8cb997
Packit 8cb997
    if state == "present":
Packit 8cb997
        if names is not None and len(names) != 1:
Packit 8cb997
            ansible_module.fail_json(
Packit 8cb997
                msg="Only one host can be added at a time.")
Packit 8cb997
Packit 8cb997
    check_parameters(
Packit 8cb997
        ansible_module, state, action,
Packit 8cb997
        description, locality, location, platform, os, password, random,
Packit 8cb997
        certificate, managedby_host, principal, allow_create_keytab_user,
Packit 8cb997
        allow_create_keytab_group, allow_create_keytab_host,
Packit 8cb997
        allow_create_keytab_hostgroup, allow_retrieve_keytab_user,
Packit 8cb997
        allow_retrieve_keytab_group, allow_retrieve_keytab_host,
Packit 8cb997
        allow_retrieve_keytab_hostgroup, mac_address, sshpubkey, userclass,
Packit 8cb997
        auth_ind, requires_pre_auth, ok_as_delegate, ok_to_auth_as_delegate,
Packit 8cb997
        force, reverse, ip_address, update_dns, update_password)
Packit 8cb997
Packit 8cb997
    # Use hosts if names is None
Packit 8cb997
    if hosts is not None:
Packit 8cb997
        names = hosts
Packit 8cb997
Packit 8cb997
    # Init
Packit 8cb997
Packit 8cb997
    changed = False
Packit 8cb997
    exit_args = {}
Packit 8cb997
    ccache_dir = None
Packit 8cb997
    ccache_name = None
Packit 8cb997
    try:
Packit 8cb997
        if not valid_creds(ansible_module, ipaadmin_principal):
Packit 8cb997
            ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
Packit 8cb997
                                                 ipaadmin_password)
Packit 8cb997
        api_connect()
Packit 8cb997
Packit 8cb997
        # Check version specific settings
Packit 8cb997
Packit 8cb997
        server_realm = api_get_realm()
Packit 8cb997
Packit 8cb997
        commands = []
Packit 8cb997
Packit 8cb997
        for host in names:
Packit 8cb997
            if isinstance(host, dict):
Packit 8cb997
                name = host.get("name")
Packit 8cb997
                description = host.get("description")
Packit 8cb997
                locality = host.get("locality")
Packit 8cb997
                location = host.get("location")
Packit 8cb997
                platform = host.get("platform")
Packit 8cb997
                os = host.get("os")
Packit 8cb997
                password = host.get("password")
Packit 8cb997
                random = host.get("random")
Packit 8cb997
                certificate = host.get("certificate")
Packit 8cb997
                managedby_host = host.get("managedby_host")
Packit 8cb997
                principal = host.get("principal")
Packit 8cb997
                allow_create_keytab_user = host.get(
Packit 8cb997
                    "allow_create_keytab_user")
Packit 8cb997
                allow_create_keytab_group = host.get(
Packit 8cb997
                    "allow_create_keytab_group")
Packit 8cb997
                allow_create_keytab_host = host.get(
Packit 8cb997
                    "allow_create_keytab_host")
Packit 8cb997
                allow_create_keytab_hostgroup = host.get(
Packit 8cb997
                    "allow_create_keytab_hostgroup")
Packit 8cb997
                allow_retrieve_keytab_user = host.get(
Packit 8cb997
                    "allow_retrieve_keytab_user")
Packit 8cb997
                allow_retrieve_keytab_group = host.get(
Packit 8cb997
                    "allow_retrieve_keytab_group")
Packit 8cb997
                allow_retrieve_keytab_host = host.get(
Packit 8cb997
                    "allow_retrieve_keytab_host")
Packit 8cb997
                allow_retrieve_keytab_hostgroup = host.get(
Packit 8cb997
                    "allow_retrieve_keytab_hostgroup")
Packit 8cb997
                mac_address = host.get("mac_address")
Packit 8cb997
                sshpubkey = host.get("sshpubkey")
Packit 8cb997
                userclass = host.get("userclass")
Packit 8cb997
                auth_ind = host.get("auth_ind")
Packit 8cb997
                requires_pre_auth = host.get("requires_pre_auth")
Packit 8cb997
                ok_as_delegate = host.get("ok_as_delegate")
Packit 8cb997
                ok_to_auth_as_delegate = host.get("ok_to_auth_as_delegate")
Packit 8cb997
                force = host.get("force")
Packit 8cb997
                reverse = host.get("reverse")
Packit 8cb997
                ip_address = host.get("ip_address")
Packit 8cb997
                update_dns = host.get("update_dns")
Packit 8cb997
                # update_password is not part of hosts structure
Packit 8cb997
                # action is not part of hosts structure
Packit 8cb997
                # state is not part of hosts structure
Packit 8cb997
Packit 8cb997
                check_parameters(
Packit 8cb997
                    ansible_module, state, action,
Packit 8cb997
                    description, locality, location, platform, os, password,
Packit 8cb997
                    random, certificate, managedby_host, principal,
Packit 8cb997
                    allow_create_keytab_user, allow_create_keytab_group,
Packit 8cb997
                    allow_create_keytab_host, allow_create_keytab_hostgroup,
Packit 8cb997
                    allow_retrieve_keytab_user, allow_retrieve_keytab_group,
Packit 8cb997
                    allow_retrieve_keytab_host,
Packit 8cb997
                    allow_retrieve_keytab_hostgroup, mac_address, sshpubkey,
Packit 8cb997
                    userclass, auth_ind, requires_pre_auth, ok_as_delegate,
Packit 8cb997
                    ok_to_auth_as_delegate, force, reverse, ip_address,
Packit 8cb997
                    update_dns, update_password)
Packit 8cb997
Packit 8cb997
            elif isinstance(host, str) or isinstance(host, unicode):
Packit 8cb997
                name = host
Packit 8cb997
            else:
Packit 8cb997
                ansible_module.fail_json(msg="Host '%s' is not valid" %
Packit 8cb997
                                         repr(host))
Packit 8cb997
Packit 8cb997
            # Make sure host exists
Packit 8cb997
            res_find = find_host(ansible_module, name)
Packit 8cb997
Packit 8cb997
            # Create command
Packit 8cb997
            if state == "present":
Packit 8cb997
                # Generate args
Packit 8cb997
                args = gen_args(
Packit 8cb997
                    description, locality, location, platform, os, password,
Packit 8cb997
                    random, mac_address, sshpubkey, userclass, auth_ind,
Packit 8cb997
                    requires_pre_auth, ok_as_delegate, ok_to_auth_as_delegate,
Packit 8cb997
                    force, reverse, ip_address, update_dns)
Packit 8cb997
Packit 8cb997
                if action == "host":
Packit 8cb997
                    # Found the host
Packit 8cb997
                    if res_find is not None:
Packit 8cb997
                        # Ignore password with update_password == on_create
Packit 8cb997
                        if update_password == "on_create" and \
Packit 8cb997
                           "userpassword" in args:
Packit 8cb997
                            del args["userpassword"]
Packit 8cb997
Packit 8cb997
                        # Ignore force, ip_address and no_reverse for mod
Packit 8cb997
                        for x in ["force", "ip_address", "no_reverse"]:
Packit 8cb997
                            if x in args:
Packit 8cb997
                                del args[x]
Packit 8cb997
Packit 98a68e
                        # Ignore auth_ind if it is empty (for resetting)
Packit 98a68e
                        # and not set in for the host
Packit 98a68e
                        if "krbprincipalauthind" not in res_find and \
Packit 98a68e
                           "krbprincipalauthind" in args and \
Packit 98a68e
                           args["krbprincipalauthind"] == ['']:
Packit 98a68e
                            del args["krbprincipalauthind"]
Packit 98a68e
Packit 8cb997
                        # For all settings is args, check if there are
Packit 8cb997
                        # different settings in the find result.
Packit 8cb997
                        # If yes: modify
Packit 8cb997
                        if not compare_args_ipa(ansible_module, args,
Packit 8cb997
                                                res_find):
Packit 8cb997
                            commands.append([name, "host_mod", args])
Packit 8cb997
                        elif random and "userpassword" in res_find:
Packit 8cb997
                            # Host exists and random is set, return
Packit 8cb997
                            # userpassword
Packit 8cb997
                            if len(names) == 1:
Packit 8cb997
                                exit_args["userpassword"] = \
Packit 8cb997
                                    res_find["userpassword"]
Packit 8cb997
                            else:
Packit 8cb997
                                exit_args.setdefault("hosts", {})[name] = {
Packit 8cb997
                                    "userpassword": res_find["userpassword"]
Packit 8cb997
                                }
Packit 8cb997
Packit 8cb997
                    else:
Packit 8cb997
                        # Remove update_dns as it is not supported by host_add
Packit 8cb997
                        if "updatedns" in args:
Packit 8cb997
                            del args["updatedns"]
Packit 8cb997
                        commands.append([name, "host_add", args])
Packit 8cb997
Packit 8cb997
                    # Handle members: certificate, managedby_host, principal,
Packit 8cb997
                    # allow_create_keytab and allow_retrieve_keytab
Packit 8cb997
                    if res_find is not None:
Packit 8cb997
                        certificate_add, certificate_del = gen_add_del_lists(
Packit 8cb997
                            certificate, res_find.get("usercertificate"))
Packit 8cb997
                        managedby_host_add, managedby_host_del = \
Packit 8cb997
                            gen_add_del_lists(managedby_host,
Packit 8cb997
                                              res_find.get("managedby_host"))
Packit 8cb997
                        principal_add, principal_del = gen_add_del_lists(
Packit 8cb997
                            principal, res_find.get("principal"))
Packit 8cb997
                        # Principals are not returned as utf8 for IPA using
Packit 8cb997
                        # python2 using host_find, therefore we need to
Packit 8cb997
                        # convert the principals that we should remove.
Packit 8cb997
                        principal_del = [to_text(x) for x in principal_del]
Packit 8cb997
Packit 8cb997
                        (allow_create_keytab_user_add,
Packit 8cb997
                         allow_create_keytab_user_del) = \
Packit 8cb997
                            gen_add_del_lists(
Packit 8cb997
                                allow_create_keytab_user,
Packit 8cb997
                                res_find.get(
Packit 8cb997
                                    "ipaallowedtoperform_write_keys_user"))
Packit 8cb997
                        (allow_create_keytab_group_add,
Packit 8cb997
                         allow_create_keytab_group_del) = \
Packit 8cb997
                            gen_add_del_lists(
Packit 8cb997
                                allow_create_keytab_group,
Packit 8cb997
                                res_find.get(
Packit 8cb997
                                    "ipaallowedtoperform_write_keys_group"))
Packit 8cb997
                        (allow_create_keytab_host_add,
Packit 8cb997
                         allow_create_keytab_host_del) = \
Packit 8cb997
                            gen_add_del_lists(
Packit 8cb997
                                allow_create_keytab_host,
Packit 8cb997
                                res_find.get(
Packit 8cb997
                                    "ipaallowedtoperform_write_keys_host"))
Packit 8cb997
                        (allow_create_keytab_hostgroup_add,
Packit 8cb997
                         allow_create_keytab_hostgroup_del) = \
Packit 8cb997
                            gen_add_del_lists(
Packit 8cb997
                                allow_create_keytab_hostgroup,
Packit 8cb997
                                res_find.get(
Packit 8cb997
                                    "ipaallowedtoperform_write_keys_"
Packit 8cb997
                                    "hostgroup"))
Packit 8cb997
                        (allow_retrieve_keytab_user_add,
Packit 8cb997
                         allow_retrieve_keytab_user_del) = \
Packit 8cb997
                            gen_add_del_lists(
Packit 8cb997
                                allow_retrieve_keytab_user,
Packit 8cb997
                                res_find.get(
Packit 8cb997
                                    "ipaallowedtoperform_read_keys_user"))
Packit 8cb997
                        (allow_retrieve_keytab_group_add,
Packit 8cb997
                         allow_retrieve_keytab_group_del) = \
Packit 8cb997
                            gen_add_del_lists(
Packit 8cb997
                                allow_retrieve_keytab_group,
Packit 8cb997
                                res_find.get(
Packit 8cb997
                                    "ipaallowedtoperform_read_keys_group"))
Packit 8cb997
                        (allow_retrieve_keytab_host_add,
Packit 8cb997
                         allow_retrieve_keytab_host_del) = \
Packit 8cb997
                            gen_add_del_lists(
Packit 8cb997
                                allow_retrieve_keytab_host,
Packit 8cb997
                                res_find.get(
Packit 8cb997
                                    "ipaallowedtoperform_read_keys_host"))
Packit 8cb997
                        (allow_retrieve_keytab_hostgroup_add,
Packit 8cb997
                         allow_retrieve_keytab_hostgroup_del) = \
Packit 8cb997
                            gen_add_del_lists(
Packit 8cb997
                                allow_retrieve_keytab_hostgroup,
Packit 8cb997
                                res_find.get(
Packit 8cb997
                                    "ipaallowedtoperform_read_keys_hostgroup"))
Packit 8cb997
Packit 8cb997
                    else:
Packit 8cb997
                        certificate_add = certificate or []
Packit 8cb997
                        certificate_del = []
Packit 8cb997
                        managedby_host_add = managedby_host or []
Packit 8cb997
                        managedby_host_del = []
Packit 8cb997
                        principal_add = principal or []
Packit 8cb997
                        principal_del = []
Packit 8cb997
                        allow_create_keytab_user_add = \
Packit 8cb997
                            allow_create_keytab_user or []
Packit 8cb997
                        allow_create_keytab_user_del = []
Packit 8cb997
                        allow_create_keytab_group_add = \
Packit 8cb997
                            allow_create_keytab_group or []
Packit 8cb997
                        allow_create_keytab_group_del = []
Packit 8cb997
                        allow_create_keytab_host_add = \
Packit 8cb997
                            allow_create_keytab_host or []
Packit 8cb997
                        allow_create_keytab_host_del = []
Packit 8cb997
                        allow_create_keytab_hostgroup_add = \
Packit 8cb997
                            allow_create_keytab_hostgroup or []
Packit 8cb997
                        allow_create_keytab_hostgroup_del = []
Packit 8cb997
                        allow_retrieve_keytab_user_add = \
Packit 8cb997
                            allow_retrieve_keytab_user or []
Packit 8cb997
                        allow_retrieve_keytab_user_del = []
Packit 8cb997
                        allow_retrieve_keytab_group_add = \
Packit 8cb997
                            allow_retrieve_keytab_group or []
Packit 8cb997
                        allow_retrieve_keytab_group_del = []
Packit 8cb997
                        allow_retrieve_keytab_host_add = \
Packit 8cb997
                            allow_retrieve_keytab_host or []
Packit 8cb997
                        allow_retrieve_keytab_host_del = []
Packit 8cb997
                        allow_retrieve_keytab_hostgroup_add = \
Packit 8cb997
                            allow_retrieve_keytab_hostgroup or []
Packit 8cb997
                        allow_retrieve_keytab_hostgroup_del = []
Packit 8cb997
Packit 8cb997
                else:
Packit 8cb997
                    certificate_add = certificate or []
Packit 8cb997
                    certificate_del = []
Packit 8cb997
                    managedby_host_add = managedby_host or []
Packit 8cb997
                    managedby_host_del = []
Packit 8cb997
                    principal_add = principal or []
Packit 8cb997
                    principal_del = []
Packit 8cb997
                    allow_create_keytab_user_add = \
Packit 8cb997
                        allow_create_keytab_user or []
Packit 8cb997
                    allow_create_keytab_user_del = []
Packit 8cb997
                    allow_create_keytab_group_add = \
Packit 8cb997
                        allow_create_keytab_group or []
Packit 8cb997
                    allow_create_keytab_group_del = []
Packit 8cb997
                    allow_create_keytab_host_add = \
Packit 8cb997
                        allow_create_keytab_host or []
Packit 8cb997
                    allow_create_keytab_host_del = []
Packit 8cb997
                    allow_create_keytab_hostgroup_add = \
Packit 8cb997
                        allow_create_keytab_hostgroup or []
Packit 8cb997
                    allow_create_keytab_hostgroup_del = []
Packit 8cb997
                    allow_retrieve_keytab_user_add = \
Packit 8cb997
                        allow_retrieve_keytab_user or []
Packit 8cb997
                    allow_retrieve_keytab_user_del = []
Packit 8cb997
                    allow_retrieve_keytab_group_add = \
Packit 8cb997
                        allow_retrieve_keytab_group or []
Packit 8cb997
                    allow_retrieve_keytab_group_del = []
Packit 8cb997
                    allow_retrieve_keytab_host_add = \
Packit 8cb997
                        allow_retrieve_keytab_host or []
Packit 8cb997
                    allow_retrieve_keytab_host_del = []
Packit 8cb997
                    allow_retrieve_keytab_hostgroup_add = \
Packit 8cb997
                        allow_retrieve_keytab_hostgroup or []
Packit 8cb997
                    allow_retrieve_keytab_hostgroup_del = []
Packit 8cb997
Packit 8cb997
                # Remove canonical principal from principal_del
Packit 8cb997
                canonical_principal = "host/" + name + "@" + server_realm
Packit 8cb997
                if canonical_principal in principal_del and \
Packit 8cb997
                   action == "host" and (principal is not None or
Packit 8cb997
                                         canonical_principal not in principal):
Packit 8cb997
                    principal_del.remove(canonical_principal)
Packit 8cb997
Packit 8cb997
                # Remove canonical managedby managedby_host_del for
Packit 8cb997
                # action host if managedby_host is set and the canonical
Packit 8cb997
                # managedby host is not in the managedby_host list.
Packit 8cb997
                canonical_managedby_host = name
Packit 8cb997
                if canonical_managedby_host in managedby_host_del and \
Packit 8cb997
                   action == "host" and (managedby_host is None or
Packit 8cb997
                                         canonical_managedby_host not in
Packit 8cb997
                                         managedby_host):
Packit 8cb997
                    managedby_host_del.remove(canonical_managedby_host)
Packit 8cb997
Packit 8cb997
                # Certificates need to be added and removed one by one,
Packit 8cb997
                # because if entry already exists, the processing of
Packit 8cb997
                # the remaining enries is stopped. The same applies to
Packit 8cb997
                # the removal of non-existing entries.
Packit 8cb997
Packit 8cb997
                # Add certificates
Packit 8cb997
                for _certificate in certificate_add:
Packit 8cb997
                    commands.append([name, "host_add_cert",
Packit 8cb997
                                     {
Packit 8cb997
                                         "usercertificate":
Packit 8cb997
                                         _certificate,
Packit 8cb997
                                     }])
Packit 8cb997
                # Remove certificates
Packit 8cb997
                for _certificate in certificate_del:
Packit 8cb997
                    commands.append([name, "host_remove_cert",
Packit 8cb997
                                     {
Packit 8cb997
                                         "usercertificate":
Packit 8cb997
                                         _certificate,
Packit 8cb997
                                     }])
Packit 8cb997
Packit 8cb997
                # Managedby_Hosts need to be added and removed one by one,
Packit 8cb997
                # because if entry already exists, the processing of
Packit 8cb997
                # the remaining enries is stopped. The same applies to
Packit 8cb997
                # the removal of non-existing entries.
Packit 8cb997
Packit 8cb997
                # Add managedby_hosts
Packit 8cb997
                for _managedby_host in managedby_host_add:
Packit 8cb997
                    commands.append([name, "host_add_managedby",
Packit 8cb997
                                     {
Packit 8cb997
                                         "host":
Packit 8cb997
                                         _managedby_host,
Packit 8cb997
                                     }])
Packit 8cb997
                # Remove managedby_hosts
Packit 8cb997
                for _managedby_host in managedby_host_del:
Packit 8cb997
                    commands.append([name, "host_remove_managedby",
Packit 8cb997
                                     {
Packit 8cb997
                                         "host":
Packit 8cb997
                                         _managedby_host,
Packit 8cb997
                                     }])
Packit 8cb997
Packit 8cb997
                # Principals need to be added and removed one by one,
Packit 8cb997
                # because if entry already exists, the processing of
Packit 8cb997
                # the remaining enries is stopped. The same applies to
Packit 8cb997
                # the removal of non-existing entries.
Packit 8cb997
Packit 8cb997
                # Add principals
Packit 8cb997
                for _principal in principal_add:
Packit 8cb997
                    commands.append([name, "host_add_principal",
Packit 8cb997
                                     {
Packit 8cb997
                                         "krbprincipalname":
Packit 8cb997
                                         _principal,
Packit 8cb997
                                     }])
Packit 8cb997
                # Remove principals
Packit 8cb997
                for _principal in principal_del:
Packit 8cb997
                    commands.append([name, "host_remove_principal",
Packit 8cb997
                                     {
Packit 8cb997
                                         "krbprincipalname":
Packit 8cb997
                                         _principal,
Packit 8cb997
                                     }])
Packit 8cb997
Packit 8cb997
                # Allow create keytab
Packit 8cb997
                if len(allow_create_keytab_user_add) > 0 or \
Packit 8cb997
                   len(allow_create_keytab_group_add) > 0 or \
Packit 8cb997
                   len(allow_create_keytab_host_add) > 0 or \
Packit 8cb997
                   len(allow_create_keytab_hostgroup_add) > 0:
Packit 8cb997
                    commands.append(
Packit 8cb997
                        [name, "host_allow_create_keytab",
Packit 8cb997
                         {
Packit 8cb997
                             "user": allow_create_keytab_user_add,
Packit 8cb997
                             "group": allow_create_keytab_group_add,
Packit 8cb997
                             "host": allow_create_keytab_host_add,
Packit 8cb997
                             "hostgroup": allow_create_keytab_hostgroup_add,
Packit 8cb997
                         }])
Packit 8cb997
Packit 8cb997
                # Disallow create keytab
Packit 8cb997
                if len(allow_create_keytab_user_del) > 0 or \
Packit 8cb997
                   len(allow_create_keytab_group_del) > 0 or \
Packit 8cb997
                   len(allow_create_keytab_host_del) > 0 or \
Packit 8cb997
                   len(allow_create_keytab_hostgroup_del) > 0:
Packit 8cb997
                    commands.append(
Packit 8cb997
                        [name, "host_disallow_create_keytab",
Packit 8cb997
                         {
Packit 8cb997
                             "user": allow_create_keytab_user_del,
Packit 8cb997
                             "group": allow_create_keytab_group_del,
Packit 8cb997
                             "host": allow_create_keytab_host_del,
Packit 8cb997
                             "hostgroup": allow_create_keytab_hostgroup_del,
Packit 8cb997
                         }])
Packit 8cb997
Packit 8cb997
                # Allow retrieve keytab
Packit 8cb997
                if len(allow_retrieve_keytab_user_add) > 0 or \
Packit 8cb997
                   len(allow_retrieve_keytab_group_add) > 0 or \
Packit 8cb997
                   len(allow_retrieve_keytab_host_add) > 0 or \
Packit 8cb997
                   len(allow_retrieve_keytab_hostgroup_add) > 0:
Packit 8cb997
                    commands.append(
Packit 8cb997
                        [name, "host_allow_retrieve_keytab",
Packit 8cb997
                         {
Packit 8cb997
                             "user": allow_retrieve_keytab_user_add,
Packit 8cb997
                             "group": allow_retrieve_keytab_group_add,
Packit 8cb997
                             "host": allow_retrieve_keytab_host_add,
Packit 8cb997
                             "hostgroup": allow_retrieve_keytab_hostgroup_add,
Packit 8cb997
                         }])
Packit 8cb997
Packit 8cb997
                # Disallow retrieve keytab
Packit 8cb997
                if len(allow_retrieve_keytab_user_del) > 0 or \
Packit 8cb997
                   len(allow_retrieve_keytab_group_del) > 0 or \
Packit 8cb997
                   len(allow_retrieve_keytab_host_del) > 0 or \
Packit 8cb997
                   len(allow_retrieve_keytab_hostgroup_del) > 0:
Packit 8cb997
                    commands.append(
Packit 8cb997
                        [name, "host_disallow_retrieve_keytab",
Packit 8cb997
                         {
Packit 8cb997
                             "user": allow_retrieve_keytab_user_del,
Packit 8cb997
                             "group": allow_retrieve_keytab_group_del,
Packit 8cb997
                             "host": allow_retrieve_keytab_host_del,
Packit 8cb997
                             "hostgroup": allow_retrieve_keytab_hostgroup_del,
Packit 8cb997
                         }])
Packit 8cb997
Packit 8cb997
            elif state == "absent":
Packit 8cb997
                if action == "host":
Packit 8cb997
Packit 8cb997
                    if res_find is not None:
Packit 8cb997
                        args = {}
Packit 8cb997
                        if update_dns is not None:
Packit 8cb997
                            args["updatedns"] = update_dns
Packit 8cb997
                        commands.append([name, "host_del", args])
Packit 8cb997
                else:
Packit 8cb997
Packit 8cb997
                    # Certificates need to be added and removed one by one,
Packit 8cb997
                    # because if entry already exists, the processing of
Packit 8cb997
                    # the remaining enries is stopped. The same applies to
Packit 8cb997
                    # the removal of non-existing entries.
Packit 8cb997
Packit 8cb997
                    # Remove certificates
Packit 8cb997
                    if certificate is not None:
Packit 8cb997
                        for _certificate in certificate:
Packit 8cb997
                            commands.append([name, "host_remove_cert",
Packit 8cb997
                                             {
Packit 8cb997
                                                 "usercertificate":
Packit 8cb997
                                                 _certificate,
Packit 8cb997
                                             }])
Packit 8cb997
Packit 8cb997
                    # Managedby_Hosts need to be added and removed one by one,
Packit 8cb997
                    # because if entry already exists, the processing of
Packit 8cb997
                    # the remaining enries is stopped. The same applies to
Packit 8cb997
                    # the removal of non-existing entries.
Packit 8cb997
Packit 8cb997
                    # Remove managedby_hosts
Packit 8cb997
                    if managedby_host is not None:
Packit 8cb997
                        for _managedby_host in managedby_host:
Packit 8cb997
                            commands.append([name, "host_remove_managedby",
Packit 8cb997
                                             {
Packit 8cb997
                                                 "host":
Packit 8cb997
                                                 _managedby_host,
Packit 8cb997
                                             }])
Packit 8cb997
Packit 8cb997
                    # Principals need to be added and removed one by one,
Packit 8cb997
                    # because if entry already exists, the processing of
Packit 8cb997
                    # the remaining enries is stopped. The same applies to
Packit 8cb997
                    # the removal of non-existing entries.
Packit 8cb997
Packit 8cb997
                    # Remove principals
Packit 8cb997
                    if principal is not None:
Packit 8cb997
                        for _principal in principal:
Packit 8cb997
                            commands.append([name, "host_remove_principal",
Packit 8cb997
                                             {
Packit 8cb997
                                                 "krbprincipalname":
Packit 8cb997
                                                 _principal,
Packit 8cb997
                                             }])
Packit 8cb997
Packit 8cb997
                    # Disallow create keytab
Packit 8cb997
                    if allow_create_keytab_user is not None or \
Packit 8cb997
                       allow_create_keytab_group is not None or \
Packit 8cb997
                       allow_create_keytab_host is not None or \
Packit 8cb997
                       allow_create_keytab_hostgroup is not None:
Packit 8cb997
                        commands.append(
Packit 8cb997
                            [name, "host_disallow_create_keytab",
Packit 8cb997
                             {
Packit 8cb997
                                 "user": allow_create_keytab_user,
Packit 8cb997
                                 "group": allow_create_keytab_group,
Packit 8cb997
                                 "host": allow_create_keytab_host,
Packit 8cb997
                                 "hostgroup": allow_create_keytab_hostgroup,
Packit 8cb997
                             }])
Packit 8cb997
Packit 8cb997
                    # Disallow retrieve keytab
Packit 8cb997
                    if allow_retrieve_keytab_user is not None or \
Packit 8cb997
                       allow_retrieve_keytab_group is not None or \
Packit 8cb997
                       allow_retrieve_keytab_host is not None or \
Packit 8cb997
                       allow_retrieve_keytab_hostgroup is not None:
Packit 8cb997
                        commands.append(
Packit 8cb997
                            [name, "host_disallow_retrieve_keytab",
Packit 8cb997
                             {
Packit 8cb997
                                 "user": allow_retrieve_keytab_user,
Packit 8cb997
                                 "group": allow_retrieve_keytab_group,
Packit 8cb997
                                 "host": allow_retrieve_keytab_host,
Packit 8cb997
                                 "hostgroup": allow_retrieve_keytab_hostgroup,
Packit 8cb997
                             }])
Packit 8cb997
Packit 8cb997
            elif state == "disabled":
Packit 8cb997
                if res_find is not None:
Packit 8cb997
                    commands.append([name, "host_disable", {}])
Packit 8cb997
                else:
Packit 8cb997
                    raise ValueError("No host '%s'" % name)
Packit 8cb997
Packit 8cb997
            else:
Packit 8cb997
                ansible_module.fail_json(msg="Unkown state '%s'" % state)
Packit 8cb997
Packit 8cb997
        # Execute commands
Packit 8cb997
Packit 8cb997
        errors = []
Packit 8cb997
        for name, command, args in commands:
Packit 8cb997
            try:
Packit 8cb997
                result = api_command(ansible_module, command, to_text(name),
Packit 8cb997
                                     args)
Packit 8cb997
                if "completed" in result:
Packit 8cb997
                    if result["completed"] > 0:
Packit 8cb997
                        changed = True
Packit 8cb997
                else:
Packit 8cb997
                    changed = True
Packit 8cb997
Packit 8cb997
                if "random" in args and command in ["host_add", "host_mod"] \
Packit 8cb997
                   and "randompassword" in result["result"]:
Packit 8cb997
                    if len(names) == 1:
Packit 8cb997
                        exit_args["randompassword"] = \
Packit 8cb997
                            result["result"]["randompassword"]
Packit 8cb997
                    else:
Packit 8cb997
                        exit_args.setdefault(name, {})["randompassword"] = \
Packit 8cb997
                            result["result"]["randompassword"]
Packit 8cb997
Packit 8cb997
            except Exception as e:
Packit 8cb997
                msg = str(e)
Packit 8cb997
                if "already contains" in msg \
Packit 8cb997
                   or "does not contain" in msg:
Packit 8cb997
                    continue
Packit 8cb997
Packit 8cb997
                #  The canonical principal name may not be removed
Packit 8cb997
                if "equal to the canonical principal name must" in msg:
Packit 8cb997
                    continue
Packit 8cb997
Packit 8cb997
                # Host is already disabled, ignore error
Packit 8cb997
                if "This entry is already disabled" in msg:
Packit 8cb997
                    continue
Packit 8cb997
                ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
Packit 8cb997
                                                             msg))
Packit 8cb997
Packit 8cb997
            # Get all errors
Packit 8cb997
            # All "already a member" and "not a member" failures in the
Packit 8cb997
            # result are ignored. All others are reported.
Packit 8cb997
            if "failed" in result and len(result["failed"]) > 0:
Packit 8cb997
                for item in result["failed"]:
Packit 8cb997
                    failed_item = result["failed"][item]
Packit 8cb997
                    for member_type in failed_item:
Packit 8cb997
                        for member, failure in failed_item[member_type]:
Packit 8cb997
                            if "already a member" in failure \
Packit 8cb997
                               or "not a member" in failure:
Packit 8cb997
                                continue
Packit 8cb997
                            errors.append("%s: %s %s: %s" % (
Packit 8cb997
                                command, member_type, member, failure))
Packit 8cb997
Packit 8cb997
        if len(errors) > 0:
Packit 8cb997
            ansible_module.fail_json(msg=", ".join(errors))
Packit 8cb997
Packit 8cb997
    except Exception as e:
Packit 8cb997
        ansible_module.fail_json(msg=str(e))
Packit 8cb997
Packit 8cb997
    finally:
Packit 8cb997
        temp_kdestroy(ccache_dir, ccache_name)
Packit 8cb997
Packit 8cb997
    # Done
Packit 8cb997
Packit 8cb997
    ansible_module.exit_json(changed=changed, host=exit_args)
Packit 8cb997
Packit 8cb997
Packit 8cb997
if __name__ == "__main__":
Packit 8cb997
    main()