diff --git a/README-pwpolicy.md b/README-pwpolicy.md index 7fd051643b6514be4ae07fa7d3c72e7160f9bb5f..8d158459eb2ba10f273b23bbe34b5a411c8aadaa 100644 --- a/README-pwpolicy.md +++ b/README-pwpolicy.md @@ -128,20 +128,20 @@ Variable | Description | Required `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 pwpolicy name strings. If name is not given, `global_policy` will be used automatically. | no -`maxlife` \| `krbmaxpwdlife` | Maximum password lifetime in days. (int) | no -`minlife` \| `krbminpwdlife` | Minimum password lifetime in hours. (int) | no -`history` \| `krbpwdhistorylength` | Password history size. (int) | no -`minclasses` \| `krbpwdmindiffchars` | Minimum number of character classes. (int) | no -`minlength` \| `krbpwdminlength` | Minimum length of password. (int) | no -`priority` \| `cospriority` | Priority of the policy, higher number means lower priority. (int) | no -`maxfail` \| `krbpwdmaxfailure` | Consecutive failures before lockout. (int) | no -`failinterval` \| `krbpwdfailurecountinterval` | Period after which failure count will be reset in seconds. (int) | no -`lockouttime` \| `krbpwdlockoutduration` | Period for which lockout is enforced in seconds. (int) | no -`maxrepeat` \| `ipapwdmaxrepeat` | Maximum number of same consecutive characters. Requires IPA 4.9+ (int) | no -`maxsequence` \| `ipapwdmaxsequence` | The maximum length of monotonic character sequences (abcd). Requires IPA 4.9+ (int) | no -`dictcheck` \| `ipapwdictcheck` | Check if the password is a dictionary word. Requires IPA 4.9+ (int) | no -`usercheck` \| `ipapwdusercheck` | Check if the password contains the username. Requires IPA 4.9+ (int) | no -`gracelimit` \| `passwordgracelimit` | Number of LDAP authentications allowed after expiration. Requires IPA 4.9.10 (int) | no +`maxlife` \| `krbmaxpwdlife` | Maximum password lifetime in days. (int or "") | no +`minlife` \| `krbminpwdlife` | Minimum password lifetime in hours. (int or "") | no +`history` \| `krbpwdhistorylength` | Password history size. (int or "") | no +`minclasses` \| `krbpwdmindiffchars` | Minimum number of character classes. (int or "") | no +`minlength` \| `krbpwdminlength` | Minimum length of password. (int or "") | no +`priority` \| `cospriority` | Priority of the policy, higher number means lower priority. (int or "") | no +`maxfail` \| `krbpwdmaxfailure` | Consecutive failures before lockout. (int or "") | no +`failinterval` \| `krbpwdfailurecountinterval` | Period after which failure count will be reset in seconds. (int or "") | no +`lockouttime` \| `krbpwdlockoutduration` | Period for which lockout is enforced in seconds. (int or "") | no +`maxrepeat` \| `ipapwdmaxrepeat` | Maximum number of same consecutive characters. Requires IPA 4.9+ (int or "") | no +`maxsequence` \| `ipapwdmaxsequence` | The maximum length of monotonic character sequences (abcd). Requires IPA 4.9+ (int or "") | no +`dictcheck` \| `ipapwdictcheck` | Check if the password is a dictionary word. Requires IPA 4.9+. (bool or "") | no +`usercheck` \| `ipapwdusercheck` | Check if the password contains the username. Requires IPA 4.9+. (bool or "") | no +`gracelimit` \| `passwordgracelimit` | Number of LDAP authentications allowed after expiration. Requires IPA 4.9.10 (int or "") | no `state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | yes diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py index 6bae7cc3bf923ab3e5808a66e9f207d571e994f5..0af0d63e3ae4b93062ca0663902f8251f03b2331 100644 --- a/plugins/module_utils/ansible_freeipa_module.py +++ b/plugins/module_utils/ansible_freeipa_module.py @@ -30,7 +30,7 @@ __all__ = ["gssapi", "netaddr", "api", "ipalib_errors", "Env", "kinit_password", "kinit_keytab", "run", "DN", "VERSION", "paths", "tasks", "get_credentials_if_valid", "Encoding", "DNSName", "getargspec", "certificate_loader", - "write_certificate_list"] + "write_certificate_list", "boolean"] import os # ansible-freeipa requires locale to be C, IPA requires utf-8. @@ -49,6 +49,7 @@ from ansible.module_utils._text import to_text from ansible.module_utils.common.text.converters import jsonify from ansible.module_utils import six from ansible.module_utils.common._collections_compat import Mapping +from ansible.module_utils.parsing.convert_bool import boolean # Import getargspec from inspect or provide own getargspec for # Python 2 compatibility with Python 3.11+. diff --git a/plugins/modules/ipapwpolicy.py b/plugins/modules/ipapwpolicy.py index f75635536c27357fdf247956dee7767867d4a5a8..a71a88dd20fb1824cc16ab10c5d6ea7c968f4695 100644 --- a/plugins/modules/ipapwpolicy.py +++ b/plugins/modules/ipapwpolicy.py @@ -45,82 +45,84 @@ options: required: false aliases: ["cn"] maxlife: - description: Maximum password lifetime (in days) + description: Maximum password lifetime (in days). (int or "") type: str required: false aliases: ["krbmaxpwdlife"] minlife: - description: Minimum password lifetime (in hours) + description: Minimum password lifetime (in hours). (int or "") type: str required: false aliases: ["krbminpwdlife"] history: - description: Password history size + description: Password history size. (int or "") type: str required: false aliases: ["krbpwdhistorylength"] minclasses: - description: Minimum number of character classes + description: Minimum number of character classes. (int or "") type: str required: false aliases: ["krbpwdmindiffchars"] minlength: - description: Minimum length of password + description: Minimum length of password. (int or "") type: str required: false aliases: ["krbpwdminlength"] priority: - description: Priority of the policy (higher number means lower priority) + description: > + Priority of the policy (higher number means lower priority). (int or "") type: str required: false aliases: ["cospriority"] maxfail: - description: Consecutive failures before lockout + description: Consecutive failures before lockout. (int or "") type: str required: false aliases: ["krbpwdmaxfailure"] failinterval: - description: Period after which failure count will be reset (seconds) + description: > + Period after which failure count will be reset (seconds). (int or "") type: str required: false aliases: ["krbpwdfailurecountinterval"] lockouttime: - description: Period for which lockout is enforced (seconds) + description: Period for which lockout is enforced (seconds). (int or "") type: str required: false aliases: ["krbpwdlockoutduration"] maxrepeat: description: > Maximum number of same consecutive characters. - Requires IPA 4.9+ + Requires IPA 4.9+. (int or "") type: str required: false aliases: ["ipapwdmaxrepeat"] maxsequence: description: > The maximum length of monotonic character sequences (abcd). - Requires IPA 4.9+ + Requires IPA 4.9+. (int or "") type: str required: false aliases: ["ipapwdmaxsequence"] dictcheck: description: > Check if the password is a dictionary word. - Requires IPA 4.9+ + Requires IPA 4.9+. (bool or "") type: str required: false aliases: ["ipapwdictcheck"] usercheck: description: > Check if the password contains the username. - Requires IPA 4.9+ + Requires IPA 4.9+. (bool or "") type: str required: false aliases: ["ipapwdusercheck"] gracelimit: description: > Number of LDAP authentications allowed after expiration. - Requires IPA 4.10.1+ + Requires IPA 4.10.1+. (int or "") type: str required: false aliases: ["passwordgracelimit"] @@ -151,7 +153,7 @@ RETURN = """ """ from ansible.module_utils.ansible_freeipa_module import \ - IPAAnsibleModule, compare_args_ipa + IPAAnsibleModule, compare_args_ipa, boolean def find_pwpolicy(module, name): @@ -359,17 +361,12 @@ def main(): gracelimit = int_or_empty_param(gracelimit, "gracelimit") def bool_or_empty_param(value, param): # pylint: disable=R1710 - # As of Ansible 2.14, values True, False, Yes an No, with variable - # capitalization are accepted by Ansible. - if not value: + if value is None or value == "": return value - if value in ["TRUE", "True", "true", "YES", "Yes", "yes"]: - return True - if value in ["FALSE", "False", "false", "NO", "No", "no"]: - return False - ansible_module.fail_json( - msg="Invalid value '%s' for argument '%s'." % (value, param) - ) + try: + return boolean(value) + except TypeError as terr: + ansible_module.fail_json(msg="Param '%s': %s" % (param, str(terr))) dictcheck = bool_or_empty_param(dictcheck, "dictcheck") usercheck = bool_or_empty_param(usercheck, "usercheck") diff --git a/tests/pwpolicy/test_pwpolicy_invalid_data_type.yml b/tests/pwpolicy/test_pwpolicy_invalid_data_type.yml index 8a1aaed7220f0845163099c173febbe89261d063..4c97622b9497d036f6e4a19043b6702d1d6b051c 100644 --- a/tests/pwpolicy/test_pwpolicy_invalid_data_type.yml +++ b/tests/pwpolicy/test_pwpolicy_invalid_data_type.yml @@ -103,7 +103,7 @@ name: ops dictcheck: "error" register: result - failed_when: result.changed or (result.failed and "Invalid value 'error' for argument 'dictcheck" not in result.msg) + failed_when: result.changed or (result.failed and "is not a valid boolean" not in result.msg) when: ipa_version is version("4.9", ">=") - name: Ensure invalid values for usercheck raise proper error. @@ -113,7 +113,7 @@ name: ops usercheck: "error" register: result - failed_when: result.changed or (result.failed and "Invalid value 'error' for argument 'usercheck'" not in result.msg) + failed_when: result.changed or (result.failed and "is not a valid boolean" not in result.msg) when: ipa_version is version("4.9", ">=") - name: Ensure invalid values for gracelimit raise proper error.