skx / marionette

Something like puppet, for the localhost only.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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".