diff --git a/lib/ansible/inventory/script.py b/lib/ansible/inventory/script.py index 915aaa18035..d91ecdf3ad7 100644 --- a/lib/ansible/inventory/script.py +++ b/lib/ansible/inventory/script.py @@ -42,6 +42,8 @@ class InventoryScript(object): raise errors.AnsibleError("problem running %s (%s)" % (' '.join(cmd), e)) (stdout, stderr) = sp.communicate() self.data = stdout + # see comment about _meta below + self.host_vars_from_top = None self.groups = self._parse(stderr) def _parse(self, err): @@ -52,11 +54,23 @@ class InventoryScript(object): groups = dict(all=all) group = None + if 'failed' in self.raw: sys.stderr.write(err + "\n") raise errors.AnsibleError("failed to parse executable inventory script results: %s" % self.raw) for (group_name, data) in self.raw.items(): + + # in Ansible 1.3 and later, a "_meta" subelement may contain + # a variable "hostvars" which contains a hash for each host + # if this "hostvars" exists at all then do not call --host for each + # host. This is for efficiency and scripts should still return data + # if called with --host for backwards compat with 1.2 and earlier. + + if group_name == '_meta': + if 'hostvars' in data: + self.host_vars_from_top = data['hostvars'] + continue group = groups[group_name] = Group(group_name) host = None @@ -85,6 +99,8 @@ class InventoryScript(object): # Separate loop to ensure all groups are defined for (group_name, data) in self.raw.items(): + if group_name == '_meta': + continue if isinstance(data, dict) and 'children' in data: for child_name in data['children']: if child_name in groups: @@ -93,6 +109,11 @@ class InventoryScript(object): def get_host_variables(self, host): """ Runs