Merge pull request #1261 from talentedmrjones/europa-secret-exec
Europa: secret exec
This commit is contained in:
commit
c826794643
45
plan/task/secretexec.go
Normal file
45
plan/task/secretexec.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"go.dagger.io/dagger/compiler"
|
||||||
|
"go.dagger.io/dagger/plancontext"
|
||||||
|
"go.dagger.io/dagger/solver"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Register("SecretExec", func() Task { return &secretExecTask{} })
|
||||||
|
}
|
||||||
|
|
||||||
|
type secretExecTask struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c secretExecTask) Run(ctx context.Context, pctx *plancontext.Context, _ solver.Solver, v *compiler.Value) (*compiler.Value, error) {
|
||||||
|
var secretExec struct {
|
||||||
|
Command struct {
|
||||||
|
Name string
|
||||||
|
Args []string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := v.Decode(&secretExec); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
lg := log.Ctx(ctx)
|
||||||
|
|
||||||
|
lg.Debug().Str("name", secretExec.Command.Name).Str("args", strings.Join(secretExec.Command.Args, " ")).Msg("executing secret command")
|
||||||
|
|
||||||
|
// sec audited by @aluzzardi and @mrjones
|
||||||
|
out, err := exec.CommandContext(ctx, secretExec.Command.Name, secretExec.Command.Args...).Output() //#nosec G204
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
secret := pctx.Secrets.New(string(out))
|
||||||
|
return compiler.NewValue().FillFields(map[string]interface{}{
|
||||||
|
"contents": secret.MarshalCUE(),
|
||||||
|
})
|
||||||
|
}
|
@ -63,14 +63,6 @@ _#inputSecret: {
|
|||||||
contents: #Secret
|
contents: #Secret
|
||||||
|
|
||||||
{
|
{
|
||||||
@dagger(notimplemented)
|
|
||||||
|
|
||||||
// Execute a command ON THE CLIENT MACHINE and read secret from standard output
|
|
||||||
command: [string, ...string] | string
|
|
||||||
// Execute command in an interactive terminal
|
|
||||||
// for example to prompt for a passphrase
|
|
||||||
interactive: true | *false
|
|
||||||
} | {
|
|
||||||
// Read secret from a file ON THE CLIENT MACHINE
|
// Read secret from a file ON THE CLIENT MACHINE
|
||||||
$dagger: task: _name: "SecretFile"
|
$dagger: task: _name: "SecretFile"
|
||||||
path: string
|
path: string
|
||||||
@ -78,6 +70,14 @@ _#inputSecret: {
|
|||||||
// Read secret from an environment variable ON THE CLIENT MACHINE
|
// Read secret from an environment variable ON THE CLIENT MACHINE
|
||||||
$dagger: task: _name: "SecretEnv"
|
$dagger: task: _name: "SecretEnv"
|
||||||
envvar: string
|
envvar: string
|
||||||
|
} | {
|
||||||
|
// Get secret by executing a command ON THE CLIENT MACHINE
|
||||||
|
_type: "SecretExec"
|
||||||
|
command: {
|
||||||
|
name: string
|
||||||
|
args: [...string]
|
||||||
|
interactive: true | *false @dagger(notimplemented) // FIXME: https://github.com/dagger/dagger/issues/1268
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,3 +57,15 @@ setup() {
|
|||||||
assert_failure
|
assert_failure
|
||||||
assert_output --partial 'failed to up environment: actions.verify.contents: conflicting values "local directory" and "local dfsadf"'
|
assert_output --partial 'failed to up environment: actions.verify.contents: conflicting values "local directory" and "local dfsadf"'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "plan/inputs/secrets exec" {
|
||||||
|
cd "$TESTDIR"
|
||||||
|
"$DAGGER" --europa up ./plan/inputs/secrets/exec.cue
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "plan/inputs/secrets invalid command" {
|
||||||
|
cd "$TESTDIR"
|
||||||
|
run "$DAGGER" --europa up ./plan/inputs/secrets/invalid_command.cue
|
||||||
|
assert_failure
|
||||||
|
assert_output --partial 'failed: exec: "rtyet": executable file not found'
|
||||||
|
}
|
||||||
|
34
tests/plan/inputs/secrets/exec.cue
Normal file
34
tests/plan/inputs/secrets/exec.cue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"alpha.dagger.io/europa/dagger/engine"
|
||||||
|
)
|
||||||
|
|
||||||
|
engine.#Plan & {
|
||||||
|
inputs: secrets: echo: command: {
|
||||||
|
name: "echo"
|
||||||
|
args: ["hello europa"]
|
||||||
|
}
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
|
||||||
|
image: engine.#Pull & {
|
||||||
|
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||||
|
}
|
||||||
|
|
||||||
|
verify: engine.#Exec & {
|
||||||
|
input: image.output
|
||||||
|
mounts: secret: {
|
||||||
|
dest: "/run/secrets/test"
|
||||||
|
contents: inputs.secrets.echo.contents
|
||||||
|
}
|
||||||
|
args: [
|
||||||
|
"sh", "-c",
|
||||||
|
#"""
|
||||||
|
test "$(cat /run/secrets/test)" = "hello europa"
|
||||||
|
ls -l /run/secrets/test | grep -- "-r--------"
|
||||||
|
"""#,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
tests/plan/inputs/secrets/invalid_command.cue
Normal file
34
tests/plan/inputs/secrets/invalid_command.cue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"alpha.dagger.io/europa/dagger/engine"
|
||||||
|
)
|
||||||
|
|
||||||
|
engine.#Plan & {
|
||||||
|
inputs: secrets: echo: command: {
|
||||||
|
name: "rtyet" // should fail because command doesnt exist
|
||||||
|
args: ["hello europa"]
|
||||||
|
}
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
|
||||||
|
image: engine.#Pull & {
|
||||||
|
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||||
|
}
|
||||||
|
|
||||||
|
verify: engine.#Exec & {
|
||||||
|
input: image.output
|
||||||
|
mounts: secret: {
|
||||||
|
dest: "/run/secrets/test"
|
||||||
|
contents: inputs.secrets.echo.contents
|
||||||
|
}
|
||||||
|
args: [
|
||||||
|
"sh", "-c",
|
||||||
|
#"""
|
||||||
|
test "$(cat /run/secrets/test)" = "hello europa"
|
||||||
|
ls -l /run/secrets/test | grep -- "-r--------"
|
||||||
|
"""#,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user