fix config manager list loption with choices (#74267)

fixes #74225

  Co-authored-by: Kim Nørring <github@norring.dk>
This commit is contained in:
Brian Coca 2021-04-15 15:07:43 -04:00 committed by GitHub
parent 0a7670d1f7
commit b91749d671
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 1 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- plugin config now allows list type options to have multiple valid choices (#74225).

View file

@ -552,7 +552,15 @@ class ConfigManager(object):
# deal with restricted values
if value is not None and 'choices' in defs[config] and defs[config]['choices'] is not None:
if value not in defs[config]['choices']:
invalid_choices = True # assume the worst!
if defs[config].get('type') == 'list':
# for a list type, compare all values in type are allowed
invalid_choices = not all(choice in defs[config]['choices'] for choice in value)
else:
# these should be only the simple data types (string, int, bool, float, etc) .. ignore dicts for now
invalid_choices = value not in defs[config]['choices']
if invalid_choices:
raise AnsibleOptionsError('Invalid value "%s" for configuration option "%s", valid values are: %s' %
(value, to_native(_get_entry(plugin_type, plugin_name, config)), defs[config]['choices']))

View file

@ -0,0 +1,51 @@
# (c) 2021 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = """
name: bogus
author: Ansible Core Team
version_added: histerical
short_description: returns what you gave it
description:
- this is mostly a noop
options:
_terms:
description: stuff to pass through
test_list:
description: does nothihng, just for testing values
type: list
choices:
- Dan
- Yevgeni
- Carla
- Manuela
"""
EXAMPLES = """
- name: like some other plugins, this is mostly useless
debug: msg={{ q('bogus', [1,2,3])}}
"""
RETURN = """
_list:
description: basically the same as you fed in
type: list
elements: raw
"""
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
self.set_options(var_options=variables, direct=kwargs)
dump = self.get_option('test_list')
return terms

View file

@ -18,3 +18,6 @@ ANSIBLE_CONFIG=nonexistent.cfg ansible-config dump --only-changed -v | grep 'No
# https://github.com/ansible/ansible/pull/73715
ANSIBLE_CONFIG=inline_comment_ansible.cfg ansible-config dump --only-changed | grep "'ansibull'"
# test the config option validation
ansible-playbook validation.yml "$@"

View file

@ -0,0 +1,17 @@
- hosts: localhost
gather_facts: false
tasks:
- name: does nothing but an empty assign, should fail only if lookup gets invalid options
set_fact: whatever={{ lookup('bogus', 1, test_list=['Dan', 'Manuela']) }}
- name: now pass invalid option and fail!
set_fact: whatever={{ lookup('bogus', 1, test_list=['Dan', 'Manuela', 'Yoko']) }}
register: bad_input
ignore_errors: true
- name: ensure it fails as expected
assert:
that:
- bad_input is failed
- '"Invalid value " in bad_input.msg'
- '"valid values are:" in bad_input.msg'