From 74e0f925959d0296c1da5b16c5c31d5862f43349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Tue, 1 Nov 2022 10:31:14 +0100 Subject: [PATCH] Documentation rewrite --- README.md | 219 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 172 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index d7cf212..7d41c5a 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,186 @@ reconstructed ============= -An Ansible plugin that can generate structured inventories programmatically. +`reconstructed` is an Ansible inventory plugin which can be used to generate +group hierarchies and place hosts within them based solely on host facts. +This allows functionality similar to what the [ansible.builtin.add_host](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/add_host_module.html) +module can provide, but it is available during inventory construction rather +than playbook execution. -This is a work in progress. I will make this README more useful later, provided -I just don't forget about this whole thing. +Installation from Ansible Galaxy +-------------------------------- -A `reconstructed` inventory executes a list of instructions that is read -from the `instructions` YAML field. Each instruction is a table with some -minimal control flow (`when`, `loop` and `run_once` keywords that work mostly -like their playbook cousins), an `action` field that contains the name of the -instruction to execute, and whatever fields are needed for the instruction. +You can install the latest version from Ansible Galaxy repository. -The following actions are supported: +```bash +ansible-galaxy collection install -U tseeker.reconstructed +``` - * `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. 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. +If you are using a *requirements.yml* file to download collections and roles, +you can use these lines: - * `add_child` adds a child group to another group. The name of the - group being added must be provided in the `child` entry, while - the name of the parent must be provided in the `group` entry. Both - groups must exist. In addition, the names may be specified using - Jinja templates. +```yaml +collections: + - tseeker.reconstructed +``` - * `add_host` adds the current inventory host to a group. The name - of the group must be provided in the `group` entry. The group - must exist. +Usage +----- - * `fail` causes the computations for the current host to stop with - an error. The error message may be specified in the `message` - entry; if present, it will be evaluated using Jinja. +A `reconstructed` script can be added to the inventory by creating a YAML +file in the inventory, with the following structure: - * `set_fact` and `set_var` create a fact and a local variable, - respectively. Local variables will only be kept during the execution - of the script for the current host, while facts will be added to the - host's data. The `name` entry specifies the name of the fact or - variable while the `value` entry specifies its value. Both may be - Jinja templates. +```yaml +--- +plugin: tseeker.reconstructed.reconstructed +instructions: + - action: ... + - action: ... + # ... +``` - * `stop` stops processing the list of instructions for the current - host. +Script actions are somewhat similar to playbook tasks. Once a script has been +added, it will be executed once for each host in the input inventory. -In addition, the `block` can be used to repeat multiple instructions or make -them obey a single conditional. The instruction must include a `block` field, -containing the list of instructions which are part of the block. It may have -a `rescue` field, containing a list of instructions which will be executed on -error, and `always`, which may contain a list of instructions to execute in -all cases. +Each action record in a script must include an `action` field, which describes +the action to perform. In addition, it may include fields which contain the +action's details, as well as fields which implement various controls that +apply to an action (loops, local variables, etc). -If the `vars` field is defined on an instruction, it must contain a table of -local variables to define. Their values are computed after the loop variable -is evaluated, but before the condition is. If these variables already existed, -their state will be saved and they will be restored after the instruction is -done executing. This is different from the core Ansible behaviour, which does -not evaluate the `vars` unless they are used. +The script can manipulate and use host facts. In addition, local variables +which do not pollute the inventory are used automatically for e.g. loops, and +can be defined manually. + +### Actions + +The following actions may be used in a `reconstructed` script. + +#### add_child + +This action adds an existing group to the set of another existing group's +children. + +It supports the following fields. + + * `group` must contain the name of the parent group, or a Jinja template + that evaluates to that name. The group must exist. + * `child` must contain the name of the child group, or a Jinja template + that evaluates to that name. The group must exist. + +#### add_host + +The `add_host` action can be used to add the inventory host currently being +processed to a group. + +The following field is supported. + + * `group` must contain the name of the group to add the host to. It may + be a Jinja template. The group in question must exist. + +#### block + +The `block` action can be used to group multiple actions and to support error +recovery, behaving in many ways like the playbooks' `block`. The following +fields may be used. + + * `block` contains the block's main list of instructions. + * `rescue` contains a list of instructions that will be executed if an + error occurs while executing the main list. The `reconstructed_error` + local variable will contain the message of the error that caused the + `rescue` list to be executed. This field may be omitted. + * `always` contains a list of instructions that will be executed after + both other lists, independently of any error. This field may be omitted. + +#### create_group + +The `create_group` action creates an inventory group. In addition, it may +specify the new group's parent and add the current host to the group. + +If the group already exists, no error will be raised. The group will be added +to the specified parent and the host will be added to the group if requested. + +The following fields are supported. + + * `group` contains the name of the group. It must be present and may contain + a Jinja template. + * `parent` may contain the name of an additional group to which the new + group will be added as a child. The group in question must exist. This + field is optional and may contain a Jinja template. + * If the `add_host` field is present, it may contain a boolean which will + determine whether the current inventory host must be added to the group. + +#### fail + +This action causes the script to fail immediately. The following field may be +used: + + * `msg` may contain a message (or a Jinja template resulting in a message) + to write to the output. By default the message will be `fail requested` + followed by the name of the current host. + +#### set_fact + +This action sets an Ansible fact associated to the current host. The following +fields must be set: + + * `name` is the name of the fact to set, or a Jinja template returning the + name. It must represent a valid fact name. + * `value` is the fact's new value, or a template computing it. + +#### set_var + +This action sets a local variable. Local variables are only kept for the +duration of the script's execution for a given host. A local variable will +hide a fact by the same name. + +The following fields are required: + + * `name` is the name of the fact to set, or a Jinja template returning the + name. It must result in a valid fact name. + * `value` is the variable's new value, or a template computing it. + +#### stop + +The `stop` action interrupts the execution of the script for the current host. +It requires no additional information. + +### Control fields + +The following additional fields may be added to any action record to alter its +behaviour. + +#### run_once + +If this field is set to a ``true``, it will cause the action to be executed +only once. + +#### loop and loop_var + +The `loop` field may contain a list or a Jinja template that evaluates to a +list. The action record will be repeated for each item in the list, with a +local variable set to the value of the item. + +By default the variable that contains the item is called `item`. However it +is possible to add a `loop_var` field containing a valid variable name to +change it. This variable will be restored to its previous state once the loop +is finished. + +#### vars + +The `vars` field may contain a table of local variables to set for the duration +of the action. The table's keys are variable names, and its values will be +evaluated using Jinja. During a loop, variables will be evaluated evaluated +once for each loop iteration. Once the action is finished, the local variables +defined using `vars` will disappear. + +#### when + +The `when` field may be used to check a condition and prevent the execution +of the action it is bound to if the condition isn't satisfied. The condition +is evaluated once for each iteration of a loop. All local variables defined +using `vars` are available for use in the condition. + +## To do + + * `create_group.add_host` should allow Jinja templates + * Add a `debug` action