secret input type, simplify state format
Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
parent
5442d6b261
commit
9d416d65f7
@ -10,6 +10,7 @@ import (
|
|||||||
"dagger.io/go/cmd/dagger/logger"
|
"dagger.io/go/cmd/dagger/logger"
|
||||||
"dagger.io/go/dagger"
|
"dagger.io/go/dagger"
|
||||||
"dagger.io/go/dagger/compiler"
|
"dagger.io/go/dagger/compiler"
|
||||||
|
"dagger.io/go/dagger/state"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
@ -84,9 +85,9 @@ var listCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func isUserSet(env *dagger.EnvironmentState, val *compiler.Value) bool {
|
func isUserSet(env *state.State, val *compiler.Value) bool {
|
||||||
for _, i := range env.Inputs {
|
for key := range env.Inputs {
|
||||||
if val.Path().String() == i.Key {
|
if val.Path().String() == key {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
package input
|
package input
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"dagger.io/go/cmd/dagger/logger"
|
||||||
|
"dagger.io/go/dagger/state"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
var secretCmd = &cobra.Command{
|
var secretCmd = &cobra.Command{
|
||||||
Use: "secret TARGET VALUE",
|
Use: "secret <TARGET> [-f] [<VALUE|PATH>]",
|
||||||
Short: "Add an encrypted input secret",
|
Short: "Add an encrypted input secret",
|
||||||
Args: cobra.ExactArgs(2),
|
Args: cobra.RangeArgs(1, 2),
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
// Fix Viper bug for duplicate flags:
|
// Fix Viper bug for duplicate flags:
|
||||||
// https://github.com/spf13/viper/issues/233
|
// https://github.com/spf13/viper/issues/233
|
||||||
@ -17,14 +23,35 @@ var secretCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
// lg := logger.New()
|
lg := logger.New()
|
||||||
// ctx := lg.WithContext(cmd.Context())
|
ctx := lg.WithContext(cmd.Context())
|
||||||
|
|
||||||
panic("not implemented")
|
var secret string
|
||||||
|
if len(args) == 1 {
|
||||||
|
// No value specified: prompt terminal
|
||||||
|
fmt.Print("Secret: ")
|
||||||
|
data, err := term.ReadPassword(syscall.Stdin)
|
||||||
|
if err != nil {
|
||||||
|
lg.Fatal().Err(err).Msg("unable to read secret from terminal")
|
||||||
|
}
|
||||||
|
fmt.Println("")
|
||||||
|
secret = string(data)
|
||||||
|
} else {
|
||||||
|
// value specified: read it
|
||||||
|
secret = readInput(ctx, args[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
updateEnvironmentInput(
|
||||||
|
ctx,
|
||||||
|
args[0],
|
||||||
|
state.SecretInput(secret),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
secretCmd.Flags().BoolP("file", "f", false, "Read value from file")
|
||||||
|
|
||||||
if err := viper.BindPFlags(secretCmd.Flags()); err != nil {
|
if err := viper.BindPFlags(secretCmd.Flags()); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
cueflow "cuelang.org/go/tools/flow"
|
cueflow "cuelang.org/go/tools/flow"
|
||||||
"dagger.io/go/dagger/compiler"
|
"dagger.io/go/dagger/compiler"
|
||||||
"dagger.io/go/dagger/state"
|
"dagger.io/go/dagger/state"
|
||||||
"dagger.io/go/pkg/cuetils"
|
|
||||||
"dagger.io/go/stdlib"
|
"dagger.io/go/stdlib"
|
||||||
|
|
||||||
"github.com/opentracing/opentracing-go"
|
"github.com/opentracing/opentracing-go"
|
||||||
@ -43,15 +42,15 @@ func NewEnvironment(st *state.State) (*Environment, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prepare inputs
|
// Prepare inputs
|
||||||
for _, input := range st.Inputs {
|
for key, input := range st.Inputs {
|
||||||
v, err := input.Value.Compile(st)
|
v, err := input.Compile(st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if input.Key == "" {
|
if key == "" {
|
||||||
err = e.input.FillPath(cue.MakePath(), v)
|
err = e.input.FillPath(cue.MakePath(), v)
|
||||||
} else {
|
} else {
|
||||||
err = e.input.FillPath(cue.ParsePath(input.Key), v)
|
err = e.input.FillPath(cue.ParsePath(key), v)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -24,25 +24,12 @@ import (
|
|||||||
// Under the hood, an artifact is encoded as a LLB pipeline, and
|
// Under the hood, an artifact is encoded as a LLB pipeline, and
|
||||||
// attached to the cue configuration as a
|
// attached to the cue configuration as a
|
||||||
//
|
//
|
||||||
type InputType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
InputTypeDir InputType = "dir"
|
|
||||||
InputTypeGit InputType = "git"
|
|
||||||
InputTypeDocker InputType = "docker"
|
|
||||||
InputTypeText InputType = "text"
|
|
||||||
InputTypeJSON InputType = "json"
|
|
||||||
InputTypeYAML InputType = "yaml"
|
|
||||||
InputTypeFile InputType = "file"
|
|
||||||
InputTypeEmpty InputType = ""
|
|
||||||
)
|
|
||||||
|
|
||||||
type Input struct {
|
type Input struct {
|
||||||
Type InputType `yaml:"type,omitempty"`
|
|
||||||
|
|
||||||
Dir *dirInput `yaml:"dir,omitempty"`
|
Dir *dirInput `yaml:"dir,omitempty"`
|
||||||
Git *gitInput `yaml:"git,omitempty"`
|
Git *gitInput `yaml:"git,omitempty"`
|
||||||
Docker *dockerInput `yaml:"docker,omitempty"`
|
Docker *dockerInput `yaml:"docker,omitempty"`
|
||||||
|
Secret *secretInput `yaml:"secret,omitempty"`
|
||||||
Text *textInput `yaml:"text,omitempty"`
|
Text *textInput `yaml:"text,omitempty"`
|
||||||
JSON *jsonInput `yaml:"json,omitempty"`
|
JSON *jsonInput `yaml:"json,omitempty"`
|
||||||
YAML *yamlInput `yaml:"yaml,omitempty"`
|
YAML *yamlInput `yaml:"yaml,omitempty"`
|
||||||
@ -50,32 +37,31 @@ type Input struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i Input) Compile(state *State) (*compiler.Value, error) {
|
func (i Input) Compile(state *State) (*compiler.Value, error) {
|
||||||
switch i.Type {
|
switch {
|
||||||
case InputTypeDir:
|
case i.Dir != nil:
|
||||||
return i.Dir.Compile(state)
|
return i.Dir.Compile(state)
|
||||||
case InputTypeGit:
|
case i.Git != nil:
|
||||||
return i.Git.Compile(state)
|
return i.Git.Compile(state)
|
||||||
case InputTypeDocker:
|
case i.Docker != nil:
|
||||||
return i.Docker.Compile(state)
|
return i.Docker.Compile(state)
|
||||||
case InputTypeText:
|
case i.Text != nil:
|
||||||
return i.Text.Compile(state)
|
return i.Text.Compile(state)
|
||||||
case InputTypeJSON:
|
case i.Secret != nil:
|
||||||
|
return i.Secret.Compile(state)
|
||||||
|
case i.JSON != nil:
|
||||||
return i.JSON.Compile(state)
|
return i.JSON.Compile(state)
|
||||||
case InputTypeYAML:
|
case i.YAML != nil:
|
||||||
return i.YAML.Compile(state)
|
return i.YAML.Compile(state)
|
||||||
case InputTypeFile:
|
case i.File != nil:
|
||||||
return i.File.Compile(state)
|
return i.File.Compile(state)
|
||||||
case "":
|
|
||||||
return nil, fmt.Errorf("input has not been set")
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported input type: %s", i.Type)
|
return nil, fmt.Errorf("input has not been set")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// An input artifact loaded from a local directory
|
// An input artifact loaded from a local directory
|
||||||
func DirInput(path string, include []string) Input {
|
func DirInput(path string, include []string) Input {
|
||||||
return Input{
|
return Input{
|
||||||
Type: InputTypeDir,
|
|
||||||
Dir: &dirInput{
|
Dir: &dirInput{
|
||||||
Path: path,
|
Path: path,
|
||||||
Include: include,
|
Include: include,
|
||||||
@ -124,7 +110,6 @@ type gitInput struct {
|
|||||||
|
|
||||||
func GitInput(remote, ref, dir string) Input {
|
func GitInput(remote, ref, dir string) Input {
|
||||||
return Input{
|
return Input{
|
||||||
Type: InputTypeGit,
|
|
||||||
Git: &gitInput{
|
Git: &gitInput{
|
||||||
Remote: remote,
|
Remote: remote,
|
||||||
Ref: ref,
|
Ref: ref,
|
||||||
@ -149,7 +134,6 @@ func (git gitInput) Compile(_ *State) (*compiler.Value, error) {
|
|||||||
// An input artifact loaded from a docker container
|
// An input artifact loaded from a docker container
|
||||||
func DockerInput(ref string) Input {
|
func DockerInput(ref string) Input {
|
||||||
return Input{
|
return Input{
|
||||||
Type: InputTypeDocker,
|
|
||||||
Docker: &dockerInput{
|
Docker: &dockerInput{
|
||||||
Ref: ref,
|
Ref: ref,
|
||||||
},
|
},
|
||||||
@ -166,63 +150,62 @@ func (i dockerInput) Compile(_ *State) (*compiler.Value, error) {
|
|||||||
|
|
||||||
// An input value encoded as text
|
// An input value encoded as text
|
||||||
func TextInput(data string) Input {
|
func TextInput(data string) Input {
|
||||||
|
i := textInput(data)
|
||||||
return Input{
|
return Input{
|
||||||
Type: InputTypeText,
|
Text: &i,
|
||||||
Text: &textInput{
|
|
||||||
Data: data,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type textInput struct {
|
type textInput string
|
||||||
Data string `json:"data,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i textInput) Compile(_ *State) (*compiler.Value, error) {
|
func (i textInput) Compile(_ *State) (*compiler.Value, error) {
|
||||||
return compiler.Compile("", fmt.Sprintf("%q", i.Data))
|
return compiler.Compile("", fmt.Sprintf("%q", i))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A secret input value
|
||||||
|
func SecretInput(data string) Input {
|
||||||
|
i := secretInput(data)
|
||||||
|
return Input{
|
||||||
|
Secret: &i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type secretInput string
|
||||||
|
|
||||||
|
func (i secretInput) Compile(_ *State) (*compiler.Value, error) {
|
||||||
|
return compiler.Compile("", fmt.Sprintf("%q", i))
|
||||||
}
|
}
|
||||||
|
|
||||||
// An input value encoded as JSON
|
// An input value encoded as JSON
|
||||||
func JSONInput(data string) Input {
|
func JSONInput(data string) Input {
|
||||||
|
i := jsonInput(data)
|
||||||
return Input{
|
return Input{
|
||||||
Type: InputTypeJSON,
|
JSON: &i,
|
||||||
JSON: &jsonInput{
|
|
||||||
Data: data,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonInput struct {
|
type jsonInput string
|
||||||
// Marshalled JSON data
|
|
||||||
Data string `json:"data,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i jsonInput) Compile(_ *State) (*compiler.Value, error) {
|
func (i jsonInput) Compile(_ *State) (*compiler.Value, error) {
|
||||||
return compiler.DecodeJSON("", []byte(i.Data))
|
return compiler.DecodeJSON("", []byte(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
// An input value encoded as YAML
|
// An input value encoded as YAML
|
||||||
func YAMLInput(data string) Input {
|
func YAMLInput(data string) Input {
|
||||||
|
i := yamlInput(data)
|
||||||
return Input{
|
return Input{
|
||||||
Type: InputTypeYAML,
|
YAML: &i,
|
||||||
YAML: &yamlInput{
|
|
||||||
Data: data,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type yamlInput struct {
|
type yamlInput string
|
||||||
// Marshalled YAML data
|
|
||||||
Data string `json:"data,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i yamlInput) Compile(_ *State) (*compiler.Value, error) {
|
func (i yamlInput) Compile(_ *State) (*compiler.Value, error) {
|
||||||
return compiler.DecodeYAML("", []byte(i.Data))
|
return compiler.DecodeYAML("", []byte(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
func FileInput(data string) Input {
|
func FileInput(data string) Input {
|
||||||
return Input{
|
return Input{
|
||||||
Type: InputTypeFile,
|
|
||||||
File: &fileInput{
|
File: &fileInput{
|
||||||
Path: data,
|
Path: data,
|
||||||
},
|
},
|
||||||
|
@ -11,17 +11,12 @@ type State struct {
|
|||||||
Name string `yaml:"name,omitempty"`
|
Name string `yaml:"name,omitempty"`
|
||||||
|
|
||||||
// User Inputs
|
// User Inputs
|
||||||
Inputs []inputKV `yaml:"inputs,omitempty"`
|
Inputs map[string]Input `yaml:"inputs,omitempty"`
|
||||||
|
|
||||||
// Computed values
|
// Computed values
|
||||||
Computed string `yaml:"-"`
|
Computed string `yaml:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type inputKV struct {
|
|
||||||
Key string `yaml:"key,omitempty"`
|
|
||||||
Value Input `yaml:"value,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cue module containing the environment plan
|
// Cue module containing the environment plan
|
||||||
// The input's top-level artifact is used as a module directory.
|
// The input's top-level artifact is used as a module directory.
|
||||||
func (s *State) PlanSource() Input {
|
func (s *State) PlanSource() Input {
|
||||||
@ -29,15 +24,10 @@ func (s *State) PlanSource() Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) SetInput(key string, value Input) error {
|
func (s *State) SetInput(key string, value Input) error {
|
||||||
for i, inp := range s.Inputs {
|
if s.Inputs == nil {
|
||||||
if inp.Key != key {
|
s.Inputs = make(map[string]Input)
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Remove existing inputs with the same key
|
|
||||||
s.Inputs = append(s.Inputs[:i], s.Inputs[i+1:]...)
|
|
||||||
}
|
}
|
||||||
|
s.Inputs[key] = value
|
||||||
s.Inputs = append(s.Inputs, inputKV{Key: key, Value: value})
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,14 +35,6 @@ func (s *State) SetInput(key string, value Input) error {
|
|||||||
// For example RemoveInputs("foo.bar") will remove all inputs
|
// For example RemoveInputs("foo.bar") will remove all inputs
|
||||||
// at foo.bar, foo.bar.baz, etc.
|
// at foo.bar, foo.bar.baz, etc.
|
||||||
func (s *State) RemoveInputs(key string) error {
|
func (s *State) RemoveInputs(key string) error {
|
||||||
newInputs := make([]inputKV, 0, len(s.Inputs))
|
delete(s.Inputs, key)
|
||||||
for _, i := range s.Inputs {
|
|
||||||
if i.Key == key {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
newInputs = append(newInputs, i)
|
|
||||||
}
|
|
||||||
s.Inputs = newInputs
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user