Inventory plugin for empty group creation

This commit is contained in:
Emmanuel BENOîT 2022-08-07 22:38:48 +02:00
parent 92a73d7113
commit 99496593a9
2 changed files with 108 additions and 1 deletions

View file

@ -12,4 +12,4 @@ use_persistent_connections = true
usetty = false usetty = false
[inventory] [inventory]
enable_plugins = constructed, community.general.proxmox, yaml enable_plugins = constructed, community.general.proxmox, group_creator, yaml

View file

@ -0,0 +1,107 @@
import os
from ansible import constants as C
from ansible.errors import AnsibleParserError
from ansible.module_utils._text import to_native
from ansible.plugins.inventory import BaseInventoryPlugin
DOCUMENTATION = """
name: group_creator
short_description: Uses Jinja2 templates to construct empty groups.
description:
- Uses a YAML configuration file with a valid YAML extension to define
groups. The groups' names as well as the list of parent groups for a
given group may use Jinja2 templates based on the host variables.
options:
plugin:
description:
- Token that ensures this is a source file for the C(group_creator)
plugin.
required: True
choices: ['group_creator']
groups:
description:
- The list of groups to create.
type: list
elements: dict
required: True
suboptions:
name:
description:
- The template to generate a group name from. If an empty
string is returned, the group will not be created.
type: str
required: true
parents:
description:
- A list of templates to generate the names of the group's
parents from. Empty strings will be ignored.
type: list
elements: str
default: []
strict:
description:
- If C(yes) make invalid templates a fatal error, otherwise skip and
continue.
required: False
type: bool
default: no
"""
class InventoryModule(BaseInventoryPlugin):
"""Constructs empty groups based on arbitrary variables."""
NAME = "group_creator"
def __init__(self):
super(InventoryModule, self).__init__()
def verify_file(self, path):
valid = False
if super(InventoryModule, self).verify_file(path):
file_name, ext = os.path.splitext(path)
if not ext or ext in ['.config'] + C.YAML_FILENAME_EXTENSIONS:
valid = True
return valid
def _evaluate(self, template, variables, auto_template):
t = self.templar
if auto_template:
template = "%s%s%s" % (
t.environment.variable_start_string,
template,
t.environment.variable_end_string,
)
t.available_variables = variables
return t.template(template, disable_lookups=True)
def _get_group_name(self, host, name, host_vars, strict):
try:
name = self._evaluate(name, host_vars, False)
return self._sanitize_group_name(name)
except Exception as e:
if strict:
raise AnsibleParserError(
"Could not generate group name for host %s from '%s': (%s) %s"
% (host, name, to_native(repr(type(e))), to_native(e))
)
return ""
def parse(self, inventory, loader, path, cache=False):
super(InventoryModule, self).parse(inventory, loader, path, cache=cache)
self._read_config_data(path)
strict = self.get_option("strict")
for host in inventory.hosts:
host_vars = self.inventory.get_host(host).get_vars()
for group in self.get_option("groups"):
name = self._get_group_name(host, group['name'], host_vars, strict)
if not name:
continue
self.inventory.add_group(name)
for ptmpl in group.get("parents"):
parent = self._get_group_name(host, ptmpl, host_vars, strict)
if parent:
self.inventory.add_group(parent)
self.inventory.add_child(parent, name)