diff --git a/.golangci.yml b/.golangci.yml index 97b6d15a3..00c50154f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -157,3 +157,4 @@ issues: - funlen - goconst - gocyclo + - wsl diff --git a/compiler/template/native/convert.go b/compiler/template/native/convert.go index 7a773b83b..68385c6cb 100644 --- a/compiler/template/native/convert.go +++ b/compiler/template/native/convert.go @@ -18,9 +18,22 @@ import ( func convertPlatformVars(slice raw.StringSliceMap, name string) raw.StringSliceMap { envs := make(map[string]string) + // iterate through the list of key/value pairs provided for key, value := range slice { + // lowercase the key key = strings.ToLower(key) + + // check if the key has a 'deployment_parameter_*' prefix + if strings.HasPrefix(key, "deployment_parameter_") { + // add the key/value pair with the 'deployment_parameter_` prefix + // + // this is used to ensure we prevent conflicts with `vela_*` prefixed variables + envs[key] = value + } + + // check if the key has a 'vela_*' prefix if strings.HasPrefix(key, "vela_") { + // add the key/value pair without the 'vela_` prefix envs[strings.TrimPrefix(key, "vela_")] = value } } @@ -54,14 +67,21 @@ type funcHandler struct { // returnPlatformVar returns the value of the platform // variable if it exists within the environment map. -func (h funcHandler) returnPlatformVar(input string) string { - input = strings.ToLower(input) - input = strings.TrimPrefix(input, "vela_") - // check if key exists within map - if _, ok := h.envs[input]; ok { - // return value if exists - return h.envs[input] +func (h funcHandler) returnPlatformVar(key string) string { + // lowercase the key + key = strings.ToLower(key) + + // iterate through the list of possible prefixes to look for + for _, prefix := range []string{"deployment_parameter_", "vela_"} { + // trim the prefix from the input key + trimmed := strings.TrimPrefix(key, prefix) + // check if the key exists within map + if _, ok := h.envs[trimmed]; ok { + // return the non-prefixed value if exists + return h.envs[trimmed] + } } + // return empty string if not exists return "" } diff --git a/compiler/template/native/convert_test.go b/compiler/template/native/convert_test.go index 9e350a2fe..db0b42a8f 100644 --- a/compiler/template/native/convert_test.go +++ b/compiler/template/native/convert_test.go @@ -18,6 +18,14 @@ func Test_convertPlatformVars(t *testing.T) { templateName string want raw.StringSliceMap }{ + { + name: "with all deployment parameter prefixed vars", + slice: raw.StringSliceMap{ + "DEPLOYMENT_PARAMETER_IMAGE": "alpine:3.14", + }, + templateName: "foo", + want: raw.StringSliceMap{"deployment_parameter_image": "alpine:3.14", "template_name": "foo"}, + }, { name: "with all vela prefixed vars", slice: raw.StringSliceMap{ @@ -30,15 +38,18 @@ func Test_convertPlatformVars(t *testing.T) { want: raw.StringSliceMap{"build_author": "octocat", "repo_full_name": "go-vela/hello-world", "user_admin": "true", "workspace": "/vela/src/github.com/go-vela/hello-world", "template_name": "foo"}, }, { - name: "with combination of vela and user vars", + name: "with combination of deployment parameter, vela, and user vars", slice: raw.StringSliceMap{ - "VELA_BUILD_AUTHOR": "octocat", - "VELA_REPO_FULL_NAME": "go-vela/hello-world", - "FOO_VAR1": "test1", - "BAR_VAR1": "test2", + "DEPLOYMENT_PARAMETER_IMAGE": "alpine:3.14", + "VELA_BUILD_AUTHOR": "octocat", + "VELA_REPO_FULL_NAME": "go-vela/hello-world", + "VELA_USER_ADMIN": "true", + "VELA_WORKSPACE": "/vela/src/github.com/go-vela/hello-world", + "FOO_VAR1": "test1", + "BAR_VAR1": "test2", }, templateName: "foo", - want: raw.StringSliceMap{"build_author": "octocat", "repo_full_name": "go-vela/hello-world", "template_name": "foo"}, + want: raw.StringSliceMap{"deployment_parameter_image": "alpine:3.14", "build_author": "octocat", "repo_full_name": "go-vela/hello-world", "user_admin": "true", "workspace": "/vela/src/github.com/go-vela/hello-world", "template_name": "foo"}, }, } @@ -66,6 +77,46 @@ func Test_funcHandler_returnPlatformVar(t *testing.T) { args args want string }{ + { + name: "existing deployment parameter without prefix (lowercase)", + fields: fields{ + envs: raw.StringSliceMap{ + "image": "alpine", + }, + }, + args: args{input: "image"}, + want: "alpine", + }, + { + name: "existing deployment parameter without prefix (uppercase)", + fields: fields{ + envs: raw.StringSliceMap{ + "image": "alpine", + }, + }, + args: args{input: "IMAGE"}, + want: "alpine", + }, + { + name: "existing deployment parameter with prefix (lowercase)", + fields: fields{ + envs: raw.StringSliceMap{ + "image": "alpine", + }, + }, + args: args{input: "deployment_parameter_image"}, + want: "alpine", + }, + { + name: "existing deployment parameter with prefix (uppercase)", + fields: fields{ + envs: raw.StringSliceMap{ + "image": "alpine", + }, + }, + args: args{input: "DEPLOYMENT_PARAMETER_IMAGE"}, + want: "alpine", + }, { name: "existing platform var without prefix (lowercase)", fields: fields{ diff --git a/compiler/template/starlark/convert.go b/compiler/template/starlark/convert.go index 9ec0d4ee5..474086316 100644 --- a/compiler/template/starlark/convert.go +++ b/compiler/template/starlark/convert.go @@ -47,6 +47,7 @@ func convertTemplateVars(m map[string]interface{}) (*starlark.Dict, error) { // https://pkg.go.dev/go.starlark.net/starlark#StringDict func convertPlatformVars(slice raw.StringSliceMap, name string) (*starlark.Dict, error) { build := starlark.NewDict(0) + deployment := starlark.NewDict(0) repo := starlark.NewDict(0) user := starlark.NewDict(0) system := starlark.NewDict(0) @@ -57,6 +58,11 @@ func convertPlatformVars(slice raw.StringSliceMap, name string) (*starlark.Dict, return nil, err } + err = dict.SetKey(starlark.String("deployment"), deployment) + if err != nil { + return nil, err + } + err = dict.SetKey(starlark.String("repo"), repo) if err != nil { return nil, err @@ -77,31 +83,47 @@ func convertPlatformVars(slice raw.StringSliceMap, name string) (*starlark.Dict, return nil, err } + // iterate through the list of key/value pairs provided for key, value := range slice { + // lowercase the key key = strings.ToLower(key) - if strings.HasPrefix(key, "vela_") { - key = strings.TrimPrefix(key, "vela_") - - switch { - case strings.HasPrefix(key, "build_"): - err := build.SetKey(starlark.String(strings.TrimPrefix(key, "build_")), starlark.String(value)) - if err != nil { - return nil, err - } - case strings.HasPrefix(key, "repo_"): - err := repo.SetKey(starlark.String(strings.TrimPrefix(key, "repo_")), starlark.String(value)) - if err != nil { - return nil, err - } - case strings.HasPrefix(key, "user_"): - err := user.SetKey(starlark.String(strings.TrimPrefix(key, "user_")), starlark.String(value)) - if err != nil { - return nil, err - } - default: - err := system.SetKey(starlark.String(key), starlark.String(value)) - if err != nil { - return nil, err + + // iterate through the list of possible prefixes to look for + for _, prefix := range []string{"deployment_parameter_", "vela_"} { + // check if the key has the prefix + if strings.HasPrefix(key, prefix) { + // trim the prefix from the input key + key = strings.TrimPrefix(key, prefix) + + // check if the prefix is from 'vela_*' + if strings.EqualFold(prefix, "vela_") { + switch { + case strings.HasPrefix(key, "build_"): + err := build.SetKey(starlark.String(strings.TrimPrefix(key, "build_")), starlark.String(value)) + if err != nil { + return nil, err + } + case strings.HasPrefix(key, "repo_"): + err := repo.SetKey(starlark.String(strings.TrimPrefix(key, "repo_")), starlark.String(value)) + if err != nil { + return nil, err + } + case strings.HasPrefix(key, "user_"): + err := user.SetKey(starlark.String(strings.TrimPrefix(key, "user_")), starlark.String(value)) + if err != nil { + return nil, err + } + default: + err := system.SetKey(starlark.String(key), starlark.String(value)) + if err != nil { + return nil, err + } + } + } else { // prefix is from 'deployment_parameter_*' + err := deployment.SetKey(starlark.String(key), starlark.String(value)) + if err != nil { + return nil, err + } } } } diff --git a/compiler/template/starlark/convert_test.go b/compiler/template/starlark/convert_test.go index cfaae4acb..b6eb03bf8 100644 --- a/compiler/template/starlark/convert_test.go +++ b/compiler/template/starlark/convert_test.go @@ -82,59 +82,112 @@ func TestStarlark_Render_convertTemplateVars(t *testing.T) { } } -func TestStarlark_Render_velaEnvironmentData(t *testing.T) { +func TestStarlark_Render_convertPlatformVars(t *testing.T) { // setup types - build := starlark.NewDict(1) - + build := starlark.NewDict(0) err := build.SetKey(starlark.String("author"), starlark.String("octocat")) if err != nil { t.Error(err) } - repo := starlark.NewDict(1) + deployment := starlark.NewDict(0) + err = deployment.SetKey(starlark.String("image"), starlark.String("alpine:3.14")) + if err != nil { + t.Error(err) + } + repo := starlark.NewDict(0) err = repo.SetKey(starlark.String("full_name"), starlark.String("go-vela/hello-world")) if err != nil { t.Error(err) } - user := starlark.NewDict(1) - + user := starlark.NewDict(0) err = user.SetKey(starlark.String("admin"), starlark.String("true")) if err != nil { t.Error(err) } - system := starlark.NewDict(2) - + system := starlark.NewDict(0) err = system.SetKey(starlark.String("template_name"), starlark.String("foo")) if err != nil { t.Error(err) } - err = system.SetKey(starlark.String("workspace"), starlark.String("/vela/src/github.com/go-vela/hello-world")) if err != nil { t.Error(err) } - withAllPre := starlark.NewDict(0) - - err = withAllPre.SetKey(starlark.String("build"), build) + // setup full dictionary + withAll := starlark.NewDict(0) + err = withAll.SetKey(starlark.String("build"), build) if err != nil { t.Error(err) } - - err = withAllPre.SetKey(starlark.String("repo"), repo) + err = withAll.SetKey(starlark.String("deployment"), deployment) + if err != nil { + t.Error(err) + } + err = withAll.SetKey(starlark.String("repo"), repo) + if err != nil { + t.Error(err) + } + err = withAll.SetKey(starlark.String("user"), user) + if err != nil { + t.Error(err) + } + err = withAll.SetKey(starlark.String("system"), system) if err != nil { t.Error(err) } - err = withAllPre.SetKey(starlark.String("user"), user) + // setup vela dictionary + withAllVela := starlark.NewDict(0) + err = withAllVela.SetKey(starlark.String("build"), build) + if err != nil { + t.Error(err) + } + err = withAllVela.SetKey(starlark.String("deployment"), starlark.NewDict(0)) + if err != nil { + t.Error(err) + } + err = withAllVela.SetKey(starlark.String("repo"), repo) + if err != nil { + t.Error(err) + } + err = withAllVela.SetKey(starlark.String("user"), user) + if err != nil { + t.Error(err) + } + err = withAllVela.SetKey(starlark.String("system"), system) if err != nil { t.Error(err) } - err = withAllPre.SetKey(starlark.String("system"), system) + // setup deployment dictionary + withAllDeployment := starlark.NewDict(0) + err = withAllDeployment.SetKey(starlark.String("build"), starlark.NewDict(0)) + if err != nil { + t.Error(err) + } + err = withAllDeployment.SetKey(starlark.String("deployment"), deployment) + if err != nil { + t.Error(err) + } + err = withAllDeployment.SetKey(starlark.String("repo"), starlark.NewDict(0)) + if err != nil { + t.Error(err) + } + err = withAllDeployment.SetKey(starlark.String("user"), starlark.NewDict(0)) + if err != nil { + t.Error(err) + } + system = starlark.NewDict(0) + err = system.SetKey(starlark.String("template_name"), starlark.String("foo")) + if err != nil { + t.Error(err) + } + err = withAllDeployment.SetKey(starlark.String("system"), system) if err != nil { t.Error(err) } @@ -146,6 +199,14 @@ func TestStarlark_Render_velaEnvironmentData(t *testing.T) { want *starlark.Dict wantErr bool }{ + { + name: "with all deployment parameter prefixed vars", + slice: raw.StringSliceMap{ + "DEPLOYMENT_PARAMETER_IMAGE": "alpine:3.14", + }, + templateName: "foo", + want: withAllDeployment, + }, { name: "with all vela prefixed var", slice: raw.StringSliceMap{ @@ -155,7 +216,21 @@ func TestStarlark_Render_velaEnvironmentData(t *testing.T) { "VELA_WORKSPACE": "/vela/src/github.com/go-vela/hello-world", }, templateName: "foo", - want: withAllPre, + want: withAllVela, + }, + { + name: "with combination of deployment parameter, vela, and user vars", + slice: raw.StringSliceMap{ + "DEPLOYMENT_PARAMETER_IMAGE": "alpine:3.14", + "VELA_BUILD_AUTHOR": "octocat", + "VELA_REPO_FULL_NAME": "go-vela/hello-world", + "VELA_USER_ADMIN": "true", + "VELA_WORKSPACE": "/vela/src/github.com/go-vela/hello-world", + "FOO_VAR1": "test1", + "BAR_VAR1": "test2", + }, + templateName: "foo", + want: withAll, }, }