This library contains the code for agent-operators
. An operator
is a unit of code that can perform write operations on target machines.
Each operator knows how to execute actions and how to roll them back in case of failure.
Install the library
go get github.com/trento-project/workbench
Install the cli tool
go install github.com/trento-project/workbench
An operator is a unit of code that can perform write operations on target machines.
A write operation can either fail or succeed. If it succeeds, the operation displays a diff highlighting the changes before and after the commit phase.
The operator accepts arguments to specify how to perform the operations. The arguments are in the form of a map[string]any
, and each operator knows how to extract and validate them.
It follows a transactional approach, where each operation has distinct stages:
- PLAN
- COMMIT
- VERIFY
- ROLLBACK
The documentation for each of the operators can be found in the operators go source.
The goal of the PLAN stage is to collect information about the operations and verify prerequisites.
This is also the phase where information for diffing is gathered by collecting the before
state.
Additionally, during this phase, it is important to ensure that any resources modified during the COMMIT phase are backed up. This allows restoration during the ROLLBACK phase or manual recovery by system administrators if the rollback fails.
If an error occurs during the PLAN phase, no rollback is needed; the operation is simply aborted with the plan error.
The COMMIT phase executes the actual write operations on the system, utilizing the information collected during the PLAN phase.
If an error occurs during this phase, a rollback is triggered.
The COMMIT phase should be idempotent. If a requested change has already been applied, the commit operation is simply skipped without returning an error.
Idempotency should be implemented appropriately based on the type of operations to be performed.
The VERIFY phase ensures that the actions applied during the COMMIT phase have produced the expected results on the system.
If an error occurs during this phase, the rollback process is initiated.
This phase is also when the after
state is recorded for the diff, highlighting changes made during the commit phase.
The ROLLBACK phase must implement mechanisms to revert any changes made during the COMMIT phase.
It can use information collected during the PLAN phase to restore the system to its previous state.
The rollback implementation may vary depending on the type of operation performed during the COMMIT phase.
Be sure to provide clear error messages and log actions appropriately.
If the rollback fails, the error is returned without further action.
The Executor is a wrapper around an operator. The operator implements the phase interface and must be wrapped in an Executor.
The Executor manages operations transactionally.
For library users, the Executor is transparent—using an Operator means it is already wrapped within an Executor.
The Registry holds all available operators. Each operator has a version. By default, if no version is specified when requesting an operator, the latest version is fetched from the Registry.
To use an operator, it must be fetched using the GetOperatorBuilder
function, providing the operator name as an argument.
builder, err := registry.GetOperatorBuilder(operatorName)
op := builder("test-cli", opArgs)
report := op.Run(ctx)
// the report contains the success or the error of the execution
The operator name follows this format: <operatorname>@<version>
.
The Registry returns an Operator Builder:
type OperatorBuilder func(operationID string, arguments OperatorArguments) Operator
The operationID
is a unique identifier for the operation, and arguments
are modeled as map[string]any
.
The Workbench library also exposes a CLI
to run operators without importing the library. The CLI is intended only for testing and development purposes.
The CLI follows the same rules as the library, implementing only the operators exposed by the registry.
Usage:
workbench [OPTIONS]
Application Options:
-a, --arguments= JSON arguments for an operator
-v, --verbose Log verbosity
Help Options:
-h, --help Show this help message
The CLI accepts the name of an operator as an argument, following the same convention <operatorname>@<version>
, and requires the -a
option to pass the arguments.
The arguments must be provided as a JSON string.
sudo ./workbench -a '{"solution": "HANA"}' saptuneapplysolution
Using sudo
may be necessary depending on the type of operator being executed.
In this example, the saptuneapplysolution
operator is called with the argument solution
set to HANA
.
The CLI will perform the operations, log any errors, and finally display the diff when the execution succeeds.