Group Plugins#
Group plugins can organize and manipulate the return data of an Idem run before it is rendered.
Finding Group Plugins#
Use idem doc
to list all the available group plugins:
$ idem doc group | grep -o "^group.\w*"
You can also use jq
to list plugins next to their doc strings:
$ idem doc group --output=json | jq -r '. | keys[] as $k | "\($k): \(.[$k].doc)"'
At the time of writing, with no extra plugins installed, this is the result of that command:
group.duration.apply: Sort the output by the total seconds of the state's run time
group.init.apply: Apply all group plugins specified in config
group.number.apply: Sort the data by run number
group.omit_noop.apply: Remove states that reported success without changes
group.sort.apply: Reorganize the data by sorting by each state's unique tag
Using Group Plugins#
Group plugins are specified in a single string and are separated by a pipe. Each group plugin will be run in the order that it is defined.
Group plugins can be specified on the cli with the --group
flag.
$ idem state my_state.sls --group="number|omit_noop"
Group plugins can also be specified in the idem config.
# idem.cfg
idem:
group: number|omit_noop
Creating a Group Plugin#
First create a directory at my_project_root/my_provider/group.
In your project’s conf.py, extend the Idem namespace with your group
directory.
# my_project_root/my_provider/conf.py
DYNE = {"group": ["group"]}
Now create a plugin in your source
directory.
The plugin simply needs to implement the apply
function. This function receives the hub
,
and data
arguments. These will be passed into the function.
data
contains the full results of a state run.
Here are the contents of data
for a run containing a single state:
{
"resource_ref_|-state_block_name_|-state_name_|-function": {
"tag": "resource_ref_|-state_block_name_|-state_name_|-function",
"name": "state_name",
"changes": {},
"new_state": {},
"old_state": {},
"comment": None,
"rerun_data": None,
"result": True,
"esm_tag": "resource_ref_|-state_block_name_|-state_name_|-",
"__run_num": 1,
"start_time": "2022-08-15 09:39:33.608291",
"total_seconds": 0.001207,
"sls_meta": {"SLS": {}, "ID_DECS": {}},
},
}
This is what a basic group plugin looks like:
# my_project_root/my_provider/group/my_plugin.py
from typing import Any
from typing import Dict
def apply(hub, data: Dict[str, Any]) -> Dict[str, Any]:
"""
Re-organize/filter the state runtime results from "data"
"""
# initialize an ordered dictionary for the return (All dictionaries are ordered after python 3.8)
ret = {}
# iterate over the state return data in the order you want to add it to the return
for tag in data:
# retrieve the result of a single state
state_ret = data[tag]
# Break the state tag into it's component parts
comps = tag.split("_|-")
state = comps[0]
id_ = comps[1]
fun = comps[3]
# "result" is True if the state ran successfully, otherwise it is False
result = state_ret.get("result")
# Any comment(s) from the running state
comment = state_ret.get("comment")
# An empty dictionary if there were no changes, else a comparison of "new" and "old" state of the resource
changes = state_ret.get("changes", {})
# The state of the resource before the function ran
old_state = state_ret.get("old_state", {})
# The state of the resource after the function ran
new_state = state_ret.get("new_state", {})
# omit this state ret from the return data based on any of the previous information
if not True:
continue
# Copy the state ret from the input data to the return data
ret[tag] = data[tag]
return ret