Skip to content

Commit

Permalink
namespace facts (ansible#18445)
Browse files Browse the repository at this point in the history
* namespace facts

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

* updated to 2.4

* Update intro_configuration.rst
  • Loading branch information
bcoca authored and dharmabumstead committed Mar 16, 2017
1 parent 12f6bea commit dd8d699
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 4 deletions.
21 changes: 21 additions & 0 deletions docs/docsite/rst/intro_configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions examples/ansible.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions lib/ansible/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ def load_config_file():
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')
Expand Down
8 changes: 6 additions & 2 deletions lib/ansible/executor/task_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,9 @@ def _evaluate_failed_when_result(result):
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
Expand Down Expand Up @@ -596,7 +598,9 @@ def _evaluate_failed_when_result(result):
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
Expand Down
2 changes: 1 addition & 1 deletion lib/ansible/plugins/action/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ def _execute_module(self, module_name=None, module_args=None, tmp=None, task_var
# 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
Expand Down
6 changes: 5 additions & 1 deletion lib/ansible/vars/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,11 @@ def get_vars(self, loader, play=None, host=None, task=None, include_hostvars=Tru
# 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

Expand Down

0 comments on commit dd8d699

Please sign in to comment.