diff --git a/.changes/unreleased/charts-console-Added-20260320-180000.yaml b/.changes/unreleased/charts-console-Added-20260320-180000.yaml new file mode 100644 index 000000000..fd9341c40 --- /dev/null +++ b/.changes/unreleased/charts-console-Added-20260320-180000.yaml @@ -0,0 +1,4 @@ +project: charts/console +kind: Added +body: Add Gateway API (HTTPRoute) support as an alternative to Ingress for exposing Console. Only one of gateway or ingress may be enabled at a time. +time: 2026-03-20T18:00:00.000000-05:00 diff --git a/.changes/unreleased/operator-Added-20260320-180000.yaml b/.changes/unreleased/operator-Added-20260320-180000.yaml new file mode 100644 index 000000000..5a1511714 --- /dev/null +++ b/.changes/unreleased/operator-Added-20260320-180000.yaml @@ -0,0 +1,4 @@ +project: operator +kind: Added +body: Add Gateway API (HTTPRoute) support to Console CRD, allowing Console to be exposed via Gateway API controllers as an alternative to Ingress. Bumps sigs.k8s.io/gateway-api to v1.5.1. +time: 2026-03-20T18:00:00.000000-05:00 diff --git a/acceptance/go.mod b/acceptance/go.mod index fed0ea26c..e8368fd11 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -313,7 +313,7 @@ require ( k8s.io/kubectl v0.35.1 // indirect oras.land/oras-go/v2 v2.6.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect - sigs.k8s.io/gateway-api v1.4.1 // indirect + sigs.k8s.io/gateway-api v1.5.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index ce20284b7..b356515a7 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -337,8 +337,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLxCY3f87278uWfIDhJnbdvDjvmE= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -551,10 +551,10 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 h1:H55sU3giNgBkIvmAo0vI/AAFwVTwfWsf6MN3+9H6U8o= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98/go.mod h1:RqnyioA3pIEZMkSbOIcrw32YSgETfn/VrLuEikEdPNU= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -955,8 +955,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= -sigs.k8s.io/gateway-api v1.4.1 h1:NPxFutNkKNa8UfLd2CMlEuhIPMQgDQ6DXNKG9sHbJU8= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0= +sigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= diff --git a/charts/connectors/go.mod b/charts/connectors/go.mod index d46e25f03..a96d141ec 100644 --- a/charts/connectors/go.mod +++ b/charts/connectors/go.mod @@ -136,6 +136,8 @@ require ( github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/onsi/ginkgo/v2 v2.28.0 // indirect + github.com/onsi/gomega v1.39.1 // indirect github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect @@ -220,6 +222,7 @@ require ( oras.land/oras-go/v2 v2.6.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect sigs.k8s.io/controller-runtime v0.23.1 // indirect + sigs.k8s.io/gateway-api v1.5.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect diff --git a/charts/connectors/go.sum b/charts/connectors/go.sum index c553f7bdf..dc17431ec 100644 --- a/charts/connectors/go.sum +++ b/charts/connectors/go.sum @@ -215,8 +215,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLxCY3f87278uWfIDhJnbdvDjvmE= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= @@ -352,10 +352,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 h1:H55sU3giNgBkIvmAo0vI/AAFwVTwfWsf6MN3+9H6U8o= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98/go.mod h1:RqnyioA3pIEZMkSbOIcrw32YSgETfn/VrLuEikEdPNU= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -698,8 +698,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= -sigs.k8s.io/gateway-api v1.4.1 h1:NPxFutNkKNa8UfLd2CMlEuhIPMQgDQ6DXNKG9sHbJU8= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0= +sigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= diff --git a/charts/console/chart/README.md b/charts/console/chart/README.md index 2c500b9a8..7b0cf10e3 100644 --- a/charts/console/chart/README.md +++ b/charts/console/chart/README.md @@ -117,6 +117,28 @@ Override `console.fullname` template. **Default:** `""` +### [gateway](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=gateway) + +Gateway API `HTTPRoute` settings. + +**Default:** + +``` +{"annotations":{},"enabled":false,"hostnames":["chart-example.local"],"parentRefs":[],"path":"/","pathType":"PathPrefix"} +``` + +### [gateway.parentRefs](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=gateway.parentRefs) + +Gateway parent references for this route. If no parentRefs are specified, the HTTPRoute is still rendered but will not attach to any Gateway until configured. + +**Default:** `[]` + +### [gateway.pathType](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=gateway.pathType) + +One of Exact, PathPrefix, or RegularExpression. + +**Default:** `"PathPrefix"` + ### [image](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=image) Redpanda Console Docker image settings. diff --git a/charts/console/chart/notes.go b/charts/console/chart/notes.go index 57fff974a..b1561f929 100644 --- a/charts/console/chart/notes.go +++ b/charts/console/chart/notes.go @@ -21,6 +21,11 @@ func Notes(dot *helmette.Dot) []string { commands := []string{ `1. Get the application URL by running these commands:`, } + if values.Gateway.Enabled { + for _, hostname := range values.Gateway.Hostnames { + commands = append(commands, fmt.Sprintf("http://%s%s", hostname, values.Gateway.Path)) + } + } if values.Ingress.Enabled { scheme := "http" if len(values.Ingress.TLS) > 0 { @@ -31,7 +36,13 @@ func Notes(dot *helmette.Dot) []string { commands = append(commands, fmt.Sprintf("%s://%s%s", scheme, host.Host, path.Path)) } } - } else if helmette.Contains("NodePort", string(values.Service.Type)) { + } + + if len(commands) > 1 { + return commands + } + + if helmette.Contains("NodePort", string(values.Service.Type)) { commands = append( commands, fmt.Sprintf(` export NODE_PORT=$(kubectl get --namespace %s -o jsonpath="{.spec.ports[0].nodePort}" services %s)`, dot.Release.Namespace, Fullname(dot)), diff --git a/charts/console/chart/templates/_chart.chart.tpl b/charts/console/chart/templates/_chart.chart.tpl index 5d5c27eb5..55552844b 100644 --- a/charts/console/chart/templates/_chart.chart.tpl +++ b/charts/console/chart/templates/_chart.chart.tpl @@ -36,7 +36,7 @@ {{- $_ := (set $values.secret.authentication "jwtSigningKey" (randAlphaNum (32 | int))) -}} {{- end -}} {{- $_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) "extraContainerPorts" (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) "monitoring" (dict "enabled" false "scrapeInterval" "" "labels" (coalesce nil))) "Metrics" (dict "ViaOperator" false "CloudEnvironment" "" "KubernetesVersion" "" "ChartVersion" "" "ClusterID" "")) (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 -}} +{{- (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)) "gateway" (dict "enabled" false "annotations" (coalesce nil) "parentRefs" (coalesce nil) "hostnames" (coalesce nil) "path" "") "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) "extraContainerPorts" (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) "monitoring" (dict "enabled" false "scrapeInterval" "" "labels" (coalesce nil))) "Metrics" (dict "ViaOperator" false "CloudEnvironment" "" "KubernetesVersion" "" "ChartVersion" "" "ClusterID" "")) (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 -}} diff --git a/charts/console/chart/templates/_chart.notes.tpl b/charts/console/chart/templates/_chart.notes.tpl index b1b113e48..acbf068e4 100644 --- a/charts/console/chart/templates/_chart.notes.tpl +++ b/charts/console/chart/templates/_chart.notes.tpl @@ -7,6 +7,14 @@ {{- $_is_returning := false -}} {{- $values := $dot.Values.AsMap -}} {{- $commands := (list `1. Get the application URL by running these commands:`) -}} +{{- if $values.gateway.enabled -}} +{{- range $_, $hostname := $values.gateway.hostnames -}} +{{- $commands = (concat (default (list) $commands) (list (printf "http://%s%s" $hostname $values.gateway.path))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- end -}} {{- if $values.ingress.enabled -}} {{- $scheme := "http" -}} {{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $values.ingress.tls)))) "r") | int) (0 | int)) -}} @@ -23,7 +31,13 @@ {{- if $_is_returning -}} {{- break -}} {{- end -}} -{{- else -}}{{- if (contains "NodePort" (toString $values.service.type)) -}} +{{- end -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $commands)))) "r") | int) (1 | int)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $commands) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (contains "NodePort" (toString $values.service.type)) -}} {{- $commands = (concat (default (list) $commands) (list (printf ` export NODE_PORT=$(kubectl get --namespace %s -o jsonpath="{.spec.ports[0].nodePort}" services %s)` $dot.Release.Namespace (get (fromJson (include "chart.Fullname" (dict "a" (list $dot)))) "r")) (printf ` export NODE_IP=$(kubectl get nodes --namespace %s -o jsonpath="{.items[0].status.addresses[0].address}")` $dot.Release.Namespace) " echo http://$NODE_IP:$NODE_PORT")) -}} {{- else -}}{{- if (contains "NodePort" (toString $values.service.type)) -}} {{- $commands = (concat (default (list) $commands) (list ` NOTE: It may take a few minutes for the LoadBalancer IP to be available.` (printf ` You can watch the status of by running 'kubectl get --namespace %s svc -w %s'` $dot.Release.Namespace (get (fromJson (include "chart.Fullname" (dict "a" (list $dot)))) "r")) (printf ` export SERVICE_IP=$(kubectl get svc --namespace %s %s --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")` $dot.Release.Namespace (get (fromJson (include "chart.Fullname" (dict "a" (list $dot)))) "r")) (printf ` echo http://$SERVICE_IP:%d` ($values.service.port | int)))) -}} @@ -32,7 +46,6 @@ {{- end -}} {{- end -}} {{- end -}} -{{- end -}} {{- $_is_returning = true -}} {{- (dict "r" $commands) | toJson -}} {{- break -}} diff --git a/charts/console/chart/templates/_console.gateway.tpl b/charts/console/chart/templates/_console.gateway.tpl new file mode 100644 index 000000000..58b741645 --- /dev/null +++ b/charts/console/chart/templates/_console.gateway.tpl @@ -0,0 +1,47 @@ +{{- /* GENERATED FILE DO NOT EDIT */ -}} +{{- /* Transpiled by gotohelm from "github.com/redpanda-data/redpanda-operator/charts/console/v3/gateway.go" */ -}} + +{{- define "console.HTTPRoute" -}} +{{- $state := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (not $state.Values.gateway.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $parentRefs := (coalesce nil) -}} +{{- range $_, $parentRef := $state.Values.gateway.parentRefs -}} +{{- $ref := (mustMergeOverwrite (dict "name" "") (dict "name" (toString (get (fromJson (include (first $state.Template) (dict "a" (concat (rest $state.Template) (list $parentRef.name))))) "r")))) -}} +{{- if (ne (toJson $parentRef.namespace) "null") -}} +{{- $namespace := (get (fromJson (include (first $state.Template) (dict "a" (concat (rest $state.Template) (list $parentRef.namespace))))) "r") -}} +{{- $_ := (set $ref "namespace" (toString $namespace)) -}} +{{- end -}} +{{- if (ne (toJson $parentRef.sectionName) "null") -}} +{{- $sectionName := (toString (get (fromJson (include (first $state.Template) (dict "a" (concat (rest $state.Template) (list (toString $parentRef.sectionName)))))) "r")) -}} +{{- $_ := (set $ref "sectionName" $sectionName) -}} +{{- end -}} +{{- $parentRefs = (concat (default (list) $parentRefs) (list $ref)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $hostnames := (coalesce nil) -}} +{{- range $_, $hostname := $state.Values.gateway.hostnames -}} +{{- $hostnames = (concat (default (list) $hostnames) (list (toString (get (fromJson (include (first $state.Template) (dict "a" (concat (rest $state.Template) (list $hostname))))) "r")))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $pathType := "PathPrefix" -}} +{{- if (ne (toJson $state.Values.gateway.pathType) "null") -}} +{{- $pathType = $state.Values.gateway.pathType -}} +{{- end -}} +{{- $path := (get (fromJson (include (first $state.Template) (dict "a" (concat (rest $state.Template) (list $state.Values.gateway.path))))) "r") -}} +{{- $port := (($state.Values.service.port | int) | int) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict) "status" (dict "parents" (coalesce nil))) (mustMergeOverwrite (dict) (dict "kind" "HTTPRoute" "apiVersion" "gateway.networking.k8s.io/v1")) (dict "metadata" (mustMergeOverwrite (dict) (dict "name" (get (fromJson (include "console.RenderState.FullName" (dict "a" (list $state)))) "r") "labels" (get (fromJson (include "console.RenderState.Labels" (dict "a" (list $state (coalesce nil))))) "r") "namespace" $state.Namespace "annotations" $state.Values.gateway.annotations)) "spec" (mustMergeOverwrite (dict) (mustMergeOverwrite (dict) (dict "parentRefs" $parentRefs)) (dict "hostnames" $hostnames "rules" (list (mustMergeOverwrite (dict) (dict "matches" (list (mustMergeOverwrite (dict) (dict "path" (mustMergeOverwrite (dict) (dict "type" $pathType "value" $path))))) "backendRefs" (list (mustMergeOverwrite (dict "name" "") (mustMergeOverwrite (dict "name" "") (mustMergeOverwrite (dict "name" "") (dict "name" (toString (get (fromJson (include "console.RenderState.FullName" (dict "a" (list $state)))) "r")) "port" $port)) (dict)) (dict))))))))))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/console/chart/templates/_console.render.tpl b/charts/console/chart/templates/_console.render.tpl index 66d8af884..d8a00f1c5 100644 --- a/charts/console/chart/templates/_console.render.tpl +++ b/charts/console/chart/templates/_console.render.tpl @@ -80,7 +80,7 @@ {{- $state := (index .a 0) -}} {{- range $_ := (list 1) -}} {{- $_is_returning := false -}} -{{- $manifests := (list (get (fromJson (include "console.ServiceAccount" (dict "a" (list $state)))) "r") (get (fromJson (include "console.Secret" (dict "a" (list $state)))) "r") (get (fromJson (include "console.ConfigMap" (dict "a" (list $state)))) "r") (get (fromJson (include "console.Service" (dict "a" (list $state)))) "r") (get (fromJson (include "console.Ingress" (dict "a" (list $state)))) "r") (get (fromJson (include "console.Deployment" (dict "a" (list $state)))) "r") (get (fromJson (include "console.HorizontalPodAutoscaler" (dict "a" (list $state)))) "r") (get (fromJson (include "console.ServiceMonitor" (dict "a" (list $state)))) "r")) -}} +{{- $manifests := (list (get (fromJson (include "console.ServiceAccount" (dict "a" (list $state)))) "r") (get (fromJson (include "console.Secret" (dict "a" (list $state)))) "r") (get (fromJson (include "console.ConfigMap" (dict "a" (list $state)))) "r") (get (fromJson (include "console.Service" (dict "a" (list $state)))) "r") (get (fromJson (include "console.Ingress" (dict "a" (list $state)))) "r") (get (fromJson (include "console.HTTPRoute" (dict "a" (list $state)))) "r") (get (fromJson (include "console.Deployment" (dict "a" (list $state)))) "r") (get (fromJson (include "console.HorizontalPodAutoscaler" (dict "a" (list $state)))) "r") (get (fromJson (include "console.ServiceMonitor" (dict "a" (list $state)))) "r")) -}} {{- $_is_returning = true -}} {{- (dict "r" $manifests) | toJson -}} {{- break -}} @@ -91,7 +91,7 @@ {{- range $_ := (list 1) -}} {{- $_is_returning := false -}} {{- $_is_returning = true -}} -{{- (dict "r" (list (mustMergeOverwrite (dict "metadata" (dict)) (dict)) (mustMergeOverwrite (dict "metadata" (dict)) (dict)) (mustMergeOverwrite (dict "metadata" (dict)) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict) "status" (dict "loadBalancer" (dict))) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict) "status" (dict "loadBalancer" (dict))) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict "selector" (coalesce nil) "template" (dict "metadata" (dict) "spec" (dict "containers" (coalesce nil))) "strategy" (dict)) "status" (dict)) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict "scaleTargetRef" (dict "kind" "" "name" "") "maxReplicas" 0) "status" (dict "desiredReplicas" 0 "currentMetrics" (coalesce nil))) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict "endpoints" (coalesce nil) "selector" (dict) "namespaceSelector" (dict))) (dict)))) | toJson -}} +{{- (dict "r" (list (mustMergeOverwrite (dict "metadata" (dict)) (dict)) (mustMergeOverwrite (dict "metadata" (dict)) (dict)) (mustMergeOverwrite (dict "metadata" (dict)) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict) "status" (dict "loadBalancer" (dict))) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict) "status" (dict "loadBalancer" (dict))) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict) "status" (dict "parents" (coalesce nil))) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict "selector" (coalesce nil) "template" (dict "metadata" (dict) "spec" (dict "containers" (coalesce nil))) "strategy" (dict)) "status" (dict)) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict "scaleTargetRef" (dict "kind" "" "name" "") "maxReplicas" 0) "status" (dict "desiredReplicas" 0 "currentMetrics" (coalesce nil))) (dict)) (mustMergeOverwrite (dict "metadata" (dict) "spec" (dict "endpoints" (coalesce nil) "selector" (dict) "namespaceSelector" (dict))) (dict)))) | toJson -}} {{- break -}} {{- end -}} {{- end -}} diff --git a/charts/console/chart/testdata/template-cases.golden.txtar b/charts/console/chart/testdata/template-cases.golden.txtar index 4a3492b9c..694ea9de0 100644 --- a/charts/console/chart/testdata/template-cases.golden.txtar +++ b/charts/console/chart/testdata/template-cases.golden.txtar @@ -22205,6 +22205,229 @@ spec: - name: secrets secret: secretName: console +-- testdata/gateway-templating.yaml.golden -- +--- +# Source: console/templates/entry-point.yaml +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v3.3.2 + helm.sh/chart: console-3.3.0 + name: console + namespace: test-namespace +--- +# Source: console/templates/entry-point.yaml +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v3.3.2 + helm.sh/chart: console-3.3.0 + name: console + namespace: test-namespace +stringData: + authentication-jwt-signingkey: SECRETKEY + authentication-oidc-client-secret: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + license: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" + schema-registry-bearertoken: "" + schema-registry-password: "" + schemaregistry-tls-ca: "" + schemaregistry-tls-cert: "" + schemaregistry-tls-key: "" + serde-protobuf-git-basicauth-password: "" +type: Opaque +--- +# Source: console/templates/entry-point.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.config + {} +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v3.3.2 + helm.sh/chart: console-3.3.0 + name: console + namespace: test-namespace +--- +# Source: console/templates/entry-point.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v3.3.2 + helm.sh/chart: console-3.3.0 + name: console + namespace: test-namespace +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/entry-point.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v3.3.2 + helm.sh/chart: console-3.3.0 + name: console + namespace: test-namespace +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 28d978af90a43439edaee767a120fd85a15f923d1977979170de19b9e74c5895 + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: false + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: AUTHENTICATION_JWTSIGNINGKEY + valueFrom: + secretKeyRef: + key: authentication-jwt-signingkey + name: console + - name: REDPANDA_METRICS_K8S_DEPLOYMENT_TYPE + value: helm + - name: REDPANDA_METRICS_K8S_CHART_VERSION + value: 3.3.0 + - name: REDPANDA_METRICS_K8S_CONSOLE_IMAGE_VERSION + value: redpandadata/console:v3.3.2 + - name: REDPANDA_METRICS_K8S_VERSION + value: v1.99.0 + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v3.3.2 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: null + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + fsGroupChangePolicy: Always + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/entry-point.yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + annotations: + gateway: test + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v3.3.2 + helm.sh/chart: console-3.3.0 + name: console + namespace: test-namespace +spec: + hostnames: + - '"console.example.local"' + parentRefs: + - name: '"public-gateway"' + namespace: '"networking"' + sectionName: '"http"' + rules: + - backendRefs: + - name: console + port: 8080 + matches: + - path: + type: PathPrefix + value: / -- testdata/ingress-templating.yaml.golden -- --- # Source: console/templates/entry-point.yaml diff --git a/charts/console/chart/testdata/template-cases.txtar b/charts/console/chart/testdata/template-cases.txtar index d5aa06c3a..dcb1f2552 100644 --- a/charts/console/chart/testdata/template-cases.txtar +++ b/charts/console/chart/testdata/template-cases.txtar @@ -66,6 +66,20 @@ ingress: hosts: - '{{ "blah" | quote }}' +-- gateway-templating -- +gateway: + enabled: true + annotations: + gateway: test + parentRefs: + - name: '{{ "public-gateway" | quote }}' + namespace: '{{ "networking" | quote }}' + sectionName: '{{ "http" | quote }}' + hostnames: + - '{{ "console.example.local" | quote }}' + path: '{{ "/" }}' + pathType: PathPrefix + -- no-registry -- image: registry: "" diff --git a/charts/console/chart/values.schema.json b/charts/console/chart/values.schema.json index 0e753ba12..5bde8e4d9 100644 --- a/charts/console/chart/values.schema.json +++ b/charts/console/chart/values.schema.json @@ -3051,6 +3051,65 @@ "fullnameOverride": { "type": "string" }, + "gateway": { + "additionalProperties": false, + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "hostnames": { + "oneOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "parentRefs": { + "oneOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "sectionName": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "path": { + "type": "string" + }, + "pathType": { + "type": "string" + } + }, + "type": "object" + }, "global": { "type": "object" }, diff --git a/charts/console/chart/values.yaml b/charts/console/chart/values.yaml index 02086fcfd..b182f7625 100644 --- a/charts/console/chart/values.yaml +++ b/charts/console/chart/values.yaml @@ -107,6 +107,23 @@ ingress: # hosts: # - chart-example.local +# -- Gateway API `HTTPRoute` settings. +gateway: + enabled: false + annotations: {} + # -- Gateway parent references for this route. + # If no parentRefs are specified, the HTTPRoute is still rendered but will + # not attach to any Gateway until configured. + parentRefs: [] + # - name: public-gateway + # namespace: default + # sectionName: http + hostnames: + - chart-example.local + path: / + # -- One of Exact, PathPrefix, or RegularExpression. + pathType: PathPrefix + resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little diff --git a/charts/console/gateway.go b/charts/console/gateway.go new file mode 100644 index 000000000..b33884eaf --- /dev/null +++ b/charts/console/gateway.go @@ -0,0 +1,92 @@ +// Copyright 2026 Redpanda Data, Inc. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.md +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0 + +package console + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" +) + +func HTTPRoute(state *RenderState) *gatewayv1.HTTPRoute { + if !state.Values.Gateway.Enabled { + return nil + } + + var parentRefs []gatewayv1.ParentReference + for _, parentRef := range state.Values.Gateway.ParentRefs { + ref := gatewayv1.ParentReference{ + Name: gatewayv1.ObjectName(state.Template(parentRef.Name)), + } + if parentRef.Namespace != nil { + namespace := state.Template(*parentRef.Namespace) + ref.Namespace = ptr.To(gatewayv1.Namespace(namespace)) + } + if parentRef.SectionName != nil { + sectionName := gatewayv1.SectionName(state.Template(string(*parentRef.SectionName))) + ref.SectionName = ptr.To(sectionName) + } + parentRefs = append(parentRefs, ref) + } + + var hostnames []gatewayv1.Hostname + for _, hostname := range state.Values.Gateway.Hostnames { + hostnames = append(hostnames, gatewayv1.Hostname(state.Template(hostname))) + } + + pathType := gatewayv1.PathMatchPathPrefix + if state.Values.Gateway.PathType != nil { + pathType = *state.Values.Gateway.PathType + } + + path := state.Template(state.Values.Gateway.Path) + port := gatewayv1.PortNumber(state.Values.Service.Port) + + return &gatewayv1.HTTPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "HTTPRoute", + APIVersion: "gateway.networking.k8s.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: state.FullName(), + Labels: state.Labels(nil), + Namespace: state.Namespace, + Annotations: state.Values.Gateway.Annotations, + }, + Spec: gatewayv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayv1.CommonRouteSpec{ + ParentRefs: parentRefs, + }, + Hostnames: hostnames, + Rules: []gatewayv1.HTTPRouteRule{ + { + Matches: []gatewayv1.HTTPRouteMatch{ + { + Path: &gatewayv1.HTTPPathMatch{ + Type: ptr.To(pathType), + Value: ptr.To(path), + }, + }, + }, + BackendRefs: []gatewayv1.HTTPBackendRef{ + { + BackendRef: gatewayv1.BackendRef{ + BackendObjectReference: gatewayv1.BackendObjectReference{ + Name: gatewayv1.ObjectName(state.FullName()), + Port: ptr.To(port), + }, + }, + }, + }, + }, + }, + }, + } +} diff --git a/charts/console/go.mod b/charts/console/go.mod index ac4ce17b6..b01dc67fe 100644 --- a/charts/console/go.mod +++ b/charts/console/go.mod @@ -20,6 +20,7 @@ require ( k8s.io/client-go v0.35.1 k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 sigs.k8s.io/controller-runtime v0.23.1 + sigs.k8s.io/gateway-api v1.5.1 sigs.k8s.io/yaml v1.6.0 ) @@ -124,6 +125,7 @@ require ( github.com/google/cel-go v0.27.0 // indirect github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect + github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect diff --git a/charts/console/go.sum b/charts/console/go.sum index fad5ce7ed..fd3a1d19f 100644 --- a/charts/console/go.sum +++ b/charts/console/go.sum @@ -288,8 +288,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLxCY3f87278uWfIDhJnbdvDjvmE= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -467,10 +467,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 h1:H55sU3giNgBkIvmAo0vI/AAFwVTwfWsf6MN3+9H6U8o= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98/go.mod h1:RqnyioA3pIEZMkSbOIcrw32YSgETfn/VrLuEikEdPNU= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -838,8 +838,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= -sigs.k8s.io/gateway-api v1.4.1 h1:NPxFutNkKNa8UfLd2CMlEuhIPMQgDQ6DXNKG9sHbJU8= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0= +sigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= diff --git a/charts/console/render.go b/charts/console/render.go index c0ffdd761..dca343494 100644 --- a/charts/console/render.go +++ b/charts/console/render.go @@ -25,6 +25,7 @@ import ( networkingv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/yaml" "github.com/redpanda-data/redpanda-operator/gotohelm/helmette" @@ -47,6 +48,7 @@ const ( func init() { must(scheme.AddToScheme(Scheme)) must(monitoringv1.AddToScheme(Scheme)) + must(gatewayv1.Install(Scheme)) } // +gotohelm:ignore=true @@ -183,6 +185,7 @@ func Render(state *RenderState) []kube.Object { ConfigMap(state), Service(state), Ingress(state), + HTTPRoute(state), Deployment(state), HorizontalPodAutoscaler(state), ServiceMonitor(state), @@ -201,6 +204,7 @@ func Types() []kube.Object { &corev1.ConfigMap{}, &corev1.Service{}, &networkingv1.Ingress{}, + &gatewayv1.HTTPRoute{}, &appsv1.Deployment{}, &autoscalingv2.HorizontalPodAutoscaler{}, &monitoringv1.ServiceMonitor{}, diff --git a/charts/console/render_test.go b/charts/console/render_test.go index 2ff93fee4..7db1fe7b2 100644 --- a/charts/console/render_test.go +++ b/charts/console/render_test.go @@ -15,9 +15,11 @@ import ( "reflect" "testing" + "github.com/redpanda-data/common-go/kube" "github.com/stretchr/testify/require" networkingv1 "k8s.io/api/networking/v1" "k8s.io/utils/ptr" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" ) // TestAppVersion asserts that the AppVersion const is inline with the version @@ -69,19 +71,14 @@ func TestTypes(t *testing.T) { Deployment: &PartialDeploymentConfig{ Create: ptr.To(true), }, - Ingress: &PartialIngressConfig{ + Gateway: &PartialGatewayConfig{ Enabled: ptr.To(true), - Hosts: []PartialIngressHost{ + ParentRefs: []PartialGatewayParentReference{ { - Host: ptr.To("console.example.com"), - Paths: []PartialIngressPath{ - { - Path: ptr.To("/"), - PathType: ptr.To(networkingv1.PathTypePrefix), - }, - }, + Name: ptr.To("public-gateway"), }, }, + Hostnames: []string{"console.example.com"}, }, Autoscaling: &PartialAutoScaling{ Enabled: ptr.To(true), @@ -112,6 +109,18 @@ func TestTypes(t *testing.T) { }, }, }, + { + name: "gateway disabled", + values: PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(false), + PathType: ptr.To(gatewayv1.PathMatchPathPrefix), + }, + ConfigMap: &PartialCreatable{ + Create: ptr.To(true), + }, + }, + }, { name: "autoscaling disabled", values: PartialRenderValues{ @@ -138,3 +147,440 @@ func TestTypes(t *testing.T) { }) } } + +func TestIngressAndGatewayCoexistence(t *testing.T) { + state, err := NewRenderState("test-namespace", "test-release", nil, PartialRenderValues{ + Ingress: &PartialIngressConfig{ + Enabled: ptr.To(true), + Hosts: []PartialIngressHost{ + { + Host: ptr.To("console.example.com"), + Paths: []PartialIngressPath{ + { + Path: ptr.To("/"), + PathType: ptr.To(networkingv1.PathTypePrefix), + }, + }, + }, + }, + }, + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + ParentRefs: []PartialGatewayParentReference{ + { + Name: ptr.To("public-gateway"), + }, + }, + Hostnames: []string{"console.example.com"}, + }, + }) + require.NoError(t, err) + + var hasIngress, hasHTTPRoute bool + for _, obj := range Render(state) { + if !isNonNil(obj) { + continue + } + if _, ok := obj.(*networkingv1.Ingress); ok { + hasIngress = true + } + if _, ok := obj.(*gatewayv1.HTTPRoute); ok { + hasHTTPRoute = true + } + } + require.True(t, hasIngress, "both enabled should produce Ingress") + require.True(t, hasHTTPRoute, "both enabled should produce HTTPRoute") +} + +// findHTTPRoute extracts the rendered HTTPRoute from a Render output, or nil. +func findHTTPRoute(objs []kube.Object) *gatewayv1.HTTPRoute { + for _, obj := range objs { + if !isNonNil(obj) { + continue + } + if hr, ok := obj.(*gatewayv1.HTTPRoute); ok { + return hr + } + } + return nil +} + +func TestGatewayConfigFields(t *testing.T) { + t.Run("hostnames", func(t *testing.T) { + state, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"a.example.com", "b.example.com"}, + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("gw")}, + }, + }, + }) + require.NoError(t, err) + hr := findHTTPRoute(Render(state)) + require.NotNil(t, hr) + require.Equal(t, []gatewayv1.Hostname{"a.example.com", "b.example.com"}, hr.Spec.Hostnames) + }) + + t.Run("change hostnames", func(t *testing.T) { + // First config + state1, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"old.example.com"}, + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("gw")}, + }, + }, + }) + require.NoError(t, err) + hr1 := findHTTPRoute(Render(state1)) + require.NotNil(t, hr1) + require.Equal(t, []gatewayv1.Hostname{"old.example.com"}, hr1.Spec.Hostnames) + + // Updated config + state2, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"new.example.com", "also-new.example.com"}, + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("gw")}, + }, + }, + }) + require.NoError(t, err) + hr2 := findHTTPRoute(Render(state2)) + require.NotNil(t, hr2) + require.Equal(t, []gatewayv1.Hostname{"new.example.com", "also-new.example.com"}, hr2.Spec.Hostnames) + }) + + t.Run("path and pathType", func(t *testing.T) { + state, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + Path: ptr.To("/api/v1"), + PathType: ptr.To(gatewayv1.PathMatchExact), + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("gw")}, + }, + }, + }) + require.NoError(t, err) + hr := findHTTPRoute(Render(state)) + require.NotNil(t, hr) + require.Len(t, hr.Spec.Rules, 1) + require.Len(t, hr.Spec.Rules[0].Matches, 1) + match := hr.Spec.Rules[0].Matches[0] + require.NotNil(t, match.Path) + require.Equal(t, gatewayv1.PathMatchExact, *match.Path.Type) + require.Equal(t, "/api/v1", *match.Path.Value) + }) + + t.Run("change path", func(t *testing.T) { + state1, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + Path: ptr.To("/old"), + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("gw")}, + }, + }, + }) + require.NoError(t, err) + hr1 := findHTTPRoute(Render(state1)) + require.Equal(t, "/old", *hr1.Spec.Rules[0].Matches[0].Path.Value) + + state2, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + Path: ptr.To("/new/path"), + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("gw")}, + }, + }, + }) + require.NoError(t, err) + hr2 := findHTTPRoute(Render(state2)) + require.Equal(t, "/new/path", *hr2.Spec.Rules[0].Matches[0].Path.Value) + }) + + t.Run("annotations", func(t *testing.T) { + state, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + Annotations: map[string]string{ + "example.com/team": "platform", + "example.com/owner": "alice", + }, + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("gw")}, + }, + }, + }) + require.NoError(t, err) + hr := findHTTPRoute(Render(state)) + require.NotNil(t, hr) + require.Equal(t, "platform", hr.Annotations["example.com/team"]) + require.Equal(t, "alice", hr.Annotations["example.com/owner"]) + }) + + t.Run("change annotations", func(t *testing.T) { + state1, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + Annotations: map[string]string{"old-key": "old-val"}, + ParentRefs: []PartialGatewayParentReference{{Name: ptr.To("gw")}}, + }, + }) + require.NoError(t, err) + hr1 := findHTTPRoute(Render(state1)) + require.Equal(t, "old-val", hr1.Annotations["old-key"]) + + state2, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + Annotations: map[string]string{"new-key": "new-val"}, + ParentRefs: []PartialGatewayParentReference{{Name: ptr.To("gw")}}, + }, + }) + require.NoError(t, err) + hr2 := findHTTPRoute(Render(state2)) + require.Equal(t, "new-val", hr2.Annotations["new-key"]) + require.Empty(t, hr2.Annotations["old-key"]) + }) + + t.Run("parentRefs with all fields", func(t *testing.T) { + state, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + ParentRefs: []PartialGatewayParentReference{ + { + Name: ptr.To("primary-gw"), + Namespace: ptr.To("gateway-system"), + SectionName: ptr.To(gatewayv1.SectionName("https")), + }, + }, + }, + }) + require.NoError(t, err) + hr := findHTTPRoute(Render(state)) + require.NotNil(t, hr) + require.Len(t, hr.Spec.ParentRefs, 1) + ref := hr.Spec.ParentRefs[0] + require.Equal(t, gatewayv1.ObjectName("primary-gw"), ref.Name) + require.NotNil(t, ref.Namespace) + require.Equal(t, gatewayv1.Namespace("gateway-system"), *ref.Namespace) + require.NotNil(t, ref.SectionName) + require.Equal(t, gatewayv1.SectionName("https"), *ref.SectionName) + }) + + t.Run("multiple parentRefs", func(t *testing.T) { + state, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("gw-a"), Namespace: ptr.To("ns-a")}, + {Name: ptr.To("gw-b"), Namespace: ptr.To("ns-b"), SectionName: ptr.To(gatewayv1.SectionName("http"))}, + }, + }, + }) + require.NoError(t, err) + hr := findHTTPRoute(Render(state)) + require.NotNil(t, hr) + require.Len(t, hr.Spec.ParentRefs, 2) + require.Equal(t, gatewayv1.ObjectName("gw-a"), hr.Spec.ParentRefs[0].Name) + require.Equal(t, gatewayv1.ObjectName("gw-b"), hr.Spec.ParentRefs[1].Name) + require.Equal(t, gatewayv1.SectionName("http"), *hr.Spec.ParentRefs[1].SectionName) + }) + + t.Run("change parentRefs", func(t *testing.T) { + state1, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + ParentRefs: []PartialGatewayParentReference{{Name: ptr.To("old-gw")}}, + }, + }) + require.NoError(t, err) + hr1 := findHTTPRoute(Render(state1)) + require.Equal(t, gatewayv1.ObjectName("old-gw"), hr1.Spec.ParentRefs[0].Name) + + state2, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("new-gw"), Namespace: ptr.To("new-ns")}, + }, + }, + }) + require.NoError(t, err) + hr2 := findHTTPRoute(Render(state2)) + require.Equal(t, gatewayv1.ObjectName("new-gw"), hr2.Spec.ParentRefs[0].Name) + require.Equal(t, gatewayv1.Namespace("new-ns"), *hr2.Spec.ParentRefs[0].Namespace) + }) + + t.Run("parentRef with only name", func(t *testing.T) { + state, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("simple-gw")}, + }, + }, + }) + require.NoError(t, err) + hr := findHTTPRoute(Render(state)) + require.Len(t, hr.Spec.ParentRefs, 1) + require.Equal(t, gatewayv1.ObjectName("simple-gw"), hr.Spec.ParentRefs[0].Name) + require.Nil(t, hr.Spec.ParentRefs[0].Namespace) + require.Nil(t, hr.Spec.ParentRefs[0].SectionName) + }) + + t.Run("default pathType is PathPrefix", func(t *testing.T) { + state, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + ParentRefs: []PartialGatewayParentReference{{Name: ptr.To("gw")}}, + // PathType not set — should default to PathPrefix + }, + }) + require.NoError(t, err) + hr := findHTTPRoute(Render(state)) + require.NotNil(t, hr) + require.Equal(t, gatewayv1.PathMatchPathPrefix, *hr.Spec.Rules[0].Matches[0].Path.Type) + }) + + t.Run("backend service port from values", func(t *testing.T) { + state, err := NewRenderState("ns", "rel", nil, PartialRenderValues{ + Service: &PartialServiceConfig{ + Port: ptr.To(int32(9090)), + }, + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + ParentRefs: []PartialGatewayParentReference{{Name: ptr.To("gw")}}, + }, + }) + require.NoError(t, err) + hr := findHTTPRoute(Render(state)) + require.NotNil(t, hr) + require.Len(t, hr.Spec.Rules[0].BackendRefs, 1) + require.Equal(t, gatewayv1.PortNumber(9090), *hr.Spec.Rules[0].BackendRefs[0].Port) + }) +} + +// isNonNil returns true if the kube.Object interface holds a non-nil pointer. +func isNonNil(obj kube.Object) bool { + return obj != nil && !reflect.ValueOf(obj).IsNil() +} + +func TestGatewayRemoval(t *testing.T) { + // Simulate the scenario where gateway was previously enabled and is now + // removed from the config. Console should render without errors and + // produce no HTTPRoute. + t.Run("gateway removed from config", func(t *testing.T) { + state, err := NewRenderState("test-namespace", "test-release", nil, PartialRenderValues{ + ConfigMap: &PartialCreatable{ + Create: ptr.To(true), + }, + // No gateway stanza at all - simulates removal + }) + require.NoError(t, err) + + for _, obj := range Render(state) { + if !isNonNil(obj) { + continue + } + _, isHTTPRoute := obj.(*gatewayv1.HTTPRoute) + require.False(t, isHTTPRoute, "HTTPRoute should not be rendered when gateway is not configured") + } + }) + + t.Run("gateway explicitly disabled", func(t *testing.T) { + state, err := NewRenderState("test-namespace", "test-release", nil, PartialRenderValues{ + ConfigMap: &PartialCreatable{ + Create: ptr.To(true), + }, + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(false), + }, + }) + require.NoError(t, err) + + for _, obj := range Render(state) { + if !isNonNil(obj) { + continue + } + _, isHTTPRoute := obj.(*gatewayv1.HTTPRoute) + require.False(t, isHTTPRoute, "HTTPRoute should not be rendered when gateway is disabled") + } + }) + + t.Run("switch from gateway to ingress", func(t *testing.T) { + // First render with gateway + state1, err := NewRenderState("test-namespace", "test-release", nil, PartialRenderValues{ + ConfigMap: &PartialCreatable{Create: ptr.To(true)}, + Gateway: &PartialGatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + ParentRefs: []PartialGatewayParentReference{ + {Name: ptr.To("my-gw")}, + }, + }, + }) + require.NoError(t, err) + + var hasHTTPRoute bool + for _, obj := range Render(state1) { + if !isNonNil(obj) { + continue + } + if _, ok := obj.(*gatewayv1.HTTPRoute); ok { + hasHTTPRoute = true + } + } + require.True(t, hasHTTPRoute, "first render should have HTTPRoute") + + // Now render with ingress instead (gateway removed) + state2, err := NewRenderState("test-namespace", "test-release", nil, PartialRenderValues{ + ConfigMap: &PartialCreatable{Create: ptr.To(true)}, + Ingress: &PartialIngressConfig{ + Enabled: ptr.To(true), + Hosts: []PartialIngressHost{ + { + Host: ptr.To("console.example.com"), + Paths: []PartialIngressPath{{Path: ptr.To("/"), PathType: ptr.To(networkingv1.PathTypePrefix)}}, + }, + }, + }, + }) + require.NoError(t, err) + + var hasIngress bool + hasHTTPRoute = false + for _, obj := range Render(state2) { + if !isNonNil(obj) { + continue + } + if _, ok := obj.(*gatewayv1.HTTPRoute); ok { + hasHTTPRoute = true + } + if _, ok := obj.(*networkingv1.Ingress); ok { + hasIngress = true + } + } + require.False(t, hasHTTPRoute, "second render should not have HTTPRoute") + require.True(t, hasIngress, "second render should have Ingress") + }) +} diff --git a/charts/console/rendervalues.go b/charts/console/rendervalues.go index a789e8444..1a0f24b58 100644 --- a/charts/console/rendervalues.go +++ b/charts/console/rendervalues.go @@ -15,6 +15,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" ) type RenderValues struct { @@ -33,6 +34,7 @@ type RenderValues struct { SecurityContext corev1.SecurityContext `json:"securityContext" partial:"builtin"` Service ServiceConfig `json:"service"` Ingress IngressConfig `json:"ingress"` + Gateway GatewayConfig `json:"gateway"` Resources corev1.ResourceRequirements `json:"resources"` Autoscaling AutoScaling `json:"autoscaling"` NodeSelector map[string]string `json:"nodeSelector"` @@ -103,6 +105,21 @@ type IngressPath struct { PathType *networkingv1.PathType `json:"pathType"` } +type GatewayConfig struct { + Enabled bool `json:"enabled"` + Annotations map[string]string `json:"annotations"` + ParentRefs []GatewayParentReference `json:"parentRefs"` + Hostnames []string `json:"hostnames"` + Path string `json:"path"` + PathType *gatewayv1.PathMatchType `json:"pathType,omitempty"` +} + +type GatewayParentReference struct { + Name string `json:"name"` + Namespace *string `json:"namespace,omitempty"` + SectionName *gatewayv1.SectionName `json:"sectionName,omitempty"` +} + type AutoScaling struct { Enabled bool `json:"enabled"` MinReplicas int32 `json:"minReplicas"` diff --git a/charts/console/rendervalues_partial.gen.go b/charts/console/rendervalues_partial.gen.go index 261cdcfc4..de7dd4571 100644 --- a/charts/console/rendervalues_partial.gen.go +++ b/charts/console/rendervalues_partial.gen.go @@ -19,6 +19,7 @@ import ( corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" applycorev1 "k8s.io/client-go/applyconfigurations/core/v1" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" ) type PartialRenderValues struct { @@ -37,6 +38,7 @@ type PartialRenderValues struct { SecurityContext *applycorev1.SecurityContextApplyConfiguration "json:\"securityContext,omitempty\"" Service *PartialServiceConfig "json:\"service,omitempty\"" Ingress *PartialIngressConfig "json:\"ingress,omitempty\"" + Gateway *PartialGatewayConfig "json:\"gateway,omitempty\"" Resources *corev1.ResourceRequirements "json:\"resources,omitempty\"" Autoscaling *PartialAutoScaling "json:\"autoscaling,omitempty\"" NodeSelector map[string]string "json:\"nodeSelector,omitempty\"" @@ -93,6 +95,15 @@ type PartialIngressConfig struct { TLS []networkingv1.IngressTLS "json:\"tls,omitempty\"" } +type PartialGatewayConfig struct { + Enabled *bool "json:\"enabled,omitempty\"" + Annotations map[string]string "json:\"annotations,omitempty\"" + ParentRefs []PartialGatewayParentReference "json:\"parentRefs,omitempty\"" + Hostnames []string "json:\"hostnames,omitempty\"" + Path *string "json:\"path,omitempty\"" + PathType *gatewayv1.PathMatchType "json:\"pathType,omitempty\"" +} + type PartialAutoScaling struct { Enabled *bool "json:\"enabled,omitempty\"" MinReplicas *int32 "json:\"minReplicas,omitempty\"" @@ -174,6 +185,12 @@ type PartialIngressHost struct { Paths []PartialIngressPath "json:\"paths,omitempty\"" } +type PartialGatewayParentReference struct { + Name *string "json:\"name,omitempty\"" + Namespace *string "json:\"namespace,omitempty\"" + SectionName *gatewayv1.SectionName "json:\"sectionName,omitempty\"" +} + type PartialOIDCLoginSecrets struct { ClientSecret *string "json:\"clientSecret,omitempty\"" } diff --git a/charts/redpanda/chart/templates/_values.go.tpl b/charts/redpanda/chart/templates/_values.go.tpl index ca931acbe..818f2a1a6 100644 --- a/charts/redpanda/chart/templates/_values.go.tpl +++ b/charts/redpanda/chart/templates/_values.go.tpl @@ -508,10 +508,9 @@ {{- $_ := (set $certs $l.rpc.tls.cert true) -}} {{- end -}} {{- range $_, $listener := $listeners -}} -{{- if (not (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $listener.tls $tls)))) "r")) -}} -{{- continue -}} -{{- end -}} +{{- if (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $listener.tls $tls)))) "r") -}} {{- $_ := (set $certs $listener.tls.cert true) -}} +{{- end -}} {{- range $_, $external := $listener.external -}} {{- if (or (not (get (fromJson (include "redpanda.ExternalListener.IsEnabled" (dict "a" (list $external)))) "r")) (not (get (fromJson (include "redpanda.ExternalTLS.IsEnabled" (dict "a" (list $external.tls $listener.tls $tls)))) "r"))) -}} {{- continue -}} @@ -627,9 +626,9 @@ {{- $seen := (dict) -}} {{- $deduped := (coalesce nil) -}} {{- range $_, $item := $items -}} -{{- $_1029___ok_11 := (get (fromJson (include "_shims.dicttest" (dict "a" (list $seen $item.key false)))) "r") -}} -{{- $_ := (index $_1029___ok_11 0) -}} -{{- $ok_11 := (index $_1029___ok_11 1) -}} +{{- $_1027___ok_11 := (get (fromJson (include "_shims.dicttest" (dict "a" (list $seen $item.key false)))) "r") -}} +{{- $_ := (index $_1027___ok_11 0) -}} +{{- $ok_11 := (index $_1027___ok_11 1) -}} {{- if $ok_11 -}} {{- continue -}} {{- end -}} @@ -852,9 +851,9 @@ {{- $name := (index .a 1) -}} {{- range $_ := (list 1) -}} {{- $_is_returning := false -}} -{{- $_1317_cert_ok := (get (fromJson (include "_shims.dicttest" (dict "a" (list $m $name (dict "enabled" (coalesce nil) "caEnabled" false "applyInternalDNSNames" (coalesce nil) "duration" "" "issuerRef" (coalesce nil) "secretRef" (coalesce nil) "clientSecretRef" (coalesce nil)))))) "r") -}} -{{- $cert := (index $_1317_cert_ok 0) -}} -{{- $ok := (index $_1317_cert_ok 1) -}} +{{- $_1315_cert_ok := (get (fromJson (include "_shims.dicttest" (dict "a" (list $m $name (dict "enabled" (coalesce nil) "caEnabled" false "applyInternalDNSNames" (coalesce nil) "duration" "" "issuerRef" (coalesce nil) "secretRef" (coalesce nil) "clientSecretRef" (coalesce nil)))))) "r") -}} +{{- $cert := (index $_1315_cert_ok 0) -}} +{{- $ok := (index $_1315_cert_ok 1) -}} {{- if (not $ok) -}} {{- $_ := (fail (printf "Certificate %q referenced, but not found in the tls.certs map" $name)) -}} {{- end -}} @@ -1333,9 +1332,9 @@ {{- $result := (dict) -}} {{- range $k, $v := $c -}} {{- if (not (empty $v)) -}} -{{- $_1847___ok_15 := (get (fromJson (include "_shims.asnumeric" (dict "a" (list $v)))) "r") -}} -{{- $_ := ((index $_1847___ok_15 0) | float64) -}} -{{- $ok_15 := (index $_1847___ok_15 1) -}} +{{- $_1845___ok_15 := (get (fromJson (include "_shims.asnumeric" (dict "a" (list $v)))) "r") -}} +{{- $_ := ((index $_1845___ok_15 0) | float64) -}} +{{- $ok_15 := (index $_1845___ok_15 1) -}} {{- if $ok_15 -}} {{- $_ := (set $result $k $v) -}} {{- else -}}{{- if (kindIs "bool" $v) -}} @@ -1361,9 +1360,9 @@ {{- $_is_returning := false -}} {{- $result := (dict) -}} {{- range $k, $v := $c -}} -{{- $_1867_b_16_ok_17 := (get (fromJson (include "_shims.typetest" (dict "a" (list "bool" $v false)))) "r") -}} -{{- $b_16 := (index $_1867_b_16_ok_17 0) -}} -{{- $ok_17 := (index $_1867_b_16_ok_17 1) -}} +{{- $_1865_b_16_ok_17 := (get (fromJson (include "_shims.typetest" (dict "a" (list "bool" $v false)))) "r") -}} +{{- $b_16 := (index $_1865_b_16_ok_17 0) -}} +{{- $ok_17 := (index $_1865_b_16_ok_17 1) -}} {{- if $ok_17 -}} {{- $_ := (set $result $k $b_16) -}} {{- continue -}} @@ -1406,15 +1405,15 @@ {{- $config := (index .a 1) -}} {{- range $_ := (list 1) -}} {{- $_is_returning := false -}} -{{- $_1912___hasAccessKey := (get (fromJson (include "_shims.dicttest" (dict "a" (list $config "cloud_storage_access_key" (coalesce nil))))) "r") -}} -{{- $_ := (index $_1912___hasAccessKey 0) -}} -{{- $hasAccessKey := (index $_1912___hasAccessKey 1) -}} -{{- $_1913___hasSecretKey := (get (fromJson (include "_shims.dicttest" (dict "a" (list $config "cloud_storage_secret_key" (coalesce nil))))) "r") -}} -{{- $_ := (index $_1913___hasSecretKey 0) -}} -{{- $hasSecretKey := (index $_1913___hasSecretKey 1) -}} -{{- $_1914___hasSharedKey := (get (fromJson (include "_shims.dicttest" (dict "a" (list $config "cloud_storage_azure_shared_key" (coalesce nil))))) "r") -}} -{{- $_ := (index $_1914___hasSharedKey 0) -}} -{{- $hasSharedKey := (index $_1914___hasSharedKey 1) -}} +{{- $_1910___hasAccessKey := (get (fromJson (include "_shims.dicttest" (dict "a" (list $config "cloud_storage_access_key" (coalesce nil))))) "r") -}} +{{- $_ := (index $_1910___hasAccessKey 0) -}} +{{- $hasAccessKey := (index $_1910___hasAccessKey 1) -}} +{{- $_1911___hasSecretKey := (get (fromJson (include "_shims.dicttest" (dict "a" (list $config "cloud_storage_secret_key" (coalesce nil))))) "r") -}} +{{- $_ := (index $_1911___hasSecretKey 0) -}} +{{- $hasSecretKey := (index $_1911___hasSecretKey 1) -}} +{{- $_1912___hasSharedKey := (get (fromJson (include "_shims.dicttest" (dict "a" (list $config "cloud_storage_azure_shared_key" (coalesce nil))))) "r") -}} +{{- $_ := (index $_1912___hasSharedKey 0) -}} +{{- $hasSharedKey := (index $_1912___hasSharedKey 1) -}} {{- $envvars := (coalesce nil) -}} {{- if (and (not $hasAccessKey) (get (fromJson (include "redpanda.SecretRef.IsValid" (dict "a" (list $tsc.accessKey)))) "r")) -}} {{- $envvars = (concat (default (list) $envvars) (list (mustMergeOverwrite (dict "name" "") (dict "name" "REDPANDA_CLOUD_STORAGE_ACCESS_KEY" "valueFrom" (get (fromJson (include "redpanda.SecretRef.AsSource" (dict "a" (list $tsc.accessKey)))) "r"))))) -}} @@ -1437,12 +1436,12 @@ {{- $c := (index .a 0) -}} {{- range $_ := (list 1) -}} {{- $_is_returning := false -}} -{{- $_1950___containerExists := (get (fromJson (include "_shims.dicttest" (dict "a" (list $c "cloud_storage_azure_container" (coalesce nil))))) "r") -}} -{{- $_ := (index $_1950___containerExists 0) -}} -{{- $containerExists := (index $_1950___containerExists 1) -}} -{{- $_1951___accountExists := (get (fromJson (include "_shims.dicttest" (dict "a" (list $c "cloud_storage_azure_storage_account" (coalesce nil))))) "r") -}} -{{- $_ := (index $_1951___accountExists 0) -}} -{{- $accountExists := (index $_1951___accountExists 1) -}} +{{- $_1948___containerExists := (get (fromJson (include "_shims.dicttest" (dict "a" (list $c "cloud_storage_azure_container" (coalesce nil))))) "r") -}} +{{- $_ := (index $_1948___containerExists 0) -}} +{{- $containerExists := (index $_1948___containerExists 1) -}} +{{- $_1949___accountExists := (get (fromJson (include "_shims.dicttest" (dict "a" (list $c "cloud_storage_azure_storage_account" (coalesce nil))))) "r") -}} +{{- $_ := (index $_1949___accountExists 0) -}} +{{- $accountExists := (index $_1949___accountExists 1) -}} {{- $_is_returning = true -}} {{- (dict "r" (and $containerExists $accountExists)) | toJson -}} {{- break -}} @@ -1453,9 +1452,9 @@ {{- $c := (index .a 0) -}} {{- range $_ := (list 1) -}} {{- $_is_returning := false -}} -{{- $_1956_value_ok := (get (fromJson (include "_shims.dicttest" (dict "a" (list $c `cloud_storage_cache_size` (coalesce nil))))) "r") -}} -{{- $value := (index $_1956_value_ok 0) -}} -{{- $ok := (index $_1956_value_ok 1) -}} +{{- $_1954_value_ok := (get (fromJson (include "_shims.dicttest" (dict "a" (list $c `cloud_storage_cache_size` (coalesce nil))))) "r") -}} +{{- $value := (index $_1954_value_ok 0) -}} +{{- $ok := (index $_1954_value_ok 1) -}} {{- if (not $ok) -}} {{- $_is_returning = true -}} {{- (dict "r" (coalesce nil)) | toJson -}} diff --git a/charts/redpanda/chart/values.schema.json b/charts/redpanda/chart/values.schema.json index 64e0b0ce1..382c76af0 100644 --- a/charts/redpanda/chart/values.schema.json +++ b/charts/redpanda/chart/values.schema.json @@ -3391,6 +3391,65 @@ "fullnameOverride": { "type": "string" }, + "gateway": { + "additionalProperties": false, + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "hostnames": { + "oneOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "parentRefs": { + "oneOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "sectionName": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "path": { + "type": "string" + }, + "pathType": { + "type": "string" + } + }, + "type": "object" + }, "global": { "type": "object" }, diff --git a/charts/redpanda/go.mod b/charts/redpanda/go.mod index 002340f8b..44c116b50 100644 --- a/charts/redpanda/go.mod +++ b/charts/redpanda/go.mod @@ -285,7 +285,7 @@ require ( k8s.io/kubectl v0.35.1 // indirect oras.land/oras-go/v2 v2.6.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect - sigs.k8s.io/gateway-api v1.4.1 // indirect + sigs.k8s.io/gateway-api v1.5.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect diff --git a/charts/redpanda/go.sum b/charts/redpanda/go.sum index c315c2ad2..577733e76 100644 --- a/charts/redpanda/go.sum +++ b/charts/redpanda/go.sum @@ -303,8 +303,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLxCY3f87278uWfIDhJnbdvDjvmE= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -491,10 +491,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 h1:H55sU3giNgBkIvmAo0vI/AAFwVTwfWsf6MN3+9H6U8o= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98/go.mod h1:RqnyioA3pIEZMkSbOIcrw32YSgETfn/VrLuEikEdPNU= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -870,8 +870,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= -sigs.k8s.io/gateway-api v1.4.1 h1:NPxFutNkKNa8UfLd2CMlEuhIPMQgDQ6DXNKG9sHbJU8= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0= +sigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= diff --git a/charts/redpanda/testdata/template-cases.golden.txtar b/charts/redpanda/testdata/template-cases.golden.txtar index bfb3bf315..ab42abc87 100644 --- a/charts/redpanda/testdata/template-cases.golden.txtar +++ b/charts/redpanda/testdata/template-cases.golden.txtar @@ -9092,6 +9092,8 @@ spec: initialDelaySeconds: 1 periodSeconds: 10 volumeMounts: + - mountPath: /etc/tls/certs/cert2 + name: redpanda-cert2-cert - mountPath: /etc/tls/certs/default name: redpanda-default-cert - mountPath: /etc/tls/certs/external @@ -9150,6 +9152,8 @@ spec: timeoutSeconds: 0 resources: {} volumeMounts: + - mountPath: /etc/tls/certs/cert2 + name: redpanda-cert2-cert - mountPath: /etc/tls/certs/default name: redpanda-default-cert - mountPath: /etc/tls/certs/external @@ -9178,6 +9182,8 @@ spec: runAsNonRoot: false runAsUser: 0 volumeMounts: + - mountPath: /etc/tls/certs/cert2 + name: redpanda-cert2-cert - mountPath: /etc/tls/certs/default name: redpanda-default-cert - mountPath: /etc/tls/certs/external @@ -9212,6 +9218,8 @@ spec: name: redpanda-configurator resources: {} volumeMounts: + - mountPath: /etc/tls/certs/cert2 + name: redpanda-cert2-cert - mountPath: /etc/tls/certs/default name: redpanda-default-cert - mountPath: /etc/tls/certs/external @@ -9267,6 +9275,10 @@ spec: topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: ScheduleAnyway volumes: + - name: redpanda-cert2-cert + secret: + defaultMode: 288 + secretName: redpanda-cert2-cert - name: redpanda-default-cert secret: defaultMode: 288 @@ -9330,6 +9342,31 @@ spec: # Source: redpanda/templates/entry-point.yaml apiVersion: cert-manager.io/v1 kind: Certificate +metadata: + labels: + app.kubernetes.io/component: redpanda + app.kubernetes.io/instance: redpanda + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: redpanda + helm.sh/chart: redpanda-25.3.1 + name: redpanda-cert2-root-certificate + namespace: default +spec: + commonName: redpanda-cert2-root-certificate + duration: 43800h0m0s + isCA: true + issuerRef: + group: cert-manager.io + kind: Issuer + name: redpanda-cert2-selfsigned-issuer + privateKey: + algorithm: ECDSA + size: 256 + secretName: redpanda-cert2-root-certificate +--- +# Source: redpanda/templates/entry-point.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate metadata: labels: app.kubernetes.io/component: redpanda @@ -9380,6 +9417,43 @@ spec: # Source: redpanda/templates/entry-point.yaml apiVersion: cert-manager.io/v1 kind: Certificate +metadata: + labels: + app.kubernetes.io/component: redpanda + app.kubernetes.io/instance: redpanda + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: redpanda + helm.sh/chart: redpanda-25.3.1 + name: redpanda-cert2-cert + namespace: default +spec: + dnsNames: + - redpanda-cluster.redpanda.default.svc.cluster.local + - redpanda-cluster.redpanda.default.svc + - redpanda-cluster.redpanda.default + - '*.redpanda-cluster.redpanda.default.svc.cluster.local' + - '*.redpanda-cluster.redpanda.default.svc' + - '*.redpanda-cluster.redpanda.default' + - redpanda.default.svc.cluster.local + - redpanda.default.svc + - redpanda.default + - '*.redpanda.default.svc.cluster.local' + - '*.redpanda.default.svc' + - '*.redpanda.default' + duration: 43800h0m0s + isCA: false + issuerRef: + group: cert-manager.io + kind: Issuer + name: redpanda-cert2-root-issuer + privateKey: + algorithm: ECDSA + size: 256 + secretName: redpanda-cert2-cert +--- +# Source: redpanda/templates/entry-point.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate metadata: labels: app.kubernetes.io/component: redpanda @@ -9454,6 +9528,37 @@ spec: # Source: redpanda/templates/entry-point.yaml apiVersion: cert-manager.io/v1 kind: Issuer +metadata: + labels: + app.kubernetes.io/component: redpanda + app.kubernetes.io/instance: redpanda + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: redpanda + helm.sh/chart: redpanda-25.3.1 + name: redpanda-cert2-selfsigned-issuer + namespace: default +spec: + selfSigned: {} +--- +# Source: redpanda/templates/entry-point.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/component: redpanda + app.kubernetes.io/instance: redpanda + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: redpanda + helm.sh/chart: redpanda-25.3.1 + name: redpanda-cert2-root-issuer + namespace: default +spec: + ca: + secretName: redpanda-cert2-root-certificate +--- +# Source: redpanda/templates/entry-point.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer metadata: labels: app.kubernetes.io/component: redpanda @@ -9556,6 +9661,8 @@ spec: resources: {} securityContext: {} volumeMounts: + - mountPath: /etc/tls/certs/cert2 + name: redpanda-cert2-cert - mountPath: /etc/tls/certs/default name: redpanda-default-cert - mountPath: /etc/tls/certs/external @@ -9601,6 +9708,10 @@ spec: serviceAccountName: redpanda tolerations: [] volumes: + - name: redpanda-cert2-cert + secret: + defaultMode: 288 + secretName: redpanda-cert2-cert - name: redpanda-default-cert secret: defaultMode: 288 diff --git a/charts/redpanda/values.go b/charts/redpanda/values.go index 019705eb5..56346efc7 100644 --- a/charts/redpanda/values.go +++ b/charts/redpanda/values.go @@ -904,12 +904,10 @@ func (l *Listeners) InUseServerCerts(tls *TLS) []string { } for _, listener := range listeners { - if !listener.TLS.IsEnabled(tls) { - continue + if listener.TLS.IsEnabled(tls) { + certs[listener.TLS.Cert] = true } - certs[listener.TLS.Cert] = true - for _, external := range helmette.SortedMap(listener.External) { if !external.IsEnabled() || !external.TLS.IsEnabled(&listener.TLS, tls) { continue diff --git a/gen/go.mod b/gen/go.mod index 77f975938..1860dba6a 100644 --- a/gen/go.mod +++ b/gen/go.mod @@ -300,7 +300,7 @@ require ( oras.land/oras-go/v2 v2.6.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect sigs.k8s.io/controller-runtime v0.23.1 // indirect - sigs.k8s.io/gateway-api v1.4.1 // indirect + sigs.k8s.io/gateway-api v1.5.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect diff --git a/gen/go.sum b/gen/go.sum index b40f0f8fa..a7df5e6ee 100644 --- a/gen/go.sum +++ b/gen/go.sum @@ -329,8 +329,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLxCY3f87278uWfIDhJnbdvDjvmE= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -531,10 +531,10 @@ github.com/oleiade/reflections v1.1.0 h1:D+I/UsXQB4esMathlt0kkZRJZdUDmhv5zGi/HOw github.com/oleiade/reflections v1.1.0/go.mod h1:mCxx0QseeVCHs5Um5HhJeCKVC7AwS8kO67tky4rdisA= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 h1:H55sU3giNgBkIvmAo0vI/AAFwVTwfWsf6MN3+9H6U8o= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98/go.mod h1:RqnyioA3pIEZMkSbOIcrw32YSgETfn/VrLuEikEdPNU= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -926,8 +926,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= -sigs.k8s.io/gateway-api v1.4.1 h1:NPxFutNkKNa8UfLd2CMlEuhIPMQgDQ6DXNKG9sHbJU8= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0= +sigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= diff --git a/go.work.sum b/go.work.sum index 954371e08..da7469c5b 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1754,6 +1754,7 @@ github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL9 github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= @@ -1763,6 +1764,7 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= @@ -3498,6 +3500,7 @@ golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -4103,6 +4106,7 @@ k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20260108192941-914a6e750570/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= oras.land/oras-go v1.2.0/go.mod h1:pFNs7oHp2dYsYMSS82HaX5l4mpnGO7hbpPN6EWH2ltc= oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= diff --git a/gotohelm/go.mod b/gotohelm/go.mod index 5a29b747d..a919fe7b5 100644 --- a/gotohelm/go.mod +++ b/gotohelm/go.mod @@ -140,6 +140,8 @@ require ( github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/onsi/ginkgo/v2 v2.28.0 // indirect + github.com/onsi/gomega v1.39.1 // indirect github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect @@ -218,6 +220,7 @@ require ( k8s.io/kubectl v0.35.1 // indirect oras.land/oras-go/v2 v2.6.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect + sigs.k8s.io/gateway-api v1.5.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect diff --git a/gotohelm/go.sum b/gotohelm/go.sum index ff5b673d1..15c558186 100644 --- a/gotohelm/go.sum +++ b/gotohelm/go.sum @@ -215,8 +215,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLxCY3f87278uWfIDhJnbdvDjvmE= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= @@ -352,10 +352,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 h1:H55sU3giNgBkIvmAo0vI/AAFwVTwfWsf6MN3+9H6U8o= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98/go.mod h1:RqnyioA3pIEZMkSbOIcrw32YSgETfn/VrLuEikEdPNU= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -694,8 +694,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= -sigs.k8s.io/gateway-api v1.4.1 h1:NPxFutNkKNa8UfLd2CMlEuhIPMQgDQ6DXNKG9sHbJU8= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0= +sigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= diff --git a/gotohelm/testdata/src/example/go.mod b/gotohelm/testdata/src/example/go.mod index ae274a8a3..0817d05b6 100644 --- a/gotohelm/testdata/src/example/go.mod +++ b/gotohelm/testdata/src/example/go.mod @@ -61,6 +61,7 @@ require ( github.com/google/cel-go v0.27.0 // indirect github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect + github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect diff --git a/gotohelm/testdata/src/example/go.sum b/gotohelm/testdata/src/example/go.sum index 325277b92..e1a8a4c16 100644 --- a/gotohelm/testdata/src/example/go.sum +++ b/gotohelm/testdata/src/example/go.sum @@ -160,8 +160,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLxCY3f87278uWfIDhJnbdvDjvmE= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= @@ -236,10 +236,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 h1:H55sU3giNgBkIvmAo0vI/AAFwVTwfWsf6MN3+9H6U8o= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98/go.mod h1:RqnyioA3pIEZMkSbOIcrw32YSgETfn/VrLuEikEdPNU= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -459,8 +459,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= -sigs.k8s.io/gateway-api v1.4.1 h1:NPxFutNkKNa8UfLd2CMlEuhIPMQgDQ6DXNKG9sHbJU8= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0= +sigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= diff --git a/harpoon/go.mod b/harpoon/go.mod index 1b3e781ab..e1ba40352 100644 --- a/harpoon/go.mod +++ b/harpoon/go.mod @@ -88,6 +88,7 @@ require ( github.com/google/cel-go v0.27.0 // indirect github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect + github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/gosuri/uitable v0.0.4 // indirect diff --git a/harpoon/go.sum b/harpoon/go.sum index 86a8ce533..31cb04739 100644 --- a/harpoon/go.sum +++ b/harpoon/go.sum @@ -221,8 +221,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLxCY3f87278uWfIDhJnbdvDjvmE= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= @@ -367,10 +367,10 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 h1:H55sU3giNgBkIvmAo0vI/AAFwVTwfWsf6MN3+9H6U8o= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98/go.mod h1:RqnyioA3pIEZMkSbOIcrw32YSgETfn/VrLuEikEdPNU= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -715,8 +715,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= -sigs.k8s.io/gateway-api v1.4.1 h1:NPxFutNkKNa8UfLd2CMlEuhIPMQgDQ6DXNKG9sHbJU8= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0= +sigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= diff --git a/licenses/third_party.md b/licenses/third_party.md index 2774cfcf0..b5f385971 100644 --- a/licenses/third_party.md +++ b/licenses/third_party.md @@ -191,7 +191,7 @@ run `task generate:third-party-licenses-list` | github.com/monochromegane/go-gitignore | [MIT](https://github.com/monochromegane/go-gitignore/blob/205db1a8cc00/LICENSE) | | github.com/munnerz/goautoneg | [BSD-3-Clause](https://github.com/munnerz/goautoneg/blob/a7dc8b61c822/LICENSE) | | github.com/mxk/go-flowrate/flowrate | [BSD-3-Clause](https://github.com/mxk/go-flowrate/blob/cca7078d478f/LICENSE) | -| github.com/onsi/gomega | [MIT](https://github.com/onsi/gomega/blob/v1.38.2/LICENSE) | +| github.com/onsi/gomega | [MIT](https://github.com/onsi/gomega/blob/v1.39.1/LICENSE) | | github.com/opencontainers/go-digest | [Apache-2.0](https://github.com/opencontainers/go-digest/blob/d50d2fec9c98/LICENSE) | | github.com/opencontainers/image-spec/specs-go | [Apache-2.0](https://github.com/opencontainers/image-spec/blob/v1.1.1/LICENSE) | | github.com/peterbourgon/diskv | [MIT](https://github.com/peterbourgon/diskv/blob/v2.0.1/LICENSE) | @@ -317,7 +317,7 @@ run `task generate:third-party-licenses-list` | pgregory.net/rapid | [MPL-2.0](https://github.com/chrisseto/rapid/blob/cdeef406c65c/LICENSE) | | sigs.k8s.io/apiserver-network-proxy/konnectivity-client | [Apache-2.0](https://github.com/kubernetes-sigs/apiserver-network-proxy/blob/konnectivity-client/v0.34.0/konnectivity-client/LICENSE) | | sigs.k8s.io/controller-runtime | [Apache-2.0](https://github.com/kubernetes-sigs/controller-runtime/blob/v0.23.1/LICENSE) | -| sigs.k8s.io/gateway-api/apis/v1 | [Apache-2.0](https://github.com/kubernetes-sigs/gateway-api/blob/v1.4.1/LICENSE) | +| sigs.k8s.io/gateway-api/apis/v1 | [Apache-2.0](https://github.com/kubernetes-sigs/gateway-api/blob/v1.5.1/LICENSE) | | sigs.k8s.io/json | [Apache-2.0](https://github.com/kubernetes-sigs/json/blob/2d320260d730/LICENSE) | | sigs.k8s.io/json | [BSD-3-Clause](https://github.com/kubernetes-sigs/json/blob/2d320260d730/LICENSE) | | sigs.k8s.io/kustomize/api | [Apache-2.0](https://github.com/kubernetes-sigs/kustomize/blob/api/v0.20.1/api/LICENSE) | diff --git a/operator/api/redpanda/v1alpha2/console_types.go b/operator/api/redpanda/v1alpha2/console_types.go index 0f1c328ff..2239d2edc 100644 --- a/operator/api/redpanda/v1alpha2/console_types.go +++ b/operator/api/redpanda/v1alpha2/console_types.go @@ -20,6 +20,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" applycorev1 "k8s.io/client-go/applyconfigurations/core/v1" "k8s.io/utils/ptr" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" "github.com/redpanda-data/redpanda-operator/charts/console/v3" "github.com/redpanda-data/redpanda-operator/operator/pkg/functional" @@ -108,6 +109,7 @@ type ConsoleValues struct { SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"` Service *ServiceConfig `json:"service,omitempty"` Ingress *IngressConfig `json:"ingress,omitempty"` + Gateway *GatewayConfig `json:"gateway,omitempty"` Resources *corev1.ResourceRequirements `json:"resources,omitempty"` Autoscaling *AutoScaling `json:"autoscaling,omitempty"` NodeSelector map[string]string `json:"nodeSelector,omitempty"` @@ -195,6 +197,23 @@ type IngressPath struct { PathType *networkingv1.PathType `json:"pathType,omitempty"` } +// GatewayConfig configures a Gateway API HTTPRoute for Console. +type GatewayConfig struct { + Enabled *bool `json:"enabled,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + ParentRefs []GatewayParentReference `json:"parentRefs,omitempty"` + Hostnames []string `json:"hostnames,omitempty"` + Path *string `json:"path,omitempty"` + PathType *gatewayv1.PathMatchType `json:"pathType,omitempty"` +} + +// GatewayParentReference identifies a parent Gateway for the HTTPRoute. +type GatewayParentReference struct { + Name string `json:"name"` + Namespace *string `json:"namespace,omitempty"` + SectionName *gatewayv1.SectionName `json:"sectionName,omitempty"` +} + type SecretMount struct { Name string `json:"name,omitempty"` SecretName string `json:"secretName,omitempty"` diff --git a/operator/api/redpanda/v1alpha2/conversion.go b/operator/api/redpanda/v1alpha2/conversion.go index ab64c9b0c..cfa892684 100644 --- a/operator/api/redpanda/v1alpha2/conversion.go +++ b/operator/api/redpanda/v1alpha2/conversion.go @@ -279,6 +279,7 @@ var ( conv_runtime_RawExtension_To_ServiceAccountConfig = convertRuntimeRawExtension[*ServiceAccountConfig] conv_runtime_RawExtension_To_Service = convertRuntimeRawExtension[*ServiceConfig] conv_runtime_RawExtension_To_Ingress = convertRuntimeRawExtension[*IngressConfig] + conv_runtime_RawExtension_To_Gateway = convertRuntimeRawExtension[*GatewayConfig] conv_runtime_RawExtension_To_Autoscaling = convertRuntimeRawExtension[*AutoScaling] conv_runtime_RawExtension_To_SecretMounts = convertRuntimeRawExtension[SecretMount] conv_runtime_RawExtension_To_Secret = convertRuntimeRawExtension[SecretConfig] diff --git a/operator/api/redpanda/v1alpha2/redpanda_clusterspec_types.go b/operator/api/redpanda/v1alpha2/redpanda_clusterspec_types.go index 150338b8a..6ff3c5f60 100644 --- a/operator/api/redpanda/v1alpha2/redpanda_clusterspec_types.go +++ b/operator/api/redpanda/v1alpha2/redpanda_clusterspec_types.go @@ -238,6 +238,9 @@ type RedpandaConsole struct { // Configures the Kubernetes Ingress resource for Redpanda Console. Ingress *runtime.RawExtension `json:"ingress,omitempty"` // +kubebuilder:pruning:PreserveUnknownFields + // Configures a Gateway API HTTPRoute for Redpanda Console. + Gateway *runtime.RawExtension `json:"gateway,omitempty"` + // +kubebuilder:pruning:PreserveUnknownFields // Configures resource requests and limits for the Pods that run Redpanda Console. Resources *runtime.RawExtension `json:"resources,omitempty"` // +kubebuilder:pruning:PreserveUnknownFields diff --git a/operator/api/redpanda/v1alpha2/testdata/crd-docs.adoc b/operator/api/redpanda/v1alpha2/testdata/crd-docs.adoc index 11a137345..f3bfab008 100644 --- a/operator/api/redpanda/v1alpha2/testdata/crd-docs.adoc +++ b/operator/api/redpanda/v1alpha2/testdata/crd-docs.adoc @@ -967,6 +967,7 @@ ConsoleCreateObj represents configuration options for creating Kubernetes object | *`securityContext`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#securitycontext-v1-core[$$SecurityContext$$]__ | | | | *`service`* __xref:{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-serviceconfig[$$ServiceConfig$$]__ | | | | *`ingress`* __xref:{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-ingressconfig[$$IngressConfig$$]__ | | | +| *`gateway`* __xref:{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-gatewayconfig[$$GatewayConfig$$]__ | | | | *`resources`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#resourcerequirements-v1-core[$$ResourceRequirements$$]__ | | | | *`autoscaling`* __xref:{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-autoscaling[$$AutoScaling$$]__ | | | | *`nodeSelector`* __object (keys:string, values:string)__ | | | @@ -1316,6 +1317,55 @@ FilterType specifies the type, either include or exclude of a consumer group fil |=== +[id="{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-gatewayconfig"] +==== GatewayConfig + + + +GatewayConfig configures a Gateway API HTTPRoute for Console. + + + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-consolespec[$$ConsoleSpec$$] +**** + +[cols="20a,50a,15a,15a", options="header"] +|=== +| Field | Description | Default | Validation +| *`enabled`* __boolean__ | | | +| *`annotations`* __object (keys:string, values:string)__ | | | +| *`parentRefs`* __xref:{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-gatewayparentreference[$$GatewayParentReference$$] array__ | | | +| *`hostnames`* __string array__ | | | +| *`path`* __string__ | | | +| *`pathType`* __xref:{anchor_prefix}-sigs-k8s-io-gateway-api-apis-v1-pathmatchtype[$$PathMatchType$$]__ | | | +|=== + + +[id="{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-gatewayparentreference"] +==== GatewayParentReference + + + +GatewayParentReference identifies a parent Gateway for the HTTPRoute. + + + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-gatewayconfig[$$GatewayConfig$$] +**** + +[cols="20a,50a,15a,15a", options="header"] +|=== +| Field | Description | Default | Validation +| *`name`* __string__ | | | +| *`namespace`* __string__ | | | +| *`sectionName`* __xref:{anchor_prefix}-sigs-k8s-io-gateway-api-apis-v1-sectionname[$$SectionName$$]__ | | | +|=== + + [id="{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-group"] ==== Group @@ -2749,6 +2799,7 @@ see the Helm values for the Redpanda Console chart: https://artifacthub.io/packa | *`securityContext`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#rawextension-runtime-pkg[$$RawExtension$$]__ | Sets the security context for the Pods that run Redpanda Console. + | | | *`service`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#rawextension-runtime-pkg[$$RawExtension$$]__ | Configures the Kubernetes Service for Redpanda Console. + | | | *`ingress`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#rawextension-runtime-pkg[$$RawExtension$$]__ | Configures the Kubernetes Ingress resource for Redpanda Console. + | | +| *`gateway`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#rawextension-runtime-pkg[$$RawExtension$$]__ | Configures a Gateway API HTTPRoute for Redpanda Console. + | | | *`resources`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#rawextension-runtime-pkg[$$RawExtension$$]__ | Configures resource requests and limits for the Pods that run Redpanda Console. + | | | *`autoscaling`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#rawextension-runtime-pkg[$$RawExtension$$]__ | Configures Horizontal Pod Autoscaling (HPA) for Redpanda Console. + | | | *`nodeSelector`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#rawextension-runtime-pkg[$$RawExtension$$]__ | Specifies Node labels for Pod assignment. + | | diff --git a/operator/api/redpanda/v1alpha2/zz_generated.conversion.go b/operator/api/redpanda/v1alpha2/zz_generated.conversion.go index b4d424898..e3de4f804 100644 --- a/operator/api/redpanda/v1alpha2/zz_generated.conversion.go +++ b/operator/api/redpanda/v1alpha2/zz_generated.conversion.go @@ -4,15 +4,16 @@ package v1alpha2 import ( - v15 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + v16 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" v3 "github.com/redpanda-data/redpanda-operator/charts/console/v3" ir "github.com/redpanda-data/redpanda-operator/pkg/ir" v12 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" - v14 "k8s.io/api/networking/v1" + v15 "k8s.io/api/networking/v1" v13 "k8s.io/apimachinery/pkg/apis/meta/v1" intstr "k8s.io/apimachinery/pkg/util/intstr" v11 "k8s.io/client-go/applyconfigurations/core/v1" + v14 "sigs.k8s.io/gateway-api/apis/v1" ) func init() { @@ -80,6 +81,7 @@ func init() { consolePartialRenderValues.SecurityContext = pV1SecurityContextToPV1SecurityContextApplyConfiguration((*source).SecurityContext) consolePartialRenderValues.Service = pV1alpha2ServiceConfigToPConsolePartialServiceConfig((*source).Service) consolePartialRenderValues.Ingress = pV1alpha2IngressConfigToPConsolePartialIngressConfig((*source).Ingress) + consolePartialRenderValues.Gateway = pV1alpha2GatewayConfigToPConsolePartialGatewayConfig((*source).Gateway) consolePartialRenderValues.Resources = pV1ResourceRequirementsToPV1ResourceRequirements((*source).Resources) consolePartialRenderValues.Autoscaling = pV1alpha2AutoScalingToPConsolePartialAutoScaling((*source).Autoscaling) if (*source).NodeSelector != nil { @@ -307,6 +309,11 @@ func init() { return nil, err } v1alpha2ConsoleValues.Ingress = pV1alpha2IngressConfig + pV1alpha2GatewayConfig, err := conv_runtime_RawExtension_To_Gateway((*source).Gateway) + if err != nil { + return nil, err + } + v1alpha2ConsoleValues.Gateway = pV1alpha2GatewayConfig pV1ResourceRequirements, err := conv_runtime_RawExtension_To_corev1_Resources((*source).Resources) if err != nil { return nil, err @@ -1154,6 +1161,44 @@ func pV1alpha2ExternalSecretKeySelectorToPIrExternalSecretKeySelector(source *Ex } return pIrExternalSecretKeySelector } +func pV1alpha2GatewayConfigToPConsolePartialGatewayConfig(source *GatewayConfig) *v3.PartialGatewayConfig { + var pConsolePartialGatewayConfig *v3.PartialGatewayConfig + if source != nil { + var consolePartialGatewayConfig v3.PartialGatewayConfig + if (*source).Enabled != nil { + xbool := *(*source).Enabled + consolePartialGatewayConfig.Enabled = &xbool + } + if (*source).Annotations != nil { + consolePartialGatewayConfig.Annotations = make(map[string]string, len((*source).Annotations)) + for key, value := range (*source).Annotations { + consolePartialGatewayConfig.Annotations[key] = value + } + } + if (*source).ParentRefs != nil { + consolePartialGatewayConfig.ParentRefs = make([]v3.PartialGatewayParentReference, len((*source).ParentRefs)) + for i := 0; i < len((*source).ParentRefs); i++ { + consolePartialGatewayConfig.ParentRefs[i] = v1alpha2GatewayParentReferenceToConsolePartialGatewayParentReference((*source).ParentRefs[i]) + } + } + if (*source).Hostnames != nil { + consolePartialGatewayConfig.Hostnames = make([]string, len((*source).Hostnames)) + for j := 0; j < len((*source).Hostnames); j++ { + consolePartialGatewayConfig.Hostnames[j] = (*source).Hostnames[j] + } + } + if (*source).Path != nil { + xstring := *(*source).Path + consolePartialGatewayConfig.Path = &xstring + } + if (*source).PathType != nil { + v1PathMatchType := v14.PathMatchType(*(*source).PathType) + consolePartialGatewayConfig.PathType = &v1PathMatchType + } + pConsolePartialGatewayConfig = &consolePartialGatewayConfig + } + return pConsolePartialGatewayConfig +} func pV1alpha2ImageToPConsolePartialImage(source *Image) *v3.PartialImage { var pConsolePartialImage *v3.PartialImage if source != nil { @@ -1203,7 +1248,7 @@ func pV1alpha2IngressConfigToPConsolePartialIngressConfig(source *IngressConfig) } } if (*source).TLS != nil { - consolePartialIngressConfig.TLS = make([]v14.IngressTLS, len((*source).TLS)) + consolePartialIngressConfig.TLS = make([]v15.IngressTLS, len((*source).TLS)) for j := 0; j < len((*source).TLS); j++ { consolePartialIngressConfig.TLS[j] = v1IngressTLSToV1IngressTLS((*source).TLS[j]) } @@ -1253,7 +1298,7 @@ func pV1alpha2MonitoringConfigToPConsolePartialMonitoringConfig(source *Monitori consolePartialMonitoringConfig.Enabled = &xbool } if (*source).ScrapeInterval != nil { - v1Duration := v15.Duration(*(*source).ScrapeInterval) + v1Duration := v16.Duration(*(*source).ScrapeInterval) consolePartialMonitoringConfig.ScrapeInterval = &v1Duration } if (*source).Labels != nil { @@ -1520,8 +1565,8 @@ func v1HTTPHeaderToV1HTTPHeader(source v1.HTTPHeader) v1.HTTPHeader { v1HTTPHeader.Value = source.Value return v1HTTPHeader } -func v1IngressTLSToV1IngressTLS(source v14.IngressTLS) v14.IngressTLS { - var v1IngressTLS v14.IngressTLS +func v1IngressTLSToV1IngressTLS(source v15.IngressTLS) v15.IngressTLS { + var v1IngressTLS v15.IngressTLS if source.Hosts != nil { v1IngressTLS.Hosts = make([]string, len(source.Hosts)) for i := 0; i < len(source.Hosts); i++ { @@ -1696,6 +1741,20 @@ func v1WeightedPodAffinityTermToV1WeightedPodAffinityTerm(source v1.WeightedPodA v1WeightedPodAffinityTerm.PodAffinityTerm = v1PodAffinityTermToV1PodAffinityTerm(source.PodAffinityTerm) return v1WeightedPodAffinityTerm } +func v1alpha2GatewayParentReferenceToConsolePartialGatewayParentReference(source GatewayParentReference) v3.PartialGatewayParentReference { + var consolePartialGatewayParentReference v3.PartialGatewayParentReference + pString := source.Name + consolePartialGatewayParentReference.Name = &pString + if source.Namespace != nil { + xstring := *source.Namespace + consolePartialGatewayParentReference.Namespace = &xstring + } + if source.SectionName != nil { + v1SectionName := v14.SectionName(*source.SectionName) + consolePartialGatewayParentReference.SectionName = &v1SectionName + } + return consolePartialGatewayParentReference +} func v1alpha2IngressHostToConsolePartialIngressHost(source IngressHost) v3.PartialIngressHost { var consolePartialIngressHost v3.PartialIngressHost pString := source.Host @@ -1713,7 +1772,7 @@ func v1alpha2IngressPathToConsolePartialIngressPath(source IngressPath) v3.Parti pString := source.Path consolePartialIngressPath.Path = &pString if source.PathType != nil { - v1PathType := v14.PathType(*source.PathType) + v1PathType := v15.PathType(*source.PathType) consolePartialIngressPath.PathType = &v1PathType } return consolePartialIngressPath diff --git a/operator/api/redpanda/v1alpha2/zz_generated.deepcopy.go b/operator/api/redpanda/v1alpha2/zz_generated.deepcopy.go index 20f88b122..9da2267f3 100644 --- a/operator/api/redpanda/v1alpha2/zz_generated.deepcopy.go +++ b/operator/api/redpanda/v1alpha2/zz_generated.deepcopy.go @@ -22,6 +22,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + apisv1 "sigs.k8s.io/gateway-api/apis/v1" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -1098,6 +1099,11 @@ func (in *ConsoleValues) DeepCopyInto(out *ConsoleValues) { *out = new(IngressConfig) (*in).DeepCopyInto(*out) } + if in.Gateway != nil { + in, out := &in.Gateway, &out.Gateway + *out = new(GatewayConfig) + (*in).DeepCopyInto(*out) + } if in.Resources != nil { in, out := &in.Resources, &out.Resources *out = new(v1.ResourceRequirements) @@ -1648,6 +1654,80 @@ func (in *FsValidator) DeepCopy() *FsValidator { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GatewayConfig) DeepCopyInto(out *GatewayConfig) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ParentRefs != nil { + in, out := &in.ParentRefs, &out.ParentRefs + *out = make([]GatewayParentReference, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Hostnames != nil { + in, out := &in.Hostnames, &out.Hostnames + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Path != nil { + in, out := &in.Path, &out.Path + *out = new(string) + **out = **in + } + if in.PathType != nil { + in, out := &in.PathType, &out.PathType + *out = new(apisv1.PathMatchType) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayConfig. +func (in *GatewayConfig) DeepCopy() *GatewayConfig { + if in == nil { + return nil + } + out := new(GatewayConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GatewayParentReference) DeepCopyInto(out *GatewayParentReference) { + *out = *in + if in.Namespace != nil { + in, out := &in.Namespace, &out.Namespace + *out = new(string) + **out = **in + } + if in.SectionName != nil { + in, out := &in.SectionName, &out.SectionName + *out = new(apisv1.SectionName) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayParentReference. +func (in *GatewayParentReference) DeepCopy() *GatewayParentReference { + if in == nil { + return nil + } + out := new(GatewayParentReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Group) DeepCopyInto(out *Group) { *out = *in @@ -3736,6 +3816,11 @@ func (in *RedpandaConsole) DeepCopyInto(out *RedpandaConsole) { *out = new(runtime.RawExtension) (*in).DeepCopyInto(*out) } + if in.Gateway != nil { + in, out := &in.Gateway, &out.Gateway + *out = new(runtime.RawExtension) + (*in).DeepCopyInto(*out) + } if in.Resources != nil { in, out := &in.Resources, &out.Resources *out = new(runtime.RawExtension) diff --git a/operator/chart/files/rbac/console.ClusterRole.yaml b/operator/chart/files/rbac/console.ClusterRole.yaml index 98f4395e2..d39c62df2 100644 --- a/operator/chart/files/rbac/console.ClusterRole.yaml +++ b/operator/chart/files/rbac/console.ClusterRole.yaml @@ -71,6 +71,18 @@ rules: - get - patch - update + - apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: diff --git a/operator/chart/testdata/template-cases.golden.txtar b/operator/chart/testdata/template-cases.golden.txtar index 0ff65ce9a..e6905799e 100644 --- a/operator/chart/testdata/template-cases.golden.txtar +++ b/operator/chart/testdata/template-cases.golden.txtar @@ -140,6 +140,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -898,6 +910,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -1464,6 +1488,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -2249,6 +2285,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -2835,6 +2883,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -3606,6 +3666,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -4178,6 +4250,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -5152,6 +5236,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -5981,6 +6077,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -6753,6 +6861,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -7323,6 +7443,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -8133,6 +8265,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -8791,6 +8935,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -9647,6 +9803,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -10338,6 +10506,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -11125,6 +11305,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -11698,6 +11890,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -12475,6 +12679,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -13050,6 +13266,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -13860,6 +14088,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -14433,6 +14673,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -15047,6 +15299,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -15634,6 +15898,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -16417,6 +16693,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -17008,6 +17296,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -17996,6 +18296,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -18736,6 +19048,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -19398,6 +19722,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -19959,6 +20295,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -20744,6 +21092,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -21325,6 +21685,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -22103,6 +22475,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -23043,6 +23427,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -24036,6 +24432,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -24618,6 +25026,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -25435,6 +25855,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -26008,6 +26440,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -26942,6 +27386,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -28043,6 +28499,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -28970,6 +29438,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -29545,6 +30025,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -30718,6 +31210,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -31457,6 +31961,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -32247,6 +32763,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -32837,6 +33365,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -33934,6 +34474,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -35017,6 +35569,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -35995,6 +36559,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -36987,6 +37563,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -37992,6 +38580,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -38584,6 +39184,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -39574,6 +40186,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -40157,6 +40781,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -41176,6 +41812,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -42597,6 +43245,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -43771,6 +44431,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -44463,6 +45135,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -45272,6 +45956,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -46007,6 +46703,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -47249,6 +47957,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -49386,6 +50106,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -50730,6 +51462,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -52425,6 +53169,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -53509,6 +54265,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -55772,6 +56540,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -57095,6 +57875,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -57786,6 +58578,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -59146,6 +59950,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -60501,6 +61317,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -61575,6 +62403,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -62856,6 +63696,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -64168,6 +65020,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -65038,6 +65902,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -66162,6 +67038,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -66884,6 +67772,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -68250,6 +69150,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -69099,6 +70011,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -70366,6 +71290,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -71060,6 +71996,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -71861,6 +72809,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -72518,6 +73478,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -73319,6 +74291,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -73975,6 +74959,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -74732,6 +75728,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -75298,6 +76306,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -76072,6 +77092,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -76638,6 +77670,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -77395,6 +78439,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -77961,6 +79017,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -78718,6 +79786,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -79284,6 +80364,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -80049,6 +81141,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -80615,6 +81719,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -81380,6 +82496,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -81946,6 +83074,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -82777,6 +83917,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -83444,6 +84596,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -84332,6 +85496,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -84898,6 +86074,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: @@ -85662,6 +86850,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: diff --git a/operator/config/crd/bases/cluster.redpanda.com_consoles.yaml b/operator/config/crd/bases/cluster.redpanda.com_consoles.yaml index 75535f8cf..b185200b9 100644 --- a/operator/config/crd/bases/cluster.redpanda.com_consoles.yaml +++ b/operator/config/crd/bases/cluster.redpanda.com_consoles.yaml @@ -6999,6 +6999,91 @@ spec: - name type: object type: array + gateway: + description: GatewayConfig configures a Gateway API HTTPRoute for + Console. + properties: + annotations: + additionalProperties: + type: string + type: object + enabled: + type: boolean + hostnames: + items: + type: string + type: array + parentRefs: + items: + description: GatewayParentReference identifies a parent Gateway + for the HTTPRoute. + properties: + name: + type: string + namespace: + type: string + sectionName: + description: |- + SectionName is the name of a section in a Kubernetes resource. + + In the following resources, SectionName is interpreted as the following: + + * Gateway: Listener name + * HTTPRoute: HTTPRouteRule name + * Service: Port name + + Section names can have a variety of forms, including RFC 1123 subdomains, + RFC 1123 labels, or RFC 1035 labels. + + This validation is based off of the corresponding Kubernetes validation: + https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L208 + + Valid values include: + + * "example" + * "foo-example" + * "example.com" + * "foo.example.com" + + Invalid values include: + + * "example.com/bar" - "/" is an invalid character + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + type: array + path: + type: string + pathType: + description: |- + PathMatchType specifies the semantics of how HTTP paths should be compared. + Valid PathMatchType values, along with their support levels, are: + + * "Exact" - Core + * "PathPrefix" - Core + * "RegularExpression" - Implementation Specific + + PathPrefix and Exact paths must be syntactically valid: + + - Must begin with the `/` character + - Must not contain consecutive `/` characters (e.g. `/foo///`, `//`). + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + type: object image: properties: pullPolicy: diff --git a/operator/config/crd/bases/cluster.redpanda.com_redpandas.yaml b/operator/config/crd/bases/cluster.redpanda.com_redpandas.yaml index 21609c088..44d1587f3 100644 --- a/operator/config/crd/bases/cluster.redpanda.com_redpandas.yaml +++ b/operator/config/crd/bases/cluster.redpanda.com_redpandas.yaml @@ -1618,6 +1618,11 @@ spec: the entire naming convention including release name and chart name. type: string + gateway: + description: Configures a Gateway API HTTPRoute for Redpanda + Console. + type: object + x-kubernetes-preserve-unknown-fields: true image: description: Defines the container image for the Redpanda Console, including the repository, name, and tag. @@ -35412,6 +35417,11 @@ spec: the entire naming convention including release name and chart name. type: string + gateway: + description: Configures a Gateway API HTTPRoute for Redpanda + Console. + type: object + x-kubernetes-preserve-unknown-fields: true image: description: Defines the container image for the Redpanda Console, including the repository, name, and tag. diff --git a/operator/config/rbac/bases/operator/role.yaml b/operator/config/rbac/bases/operator/role.yaml index f8a24cf28..3b6f9a6d8 100644 --- a/operator/config/rbac/bases/operator/role.yaml +++ b/operator/config/rbac/bases/operator/role.yaml @@ -216,6 +216,18 @@ rules: - patch - update - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: diff --git a/operator/config/rbac/itemized/console.yaml b/operator/config/rbac/itemized/console.yaml index 1cf4f82ed..be6e784ff 100644 --- a/operator/config/rbac/itemized/console.yaml +++ b/operator/config/rbac/itemized/console.yaml @@ -71,6 +71,18 @@ rules: - get - patch - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - monitoring.coreos.com resources: diff --git a/operator/go.mod b/operator/go.mod index 617b5e47c..206177c58 100644 --- a/operator/go.mod +++ b/operator/go.mod @@ -18,8 +18,8 @@ require ( github.com/json-iterator/go v1.1.12 github.com/moby/moby v24.0.7+incompatible github.com/moby/sys/mountinfo v0.7.2 - github.com/onsi/ginkgo/v2 v2.27.2 - github.com/onsi/gomega v1.38.2 + github.com/onsi/ginkgo/v2 v2.28.0 + github.com/onsi/gomega v1.39.1 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.89.0 github.com/prometheus/client_golang v1.23.2 github.com/prometheus/common v0.67.5 @@ -65,6 +65,7 @@ require ( k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 pgregory.net/rapid v1.1.0 sigs.k8s.io/controller-runtime v0.23.1 + sigs.k8s.io/gateway-api v1.5.1 sigs.k8s.io/multicluster-runtime v0.23.1 sigs.k8s.io/yaml v1.6.0 ) @@ -190,7 +191,7 @@ require ( github.com/google/cel-go v0.27.0 // indirect github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 // indirect + github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect @@ -354,7 +355,6 @@ require ( k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 // indirect oras.land/oras-go/v2 v2.6.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect - sigs.k8s.io/gateway-api v1.4.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect diff --git a/operator/go.sum b/operator/go.sum index de873d5aa..619e213aa 100644 --- a/operator/go.sum +++ b/operator/go.sum @@ -335,8 +335,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLxCY3f87278uWfIDhJnbdvDjvmE= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -549,10 +549,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 h1:H55sU3giNgBkIvmAo0vI/AAFwVTwfWsf6MN3+9H6U8o= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98/go.mod h1:RqnyioA3pIEZMkSbOIcrw32YSgETfn/VrLuEikEdPNU= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -956,8 +956,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= -sigs.k8s.io/gateway-api v1.4.1 h1:NPxFutNkKNa8UfLd2CMlEuhIPMQgDQ6DXNKG9sHbJU8= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0= +sigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= diff --git a/operator/internal/controller/console/controller.go b/operator/internal/controller/console/controller.go index ec65be39e..a9ddadbfe 100644 --- a/operator/internal/controller/console/controller.go +++ b/operator/internal/controller/console/controller.go @@ -32,6 +32,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" mcbuilder "sigs.k8s.io/multicluster-runtime/pkg/builder" mcreconcile "sigs.k8s.io/multicluster-runtime/pkg/reconcile" @@ -56,6 +57,7 @@ const ( // +kubebuilder:rbac:groups=cluster.redpanda.com,resources=consoles/status,verbs=get;update;patch // +kubebuilder:rbac:groups=autoscaling,resources=horizontalpodautoscalers,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=core,resources=configmaps;secrets;services;serviceaccounts,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups="monitoring.coreos.com",resources=servicemonitors,verbs=get;list;watch;create;update;patch;delete @@ -93,7 +95,13 @@ func (c *Controller) SetupWithManager(ctx context.Context, mgr multicluster.Mana // If it gets installed during the operator runtime, we will need to restart the operator to start watching for it. // While not ideal, given that we don't modify Console's ServiceMonitor at all, I think it's **fine**. if _, ok := t.(*monitoringv1.ServiceMonitor); ok { - if c.skipServiceMonitorWatchIfNotInstalled(ctx) { + if c.skipWatchIfNotInstalled(ctx, &monitoringv1.ServiceMonitorList{}, "ServiceMonitors") { + continue + } + } + // Skip HTTPRoute watch if Gateway API CRDs are not installed. + if _, ok := t.(*gatewayv1.HTTPRoute); ok { + if c.skipWatchIfNotInstalled(ctx, &gatewayv1.HTTPRouteList{}, "HTTPRoutes") { continue } } @@ -336,13 +344,12 @@ func (c *Controller) maybeSetJWTToken(ctx context.Context, cr *redpandav1alpha2. return nil } -func (c *Controller) skipServiceMonitorWatchIfNotInstalled(ctx context.Context) (skip bool) { - var serviceMonitorList monitoringv1.ServiceMonitorList - err := c.Ctl.List(ctx, "default", &serviceMonitorList) +func (c *Controller) skipWatchIfNotInstalled(ctx context.Context, list client.ObjectList, name string) (skip bool) { + err := c.Ctl.List(ctx, "default", list) if errors.Is(err, &meta.NoKindMatchError{}) { return true } else if err != nil { - log.Error(ctx, err, "could not list ServiceMonitors") + log.Error(ctx, err, "could not list "+name) return true } return false diff --git a/operator/internal/controller/console/controller_test.go b/operator/internal/controller/console/controller_test.go index 2f515b75c..7e163ad9a 100644 --- a/operator/internal/controller/console/controller_test.go +++ b/operator/internal/controller/console/controller_test.go @@ -10,9 +10,13 @@ package console import ( + "bytes" "context" "fmt" "math/rand" + "os" + "os/exec" + "path/filepath" "slices" "strings" "testing" @@ -103,6 +107,53 @@ func TestController(t *testing.T) { }, }, }, + { + name: "gateway-enabled", + console: &redpandav1alpha2.Console{ + ObjectMeta: metav1.ObjectMeta{ + Name: "console-gateway", + }, + Spec: redpandav1alpha2.ConsoleSpec{ + ConsoleValues: redpandav1alpha2.ConsoleValues{ + Gateway: &redpandav1alpha2.GatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com"}, + Path: ptr.To("/"), + Annotations: map[string]string{ + "example.com/team": "platform", + }, + ParentRefs: []redpandav1alpha2.GatewayParentReference{ + { + Name: "my-gateway", + Namespace: ptr.To("gateway-system"), + }, + }, + }, + }, + }, + }, + }, + { + name: "gateway-custom-path", + console: &redpandav1alpha2.Console{ + ObjectMeta: metav1.ObjectMeta{ + Name: "console-gw-path", + }, + Spec: redpandav1alpha2.ConsoleSpec{ + ConsoleValues: redpandav1alpha2.ConsoleValues{ + Gateway: &redpandav1alpha2.GatewayConfig{ + Enabled: ptr.To(true), + Hostnames: []string{"console.example.com", "console.internal"}, + Path: ptr.To("/console"), + ParentRefs: []redpandav1alpha2.GatewayParentReference{ + {Name: "gw-a"}, + {Name: "gw-b", Namespace: ptr.To("other-ns")}, + }, + }, + }, + }, + }, + }, { name: "jwt-set", console: &redpandav1alpha2.Console{ @@ -128,6 +179,9 @@ func TestController(t *testing.T) { }, }) + allCRDs := crds.All() + allCRDs = append(allCRDs, loadGatewayAPICRDs(t)...) + require.NoError(t, kube.ApplyAllAndWait(t.Context(), ctl, func(crd *apiextensionsv1.CustomResourceDefinition, err error) (bool, error) { if err != nil { return false, err @@ -140,7 +194,7 @@ func TestController(t *testing.T) { } return false, nil - }, crds.All()...)) + }, allCRDs...)) // Create namespace ns, err := kube.Create(t.Context(), ctl, corev1.Namespace{ @@ -274,6 +328,53 @@ func scrapeControllerObjects(t *testing.T, ctl *kube.Ctl, console *redpandav1alp return objects } +// loadGatewayAPICRDs loads Gateway API CRDs from the sigs.k8s.io/gateway-api +// module in the Go module cache. This is needed for envtest to support +// HTTPRoute resources. +func loadGatewayAPICRDs(t *testing.T) []*apiextensionsv1.CustomResourceDefinition { + t.Helper() + + // Resolve the gateway-api module directory from the module cache. + cmd := exec.Command("go", "list", "-m", "-f", "{{.Dir}}", "sigs.k8s.io/gateway-api") + var out bytes.Buffer + cmd.Stdout = &out + cmd.Stderr = os.Stderr + require.NoError(t, cmd.Run(), "failed to resolve gateway-api module directory") + + crdDir := filepath.Join(strings.TrimSpace(out.String()), "config", "crd", "standard") + + scheme := runtime.NewScheme() + require.NoError(t, apiextensionsv1.AddToScheme(scheme)) + + entries, err := os.ReadDir(crdDir) + require.NoError(t, err) + + var result []*apiextensionsv1.CustomResourceDefinition + for _, entry := range entries { + if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".yaml") { + continue + } + + data, err := os.ReadFile(filepath.Join(crdDir, entry.Name())) + require.NoError(t, err) + + objs, err := kube.DecodeYAML(data, scheme) + if err != nil { + // Skip non-CRD YAML files (e.g. ValidatingAdmissionPolicy). + continue + } + + for _, obj := range objs { + if crd, ok := obj.(*apiextensionsv1.CustomResourceDefinition); ok { + result = append(result, crd) + } + } + } + + require.NotEmpty(t, result, "no Gateway API CRDs found in %s", crdDir) + return result +} + // cleanObjectForGolden removes dynamic fields that change between test runs func cleanObjectForGolden(scheme *runtime.Scheme, obj client.Object) { gvks, _, err := scheme.ObjectKinds(obj) diff --git a/operator/internal/controller/console/testdata/controller-tests.golden.txtar b/operator/internal/controller/console/testdata/controller-tests.golden.txtar index 69e9faefe..a73b98181 100644 --- a/operator/internal/controller/console/testdata/controller-tests.golden.txtar +++ b/operator/internal/controller/console/testdata/controller-tests.golden.txtar @@ -227,6 +227,460 @@ type: ClusterIP status: loadBalancer: {} +-- gateway-custom-path -- +- apiVersion: v1 + data: + config.yaml: | + # from .Values.config + {} + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: console-gw-path + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gw-path-console + namespace: test-ns +- apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: console-gw-path + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gw-path-console + namespace: test-ns + spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/instance: console-gw-path + app.kubernetes.io/name: console + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + annotations: + checksum/config: 28d978af90a43439edaee767a120fd85a15f923d1977979170de19b9e74c5895 + labels: + app.kubernetes.io/instance: console-gw-path + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: false + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + env: + - name: AUTHENTICATION_JWTSIGNINGKEY + valueFrom: + secretKeyRef: + key: authentication-jwt-signingkey + name: console-gw-path-console + - name: REDPANDA_METRICS_K8S_DEPLOYMENT_TYPE + value: operator + - name: REDPANDA_METRICS_K8S_CHART_VERSION + - name: REDPANDA_METRICS_K8S_CONSOLE_IMAGE_VERSION + value: redpandadata/console:v3.3.2 + - name: REDPANDA_METRICS_K8S_CLUSTER_ID + value: 00000000-0000-0000-0000-000000000000 + image: docker.redpanda.com/redpandadata/console:v3.3.2 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + fsGroup: 99 + fsGroupChangePolicy: Always + runAsUser: 99 + serviceAccount: console-gw-path-console + serviceAccountName: console-gw-path-console + terminationGracePeriodSeconds: 30 + volumes: + - configMap: + defaultMode: 420 + name: console-gw-path-console + name: configs + - name: secrets + secret: + defaultMode: 420 + secretName: console-gw-path-console + status: {} +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + labels: + app.kubernetes.io/instance: console-gw-path + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gw-path-console + namespace: test-ns + spec: + hostnames: + - console.example.com + - console.internal + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: gw-a + - group: gateway.networking.k8s.io + kind: Gateway + name: gw-b + namespace: other-ns + rules: + - backendRefs: + - group: "" + kind: Service + name: console-gw-path-console + port: 8080 + weight: 1 + matches: + - path: + type: PathPrefix + value: /console + status: + parents: null +- apiVersion: v1 + data: + authentication-jwt-signingkey: cyBVLipLbStGaHl5LXg4XlAsP1glSj5XNX1KWWFISX4= + authentication-oidc-client-secret: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + license: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" + schema-registry-bearertoken: "" + schema-registry-password: "" + schemaregistry-tls-ca: "" + schemaregistry-tls-cert: "" + schemaregistry-tls-key: "" + serde-protobuf-git-basicauth-password: "" + kind: Secret + metadata: + labels: + app.kubernetes.io/instance: console-gw-path + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gw-path-console + namespace: test-ns + type: Opaque +- apiVersion: v1 + data: + key: cyBVLipLbStGaHl5LXg4XlAsP1glSj5XNX1KWWFISX4= + immutable: true + kind: Secret + metadata: + name: console-gw-path-jwt-secret + namespace: test-ns + type: Opaque +- apiVersion: v1 + automountServiceAccountToken: false + kind: ServiceAccount + metadata: + labels: + app.kubernetes.io/instance: console-gw-path + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gw-path-console + namespace: test-ns +- apiVersion: v1 + kind: Service + metadata: + labels: + app.kubernetes.io/instance: console-gw-path + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gw-path-console + namespace: test-ns + spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 8080 + selector: + app.kubernetes.io/instance: console-gw-path + app.kubernetes.io/name: console + sessionAffinity: None + type: ClusterIP + status: + loadBalancer: {} +-- gateway-enabled -- +- apiVersion: v1 + data: + config.yaml: | + # from .Values.config + {} + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: console-gateway + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gateway-console + namespace: test-ns +- apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: console-gateway + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gateway-console + namespace: test-ns + spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/instance: console-gateway + app.kubernetes.io/name: console + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + annotations: + checksum/config: 28d978af90a43439edaee767a120fd85a15f923d1977979170de19b9e74c5895 + labels: + app.kubernetes.io/instance: console-gateway + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: false + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + env: + - name: AUTHENTICATION_JWTSIGNINGKEY + valueFrom: + secretKeyRef: + key: authentication-jwt-signingkey + name: console-gateway-console + - name: REDPANDA_METRICS_K8S_DEPLOYMENT_TYPE + value: operator + - name: REDPANDA_METRICS_K8S_CHART_VERSION + - name: REDPANDA_METRICS_K8S_CONSOLE_IMAGE_VERSION + value: redpandadata/console:v3.3.2 + - name: REDPANDA_METRICS_K8S_CLUSTER_ID + value: 00000000-0000-0000-0000-000000000000 + image: docker.redpanda.com/redpandadata/console:v3.3.2 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + fsGroup: 99 + fsGroupChangePolicy: Always + runAsUser: 99 + serviceAccount: console-gateway-console + serviceAccountName: console-gateway-console + terminationGracePeriodSeconds: 30 + volumes: + - configMap: + defaultMode: 420 + name: console-gateway-console + name: configs + - name: secrets + secret: + defaultMode: 420 + secretName: console-gateway-console + status: {} +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + annotations: + example.com/team: platform + labels: + app.kubernetes.io/instance: console-gateway + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gateway-console + namespace: test-ns + spec: + hostnames: + - console.example.com + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: my-gateway + namespace: gateway-system + rules: + - backendRefs: + - group: "" + kind: Service + name: console-gateway-console + port: 8080 + weight: 1 + matches: + - path: + type: PathPrefix + value: / + status: + parents: null +- apiVersion: v1 + data: + authentication-jwt-signingkey: QFMxdEokPGxVdnZlWXU7QVsuRiIubz9AUkNFS3YoXiw= + authentication-oidc-client-secret: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + license: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" + schema-registry-bearertoken: "" + schema-registry-password: "" + schemaregistry-tls-ca: "" + schemaregistry-tls-cert: "" + schemaregistry-tls-key: "" + serde-protobuf-git-basicauth-password: "" + kind: Secret + metadata: + labels: + app.kubernetes.io/instance: console-gateway + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gateway-console + namespace: test-ns + type: Opaque +- apiVersion: v1 + data: + key: QFMxdEokPGxVdnZlWXU7QVsuRiIubz9AUkNFS3YoXiw= + immutable: true + kind: Secret + metadata: + name: console-gateway-jwt-secret + namespace: test-ns + type: Opaque +- apiVersion: v1 + automountServiceAccountToken: false + kind: ServiceAccount + metadata: + labels: + app.kubernetes.io/instance: console-gateway + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gateway-console + namespace: test-ns +- apiVersion: v1 + kind: Service + metadata: + labels: + app.kubernetes.io/instance: console-gateway + app.kubernetes.io/managed-by: redpanda-operator + app.kubernetes.io/name: console + name: console-gateway-console + namespace: test-ns + spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 8080 + selector: + app.kubernetes.io/instance: console-gateway + app.kubernetes.io/name: console + sessionAffinity: None + type: ClusterIP + status: + loadBalancer: {} -- jwt-set -- - apiVersion: v1 data: diff --git a/operator/internal/controller/scheme.go b/operator/internal/controller/scheme.go index c3ec1f685..5fd04c3fc 100644 --- a/operator/internal/controller/scheme.go +++ b/operator/internal/controller/scheme.go @@ -16,6 +16,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" redpandav1alpha1 "github.com/redpanda-data/redpanda-operator/operator/api/redpanda/v1alpha1" redpandav1alpha2 "github.com/redpanda-data/redpanda-operator/operator/api/redpanda/v1alpha2" @@ -34,6 +35,7 @@ var ( certmanagerv1.AddToScheme, clientgoscheme.AddToScheme, monitoringv1.AddToScheme, + gatewayv1.Install, redpandav1alpha1.Install, redpandav1alpha2.Install, } diff --git a/operator/internal/lifecycle/testdata/redpanda-cases.values.golden.txtar b/operator/internal/lifecycle/testdata/redpanda-cases.values.golden.txtar index a9ad592c3..28da5cf15 100644 --- a/operator/internal/lifecycle/testdata/redpanda-cases.values.golden.txtar +++ b/operator/internal/lifecycle/testdata/redpanda-cases.values.golden.txtar @@ -73,6 +73,12 @@ values: create: false enabled: true fullnameOverride: "" + gateway: + enabled: false + hostnames: + - chart-example.local + path: / + pathType: PathPrefix image: pullPolicy: IfNotPresent registry: docker.redpanda.com @@ -668,6 +674,12 @@ values: create: false enabled: true fullnameOverride: "" + gateway: + enabled: false + hostnames: + - chart-example.local + path: / + pathType: PathPrefix image: pullPolicy: IfNotPresent registry: docker.redpanda.com @@ -1631,6 +1643,12 @@ values: create: false enabled: true fullnameOverride: "" + gateway: + enabled: false + hostnames: + - chart-example.local + path: / + pathType: PathPrefix image: pullPolicy: IfNotPresent registry: docker.redpanda.com diff --git a/pkg/go.mod b/pkg/go.mod index b306da868..06ca5ecfe 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -207,6 +207,8 @@ require ( github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/onsi/ginkgo/v2 v2.28.0 // indirect + github.com/onsi/gomega v1.39.1 // indirect github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect @@ -297,6 +299,7 @@ require ( k8s.io/kubectl v0.35.1 // indirect oras.land/oras-go/v2 v2.6.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect + sigs.k8s.io/gateway-api v1.5.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect diff --git a/pkg/go.sum b/pkg/go.sum index 706bd3179..ef56afb56 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -305,8 +305,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8 h1:3DsUAV+VNEQa2CUVLxCY3f87278uWfIDhJnbdvDjvmE= -github.com/google/pprof v0.0.0-20251114195745-4902fdda35c8/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -487,10 +487,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc= +github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98 h1:H55sU3giNgBkIvmAo0vI/AAFwVTwfWsf6MN3+9H6U8o= github.com/opencontainers/go-digest v1.0.1-0.20231025023718-d50d2fec9c98/go.mod h1:RqnyioA3pIEZMkSbOIcrw32YSgETfn/VrLuEikEdPNU= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -870,8 +870,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= -sigs.k8s.io/gateway-api v1.4.1 h1:NPxFutNkKNa8UfLd2CMlEuhIPMQgDQ6DXNKG9sHbJU8= -sigs.k8s.io/gateway-api v1.4.1/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk= +sigs.k8s.io/gateway-api v1.5.1 h1:RqVRIlkhLhUO8wOHKTLnTJA6o/1un4po4/6M1nRzdd0= +sigs.k8s.io/gateway-api v1.5.1/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I=