diff --git a/README-config.md b/README-config.md new file mode 100644 index 0000000000000000000000000000000000000000..ee96981673d43917c726938f6e221baad6dfcfb9 --- /dev/null +++ b/README-config.md @@ -0,0 +1,149 @@ +Config module +=========== + +Description +----------- + +The config module allows the setting of global config parameters within IPA. If no parameters are specified it returns the list of all current parameters. + +The config module is as compatible as possible to the Ansible upstream `ipa_config` module, but adds many additional parameters + + +Features +-------- +* IPA server configuration management + + +Supported FreeIPA Versions +-------------------------- + +FreeIPA versions 4.4.0 and up are supported by the ipaconfig module. + + +Requirements +------------ + +**Controller** +* Ansible version: 2.8+ + +**Node** +* Supported FreeIPA version (see above) + + +Usage +===== + +Example inventory file + +```ini +[ipaserver] +ipaserver.test.local +``` + + +Example playbook to read config options: + +```yaml +--- +- name: Playbook to handle global config options + hosts: ipaserver + become: true + tasks: + - name: return current values of the global configuration options + ipaconfig: + ipaadmin_password: password + register: result + - name: display default login shell + debug: + msg: '{{result.config.defaultlogin }}' + + - name: ensure defaultloginshell and maxusernamelength are set as required + ipaconfig: + ipaadmin_password: password + defaultlogin: /bin/bash + maxusername: 64 +``` + +```yaml +--- +- name: Playbook to ensure some config options are set + hosts: ipaserver + become: true + tasks: + - name: set defaultlogin and maxusername + ipaconfig: + ipaadmin_password: password + defaultlogin: /bin/bash + maxusername: 64 +``` + + +Variables +========= + +ipauser +------- + +**General 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 +`maxusername` \| `ipamaxusernamelength` | Set the maximum username length (1 to 255) | no +`maxhostname` \| `ipamaxhostnamelength` | Set the maximum hostname length between 64-255 | no +`homedirectory` \| `ipahomesrootdir` | Set the default location of home directories | no +`defaultshell` \| `ipadefaultloginshell` | Set the default shell for new users | no +`defaultgroup` \| `ipadefaultprimarygroup` | Set the default group for new users | no +`emaildomain`\| `ipadefaultemaildomain` | Set the default e-mail domain | false +`searchtimelimit` \| `ipasearchtimelimit` | Set maximum amount of time (seconds) for a search -1 to 2147483647 (-1 or 0 is unlimited) | no +`searchrecordslimit` \| `ipasearchrecordslimit` | Set maximum number of records to search -1 to 2147483647 (-1 or 0 is unlimited) | no +`usersearch` \| `ipausersearchfields` | Set list of fields to search when searching for users | no +`groupsearch` \| `ipagroupsearchfields` | Set list of fields to search in when searching for groups | no +`enable_migration` \| `ipamigrationenabled` | Enable migration mode (choices: True, False ) | no +`groupobjectclasses` \| `ipagroupobjectclasses` | Set default group objectclasses (list) | no +`userobjectclasses` \| `ipauserobjectclasses` | Set default user objectclasses (list) | no +`pwdexpnotify` \| `ipapwdexpadvnotify` | Set number of days's notice of impending password expiration (0 to 2147483647) | no +`configstring` \| `ipaconfigstring` | Set extra hashes to generate in password plug-in (choices:`AllowNThash`, `KDC:Disable Last Success`, `KDC:Disable Lockout`, `KDC:Disable Default Preauth for SPNs`). Use `""` to clear this variable. | no +`selinuxusermaporder` \| `ipaselinuxusermaporder`| Set ordered list in increasing priority of SELinux users | no +`selinuxusermapdefault`\| `ipaselinuxusermapdefault` | Set default SELinux user when no match is found in SELinux map rule | no +`pac_type` \| `ipakrbauthzdata` | set default types of PAC supported for services (choices: `MS-PAC`, `PAD`, `nfs:NONE`). Use `""` to clear this variable. | no +`user_auth_type` \| `ipauserauthtype` | set default types of supported user authentication (choices: `password`, `radius`, `otp`, `disabled`). Use `""` to clear this variable. | no +`domain_resolution_order` \| `ipadomainresolutionorder` | Set list of domains used for short name qualification | no +`ca_renewal_master_server` \| `ipacarenewalmasterserver`| Renewal master for IPA certificate authority. | no + + +Return Values +============= + +Variable | Description | Returned When +-------- | ----------- | ------------- +`config` | config dict <br />Fields: | No values to configure are specified + | `maxusername` | + | `maxhostname` | + | `homedirectory` | + | `defaultshell` | + | `defaultgroup` | + | `emaildomain` | + | `searchtimelimit` | + | `searchrecordslimit` | + | `usersearch` | + | `groupsearch` | + | `enable_migration` | + | `groupobjectclasses` | + | `userobjectclasses` | + | `pwdexpnotify` | + | `configstring` | + | `selinuxusermapdefault` | + | `selinuxusermaporder` | + | `pac_type` | + | `user_auth_type` | + | `domain_resolution_order` | + | `ca_renewal_master_server` | + +All returned fields take the same form as their namesake input parameters + +Authors +======= + +Chris Procter diff --git a/playbooks/config/retrieve-config.yml b/playbooks/config/retrieve-config.yml new file mode 100644 index 0000000000000000000000000000000000000000..7f05e802e2730a7d6cf83e02dbd1c4f91ed766fc --- /dev/null +++ b/playbooks/config/retrieve-config.yml @@ -0,0 +1,14 @@ +--- +- name: Playbook to handle global DNS configuration + hosts: ipaserver + become: no + gather_facts: no + + tasks: + - name: Query IPA global configuration + ipaconfig: + ipaadmin_password: SomeADMINpassword + register: serverconfig + + - debug: + msg: "{{ serverconfig }}" diff --git a/playbooks/config/set-ca-renewal-master-server.yml b/playbooks/config/set-ca-renewal-master-server.yml new file mode 100644 index 0000000000000000000000000000000000000000..128ac8d96a9c2f74fbecf6518e33a69dbe50d206 --- /dev/null +++ b/playbooks/config/set-ca-renewal-master-server.yml @@ -0,0 +1,11 @@ +--- +- name: Playbook to handle global DNS configuration + hosts: ipaserver + become: no + gather_facts: no + + tasks: + - name: set ca_renewal_master_server + ipaconfig: + ipaadmin_password: SomeADMINpassword + ca_renewal_master_server: carenewal.example.com diff --git a/plugins/modules/ipaconfig.py b/plugins/modules/ipaconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..41a6d0a877a177bd30ecc312534c51dbe66dbe1f --- /dev/null +++ b/plugins/modules/ipaconfig.py @@ -0,0 +1,479 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Chris Procter <cprocter@redhat.com> +# +# Copyright (C) 2020 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/>. + +ANSIBLE_METADATA = { + "metadata_version": "1.0", + "supported_by": "community", + "status": ["preview"], +} + + +DOCUMENTATION = ''' +--- +module: ipa_config +author: chris procter +short_description: Modify IPA global config options +description: +- Modify IPA global config options +options: + ipaadmin_principal: + description: The admin principal + default: admin + ipaadmin_password: + description: The admin password + required: false + maxusername: + description: Set the maximum username length between 1-255 + required: false + aliases: ['ipamaxusernamelength'] + maxhostname: + description: Set the maximum hostname length between 64-255 + required: false + aliases: ['ipamaxhostnamelength'] + homedirectory: + description: Set the default location of home directories + required: false + aliases: ['ipahomesrootdir'] + defaultshell: + description: Set the default shell for new users + required: false + aliases: ['ipadefaultloginshell', 'loginshell'] + defaultgroup: + description: Set the default group for new users + required: false + aliases: ['ipadefaultprimarygroup'] + emaildomain: + description: Set the default e-mail domain + required: false + aliases: ['ipadefaultemaildomain'] + searchtimelimit: + description: + - Set maximum amount of time (seconds) for a search + - values -1 to 2147483647 (-1 or 0 is unlimited) + required: false + aliases: ['ipasearchtimelimit'] + searchrecordslimit: + description: + - Set maximum number of records to search + - values -1 to 2147483647 (-1 or 0 is unlimited) + required: false + aliases: ['ipasearchrecordslimit'] + usersearch: + description: + - Set comma-separated list of fields to search for user search + required: false + aliases: ['ipausersearchfields'] + groupsearch: + description: + - Set comma-separated list of fields to search for group search + required: false + aliases: ['ipagroupsearchfields'] + enable_migration: + description: Enable migration mode + type: bool + required: false + aliases: ['ipamigrationenabled'] + groupobjectclasses: + description: Set default group objectclasses (comma-separated list) + required: false + type: list + aliases: ['ipagroupobjectclasses'] + userobjectclasses: + description: Set default user objectclasses (comma-separated list) + required: false + type: list + aliases: ['ipauserobjectclasses'] + pwdexpnotify: + description: + - Set number of days's notice of impending password expiration + - values 0 to 2147483647 + required: false + aliases: ['ipapwdexpadvnotify'] + configstring: + description: Set extra hashes to generate in password plug-in + required: false + type: list + choices: + - "AllowNThash" + - "KDC:Disable Last Success" + - "KDC:Disable Lockout" + - "KDC:Disable Default Preauth for SPNs" + - "" + aliases: ['ipaconfigstring'] + selinuxusermaporder: + description: Set order in increasing priority of SELinux users + required: false + type: list + aliases: ['ipaselinuxusermaporder'] + selinuxusermapdefault: + description: Set default SELinux user when no match found in map rule + required: false + aliases: ['ipaselinuxusermapdefault'] + pac_type: + description: set default types of PAC supported for services + required: false + type: list + choices: ["MS-PAC", "PAD", "nfs:NONE", ""] + aliases: ["ipakrbauthzdata"] + user_auth_type: + description: set default types of supported user authentication + required: false + type: list + choices: ["password", "radius", "otp", "disabled", ""] + aliases: ["ipauserauthtype"] + ca_renewal_master_server: + description: Renewal master for IPA certificate authority. + required: false + type: string + domain_resolution_order: + description: set list of domains used for short name qualification + required: false + type: list + aliases: ["ipadomainresolutionorder"] +''' + +EXAMPLES = ''' +--- +- name: Playbook to handle global configuration options + hosts: ipaserver + become: true + tasks: + - name: return current values of the global configuration options + ipaconfig: + ipaadmin_password: password + register: result + - name: display default login shell + debug: + msg: '{{result.config.defaultshell[0] }}' + + - name: set defaultshell and maxusername + ipaconfig: + ipaadmin_password: password + defaultshell: /bin/bash + maxusername: 64 +''' + +RETURN = ''' +config: + description: Dict of all global config options + returned: When no options are set + type: dict + options: + maxusername: + description: maximum username length + returned: always + maxhostname: + description: maximum hostname length + returned: always + homedirectory: + description: default location of home directories + returned: always + defaultshell: + description: default shell for new users + returned: always + defaultgroup: + description: default group for new users + returned: always + emaildomain: + description: default e-mail domain + returned: always + searchtimelimit: + description: maximum amount of time (seconds) for a search + returned: always + searchrecordslimit: + description: maximum number of records to search + returned: always + usersearch: + description: comma-separated list of fields to search in user search + type: list + returned: always + groupsearch: + description: comma-separated list of fields to search in group search + type: list + returned: always + enable_migration: + description: Enable migration mode + type: bool + returned: always + groupobjectclasses: + description: default group objectclasses (comma-separated list) + type: list + returned: always + userobjectclasses: + description: default user objectclasses (comma-separated list) + type: list + returned: always + pwdexpnotify: + description: number of days's notice of impending password expiration + returned: always + configstring: + description: extra hashes to generate in password plug-in + type: list + returned: always + selinuxusermaporder: + description: order in increasing priority of SELinux users + returned: always + selinuxusermapdefault: + description: default SELinux user when no match is found in map rule + returned: always + pac_type: + description: default types of PAC supported for services + type: list + returned: always + user_auth_type: + description: default types of supported user authentication + returned: always + ca_renewal_master_server: + description: master for IPA certificate authority. + returned: always + domain_resolution_order: + description: list of domains used for short name qualification + returned: always +''' + + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ + temp_kdestroy, valid_creds, api_connect, api_command_no_name, \ + compare_args_ipa, module_params_get +import ipalib.errors + + +def config_show(module): + _result = api_command_no_name(module, "config_show", {}) + + return _result["result"] + + +def gen_args(params): + _args = {} + for k, v in params.items(): + if v is not None: + _args[k] = v + + return _args + + +def main(): + ansible_module = AnsibleModule( + argument_spec=dict( + # general + ipaadmin_principal=dict(type="str", default="admin"), + ipaadmin_password=dict(type="str", required=False, no_log=True), + maxusername=dict(type="int", required=False, + aliases=['ipamaxusernamelength']), + maxhostname=dict(type="int", required=False, + aliases=['ipamaxhostnamelength']), + homedirectory=dict(type="str", required=False, + aliases=['ipahomesrootdir']), + defaultshell=dict(type="str", required=False, + aliases=['ipadefaultloginshell', + 'loginshell']), + defaultgroup=dict(type="str", required=False, + aliases=['ipadefaultprimarygroup']), + emaildomain=dict(type="str", required=False, + aliases=['ipadefaultemaildomain']), + searchtimelimit=dict(type="int", required=False, + aliases=['ipasearchtimelimit']), + searchrecordslimit=dict(type="int", required=False, + aliases=['ipasearchrecordslimit']), + usersearch=dict(type="list", required=False, + aliases=['ipausersearchfields']), + groupsearch=dict(type="list", required=False, + aliases=['ipagroupsearchfields']), + enable_migration=dict(type="bool", required=False, + aliases=['ipamigrationenabled']), + groupobjectclasses=dict(type="list", required=False, + aliases=['ipagroupobjectclasses']), + userobjectclasses=dict(type="list", required=False, + aliases=['ipauserobjectclasses']), + pwdexpnotify=dict(type="int", required=False, + aliases=['ipapwdexpadvnotify']), + configstring=dict(type="list", required=False, + aliases=['ipaconfigstring'], + choices=["AllowNThash", + "KDC:Disable Last Success", + "KDC:Disable Lockout", + "KDC:Disable Default Preauth for SPNs", + ""]), # noqa E128 + selinuxusermaporder=dict(type="list", required=False, + aliases=['ipaselinuxusermaporder']), + selinuxusermapdefault=dict(type="str", required=False, + aliases=['ipaselinuxusermapdefault']), + pac_type=dict(type="list", required=False, + aliases=["ipakrbauthzdata"], + choices=["MS-PAC", "PAD", "nfs:NONE", ""]), + user_auth_type=dict(type="list", required=False, + choices=["password", "radius", "otp", + "disabled", ""], + aliases=["ipauserauthtype"]), + ca_renewal_master_server=dict(type="str", required=False), + domain_resolution_order=dict(type="list", required=False, + aliases=["ipadomainresolutionorder"]) + ), + supports_check_mode=True, + ) + + ansible_module._ansible_debug = True + + # Get parameters + + # general + ipaadmin_principal = module_params_get(ansible_module, + "ipaadmin_principal") + ipaadmin_password = module_params_get(ansible_module, + "ipaadmin_password") + + field_map = { + "maxusername": "ipamaxusernamelength", + "maxhostname": "ipamaxhostnamelength", + "homedirectory": "ipahomesrootdir", + "defaultshell": "ipadefaultloginshell", + "defaultgroup": "ipadefaultprimarygroup", + "emaildomain": "ipadefaultemaildomain", + "searchtimelimit": "ipasearchtimelimit", + "searchrecordslimit": "ipasearchrecordslimit", + "usersearch": "ipausersearchfields", + "groupsearch": "ipagroupsearchfields", + "enable_migration": "ipamigrationenabled", + "groupobjectclasses": "ipagroupobjectclasses", + "userobjectclasses": "ipauserobjectclasses", + "pwdexpnotify": "ipapwdexpadvnotify", + "configstring": "ipaconfigstring", + "selinuxusermaporder": "ipaselinuxusermaporder", + "selinuxusermapdefault": "ipaselinuxusermapdefault", + "pac_type": "ipakrbauthzdata", + "user_auth_type": "ipauserauthtype", + "ca_renewal_master_server": "ca_renewal_master_server", + "domain_resolution_order": "ipadomainresolutionorder" + } + reverse_field_map = {v: k for k, v in field_map.items()} + + params = {} + for x in field_map.keys(): + val = module_params_get(ansible_module, x) + + if val is not None: + params[field_map.get(x, x)] = val + + if params.get("ipamigrationenabled") is not None: + params["ipamigrationenabled"] = \ + str(params["ipamigrationenabled"]).upper() + + if params.get("ipaselinuxusermaporder", None): + params["ipaselinuxusermaporder"] = \ + "$".join(params["ipaselinuxusermaporder"]) + + if params.get("ipadomainresolutionorder", None): + params["ipadomainresolutionorder"] = \ + ":".join(params["ipadomainresolutionorder"]) + + if params.get("ipausersearchfields", None): + params["ipausersearchfields"] = \ + ",".join(params["ipausersearchfields"]) + + if params.get("ipagroupsearchfields", None): + params["ipagroupsearchfields"] = \ + ",".join(params["ipagroupsearchfields"]) + + # verify limits on INT values. + args_with_limits = [ + ("ipamaxusernamelength", 1, 255), + ("ipamaxhostnamelength", 64, 255), + ("ipasearchtimelimit", -1, 2147483647), + ("ipasearchrecordslimit", -1, 2147483647), + ("ipapwdexpadvnotify", 0, 2147483647), + ] + for arg, min, max in args_with_limits: + if arg in params and (params[arg] > max or params[arg] < min): + ansible_module.fail_json( + msg="Argument '%s' must be between %d and %d." + % (arg, min, max)) + + changed = False + exit_args = {} + ccache_dir = None + ccache_name = None + res_show = None + try: + if not valid_creds(ansible_module, ipaadmin_principal): + ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, + ipaadmin_password) + api_connect() + if params: + res_show = config_show(ansible_module) + params = { + k: v for k, v in params.items() + if k not in res_show or res_show[k] != v + } + if params \ + and not compare_args_ipa(ansible_module, params, res_show): + changed = True + api_command_no_name(ansible_module, "config_mod", params) + + else: + rawresult = api_command_no_name(ansible_module, "config_show", {}) + result = rawresult['result'] + del result['dn'] + for key, v in result.items(): + k = reverse_field_map.get(key, key) + if ansible_module.argument_spec.get(k): + if k == 'ipaselinuxusermaporder': + exit_args['ipaselinuxusermaporder'] = \ + result.get(key)[0].split('$') + elif k == 'domain_resolution_order': + exit_args['domain_resolution_order'] = \ + result.get(key)[0].split('$') + elif k == 'usersearch': + exit_args['usersearch'] = \ + result.get(key)[0].split(',') + elif k == 'groupsearch': + exit_args['groupsearch'] = \ + result.get(key)[0].split(',') + elif isinstance(v, str) and \ + ansible_module.argument_spec[k]['type'] == "list": + exit_args[k] = [v] + elif isinstance(v, list) and \ + ansible_module.argument_spec[k]['type'] == "str": + exit_args[k] = ",".join(v) + elif isinstance(v, list) and \ + ansible_module.argument_spec[k]['type'] == "int": + exit_args[k] = ",".join(v) + elif isinstance(v, list) and \ + ansible_module.argument_spec[k]['type'] == "bool": + exit_args[k] = (v[0] == "TRUE") + else: + exit_args[k] = v + except ipalib.errors.EmptyModlist: + changed = False + except Exception as e: + ansible_module.fail_json(msg="%s %s" % (params, str(e))) + + finally: + temp_kdestroy(ccache_dir, ccache_name) + + # Done + ansible_module.exit_json(changed=changed, config=exit_args) + + +if __name__ == "__main__": + main() diff --git a/tests/config/test_config.yml b/tests/config/test_config.yml new file mode 100644 index 0000000000000000000000000000000000000000..c288e45197c749756dd1c46395edac3ca40299c2 --- /dev/null +++ b/tests/config/test_config.yml @@ -0,0 +1,388 @@ +--- +- name: Playbook to handle server configuration + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Retrieve current configuration. + - name: return current values of the global configuration options + ipaconfig: + ipaadmin_password: SomeADMINpassword + register: previousconfig + + - debug: + msg: "{{previousconfig}}" + + # setup environment. + - name: create test group + ipagroup: + ipaadmin_password: 'SomeADMINpassword' + name: somedefaultgroup + + - name: Ensure the default e-mail domain is ipa.test. + ipaconfig: + ipaadmin_password: SomeADMINpassword + emaildomain: ipa.test + + - name: set default shell to '/bin/sh' + ipaconfig: + ipaadmin_password: SomeADMINpassword + defaultshell: /bin/sh + + - name: set default group + ipaconfig: + ipaadmin_password: SomeADMINpassword + defaultgroup: ipausers + + - name: set default home directory + ipaconfig: + ipaadmin_password: SomeADMINpassword + homedirectory: /home + + - name: clear pac-type + ipaconfig: + ipaadmin_password: SomeADMINpassword + pac_type: "" + + - name: set maxusername to 255 + ipaconfig: + ipaadmin_password: SomeADMINpassword + maxusername: 255 + + - name: set maxhostname to 255 + ipaconfig: + ipaadmin_password: SomeADMINpassword + maxhostname: 255 + + - name: set pwdexpnotify to 0 + ipaconfig: + ipaadmin_password: SomeADMINpassword + pwdexpnotify: 0 + + - name: set searchrecordslimit to 10 + ipaconfig: + ipaadmin_password: SomeADMINpassword + searchrecordslimit: 10 + + - name: set searchtimelimit to 1 + ipaconfig: + ipaadmin_password: SomeADMINpassword + searchtimelimit: 1 + + - name: clear configstring + ipaconfig: + ipaadmin_password: SomeADMINpassword + configstring: "" + + - name: set configstring to AllowNThash + ipaconfig: + ipaadmin_password: SomeADMINpassword + configstring: 'KDC:Disable Lockout' + + - name: set selinuxusermapdefault + ipaconfig: + ipaadmin_password: SomeADMINpassword + selinuxusermapdefault: "staff_u:s0-s0:c0.c1023" + + - name: set selinuxusermaporder + ipaconfig: + ipaadmin_password: SomeADMINpassword + selinuxusermaporder: 'user_u:s0$staff_u:s0-s0:c0.c1023' + + - name: set usersearch to `uid` + ipaconfig: + ipaadmin_password: SomeADMINpassword + usersearch: uid + + - name: set groupsearch to `cn` + ipaconfig: + ipaadmin_password: SomeADMINpassword + groupsearch: cn + + # tests + - name: Ensure the default e-mail domain is somedomain.test. + ipaconfig: + ipaadmin_password: SomeADMINpassword + emaildomain: somedomain.test + register: result + failed_when: not result.changed + + - name: Ensure the default e-mail domain is somedomain.test, again. + ipaconfig: + ipaadmin_password: SomeADMINpassword + emaildomain: somedomain.test + register: result + failed_when: result.changed + + - name: set default shell to '/bin/someshell' + ipaconfig: + ipaadmin_password: SomeADMINpassword + defaultshell: /bin/someshell + register: result + failed_when: not result.changed + + - name: set default shell to '/bin/someshell', again. + ipaconfig: + ipaadmin_password: SomeADMINpassword + defaultshell: /bin/someshell + register: result + failed_when: result.changed + + - name: set default group + ipaconfig: + ipaadmin_password: SomeADMINpassword + defaultgroup: somedefaultgroup + register: result + failed_when: not result.changed + + - name: set default group + ipaconfig: + ipaadmin_password: SomeADMINpassword + defaultgroup: somedefaultgroup + register: result + failed_when: result.changed + + - name: set default home directory + ipaconfig: + ipaadmin_password: SomeADMINpassword + homedirectory: /Users + register: result + failed_when: not result.changed + + - name: set default home directory + ipaconfig: + ipaadmin_password: SomeADMINpassword + homedirectory: /Users + register: result + failed_when: result.changed + + - name: set pac-type + ipaconfig: + ipaadmin_password: SomeADMINpassword + pac_type: "nfs:NONE" + register: result + failed_when: not result.changed + + - name: set pac-type, again. + ipaconfig: + ipaadmin_password: SomeADMINpassword + pac_type: "nfs:NONE" + register: result + failed_when: result.changed + + - name: set maxusername to 33 + ipaconfig: + ipaadmin_password: SomeADMINpassword + maxusername: 33 + register: result + failed_when: not result.changed + + - name: set maxusername to 33, again. + ipaconfig: + ipaadmin_password: SomeADMINpassword + maxusername: 33 + register: result + failed_when: result.changed + + - name: set maxhostname to 77 + ipaconfig: + ipaadmin_password: SomeADMINpassword + maxhostname: 77 + register: result + failed_when: not result.changed + + - name: set maxhostname to 77, again + ipaconfig: + ipaadmin_password: SomeADMINpassword + maxhostname: 77 + register: result + failed_when: result.changed + + - name: set pwdexpnotify to 17 + ipaconfig: + ipaadmin_password: SomeADMINpassword + pwdexpnotify: 17 + register: result + failed_when: not result.changed + + - name: set pwdexpnotify to 17, again + ipaconfig: + ipaadmin_password: SomeADMINpassword + pwdexpnotify: 17 + register: result + failed_when: result.changed + + - name: set searchrecordslimit to -1 + ipaconfig: + ipaadmin_password: SomeADMINpassword + searchrecordslimit: -1 + register: result + failed_when: not result.changed + + - name: set searchrecordslimit to -1, again. + ipaconfig: + ipaadmin_password: SomeADMINpassword + searchrecordslimit: -1 + register: result + failed_when: result.changed + + - name: set searchtimelimit to 12345 + ipaconfig: + ipaadmin_password: SomeADMINpassword + searchtimelimit: 12345 + register: result + failed_when: not result.changed + + - name: set searchtimelimit to 12345, again. + ipaconfig: + ipaadmin_password: SomeADMINpassword + searchtimelimit: 12345 + register: result + failed_when: result.changed + + - name: change enable_migration + ipaconfig: + ipaadmin_password: SomeADMINpassword + enable_migration: '{{ not previousconfig.config.enable_migration }}' + register: result + failed_when: not result.changed + + - name: change enable_migration, again + ipaconfig: + ipaadmin_password: SomeADMINpassword + enable_migration: '{{ not previousconfig.config.enable_migration }}' + register: result + failed_when: result.changed + + - name: set configstring to AllowNThash + ipaconfig: + ipaadmin_password: SomeADMINpassword + configstring: AllowNThash + register: result + failed_when: not result.changed + + - name: set configstring to AllowNThash, again. + ipaconfig: + ipaadmin_password: SomeADMINpassword + configstring: AllowNThash + register: result + failed_when: result.changed + + - name: set selinuxusermaporder + ipaconfig: + ipaadmin_password: SomeADMINpassword + selinuxusermaporder: 'user_u:s0$staff_u:s0-s0:c0.c1023$sysadm_u:s0-s0:c0.c1023$unconfined_u:s0-s0:c0.c1023' + register: result + failed_when: not result.changed + + - name: set selinuxusermaporder, again + ipaconfig: + ipaadmin_password: SomeADMINpassword + selinuxusermaporder: 'user_u:s0$staff_u:s0-s0:c0.c1023$sysadm_u:s0-s0:c0.c1023$unconfined_u:s0-s0:c0.c1023' + register: result + failed_when: result.changed + + - name: set selinuxusermapdefault + ipaconfig: + ipaadmin_password: SomeADMINpassword + selinuxusermapdefault: 'user_u:s0' + register: result + failed_when: not result.changed + + - name: set selinuxusermapdefault, again + ipaconfig: + ipaadmin_password: SomeADMINpassword + selinuxusermapdefault: 'user_u:s0' + register: result + failed_when: result.changed + + - name: set groupsearch to `description` + ipaconfig: + ipaadmin_password: SomeADMINpassword + groupsearch: description + register: result + failed_when: not result.changed + + - name: set groupsearch to `gidNumber`, again + ipaconfig: + ipaadmin_password: SomeADMINpassword + groupsearch: description + register: result + failed_when: result.changed + + - name: set usersearch to `uidNumber` + ipaconfig: + ipaadmin_password: SomeADMINpassword + usersearch: uidNumber + register: result + failed_when: not result.changed + + - name: set usersearch to `uidNumber`, again + ipaconfig: + ipaadmin_password: SomeADMINpassword + usersearch: uidNumber + register: result + failed_when: result.changed + + - name: reset changed fields + ipaconfig: + ipaadmin_password: 'SomeADMINpassword' + maxusername: '{{previousconfig.config.maxusername | default(omit)}}' + maxhostname: '{{previousconfig.config.maxhostname | default(omit)}}' + homedirectory: '{{previousconfig.config.homedirectory | default(omit)}}' + defaultshell: '{{previousconfig.config.defaultshell | default(omit)}}' + defaultgroup: '{{previousconfig.config.defaultgroup | default(omit)}}' + emaildomain: '{{previousconfig.config.emaildomain | default(omit)}}' + searchtimelimit: '{{previousconfig.config.searchtimelimit | default(omit)}}' + searchrecordslimit: '{{previousconfig.config.searchrecordslimit | default(omit)}}' + usersearch: '{{previousconfig.config.usersearch | default(omit)}}' + groupsearch: '{{previousconfig.config.groupsearch | default(omit)}}' + enable_migration: '{{previousconfig.config.enable_migration | default(omit)}}' + groupobjectclasses: '{{previousconfig.config.groupobjectclasses | default(omit)}}' + userobjectclasses: '{{previousconfig.config.userobjectclasses | default(omit)}}' + pwdexpnotify: '{{previousconfig.config.pwdexpnotify | default(omit)}}' + configstring: '{{previousconfig.config.configstring | default(omit)}}' + selinuxusermapdefault: '{{previousconfig.config.selinuxusermapdefault | default(omit)}}' + selinuxusermaporder: '{{previousconfig.config.selinuxusermaporder | default(omit)}}' + pac_type: '{{previousconfig.config.pac_type | default(omit)}}' + user_auth_type: '{{previousconfig.config.user_auth_type | default(omit)}}' + domain_resolution_order: '{{previousconfig.config.domain_resolution_order | default(omit)}}' + ca_renewal_master_server: '{{previousconfig.config.ca_renewal_master_server | default(omit)}}' + register: result + failed_when: not result.changed + + - name: reset changed fields, again + ipaconfig: + ipaadmin_password: 'SomeADMINpassword' + maxusername: '{{previousconfig.config.maxusername | default(omit)}}' + maxhostname: '{{previousconfig.config.maxhostname | default(omit)}}' + homedirectory: '{{previousconfig.config.homedirectory | default(omit)}}' + defaultshell: '{{previousconfig.config.defaultshell | default(omit)}}' + defaultgroup: '{{previousconfig.config.defaultgroup | default(omit)}}' + emaildomain: '{{previousconfig.config.emaildomain | default(omit)}}' + searchtimelimit: '{{previousconfig.config.searchtimelimit | default(omit)}}' + searchrecordslimit: '{{previousconfig.config.searchrecordslimit | default(omit)}}' + usersearch: '{{previousconfig.config.usersearch | default(omit)}}' + groupsearch: '{{previousconfig.config.groupsearch | default(omit)}}' + enable_migration: '{{previousconfig.config.enable_migration | default(omit)}}' + groupobjectclasses: '{{previousconfig.config.groupobjectclasses | default(omit)}}' + userobjectclasses: '{{previousconfig.config.userobjectclasses | default(omit)}}' + pwdexpnotify: '{{previousconfig.config.pwdexpnotify | default(omit)}}' + configstring: '{{previousconfig.config.configstring | default(omit)}}' + selinuxusermapdefault: '{{previousconfig.config.selinuxusermapdefault | default(omit)}}' + selinuxusermaporder: '{{previousconfig.config.selinuxusermaporder | default(omit)}}' + pac_type: '{{previousconfig.config.pac_type | default(omit)}}' + user_auth_type: '{{previousconfig.config.user_auth_type | default(omit)}}' + domain_resolution_order: '{{previousconfig.config.domain_resolution_order | default(omit)}}' + ca_renewal_master_server: '{{previousconfig.config.ca_renewal_master_server | default(omit)}}' + register: result + failed_when: result.changed + + # cleanup + + - name: cleanup test group + ipagroup: + ipaadmin_password: 'SomeADMINpassword' + name: somedefaultgroup + state: absent