This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
dagger/plan/task/decodesecret.go
Richard Jones f3a75f8d74
improved handling of p []cue.Selector in for loop
Signed-off-by: Richard Jones <richard@dagger.io>
2022-02-05 10:01:06 -07:00

83 lines
2.0 KiB
Go

package task
import (
"context"
"encoding/json"
"errors"
"cuelang.org/go/cue"
"github.com/rs/zerolog/log"
"go.dagger.io/dagger/compiler"
"go.dagger.io/dagger/plancontext"
"go.dagger.io/dagger/solver"
"gopkg.in/yaml.v3"
)
func init() {
Register("DecodeSecret", func() Task { return &decodeSecretTask{} })
}
type decodeSecretTask struct {
}
func (c *decodeSecretTask) Run(ctx context.Context, pctx *plancontext.Context, _ solver.Solver, v *compiler.Value) (*compiler.Value, error) {
lg := log.Ctx(ctx)
lg.Debug().Msg("decoding secret")
input := v.Lookup("input")
inputSecret, err := pctx.Secrets.FromValue(input)
if err != nil {
return nil, err
}
format, err := v.Lookup("format").String()
if err != nil {
return nil, err
}
lg.Debug().Str("format", format).Msg("unmarshaling secret")
inputSecretPlaintext := inputSecret.PlainText()
var unmarshaled map[string]interface{}
switch format {
case "json":
err = json.Unmarshal([]byte(inputSecretPlaintext), &unmarshaled)
case "yaml":
err = yaml.Unmarshal([]byte(inputSecretPlaintext), &unmarshaled)
}
if err != nil {
// returning err here could expose secret plaintext!
return nil, errors.New("could not unmarshal secret")
}
output := compiler.NewValue()
// recurse over unmarshaled to convert string values to secrets
var convert func(p []cue.Selector, i interface{})
convert = func(p []cue.Selector, i interface{}) {
switch entry := i.(type) {
case string:
secret := pctx.Secrets.New(entry)
p = append(p, cue.ParsePath("contents").Selectors()...)
logPath := cue.MakePath(p[1 : len(p)-1]...)
lg.Debug().Str("path", logPath.String()).Str("type", "string").Msg("found secret")
path := cue.MakePath(p...)
output.FillPath(path, secret.MarshalCUE())
case map[string]interface{}:
for k, v := range entry {
np := append([]cue.Selector{}, p...)
np = append(np, cue.ParsePath(k).Selectors()...)
convert(np, v)
}
}
}
convert(cue.ParsePath("output").Selectors(), unmarshaled)
return output, nil
}