Merge pull request #1687 from dhozac/allow-grouping-in-external-inventory
Allow inventory scripts to define groups of groups and group vars
This commit is contained in:
commit
ffac7ce2f9
3 changed files with 43 additions and 20 deletions
|
@ -100,16 +100,35 @@ It's possible to write an external inventory script in any language. If you are
|
||||||
Script Conventions
|
Script Conventions
|
||||||
``````````````````
|
``````````````````
|
||||||
|
|
||||||
When the external node script is called with the single argument '--list', the script must return a JSON hash/dictionary of all the groups to be managed, with a list of each host/IP as the value for each hash/dictionary element, like so::
|
When the external node script is called with the single argument '--list', the script must return a JSON hash/dictionary of all the groups to be managed.
|
||||||
|
Each group's value should be either a hash/dictionary containing a list of each host/IP, potential child groups, and potential group variables, or
|
||||||
|
simply a list of host/IP addresses, like so::
|
||||||
|
|
||||||
{
|
{
|
||||||
'databases' : [ 'host1.example.com', 'host2.example.com' ],
|
'databases' : {
|
||||||
|
'hosts' : [ 'host1.example.com', 'host2.example.com' ],
|
||||||
|
'vars' : {
|
||||||
|
'a' : true
|
||||||
|
}
|
||||||
|
},
|
||||||
'webservers' : [ 'host2.example.com', 'host3.example.com' ],
|
'webservers' : [ 'host2.example.com', 'host3.example.com' ],
|
||||||
'atlanta' : [ 'host1.example.com', 'host4.example.com', 'host5.example.com' ]
|
'atlanta' : {
|
||||||
|
'hosts' : [ 'host1.example.com', 'host4.example.com', 'host5.example.com' ],
|
||||||
|
'vars' : {
|
||||||
|
'b' : false
|
||||||
|
},
|
||||||
|
'children': [ 'marietta', '5points' ],
|
||||||
|
},
|
||||||
|
'marietta' : [ 'host6.example.com' ],
|
||||||
|
'5points' : [ 'host7.example.com' ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.. versionadded: 1.0
|
||||||
|
|
||||||
|
Before version 1.0, each group could only have a list of hostnames/IP addresses, like the webservers, marietta, and 5points groups above.
|
||||||
|
|
||||||
When called with the arguments '--host <hostname>' (where <hostname> is a host from above), the script must return either an empty JSON
|
When called with the arguments '--host <hostname>' (where <hostname> is a host from above), the script must return either an empty JSON
|
||||||
hash/dictionary, or a list of key/value variables to make available to templates or playbooks. Returning variables is optional,
|
hash/dictionary, or a hash/dictionary of variables to make available to templates and playbooks. Returning variables is optional,
|
||||||
if the script does not wish to do this, returning an empty hash/dictionary is the way to go::
|
if the script does not wish to do this, returning an empty hash/dictionary is the way to go::
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -278,6 +278,7 @@ class Inventory(object):
|
||||||
if updated is not None:
|
if updated is not None:
|
||||||
vars.update(updated)
|
vars.update(updated)
|
||||||
|
|
||||||
|
vars.update(host.get_variables())
|
||||||
if self._is_script:
|
if self._is_script:
|
||||||
cmd = [self.host_list,"--host",hostname]
|
cmd = [self.host_list,"--host",hostname]
|
||||||
try:
|
try:
|
||||||
|
@ -287,14 +288,7 @@ class Inventory(object):
|
||||||
(out, err) = sp.communicate()
|
(out, err) = sp.communicate()
|
||||||
results = utils.parse_json(out)
|
results = utils.parse_json(out)
|
||||||
|
|
||||||
# FIXME: this is a bit redundant with host.py and should share code
|
|
||||||
results['inventory_hostname'] = hostname
|
|
||||||
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)
|
|
||||||
vars.update(results)
|
vars.update(results)
|
||||||
else:
|
|
||||||
vars.update(host.get_variables())
|
|
||||||
return vars
|
return vars
|
||||||
|
|
||||||
def add_group(self, group):
|
def add_group(self, group):
|
||||||
|
|
|
@ -45,15 +45,25 @@ class InventoryScript(object):
|
||||||
all=Group('all')
|
all=Group('all')
|
||||||
groups = dict(all=all)
|
groups = dict(all=all)
|
||||||
group = None
|
group = None
|
||||||
for (group_name, hosts) in self.raw.items():
|
for (group_name, data) in self.raw.items():
|
||||||
group = groups[group_name] = Group(group_name)
|
group = groups[group_name] = Group(group_name)
|
||||||
host = None
|
host = None
|
||||||
for hostname in hosts:
|
if not isinstance(data, dict):
|
||||||
|
data = {'hosts': data}
|
||||||
|
if 'hosts' in data:
|
||||||
|
for hostname in data['hosts']:
|
||||||
if not hostname in all_hosts:
|
if not hostname in all_hosts:
|
||||||
all_hosts[hostname] = Host(hostname)
|
all_hosts[hostname] = Host(hostname)
|
||||||
host = all_hosts[hostname]
|
host = all_hosts[hostname]
|
||||||
group.add_host(host)
|
group.add_host(host)
|
||||||
# FIXME: hack shouldn't be needed
|
if 'vars' in data:
|
||||||
all.add_host(host)
|
for k, v in data['vars'].iteritems():
|
||||||
|
group.set_variable(k, v)
|
||||||
all.add_child_group(group)
|
all.add_child_group(group)
|
||||||
|
# Separate loop to ensure all groups are defined
|
||||||
|
for (group_name, data) in self.raw.items():
|
||||||
|
if isinstance(data, dict) and 'children' in data:
|
||||||
|
for child_name in data['children']:
|
||||||
|
if child_name in groups:
|
||||||
|
groups[group_name].add_child_group(groups[child_name])
|
||||||
return groups
|
return groups
|
||||||
|
|
Loading…
Reference in a new issue