Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix env vars in Go #576

Merged
merged 5 commits into from
Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions pkg/course/course.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,19 @@ type FileV2 struct {
// Hooks is a set of scripts to be run before or after the release is installed.
Hooks Hooks `yaml:"hooks,omitempty" json:"hooks,omitempty"`
// NamespaceMgmt contains the default namespace config for all namespaces managed by this course.
NamespaceMgmt struct {
// Default is the default namespace config for this course
Default *NamespaceConfig `yaml:"default" json:"default"`
} `yaml:"namespace_management,omitempty" json:"namespace_management,omitempty"`
Secrets SecretsList `yaml:"secrets,omitempty" json:"secrets,omitempty"`
NamespaceMgmt NamespaceMgmt `yaml:"namespace_management,omitempty" json:"namespace_management,omitempty"`
Secrets SecretsList `yaml:"secrets,omitempty" json:"secrets,omitempty"`
// Releases is the list of releases that should be maintained by this course file.
Releases []*Release `yaml:"releases,omitempty" json:"releases,omitempty"`
// HelmArgs is a list of arguments to pass to helm commands
HelmArgs []string `yaml:"helm_args,omitempty" json:"helm_args,omitempty"`
}

type NamespaceMgmt struct {
// Default is the default namespace config for this course
Default *NamespaceConfig `yaml:"default" json:"default"`
}

// FileV2Unmarshal is a helper type that allows us to have a custom unmarshal function for the FileV2 struct
type FileV2Unmarshal FileV2

Expand All @@ -95,14 +97,18 @@ type Hooks struct {

// NamespaceConfig allows setting namespace annotations and labels
type NamespaceConfig struct {
Metadata struct {
Annotations map[string]string `yaml:"annotations,omitempty" json:"annotations,omitempty"`
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
} `yaml:"metadata,omitempty" json:"metadata,omitempty"`
Settings struct {
// Overwrite specifies if these annotations and labels should be overwritten in the event that they already exist.
Overwrite *bool `yaml:"overwrite,omitempty" json:"overwrite,omitempty"`
} `yaml:"settings" json:"settings"`
Metadata NSMetadata `yaml:"metadata,omitempty" json:"metadata,omitempty"`
Settings NSSettings `yaml:"settings" json:"settings"`
}

type NSMetadata struct {
Annotations map[string]string `yaml:"annotations,omitempty" json:"annotations,omitempty"`
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
}

type NSSettings struct {
// Overwrite specifies if these annotations and labels should be overwritten in the event that they already exist.
Overwrite *bool `yaml:"overwrite,omitempty" json:"overwrite,omitempty"`
}

// Release represents a helm release and all of its configuration
Expand Down Expand Up @@ -435,6 +441,15 @@ func decodeYamlWithEnv(value *yaml.Node) error {
if v.Kind == yaml.SequenceNode {
for i := range v.Content {
var err error

if v.Content[i].Kind != yaml.ScalarNode {
err := decodeYamlWithEnv(v.Content[i])
if err != nil {
return err
}
continue
}

v.Content[i].Value, err = parseEnv(v.Content[i].Value)
if err != nil {
return err
Expand Down
72 changes: 72 additions & 0 deletions pkg/course/course_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,16 @@ func Test_parseEnv(t *testing.T) {
},
wantErr: false,
},
{
name: "multiple env vars",
data: `$TEST_ENV_KEY some other text $TEST_ENV_KEY2`,
want: "value1 some other text value2",
envMap: map[string]string{
"TEST_ENV_KEY": "value1",
"TEST_ENV_KEY2": "value2",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -277,3 +287,65 @@ func Test_boolPtr(t *testing.T) {
testBool := true
assert.EqualValues(t, &testBool, boolPtr(testBool))
}

func TestOpenCourseV2(t *testing.T) {
tests := []struct {
name string
fileName string
envMap map[string]string
want *FileV2
wantErr bool
}{
{
name: "file not exist",
fileName: "thisfileshouldneverexist",
wantErr: true,
},
{
name: "test env var with v2 course",
fileName: "testdata/v2_env.yaml",
envMap: map[string]string{
"EXAMPLE_ENV_VAR": "example-env-value",
"EXAMPLE_ENV_NS": "example-env-ns",
"HELM_REPO_URL": "https://example.com/stable",
},
want: &FileV2{
SchemaVersion: "v2",
DefaultRepository: "helm-repo",
DefaultNamespace: "example-env-ns",
Context: "farglebargle",
Repositories: map[string]Repository{
"helm-repo": {
URL: "https://example.com/stable",
},
},
Releases: []*Release{
{
Name: "basic",
Namespace: "namespace",
Chart: "somechart",
Repository: "helm-repo",
Version: "2.0.0",
Values: map[string]interface{}{
"envVar": "example-env-value",
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for k, v := range tt.envMap {
os.Setenv(k, v)
}
got, err := OpenCourseV2(tt.fileName)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.EqualValues(t, tt.want, got)
}
})
}
}
15 changes: 15 additions & 0 deletions pkg/course/testdata/v2_env.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
schema: v2
namespace: $EXAMPLE_ENV_NS
repository: helm-repo
context: farglebargle
repositories:
helm-repo:
url: $HELM_REPO_URL
releases:
- name: basic
namespace: namespace
chart: somechart
version: 2.0.0
repository: helm-repo
values:
envVar: $EXAMPLE_ENV_VAR