diff --git a/api/v1/valkey_types.go b/api/v1/valkey_types.go index c4a785d..fe8bae0 100644 --- a/api/v1/valkey_types.go +++ b/api/v1/valkey_types.go @@ -75,6 +75,9 @@ type ValkeySpec struct { // External access configuration ExternalAccess *ExternalAccess `json:"externalAccess,omitempty"` + + // Service Password + ServicePassword *corev1.SecretKeySelector `json:"servicePassword,omitempty"` } // ExternalAccess defines the external access configuration diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 29143da..cc115cd 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -189,6 +189,11 @@ func (in *ValkeySpec) DeepCopyInto(out *ValkeySpec) { *out = new(ExternalAccess) (*in).DeepCopyInto(*out) } + if in.ServicePassword != nil { + in, out := &in.ServicePassword, &out.ServicePassword + *out = new(corev1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValkeySpec. diff --git a/config/crd/bases/hyperspike.io_valkeys.yaml b/config/crd/bases/hyperspike.io_valkeys.yaml index e803555..4a79d43 100644 --- a/config/crd/bases/hyperspike.io_valkeys.yaml +++ b/config/crd/bases/hyperspike.io_valkeys.yaml @@ -286,6 +286,29 @@ spec: More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object + servicePassword: + description: Service Password + properties: + key: + description: The key of the secret to select from. Must be a + valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic storage: description: Persistent volume claim properties: diff --git a/internal/controller/valkey_controller.go b/internal/controller/valkey_controller.go index 06ba1c5..3d4a3fd 100644 --- a/internal/controller/valkey_controller.go +++ b/internal/controller/valkey_controller.go @@ -1185,9 +1185,31 @@ func (r *ValkeyReconciler) upsertCertificate(ctx context.Context, valkey *hyperv return nil } +func (r *ValkeyReconciler) getServicePassword(ctx context.Context, valkey *hyperv1.Valkey) (string, error) { + logger := log.FromContext(ctx) + + secret := &corev1.Secret{} + err := r.Get(ctx, types.NamespacedName{Namespace: valkey.Namespace, Name: valkey.Spec.ServicePassword.Name}, secret) + if err != nil { + logger.Error(err, "failed to fetch secret", "name", valkey.Spec.ServicePassword.Name) + return "", err + } + if secret.Data == nil { + return "", fmt.Errorf("secret %s/%s is empty", valkey.Namespace, valkey.Spec.ServicePassword.Name) + } + if secret.Data[valkey.Spec.ServicePassword.Key] == nil { + return "", fmt.Errorf("key %s is empty in secret %s/%s", valkey.Spec.ServicePassword.Key, valkey.Namespace, valkey.Spec.ServicePassword.Name) + } + return string(secret.Data[valkey.Spec.ServicePassword.Key]), nil +} + func (r *ValkeyReconciler) upsertSecret(ctx context.Context, valkey *hyperv1.Valkey, once bool) (string, error) { logger := log.FromContext(ctx) + if valkey.Spec.ServicePassword != nil { + return r.getServicePassword(ctx, valkey) + } + logger.Info("upserting secret") rs, err := randString(16) if err != nil {