Skip to content

Commit 809e009

Browse files
pvsunejoejulian
authored andcommitted
operator: add support for RedpandaCloud provider
(cherry picked from commit 2df607c)
1 parent 13c5366 commit 809e009

14 files changed

+109
-391
lines changed

src/go/k8s/apis/redpanda/v1alpha1/cluster_types.go

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -257,33 +257,17 @@ type StorageSpec struct {
257257
// used as a external listener. This port is tight to the autogenerated
258258
// host port. The collision between Kafka external, Kafka internal,
259259
// Admin, Pandaproxy, Schema Registry and RPC port is checked in the webhook.
260-
// An optional endpointTemplate can be used to configure advertised addresses
261-
// for Kafka API and Pandaproxy, while it is disallowed for other listeners.
262260
type ExternalConnectivityConfig struct {
263261
// Enabled enables the external connectivity feature
264262
Enabled bool `json:"enabled,omitempty"`
265263
// Subdomain can be used to change the behavior of an advertised
266264
// KafkaAPI. Each broker advertises Kafka API as follows
267-
// ENDPOINT.SUBDOMAIN:EXTERNAL_KAFKA_API_PORT.
265+
// BROKER_ID.SUBDOMAIN:EXTERNAL_KAFKA_API_PORT.
268266
// If Subdomain is empty then each broker advertises Kafka
269267
// API as PUBLIC_NODE_IP:EXTERNAL_KAFKA_API_PORT.
270268
// If TLS is enabled then this subdomain will be requested
271269
// as a subject alternative name.
272270
Subdomain string `json:"subdomain,omitempty"`
273-
// EndpointTemplate is a Golang template string that allows customizing each
274-
// broker advertised address.
275-
// Redpanda uses the format BROKER_ID.SUBDOMAIN:EXTERNAL_KAFKA_API_PORT by
276-
// default for advertised addresses. When an EndpointTemplate is
277-
// provided, then the BROKER_ID part is replaced with the endpoint
278-
// computed from the template.
279-
// The following variables are available to the template:
280-
// - Index: the Redpanda broker progressive number
281-
// - HostIP: the ip address of the Node, as reported in pod status
282-
//
283-
// Common template functions from Sprig (http://masterminds.github.io/sprig/)
284-
// are also available. The set of available functions is limited to hermetic
285-
// functions because template application needs to be deterministic.
286-
EndpointTemplate string `json:"endpointTemplate,omitempty"`
287271
// The preferred address type to be assigned to the external
288272
// advertised addresses. The valid types are ExternalDNS,
289273
// ExternalIP, InternalDNS, InternalIP, and Hostname.

src/go/k8s/apis/redpanda/v1alpha1/cluster_webhook.go

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"strconv"
1616

1717
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
18-
"github.com/redpanda-data/redpanda/src/go/k8s/pkg/utils"
1918
corev1 "k8s.io/api/core/v1"
2019
apierrors "k8s.io/apimachinery/pkg/api/errors"
2120
"k8s.io/apimachinery/pkg/api/resource"
@@ -278,12 +277,6 @@ func (r *Cluster) validateAdminListeners() field.ErrorList {
278277
r.Spec.Configuration.AdminAPI,
279278
"bootstrap loadbalancer not available for http admin api"))
280279
}
281-
if externalAdmin != nil && externalAdmin.External.EndpointTemplate != "" {
282-
allErrs = append(allErrs,
283-
field.Invalid(field.NewPath("spec").Child("configuration").Child("adminApi"),
284-
r.Spec.Configuration.AdminAPI,
285-
"cannot provide an endpoint template for admin listener"))
286-
}
287280

288281
// for now only one listener can have TLS to be backward compatible with v1alpha1 API
289282
foundListenerWithTLS := false
@@ -313,7 +306,6 @@ func (r *Cluster) validateKafkaListeners() field.ErrorList {
313306
}
314307

315308
var external *KafkaAPI
316-
var externalIdx int
317309
for i, p := range r.Spec.Configuration.KafkaAPI {
318310
if p.External.Enabled {
319311
if external != nil {
@@ -323,7 +315,6 @@ func (r *Cluster) validateKafkaListeners() field.ErrorList {
323315
"only one kafka api listener can be marked as external"))
324316
}
325317
external = &r.Spec.Configuration.KafkaAPI[i]
326-
externalIdx = i
327318
}
328319
}
329320

@@ -366,36 +357,10 @@ func (r *Cluster) validateKafkaListeners() field.ErrorList {
366357
r.Spec.Configuration.KafkaAPI,
367358
"bootstrap port cannot be empty"))
368359
}
369-
// nolint:dupl // not identical
370-
if external != nil && external.External.EndpointTemplate != "" {
371-
if external.External.Subdomain == "" {
372-
allErrs = append(allErrs,
373-
field.Invalid(field.NewPath("spec").Child("configuration").Child("kafkaApi").Index(externalIdx).Child("external"),
374-
external.External,
375-
"endpointTemplate can only be used in combination with subdomain"))
376-
}
377-
378-
err := checkValidEndpointTemplate(external.External.EndpointTemplate)
379-
if err != nil {
380-
log.Error(err, "Invalid endpoint template received", "template", external.External.EndpointTemplate)
381-
allErrs = append(allErrs,
382-
field.Invalid(field.NewPath("spec").Child("configuration").Child("kafkaApi").Index(externalIdx).Child("external").Child("endpointTemplate"),
383-
external.External.EndpointTemplate,
384-
fmt.Sprintf("template is invalid: %v", err)))
385-
}
386-
}
387360

388361
return allErrs
389362
}
390363

391-
func checkValidEndpointTemplate(tmpl string) error {
392-
// Using an example input to ensure that the template expression is allowed
393-
data := utils.NewEndpointTemplateData(0, "1.2.3.4")
394-
_, err := utils.ComputeEndpoint(tmpl, data)
395-
return err
396-
}
397-
398-
// nolint:funlen,gocyclo // it's a sequence of checks
399364
func (r *Cluster) validatePandaproxyListeners() field.ErrorList {
400365
var allErrs field.ErrorList
401366
var proxyExternal *PandaproxyAPI
@@ -447,25 +412,6 @@ func (r *Cluster) validatePandaproxyListeners() field.ErrorList {
447412
r.Spec.Configuration.PandaproxyAPI[i],
448413
"sudomain of external pandaproxy must be the same as kafka's"))
449414
}
450-
// nolint:dupl // not identical
451-
if kafkaExternal != nil && proxyExternal.External.EndpointTemplate != "" {
452-
if proxyExternal.External.Subdomain == "" {
453-
allErrs = append(allErrs,
454-
field.Invalid(field.NewPath("spec").Child("configuration").Child("pandaproxyApi").Index(i).Child("external"),
455-
proxyExternal.External,
456-
"endpointTemplate can only be used in combination with subdomain"))
457-
}
458-
459-
err := checkValidEndpointTemplate(proxyExternal.External.EndpointTemplate)
460-
if err != nil {
461-
log.Error(err, "Invalid endpoint template received", "template", proxyExternal.External.EndpointTemplate)
462-
allErrs = append(allErrs,
463-
field.Invalid(field.NewPath("spec").Child("configuration").Child("pandaproxyApi").Index(i).
464-
Child("external").Child("endpointTemplate"),
465-
proxyExternal.External.EndpointTemplate,
466-
fmt.Sprintf("template is invalid: %v", err)))
467-
}
468-
}
469415
}
470416

471417
// for now only one listener can have TLS to be backward compatible with v1alpha1 API
@@ -564,13 +510,6 @@ func (r *Cluster) validateSchemaRegistryListener() field.ErrorList {
564510
r.Spec.Configuration.SchemaRegistry.External,
565511
"bootstrap loadbalancer not available for schema reigstry"))
566512
}
567-
if schemaRegistry.External.EndpointTemplate != "" {
568-
allErrs = append(allErrs,
569-
field.Invalid(field.NewPath("spec").Child("configuration").Child("schemaRegistry").Child("external").Child("endpointTemplate"),
570-
r.Spec.Configuration.SchemaRegistry.External.EndpointTemplate,
571-
"cannot provide an endpoint template for schema registry"))
572-
}
573-
574513
return allErrs
575514
}
576515

src/go/k8s/apis/redpanda/v1alpha1/cluster_webhook_test.go

Lines changed: 0 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,118 +1022,6 @@ func TestCreation(t *testing.T) {
10221022
err := rp.ValidateCreate()
10231023
assert.Error(t, err)
10241024
})
1025-
t.Run("endpoint template not allowed for schemaregistry", func(t *testing.T) {
1026-
rp := redpandaCluster.DeepCopy()
1027-
const commonDomain = "company.org"
1028-
1029-
rp.Spec.Configuration.KafkaAPI = append(rp.Spec.Configuration.KafkaAPI, v1alpha1.KafkaAPI{External: v1alpha1.ExternalConnectivityConfig{
1030-
Enabled: true,
1031-
Subdomain: commonDomain,
1032-
}})
1033-
rp.Spec.Configuration.SchemaRegistry = &v1alpha1.SchemaRegistryAPI{External: &v1alpha1.ExternalConnectivityConfig{
1034-
Enabled: true,
1035-
Subdomain: commonDomain,
1036-
EndpointTemplate: "xxx",
1037-
}}
1038-
err := rp.ValidateCreate()
1039-
assert.Error(t, err)
1040-
})
1041-
// nolint:dupl // not really a duplicate
1042-
t.Run("endpoint template not allowed for adminapi", func(t *testing.T) {
1043-
rp := redpandaCluster.DeepCopy()
1044-
const commonDomain = "company.org"
1045-
1046-
rp.Spec.Configuration.KafkaAPI = append(rp.Spec.Configuration.KafkaAPI, v1alpha1.KafkaAPI{External: v1alpha1.ExternalConnectivityConfig{
1047-
Enabled: true,
1048-
Subdomain: commonDomain,
1049-
}})
1050-
rp.Spec.Configuration.AdminAPI = append(rp.Spec.Configuration.AdminAPI, v1alpha1.AdminAPI{External: v1alpha1.ExternalConnectivityConfig{
1051-
Enabled: true,
1052-
Subdomain: commonDomain,
1053-
EndpointTemplate: "xxx",
1054-
}})
1055-
err := rp.ValidateCreate()
1056-
assert.Error(t, err)
1057-
})
1058-
t.Run("endpoint template without subdomain is not allowed in kafka API", func(t *testing.T) {
1059-
rp := redpandaCluster.DeepCopy()
1060-
1061-
rp.Spec.Configuration.KafkaAPI = append(rp.Spec.Configuration.KafkaAPI, v1alpha1.KafkaAPI{External: v1alpha1.ExternalConnectivityConfig{
1062-
Enabled: true,
1063-
EndpointTemplate: "xxx",
1064-
}})
1065-
err := rp.ValidateCreate()
1066-
assert.Error(t, err)
1067-
})
1068-
t.Run("endpoint template without subdomain is not allowed in pandaproxy API", func(t *testing.T) {
1069-
rp := redpandaCluster.DeepCopy()
1070-
1071-
rp.Spec.Configuration.KafkaAPI = append(rp.Spec.Configuration.KafkaAPI, v1alpha1.KafkaAPI{External: v1alpha1.ExternalConnectivityConfig{
1072-
Enabled: true,
1073-
}})
1074-
rp.Spec.Configuration.PandaproxyAPI = append(rp.Spec.Configuration.PandaproxyAPI, v1alpha1.PandaproxyAPI{External: v1alpha1.ExternalConnectivityConfig{
1075-
Enabled: true,
1076-
EndpointTemplate: "xxx",
1077-
}})
1078-
err := rp.ValidateCreate()
1079-
assert.Error(t, err)
1080-
})
1081-
t.Run("invalid endpoint template in kafka API", func(t *testing.T) {
1082-
rp := redpandaCluster.DeepCopy()
1083-
1084-
rp.Spec.Configuration.KafkaAPI = append(rp.Spec.Configuration.KafkaAPI, v1alpha1.KafkaAPI{External: v1alpha1.ExternalConnectivityConfig{
1085-
Enabled: true,
1086-
Subdomain: "example.com",
1087-
EndpointTemplate: "{{.Inexistent}}",
1088-
}})
1089-
err := rp.ValidateCreate()
1090-
assert.Error(t, err)
1091-
})
1092-
t.Run("valid endpoint template in kafka API", func(t *testing.T) {
1093-
rp := redpandaCluster.DeepCopy()
1094-
1095-
rp.Spec.Configuration.KafkaAPI = append(rp.Spec.Configuration.KafkaAPI, v1alpha1.KafkaAPI{External: v1alpha1.ExternalConnectivityConfig{
1096-
Enabled: true,
1097-
Subdomain: "example.com",
1098-
EndpointTemplate: "{{.Index}}-broker",
1099-
}})
1100-
err := rp.ValidateCreate()
1101-
assert.NoError(t, err)
1102-
})
1103-
// nolint:dupl // not really a duplicate
1104-
t.Run("invalid endpoint template in pandaproxy API", func(t *testing.T) {
1105-
rp := redpandaCluster.DeepCopy()
1106-
1107-
const commonDomain = "mydomain"
1108-
rp.Spec.Configuration.KafkaAPI = append(rp.Spec.Configuration.KafkaAPI, v1alpha1.KafkaAPI{External: v1alpha1.ExternalConnectivityConfig{
1109-
Enabled: true,
1110-
Subdomain: commonDomain,
1111-
}})
1112-
rp.Spec.Configuration.PandaproxyAPI = append(rp.Spec.Configuration.PandaproxyAPI, v1alpha1.PandaproxyAPI{External: v1alpha1.ExternalConnectivityConfig{
1113-
Enabled: true,
1114-
Subdomain: commonDomain,
1115-
EndpointTemplate: "{{.Index | nonexistent }}",
1116-
}})
1117-
err := rp.ValidateCreate()
1118-
assert.Error(t, err)
1119-
})
1120-
// nolint:dupl // not really a duplicate
1121-
t.Run("valid endpoint template in pandaproxy API", func(t *testing.T) {
1122-
rp := redpandaCluster.DeepCopy()
1123-
1124-
const commonDomain = "mydomain"
1125-
rp.Spec.Configuration.KafkaAPI = append(rp.Spec.Configuration.KafkaAPI, v1alpha1.KafkaAPI{External: v1alpha1.ExternalConnectivityConfig{
1126-
Enabled: true,
1127-
Subdomain: commonDomain,
1128-
}})
1129-
rp.Spec.Configuration.PandaproxyAPI = append(rp.Spec.Configuration.PandaproxyAPI, v1alpha1.PandaproxyAPI{External: v1alpha1.ExternalConnectivityConfig{
1130-
Enabled: true,
1131-
Subdomain: commonDomain,
1132-
EndpointTemplate: "{{.Index}}-pp",
1133-
}})
1134-
err := rp.ValidateCreate()
1135-
assert.NoError(t, err)
1136-
})
11371025
}
11381026

11391027
func TestSchemaRegistryValidations(t *testing.T) {

src/go/k8s/apis/redpanda/v1alpha1/console_enterprise_types.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@ type EnterpriseLogin struct {
2626
JWTSecretRef SecretKeyRef `json:"jwtSecretRef"`
2727

2828
Google *EnterpriseLoginGoogle `json:"google,omitempty"`
29+
30+
RedpandaCloud *EnterpriseLoginRedpandaCloud `json:"redpandaCloud,omitempty"`
31+
}
32+
33+
// EnterpriseLoginRedpandaCloud defines configurable fields for RedpandaCloud SSO provider
34+
type EnterpriseLoginRedpandaCloud struct {
35+
Enabled bool `json:"enabled" yaml:"enabled"`
36+
37+
// Domain is the domain of the auth server
38+
Domain string `json:"domain" yaml:"domain"`
39+
40+
// Audience is the domain where this auth is intended for
41+
Audience string `json:"audience" yaml:"audience"`
42+
43+
// AllowedOrigins indicates if response is allowed from given origin
44+
AllowedOrigins string `json:"allowedOrigins,omitempty" yaml:"allowedOrigins,omitempty"`
2945
}
3046

3147
// IsGoogleLoginEnabled returns true if Google SSO provider is enabled

src/go/k8s/apis/redpanda/v1alpha1/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)