From 4ac92574f636b878adbf878aeba1116ab2cf46e8 Mon Sep 17 00:00:00 2001 From: JM Huibonhoa Date: Thu, 3 Aug 2023 09:25:40 -0400 Subject: [PATCH] [Backport - V0.31.x] Fix portal helm installation (#470) * Fix portal helm installation (#469) * print template * add changelog * add resolve issue false * update operator rbac tmpl * copy pasta mistake * missed sa namespace * copy pasta mistake * add test * use backticks * formatting * more formatting * update changelog --- ...ix-portal-platform-chart-installation.yaml | 6 + codegen/cmd_test.go | 191 ++++++++++++++++++ codegen/model/chart.go | 4 + .../chart/operator-deployment.yamltmpl | 12 ++ .../templates/chart/operator-rbac.yamltmpl | 16 ++ 5 files changed, 229 insertions(+) create mode 100644 changelog/v0.31.3/fix-portal-platform-chart-installation.yaml diff --git a/changelog/v0.31.3/fix-portal-platform-chart-installation.yaml b/changelog/v0.31.3/fix-portal-platform-chart-installation.yaml new file mode 100644 index 000000000..73ada1c82 --- /dev/null +++ b/changelog/v0.31.3/fix-portal-platform-chart-installation.yaml @@ -0,0 +1,6 @@ +changelog: + - type: NEW_FEATURE + issueLink: https://github.com/solo-io/gloo-mesh-enterprise/issues/10786 + description: > + Add the ability to specify an operator namespace using a value path. (e.g. `$.Values.common.namespace`) + resolvesIssue: false \ No newline at end of file diff --git a/codegen/cmd_test.go b/codegen/cmd_test.go index 6eed47bc3..2841068cc 100644 --- a/codegen/cmd_test.go +++ b/codegen/cmd_test.go @@ -1178,6 +1178,197 @@ var _ = Describe("Cmd", func() { Expect(renderedManifests).To(ContainSubstring(expectedCR)) }) + It("supports rendering namespace template with custom value if provided", func() { + cmd := &Command{ + Groups: []Group{ + { + GroupVersion: schema.GroupVersion{ + Group: "things.test.io", + Version: "v1", + }, + Module: "github.com/solo-io/skv2", + Resources: []Resource{ + { + Kind: "Paint", + Spec: Field{Type: Type{Name: "PaintSpec"}}, + Status: &Field{Type: Type{Name: "PaintStatus"}}, + }, + { + Kind: "ClusterResource", + Spec: Field{Type: Type{Name: "ClusterResourceSpec"}}, + ClusterScoped: true, + }, + }, + RenderManifests: true, + RenderTypes: true, + RenderClients: true, + RenderController: true, + MockgenDirective: true, + ApiRoot: "codegen/test/api", + CustomTemplates: contrib.AllGroupCustomTemplates, + }, + }, + AnyVendorConfig: skv2Imports, + RenderProtos: true, + + Chart: &Chart{ + Operators: []Operator{ + { + Name: "painter", + NamespaceFromValuePath: "$.Values.common.namespace", + Rbac: []rbacv1.PolicyRule{ + { + Verbs: []string{"GET"}, + }, + }, + Deployment: Deployment{ + Container: Container{ + Image: Image{ + Tag: "v0.0.0", + Repository: "painter", + Registry: "quay.io/solo-io", + PullPolicy: "IfNotPresent", + }, + Args: []string{"foo"}, + }, + }, + }, + }, + Values: nil, + 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", + }, + }, + }, + + ManifestRoot: "codegen/test/chart", + } + + err := cmd.Execute() + Expect(err).NotTo(HaveOccurred()) + + // Test that the deployment, SA, and CR templates are rendered correctly + deployment, err := os.ReadFile("codegen/test/chart/templates/deployment.yaml") + Expect(err).NotTo(HaveOccurred()) + + expectedDeploymentTmpl := ` +kind: Deployment +metadata: + labels: + app: painter + annotations: + app.kubernetes.io/name: painter + name: painter + namespace: {{ $.Values.common.namespace | default $.Release.Namespace }}` + + expectedSATmpl := ` +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: painter + {{- if $painter.serviceAccount}} + {{- if $painter.serviceAccount.extraAnnotations }} + annotations: + {{- range $key, $value := $painter.serviceAccount.extraAnnotations }} + {{ $key }}: {{ $value }} + {{- end }} + {{- end }} + {{- end}} + name: painter + namespace: {{ $.Values.common.namespace | default $.Release.Namespace }}` + + Expect(string(deployment)).To(ContainSubstring(expectedDeploymentTmpl)) + Expect(string(deployment)).To(ContainSubstring(expectedSATmpl)) + + rbac, err := os.ReadFile("codegen/test/chart/templates/rbac.yaml") + Expect(err).NotTo(HaveOccurred()) + + expectedClusterRoleTmpl := ` +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: painter-{{ $.Values.common.namespace | default $.Release.Namespace }}` + + expectedClusterRoleBindingTmpl := ` +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: painter-{{ $.Values.common.namespace | default $.Release.Namespace }} + labels: + app: painter +subjects: +- kind: ServiceAccount + name: painter + namespace: {{ $.Values.common.namespace | default $.Release.Namespace }} +roleRef: + kind: ClusterRole + name: painter-{{ $.Values.common.namespace | default $.Release.Namespace }} + apiGroup: rbac.authorization.k8s.io` + + Expect(string(rbac)).To(ContainSubstring(expectedClusterRoleTmpl)) + Expect(string(rbac)).To(ContainSubstring(expectedClusterRoleBindingTmpl)) + + // Test that the deployment, SA, and CR are rendered with the custom namespace value + helmValues := map[string]interface{}{ + "common": map[string]interface{}{ + "namespace": "test-namespace", + }, + } + + expectedDeployment := ` +kind: Deployment +metadata: + labels: + app: painter + annotations: + app.kubernetes.io/name: painter + name: painter + namespace: test-namespace` + + expectedSA := ` +kind: ServiceAccount +metadata: + labels: + app: painter + name: painter + namespace: test-namespace` + + expectedClusterRole := ` +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: painter-test-namespace` + + expectedClusterRoleBinding := ` +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: painter-test-namespace + labels: + app: painter +subjects: +- kind: ServiceAccount + name: painter + namespace: test-namespace +roleRef: + kind: ClusterRole + name: painter-test-namespace + apiGroup: rbac.authorization.k8s.io` + + renderedManifests := helmTemplate("codegen/test/chart", helmValues) + Expect(renderedManifests).To(ContainSubstring(expectedSA)) + Expect(renderedManifests).To(ContainSubstring(expectedDeployment)) + Expect(renderedManifests).To(ContainSubstring(expectedClusterRole)) + Expect(renderedManifests).To(ContainSubstring(expectedClusterRoleBinding)) + }) + Context("generates CRD with validation schema for a proto file", func() { var cmd *Command diff --git a/codegen/model/chart.go b/codegen/model/chart.go index 62c3e003a..b3d07b654 100644 --- a/codegen/model/chart.go +++ b/codegen/model/chart.go @@ -88,6 +88,10 @@ type Operator struct { // the name of the other operator can be included in this list. This operator // will not be provisioned unless both are enabled (by having values.enabled = true) EnabledDependsOn []string + + // (Optional) If this operator should be applied to a namespace + // specified in a common value (e.g. "$Values.common.addonNamespace") specify the full value path here + NamespaceFromValuePath string } func (o Operator) FormattedName() string { diff --git a/codegen/templates/chart/operator-deployment.yamltmpl b/codegen/templates/chart/operator-deployment.yamltmpl index f23df6ff7..b9fa4704f 100644 --- a/codegen/templates/chart/operator-deployment.yamltmpl +++ b/codegen/templates/chart/operator-deployment.yamltmpl @@ -49,7 +49,11 @@ metadata: [[ $key ]]: [[ $value ]] [[- end ]] name: [[ $operator.Name ]] +[[- if $operator.NamespaceFromValuePath ]] + namespace: [[ printf "{{ %s | default $.Release.Namespace }}" $operator.NamespaceFromValuePath ]] +[[- else ]] namespace: {{ default .Release.Namespace [[ (opVar $operator) ]].namespace }} +[[- end ]] spec: selector: matchLabels: @@ -177,7 +181,11 @@ metadata: {{- end }} {{- end}} name: [[ $operator.Name ]] +[[- if $operator.NamespaceFromValuePath ]] + namespace: [[ printf "{{ %s | default $.Release.Namespace }}" $operator.NamespaceFromValuePath ]] +[[- else ]] namespace: {{ default .Release.Namespace [[ (opVar $operator) ]].namespace }} +[[- end ]] {{- end }} @@ -200,7 +208,11 @@ metadata: [[ $key ]]: [[ $value ]] [[- end ]] name: [[ $operator.Name ]] +[[- if $operator.NamespaceFromValuePath ]] + namespace: [[ printf "{{ %s | default $.Release.Namespace }}" $operator.NamespaceFromValuePath ]] +[[- else ]] namespace: {{ default .Release.Namespace [[ (opVar $operator) ]].namespace }} +[[- end ]] spec: selector: app: [[ $operator.Name ]] diff --git a/codegen/templates/chart/operator-rbac.yamltmpl b/codegen/templates/chart/operator-rbac.yamltmpl index 1428a136c..52041fee8 100644 --- a/codegen/templates/chart/operator-rbac.yamltmpl +++ b/codegen/templates/chart/operator-rbac.yamltmpl @@ -25,7 +25,11 @@ Expressions evaluating SKv2 Config use [[ "[[" ]] and [[ "]]" ]] kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: +[[- if $operator.NamespaceFromValuePath ]] + name: [[ $operator.Name ]]-[[ printf "{{ %s | default $.Release.Namespace }}" $operator.NamespaceFromValuePath ]] +[[- else ]] name: [[ $operator.Name ]]-{{ default .Release.Namespace [[ (opVar $operator) ]].namespace }} +[[- end ]] labels: app: [[ $operator.Name ]] rules: @@ -36,16 +40,28 @@ rules: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: +[[- if $operator.NamespaceFromValuePath ]] + name: [[ $operator.Name ]]-[[ printf "{{ %s | default $.Release.Namespace }}" $operator.NamespaceFromValuePath ]] +[[- else ]] name: [[ $operator.Name ]]-{{ default .Release.Namespace [[ (opVar $operator) ]].namespace }} +[[- end ]] labels: app: [[ $operator.Name ]] subjects: - kind: ServiceAccount name: [[ $operator.Name ]] +[[- if $operator.NamespaceFromValuePath ]] + namespace: [[ printf "{{ %s | default $.Release.Namespace }}" $operator.NamespaceFromValuePath ]] +[[- else ]] namespace: {{ default .Release.Namespace [[ (opVar $operator) ]].namespace }} +[[- end ]] roleRef: kind: ClusterRole +[[- if $operator.NamespaceFromValuePath ]] + name: [[ $operator.Name ]]-[[ printf "{{ %s | default $.Release.Namespace }}" $operator.NamespaceFromValuePath ]] +[[- else ]] name: [[ $operator.Name ]]-{{ default .Release.Namespace [[ (opVar $operator) ]].namespace }} +[[- end ]] apiGroup: rbac.authorization.k8s.io {{- end }}