From 7b44cdc73149d27cb3d7bf3bc884a9c80354e75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Sat, 3 Sep 2022 10:40:46 +0200 Subject: [PATCH] create_group - add_host and parent options * The `add_host` option can be used to add the current host to the group being created. It avoids having to use a separate `add_host` instruction in this case. * The `parent` option can specify the parent group. It avoids having to use a separate `add_child` instruction in this case. --- README.md | 6 ++- example/01-test-reconstructed.yml | 66 ++++++++---------------------- inventory_plugins/reconstructed.py | 44 ++++++++++++++++---- 3 files changed, 59 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 1788942..f744298 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,11 @@ The following actions are supported: * `create_group` creates a group. The name of the group must be provided using the `group` field, which must be a valid name or a - Jinja template that evaluates to a valid name. + Jinja template that evaluates to a valid name. In addition, a + `parent` field containting the name of a single, existing parent + group (or a Jinja template generating the name) may be provided. + Finally, the `add_host` field may be set to a truthy value if the + current host must be added to the new group. * `add_child` adds a child group to another group. The name of the group being added must be provided in the `child` entry, while diff --git a/example/01-test-reconstructed.yml b/example/01-test-reconstructed.yml index 1e322da..4ab01f4 100644 --- a/example/01-test-reconstructed.yml +++ b/example/01-test-reconstructed.yml @@ -34,13 +34,9 @@ instructions: - action: create_group group: managed - loop: [by_environment, by_network, by_failover_stack, by_service] - action: block - block: - - action: create_group - group: "{{ item }}" - - action: add_child - group: managed - child: "{{ item }}" + action: create_group + group: "{{ item }}" + parent: managed # Copy inv__data fields to separate inv__ variables - loop: @@ -67,39 +63,24 @@ instructions: }} - action: create_group group: "env_{{ inv__environment }}" - - action: add_child - group: by_environment - child: "env_{{ inv__environment }}" - - action: add_host - group: "env_{{ inv__environment }}" + parent: by_environment + add_host: true # Failover stack group - - action: set_var - name: failover_group - value: >- + - action: create_group + group: >- {{ ( inv__fostack is defined ) | ternary( "fostack_" ~ inv__fostack | default("") , "no_failover" ) }} - - action: create_group - group: "{{ failover_group }}" - - action: add_child - group: by_failover_stack - child: "{{ failover_group }}" - - action: add_host - group: "{{ failover_group }}" + parent: by_failover_stack + add_host: true # Network group - - action: set_var - name: network_group - value: "net_{{ inv__network }}" - action: create_group - group: "{{ network_group }}" - - action: add_child - group: by_network - child: "{{ network_group }}" - - action: add_host - group: "{{ network_group }}" + group: "net_{{ inv__network }}" + parent: by_network + add_host: true # Service group - action: set_var @@ -107,9 +88,7 @@ instructions: value: "svc_{{ inv__service }}" - action: create_group group: "{{ service_group }}" - - action: add_child - group: by_service - child: "{{ service_group }}" + parent: by_service # Component group. We add the host directly if there is no subcomponent. - when: inv__component is defined @@ -119,22 +98,13 @@ instructions: block: - action: create_group group: "{{ comp_group }}" - - action: add_child - group: "{{ service_group }}" - child: "{{ comp_group }}" + parent: "{{ service_group }}" # Subcomponent group, or lack thereof. - when: inv__subcomponent is not defined action: add_host group: "{{ comp_group }}" - when: inv__subcomponent is defined - action: block - locals: - subcomp_group: "svcm_{{ inv__service }}_{{ inv__subcomponent }}" - block: - - action: create_group - group: "{{ subcomp_group }}" - - action: add_child - group: "{{ comp_group }}" - child: "{{ subcomp_group }}" - - action: add_host - group: "{{ subcomp_group }}" + action: create_group + group: "svcm_{{ inv__service }}_{{ inv__subcomponent }}" + parent: "{{ comp_group }}" + add_host: true diff --git a/inventory_plugins/reconstructed.py b/inventory_plugins/reconstructed.py index eaa8404..3fb359b 100644 --- a/inventory_plugins/reconstructed.py +++ b/inventory_plugins/reconstructed.py @@ -49,7 +49,11 @@ DOCUMENTATION = """ or C(always) will go out of scope once the block finishes executing. - C(create_group) creates a group. The name of the group must be provided using the C(group) field, which must be a valid name or a - Jinja template that evaluates to a valid name. + Jinja template that evaluates to a valid name. In addition, a + C(parent) field containting the name of a single, existing parent + group (or a Jinja template generating the name) may be provided. + Finally, the C(add_host) field may be set to a truthy value if the + current host must be added to the new group. - C(add_child) adds a child group to another group. The name of the group being added must be provided in the C(child) entry, while the name of the parent must be provided in the C(group) entry. Both @@ -232,18 +236,42 @@ class RcInstruction: class RciCreateGroup(RcInstruction): def __init__(self, inventory, templar): - super().__init__(inventory, templar, "create_group", ("group",)) - self._may_be_template = None - self._group = None + super().__init__( + inventory, templar, "create_group", ("group", "parent", "add_host") + ) + self._group_mbt = None + self._group_name = None + self._parent_mbt = None + self._parent_name = None + self._add_host = None def parse_action(self, record): - assert self._may_be_template is None and self._group is None - self._may_be_template, self._group = self.parse_group_name(record, "group") + assert self._group_mbt is None and self._group_name is None + assert self._parent_mbt is None and self._parent_name is None + assert self._add_host is None + self._add_host = record.get("add_host", False) + self._group_mbt, self._group_name = self.parse_group_name(record, "group") + if "parent" in record: + self._parent_mbt, self._parent_name = self.parse_group_name( + record, "parent" + ) def execute_action(self, host_name, merged_vars, host_vars, script_vars): - assert not (self._may_be_template is None or self._group is None) - name = self.get_templated_group(merged_vars, self._may_be_template, self._group) + assert not ( + self._group_mbt is None + or self._group_name is None + or self._add_host is None + ) + if self._parent_name is not None: + parent = self.get_templated_group( + merged_vars, self._parent_mbt, self._parent_name, must_exist=True + ) + name = self.get_templated_group(merged_vars, self._group_mbt, self._group_name) self._inventory.add_group(name) + if self._parent_name is not None: + self._inventory.add_child(parent, name) + if self._add_host: + self._inventory.add_child(name, host_name) return True