Skip to content

Commit

Permalink
Add support for extraVolumes/extraVolumeMounts
Browse files Browse the repository at this point in the history
  • Loading branch information
chunter0 committed Sep 6, 2024
1 parent 4f24776 commit 14c4199
Show file tree
Hide file tree
Showing 28 changed files with 1,390 additions and 2 deletions.
6 changes: 6 additions & 0 deletions changelog/v0.40.7/issue-582.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
changelog:
- type: NEW_FEATURE
issueLink: https://github.com/solo-io/skv2/issues/582
description: >
Update operator templates to handle extraVolumes/extraVolumeMounts passed in from helm values.
skipCI: "false"
233 changes: 233 additions & 0 deletions codegen/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,239 @@ var _ = Describe("Cmd", func() {
skv2Imports.External["github.com/solo-io/cue"] = []string{
"encoding/protobuf/cue/cue.proto",
}
{
type TestEntry struct {
name string
values any
staticVolumes []v1.Volume
conditionalVolumes []ConditionalVolume
staticVolumeMounts []v1.VolumeMount
conditionalVolumeMounts []ConditionalVolumeMount
}

DescribeTable(
"extraVolume/extraVolumeMounts",
Ordered, func(entry TestEntry, expectedVolumes, expectedVolumeMounts int) {
cmd := &Command{
Chart: &Chart{
Data: Data{
ApiVersion: "v1",
Description: "",
Name: "Painting Operator",
Version: "v0.0.1",
Home: "https://docs.solo.io/skv2/latest",
Sources: []string{
"https://github.com/solo-io/skv2",
},
},
Operators: []Operator{{
Name: "painter",
Deployment: Deployment{
Container: Container{
Image: Image{
Tag: "v0.0.0",
Repository: "painter",
Registry: "quay.io/solo-io",
PullPolicy: "IfNotPresent",
},
VolumeMounts: entry.staticVolumeMounts,
ConditionalVolumeMounts: entry.conditionalVolumeMounts,
},
Volumes: entry.staticVolumes,
ConditionalVolumes: entry.conditionalVolumes,
},
}},
},
ManifestRoot: fmt.Sprintf("codegen/test/chart/%s", entry.name),
}
Expect(cmd.Execute()).NotTo(HaveOccurred(), "failed to execute command")

manifests := helmTemplate(fmt.Sprintf("./test/chart/%s", entry.name), entry.values)

var (
renderedDeployment *appsv1.Deployment
decoder = kubeyaml.NewYAMLOrJSONDecoder(bytes.NewBuffer(manifests), 4096)
)
for {
var deployment appsv1.Deployment
if err := decoder.Decode(&deployment); errors.Is(err, io.EOF) {
break
}

if deployment.GetName() == "painter" && deployment.Kind == "Deployment" {
renderedDeployment = &deployment
break
}
}

Expect(renderedDeployment.Spec.Template.Spec.Volumes).To(HaveLen(expectedVolumes))

Expect(renderedDeployment.Spec.Template.Spec.Containers).To(HaveLen(1))

Expect(renderedDeployment.Spec.Template.Spec.Containers[0].VolumeMounts).To(HaveLen(expectedVolumes))
},
Entry(
"empty with no volumes",
TestEntry{
name: "extra-volumes",
values: map[string]any{
"painter": map[string]any{
"enabled": true,
"extraVolumes": []v1.Volume{{
Name: "extra-certs",
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{
SecretName: "extra-secret",
},
},
}},
"extraVolumeMounts": []v1.VolumeMount{{
Name: "extra-certs",
MountPath: "/etc/ssl/certs",
}},
},
},
},
0,
0,
),
Entry(
"with static volumes",
TestEntry{
name: "static-volumes",
values: map[string]any{
"painter": map[string]any{
"enabled": true,
"extraVolumes": []v1.Volume{{
Name: "extra-certs",
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{
SecretName: "extra-secret",
},
},
}},
"extraVolumeMounts": []v1.VolumeMount{{
Name: "extra-certs",
MountPath: "/etc/ssl/extra",
}},
},
},
staticVolumes: []v1.Volume{{
Name: "static-certs",
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{
SecretName: "static-secret",
},
},
}},
staticVolumeMounts: []v1.VolumeMount{{
Name: "static-certs",
MountPath: "/var/run/secret/static",
}},
},
2,
2,
),
Entry(
"with conditional volumes",
TestEntry{
name: "conditional-volumes",
values: map[string]any{
"painter": map[string]any{
"enabled": true,
"extraVolumes": []v1.Volume{{
Name: "extra-certs",
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{
SecretName: "extra-secret",
},
},
}},
"extraVolumeMounts": []v1.VolumeMount{{
Name: "extra-certs",
MountPath: "/etc/ssl/extra",
}},
},
},
conditionalVolumes: []ConditionalVolume{{
Condition: ".Values.painter.enabled",
Volume: v1.Volume{
Name: "conditional-certs",
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{
SecretName: "conditional-secret",
},
},
},
}},
conditionalVolumeMounts: []ConditionalVolumeMount{{
Condition: ".Values.painter.enabled",
VolumeMount: v1.VolumeMount{
Name: "conditional-certs",
MountPath: "/var/run/secret/conditional",
},
}},
},
2,
2,
),
Entry(
"with all volumes",
TestEntry{
name: "all-volumes",
values: map[string]any{
"painter": map[string]any{
"enabled": true,
"extraVolumes": []v1.Volume{{
Name: "extra-certs",
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{
SecretName: "extra-secret",
},
},
}},
"extraVolumeMounts": []v1.VolumeMount{{
Name: "extra-certs",
MountPath: "/etc/ssl/extra",
}},
},
},
staticVolumes: []v1.Volume{{
Name: "static-certs",
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{
SecretName: "static-secret",
},
},
}},
conditionalVolumes: []ConditionalVolume{{
Condition: ".Values.painter.enabled",
Volume: v1.Volume{
Name: "conditional-certs",
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{
SecretName: "conditional-secret",
},
},
},
}},
staticVolumeMounts: []v1.VolumeMount{{
Name: "static-certs",
MountPath: "/var/run/secret/static",
}},
conditionalVolumeMounts: []ConditionalVolumeMount{{
Condition: ".Values.painter.enabled",
VolumeMount: v1.VolumeMount{
Name: "conditional-certs",
MountPath: "/var/run/secret/conditional",
},
}},
},
3,
3,
),
)
}

Describe("image pull secrets", Ordered, func() {
BeforeAll(func() {
Expand Down
8 changes: 6 additions & 2 deletions codegen/templates/chart/operator-deployment.yamltmpl
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,11 @@ spec:
[[- end ]]
[[- if $volumes ]]
volumes:
[[ toYaml $volumes | indent 6 ]]
[[- toYaml $volumes | nindent 6 ]]
{{- tpl (toYaml [[ (opVar $operator) ]].extraVolumes) . | nindent 6 }}
[[- else if $conditionalVolumes ]]
volumes:
{{- tpl (toYaml [[ (opVar $operator) ]].extraVolumes) . | nindent 6 }}
[[- end ]]
[[- range $v := $conditionalVolumes ]]
{{- if [[ $v.Condition ]] }}
Expand Down Expand Up @@ -178,9 +180,11 @@ spec:
{{- end }}
[[- if $container.VolumeMounts ]]
volumeMounts:
[[ toYaml $container.VolumeMounts | indent 8 ]]
[[- toYaml $container.VolumeMounts | nindent 8 ]]
{{- tpl (toYaml [[ (opVar $operator) ]].extraVolumeMounts) . | nindent 8 }}
[[- else if $container.ConditionalVolumeMounts ]]
volumeMounts:
{{- tpl (toYaml [[ (opVar $operator) ]].extraVolumeMounts) . | nindent 8 }}
[[- end ]]
[[- range $v := $container.ConditionalVolumeMounts ]]
{{- if [[ $v.Condition ]] }}
Expand Down
8 changes: 8 additions & 0 deletions codegen/test/chart/all-volumes/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Code generated by skv2. DO NOT EDIT.

apiVersion: v1
home: https://docs.solo.io/skv2/latest
name: Painting Operator
sources:
- https://github.com/solo-io/skv2
version: v0.0.1
54 changes: 54 additions & 0 deletions codegen/test/chart/all-volumes/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Code generated by skv2. DO NOT EDIT.



{{/* Below are library functions provided by skv2 */}}

{{- /*
"skv2.utils.merge" takes an array of three values:
- the top context
- the yaml block that will be merged in (override)
- the name of the base template (source)
note: the source must be a named template (helm partial). This is necessary for the merging logic.
The behaviour is as follows, to align with already existing helm behaviour:
- If no source is found (template is empty), the merged output will be empty
- If no overrides are specified, the source is rendered as is
- If overrides are specified and source is not empty, overrides will be merged in to the source.
Overrides can replace / add to deeply nested dictionaries, but will completely replace lists.
Examples:
┌─────────────────────┬───────────────────────┬────────────────────────┐
│ Source (template) │ Overrides │ Result │
├─────────────────────┼───────────────────────┼────────────────────────┤
│ metadata: │ metadata: │ metadata: │
│ labels: │ labels: │ labels: │
│ app: gloo │ app: gloo1 │ app: gloo1 │
│ cluster: useast │ author: infra-team │ author: infra-team │
│ │ │ cluster: useast │
├─────────────────────┼───────────────────────┼────────────────────────┤
│ lists: │ lists: │ lists: │
│ groceries: │ groceries: │ groceries: │
│ - apple │ - grapes │ - grapes │
│ - banana │ │ │
└─────────────────────┴───────────────────────┴────────────────────────┘
skv2.utils.merge is a fork of a helm library chart function (https://github.com/helm/charts/blob/master/incubator/common/templates/_util.tpl).
This includes some optimizations to speed up chart rendering time, and merges in a value (overrides) with a named template, unlike the upstream
version, which merges two named templates.
*/ -}}
{{- define "skv2.utils.merge" -}}
{{- $top := first . -}}
{{- $overrides := (index . 1) -}}
{{- $tpl := fromYaml (include (index . 2) $top) -}}
{{- if or (empty $overrides) (empty $tpl) -}}
{{ include (index . 2) $top }} {{/* render source as is */}}
{{- else -}}
{{- $merged := merge $overrides $tpl -}}
{{- toYaml $merged -}} {{/* render source with overrides as YAML */}}
{{- end -}}
{{- end -}}
Loading

0 comments on commit 14c4199

Please sign in to comment.