Skip to content

Commit 3cf28ae

Browse files
authored
[v0.36.x] Update env priority (#571)
* [v0.36.x] Update env priority * changelog * add template env update
1 parent ccc2784 commit 3cf28ae

File tree

24 files changed

+471
-136
lines changed

24 files changed

+471
-136
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
changelog:
2+
- type: FIX
3+
issueLink: https://github.com/solo-io/skv2/issues/565
4+
description: >
5+
Add support for other sources in templated env vars field.
6+
skipCI: "false"
7+
- type: NON_USER_FACING
8+
description: >
9+
Reorder the priority of the environment variables to be loaded in the following order:
10+
1. Templated environment variables
11+
2. Environment variables
12+
3. Extra environment variables
13+
skipCI: "false"

ci/oss_compliance/osa_provided.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Name|Version|License
5151
[config/v1alpha1](https://k8s.io/component-base/config/v1alpha1)|v0.28.3|Apache License 2.0
5252
[v2/internal](https://k8s.io/klog/v2/internal)|v2.100.1|Apache License 2.0
5353
[kube-openapi/pkg](https://k8s.io/kube-openapi/pkg)|v0.0.0-20230717233707-2695361300d9|Apache License 2.0
54-
[k8s.io/utils](https://k8s.io/utils)|v0.0.0-20230406110748-d93618cff8a2|Apache License 2.0
54+
[k8s.io/utils](https://k8s.io/utils)|v0.0.0-20240502163921-fe8a2dddb1d0|Apache License 2.0
5555
[controller-runtime/pkg](https://sigs.k8s.io/controller-runtime/pkg)|v0.16.3|Apache License 2.0
5656
[encoding/json](https://sigs.k8s.io/json/internal/golang/encoding/json)|v0.0.0-20221116044647-bc3834ca7abd|Apache License 2.0
5757
[structured-merge-diff/v4](https://sigs.k8s.io/structured-merge-diff/v4)|v4.2.3|Apache License 2.0

codegen/cmd_test.go

+124-36
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,26 @@ import (
1010
"reflect"
1111
"strings"
1212

13-
goyaml "gopkg.in/yaml.v3"
14-
rbacv1 "k8s.io/api/rbac/v1"
15-
v12 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
16-
"k8s.io/utils/pointer"
17-
1813
. "github.com/onsi/ginkgo/v2"
1914
. "github.com/onsi/gomega"
20-
. "github.com/solo-io/skv2/codegen"
21-
"github.com/solo-io/skv2/codegen/model"
22-
. "github.com/solo-io/skv2/codegen/model"
23-
"github.com/solo-io/skv2/codegen/skv2_anyvendor"
24-
"github.com/solo-io/skv2/codegen/util"
25-
"github.com/solo-io/skv2/contrib"
15+
goyaml "gopkg.in/yaml.v3"
2616
appsv1 "k8s.io/api/apps/v1"
2717
v1 "k8s.io/api/core/v1"
18+
rbacv1 "k8s.io/api/rbac/v1"
19+
v12 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2820
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2921
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3022
"k8s.io/apimachinery/pkg/runtime/schema"
3123
"k8s.io/apimachinery/pkg/util/intstr"
3224
kubeyaml "k8s.io/apimachinery/pkg/util/yaml"
25+
"k8s.io/utils/ptr"
3326
"sigs.k8s.io/yaml"
27+
28+
. "github.com/solo-io/skv2/codegen"
29+
. "github.com/solo-io/skv2/codegen/model"
30+
"github.com/solo-io/skv2/codegen/skv2_anyvendor"
31+
"github.com/solo-io/skv2/codegen/util"
32+
"github.com/solo-io/skv2/contrib"
3433
)
3534

3635
var _ = Describe("Cmd", func() {
@@ -42,6 +41,66 @@ var _ = Describe("Cmd", func() {
4241
skv2Imports.External["github.com/solo-io/cue"] = []string{
4342
"encoding/protobuf/cue/cue.proto",
4443
}
44+
It("env variable priority", func() {
45+
cmd := &Command{
46+
Chart: &Chart{
47+
Data: Data{
48+
ApiVersion: "v1",
49+
Description: "",
50+
Name: "Painting Operator",
51+
Version: "v0.0.1",
52+
Home: "https://docs.solo.io/skv2/latest",
53+
Sources: []string{
54+
"https://github.com/solo-io/skv2",
55+
},
56+
},
57+
Operators: []Operator{{
58+
Name: "painter",
59+
Deployment: Deployment{
60+
Container: Container{
61+
Image: Image{Repository: "painter", Tag: "v0.0.1"},
62+
Env: []v1.EnvVar{{Name: "ENV_VAR", Value: "default"}},
63+
TemplateEnvVars: []TemplateEnvVar{
64+
{
65+
Condition: "$.Values.secret",
66+
Name: "ENV_VAR",
67+
Value: "templated",
68+
},
69+
},
70+
},
71+
},
72+
}},
73+
},
74+
ManifestRoot: "codegen/test/chart/env-priority",
75+
}
76+
Expect(cmd.Execute()).NotTo(HaveOccurred(), "failed to execute command")
77+
78+
manifests := helmTemplate("./test/chart/env-priority", map[string]any{"painter": map[string]any{"enabled": true}, "secret": true})
79+
var renderedDeployment *appsv1.Deployment
80+
decoder := kubeyaml.NewYAMLOrJSONDecoder(bytes.NewBuffer(manifests), 4096)
81+
for {
82+
obj := &unstructured.Unstructured{}
83+
err := decoder.Decode(obj)
84+
if err != nil {
85+
break
86+
}
87+
if obj.GetName() != "painter" || obj.GetKind() != "Deployment" {
88+
continue
89+
}
90+
91+
bytes, err := obj.MarshalJSON()
92+
Expect(err).NotTo(HaveOccurred())
93+
renderedDeployment = &appsv1.Deployment{}
94+
err = json.Unmarshal(bytes, renderedDeployment)
95+
Expect(err).NotTo(HaveOccurred())
96+
}
97+
Expect(renderedDeployment).NotTo(BeNil())
98+
99+
Expect(renderedDeployment.Spec.Template.Spec.Containers[0].Env).To(HaveLen(2))
100+
Expect(renderedDeployment.Spec.Template.Spec.Containers[0].Env[0]).To(Equal(v1.EnvVar{Name: "ENV_VAR", Value: "templated"}))
101+
Expect(renderedDeployment.Spec.Template.Spec.Containers[0].Env[1]).To(Equal(v1.EnvVar{Name: "ENV_VAR", Value: "default"}))
102+
})
103+
45104
It("install conditional sidecars", func() {
46105
agentConditional := "and ($.Values.glooAgent.enabled) ($.Values.glooAgent.runAsSidecar)"
47106

@@ -111,6 +170,30 @@ var _ = Describe("Cmd", func() {
111170
Repository: "gloo-mesh-mgmt-server",
112171
Tag: "0.0.1",
113172
},
173+
TemplateEnvVars: []TemplateEnvVar{
174+
{
175+
Name: "USERNAME",
176+
ValueFrom: v1.EnvVarSource{
177+
SecretKeyRef: &v1.SecretKeySelector{
178+
LocalObjectReference: v1.LocalObjectReference{
179+
Name: "{{ $.Values.someSecret }}",
180+
},
181+
Key: "{{ $.Values.usernameKey }}",
182+
},
183+
},
184+
},
185+
{
186+
Name: "PASSWORD",
187+
ValueFrom: v1.EnvVarSource{
188+
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
189+
LocalObjectReference: v1.LocalObjectReference{
190+
Name: "{{ $.Values.someConfigMap }}",
191+
},
192+
Key: "{{ $.Values.passwordKey }}",
193+
},
194+
},
195+
},
196+
},
114197
ContainerPorts: []ContainerPort{{
115198
Name: "stats",
116199
Port: "{{ $Values.glooMgmtServer.statsPort }}",
@@ -155,6 +238,11 @@ var _ = Describe("Cmd", func() {
155238
Expect(deployment).To(ContainSubstring("name: agent-volume"))
156239
Expect(deployment).To(ContainSubstring(`{{ index $glooAgent "ports" "grpc" }}`))
157240
Expect(deployment).To(ContainSubstring("{{ $Values.glooMgmtServer.statsPort }}"))
241+
242+
Expect(deployment).To(ContainSubstring("{{ $.Values.usernameKey }}"))
243+
Expect(deployment).To(ContainSubstring("{{ $.Values.passwordKey }}"))
244+
Expect(deployment).To(ContainSubstring("{{ $.Values.someSecret }}"))
245+
Expect(deployment).To(ContainSubstring("{{ $.Values.someConfigMap }}"))
158246
})
159247
It("generates conditional crds", func() {
160248
cmd := &Command{
@@ -772,13 +860,11 @@ var _ = Describe("Cmd", func() {
772860
}
773861
Expect(renderedDeployment).NotTo(BeNil())
774862

775-
pointerBool := func(b bool) *bool { return &b }
776-
pointerInt64 := func(i int64) *int64 { return &i }
777863
defaultSecurityContext := v1.SecurityContext{
778-
RunAsNonRoot: pointerBool(true),
779-
RunAsUser: pointerInt64(10101),
780-
ReadOnlyRootFilesystem: pointerBool(true),
781-
AllowPrivilegeEscalation: pointerBool(false),
864+
RunAsNonRoot: ptr.To(true),
865+
RunAsUser: ptr.To[int64](10101),
866+
ReadOnlyRootFilesystem: ptr.To(true),
867+
AllowPrivilegeEscalation: ptr.To(false),
782868
Capabilities: &v1.Capabilities{
783869
Drop: []v1.Capability{"ALL"},
784870
},
@@ -798,8 +884,8 @@ var _ = Describe("Cmd", func() {
798884
Entry("renders empty map for container security context when set as false via helm cli", nil, true),
799885
Entry("overrides container security context with empty map", &v1.SecurityContext{}, false),
800886
Entry("overrides container security context", &v1.SecurityContext{
801-
RunAsNonRoot: func(b bool) *bool { return &b }(true),
802-
RunAsUser: func(i int64) *int64 { return &i }(20202),
887+
RunAsNonRoot: ptr.To(true),
888+
RunAsUser: ptr.To[int64](20202),
803889
}, false),
804890
)
805891

@@ -1928,7 +2014,7 @@ roleRef:
19282014
)
19292015

19302016
DescribeTable("rendering conditional deployment strategy",
1931-
func(values map[string]any, conditionalStrategy []model.ConditionalStrategy, expectedStrategy appsv1.DeploymentStrategy) {
2017+
func(values map[string]any, conditionalStrategy []ConditionalStrategy, expectedStrategy appsv1.DeploymentStrategy) {
19322018
cmd := &Command{
19332019
Chart: &Chart{
19342020
Operators: []Operator{
@@ -1999,7 +2085,7 @@ roleRef:
19992085
),
20002086
Entry("when the condition is true",
20012087
map[string]any{"enabled": true, "condition": true},
2002-
[]model.ConditionalStrategy{
2088+
[]ConditionalStrategy{
20032089
{
20042090
Condition: "$.Values.painter.condition",
20052091
Strategy: appsv1.DeploymentStrategy{
@@ -2019,7 +2105,7 @@ roleRef:
20192105
),
20202106
Entry("when the condition is false",
20212107
map[string]any{"enabled": true, "condition": false},
2022-
[]model.ConditionalStrategy{
2108+
[]ConditionalStrategy{
20232109
{
20242110
Condition: "$.Values.painter.condition",
20252111
Strategy: appsv1.DeploymentStrategy{
@@ -2114,23 +2200,23 @@ roleRef:
21142200
map[string]interface{}{"fsGroup": 1000},
21152201
nil,
21162202
&v1.PodSecurityContext{
2117-
FSGroup: pointer.Int64(1000),
2203+
FSGroup: ptr.To[int64](1000),
21182204
}),
21192205
Entry("when PodSecurityContext is defined only in the operator",
21202206
nil,
21212207
&v1.PodSecurityContext{
2122-
FSGroup: pointer.Int64(1000),
2208+
FSGroup: ptr.To[int64](1000),
21232209
},
21242210
&v1.PodSecurityContext{
2125-
FSGroup: pointer.Int64(1000),
2211+
FSGroup: ptr.To[int64](1000),
21262212
}),
21272213
Entry("when PodSecurityContext is defined in both values and the operator",
21282214
map[string]interface{}{"fsGroup": 1024},
21292215
&v1.PodSecurityContext{
2130-
FSGroup: pointer.Int64(1000),
2216+
FSGroup: ptr.To[int64](1000),
21312217
},
21322218
&v1.PodSecurityContext{
2133-
FSGroup: pointer.Int64(1024), // should override the value defined in the operator
2219+
FSGroup: ptr.To[int64](1024), // should override the value defined in the operator
21342220
}),
21352221
)
21362222

@@ -2229,7 +2315,9 @@ roleRef:
22292315
Value: "{{ $.Values.featureGates.Foo | quote }}",
22302316
},
22312317
},
2232-
nil),
2318+
[]v1.EnvVar{
2319+
{Name: "FEATURE_ENABLE_FOO", Value: "true"},
2320+
}),
22332321
Entry("when Env and TemplateEnvVar are specified, true value",
22342322
map[string]string{"Foo": "true"},
22352323
[]v1.EnvVar{
@@ -2318,7 +2406,7 @@ roleRef:
23182406
})
23192407

23202408
DescribeTable("validation",
2321-
func(values map[string]any, defaultVolumes []v1.Volume, conditionalVolumes []model.ConditionalVolume, expected []v1.Volume) {
2409+
func(values map[string]any, defaultVolumes []v1.Volume, conditionalVolumes []ConditionalVolume, expected []v1.Volume) {
23222410
cmd := &Command{
23232411
Chart: &Chart{
23242412
Operators: []Operator{
@@ -2412,7 +2500,7 @@ roleRef:
24122500
"condition": "true",
24132501
},
24142502
nil,
2415-
[]model.ConditionalVolume{
2503+
[]ConditionalVolume{
24162504
{
24172505
Condition: "$.Values.painter.condition",
24182506
Volume: v1.Volume{
@@ -2432,7 +2520,7 @@ roleRef:
24322520
"condition": "true",
24332521
},
24342522
nil,
2435-
[]model.ConditionalVolume{
2523+
[]ConditionalVolume{
24362524
{
24372525
Condition: "$.Values.painter.invalidCondition",
24382526
Volume: v1.Volume{
@@ -2452,7 +2540,7 @@ roleRef:
24522540
Name: "vol-1",
24532541
},
24542542
},
2455-
[]model.ConditionalVolume{
2543+
[]ConditionalVolume{
24562544
{
24572545
Condition: "$.Values.painter.condition",
24582546
Volume: v1.Volume{
@@ -2484,7 +2572,7 @@ roleRef:
24842572
})
24852573

24862574
DescribeTable("validation",
2487-
func(values map[string]any, defaultMounts []v1.VolumeMount, conditionalMounts []model.ConditionalVolumeMount, expected []v1.VolumeMount) {
2575+
func(values map[string]any, defaultMounts []v1.VolumeMount, conditionalMounts []ConditionalVolumeMount, expected []v1.VolumeMount) {
24882576
cmd := &Command{
24892577
Chart: &Chart{
24902578
Operators: []Operator{
@@ -2580,7 +2668,7 @@ roleRef:
25802668
"condition": "true",
25812669
},
25822670
nil,
2583-
[]model.ConditionalVolumeMount{
2671+
[]ConditionalVolumeMount{
25842672
{
25852673
Condition: "$.Values.painter.condition",
25862674
VolumeMount: v1.VolumeMount{
@@ -2600,7 +2688,7 @@ roleRef:
26002688
"condition": "true",
26012689
},
26022690
nil,
2603-
[]model.ConditionalVolumeMount{
2691+
[]ConditionalVolumeMount{
26042692
{
26052693
Condition: "$.Values.painter.invalidCondition",
26062694
VolumeMount: v1.VolumeMount{
@@ -2620,7 +2708,7 @@ roleRef:
26202708
Name: "vol-1",
26212709
},
26222710
},
2623-
[]model.ConditionalVolumeMount{
2711+
[]ConditionalVolumeMount{
26242712
{
26252713
Condition: "$.Values.painter.condition",
26262714
VolumeMount: v1.VolumeMount{

codegen/model/chart.go

+3
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ type TemplateEnvVar struct {
173173
// Helm value
174174
// E.g. {{ .Values.foo.bar }}
175175
Value string
176+
177+
//
178+
ValueFrom corev1.EnvVarSource
176179
}
177180

178181
type ContainerPort struct {

codegen/templates/chart/operator-deployment.yamltmpl

+20-11
Original file line numberDiff line numberDiff line change
@@ -140,25 +140,34 @@ spec:
140140
containerPort: [[ $port.Port ]]
141141
[[- end ]]
142142
[[- end ]]
143-
{{- if [[ $containerVar ]].env }}
143+
[[- if or $container.Env $container.TemplateEnvVars ]]
144+
env:
145+
[[- else ]]
146+
{{- if or [[ $containerVar ]].env [[ $containerVar ]].extraEnvs }}
144147
env:
145-
{{ toYaml [[ $containerVar ]].env | indent 10 }}
148+
{{- end }}
149+
[[- end ]]
146150
[[- range $f := $container.TemplateEnvVars ]]
147-
[[- if $f.Condition ]]
148-
{{- if [[ $f.Condition ]] }}
149-
[[- end]]
151+
[[- if $f.Condition ]]
152+
{{- if [[ $f.Condition ]] }}
153+
[[- end ]]
154+
[[- if $f.Value ]]
150155
- name: [[ $f.Name ]]
151156
value: [[ $f.Value ]]
152-
[[- if $f.Condition ]]
153-
{{- end }}
154-
[[- end]]
157+
[[- else if $f.ValueFrom ]]
158+
- name: [[ $f.Name ]]
159+
valueFrom: [[ $f.ValueFrom | toYaml | nindent 14 ]]
160+
[[- end ]]
161+
[[- if $f.Condition ]]
162+
{{- end }}
163+
[[- end ]]
155164
[[- end ]]
156-
{{- else if [[ $containerVar ]].extraEnvs }}
157-
env:
165+
{{- if [[ $containerVar ]].env }}
166+
{{- toYaml [[ $containerVar ]].env | nindent 10 }}
158167
{{- end }}
159168
{{- range $name, $item := [[ $containerVar ]].extraEnvs }}
160169
- name: {{ $name }}
161-
{{- $item | toYaml | nindent 12 }}
170+
{{- $item | toYaml | nindent 12 }}
162171
{{- end }}
163172
[[- if $container.VolumeMounts ]]
164173
volumeMounts:

0 commit comments

Comments
 (0)