Make group_vars and host_vars available to usr/bin/ansible, and make vars_plugins exist

pull/1648/head
Michael DeHaan 12 years ago
parent e04dab904a
commit 6ba30170dd

@ -74,6 +74,14 @@ remote_port=22
# Example: ansible_managed = DONT TOUCH {file}: call {uid} at {host} for changes
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
# additional plugin paths for non-core plugins
action_plugins = /usr/share/ansible_plugins/action_plugins
callback_plugins = /usr/share/ansible_plugins/callback_plugins
connection_plugins = /usr/share/ansible_plugins/connection_plugins
lookup_plugins = /usr/share/ansible_plugins/lookup_plugins
inventory_plugins = /usr/share/ansible_plugins/inventory_plugins
[paramiko_connection]
# nothing to configure yet

@ -87,6 +87,7 @@ DEFAULT_ACTION_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'acti
DEFAULT_CALLBACK_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'callback_plugins', None, '/usr/share/ansible_plugins/callback_plugins'))
DEFAULT_CONNECTION_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'connection_plugins', None, '/usr/share/ansible_plugins/connection_plugins'))
DEFAULT_LOOKUP_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'lookup_plugins', None, '/usr/share/ansible_plugins/lookup_plugins'))
DEFAULT_VARS_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'vars_plugins', None, '/usr/share/ansible_plugins/vars_plugins'))
# non-configurable things
DEFAULT_REMOTE_PASS = None

@ -29,13 +29,20 @@ from ansible.inventory.host import Host
from ansible import errors
from ansible import utils
# FIXME, adapt.
dirname = os.path.dirname(__file__)
vars_plugin_list = utils.import_plugins(os.path.join(dirname, 'vars_plugins'))
for i in reversed(C.DEFAULT_VARS_PLUGIN_PATH.split(os.pathsep)):
vars_plugin_list.update(utils.import_plugins(i))
class Inventory(object):
"""
Host inventory for ansible.
"""
__slots__ = [ 'host_list', 'groups', '_restriction', '_also_restriction', '_subset', '_is_script',
'parser', '_vars_per_host', '_vars_per_group', '_hosts_cache', '_groups_list' ]
'parser', '_vars_per_host', '_vars_per_group', '_hosts_cache', '_groups_list',
'_vars_plugins' ]
def __init__(self, host_list=C.DEFAULT_HOST_LIST):
@ -88,6 +95,8 @@ class Inventory(object):
else:
raise errors.AnsibleError("YAML inventory support is deprecated in 0.6 and removed in 0.7, see the migration script in examples/scripts in the git checkout")
self._vars_plugins = [ i.VarsModule(self) for i in vars_plugin_list.values() ]
def _match(self, str, pattern_str):
return fnmatch.fnmatch(str, pattern_str)
@ -270,6 +279,11 @@ class Inventory(object):
if host is None:
raise errors.AnsibleError("host not found: %s" % hostname)
vars = {}
for ip in self._vars_plugins:
updated = ip.run(host)
vars.update(updated)
if self._is_script:
cmd = subprocess.Popen(
[self.host_list,"--host",hostname],
@ -284,10 +298,10 @@ class Inventory(object):
results['inventory_hostname_short'] = hostname.split('.')[0]
groups = [ g.name for g in host.get_groups() if g.name != 'all' ]
results['group_names'] = sorted(groups)
return results
vars.update(results)
else:
return host.get_variables()
vars.update(host.get_variables())
return vars
def add_group(self, group):
self.groups.append(group)

@ -62,3 +62,5 @@ class Host(object):
groups = self.get_groups()
results['group_names'] = sorted([ g.name for g in groups if g.name != 'all'])
return results

@ -0,0 +1,61 @@
# (c) 2012, 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/>.
import os
import glob
from ansible import utils
class VarsModule(object):
def __init__(self, inventory):
self.inventory = inventory
def run(self, host):
# return the inventory variables for the host
inventory = self.inventory
#hostrec = inventory.get_host(host)
groupz = sorted(inventory.groups_for_host(host.name), key=lambda g: g.depth)
groups = [ g.name for g in groupz ]
basedir = inventory.basedir()
if basedir is None:
# could happen when inventory is passed in via the API
return
results = {}
# load vars in playbook_dir/group_vars/name_of_group
for x in groups:
path = os.path.join(basedir, "group_vars/%s" % x)
if os.path.exists(path):
data = utils.parse_yaml_from_file(path)
if type(data) != dict:
raise errors.AnsibleError("%s must be stored as a dictionary/hash" % path)
results.update(data)
# load vars in playbook_dir/group_vars/name_of_host
path = os.path.join(basedir, "host_vars/%s" % host.name)
if os.path.exists(path):
data = utils.parse_yaml_from_file(path)
if type(data) != dict:
raise errors.AnsibleError("%s must be stored as a dictionary/hash" % path)
results.update(data)
return results

@ -242,29 +242,6 @@ class Play(object):
if type(self.vars_files) != list:
self.vars_files = [ self.vars_files ]
if (host is not None):
self.playbook.SETUP_CACHE[host].update(self.vars)
inventory = self.playbook.inventory
hostrec = inventory.get_host(host)
groupz = sorted(inventory.groups_for_host(host), key=lambda g: g.depth)
groups = [ g.name for g in groupz ]
basedir = inventory.basedir()
if basedir is not None:
for x in groups:
path = os.path.join(basedir, "group_vars/%s" % x)
if os.path.exists(path):
data = utils.parse_yaml_from_file(path)
if type(data) != dict:
raise errors.AnsibleError("%s must be stored as a dictionary/hash" % path)
self.playbook.SETUP_CACHE[host].update(data)
path = os.path.join(basedir, "host_vars/%s" % hostrec.name)
if os.path.exists(path):
data = utils.parse_yaml_from_file(path)
if type(data) != dict:
raise errors.AnsibleError("%s must be stored as a dictionary/hash" % path)
self.playbook.SETUP_CACHE[host].update(data)
for filename in self.vars_files:
if type(filename) == list:

@ -26,6 +26,7 @@ setup(name='ansible',
packages=[
'ansible',
'ansible.inventory',
'ansible.inventory.var_plugins',
'ansible.playbook',
'ansible.runner',
'ansible.runner.action_plugins',

@ -180,8 +180,6 @@ class TestPlaybook(unittest.TestCase):
runner_callbacks=test_callbacks
)
playbook.run()
assert playbook.SETUP_CACHE['host1'] == {'attr2': 2, 'attr1': 1}
assert playbook.SETUP_CACHE['host2'] == {'attr2': 2}
def test_yaml_hosts_list(self):
# Make sure playbooks support hosts: [host1, host2]

Loading…
Cancel
Save