Skip to content
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
2 changes: 2 additions & 0 deletions acceptance/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@ github.com/redpanda-data/common-go/secrets v0.1.3 h1:VRo+OFS4Zgb2UMvwcIuUujdMhAP
github.com/redpanda-data/common-go/secrets v0.1.3/go.mod h1:WjUU/5saSXwItZx6veFOGbQZUgPQz4MQ65z22y0Ky84=
github.com/redpanda-data/console/backend v0.0.0-20240303221210-05d5d9e85f20 h1:+zsE3W1V86k2sjAGWOySIlF0xn5R1aXXQBaIdr80F48=
github.com/redpanda-data/console/backend v0.0.0-20240303221210-05d5d9e85f20/go.mod h1:DC42/3+k5PefSo4IalYbDN3yRZrVFP0b69+gC/NwGd4=
github.com/redpanda-data/redpanda-operator/charts/console v0.0.0-20250718150737-e01f8476d560 h1:fhMikrIYgjTukRTS7zZHJ5sFQP4hotkfExEyFRWw6rI=
github.com/redpanda-data/redpanda-operator/charts/console v0.0.0-20250718150737-e01f8476d560/go.mod h1:aSiQU9wI3DcOv4tyvoJz5Gx2bUq71LHlLnPkQcGWpK4=
github.com/redpanda-data/redpanda-operator/gotohelm v1.1.0 h1:IV2Ic66JDKPtCnNU4Kn1naJlzZmhl0izRj17qgTCo20=
github.com/redpanda-data/redpanda-operator/gotohelm v1.1.0/go.mod h1:usCpPzzzhgtPrRTiUQOzFqGmukce8U0SrzEeX2ONDFE=
github.com/redpanda-data/redpanda/src/go/rpk v0.0.0-20250716004441-6e1647296ad6 h1:SbcvWTYFEbH5+NQOl1To5jppEa8RCK1HAkRNfhdUGLg=
Expand Down
58 changes: 0 additions & 58 deletions charts/console/chart.go

This file was deleted.

122 changes: 106 additions & 16 deletions charts/console/chart/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ package chart

import (
"embed"
"fmt"
"strings"

"github.com/redpanda-data/redpanda-operator/charts/console/v3"
"github.com/redpanda-data/redpanda-operator/gotohelm"
Expand All @@ -31,30 +33,118 @@ var (
//go:embed values.schema.json
ValuesSchemaJSON []byte

// ChartLabel is the go version of the console helm chart.
Chart = gotohelm.MustLoad(chartFiles, render)
// Chart is the go version of the console helm chart.
Chart = gotohelm.MustLoad(chartFiles, Render)
)

type Values struct {
console.Values `json:",inline"`

Enabled *bool `json:"enabled,omitempty"`
Tests Enableable `json:"tests"`
}

type Enableable struct {
Enabled bool `json:"enabled"`
}

// render is the entrypoint to both the go and helm versions of the console
// Render is the entrypoint to both the go and helm versions of the console
// 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 {
func Render(dot *helmette.Dot) []kube.Object {
state := DotToState(dot)

// NB: This slice may contain nil interfaces!
// Filtering happens elsewhere, don't call this function directly if you
// can avoid it.
return console.Render(dot)
return console.Render(state)
}

func DotToState(dot *helmette.Dot) *console.RenderState {
values := helmette.Unwrap[Values](dot.Values)
templater := &templater{Dot: dot, FauxDot: newFauxDot(dot)}

return &console.RenderState{
ReleaseName: dot.Release.Name,
Namespace: dot.Release.Namespace,
Values: values.RenderValues,
Template: templater.Template,
CommonLabels: map[string]string{
"helm.sh/chart": ChartLabel(dot),
"app.kubernetes.io/managed-by": dot.Release.Service,
"app.kubernetes.io/version": dot.Chart.AppVersion,
},
}
}

// templater is a fairly hacky yet effective way to abstract out the global
// `tpl` function that's plagued our rendering packages.
//
// It works around a very niche issue in gotohelm/helm:
// 1. The inability to return a [helmette.Chart]. Helm's internal version
// of `Chart` has JSON tags. Returning it in gotohelm results in all
// fields being downcased and therefore inaccessible. To work around this, we
// construct a [FauxChart] which explicitly keeps the Chart fields upper cased.
// 2. The inability to return a `helmette.Values`. Values is a wrapper type
// around a map[string]any. It comes with an AsMap function that's used by
// gotohelm. We hack in interoperability by assigning a shallow clone of the
// values to itself in the AsMap key.
type templater struct {
// Dot is present purely to satisfy the go requirements of helmette.Tpl. DO
// NOT REFERENCE IT IN HELM IT WILL NOT WORK.
Dot *helmette.Dot
FauxDot *FauxDot
}

func (t *templater) Template(tpl string) string {
return helmette.Tpl(t.Dot, tpl, t.FauxDot)
}

type FauxChart struct {
Name string
Version string
AppVersion string
}

type FauxDot struct {
Values map[string]any
Chart FauxChart
Release helmette.Release
Template helmette.Template
}

func newFauxDot(dot *helmette.Dot) *FauxDot {
clone := map[string]any{}
for key, value := range dot.Values.AsMap() {
clone[key] = value
}
// NB: A shallow clone MUST be used here. If there's any recursion, the
// JSON serialization in sprig "gives up" and returns an empty string.
clone["AsMap"] = dot.Values.AsMap()
return &FauxDot{
Values: clone,
Release: dot.Release,
Template: dot.Template,
Chart: FauxChart{
Name: dot.Chart.Name,
AppVersion: dot.Chart.AppVersion,
Version: dot.Chart.Version,
},
}
}

// Functions below this line are included for backwards compatibility purposes.
// They're re-namespaced in compat.tpl

func Name(dot *helmette.Dot) string {
return DotToState(dot).ChartName()
}

// Create a default fully qualified app name.
// We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
// If release name contains chart name it will be used as a full name.
func Fullname(dot *helmette.Dot) string {
return DotToState(dot).FullName()
}

// Create chart name and version as used by the chart label.
func ChartLabel(dot *helmette.Dot) string {
chart := fmt.Sprintf("%s-%s", dot.Chart.Name, dot.Chart.Version)
return cleanForK8s(strings.ReplaceAll(chart, "+", "_"))
}

func cleanForK8s(s string) string {
return helmette.TrimSuffix("-", helmette.Trunc(63, s))
}
13 changes: 8 additions & 5 deletions charts/console/chart/chart_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,19 @@ import (
"github.com/redpanda-data/redpanda-operator/pkg/testutil"
)

func TestArtifactHubImages(t *testing.T) {
func TestChartYAML(t *testing.T) {
var images []map[string]any
require.NoError(t, yaml.Unmarshal([]byte(Chart.Metadata().Annotations["artifacthub.io/images"]), &images))

require.Equal(t, []map[string]any{
assert.Equal(t, []map[string]any{
{
"name": "console",
"image": "docker.redpanda.com/redpandadata/console:" + Chart.Metadata().AppVersion,
},
}, images)

assert.Equal(t, console.ChartName, Chart.Metadata().Name)
assert.Equal(t, console.AppVersion, Chart.Metadata().AppVersion)
}

// TestValues asserts that the chart's values.yaml file can be losslessly
Expand Down Expand Up @@ -206,7 +209,7 @@ func TestGoHelmEquivalence(t *testing.T) {
Tests: &PartialEnableable{
Enabled: ptr.To(false),
},
PartialValues: console.PartialValues{
PartialRenderValues: console.PartialRenderValues{
Secret: &console.PartialSecretConfig{
Authentication: &console.PartialAuthenticationSecrets{
JWTSigningKey: ptr.To("SECRET"),
Expand Down Expand Up @@ -259,7 +262,7 @@ func TestGoHelmEquivalence(t *testing.T) {

func TestSecrets(t *testing.T) {
values := PartialValues{
PartialValues: console.PartialValues{
PartialRenderValues: console.PartialRenderValues{
Secret: &console.PartialSecretConfig{
Create: ptr.To(true),
Kafka: &console.PartialKafkaSecrets{
Expand Down Expand Up @@ -357,7 +360,7 @@ func TestIntegrationChart(t *testing.T) {
env := h.Namespaced(t)

partial := PartialValues{
PartialValues: console.PartialValues{
PartialRenderValues: console.PartialRenderValues{
Image: &console.PartialImage{
Repository: ptr.To("redpandadata/console-unstable"),
Tag: ptr.To("master-a4cf9be"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0

package console
package chart

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion charts/console/chart/templates/NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ 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.
*/}}
{{- $notes := (get ((include "console.Notes" (dict "a" (list .))) | fromJson) "r") -}}
{{- $notes := (get ((include "chart.Notes" (dict "a" (list .))) | fromJson) "r") -}}
{{- range $_, $note := $notes }}
{{ $note }}
{{- end }}
87 changes: 85 additions & 2 deletions charts/console/chart/templates/_chart.chart.tpl
Original file line number Diff line number Diff line change
@@ -1,12 +1,95 @@
{{- /* GENERATED FILE DO NOT EDIT */ -}}
{{- /* Transpiled by gotohelm from "github.com/redpanda-data/redpanda-operator/charts/console/v3/chart/chart.go" */ -}}

{{- define "chart.render" -}}
{{- define "chart.Render" -}}
{{- $dot := (index .a 0) -}}
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $state := (get (fromJson (include "chart.DotToState" (dict "a" (list $dot)))) "r") -}}
{{- $_is_returning = true -}}
{{- (dict "r" (get (fromJson (include "console.Render" (dict "a" (list $dot)))) "r")) | toJson -}}
{{- (dict "r" (get (fromJson (include "console.Render" (dict "a" (list $state)))) "r")) | toJson -}}
{{- break -}}
{{- end -}}
{{- end -}}

{{- define "chart.DotToState" -}}
{{- $dot := (index .a 0) -}}
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $values := $dot.Values.AsMap -}}
{{- $templater := (mustMergeOverwrite (dict "Dot" (coalesce nil) "FauxDot" (coalesce nil)) (dict "Dot" $dot "FauxDot" (get (fromJson (include "chart.newFauxDot" (dict "a" (list $dot)))) "r"))) -}}
{{- $_is_returning = true -}}
{{- (dict "r" (mustMergeOverwrite (dict "ReleaseName" "" "Namespace" "" "Template" (coalesce nil) "CommonLabels" (coalesce nil) "Values" (dict "replicaCount" 0 "nameOverride" "" "commonLabels" (coalesce nil) "fullnameOverride" "" "image" (dict "registry" "" "repository" "" "pullPolicy" "" "tag" "") "imagePullSecrets" (coalesce nil) "automountServiceAccountToken" false "serviceAccount" (dict "create" false "automountServiceAccountToken" false "annotations" (coalesce nil) "name" "") "annotations" (coalesce nil) "podAnnotations" (coalesce nil) "podLabels" (coalesce nil) "podSecurityContext" (dict) "securityContext" (dict) "service" (dict "type" "" "port" 0 "annotations" (coalesce nil)) "ingress" (dict "enabled" false "annotations" (coalesce nil) "hosts" (coalesce nil) "tls" (coalesce nil)) "resources" (dict) "autoscaling" (dict "enabled" false "minReplicas" 0 "maxReplicas" 0 "targetCPUUtilizationPercentage" (coalesce nil)) "nodeSelector" (coalesce nil) "tolerations" (coalesce nil) "affinity" (dict) "topologySpreadConstraints" (coalesce nil) "priorityClassName" "" "config" (coalesce nil) "extraEnv" (coalesce nil) "extraEnvFrom" (coalesce nil) "extraVolumes" (coalesce nil) "extraVolumeMounts" (coalesce nil) "extraContainers" (coalesce nil) "initContainers" (dict "extraInitContainers" (coalesce nil)) "secretMounts" (coalesce nil) "secret" (dict "create" false "kafka" (dict) "authentication" (dict "jwtSigningKey" "" "oidc" (dict)) "license" "" "redpanda" (dict "adminApi" (dict)) "serde" (dict) "schemaRegistry" (dict)) "livenessProbe" (dict) "readinessProbe" (dict) "configmap" (dict "create" false) "deployment" (dict "create" false) "strategy" (dict))) (dict "ReleaseName" $dot.Release.Name "Namespace" $dot.Release.Namespace "Values" $values "Template" (list "chart.templater.Template" $templater) "CommonLabels" (dict "helm.sh/chart" (get (fromJson (include "chart.ChartLabel" (dict "a" (list $dot)))) "r") "app.kubernetes.io/managed-by" $dot.Release.Service "app.kubernetes.io/version" $dot.Chart.AppVersion)))) | toJson -}}
{{- break -}}
{{- end -}}
{{- end -}}

{{- define "chart.templater.Template" -}}
{{- $t := (index .a 0) -}}
{{- $tpl := (index .a 1) -}}
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $_is_returning = true -}}
{{- (dict "r" (tpl $tpl $t.FauxDot)) | toJson -}}
{{- break -}}
{{- end -}}
{{- end -}}

{{- define "chart.newFauxDot" -}}
{{- $dot := (index .a 0) -}}
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $clone := (dict) -}}
{{- range $key, $value := $dot.Values.AsMap -}}
{{- $_ := (set $clone $key $value) -}}
{{- end -}}
{{- if $_is_returning -}}
{{- break -}}
{{- end -}}
{{- $_ := (set $clone "AsMap" $dot.Values.AsMap) -}}
{{- $_is_returning = true -}}
{{- (dict "r" (mustMergeOverwrite (dict "Values" (coalesce nil) "Chart" (dict "Name" "" "Version" "" "AppVersion" "") "Release" (dict "Name" "" "Namespace" "" "Service" "" "IsUpgrade" false "IsInstall" false) "Template" (dict "Name" "" "BasePath" "")) (dict "Values" $clone "Release" $dot.Release "Template" $dot.Template "Chart" (mustMergeOverwrite (dict "Name" "" "Version" "" "AppVersion" "") (dict "Name" $dot.Chart.Name "AppVersion" $dot.Chart.AppVersion "Version" $dot.Chart.Version))))) | toJson -}}
{{- break -}}
{{- end -}}
{{- end -}}

{{- define "chart.Name" -}}
{{- $dot := (index .a 0) -}}
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $_is_returning = true -}}
{{- (dict "r" (get (fromJson (include "console.RenderState.ChartName" (dict "a" (list (get (fromJson (include "chart.DotToState" (dict "a" (list $dot)))) "r"))))) "r")) | toJson -}}
{{- break -}}
{{- end -}}
{{- end -}}

{{- define "chart.Fullname" -}}
{{- $dot := (index .a 0) -}}
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $_is_returning = true -}}
{{- (dict "r" (get (fromJson (include "console.RenderState.FullName" (dict "a" (list (get (fromJson (include "chart.DotToState" (dict "a" (list $dot)))) "r"))))) "r")) | toJson -}}
{{- break -}}
{{- end -}}
{{- end -}}

{{- define "chart.ChartLabel" -}}
{{- $dot := (index .a 0) -}}
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $chart := (printf "%s-%s" $dot.Chart.Name $dot.Chart.Version) -}}
{{- $_is_returning = true -}}
{{- (dict "r" (get (fromJson (include "chart.cleanForK8s" (dict "a" (list (replace "+" "_" $chart))))) "r")) | toJson -}}
{{- break -}}
{{- end -}}
{{- end -}}

{{- define "chart.cleanForK8s" -}}
{{- $s := (index .a 0) -}}
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $_is_returning = true -}}
{{- (dict "r" (trimSuffix "-" (trunc (63 | int) $s))) | toJson -}}
{{- break -}}
{{- end -}}
{{- end -}}
Expand Down
Loading
Loading