This is a proof of concept project that implements parsing and execution of an Ansible-like imperative DSL in golang.
Only the action list parsing is implemented to enable consumers to embed it within a larger structure.
Custom actions and middlewares can be implemented on a per project basis although some potentially useful ones are available in the actions
and parser/middleware
directories respectively.
There are three steps to using it...
Initialisation is where you configure the parser with script engine, middleware and registered handlers.
p := parser.New()
p.ScriptParser = mrubyparser.New()
p.Middleware = []types.Middleware{
&withitems.Middleware{Dsl: parser},
}
p.Handlers["test"] = testAction.Prototype
Parsing is where we transform the input data to an executable object. The result is an ActionList
.
file, _ := os.Open(os.Args[1])
data, _ := ioutil.ReadAll(file)
var raw *types.UnparsedActionList
yaml.Unmarshal(data, &raw)
actionList, _ := p.Parse(raw)
Finally, you can execute the action list. This is where each step gets executed.
actionList.Execute()
It should be noted that with the possible exception of middleware fields, all script execution takes place just before the action is executed. The action itself does not need to (and at present can't) handle script execution.
This allows* actions to reference variables that come from another action earlier in the action list.
The test action simply dumps itself through fmt.Printf
. This is useful for testing middleware and generally confirming that you have everything initialized correctly.
- name: "Example test action"
test: "This is a test"
The shell action will execute a shell command locally. This may be expanded to be able to execute remotely at some point in the future.
- name: "Example shell action"
shell: "ls -l /"
The withitems middleware behaves like Ansible with_items
. It allows you to loop over a list of data and execute the action for each.
Access to the current item is available through the item
variable.
with_items
may either be a yaml list or a script expression in the form of a string.
- name: "Example with_items middleware using yaml list"
test: "Test item #{item}"
with_items:
- item1
- item2
- name: "Example with_items middleware using scripting expression"
test: "Test item #{item}"
with_items: >
"item1,item2,item3".split(",")
The register middleware behaves like Ansible register
. It stores the ActionResult struct for this action in to a variable in the scripting engine for later access.
- name: "Example of register"
command: "cat /etc/hosts"
register: hostsfile
- name: "Debug output of hostsfile"
test: "Line: #{item}"
with_items: hostsfile["Result"]["stdout"].split("\n")