diff --git a/.drone.yml b/.drone.yml index 794ed55..a292a74 100644 --- a/.drone.yml +++ b/.drone.yml @@ -10,6 +10,7 @@ steps: - name: test image: golang:1.11 commands: + - go vet ./... - go test ./... ... diff --git a/LICENSE b/LICENSE index 56f38f4..d6ab6bc 100644 --- a/LICENSE +++ b/LICENSE @@ -2,13 +2,13 @@ Copyright 2019 Drone.IO, Inc. Source code in this repository is variously licensed under the Apache License Version 2.0, an Apache compatible license, or the -Drone Community License. Source code in a given file is licensed -under the Drone Community License unless otherwise noted at the -beginning of the file. +Drone Non-Commercial License. Source code in a given file is +licensed under the Drone Non-Commercial License unless otherwise +noted at the beginning of the file. ----------------------------------------------------------------- -Drone Community License +Drone Non-Commercial License Contributor: Drone.IO, Inc. diff --git a/yaml/compiler/step.go b/yaml/compiler/step.go index a6a5a0f..dc0c77d 100644 --- a/yaml/compiler/step.go +++ b/yaml/compiler/step.go @@ -86,9 +86,9 @@ func createStep(spec *engine.Spec, src *yaml.Container) *engine.Step { // appends the environment variables to the // container definition. for key, value := range src.Environment { - if value.Secret != "" { + if value.Secret.Name != "" { sec := &engine.SecretVar{ - Name: value.Secret, + Name: value.Secret.Name, Env: key, } dst.Secrets = append(dst.Secrets, sec) @@ -106,9 +106,9 @@ func createStep(spec *engine.Spec, src *yaml.Container) *engine.Step { // if the setting parameter is sources from the // secret we create a secret enviornment variable. - if value.Secret != "" { + if value.Secret.Name != "" { sec := &engine.SecretVar{ - Name: value.Secret, + Name: value.Secret.Name, Env: key, } dst.Secrets = append(dst.Secrets, sec) diff --git a/yaml/converter/legacy/internal/config.go b/yaml/converter/legacy/internal/config.go index 671cb27..c000ff6 100644 --- a/yaml/converter/legacy/internal/config.go +++ b/yaml/converter/legacy/internal/config.go @@ -195,7 +195,7 @@ func toEnvironment(from *Container) map[string]*droneyaml.Variable { for _, val := range from.Secrets.Secrets { name := strings.ToUpper(val.Target) envs[name] = &droneyaml.Variable{ - Secret: val.Source, + Secret: droneyaml.FromSecret{Name: val.Source}, } } return envs diff --git a/yaml/env.go b/yaml/env.go index 5dbae74..9df5da3 100644 --- a/yaml/env.go +++ b/yaml/env.go @@ -19,26 +19,27 @@ type ( // can be defined as a string literal or as a reference // to a secret. Variable struct { - Value string `json:"value,omitempty"` - Secret string `json:"from_secret,omitempty" yaml:"from_secret"` + Value string `json:"value,omitempty"` + Secret FromSecret `json:"from_secret,omitempty" yaml:"from_secret"` } // variable is a tempoary type used to unmarshal // variables with references to secrets. variable struct { - Value string - Secret string `yaml:"from_secret"` + FromSecret FromSecret `yaml:"from_secret"` } ) // UnmarshalYAML implements yaml unmarshalling. func (v *Variable) UnmarshalYAML(unmarshal func(interface{}) error) error { d := new(variable) - err := unmarshal(&d.Value) - if err != nil { - err = unmarshal(d) + err := unmarshal(d) + if err == nil && (d.FromSecret.Name != "" || d.FromSecret.Path != "") { + v.Secret = d.FromSecret + return nil } - v.Value = d.Value - v.Secret = d.Secret + var s string + err = unmarshal(&s) + v.Value = s return err } diff --git a/yaml/env_test.go b/yaml/env_test.go index 5961dbc..5836e38 100644 --- a/yaml/env_test.go +++ b/yaml/env_test.go @@ -14,7 +14,8 @@ func TestEnv(t *testing.T) { tests := []struct { yaml string value string - from string + name string + path string }{ { yaml: "bar", @@ -22,7 +23,12 @@ func TestEnv(t *testing.T) { }, { yaml: "from_secret: username", - from: "username", + name: "username", + }, + { + yaml: "from_secret: { name: username, path: secret/data/docker }", + name: "username", + path: "secret/data/docker", }, } for _, test := range tests { @@ -36,8 +42,11 @@ func TestEnv(t *testing.T) { if got, want := out.Value, test.value; got != want { t.Errorf("Want variable value %q, got %q", want, got) } - if got, want := out.Secret, test.from; got != want { - t.Errorf("Want variable from_secret %q, got %q", want, got) + if got, want := out.Secret.Name, test.name; got != want { + t.Errorf("Want variable from_secret.name %q, got %q", want, got) + } + if got, want := out.Secret.Path, test.path; got != want { + t.Errorf("Want variable from_secret.path %q, got %q", want, got) } } } diff --git a/yaml/param.go b/yaml/param.go index 61fac2c..5a18205 100644 --- a/yaml/param.go +++ b/yaml/param.go @@ -1,11 +1,11 @@ // Copyright 2019 Drone IO, Inc. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,13 +20,13 @@ type ( // to a secret. Parameter struct { Value interface{} `json:"value,omitempty"` - Secret string `json:"from_secret,omitempty" yaml:"from_secret"` + Secret FromSecret `json:"from_secret,omitempty" yaml:"from_secret"` } // parameter is a tempoary type used to unmarshal // parameters with references to secrets. parameter struct { - Secret string `yaml:"from_secret"` + FromSecret FromSecret `yaml:"from_secret"` } ) @@ -34,8 +34,8 @@ type ( func (p *Parameter) UnmarshalYAML(unmarshal func(interface{}) error) error { d := new(parameter) err := unmarshal(d) - if err == nil && d.Secret != ""{ - p.Secret = d.Secret + if err == nil && (d.FromSecret.Name != "" || d.FromSecret.Path != "") { + p.Secret = d.FromSecret return nil } var i interface{} diff --git a/yaml/param_test.go b/yaml/param_test.go index 1136b13..d0427df 100644 --- a/yaml/param_test.go +++ b/yaml/param_test.go @@ -5,6 +5,7 @@ package yaml import ( + "reflect" "testing" "gopkg.in/yaml.v2" @@ -14,15 +15,32 @@ func TestParam(t *testing.T) { tests := []struct { yaml string value interface{} - from string + name string + path string }{ { yaml: "bar", value: "bar", + name: "", + path: "", }, { - yaml: "from_secret: username", - from: "username", + yaml: "[ bar ]", + value: []interface{}{"bar"}, + name: "", + path: "", + }, + { + yaml: "from_secret: username", + value: nil, + name: "username", + path: "", + }, + { + yaml: "from_secret: { path: secret/data/docker, name: username }", + value: nil, + name: "username", + path: "secret/data/docker", }, } for _, test := range tests { @@ -33,11 +51,14 @@ func TestParam(t *testing.T) { t.Error(err) return } - if got, want := out.Value, test.value; got != want { - t.Errorf("Want value %q, got %q", want, got) + if got, want := out.Value, test.value; !reflect.DeepEqual(got, want) { + t.Errorf("Want value %q of type %T, got %q of type %T", want, want, got, got) } - if got, want := out.Secret, test.from; got != want { - t.Errorf("Want from_secret %q, got %q", want, got) + if got, want := out.Secret.Name, test.name; got != want { + t.Errorf("Want from_secret.name %q, got %q", want, got) + } + if got, want := out.Secret.Path, test.path; got != want { + t.Errorf("Want from_secret.path %q, got %q", want, got) } } } diff --git a/yaml/pretty/container.go b/yaml/pretty/container.go index def83cb..6cf1359 100644 --- a/yaml/pretty/container.go +++ b/yaml/pretty/container.go @@ -114,12 +114,12 @@ func printEnviron(w writer, v map[string]*yaml.Variable) { w.IndentIncrease() for _, k := range keys { v := v[k] - if v.Secret == "" { + if v.Secret.Name == "" && v.Secret.Path == "" { w.WriteTagValue(k, v.Value) } else { w.WriteTag(k) w.IndentIncrease() - w.WriteTagValue("from_secret", v.Secret) + printFromSecret(w, v.Secret) w.IndentDecrease() } } @@ -183,12 +183,12 @@ func printSettings(w writer, v map[string]*yaml.Parameter) { w.IndentIncrease() for _, k := range keys { v := v[k] - if v.Secret == "" { + if v.Secret.Name == "" && v.Secret.Path == "" { w.WriteTagValue(k, v.Value) } else { w.WriteTag(k) w.IndentIncrease() - w.WriteTagValue("from_secret", v.Secret) + printFromSecret(w, v.Secret) w.IndentDecrease() } } @@ -208,6 +208,19 @@ func printVolumeMounts(w writer, v []*yaml.VolumeMount) { } } +// helper function pretty prints the from_secret sequence. +func printFromSecret(w writer, v yaml.FromSecret) { + if v.Path == "" { + w.WriteTagValue("from_secret", v.Name) + } else { + w.WriteTag("from_secret") + w.IndentIncrease() + w.WriteTagValue("path", v.Path) + w.WriteTagValue("name", v.Name) + w.IndentDecrease() + } +} + // helper function returns true if the Build block should // be printed in short form. func shortBuild(b *yaml.Build) bool {