exclude lookup_terms from config errors (#41740)

* exclude lookup_terms from config errors
* moved direct
This commit is contained in:
Brian Coca 2018-06-21 17:50:24 -04:00 committed by GitHub
parent 06b73ff8f1
commit 0102e42272
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 71 deletions

View file

@ -31,6 +31,8 @@ from ansible.utils.path import makedirs_safe
Plugin = namedtuple('Plugin', 'name type') Plugin = namedtuple('Plugin', 'name type')
Setting = namedtuple('Setting', 'name value origin type') Setting = namedtuple('Setting', 'name value origin type')
INTERNAL_DEFS = {'lookup': ('_terms',)}
# FIXME: see if we can unify in module_utils with similar function used by argspec # FIXME: see if we can unify in module_utils with similar function used by argspec
def ensure_type(value, value_type, origin=None): def ensure_type(value, value_type, origin=None):
@ -219,7 +221,7 @@ class ConfigManager(object):
with open(cfile, 'rb') as f: with open(cfile, 'rb') as f:
try: try:
cfg_text = to_text(f.read(), errors='surrogate_or_strict') cfg_text = to_text(f.read(), errors='surrogate_or_strict')
except UnicodeError: except UnicodeError as e:
raise AnsibleOptionsError("Error reading config file(%s) because the config file was not utf8 encoded: %s" % (cfile, to_native(e))) raise AnsibleOptionsError("Error reading config file(%s) because the config file was not utf8 encoded: %s" % (cfile, to_native(e)))
try: try:
if PY3: if PY3:
@ -240,12 +242,12 @@ class ConfigManager(object):
''' Load YAML Config Files in order, check merge flags, keep origin of settings''' ''' Load YAML Config Files in order, check merge flags, keep origin of settings'''
pass pass
def get_plugin_options(self, plugin_type, name, keys=None, variables=None): def get_plugin_options(self, plugin_type, name, keys=None, variables=None, direct=None):
options = {} options = {}
defs = self.get_configuration_definitions(plugin_type, name) defs = self.get_configuration_definitions(plugin_type, name)
for option in defs: for option in defs:
options[option] = self.get_config_value(option, plugin_type=plugin_type, plugin_name=name, keys=keys, variables=variables) options[option] = self.get_config_value(option, plugin_type=plugin_type, plugin_name=name, keys=keys, variables=variables, direct=direct)
return options return options
@ -289,17 +291,17 @@ class ConfigManager(object):
return value, origin return value, origin
def get_config_value(self, config, cfile=None, plugin_type=None, plugin_name=None, keys=None, variables=None): def get_config_value(self, config, cfile=None, plugin_type=None, plugin_name=None, keys=None, variables=None, direct=None):
''' wrapper ''' ''' wrapper '''
try: try:
value, _drop = self.get_config_value_and_origin(config, cfile=cfile, plugin_type=plugin_type, plugin_name=plugin_name, value, _drop = self.get_config_value_and_origin(config, cfile=cfile, plugin_type=plugin_type, plugin_name=plugin_name,
keys=keys, variables=variables) keys=keys, variables=variables, direct=direct)
except Exception as e: except Exception as e:
raise AnsibleError("Invalid settings supplied for %s: %s" % (config, to_native(e))) raise AnsibleError("Invalid settings supplied for %s: %s" % (config, to_native(e)))
return value return value
def get_config_value_and_origin(self, config, cfile=None, plugin_type=None, plugin_name=None, keys=None, variables=None): def get_config_value_and_origin(self, config, cfile=None, plugin_type=None, plugin_name=None, keys=None, variables=None, direct=None):
''' Given a config key figure out the actual value and report on the origin of the settings ''' ''' Given a config key figure out the actual value and report on the origin of the settings '''
if cfile is None: if cfile is None:
@ -318,13 +320,20 @@ class ConfigManager(object):
defs = self._plugins[plugin_type][plugin_name] defs = self._plugins[plugin_type][plugin_name]
if config in defs: if config in defs:
# direct setting via plugin arguments, can set to None so we bypass rest of processing/defaults
if direct and config in direct:
value = direct[config]
origin = 'Direct'
else:
# Use 'variable overrides' if present, highest precedence, but only present when querying running play # Use 'variable overrides' if present, highest precedence, but only present when querying running play
if variables and defs[config].get('vars'): if variables and defs[config].get('vars'):
value, origin = self._loop_entries(variables, defs[config]['vars']) value, origin = self._loop_entries(variables, defs[config]['vars'])
origin = 'var: %s' % origin origin = 'var: %s' % origin
# use playbook keywords if you have em # use playbook keywords if you have em
if value is None and keys: if value is None and keys and defs[config].get('keywords'):
value, origin = self._loop_entries(keys, defs[config]['keywords']) value, origin = self._loop_entries(keys, defs[config]['keywords'])
origin = 'keyword: %s' % origin origin = 'keyword: %s' % origin
@ -365,6 +374,7 @@ class ConfigManager(object):
if plugin_name: if plugin_name:
entry += 'plugin: %s ' % plugin_name entry += 'plugin: %s ' % plugin_name
entry += 'setting: %s ' % config entry += 'setting: %s ' % config
if not plugin_type or config not in INTERNAL_DEFS.get(plugin_type, {}):
raise AnsibleError("No setting was provided for required configuration %s" % (entry)) raise AnsibleError("No setting was provided for required configuration %s" % (entry))
else: else:
value = defs[config].get('default') value = defs[config].get('default')

View file

@ -73,14 +73,7 @@ class AnsiblePlugin(with_metaclass(ABCMeta, object)):
if not self._options: if not self._options:
# load config options if we have not done so already, if vars provided we should be mostly done # load config options if we have not done so already, if vars provided we should be mostly done
self._options = C.config.get_plugin_options(get_plugin_class(self), self._load_name, keys=task_keys, variables=var_options) self._options = C.config.get_plugin_options(get_plugin_class(self), self._load_name, keys=task_keys, variables=var_options, direct=direct)
# they can be direct options overriding config
if direct:
for k in self._options:
if k in direct:
self.set_option(k, direct[k])
# allow extras/wildcards from vars that are not directly consumed in configuration # allow extras/wildcards from vars that are not directly consumed in configuration
if self.allow_extras and var_options and '_extras' in var_options: if self.allow_extras and var_options and '_extras' in var_options:
self.set_option('_extras', var_options['_extras']) self.set_option('_extras', var_options['_extras'])

View file

@ -98,13 +98,7 @@ class CallbackBase(AnsiblePlugin):
''' '''
# load from config # load from config
self._plugin_options = C.config.get_plugin_options(get_plugin_class(self), self._load_name, keys=task_keys, variables=var_options) self._plugin_options = C.config.get_plugin_options(get_plugin_class(self), self._load_name, keys=task_keys, variables=var_options, direct=direct)
# or parse specific options
if direct:
for k in direct:
if k in self._plugin_options:
self.set_option(k, direct[k])
def _dump_results(self, result, indent=None, sort_keys=True, keep_invocation=False): def _dump_results(self, result, indent=None, sort_keys=True, keep_invocation=False):

View file

@ -69,7 +69,6 @@ class LookupModule(LookupBase):
self._templar.set_available_variables(variables) self._templar.set_available_variables(variables)
myvars = getattr(self._templar, '_available_variables', {}) myvars = getattr(self._templar, '_available_variables', {})
self.set_option('_terms', terms)
self.set_options(direct=kwargs) self.set_options(direct=kwargs)
default = self.get_option('default') default = self.get_option('default')