Allow modules to setup output variables
skx opened this issue · comments
It occurred to me in a recent comment that it might be nice to write something like this:
let blah = shell{ command => "uptime" }
log { message => "${blah.stdout}" }
Assigning blocks to variables is a big change that is going to be fiddly and annoying. That said allowing a module to generate outputs is a little appealing, whether for debugging or real use.
The HTTP-module is another obvious case where we have status-code, return-line, and content, upon successful execution.
So instead of allowing the variable assignment I'll propose a simple, optional, interface which allows a module to set variables in the environment - scoped by the rule-name.
For example:
shell { name => "uptime", command => "uptime" }
log { message => "${uptime.stdout}" }
Here we see shell
is executed with a name uptime
. That will set:
${uptime.stdout}
${uptime.stderr}
That's a simple change, and should allow conditional execution in the future.
TLDR:
- Some modules will be updated to store variables in the environment after they're executed.
- These can be used in later rules in the obvious way.
shell { name => "user", command => "whoami"}
shell { command => "..", if => equal("${user.stdout}", "root" }
Proof of concept works as I'd hoped:
#
# Run a command.
#
# This will produce "${user.stdout}" and "${user.stderr}" variables.
#
shell { name => "user",
command => "/usr/bin/whoami"
}
#
# Are we steve?
#
log {
message => "STEVE!",
if => equal( "${user.stdout}", "skx\n" )
}
#
# Are we root?
#
log {
message => "ROOT!",
if => equal( "${user.stdout}", "root\n" )
}
That shows:
$ ./marionette root.in
2022/02/20 10:43:20 [USER] STEVE
$ sudo ./marionette root.in
[sudo] password for skx:
2022/02/20 10:43:24 [USER] ROOT!
Only annoyance here is the trailing-newline on the command-output, which I need to strip. Or I need a new built-in "contains" rather than "equals".