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.
This commit is contained in:
Emmanuel BENOîT 2022-09-03 10:40:46 +02:00
parent 9d7ea81783
commit 7b44cdc731
3 changed files with 59 additions and 57 deletions

View file

@ -16,7 +16,11 @@ The following actions are supported:
* `create_group` creates a group. The name of the group must be * `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 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 * `add_child` adds a child group to another group. The name of the
group being added must be provided in the `child` entry, while group being added must be provided in the `child` entry, while

View file

@ -34,13 +34,9 @@ instructions:
- action: create_group - action: create_group
group: managed group: managed
- loop: [by_environment, by_network, by_failover_stack, by_service] - loop: [by_environment, by_network, by_failover_stack, by_service]
action: block action: create_group
block: group: "{{ item }}"
- action: create_group parent: managed
group: "{{ item }}"
- action: add_child
group: managed
child: "{{ item }}"
# Copy inv__data fields to separate inv__ variables # Copy inv__data fields to separate inv__ variables
- loop: - loop:
@ -67,39 +63,24 @@ instructions:
}} }}
- action: create_group - action: create_group
group: "env_{{ inv__environment }}" group: "env_{{ inv__environment }}"
- action: add_child parent: by_environment
group: by_environment add_host: true
child: "env_{{ inv__environment }}"
- action: add_host
group: "env_{{ inv__environment }}"
# Failover stack group # Failover stack group
- action: set_var - action: create_group
name: failover_group group: >-
value: >-
{{ {{
( inv__fostack is defined ) ( inv__fostack is defined )
| ternary( "fostack_" ~ inv__fostack | default("") , "no_failover" ) | ternary( "fostack_" ~ inv__fostack | default("") , "no_failover" )
}} }}
- action: create_group parent: by_failover_stack
group: "{{ failover_group }}" add_host: true
- action: add_child
group: by_failover_stack
child: "{{ failover_group }}"
- action: add_host
group: "{{ failover_group }}"
# Network group # Network group
- action: set_var
name: network_group
value: "net_{{ inv__network }}"
- action: create_group - action: create_group
group: "{{ network_group }}" group: "net_{{ inv__network }}"
- action: add_child parent: by_network
group: by_network add_host: true
child: "{{ network_group }}"
- action: add_host
group: "{{ network_group }}"
# Service group # Service group
- action: set_var - action: set_var
@ -107,9 +88,7 @@ instructions:
value: "svc_{{ inv__service }}" value: "svc_{{ inv__service }}"
- action: create_group - action: create_group
group: "{{ service_group }}" group: "{{ service_group }}"
- action: add_child parent: by_service
group: by_service
child: "{{ service_group }}"
# Component group. We add the host directly if there is no subcomponent. # Component group. We add the host directly if there is no subcomponent.
- when: inv__component is defined - when: inv__component is defined
@ -119,22 +98,13 @@ instructions:
block: block:
- action: create_group - action: create_group
group: "{{ comp_group }}" group: "{{ comp_group }}"
- action: add_child parent: "{{ service_group }}"
group: "{{ service_group }}"
child: "{{ comp_group }}"
# Subcomponent group, or lack thereof. # Subcomponent group, or lack thereof.
- when: inv__subcomponent is not defined - when: inv__subcomponent is not defined
action: add_host action: add_host
group: "{{ comp_group }}" group: "{{ comp_group }}"
- when: inv__subcomponent is defined - when: inv__subcomponent is defined
action: block action: create_group
locals: group: "svcm_{{ inv__service }}_{{ inv__subcomponent }}"
subcomp_group: "svcm_{{ inv__service }}_{{ inv__subcomponent }}" parent: "{{ comp_group }}"
block: add_host: true
- action: create_group
group: "{{ subcomp_group }}"
- action: add_child
group: "{{ comp_group }}"
child: "{{ subcomp_group }}"
- action: add_host
group: "{{ subcomp_group }}"

View file

@ -49,7 +49,11 @@ DOCUMENTATION = """
or C(always) will go out of scope once the block finishes executing. 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 - 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 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 - 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 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 the name of the parent must be provided in the C(group) entry. Both
@ -232,18 +236,42 @@ class RcInstruction:
class RciCreateGroup(RcInstruction): class RciCreateGroup(RcInstruction):
def __init__(self, inventory, templar): def __init__(self, inventory, templar):
super().__init__(inventory, templar, "create_group", ("group",)) super().__init__(
self._may_be_template = None inventory, templar, "create_group", ("group", "parent", "add_host")
self._group = None )
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): def parse_action(self, record):
assert self._may_be_template is None and self._group is None assert self._group_mbt is None and self._group_name is None
self._may_be_template, self._group = self.parse_group_name(record, "group") 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): 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) assert not (
name = self.get_templated_group(merged_vars, self._may_be_template, self._group) 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) 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 return True