-
Notifications
You must be signed in to change notification settings - Fork 16
Description
The idea is to avoid the pattern:
results, err := gr.RunSync(
&task.RemoteCommand{Command: "ip addr | grep \\/24 | awk '{ print $2 }'"},
)
if err != nil {
log.Fatal(err)
}
if err := output.RenderResults(os.Stdout, results, true); err != nil {
log.Fatal(err)
}
To do that we could either modify existing Logging interface or create a new one like:
type Output interface {
PreHost(Context, Host, Task) // Called before executing a task on a host
PostHost(Context, Host, Task) // Called before executing a task on a host
PreTask(Context, Task) // Called before executing the task on any host
PostTask(Context, Task) // Called after executing the task on all the hosts
Success(Context, TaskInstanceResult) // Called if the task succeeded
Fail(error) // Called if the task failed
}
I think that extending the logging interface should be enough and different plugins could do different things. For instance, a logrus plugin could just ignore those method (no ops) and implement Info, Error, etc., while a RenderResult
plugin could do the opposite; implement logging like methods like Info
and Error
and implement instead Host
, Task
, Success
and Fail
.
To make this even more useful, it'd be great to allow multiple output loggers.
An alternative would be to leave things as they are and add a callback to RunAsync
but I think there is value on the output interface as it will simplify the overall workflow and delegate responsibility to the output plugin.
I also think it's general enough that users could leverage the pattern to create their own "event based" workflow. For instance, your "Output" plugin could update a database on Success
with data the gathered on the task, and send notifications to slack on Fail
, PreTask
and PostTask
.