Blame plugins/modules/ipatrust.py

Packit Service ee01e6
#!/usr/bin/python
Packit Service a166ed
# -*- coding: utf-8 -*-
Packit Service a166ed
Packit Service a166ed
# Authors:
Packit Service a166ed
#   Rob Verduijn <rob.verduijn@gmail.com>
Packit Service a166ed
#
Packit Service a166ed
# Copyright (C) 2019 By Rob Verduijn
Packit Service a166ed
# see file 'COPYING' for use and warranty information
Packit Service a166ed
#
Packit Service a166ed
# This program is free software; you can redistribute it and/or modify
Packit Service a166ed
# it under the terms of the GNU General Public License as published by
Packit Service a166ed
# the Free Software Foundation, either version 3 of the License, or
Packit Service a166ed
# (at your option) any later version.
Packit Service a166ed
#
Packit Service a166ed
# This program is distributed in the hope that it will be useful,
Packit Service a166ed
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service a166ed
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service a166ed
# GNU General Public License for more details.
Packit Service a166ed
#
Packit Service a166ed
# You should have received a copy of the GNU General Public License
Packit Service a166ed
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit Service a166ed
Packit Service a166ed
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
Packit Service a166ed
    temp_kdestroy, valid_creds, api_connect, api_command, module_params_get
Packit Service a166ed
from ansible.module_utils.basic import AnsibleModule
Packit Service a166ed
ANSIBLE_METADATA = {'metadata_version': '1.1',
Packit Service a166ed
                    'supported_by': 'community',
Packit Service a166ed
                    'status': ['preview'],
Packit Service a166ed
                    }
Packit Service a166ed
Packit Service a166ed
DOCUMENTATION = """
Packit Service a166ed
---
Packit Service a166ed
module: ipatrust
Packit Service a166ed
short_description: Manage FreeIPA Domain Trusts.
Packit Service a166ed
description: Manage FreeIPA Domain Trusts.
Packit Service a166ed
options:
Packit Service a166ed
  realm:
Packit Service a166ed
    description:
Packit Service a166ed
    - Realm name
Packit Service a166ed
    required: true
Packit Service a166ed
  trust_type:
Packit Service a166ed
    description:
Packit Service a166ed
    - Trust type (ad for Active Directory, default)
Packit Service a166ed
    default: ad
Packit Service a166ed
    required: true
Packit Service a166ed
  admin:
Packit Service a166ed
    description:
Packit Service a166ed
    - Active Directory domain administrator
Packit Service a166ed
    required: false
Packit Service a166ed
  password:
Packit Service a166ed
    description:
Packit Service a166ed
    - Active Directory domain administrator's password
Packit Service a166ed
    required: false
Packit Service a166ed
  server:
Packit Service a166ed
    description:
Packit Service a166ed
    - Domain controller for the Active Directory domain (optional)
Packit Service a166ed
    required: false
Packit Service a166ed
  trust_secret:
Packit Service a166ed
    description:
Packit Service a166ed
    - Shared secret for the trust
Packit Service a166ed
    required: false
Packit Service a166ed
  base_id:
Packit Service a166ed
    description:
Packit Service a166ed
    - First Posix ID of the range reserved for the trusted domain
Packit Service a166ed
    required: false
Packit Service a166ed
  range_size:
Packit Service a166ed
    description:
Packit Service a166ed
    - Size of the ID range reserved for the trusted domain
Packit Service a166ed
  range_type:
Packit Service a166ed
    description:
Packit Service a166ed
    - Type of trusted domain ID range, one of ipa-ad-trust, ipa-ad-trust-posix
Packit Service a166ed
    default: ipa-ad-trust
Packit Service a166ed
    required: false
Packit Service a166ed
  two_way:
Packit Service a166ed
    description:
Packit Service a166ed
    - Establish bi-directional trust. By default trust is inbound one-way only.
Packit Service a166ed
    default: false
Packit Service a166ed
    required: false
Packit Service a166ed
    choices: ["true", "false"]
Packit Service a166ed
  external:
Packit Service a166ed
    description:
Packit Service a166ed
    - Establish external trust to a domain in another forest.
Packit Service a166ed
    - The trust is not transitive beyond the domain.
Packit Service a166ed
    default: false
Packit Service a166ed
    required: false
Packit Service a166ed
    choices: ["true", "false"]
Packit Service a166ed
  state:
Packit Service a166ed
    description: State to ensure
Packit Service a166ed
    default: present
Packit Service a166ed
    required: true
Packit Service a166ed
    choices: ["present", "absent"]
Packit Service a166ed
Packit Service a166ed
author:
Packit Service a166ed
    - Rob Verduijn
Packit Service a166ed
"""
Packit Service a166ed
Packit Service a166ed
EXAMPLES = """
Packit Service a166ed
# add ad-trust
Packit Service a166ed
- ipatrust:
Packit Service a166ed
    realm: ad.example.test
Packit Service a166ed
    trust_type: ad
Packit Service a166ed
    admin: Administrator
Packit Service a166ed
    password: Welcome2020!
Packit Service a166ed
    state: present
Packit Service a166ed
Packit Service a166ed
# delete ad-trust
Packit Service a166ed
- ipatrust:
Packit Service a166ed
    realm: ad.example.test
Packit Service a166ed
    state: absent
Packit Service a166ed
"""
Packit Service a166ed
Packit Service a166ed
RETURN = """
Packit Service a166ed
"""
Packit Service a166ed
Packit Service a166ed
Packit Service a166ed
def find_trust(module, realm):
Packit Service a166ed
    _args = {
Packit Service a166ed
        "all": True,
Packit Service a166ed
        "cn": realm,
Packit Service a166ed
    }
Packit Service a166ed
Packit Service a166ed
    _result = api_command(module, "trust_find", realm, _args)
Packit Service a166ed
Packit Service a166ed
    if len(_result["result"]) > 1:
Packit Service a166ed
        module.fail_json(msg="There is more than one realm '%s'" % (realm))
Packit Service a166ed
    elif len(_result["result"]) == 1:
Packit Service a166ed
        return _result["result"][0]
Packit Service a166ed
    else:
Packit Service a166ed
        return None
Packit Service a166ed
Packit Service a166ed
Packit Service a166ed
def del_trust(module, realm):
Packit Service a166ed
    _args = {}
Packit Service a166ed
Packit Service a166ed
    _result = api_command(module, "trust_del", realm, _args)
Packit Service a166ed
    if len(_result["result"]["failed"]) > 0:
Packit Service a166ed
        module.fail_json(
Packit Service a166ed
            msg="Trust deletion has failed for '%s'" % (realm))
Packit Service a166ed
    else:
Packit Service a166ed
        return None
Packit Service a166ed
Packit Service a166ed
Packit Service a166ed
def add_trust(module, realm, args):
Packit Service a166ed
    _args = args
Packit Service a166ed
Packit Service a166ed
    _result = api_command(module, "trust_add", realm, _args)
Packit Service a166ed
Packit Service a166ed
    if "cn" not in _result["result"]:
Packit Service a166ed
        module.fail_json(
Packit Service a166ed
            msg="Trust add has failed for '%s'" % (realm))
Packit Service a166ed
    else:
Packit Service a166ed
        return None
Packit Service a166ed
Packit Service a166ed
Packit Service a166ed
def gen_args(trust_type, admin, password, server, trust_secret, base_id,
Packit Service a166ed
             range_size, range_type, two_way, external):
Packit Service a166ed
    _args = {}
Packit Service a166ed
    if trust_type is not None:
Packit Service a166ed
        _args["trust_type"] = trust_type
Packit Service a166ed
    if admin is not None:
Packit Service a166ed
        _args["realm_admin"] = admin
Packit Service a166ed
    if password is not None:
Packit Service a166ed
        _args["realm_passwd"] = password
Packit Service a166ed
    if server is not None:
Packit Service a166ed
        _args["realm_server"] = server
Packit Service a166ed
    if trust_secret is not None:
Packit Service a166ed
        _args["trust_secret"] = trust_secret
Packit Service a166ed
    if base_id is not None:
Packit Service a166ed
        _args["base_id"] = base_id
Packit Service a166ed
    if range_size is not None:
Packit Service a166ed
        _args["range_size"] = range_size
Packit Service a166ed
    if two_way is not None:
Packit Service a166ed
        _args["bidirectional"] = two_way
Packit Service a166ed
    if external is not None:
Packit Service a166ed
        _args["external"] = external
Packit Service a166ed
Packit Service a166ed
    return _args
Packit Service a166ed
Packit Service a166ed
Packit Service a166ed
def main():
Packit Service a166ed
    ansible_module = AnsibleModule(
Packit Service a166ed
        argument_spec=dict(
Packit Service a166ed
            # general
Packit Service a166ed
            ipaadmin_principal=dict(type="str", default="admin"),
Packit Service a166ed
            ipaadmin_password=dict(type="str", required=False, no_log=True),
Packit Service a166ed
            realm=dict(type="str", default=None, required=True),
Packit Service a166ed
            # state
Packit Service a166ed
            state=dict(type="str", default="present",
Packit Service a166ed
                       choices=["present", "absent"]),
Packit Service a166ed
            # present
Packit Service a166ed
            trust_type=dict(type="str", default="ad", required=False),
Packit Service a166ed
            admin=dict(type="str", default=None, required=False),
Packit Service a166ed
            password=dict(type="str", default=None,
Packit Service a166ed
                          required=False, no_log=True),
Packit Service a166ed
            server=dict(type="str", default=None, required=False),
Packit Service a166ed
            trust_secret=dict(type="str", default=None,
Packit Service a166ed
                              required=False, no_log=True),
Packit Service a166ed
            base_id=dict(type="int", default=None, required=False),
Packit Service a166ed
            range_size=dict(type="int", default=200000, required=False),
Packit Service a166ed
            range_type=dict(type="str", default="ipa-ad-trust",
Packit Service a166ed
                            required=False, choices=["ipa-ad-trust-posix",
Packit Service a166ed
                                                     "ipa-ad-trust"]),
Packit Service a166ed
            two_way=dict(type="bool", default=False, required=False),
Packit Service a166ed
            external=dict(type="bool", default=False, required=False),
Packit Service a166ed
        ),
Packit Service a166ed
        mutually_exclusive=[["trust_secret", "admin"]],
Packit Service a166ed
        required_together=[["admin", "password"]],
Packit Service a166ed
        supports_check_mode=True
Packit Service a166ed
    )
Packit Service a166ed
Packit Service a166ed
    ansible_module._ansible_debug = True
Packit Service a166ed
Packit Service a166ed
    # general
Packit Service a166ed
    ipaadmin_principal = module_params_get(
Packit Service a166ed
        ansible_module, "ipaadmin_principal")
Packit Service a166ed
    ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
Packit Service a166ed
    realm = module_params_get(ansible_module, "realm")
Packit Service a166ed
Packit Service a166ed
    # state
Packit Service a166ed
    state = module_params_get(ansible_module, "state")
Packit Service a166ed
Packit Service a166ed
    # trust
Packit Service a166ed
    trust_type = module_params_get(ansible_module, "trust_type")
Packit Service a166ed
    admin = module_params_get(ansible_module, "admin")
Packit Service a166ed
    password = module_params_get(ansible_module, "password")
Packit Service a166ed
    server = module_params_get(ansible_module, "server")
Packit Service a166ed
    trust_secret = module_params_get(ansible_module, "trust_secret")
Packit Service a166ed
    base_id = module_params_get(ansible_module, "base_id")
Packit Service a166ed
    range_size = module_params_get(ansible_module, "range_size")
Packit Service a166ed
    range_type = module_params_get(ansible_module, "range_type")
Packit Service a166ed
    two_way = module_params_get(ansible_module, "two_way")
Packit Service a166ed
    external = module_params_get(ansible_module, "external")
Packit Service a166ed
Packit Service a166ed
    changed = False
Packit Service a166ed
    exit_args = {}
Packit Service a166ed
    ccache_dir = None
Packit Service a166ed
    ccache_name = None
Packit Service a166ed
    try:
Packit Service a166ed
        if not valid_creds(ansible_module, ipaadmin_principal):
Packit Service a166ed
            ccache_dir, ccache_name = temp_kinit(
Packit Service a166ed
                ipaadmin_principal, ipaadmin_password)
Packit Service a166ed
        api_connect()
Packit Service a166ed
        res_find = find_trust(ansible_module, realm)
Packit Service a166ed
Packit Service a166ed
        if state == "absent":
Packit Service a166ed
            if res_find is not None:
Packit Service a166ed
                del_trust(ansible_module, realm)
Packit Service a166ed
                changed = True
Packit Service a166ed
        elif res_find is None:
Packit Service a166ed
            if admin is None and trust_secret is None:
Packit Service a166ed
                ansible_module.fail_json(
Packit Service a166ed
                    msg="one of admin or trust_secret is required when state "
Packit Service a166ed
                        "is present")
Packit Service a166ed
            else:
Packit Service a166ed
                args = gen_args(trust_type, admin, password, server,
Packit Service a166ed
                                trust_secret, base_id, range_size, range_type,
Packit Service a166ed
                                two_way, external)
Packit Service a166ed
Packit Service a166ed
                add_trust(ansible_module, realm, args)
Packit Service a166ed
                changed = True
Packit Service a166ed
Packit Service a166ed
    except Exception as e:
Packit Service a166ed
        ansible_module.fail_json(msg=str(e))
Packit Service a166ed
Packit Service a166ed
    finally:
Packit Service a166ed
        temp_kdestroy(ccache_dir, ccache_name)
Packit Service a166ed
Packit Service a166ed
    # Done
Packit Service a166ed
Packit Service a166ed
    ansible_module.exit_json(changed=changed, **exit_args)
Packit Service a166ed
Packit Service a166ed
Packit Service a166ed
if __name__ == "__main__":
Packit Service a166ed
    main()