diff --git a/changelogs/fragments/debconf_multiselect.yml b/changelogs/fragments/debconf_multiselect.yml new file mode 100644 index 00000000000..e826c3d6f31 --- /dev/null +++ b/changelogs/fragments/debconf_multiselect.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - debconf - allow user to specify a list for value when vtype is multiselect (https://github.com/ansible/ansible/issues/81345). diff --git a/lib/ansible/modules/debconf.py b/lib/ansible/modules/debconf.py index 994bcda1638..779952ec94d 100644 --- a/lib/ansible/modules/debconf.py +++ b/lib/ansible/modules/debconf.py @@ -70,12 +70,14 @@ options: - The type of the value supplied. - It is highly recommended to add C(no_log=True) to task while specifying O(vtype=password). - V(seen) was added in Ansible 2.2. + - After Ansible 2.17, user can specify C(value) as a list, if C(vtype) is set as V(multiselect). type: str choices: [ boolean, error, multiselect, note, password, seen, select, string, text, title ] value: description: - - Value to set the configuration to. - type: str + - Value to set the configuration to. + - After Ansible 2.17, C(value) is of type 'raw'. + type: raw aliases: [ answer ] unseen: description: @@ -123,7 +125,7 @@ EXAMPLES = r''' RETURN = r'''#''' -from ansible.module_utils.common.text.converters import to_text +from ansible.module_utils.common.text.converters import to_text, to_native from ansible.module_utils.basic import AnsibleModule @@ -184,7 +186,7 @@ def main(): name=dict(type='str', required=True, aliases=['pkg']), question=dict(type='str', aliases=['selection', 'setting']), vtype=dict(type='str', choices=['boolean', 'error', 'multiselect', 'note', 'password', 'seen', 'select', 'string', 'text', 'title']), - value=dict(type='str', aliases=['answer']), + value=dict(type='raw', aliases=['answer']), unseen=dict(type='bool', default=False), ), required_together=(['question', 'vtype', 'value'],), @@ -217,15 +219,25 @@ def main(): if vtype == 'boolean': value = to_text(value).lower() existing = to_text(prev[question]).lower() - - if vtype == 'password': + elif vtype == 'password': existing = get_password_value(module, pkg, question, vtype) + elif vtype == 'multiselect' and isinstance(value, list): + try: + value = sorted(value) + except TypeError as exc: + module.fail_json(msg="Invalid value provided for 'multiselect': %s" % to_native(exc)) + existing = sorted([i.strip() for i in existing.split(",")]) if value != existing: changed = True if changed: if not module.check_mode: + if vtype == 'multiselect' and isinstance(value, list): + try: + value = ", ".join(value) + except TypeError as exc: + module.fail_json(msg="Invalid value provided for 'multiselect': %s" % to_native(exc)) rc, msg, e = set_selection(module, pkg, question, vtype, value, unseen) if rc: module.fail_json(msg=e) diff --git a/test/integration/targets/debconf/tasks/main.yml b/test/integration/targets/debconf/tasks/main.yml index f923626868c..4021349f17d 100644 --- a/test/integration/targets/debconf/tasks/main.yml +++ b/test/integration/targets/debconf/tasks/main.yml @@ -66,6 +66,86 @@ assert: that: - not debconf_test2.changed + + - name: Multiselect value + debconf: + name: libnss-ldapd + question: libnss-ldapd/nsswitch + vtype: multiselect + value: + - passwd + - group + - shadow + register: debconf_multiselect_test + + - name: validate results for multiselect test + assert: + that: + - debconf_multiselect_test.changed + + - name: Multiselect value again (idempotency) + debconf: + name: libnss-ldapd + question: libnss-ldapd/nsswitch + vtype: multiselect + value: + - passwd + - group + - shadow + register: debconf_multiselect_test_idem + + - name: validate results for multiselect test (idempotency) + assert: + that: + - not debconf_multiselect_test_idem.changed + + - name: Multiselect value to check if ordered value + debconf: + name: libnss-ldapd + question: libnss-ldapd/nsswitch + vtype: multiselect + value: + - group + - shadow + - passwd + register: debconf_multiselect_test_idem_2 + + - name: validate results for multiselect test for ordered value + assert: + that: + - not debconf_multiselect_test_idem_2.changed + + - name: Multiselect value to check backward compatibility + debconf: + name: libnss-ldapd + question: libnss-ldapd/nsswitch + vtype: multiselect + value: group, shadow, passwd + register: debconf_multiselect_test_idem_3 + + - name: validate results for multiselect test for backward compatibility + assert: + that: + - debconf_multiselect_test_idem_3.changed + + - name: Multiselect value to check if value contains invalid user input + debconf: + name: libnss-ldapd + question: libnss-ldapd/nsswitch + vtype: multiselect + value: + - group + - 1 + - passwd + register: debconf_multiselect_test_idem_4 + ignore_errors: yes + + - name: validate results for multiselect test for invalid value + assert: + that: + - not debconf_multiselect_test_idem_4.changed + - '"Invalid value provided" in debconf_multiselect_test_idem_4.msg' + always: - name: uninstall debconf-utils apt: