Skip to content

Commit

Permalink
feat(controller): Support anonymous auth (#185)
Browse files Browse the repository at this point in the history
NB: we don't currently support upgrading from anonymous auth to
requirepass
  • Loading branch information
dmolik authored Feb 4, 2025
1 parent ae9e443 commit 0c44d46
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 74 deletions.
4 changes: 4 additions & 0 deletions api/v1/valkey_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ type ValkeySpec struct {
// External access configuration
ExternalAccess *ExternalAccess `json:"externalAccess,omitempty"`

// Anonymous Auth
// +kubebuilder:default:=false
AnonymousAuth bool `json:"anonymousAuth,omitempty"`

// Service Password
ServicePassword *corev1.SecretKeySelector `json:"servicePassword,omitempty"`
}
Expand Down
4 changes: 4 additions & 0 deletions config/crd/bases/hyperspike.io_valkeys.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ spec:
spec:
description: ValkeySpec defines the desired state of Valkey
properties:
anonymousAuth:
default: false
description: Anonymous Auth
type: boolean
certIssuer:
description: Certificate Issuer
type: string
Expand Down
178 changes: 104 additions & 74 deletions internal/controller/valkey_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,13 @@ func (r *ValkeyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
}
}

password, err := r.upsertSecret(ctx, valkey, true)
if err != nil {
return ctrl.Result{}, err
password := ""
if !valkey.Spec.AnonymousAuth {
var err error
password, err = r.upsertSecret(ctx, valkey, true)
if err != nil {
return ctrl.Result{}, err
}
}
if err := r.upsertPodDisruptionBudget(ctx, valkey); err != nil {
return ctrl.Result{}, err
Expand Down Expand Up @@ -264,7 +268,9 @@ func (r *ValkeyReconciler) checkState(ctx context.Context, valkey *hyperv1.Valke

opt := valkeyClient.ClientOption{
InitAddress: []string{valkey.Name + "." + valkey.Namespace + ".svc:6379"},
Password: password,
}
if !valkey.Spec.AnonymousAuth {
opt.Password = password
}
if valkey.Spec.TLS {
ca, err := r.getCACertificate(ctx, valkey)
Expand Down Expand Up @@ -455,12 +461,6 @@ func (r *ValkeyReconciler) initCluster(ctx context.Context, valkey *hyperv1.Valk

logger.Info("initializing cluster")

password, err := r.GetPassword(ctx, valkey)
if err != nil {
logger.Error(err, "failed to get password")
return err
}

podNames, err := r.getPodNames(ctx, valkey)
if err != nil {
logger.Error(err, "failed to get pod names")
Expand Down Expand Up @@ -488,9 +488,17 @@ func (r *ValkeyReconciler) initCluster(ctx context.Context, valkey *hyperv1.Valk
address := podName + ":6379"
opt := valkeyClient.ClientOption{
InitAddress: []string{address},
Password: password,
ForceSingleClient: true, // this is necessary to avoid failing through to another shard and setting the wrong ip
}
if !valkey.Spec.AnonymousAuth {
var err error
opt.Password, err = r.GetPassword(ctx, valkey)
if err != nil {
logger.Error(err, "failed to get password")
return err
}
}

if valkey.Spec.TLS {
ca, err := r.getCACertificate(ctx, valkey)
if err != nil {
Expand Down Expand Up @@ -626,20 +634,26 @@ func (r *ValkeyReconciler) setClusterAnnounceIp(ctx context.Context, valkey *hyp
if len(ips) == 0 {
return errors.NewBadRequest("external ip is empty")
}
password, err := r.GetPassword(ctx, valkey)
if err != nil {
logger.Error(err, "failed to get password")
return err
password := ""
if !valkey.Spec.AnonymousAuth {
var err error
password, err = r.GetPassword(ctx, valkey)
if err != nil {
logger.Error(err, "failed to get password")
return err
}
}
clients := map[string]valkeyClient.Client{}
for podName, ip := range ips {
address := podName + "." + valkey.Name + "-headless." + valkey.Namespace + ":6379"
logger.Info("working on node", "ip", ip, "pod", podName, "address", address)
opt := valkeyClient.ClientOption{
InitAddress: []string{address},
Password: password,
ForceSingleClient: true, // this is necessary to avoid failing through to another shard and setting the wrong ip
}
if !valkey.Spec.AnonymousAuth {
opt.Password = password
}
if valkey.Spec.TLS {
ca, err := r.getCACertificate(ctx, valkey)
if err != nil {
Expand Down Expand Up @@ -950,10 +964,17 @@ func (r *ValkeyReconciler) upsertExternalAccessProxySecret(ctx context.Context,
trusted_ca:
filename: "/etc/valkey/certs/ca.crt"`
}
password, err := r.GetPassword(ctx, valkey)
if err != nil {
logger.Error(err, "failed to get password")
return err
upstreamPassword := ""
downstreamPassword := ""
if !valkey.Spec.AnonymousAuth {
password, err := r.GetPassword(ctx, valkey)
if err != nil {
logger.Error(err, "failed to get password")
return err
}
downstreamPassword = ` downstream_auth_password:
inline_string: "` + password + `"`
upstreamPassword = ` inline_string: "` + password + `"`
}
proxyLabels := labels(valkey)
proxyLabels["app.kubernetes.io/component"] = ValkeyProxy
Expand Down Expand Up @@ -984,8 +1005,7 @@ static_resources:
prefix_routes:
catch_all_route:
cluster: redis_cluster
downstream_auth_password:
inline_string: "` + password + `"
` + downstreamPassword + `
` + tlsServer + `
clusters:
- name: redis_cluster
Expand All @@ -1008,7 +1028,7 @@ static_resources:
"@type": type.googleapis.com/google.protobuf.Struct
value:
auth_password:
inline_string: "` + password + `"
` + upstreamPassword + `
` + tlsClient + `
admin:
address:
Expand Down Expand Up @@ -1486,15 +1506,16 @@ func removePort(addr string) string {
func (r *ValkeyReconciler) balanceNodes(ctx context.Context, valkey *hyperv1.Valkey) error { // nolint: gocyclo
logger := log.FromContext(ctx)

password, err := r.upsertSecret(ctx, valkey, true)
if err != nil {
return err
}

// connect to the first node!
opt := valkeyClient.ClientOption{
InitAddress: []string{valkey.Name + "-0." + valkey.Name + "-headless." + valkey.Namespace + ".svc:6379"},
Password: password,
}
if !valkey.Spec.AnonymousAuth {
var err error
opt.Password, err = r.upsertSecret(ctx, valkey, true)
if err != nil {
return err
}
}
if valkey.Spec.TLS {
ca, err := r.getCACertificate(ctx, valkey)
Expand Down Expand Up @@ -1836,28 +1857,6 @@ func (r *ValkeyReconciler) exporter(valkey *hyperv1.Valkey) corev1.Container {
Name: "VALKEY_ADDR",
Value: "valkey://127.0.0.1:6379",
},
{
Name: "VALKEY_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "password",
LocalObjectReference: corev1.LocalObjectReference{
Name: valkey.Name,
},
},
},
},
{
Name: "REDIS_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "password",
LocalObjectReference: corev1.LocalObjectReference{
Name: valkey.Name,
},
},
},
},
{
Name: "VALKEY_EXPORTER_WEB_LISTEN_ADDRESS",
Value: ":9121",
Expand Down Expand Up @@ -1894,6 +1893,30 @@ func (r *ValkeyReconciler) exporter(valkey *hyperv1.Valkey) corev1.Container {
},
},
}
if !valkey.Spec.AnonymousAuth {
container.Env = append(container.Env, corev1.EnvVar{
Name: "VALKEY_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "password",
LocalObjectReference: corev1.LocalObjectReference{
Name: valkey.Name,
},
},
},
})
container.Env = append(container.Env, corev1.EnvVar{
Name: "REDIS_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "password",
LocalObjectReference: corev1.LocalObjectReference{
Name: valkey.Name,
},
},
},
})
}
if valkey.Spec.TLS {
container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
Name: "valkey-tls",
Expand Down Expand Up @@ -2100,7 +2123,7 @@ func (r *ValkeyReconciler) upsertStatefulSet(ctx context.Context, valkey *hyperv
Command: []string{
"valkey-server",
"/valkey/etc/valkey.conf",
"--requirepass", "$(VALKEY_PASSWORD)",
"--protected-mode", "no",
},
Env: []corev1.EnvVar{
{
Expand All @@ -2115,28 +2138,6 @@ func (r *ValkeyReconciler) upsertStatefulSet(ctx context.Context, valkey *hyperv
Name: "VALKEY_NODES",
Value: getNodeNames(valkey),
},
{
Name: "REDISCLI_AUTH",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "password",
LocalObjectReference: corev1.LocalObjectReference{
Name: valkey.Name,
},
},
},
},
{
Name: "VALKEY_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "password",
LocalObjectReference: corev1.LocalObjectReference{
Name: valkey.Name,
},
},
},
},
{
Name: "VALKEY_CLUSTER_PREFERRED_ENDPOINT_TYPE",
Value: endpointType,
Expand Down Expand Up @@ -2334,6 +2335,35 @@ func (r *ValkeyReconciler) upsertStatefulSet(ctx context.Context, valkey *hyperv
},
})
}
if !valkey.Spec.AnonymousAuth {
sts.Spec.Template.Spec.Containers[0].Env = append(sts.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
Name: "REDISCLI_AUTH",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "password",
LocalObjectReference: corev1.LocalObjectReference{
Name: valkey.Name,
},
},
},
})
sts.Spec.Template.Spec.Containers[0].Env = append(sts.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
Name: "VALKEY_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "password",
LocalObjectReference: corev1.LocalObjectReference{
Name: valkey.Name,
},
},
},
})
sts.Spec.Template.Spec.Containers[0].Command = []string{
"valkey-server",
"/valkey/etc/valkey.conf",
"--requirepass", "$(VALKEY_PASSWORD)",
}
}
if valkey.Spec.ExternalAccess != nil && valkey.Spec.ExternalAccess.Enabled {
sts.Spec.Template.Spec.Containers[0].Env = append(sts.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
Name: "VALKEY_EXTERNAL_ACCESS",
Expand Down

0 comments on commit 0c44d46

Please sign in to comment.