Allow inventory to be a directory containing other inventories
This commit is contained in:
parent
647cd0141c
commit
d9c6b60b24
3 changed files with 79 additions and 1 deletions
|
@ -16,6 +16,7 @@ Core Features
|
||||||
* a new chroot connection type
|
* a new chroot connection type
|
||||||
* module common code now has basic type checking (and casting) capability
|
* module common code now has basic type checking (and casting) capability
|
||||||
* module common now supports a 'no_log' attribute to mark a field as not to be syslogged
|
* module common now supports a 'no_log' attribute to mark a field as not to be syslogged
|
||||||
|
* inventory can now point to a directory containing multiple scripts/hosts files
|
||||||
|
|
||||||
Modules Added:
|
Modules Added:
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import subprocess
|
||||||
import ansible.constants as C
|
import ansible.constants as C
|
||||||
from ansible.inventory.ini import InventoryParser
|
from ansible.inventory.ini import InventoryParser
|
||||||
from ansible.inventory.script import InventoryScript
|
from ansible.inventory.script import InventoryScript
|
||||||
|
from ansible.inventory.dir import InventoryDirectory
|
||||||
from ansible.inventory.group import Group
|
from ansible.inventory.group import Group
|
||||||
from ansible.inventory.host import Host
|
from ansible.inventory.host import Host
|
||||||
from ansible import errors
|
from ansible import errors
|
||||||
|
@ -78,7 +79,10 @@ class Inventory(object):
|
||||||
else:
|
else:
|
||||||
all.add_host(Host(x))
|
all.add_host(Host(x))
|
||||||
elif os.path.exists(host_list):
|
elif os.path.exists(host_list):
|
||||||
if utils.is_executable(host_list):
|
if os.path.isdir(host_list):
|
||||||
|
self.parser = InventoryDirectory(filename=host_list)
|
||||||
|
self.groups = self.parser.groups.values()
|
||||||
|
elif utils.is_executable(host_list):
|
||||||
self.parser = InventoryScript(filename=host_list)
|
self.parser = InventoryScript(filename=host_list)
|
||||||
self.groups = self.parser.groups.values()
|
self.groups = self.parser.groups.values()
|
||||||
else:
|
else:
|
||||||
|
|
73
lib/ansible/inventory/dir.py
Normal file
73
lib/ansible/inventory/dir.py
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
# (c) 2013, Daniel Hokka Zakrisson <daniel@hozac.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 ansible.constants as C
|
||||||
|
from ansible.inventory.host import Host
|
||||||
|
from ansible.inventory.group import Group
|
||||||
|
from ansible.inventory.ini import InventoryParser
|
||||||
|
from ansible.inventory.script import InventoryScript
|
||||||
|
from ansible import utils
|
||||||
|
from ansible import errors
|
||||||
|
|
||||||
|
class InventoryDirectory(object):
|
||||||
|
''' Host inventory parser for ansible using a directory of inventories. '''
|
||||||
|
|
||||||
|
def __init__(self, filename=C.DEFAULT_HOST_LIST):
|
||||||
|
self.names = os.listdir(filename)
|
||||||
|
self.names.sort()
|
||||||
|
self.directory = filename
|
||||||
|
self.parsers = []
|
||||||
|
self.hosts = {}
|
||||||
|
self.groups = {}
|
||||||
|
for i in self.names:
|
||||||
|
if i.endswith("~") or i.endswith(".orig") or i.endswith(".bak"):
|
||||||
|
continue
|
||||||
|
fullpath = os.path.join(self.directory, i)
|
||||||
|
if os.path.isdir(fullpath):
|
||||||
|
parser = InventoryDirectory(filename=fullpath)
|
||||||
|
elif utils.is_executable(fullpath):
|
||||||
|
parser = InventoryScript(filename=fullpath)
|
||||||
|
else:
|
||||||
|
parser = InventoryParser(filename=fullpath)
|
||||||
|
self.parsers.append(parser)
|
||||||
|
# This takes a lot of code because we can't directly use any of the objects, as they have to blend
|
||||||
|
for name, group in parser.groups.iteritems():
|
||||||
|
if name not in self.groups:
|
||||||
|
self.groups[name] = Group(name)
|
||||||
|
for k, v in group.get_variables().iteritems():
|
||||||
|
self.groups[name].set_variable(k, v)
|
||||||
|
for host in group.get_hosts():
|
||||||
|
if host.name not in self.hosts:
|
||||||
|
self.hosts[host.name] = Host(host.name)
|
||||||
|
for k, v in host.get_variables().iteritems():
|
||||||
|
self.hosts[host.name].set_variable(k, v)
|
||||||
|
self.groups[name].add_host(self.hosts[host.name])
|
||||||
|
# This needs to be a second loop to ensure all the parent groups exist
|
||||||
|
for name, group in parser.groups.iteritems():
|
||||||
|
for ancestor in group.get_ancestors():
|
||||||
|
self.groups[ancestor.name].add_child_group(self.groups[name])
|
||||||
|
|
||||||
|
def get_host_variables(self, host):
|
||||||
|
""" Gets additional host variables from all inventories """
|
||||||
|
vars = {}
|
||||||
|
for i in self.parsers:
|
||||||
|
vars.update(i.get_host_variables(host))
|
||||||
|
return vars
|
||||||
|
|
Loading…
Reference in a new issue