From 48d8ca11ffa52f6c27d7586b129090d4c06358c1 Mon Sep 17 00:00:00 2001 From: Arief Rahmansyah Date: Fri, 7 Jul 2023 17:20:53 +0700 Subject: [PATCH] Add viperKeyDelimiter; Add unit test for imagebuilder nodeselectors (#424) **What this PR does / why we need it**: Previous implementation of Viper cannot load the YAML key that contains ".". For example, give this config file: ``` NodeSelectors: cloud.google.com/gke-nodepool: image-build-job-node-pool ``` config.Load will raise error: ``` Failed initializing config: failed to unmarshal config values: 1 error(s) decoding: * 'ImageBuilderConfig.NodeSelectors[cloud]' expected type 'string', got unconvertible type 'map[string]interface {}', value: 'map[google:map[com/gke-nodepool:image-build-job-node-pool]]' ``` This PR fixes this issue by setting viper key delimiter to `::` **Does this PR introduce a user-facing change?**: ```release-note NONE ``` **Checklist** - [ ] Added unit test, integration, and/or e2e tests - [x] Tested locally - [ ] Updated documentation - [ ] Update Swagger spec if the PR introduce API changes - [ ] Regenerated Golang and Python client if the PR introduce API changes --- api/config/config.go | 8 ++++--- api/config/environment_test.go | 23 +++++++++++++++++++ .../valid-imagebuilder-nodeselectors.yaml | 3 +++ 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 api/config/testdata/valid-imagebuilder-nodeselectors.yaml diff --git a/api/config/config.go b/api/config/config.go index 955ed986f..6f176d5f8 100644 --- a/api/config/config.go +++ b/api/config/config.go @@ -37,6 +37,8 @@ import ( ) const ( + viperKeyDelimiter = "::" + MaxDeployedVersion = 2 ) @@ -449,7 +451,7 @@ func (cfg *Config) Validate() error { // // Refer to example.yaml for an example of config file. func Load(spec interface{}, filepaths ...string) (*Config, error) { - v := viper.New() + v := viper.NewWithOptions(viper.KeyDelimiter(viperKeyDelimiter)) err := reflectViperConfig("", spec, v) if err != nil { @@ -468,7 +470,7 @@ func Load(spec interface{}, filepaths ...string) (*Config, error) { // Load config values from environment variables. // Nested keys in the config is represented by variable name separated by '_'. // For example, DbConfig.Host can be set from environment variable DBCONFIG_HOST. - v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + v.SetEnvKeyReplacer(strings.NewReplacer(viperKeyDelimiter, "_")) v.AutomaticEnv() // Unmarshal config values into the config object. @@ -511,7 +513,7 @@ func reflectViperConfig(prefix string, spec interface{}, v *viper.Viper) error { viperKey := ftype.Name // Nested struct tags if prefix != "" { - viperKey = fmt.Sprintf("%s.%s", prefix, ftype.Name) + viperKey = fmt.Sprintf("%s%s%s", prefix, viperKeyDelimiter, ftype.Name) } value := ftype.Tag.Get("default") if value == "-" { diff --git a/api/config/environment_test.go b/api/config/environment_test.go index 8a02f854c..0de264612 100644 --- a/api/config/environment_test.go +++ b/api/config/environment_test.go @@ -2,9 +2,11 @@ package config import ( "fmt" + "os" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "gopkg.in/yaml.v2" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -150,3 +152,24 @@ func TestPDBConfig(t *testing.T) { }) } } + +func TestImageBuilderConfig(t *testing.T) { + baseFilePath := "./testdata/config-1.yaml" + imageBuilderCfgFilePath := "./testdata/valid-imagebuilder-nodeselectors.yaml" + + os.Clearenv() + setRequiredEnvironmentVariables() + + filePaths := []string{baseFilePath} + filePaths = append(filePaths, imageBuilderCfgFilePath) + + var emptyCfg Config + cfg, err := Load(&emptyCfg, filePaths...) + require.NoError(t, err) + require.NotNil(t, cfg) + + expected := map[string]string{ + "cloud.google.com/gke-nodepool": "image-build-job-node-pool", + } + assert.Equal(t, expected, cfg.ImageBuilderConfig.NodeSelectors) +} diff --git a/api/config/testdata/valid-imagebuilder-nodeselectors.yaml b/api/config/testdata/valid-imagebuilder-nodeselectors.yaml new file mode 100644 index 000000000..f3722775a --- /dev/null +++ b/api/config/testdata/valid-imagebuilder-nodeselectors.yaml @@ -0,0 +1,3 @@ +ImageBuilderConfig: + NodeSelectors: + cloud.google.com/gke-nodepool: image-build-job-node-pool