From 19101a5b1346caaeb675fb5f7e5a100277381a88 Mon Sep 17 00:00:00 2001 From: claire1618 <55173466+claire1618@users.noreply.github.com> Date: Tue, 24 Oct 2023 15:11:26 -0500 Subject: [PATCH] feat(yaml/secret): adding pull tag to secrets to create a lazy secrets ability (#312) * feat: adding pull tag to secrets to create a lazy secrets ability * fixing testing errors * fixing testing errors * changing pull tag options * fixing tests * fixing linter errors * fixing some errors * fixing formatting * fixing errors --------- Co-authored-by: Claire.Nicholas Co-authored-by: Tim Huynh Co-authored-by: David May <49894298+wass3rw3rk@users.noreply.github.com> Co-authored-by: Easton Crupper <65553218+ecrupper@users.noreply.github.com> --- constants/secret.go | 6 ++++++ pipeline/secret.go | 1 + pipeline/secret_test.go | 30 ++++++++++++++++++++++++++++++ yaml/build_test.go | 6 ++++++ yaml/secret.go | 7 +++++++ yaml/secret_test.go | 11 +++++++++++ yaml/testdata/secret.yml | 1 + 7 files changed, 62 insertions(+) diff --git a/constants/secret.go b/constants/secret.go index 13628e95..bb794f02 100644 --- a/constants/secret.go +++ b/constants/secret.go @@ -4,6 +4,12 @@ package constants // Secret types. const ( + // SecretPullBuild defines the pull policy type for a secret. + SecretPullBuild = "build_start" + + // SecretPullStep defines the pull policy type for a secret. + SecretPullStep = "step_start" + // SecretOrg defines the secret type for a secret scoped to a specific org. SecretOrg = "org" diff --git a/pipeline/secret.go b/pipeline/secret.go index 94250afe..bbc5e260 100644 --- a/pipeline/secret.go +++ b/pipeline/secret.go @@ -28,6 +28,7 @@ type ( Engine string `json:"engine,omitempty" yaml:"engine,omitempty"` Type string `json:"type,omitempty" yaml:"type,omitempty"` Origin *Container `json:"origin,omitempty" yaml:"origin,omitempty"` + Pull string `json:"pull,omitempty" yaml:"pull,omitempty"` } // StepSecretSlice is the pipeline representation diff --git a/pipeline/secret_test.go b/pipeline/secret_test.go index 8137e757..bf5bfbc4 100644 --- a/pipeline/secret_test.go +++ b/pipeline/secret_test.go @@ -60,6 +60,7 @@ func TestPipeline_Secret_ParseOrg_success(t *testing.T) { Key: "octocat/foo", Engine: "native", Type: "org", + Pull: "build_start", }, org: "octocat", }, @@ -70,6 +71,7 @@ func TestPipeline_Secret_ParseOrg_success(t *testing.T) { Key: "octocat/๐Ÿ‘‹/๐Ÿงช/๐Ÿ”‘", Engine: "native", Type: "org", + Pull: "build_start", }, org: "octocat", }, @@ -108,6 +110,7 @@ func TestPipeline_Secret_ParseOrg_failure(t *testing.T) { Key: "octocat/foo", Engine: "native", Type: "org", + Pull: "build_start", }, org: "wrongorg", wantErr: ErrInvalidOrg, @@ -119,6 +122,7 @@ func TestPipeline_Secret_ParseOrg_failure(t *testing.T) { Key: "octocat", Engine: "native", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidPath, @@ -130,6 +134,7 @@ func TestPipeline_Secret_ParseOrg_failure(t *testing.T) { Key: "octocat/", Engine: "native", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidPath, @@ -140,6 +145,7 @@ func TestPipeline_Secret_ParseOrg_failure(t *testing.T) { Key: "octocat/foo/bar", Engine: "native", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidName, @@ -151,6 +157,7 @@ func TestPipeline_Secret_ParseOrg_failure(t *testing.T) { Key: "octocat/foo/bar", Engine: "native", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidName, @@ -162,6 +169,7 @@ func TestPipeline_Secret_ParseOrg_failure(t *testing.T) { Key: "octocat/foo", Engine: "invalid", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidEngine, @@ -195,6 +203,7 @@ func TestPipeline_Secret_ParseRepo_success(t *testing.T) { Key: "octocat/helloworld/foo", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "octocat", repo: "helloworld", @@ -206,6 +215,7 @@ func TestPipeline_Secret_ParseRepo_success(t *testing.T) { Key: "octocat/๐Ÿ‘‹/๐Ÿงช/๐Ÿ”‘", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "octocat", repo: "๐Ÿ‘‹", @@ -253,6 +263,7 @@ func TestPipeline_Secret_ParseRepo_failure(t *testing.T) { Key: "octocat/helloworld/foo", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "wrongorg", repo: "helloworld", @@ -265,6 +276,7 @@ func TestPipeline_Secret_ParseRepo_failure(t *testing.T) { Key: "octocat/helloworld/foo", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "octocat", repo: "badrepo", @@ -277,6 +289,7 @@ func TestPipeline_Secret_ParseRepo_failure(t *testing.T) { Key: "octocat", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidPath, @@ -288,6 +301,7 @@ func TestPipeline_Secret_ParseRepo_failure(t *testing.T) { Key: "octocat/helloworld", Engine: "native", Type: "org", + Pull: "build_start", }, repo: "helloworld", org: "octocat", @@ -300,6 +314,7 @@ func TestPipeline_Secret_ParseRepo_failure(t *testing.T) { Key: "octocat/helloworld/", Engine: "native", Type: "org", + Pull: "build_start", }, repo: "helloworld", org: "octocat", @@ -311,6 +326,7 @@ func TestPipeline_Secret_ParseRepo_failure(t *testing.T) { Key: "octocat/helloworld/foo/bar", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "octocat", repo: "helloworld", @@ -323,6 +339,7 @@ func TestPipeline_Secret_ParseRepo_failure(t *testing.T) { Key: "octocat/helloworld/foo/bar", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "octocat", repo: "helloworld", @@ -335,6 +352,7 @@ func TestPipeline_Secret_ParseRepo_failure(t *testing.T) { Key: "octocat", Engine: "invalid", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidEngine, @@ -346,6 +364,7 @@ func TestPipeline_Secret_ParseRepo_failure(t *testing.T) { Key: "foo", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "octocat", repo: "helloworld", @@ -379,6 +398,7 @@ func TestPipeline_Secret_ParseShared_success(t *testing.T) { Key: "octocat/helloworld/foo", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "octocat", }, @@ -389,6 +409,7 @@ func TestPipeline_Secret_ParseShared_success(t *testing.T) { Key: "octocat/๐Ÿ‘‹/๐Ÿงช/๐Ÿ”‘", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "octocat", }, @@ -431,6 +452,7 @@ func TestPipeline_Secret_ParseShared_failure(t *testing.T) { Key: "octocat", Engine: "native", Type: "repo", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidPath, @@ -442,6 +464,7 @@ func TestPipeline_Secret_ParseShared_failure(t *testing.T) { Key: "octocat", Engine: "invalid", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidEngine, @@ -453,6 +476,7 @@ func TestPipeline_Secret_ParseShared_failure(t *testing.T) { Key: "octocat/foo", Engine: "native", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidPath, @@ -464,6 +488,7 @@ func TestPipeline_Secret_ParseShared_failure(t *testing.T) { Key: "octocat/foo/", Engine: "native", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidPath, @@ -474,6 +499,7 @@ func TestPipeline_Secret_ParseShared_failure(t *testing.T) { Key: "octocat/foo/bar", Engine: "native", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidName, @@ -485,6 +511,7 @@ func TestPipeline_Secret_ParseShared_failure(t *testing.T) { Key: "octocat/foo/bar", Engine: "native", Type: "org", + Pull: "build_start", }, org: "octocat", wantErr: ErrInvalidName, @@ -512,6 +539,7 @@ func testSecrets() *SecretSlice { Name: "foobar", Type: "repo", Origin: &Container{}, + Pull: "build_start", }, { Engine: "native", @@ -519,6 +547,7 @@ func testSecrets() *SecretSlice { Name: "foobar", Type: "org", Origin: &Container{}, + Pull: "build_start", }, { Engine: "native", @@ -526,6 +555,7 @@ func testSecrets() *SecretSlice { Name: "foobar", Type: "shared", Origin: &Container{}, + Pull: "build_start", }, { Name: "", diff --git a/yaml/build_test.go b/yaml/build_test.go index 4b652e98..f3576327 100644 --- a/yaml/build_test.go +++ b/yaml/build_test.go @@ -260,36 +260,42 @@ func TestYaml_Build_UnmarshalYAML(t *testing.T) { Key: "org/repo/docker/username", Engine: "native", Type: "repo", + Pull: "build_start", }, { Name: "docker_password", Key: "org/repo/docker/password", Engine: "vault", Type: "repo", + Pull: "build_start", }, { Name: "docker_username", Key: "org/docker/username", Engine: "native", Type: "org", + Pull: "build_start", }, { Name: "docker_password", Key: "org/docker/password", Engine: "vault", Type: "org", + Pull: "build_start", }, { Name: "docker_username", Key: "org/team/docker/username", Engine: "native", Type: "shared", + Pull: "build_start", }, { Name: "docker_password", Key: "org/team/docker/password", Engine: "vault", Type: "shared", + Pull: "build_start", }, { Origin: Origin{ diff --git a/yaml/secret.go b/yaml/secret.go index a211a245..2c44e5ab 100644 --- a/yaml/secret.go +++ b/yaml/secret.go @@ -25,6 +25,7 @@ type ( Engine string `yaml:"engine,omitempty" json:"engine,omitempty" jsonschema:"enum=native,enum=vault,default=native,description=Name of storage backend to fetch secret from.\nReference: https://go-vela.github.io/docs/reference/yaml/secrets/#the-engine-tag"` Type string `yaml:"type,omitempty" json:"type,omitempty" jsonschema:"enum=repo,enum=org,enum=shared,default=repo,description=Type of secret to fetch from storage backend.\nReference: https://go-vela.github.io/docs/reference/yaml/secrets/#the-type-tag"` Origin Origin `yaml:"origin,omitempty" json:"origin,omitempty" jsonschema:"description=Declaration to pull secrets from non-internal secret providers.\nReference: https://go-vela.github.io/docs/reference/yaml/secrets/#the-origin-tag"` + Pull string `yaml:"pull,omitempty" json:"pull,omitempty" jsonschema:"default=build_start,description=When to pull in secrets from storage backend."` } // Origin is the yaml representation of a method @@ -55,6 +56,7 @@ func (s *SecretSlice) ToPipeline() *pipeline.SecretSlice { Engine: secret.Engine, Type: secret.Type, Origin: secret.Origin.ToPipeline(), + Pull: secret.Pull, }) } @@ -94,6 +96,11 @@ func (s *SecretSlice) UnmarshalYAML(unmarshal func(interface{}) error) error { secret.Type = constants.SecretRepo } + // implicitly set `type` field if empty + if secret.Origin.Empty() && len(secret.Pull) == 0 { + secret.Pull = constants.SecretPullBuild + } + // implicitly set `pull` field if empty if !secret.Origin.Empty() && len(secret.Origin.Pull) == 0 { secret.Origin.Pull = constants.PullNotPresent diff --git a/yaml/secret_test.go b/yaml/secret_test.go index 9cb4dae6..f70637e6 100644 --- a/yaml/secret_test.go +++ b/yaml/secret_test.go @@ -108,6 +108,7 @@ func TestYaml_SecretSlice_ToPipeline(t *testing.T) { Engine: "native", Type: "repo", Origin: Origin{}, + Pull: "build_start", }, { Name: "docker_username", @@ -139,6 +140,7 @@ func TestYaml_SecretSlice_ToPipeline(t *testing.T) { }, }, }, + Pull: "build_start", }, }, want: &pipeline.SecretSlice{ @@ -148,6 +150,7 @@ func TestYaml_SecretSlice_ToPipeline(t *testing.T) { Engine: "native", Type: "repo", Origin: &pipeline.Container{}, + Pull: "build_start", }, { Name: "docker_username", @@ -176,6 +179,7 @@ func TestYaml_SecretSlice_ToPipeline(t *testing.T) { }, }, }, + Pull: "build_start", }, }, }, @@ -207,30 +211,35 @@ func TestYaml_SecretSlice_UnmarshalYAML(t *testing.T) { Key: "bar", Engine: "native", Type: "repo", + Pull: "build_start", }, { Name: "noKey", Key: "noKey", Engine: "native", Type: "repo", + Pull: "build_start", }, { Name: "noType", Key: "bar", Engine: "native", Type: "repo", + Pull: "build_start", }, { Name: "noEngine", Key: "bar", Engine: "native", Type: "repo", + Pull: "build_start", }, { Name: "noKeyEngineAndType", Key: "noKeyEngineAndType", Engine: "native", Type: "repo", + Pull: "build_start", }, { Name: "externalSecret", @@ -262,6 +271,7 @@ func TestYaml_SecretSlice_UnmarshalYAML(t *testing.T) { }, }, }, + Pull: "", }, { Name: "", @@ -293,6 +303,7 @@ func TestYaml_SecretSlice_UnmarshalYAML(t *testing.T) { }, }, }, + Pull: "", }, }, }, diff --git a/yaml/testdata/secret.yml b/yaml/testdata/secret.yml index 72a56cb0..c432eb29 100644 --- a/yaml/testdata/secret.yml +++ b/yaml/testdata/secret.yml @@ -5,6 +5,7 @@ key: bar engine: native type: repo + pull: build_start - name: noKey engine: native type: repo