Adding in hostvars to v2 and getting more integration tests working

pull/10075/head
James Cammarata 10 years ago
parent f9d451eb9c
commit 45212394ca

@ -186,6 +186,11 @@ class TaskExecutor:
# Now we do final validation on the task, which sets all fields to their final values # Now we do final validation on the task, which sets all fields to their final values
self._task.post_validate(variables) self._task.post_validate(variables)
# And filter out any fields which were set to default(omit), and got the omit token value
omit_token = variables.get('omit')
if omit_token is not None:
self._task.args = dict(filter(lambda x: x[1] != omit_token, self._task.args.iteritems()))
# Read some values from the task, so that we can modify them if need be # Read some values from the task, so that we can modify them if need be
retries = self._task.retries retries = self._task.retries
if retries <= 0: if retries <= 0:

@ -455,12 +455,12 @@ class Inventory(object):
return vars return vars
def get_variables(self, hostname, update_cached=False, vault_password=None): def get_vars(self, hostname, update_cached=False, vault_password=None):
host = self.get_host(hostname) host = self.get_host(hostname)
if not host: if not host:
raise Exception("host not found: %s" % hostname) raise Exception("host not found: %s" % hostname)
return host.get_variables() return host.get_vars()
def get_host_variables(self, hostname, update_cached=False, vault_password=None): def get_host_variables(self, hostname, update_cached=False, vault_password=None):

@ -1 +1 @@
Subproject commit 1dca81266289f365765b004ab8c0c62ee9d3467e Subproject commit 8ba8f5ef4d9361a03a690a0a71a28f3c56ce5bfb

@ -25,6 +25,7 @@ from ansible.errors import AnsibleError, AnsibleParserError
from ansible.parsing import DataLoader from ansible.parsing import DataLoader
from ansible.playbook.attribute import Attribute, FieldAttribute from ansible.playbook.attribute import Attribute, FieldAttribute
from ansible.playbook.play import Play from ansible.playbook.play import Play
from ansible.playbook.playbook_include import PlaybookInclude
from ansible.plugins import push_basedir from ansible.plugins import push_basedir

@ -18,3 +18,8 @@
# Make coding more python3-ish # Make coding more python3-ish
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
from ansible.playbook.base import Base
class PlaybookInclude(Base):
pass

@ -71,7 +71,8 @@ class AnsibleJ2Vars:
# HostVars is special, return it as-is, as is the special variable # HostVars is special, return it as-is, as is the special variable
# 'vars', which contains the vars structure # 'vars', which contains the vars structure
if isinstance(variable, dict) and varname == "vars": # or isinstance(var, HostVars): from ansible.vars.hostvars import HostVars
if isinstance(variable, dict) and varname == "vars" or isinstance(variable, HostVars):
return variable return variable
else: else:
return self._templar.template(variable) return self._templar.template(variable)

@ -23,11 +23,16 @@ import os
from collections import defaultdict from collections import defaultdict
try:
from hashlib import sha1
except ImportError:
from sha import sha as sha1
from ansible.parsing import DataLoader from ansible.parsing import DataLoader
from ansible.plugins.cache import FactCache from ansible.plugins.cache import FactCache
from ansible.template import Templar from ansible.template import Templar
from ansible.utils.debug import debug from ansible.utils.debug import debug
from ansible.vars.hostvars import HostVars
CACHED_VARS = dict() CACHED_VARS = dict()
@ -40,6 +45,9 @@ class VariableManager:
self._extra_vars = defaultdict(dict) self._extra_vars = defaultdict(dict)
self._host_vars_files = defaultdict(dict) self._host_vars_files = defaultdict(dict)
self._group_vars_files = defaultdict(dict) self._group_vars_files = defaultdict(dict)
self._inventory = None
self._omit_token = '__omit_place_holder__%s' % sha1(os.urandom(64)).hexdigest()
def _get_cache_entry(self, play=None, host=None, task=None): def _get_cache_entry(self, play=None, host=None, task=None):
play_id = "NONE" play_id = "NONE"
@ -66,6 +74,9 @@ class VariableManager:
assert isinstance(value, dict) assert isinstance(value, dict)
self._extra_vars = value.copy() self._extra_vars = value.copy()
def set_inventory(self, inventory):
self._inventory = inventory
def _merge_dicts(self, a, b): def _merge_dicts(self, a, b):
''' '''
Recursively merges dict b into a, so that keys Recursively merges dict b into a, so that keys
@ -177,8 +188,15 @@ class VariableManager:
all_vars = self._merge_dicts(all_vars, self._extra_vars) all_vars = self._merge_dicts(all_vars, self._extra_vars)
# FIXME: we need to move the special variables from the old runner # FIXME: make sure all special vars are here
# inject into here (HostVars?, groups, etc.) # Finally, we create special vars
if host and self._inventory is not None:
hostvars = HostVars(vars_manager=self, inventory=self._inventory, loader=loader)
all_vars['hostvars'] = hostvars
# the 'omit' value alows params to be left out if the variable they are based on is undefined
all_vars['omit'] = self._omit_token
CACHED_VARS[cache_entry] = all_vars CACHED_VARS[cache_entry] = all_vars
@ -229,7 +247,6 @@ class VariableManager:
(name, data) = self._load_inventory_file(path, loader) (name, data) = self._load_inventory_file(path, loader)
self._group_vars_files[name] = data self._group_vars_files[name] = data
def set_host_facts(self, host, facts): def set_host_facts(self, host, facts):
''' '''
Sets or updates the given facts for a host in the fact cache. Sets or updates the given facts for a host in the fact cache.

@ -0,0 +1,47 @@
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.template import Templar
__all__ = ['HostVars']
class HostVars(dict):
''' A special view of vars_cache that adds values from the inventory when needed. '''
def __init__(self, vars_manager, inventory, loader):
self._vars_manager = vars_manager
self._inventory = inventory
self._loader = loader
self._lookup = {}
#self.update(vars_cache)
def __getitem__(self, host_name):
if host_name not in self._lookup:
host = self._inventory.get_host(host_name)
result = self._vars_manager.get_vars(loader=self._loader, host=host)
#result.update(self._vars_cache.get(host, {}))
#templar = Templar(variables=self._vars_cache, loader=self._loader)
#self._lookup[host] = templar.template(result)
self._lookup[host_name] = result
return self._lookup[host_name]

@ -139,6 +139,7 @@ def main(args):
# create the inventory, and filter it based on the subset specified (if any) # create the inventory, and filter it based on the subset specified (if any)
inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=options.inventory) inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=options.inventory)
variable_manager.set_inventory(inventory)
# Note: slightly wrong, this is written so that implicit localhost # Note: slightly wrong, this is written so that implicit localhost
# (which is not returned in list_hosts()) is taken into account for # (which is not returned in list_hosts()) is taken into account for

Loading…
Cancel
Save