Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support vars plugins in collections #61078

wants to merge 17 commits into
base: devel

move var plugins hanlding to own file

	- add whitelisting
	- add 'stage' configuration ('all', 'task', 'inventory') for users to control when they execute.
	- TODO:
		- update ansible-inventory (when playbook dir) and InventoryManager to use them
		- update config, default to host_group_vars, update plugin to use 'stage' config
  • Loading branch information...
bcoca authored and s-hertel committed Aug 14, 2019
commit 8929edc4b652f92023039201a68c91e4eb6f6540
@@ -35,17 +35,18 @@
from ansible.errors import AnsibleError, AnsibleParserError, AnsibleUndefinedVariable, AnsibleFileNotFound, AnsibleAssertionError, AnsibleTemplateError
from import Host
from ansible.inventory.helpers import sort_groups, get_group_vars
from ansible.module_utils._text import to_bytes, to_text
from ansible.module_utils._text import to_text
from ansible.module_utils.common._collections_compat import Mapping, MutableMapping, Sequence
from ansible.module_utils.six import iteritems, text_type, string_types
from ansible.plugins.loader import lookup_loader, vars_loader
from ansible.plugins.loader import lookup_loader
from ansible.vars.fact_cache import FactCache
from ansible.template import Templar
from ansible.utils.display import Display
from ansible.utils.listify import listify_lookup_plugin_terms
from ansible.utils.vars import combine_vars, load_extra_vars, load_options_vars
from ansible.utils.unsafe_proxy import wrap_var
from ansible.vars.clean import namespace_facts, clean_facts
from ansible.vars.plugins import get_vars_from_inventory_sources, get_vars_from_path

display = Display()

@@ -231,25 +232,13 @@ def _get_plugin_vars(plugin, path, entities):
# internal fuctions that actually do the work
def _plugins_inventory(entities):
''' merges all entities by inventory source '''
data = {}
for inventory_dir in self._inventory._sources:
if ',' in inventory_dir and not os.path.exists(inventory_dir): # skip host lists
elif not os.path.isdir(to_bytes(inventory_dir)): # always pass 'inventory directory'
inventory_dir = os.path.dirname(inventory_dir)

for plugin in vars_loader.all():

data = combine_vars(data, _get_plugin_vars(plugin, inventory_dir, entities))
return data
return get_vars_from_inventory_sources(self._loader, self._inventory._sources, entities, 'task')

def _plugins_play(entities):
''' merges all entities adjacent to play '''
data = {}
for plugin in vars_loader.all():

for path in basedirs:
data = combine_vars(data, _get_plugin_vars(plugin, path, entities))
for path in basedirs:
data = combine_vars(data, get_vars_from_path(self._loader, path, entities, 'task'))
return data

# configurable functions that are sortable via config, rememer to add to _ALLOWED if expanding this list
@@ -0,0 +1,73 @@
# Copyright (c) 2018 Ansible Project
# GNU General Public License v3.0+ (see COPYING or

# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

import os

from ansible import constants as C
from ansible.errors import AnsibleError
from import Host
from ansible.module_utils._text import to_bytes
from ansible.plugins.loader import vars_loader
from ansible.utils.display import Display
from ansible.utils.vars import combine_vars

display = Display()

def get_plugin_vars(loader, plugin, path, entities):

data = {}
data = plugin.get_vars(loader, path, entities)
except AttributeError:
for entity in entities:
if isinstance(entity, Host):
except AttributeError:
if hasattr(plugin, 'run'):
raise AnsibleError("Cannot use v1 type vars plugin %s from %s" % (plugin._load_name, plugin._original_path))
raise AnsibleError("Invalid vars plugin %s from %s" % (plugin._load_name, plugin._original_path))
return data

def get_vars_from_path(loader, path, entities, stage):

data = {}
for plugin in vars_loader.all():
pobj = vars_loader.get(plugin)

if pobj.get('REQUIRES_WHITELIST', False) and plugin not in C.ENABLED_VARS_PLUGINS:
# skip plugins that require whitelisting but are not whitelisted
# 'legacy' plugins always run

if hasattr(pobj, 'get_option') and pobj.get_option('stage') not in ('all', stage):

data = combine_vars(data, get_plugin_vars(loader, pobj, path, entities))

return data

def get_vars_from_inventory_sources(loader, sources, entities, stage):

data = {}
for path in sources:

if ',' in path and not os.path.exists(path): # skip host lists
elif not os.path.isdir(to_bytes(path)):
# always pass the directory of the inventory source file
path = os.path.dirname(path)

data = combine_vars(data, get_vars_from_path(loader, path, entities, stage))

return data
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.