Skip to content

Commit

Permalink
Use new Chart Render functionality in console
Browse files Browse the repository at this point in the history
The `_shims.render-manifest` will call `console.render` only once to generate
all console resources.

It's prelude for redpanda helm chart and de-flux controller.
  • Loading branch information
RafalKorepta committed Oct 9, 2024
1 parent 6a25b77 commit 151ff93
Show file tree
Hide file tree
Showing 14 changed files with 165 additions and 110 deletions.
77 changes: 77 additions & 0 deletions charts/console/chart.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// +gotohelm:filename=_chart.go.tpl
package console

import (
_ "embed"

"github.com/redpanda-data/helm-charts/pkg/gotohelm"
"github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette"
"github.com/redpanda-data/helm-charts/pkg/kube"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/scheme"
)

var (
// Scheme is a [runtime.Scheme] with the appropriate extensions to load all
// objects produced by the redpanda chart.
Scheme = runtime.NewScheme()

//go:embed Chart.yaml
chartYAML []byte

//go:embed values.yaml
defaultValuesYAML []byte

// ChartLabel is the go version of the redpanda helm chart.
Chart = gotohelm.MustLoad(chartYAML, defaultValuesYAML, render)
)

// +gotohelm:ignore=true
func init() {
must(scheme.AddToScheme(Scheme))
}

// +gotohelm:ignore=true
func must(err error) {
if err != nil {
panic(err)
}
}

// render is the entrypoint to both the go and helm versions of the redpanda
// helm chart.
// In helm, _shims.render-manifest is used to call and filter the output of
// this function.
// In go, this function should be call by executing [ChartLabel.Render], which will
// handle construction of [helmette.Dot], subcharting, and output filtering.
func render(dot *helmette.Dot) []kube.Object {
manifests := []kube.Object{
ServiceAccount(dot),
Secret(dot),
ConfigMap(dot),
Service(dot),
Ingress(dot),
Deployment(dot),
HorizontalPodAutoscaler(dot),
}

// NB: This slice may contain nil interfaces!
// Filtering happens elsewhere, don't call this function directly if you
// can avoid it.
return manifests
}
67 changes: 67 additions & 0 deletions charts/console/chart_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
package console

import (
"context"
"encoding/json"
"fmt"
"os"
"regexp"
"slices"
"strings"
"testing"

fuzz "github.com/google/gofuzz"
"github.com/redpanda-data/helm-charts/charts/redpanda"
"github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette"
"github.com/redpanda-data/helm-charts/pkg/helm"
"github.com/redpanda-data/helm-charts/pkg/kube"
"github.com/redpanda-data/helm-charts/pkg/testutil"
"github.com/santhosh-tekuri/jsonschema/v5"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/tools/txtar"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
"sigs.k8s.io/yaml"
)

Expand Down Expand Up @@ -156,3 +163,63 @@ func TestGenerateCases(t *testing.T) {

require.NoError(t, os.WriteFile("testdata/template-cases-generated.txtar", archive, 0o644))
}

func TestGoHelmEquivalence(t *testing.T) {
client, err := helm.New(helm.Options{ConfigHome: testutil.TempDir(t)})
require.NoError(t, err)

values := PartialValues{
Tests: &PartialEnableable{
Enabled: ptr.To(false),
},
Secret: &PartialSecretConfig{
Login: &PartialLoginSecrets{
JWTSecret: ptr.To("SECRET"),
},
},
Ingress: &PartialIngressConfig{
Enabled: ptr.To(true),
},
}

goObjs, err := Chart.Render(kube.Config{}, helmette.Release{
Name: "gotohelm",
Namespace: "mynamespace",
Service: "Helm",
}, values)
require.NoError(t, err)

rendered, err := client.Template(context.Background(), ".", helm.TemplateOptions{
Name: "gotohelm",
Namespace: "mynamespace",
Values: values,
})
require.NoError(t, err)

helmObjs, err := kube.DecodeYAML(rendered, redpanda.Scheme)
require.NoError(t, err)

slices.SortStableFunc(helmObjs, func(a, b kube.Object) int {
aStr := fmt.Sprintf("%s/%s/%s", a.GetObjectKind().GroupVersionKind().String(), a.GetNamespace(), a.GetName())
bStr := fmt.Sprintf("%s/%s/%s", b.GetObjectKind().GroupVersionKind().String(), b.GetNamespace(), b.GetName())
return strings.Compare(aStr, bStr)
})

slices.SortStableFunc(goObjs, func(a, b kube.Object) int {
aStr := fmt.Sprintf("%s/%s/%s", a.GetObjectKind().GroupVersionKind().String(), a.GetNamespace(), a.GetName())
bStr := fmt.Sprintf("%s/%s/%s", b.GetObjectKind().GroupVersionKind().String(), b.GetNamespace(), b.GetName())
return strings.Compare(aStr, bStr)
})

// resource.Quantity is a special object. To Ensure they compare correctly,
// we'll round trip it through JSON so the internal representations will
// match (assuming the values are actually equal).
assert.Equal(t, len(helmObjs), len(goObjs))

// Iterate and compare instead of a single comparison for better error
// messages. Some divergences will fail an Equal check on slices but not
// report which element(s) aren't equal.
for i := range helmObjs {
assert.Equal(t, helmObjs[i], goObjs[i])
}
}
2 changes: 1 addition & 1 deletion charts/console/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func Deployment(dot *helmette.Dot) *appsv1.Deployment {
}

var initContainers []corev1.Container
if values.InitContainers.ExtraInitContainers != nil {
if !helmette.Empty(values.InitContainers.ExtraInitContainers) {
initContainers = helmette.UnmarshalYamlArray[corev1.Container](helmette.Tpl(*values.InitContainers.ExtraInitContainers, dot))
}

Expand Down
4 changes: 2 additions & 2 deletions charts/console/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func Fullname(dot *helmette.Dot) string {
}

// Create chart name and version as used by the chart label.
func Chart(dot *helmette.Dot) string {
func ChartLabel(dot *helmette.Dot) string {
chart := fmt.Sprintf("%s-%s", dot.Chart.Name, dot.Chart.Version)
return cleanForK8s(strings.ReplaceAll(chart, "+", "_"))
}
Expand All @@ -61,7 +61,7 @@ func Labels(dot *helmette.Dot) map[string]string {
values := helmette.Unwrap[Values](dot.Values)

labels := map[string]string{
"helm.sh/chart": Chart(dot),
"helm.sh/chart": ChartLabel(dot),
"app.kubernetes.io/managed-by": dot.Release.Service,
}

Expand Down
13 changes: 13 additions & 0 deletions charts/console/templates/_chart.go.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- /* Generated from "chart.go" */ -}}

{{- define "console.render" -}}
{{- $dot := (index .a 0) -}}
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $manifests := (list (get (fromJson (include "console.ServiceAccount" (dict "a" (list $dot) ))) "r") (get (fromJson (include "console.Secret" (dict "a" (list $dot) ))) "r") (get (fromJson (include "console.ConfigMap" (dict "a" (list $dot) ))) "r") (get (fromJson (include "console.Service" (dict "a" (list $dot) ))) "r") (get (fromJson (include "console.Ingress" (dict "a" (list $dot) ))) "r") (get (fromJson (include "console.Deployment" (dict "a" (list $dot) ))) "r") (get (fromJson (include "console.HorizontalPodAutoscaler" (dict "a" (list $dot) ))) "r")) -}}
{{- $_is_returning = true -}}
{{- (dict "r" $manifests) | toJson -}}
{{- break -}}
{{- end -}}
{{- end -}}

2 changes: 1 addition & 1 deletion charts/console/templates/_deployment.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
{{- $replicas = ($values.replicaCount | int) -}}
{{- end -}}
{{- $initContainers := (coalesce nil) -}}
{{- if (ne $values.initContainers.extraInitContainers (coalesce nil)) -}}
{{- if (not (empty $values.initContainers.extraInitContainers)) -}}
{{- $initContainers = (fromYamlArray (tpl $values.initContainers.extraInitContainers $dot)) -}}
{{- end -}}
{{- $volumeMounts := (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "configs" "mountPath" "/etc/console/configs" "readOnly" true ))) -}}
Expand Down
4 changes: 2 additions & 2 deletions charts/console/templates/_helpers.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
{{- end -}}
{{- end -}}

{{- define "console.Chart" -}}
{{- define "console.ChartLabel" -}}
{{- $dot := (index .a 0) -}}
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
Expand All @@ -50,7 +50,7 @@
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $values := $dot.Values.AsMap -}}
{{- $labels := (dict "helm.sh/chart" (get (fromJson (include "console.Chart" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/managed-by" $dot.Release.Service ) -}}
{{- $labels := (dict "helm.sh/chart" (get (fromJson (include "console.ChartLabel" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/managed-by" $dot.Release.Service ) -}}
{{- if (ne $dot.Chart.AppVersion "") -}}
{{- $_ := (set $labels "app.kubernetes.io/version" $dot.Chart.AppVersion) -}}
{{- end -}}
Expand Down
17 changes: 0 additions & 17 deletions charts/console/templates/configmap.yaml

This file was deleted.

17 changes: 0 additions & 17 deletions charts/console/templates/deployment.yaml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{/*
{{- /*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
Expand All @@ -14,4 +14,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/}}
{{- include "_shims.render-manifest" (list "console.Secret" .) -}}
{{- include "_shims.render-manifest" (list "console.render" .) -}}
17 changes: 0 additions & 17 deletions charts/console/templates/hpa.yaml

This file was deleted.

17 changes: 0 additions & 17 deletions charts/console/templates/ingress.yaml

This file was deleted.

17 changes: 0 additions & 17 deletions charts/console/templates/service.yaml

This file was deleted.

17 changes: 0 additions & 17 deletions charts/console/templates/serviceaccount.yaml

This file was deleted.

0 comments on commit 151ff93

Please sign in to comment.