diff --git a/README-servicedelegationrule.md b/README-servicedelegationrule.md new file mode 100644 index 0000000000000000000000000000000000000000..3743eeb5ddd6bd9268bfec96db3d3ca3c047e341 --- /dev/null +++ b/README-servicedelegationrule.md @@ -0,0 +1,172 @@ +Servicedelegationrule module +============ + +Description +----------- + +The servicedelegationrule module allows to ensure presence and absence of servicedelegationrules and servicedelegationrule members. + +Features +-------- + +* Servicedelegationrule management + + +Supported FreeIPA Versions +-------------------------- + +FreeIPA versions 4.4.0 and up are supported by the ipaservicedelegationrule module. + +Host princpals are only usable with IPA versions 4.9.0 and up. + + +Requirements +------------ + +**Controller** +* Ansible version: 2.8+ + +**Node** +* Supported FreeIPA version (see above) + + +Usage +===== + +Example inventory file + +```ini +[ipaserver] +ipaserver.test.local +``` + + +Example playbook to make sure servicedelegationrule delegation-rule is present: + +```yaml +--- +- name: Playbook to manage IPA servicedelegationrule + hosts: ipaserver + become: no + + tasks: + - name: Ensure servicedelegationrule delegation-rule is present + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule +``` + + +Example playbook to make sure servicedelegationrule delegation-rule member principal test/example.com is present: + +```yaml +--- +- name: Playbook to manage IPA servicedelegationrule + hosts: ipaserver + become: no + + tasks: + - name: Ensure servicedelegationrule delegation-rule member principal test/example.com is present + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + principal: test/example.com + action: member +``` + + +Example playbook to make sure servicedelegationrule delegation-rule member principal test/example.com is absent: + +```yaml +--- +- name: Playbook to manage IPA servicedelegationrule + hosts: ipaserver + become: no + + tasks: + - name: Ensure servicedelegationrule delegation-rule member principal test/example.com is absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + principal: test/example.com + action: member + state: absent + state: absent +``` + + +Example playbook to make sure servicedelegationrule delegation-rule member target delegation-target is present: + +```yaml +--- +- name: Playbook to manage IPA servicedelegationrule + hosts: ipaserver + become: no + + tasks: + - name: Ensure servicedelegationrule delegation-rule member target delegation-target is present + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + target: delegation-target + action: member +``` + + +Example playbook to make sure servicedelegationrule delegation-rule member target delegation-target is absent: + +```yaml +--- +- name: Playbook to manage IPA servicedelegationrule + hosts: ipaserver + become: no + + tasks: + - name: Ensure servicedelegationrule delegation-rule member target delegation-target is absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + target: delegation-target + action: member + state: absent + state: absent +``` + + +Example playbook to make sure servicedelegationrule delegation-rule is absent: + +```yaml +--- +- name: Playbook to manage IPA servicedelegationrule + hosts: ipaserver + become: no + + tasks: + - name: Ensure servicedelegationrule delegation-rule is absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + state: absent +``` + + +Variables +--------- + +Variable | Description | Required +-------- | ----------- | -------- +`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no +`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no +`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no +`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to yes. (bool) | no +`name` \| `cn` | The list of servicedelegationrule name strings. | yes +`principal` | The list of principals. A principal can be of the format: fqdn, fqdn@REALM, service/fqdn, service/fqdn@REALM, host/fqdn, host/fqdn@REALM, alias$, alias$@REALM, where fqdn and fqdn@REALM are host principals and the same as host/fqdn and host/fqdn@REALM. Host princpals are only usable with IPA versions 4.9.0 and up. | no +`target` \| `servicedelegationtarget` | The list of service delegation targets. | no +`action` | Work on servicedelegationrule or member level. It can be on of `member` or `servicedelegationrule` and defaults to `servicedelegationrule`. | no +`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no + + +Authors +======= + +Thomas Woerner diff --git a/README.md b/README.md index a50b7d82bffa9322044079ce37ed0e3112a2b515..ea53a5230d980dc814de08f0b8e793a07998dbe2 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Features * Modules for self service management * Modules for server management * Modules for service management +* Modules for service delegation rule management * Modules for service delegation target management * Modules for sudocmd management * Modules for sudocmdgroup management @@ -451,6 +452,7 @@ Modules in plugin/modules * [ipaselfservice](README-selfservice.md) * [ipaserver](README-server.md) * [ipaservice](README-service.md) +* [ipaservicedelegationrule](README-servicedelegationrule.md) * [ipaservicedelegationtarget](README-servicedelegationtarget.md) * [ipasudocmd](README-sudocmd.md) * [ipasudocmdgroup](README-sudocmdgroup.md) diff --git a/playbooks/servicedelegationrule/servicedelegationrule-absent.yml b/playbooks/servicedelegationrule/servicedelegationrule-absent.yml new file mode 100644 index 0000000000000000000000000000000000000000..599561576e7458dbb15d99179f7b652a6874184d --- /dev/null +++ b/playbooks/servicedelegationrule/servicedelegationrule-absent.yml @@ -0,0 +1,10 @@ +--- +- name: Servicedelegationrule absent example + hosts: ipaserver + become: no + + tasks: + - name: Ensure servicedelegationrule test-delegation-rule is absent + ipaservicedelegationrule: + name: test-delegation-rule + state: absent diff --git a/playbooks/servicedelegationrule/servicedelegationrule-present.yml b/playbooks/servicedelegationrule/servicedelegationrule-present.yml new file mode 100644 index 0000000000000000000000000000000000000000..8e3ccd49ac60ac825f6985d21ec237e87398082b --- /dev/null +++ b/playbooks/servicedelegationrule/servicedelegationrule-present.yml @@ -0,0 +1,9 @@ +--- +- name: Servicedelegationrule present example + hosts: ipaserver + become: no + + tasks: + - name: Ensure servicedelegationrule test-delegation-rule is present + ipaservicedelegationrule: + name: test-delegation-rule diff --git a/playbooks/servicedelegationrule/servicedelegationrule-principal-member-absent.yml b/playbooks/servicedelegationrule/servicedelegationrule-principal-member-absent.yml new file mode 100644 index 0000000000000000000000000000000000000000..784da69a8b697a3d3ae6e722f75586de1a09b058 --- /dev/null +++ b/playbooks/servicedelegationrule/servicedelegationrule-principal-member-absent.yml @@ -0,0 +1,12 @@ +--- +- name: Servicedelegationrule principal member absent example + hosts: ipaserver + become: no + + tasks: + - name: Ensure principal member test/example.com is absent in servicedelegationrule test-delegation-rule + ipaservicedelegationrule: + name: test-delegation-rule + principal: test/example.com + action: member + state: absent diff --git a/playbooks/servicedelegationrule/servicedelegationrule-principal-member-present.yml b/playbooks/servicedelegationrule/servicedelegationrule-principal-member-present.yml new file mode 100644 index 0000000000000000000000000000000000000000..d8f960583e803da6fff4860eba4a571d5626f8c4 --- /dev/null +++ b/playbooks/servicedelegationrule/servicedelegationrule-principal-member-present.yml @@ -0,0 +1,11 @@ +--- +- name: Servicedelegationrule principal member present example + hosts: ipaserver + become: no + + tasks: + - name: Ensure principal member test/example.com is present in servicedelegationrule test-delegation-rule + ipaservicedelegationrule: + name: test-delegation-rule + principal: test/example.com + action: member diff --git a/playbooks/servicedelegationrule/servicedelegationrule-target-member-absent.yml b/playbooks/servicedelegationrule/servicedelegationrule-target-member-absent.yml new file mode 100644 index 0000000000000000000000000000000000000000..cb280e4f38c409f24241f94a6f5c47b21d7aa5f3 --- /dev/null +++ b/playbooks/servicedelegationrule/servicedelegationrule-target-member-absent.yml @@ -0,0 +1,12 @@ +--- +- name: Servicedelegationrule absent example + hosts: ipaserver + become: no + + tasks: + - name: Ensure member test/example.com is absent in servicedelegationrule test-delegation-rule + ipaservicedelegationrule: + name: test-delegation-rule + principal: test/example.com + action: member + state: absent diff --git a/playbooks/servicedelegationrule/servicedelegationrule-target-member-present.yml b/playbooks/servicedelegationrule/servicedelegationrule-target-member-present.yml new file mode 100644 index 0000000000000000000000000000000000000000..257971d147b88f63d4f3a3ab1f81177dea1047a0 --- /dev/null +++ b/playbooks/servicedelegationrule/servicedelegationrule-target-member-present.yml @@ -0,0 +1,11 @@ +--- +- name: Servicedelegationrule member present example + hosts: ipaserver + become: no + + tasks: + - name: Ensure member test/example.com is present in servicedelegationrule test-delegation-rule + ipaservicedelegationrule: + name: test-delegation-rule + principal: test/example.com + action: member diff --git a/plugins/modules/ipaservicedelegationrule.py b/plugins/modules/ipaservicedelegationrule.py new file mode 100644 index 0000000000000000000000000000000000000000..93e41b46f554c15396137976ff52938202601f63 --- /dev/null +++ b/plugins/modules/ipaservicedelegationrule.py @@ -0,0 +1,352 @@ +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Copyright (C) 2022 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import (absolute_import, division, print_function) + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.0", + "supported_by": "community", + "status": ["preview"], +} + +DOCUMENTATION = """ +--- +module: ipaservicedelegationrule +short description: Manage FreeIPA servicedelegationrule +description: | + Manage FreeIPA servicedelegationrule and servicedelegationrule members +extends_documentation_fragment: + - ipamodule_base_docs +options: + name: + description: The list of servicedelegationrule name strings. + required: true + aliases: ["cn"] + principal: + description: | + The list of principals. A principal can be of the format: + fqdn, fqdn@REALM, service/fqdn, service/fqdn@REALM, host/fqdn, + host/fqdn@REALM, alias$, alias$@REALM, where fqdn and fqdn@REALM + are host principals and the same as host/fqdn and host/fqd + Host princpals are only usable with IPA versions 4.9.0 and up. + required: false + target: + description: | + The list of service delegation targets. + required: false + aliases: ["servicedelegationtarget"] + action: + description: Work on servicedelegationrule or member level. + choices: ["servicedelegationrule", "member"] + default: servicedelegationrule + required: false + state: + description: The state to ensure. + choices: ["present", "absent"] + default: present + required: true +""" + +EXAMPLES = """ +# Ensure servicedelegationrule delegation-rule is present +- ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + +# Ensure servicedelegationrule delegation-rule member principal +# test/example.com is present +- ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + principal: test/example.com + action: member + +# Ensure servicedelegationrule delegation-rule member principal +# test/example.com is absent +- ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + principal: test/example.com + action: member + state: absent + +# Ensure servicedelegationrule delegation-rule member target +# test/example.com is present +- ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + target: delegation-target + action: member + +# Ensure servicedelegationrule delegation-rule member target +# test/example.com is absent +- ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + target: delegation-target + action: member + state: absent + +# Ensure servicedelegationrule delegation-rule is absent +- ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + name: delegation-rule + state: absent +""" + +RETURN = """ +""" + + +from ansible.module_utils.ansible_freeipa_module import \ + IPAAnsibleModule, gen_add_del_lists, gen_add_list, gen_intersection_list, \ + servicedelegation_normalize_principals, ipalib_errors +from ansible.module_utils import six + +if six.PY3: + unicode = str + + +def find_servicedelegationrule(module, name): + """Find if a servicedelegationrule with the given name already exist.""" + try: + _result = module.ipa_command("servicedelegationrule_show", name, + {"all": True}) + except Exception: # pylint: disable=broad-except + # An exception is raised if servicedelegationrule name is not found. + return None + else: + return _result["result"] + + +def check_targets(module, targets): + def _check_exists(module, _type, name): + # Check if item of type _type exists using the show command + try: + module.ipa_command("%s_show" % _type, name, {}) + except ipalib_errors.NotFound as e: + msg = str(e) + if "%s not found" % _type in msg: + return False + module.fail_json(msg="%s_show failed: %s" % (_type, msg)) + return True + + for _target in targets: + if not _check_exists(module, "servicedelegationtarget", _target): + module.fail_json( + msg="Service delegation target '%s' does not exist" % _target) + + +def main(): + ansible_module = IPAAnsibleModule( + argument_spec=dict( + # general + name=dict(type="list", aliases=["cn"], default=None, + required=True), + # present + principal=dict(required=False, type='list', default=None), + target=dict(required=False, type='list', + aliases=["servicedelegationtarget"], default=None), + + action=dict(type="str", default="servicedelegationrule", + choices=["member", "servicedelegationrule"]), + # state + state=dict(type="str", default="present", + choices=["present", "absent"]), + ), + supports_check_mode=True, + ) + + ansible_module._ansible_debug = True + + # Get parameters + + # general + names = ansible_module.params_get("name") + + # present + principal = ansible_module.params_get("principal") + target = ansible_module.params_get("target") + + action = ansible_module.params_get("action") + + # state + state = ansible_module.params_get("state") + + # Check parameters + + invalid = [] + + if state == "present": + if len(names) != 1: + ansible_module.fail_json( + msg="Only one servicedelegationrule can be added at a time.") + + if state == "absent": + if len(names) < 1: + ansible_module.fail_json(msg="No name given.") + if action == "servicedelegationrule": + invalid = ["principal", "target"] + + ansible_module.params_fail_used_invalid(invalid, state, action) + + # Init + + membertarget = "ipaallowedtarget_servicedelegationtarget" + changed = False + exit_args = {} + + # Connect to IPA API + with ansible_module.ipa_connect(): + + # Normalize principals + if principal: + principal = servicedelegation_normalize_principals(ansible_module, + principal) + if target: + check_targets(ansible_module, target) + + commands = [] + principal_add = principal_del = [] + target_add = target_del = [] + for name in names: + # Make sure servicedelegationrule exists + res_find = find_servicedelegationrule(ansible_module, name) + + # Create command + if state == "present": + + if action == "servicedelegationrule": + # A servicedelegationrule does not have normal options. + # There is no servicedelegationtarget-mod command. + # Principal members are handled with the _add_member and + # _remove_member commands further down. + if res_find is None: + commands.append([name, "servicedelegationrule_add", + {}]) + res_find = {} + + # Generate addition and removal lists for principal + principal_add, principal_del = gen_add_del_lists( + principal, res_find.get("memberprincipal")) + + # Generate addition and removal lists for target + target_add, target_del = gen_add_del_lists( + target, res_find.get(membertarget)) + + elif action == "member": + if res_find is None: + ansible_module.fail_json( + msg="No servicedelegationrule '%s'" % name) + + # Reduce add lists for principal + # to new entries only that are not in res_find. + if principal is not None and \ + "memberprincipal" in res_find: + principal_add = gen_add_list( + principal, res_find["memberprincipal"]) + else: + principal_add = principal + + # Reduce add lists for target + # to new entries only that are not in res_find. + if target is not None and membertarget in res_find: + target_add = gen_add_list( + target, res_find[membertarget]) + else: + target_add = target + + elif state == "absent": + if action == "servicedelegationrule": + if res_find is not None: + commands.append([name, "servicedelegationrule_del", + {}]) + + elif action == "member": + if res_find is None: + ansible_module.fail_json( + msg="No servicedelegationrule '%s'" % name) + + # Reduce del lists of principals to the entries only + # that are in res_find. + if principal is not None: + principal_del = gen_intersection_list( + principal, res_find.get("memberprincipal")) + else: + principal_del = principal + + # Reduce del lists of targets to the entries only + # that are in res_find. + if target is not None: + target_del = gen_intersection_list( + target, res_find.get(membertarget)) + else: + target_del = target + + else: + ansible_module.fail_json(msg="Unkown state '%s'" % state) + + # Handle members + + # Add principal members + if principal_add is not None and len(principal_add) > 0: + commands.append( + [name, "servicedelegationtarget_add_member", + { + "principal": principal_add, + }]) + # Remove principal members + if principal_del is not None and len(principal_del) > 0: + commands.append( + [name, "servicedelegationtarget_remove_member", + { + "principal": principal_del, + }]) + + # Add target members + if target_add is not None and len(target_add) > 0: + commands.append( + [name, "servicedelegationrule_add_target", + { + "servicedelegationtarget": target_add, + }]) + # Remove target members + if target_del is not None and len(target_del) > 0: + commands.append( + [name, "servicedelegationrule_remove_target", + { + "servicedelegationtarget": target_del, + }]) + + # Execute commands + + changed = ansible_module.execute_ipa_commands( + commands, fail_on_member_errors=True) + + # Done + + ansible_module.exit_json(changed=changed, **exit_args) + + +if __name__ == "__main__": + main() diff --git a/tests/servicedelegationrule/test_servicedelegationrule.yml b/tests/servicedelegationrule/test_servicedelegationrule.yml new file mode 100644 index 0000000000000000000000000000000000000000..0e351e8b77de6506fefd563889e6d6938945bd9d --- /dev/null +++ b/tests/servicedelegationrule/test_servicedelegationrule.yml @@ -0,0 +1,188 @@ +--- +- name: Test servicedelegationrule + hosts: "{{ ipa_test_host | default('ipaserver') }}" + # Change "become" or "gather_facts" to "yes", + # if you test playbook requires any. + become: no + gather_facts: yes + + tasks: + + # CLEANUP TEST ITEMS + + - name: Ensure servicedelegationrule test-delegation-rule is absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + state: absent + + - name: Ensure service is absent + ipaservice: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ 'test-service/' + ansible_facts['fqdn'] }}" + state: absent + continue: yes + + - name: Ensure servicedelegationrule test-delegation-target is absent + ipaservicedelegationtarget: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-target + state: absent + + # CREATE TEST ITEMS + + - name: Ensure service test-sevice is present + ipaservice: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ 'test-service/' + ansible_facts['fqdn'] }}" + register: result + failed_when: not result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-target is present + ipaservicedelegationtarget: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-target + register: result + failed_when: not result.changed or result.failed + + # TESTS + + - name: Ensure servicedelegationrule test-delegation-rule is present + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + register: result + failed_when: not result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule is present again + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + register: result + failed_when: result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member target test-delegation-target is present + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + target: test-delegation-target + action: member + register: result + failed_when: not result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member target test-delegation-target is present, again + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + target: test-delegation-target + action: member + register: result + failed_when: result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member principal "{{ 'test-service/' + ansible_facts['fqdn'] }}" is present + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + principal: "{{ 'test-service/' + ansible_facts['fqdn'] }}" + action: member + register: result + failed_when: not result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member principal "{{ 'test-service/' + ansible_facts['fqdn'] }}" is present again + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + principal: "{{ 'test-service/' + ansible_facts['fqdn'] }}" + action: member + register: result + failed_when: result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member principal "{{ 'test-service/' + ansible_facts['fqdn'] }}" is absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + principal: "{{ 'test-service/' + ansible_facts['fqdn'] }}" + action: member + state: absent + register: result + failed_when: not result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member principal "{{ 'test-service/' + ansible_facts['fqdn'] }}" is present absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + principal: "{{ 'test-service/' + ansible_facts['fqdn'] }}" + action: member + state: absent + register: result + failed_when: result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member target test-delegation-target is absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + target: test-delegation-target + action: member + state: absent + register: result + failed_when: not result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member target test-delegation-target is absent, again + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + target: test-delegation-target + action: member + state: absent + register: result + failed_when: result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule is absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + state: absent + register: result + failed_when: not result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule is absent again + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + state: absent + register: result + failed_when: result.changed or result.failed + + # CLEANUP TEST ITEMS + + - name: Ensure servicedelegationrule test-delegation-target is absent + ipaservicedelegationtarget: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-target + state: absent + + - name: Ensure service is absent + ipaservice: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ 'test-service/' + ansible_facts['fqdn'] }}" + state: absent + continue: yes diff --git a/tests/servicedelegationrule/test_servicedelegationrule_client_context.yml b/tests/servicedelegationrule/test_servicedelegationrule_client_context.yml new file mode 100644 index 0000000000000000000000000000000000000000..03546ffc179fd831eeaaaca9be320810c84ac268 --- /dev/null +++ b/tests/servicedelegationrule/test_servicedelegationrule_client_context.yml @@ -0,0 +1,39 @@ +--- +- name: Test servicedelegationrule + hosts: ipaclients, ipaserver + # Change "become" or "gather_facts" to "yes", + # if you test playbook requires any. + become: no + gather_facts: no + + tasks: + - name: Include FreeIPA facts. + include_tasks: ../env_freeipa_facts.yml + + # Test will only be executed if host is not a server. + - name: Execute with server context in the client. + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: server + name: ThisShouldNotWork + register: result + failed_when: not (result.failed and result.msg is regex("No module named '*ipaserver'*")) + when: ipa_host_is_client + +# Import basic module tests, and execute with ipa_context set to 'client'. +# If ipaclients is set, it will be executed using the client, if not, +# ipaserver will be used. +# +# With this setup, tests can be executed against an IPA client, against +# an IPA server using "client" context, and ensure that tests are executed +# in upstream CI. + +- name: Test servicedelegationrule using client context, in client host. + import_playbook: test_servicedelegationrule.yml + when: groups['ipaclients'] + vars: + ipa_test_host: ipaclients + +- name: Test servicedelegationrule using client context, in server host. + import_playbook: test_servicedelegationrule.yml + when: groups['ipaclients'] is not defined or not groups['ipaclients'] diff --git a/tests/servicedelegationrule/test_servicedelegationrule_hostprincipal.yml b/tests/servicedelegationrule/test_servicedelegationrule_hostprincipal.yml new file mode 100644 index 0000000000000000000000000000000000000000..f0f79a76e69278b885fb9657895aa06473571ece --- /dev/null +++ b/tests/servicedelegationrule/test_servicedelegationrule_hostprincipal.yml @@ -0,0 +1,148 @@ +--- +- name: Test servicedelegationrule_hostprincipal + hosts: "{{ ipa_test_host | default('ipaserver') }}" + become: no + gather_facts: yes + + tasks: + # setup + - include_tasks: ../env_freeipa_facts.yml + + # host principals are only possible with IPA 4.9.0+ + - block: + + # SET FACTS + + - name: Get Domain from server name + set_fact: + ipaserver_domain: "{{ ansible_facts['fqdn'].split('.')[1:] | join ('.') }}" + when: ipaserver_domain is not defined + + - name: Get REALM from server name + set_fact: + ipaserver_realm: "{{ ipaserver_domain | upper }}" + when: ipaserver_realm is not defined + + - name: Set test-host fqdn + set_fact: + test_host_fqdn: "{{ 'test-host.' + ipaserver_domain }}" + test_host_fqdn_realm: "{{ 'test-host.' + ipaserver_domain + '@' + ipaserver_realm }}" + + # CLEANUP TEST ITEMS + + - name: Ensure servicedelegationrule test-delegation-rule is absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + state: absent + + - name: Ensure host is absent + ipahost: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ test_host_fqdn }}" + state: absent + + # CREATE TEST ITEMS + + - name: Ensure host is present + ipahost: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ test_host_fqdn }}" + force: yes + + - name: Ensure servicedelegationrule test-delegation-rule is present + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + register: result + failed_when: not result.changed or result.failed + + # TESTS + + - name: Ensure servicedelegationrule test-delegation-rule member host principal "{{ test_host_fqdn }}" is present + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + principal: "{{ test_host_fqdn }}" + action: member + register: result + failed_when: not result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member host principal "{{ test_host_fqdn }}" is present again + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + principal: "{{ test_host_fqdn }}" + action: member + register: result + failed_when: result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member host principal "{{ test_host_fqdn_realm }}" is present unchanged + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + principal: "{{ test_host_fqdn_realm }}" + action: member + register: result + failed_when: result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member host principal "{{ 'host/' + test_host_fqdn_realm }}" is present unchanged + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + principal: "{{ 'host/' + test_host_fqdn_realm }}" + action: member + register: result + failed_when: result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member host principal "{{ test_host_fqdn_realm }}" is absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + principal: "{{ test_host_fqdn_realm }}" + action: member + state: absent + register: result + failed_when: not result.changed or result.failed + + - name: Ensure servicedelegationrule test-delegation-rule member host principal "{{ test_host_fqdn }}" is absent unchanged + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + principal: "{{ test_host_fqdn }}" + action: member + state: absent + register: result + failed_when: result.changed or result.failed + + # CLEANUP TEST ITEMS + + - name: Ensure servicedelegationrule test-delegation-rule is absent + ipaservicedelegationrule: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: test-delegation-rule + state: absent + register: result + failed_when: not result.changed or result.failed + + - name: Ensure host is absent + ipahost: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + name: "{{ test_host_fqdn }}" + state: absent + register: result + failed_when: not result.changed or result.failed + + when: ipa_version is version('4.9.0', '>=')