diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py index 9eadc80244..177990776d 100644 --- a/lib/ansible/cli/__init__.py +++ b/lib/ansible/cli/__init__.py @@ -180,9 +180,11 @@ class CLI(with_metaclass(ABCMeta, object)): ver = deprecated[1]['version'] display.deprecated("%s option, %s %s" % (name, why, alt), version=ver) - # warn about typing issues with configuration entries - for unable in C.config.UNABLE: - display.warning("Unable to set correct type for configuration entry: %s" % unable) + # Errors with configuration entries + if C.config.UNABLE: + for unable in C.config.UNABLE: + display.error("Unable to set correct type for configuration entry for %s: %s" % (unable, C.config.UNABLE[unable])) + raise AnsibleError("Invalid configuration settings") @staticmethod def split_vault_id(vault_id): diff --git a/lib/ansible/config/base.yml b/lib/ansible/config/base.yml index 020ffeb0c7..9911f72f64 100644 --- a/lib/ansible/config/base.yml +++ b/lib/ansible/config/base.yml @@ -746,7 +746,7 @@ DEFAULT_LOCAL_TMP: type: tmppath DEFAULT_LOG_PATH: name: Ansible log file path - default: '' + default: ~ description: File to which Ansible will log on the controller. When empty logging is disabled. env: [{name: ANSIBLE_LOG_PATH}] ini: diff --git a/lib/ansible/config/manager.py b/lib/ansible/config/manager.py index c0882a613d..36f8a6a3c5 100644 --- a/lib/ansible/config/manager.py +++ b/lib/ansible/config/manager.py @@ -60,7 +60,7 @@ def ensure_type(value, value_type, origin=None): if value_type in ('boolean', 'bool'): value = boolean(value, strict=False) - elif value: + elif value is not None: if value_type in ('integer', 'int'): value = int(value) @@ -166,7 +166,7 @@ def find_ini_config_file(): class ConfigManager(object): - UNABLE = [] + UNABLE = {} DEPRECATED = [] def __init__(self, conf_file=None, defs_file=None): @@ -281,7 +281,12 @@ class ConfigManager(object): def get_config_value(self, config, cfile=None, plugin_type=None, plugin_name=None, keys=None, variables=None): ''' wrapper ''' - value, _drop = self.get_config_value_and_origin(config, cfile=cfile, plugin_type=plugin_type, plugin_name=plugin_name, keys=keys, variables=variables) + + try: + value, _drop = self.get_config_value_and_origin(config, cfile=cfile, plugin_type=plugin_type, plugin_name=plugin_name, + keys=keys, variables=variables) + except Exception as e: + raise AnsibleError("Invalid settings supplied for %s: %s" % (config, to_native(e))) return value def get_config_value_and_origin(self, config, cfile=None, plugin_type=None, plugin_name=None, keys=None, variables=None): @@ -358,11 +363,8 @@ class ConfigManager(object): if plugin_type is None and isinstance(value, string_types) and (value.startswith('{{') and value.endswith('}}')): return value, origin - # ensure correct type - try: - value = ensure_type(value, defs[config].get('type'), origin=origin) - except Exception as e: - self.UNABLE.append(config) + # ensure correct type, can raise exceptoins on mismatched types + value = ensure_type(value, defs[config].get('type'), origin=origin) # deal with deprecation of the setting if 'deprecated' in defs[config] and origin != 'default': @@ -401,7 +403,13 @@ class ConfigManager(object): raise AnsibleOptionsError("Invalid configuration definition '%s': type is %s" % (to_native(config), type(defs[config]))) # get value and origin - value, origin = self.get_config_value_and_origin(config, configfile) + try: + value, origin = self.get_config_value_and_origin(config, configfile) + except Exception as e: + # when building constants.py we ignore invalid configs + # CLI takes care of warnings once 'display' is loaded + self.UNABLE[config] = to_text(e) + continue # set the constant self.data.update_setting(Setting(config, value, origin, defs[config].get('type', 'string'))) diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index e922b506e0..3db9665423 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -185,6 +185,7 @@ for setting in config.data.get_settings(): pass # not a python data structure except: pass # not templatable - value = ensure_type(value, setting.name) + + value = ensure_type(value, setting.type) set_constant(setting.name, value) diff --git a/lib/ansible/utils/display.py b/lib/ansible/utils/display.py index 3724c81bd6..2f21646467 100644 --- a/lib/ansible/utils/display.py +++ b/lib/ansible/utils/display.py @@ -57,15 +57,15 @@ class FilterBlackList(logging.Filter): logger = None # TODO: make this a logging callback instead -if C.DEFAULT_LOG_PATH: +if getattr(C, 'DEFAULT_LOG_PATH'): path = C.DEFAULT_LOG_PATH - if (os.path.exists(path) and os.access(path, os.W_OK)) or os.access(os.path.dirname(path), os.W_OK): + if path and (os.path.exists(path) and os.access(path, os.W_OK)) or os.access(os.path.dirname(path), os.W_OK): logging.basicConfig(filename=path, level=logging.DEBUG, format='%(asctime)s %(name)s %(message)s') mypid = str(os.getpid()) user = getpass.getuser() logger = logging.getLogger("p=%s u=%s | " % (mypid, user)) for handler in logging.root.handlers: - handler.addFilter(FilterBlackList(C.DEFAULT_LOG_FILTER)) + handler.addFilter(FilterBlackList(getattr(C, 'DEFAULT_LOG_FILTER', []))) else: print("[WARNING]: log file at %s is not writeable and we cannot create it, aborting\n" % path, file=sys.stderr)