Brian Coca 1 week ago committed by GitHub
commit cbaedea9f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,3 @@
minor_changes:
- The ``Constructed`` base class (and plugin) no has a ``vars`` key in the ``keyed_groups`` option, so users can add vars directly w/o need of a 2nd inventory or vars plugin or guessing group names.
- The ``constructed`` inventory plugin also now can have an option ``group_vars`` to allow for assiging vars to groups w/o the need of a 2nd inventory or vars plugin.

@ -58,6 +58,11 @@ options:
type: bool
default: true
version_added: '2.12'
vars:
description:
- Set variables for this group
type: dict
version_added: '2.18'
use_extra_vars:
version_added: '2.11'
description: Merge extra vars into the available variables for composition (highest precedence).

@ -298,6 +298,12 @@ class _BaseInventoryPlugin(AnsiblePlugin):
return (hostnames, port)
def _set_group_vars(self, group_name, gvars):
gobj = self.inventory.groups.get(group_name)
for gvar in gvars:
gobj.set_variable(gvar, gvars[gvar])
class BaseInventoryPlugin(_BaseInventoryPlugin):
""" Parses an Inventory Source """
@ -406,6 +412,11 @@ class Constructable(_BaseInventoryPlugin):
for keyed in keys:
if keyed and isinstance(keyed, dict):
group_vars = keyed.get('vars', {})
if group_vars:
# allow using group vars for templating
variables = combine_vars(variables, group_vars)
if fetch_hostvars:
variables = combine_vars(variables, self.inventory.get_host(host).get_vars())
try:
@ -414,6 +425,7 @@ class Constructable(_BaseInventoryPlugin):
if strict:
raise AnsibleParserError("Could not generate group for host %s from %s entry: %s" % (host, keyed.get('key'), to_native(e)))
continue
default_value_name = keyed.get('default_value', None)
trailing_separator = keyed.get('trailing_separator')
if trailing_separator is not None and default_value_name is not None:
@ -467,11 +479,12 @@ class Constructable(_BaseInventoryPlugin):
result_gname = self.inventory.add_group(gname)
self.inventory.add_host(host, result_gname)
self._set_group_vars(result_gname, group_vars)
if raw_parent_name:
parent_name = self._sanitize_group_name(raw_parent_name)
self.inventory.add_group(parent_name)
self.inventory.add_child(parent_name, result_gname)
else:
# exclude case of empty list and dictionary, because these are valid constructions
# simply no groups need to be constructed, but are still falsy

@ -31,6 +31,12 @@ DOCUMENTATION = """
default: false
type: boolean
version_added: '2.11'
group_vars:
description: dictionary of dictionaries, the top keys are group names, the dictionaries withtin are variables for that group.
required: false
type: dict
default: {}
version_added: '2.17'
extends_documentation_fragment:
- constructed
"""
@ -77,6 +83,29 @@ EXAMPLES = r"""
# this creates a common parent group for all ec2 availability zones
- key: placement.availability_zone
parent_group: all_ec2_zones
# Assuming that there exist `tags` that are assigned to various servers such as 'stuff', 'things', 'status', etc.
# also add vars directly to these groups
- key: tags
prefix: tag
default_value: "running"
priority: "{{ 10 if 'status' in ansible_keyed_group_name else 50 }}"
vars:
ansible_group_priority: '{{ "status" in tags)|ternary(10, 30)}}'
allowed_ssh_groups: qa,ops
group_origin: tags
group_vars:
# group names: mapped to variables for those groups
all:
ntpserver: "ntp.{{ansible_facts['domain']}}"
webservers:
open_ports: 80,8080,443
allowed_ssh_groups: webdevs,qa,ops
dbservers:
open_ports: 1283
allowed_ssh_groups: dbas,qa,ops
ansible_group_priority: 111
"""
import os
@ -171,5 +200,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
# constructed groups based variable values
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), hostvars, host, strict=strict, fetch_hostvars=False)
# handle group vars
groups = self.get_option('group_vars')
for group_name in groups.keys():
self._set_group_vars(group_name, groups[group_name])
except Exception as ex:
raise AnsibleParserError(f"Failed to parse {path!r}.") from ex

@ -0,0 +1,2 @@
override_priority_2: "b_keyed_group_priority_2"
override_priority_3: "b_keyed_group_priority_2"

@ -0,0 +1,3 @@
override_priority_1: "c_static_group_priority_1"
override_priority_2: "c_static_group_priority_1"
override_priority_3: "c_static_group_priority_1"

@ -0,0 +1,13 @@
plugin: ansible.builtin.constructed
keyed_groups:
- key: keyed_group_1
default_value: "priority_2"
prefix: b_keyed_group
vars:
ansible_group_priority: 2
- key: keyed_group_2
default_value: "priority_3"
prefix: a_keyed_group
vars:
ansible_group_priority: '{{("priority_3" in keyed_group_2)|ternary(3, 1)}}'

@ -0,0 +1,7 @@
all:
children:
c_static_group_priority_1:
hosts:
host0:
keyed_group_1: ""
keyed_group_2: ""

@ -66,3 +66,24 @@ ansible-inventory -i invs/1/one.yml -i invs/2/constructed.yml --graph | tee out.
grep '@c_lola' out.txt
grep '@c_group4testing' out.txt
# Testing the priority
ansible-inventory -i invs/3/priority_inventory.yml -i invs/3/keyed_group_str_default_value_with_priority.yml --list | tee out.txt
# If we expect the variables to be resolved lexicographically, ('c' would override 'b', which would override 'a')
# then we would expect c_static_group_priority_1 to take precedence.
# However, setting the priorities here is what we're testing, and is indicated in the names of the groups.
#
# If you comment out the priorities of the keyed groups, all of the below will return c_static_group_priority_1
# override_priority_1 is ONLY set in c_static_group_priority_1 - so it should not get overridden by any other group
grep '"override_priority_1": "c_static_group_priority_1"' out.txt
# override_priority_2 is set in both c_static_group_priority_1 and b_keyed_group_priority_2 which (as advertised) has a priority
# of 2, which should override c_static_group_priority_1. This means that the value from b_keyed_group_priority_2 should return.
grep '"override_priority_2": "b_keyed_group_priority_2"' out.txt
# override_priority_3 is set in all the groups, which means the group with the highest priority set should win.
# Lexicographically, this would otherwise be c_static_group_priority_1. However, since we set the priority of
# a_keyed_group_priority_3 to 3, we will expect it to override the other two groups, and return its variable.
# Note that a_keyed_group_priority_3 has its priority set with a conditional, so here we are testing our ability
# to set this priority with a variable, including the `ansible_keyed_group_name` variable that we expose.
grep '"override_priority_3": "a_keyed_group_priority_3"' out.txt

Loading…
Cancel
Save