namespace facts (#18445)

* namespace facts

always namespace facts, make the polluting of 'main' conditional on config

* updated to 2.4

* Update intro_configuration.rst
This commit is contained in:
Brian Coca 2017-03-15 20:12:16 -04:00 committed by scottb
parent 12f6beaebd
commit dd8d699981
6 changed files with 38 additions and 4 deletions

View file

@ -762,6 +762,27 @@ always default to the current user if this is not defined::
remote_user = root
.. _restrict_facts_namespace:
restrict_facts_namespace
========================
.. versionadded:: 2.4
This allows restricting facts in their own namespace (under ansible_facts) instead of pushing them into the main.
False by default. Can also be set via the environment variable `ANSIBLE_RESTRICT_FACTS`. Using `ansible_system` as an example:
When False::
- debug: var=ansible_system
When True::
- debug: var=ansible_facts.ansible_system
.. _retry_files_enabled:
retry_files_enabled

View file

@ -288,6 +288,10 @@
# only update this setting if you know how this works, otherwise it can break module execution
#network_group_modules=['eos', 'nxos', 'ios', 'iosxr', 'junos', 'vyos']
# This keeps facts from polluting the main namespace as variables.
# Setting to True keeps them under the ansible_facts namespace, the default is False
#restrict_facts_namespace: True
[privilege_escalation]
#become=True
#become_method=sudo

View file

@ -236,6 +236,7 @@ DEFAULT_VAR_COMPRESSION_LEVEL = get_config(p, DEFAULTS, 'var_compression_level',
DEFAULT_INTERNAL_POLL_INTERVAL = get_config(p, DEFAULTS, 'internal_poll_interval', None, 0.001, value_type='float')
ERROR_ON_MISSING_HANDLER = get_config(p, DEFAULTS, 'error_on_missing_handler', 'ANSIBLE_ERROR_ON_MISSING_HANDLER', True, value_type='boolean')
SHOW_CUSTOM_STATS = get_config(p, DEFAULTS, 'show_custom_stats', 'ANSIBLE_SHOW_CUSTOM_STATS', False, value_type='boolean')
NAMESPACE_FACTS = get_config(p, DEFAULTS, 'restrict_facts_namespace', 'ANSIBLE_RESTRICT_FACTS', False, value_type='boolean')
# static includes
DEFAULT_TASK_INCLUDES_STATIC = get_config(p, DEFAULTS, 'task_includes_static', 'ANSIBLE_TASK_INCLUDES_STATIC', False, value_type='boolean')

View file

@ -557,7 +557,9 @@ class TaskExecutor:
return failed_when_result
if 'ansible_facts' in result:
vars_copy.update(result['ansible_facts'])
if not C.NAMESPACE_FACTS:
vars_copy.update(result['ansible_facts'])
vars_copy.update({'ansible_facts': result['ansible_facts']})
# set the failed property if the result has a non-zero rc. This will be
# overridden below if the failed_when property is set
@ -596,7 +598,9 @@ class TaskExecutor:
variables[self._task.register] = wrap_var(result)
if 'ansible_facts' in result:
variables.update(result['ansible_facts'])
if not C.NAMESPACE_FACTS:
variables.update(result['ansible_facts'])
variables.update({'ansible_facts': result['ansible_facts']})
# save the notification target in the result, if it was specified, as
# this task may be running in a loop in which case the notification

View file

@ -733,7 +733,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
# actually execute
res = self._low_level_execute_command(cmd, sudoable=sudoable, in_data=in_data)
# parse the main result, also cleans up internal keys
# parse the main result
data = self._parse_returned_data(res)
#NOTE: INTERNAL KEYS ONLY ACCESSIBLE HERE

View file

@ -281,7 +281,11 @@ class VariableManager:
# finally, the facts caches for this host, if it exists
try:
host_facts = wrap_var(self._fact_cache.get(host.name, dict()))
all_vars = combine_vars(all_vars, host_facts)
if not C.NAMESPACE_FACTS:
# allow facts to polute main namespace
all_vars = combine_vars(all_vars, host_facts)
# always return namespaced facts
all_vars = combine_vars(all_vars, {'ansible_facts': host_facts})
except KeyError:
pass