Repository: spotahome/redis-operator (go)

Issue:
Metadata of embedded volumeClaimTemplate not retained in statefulset
### Expected behaviour

Creating a cluster with the persistent-storage.yaml shall result in a statefulset being created

### Actual behaviour

Statefulset is not created as the pvc cannot be created. 
Error: 

```create Pod rfr-redisfailover-persistent-0 in StatefulSet rfr-redisfailover-persistent failed error: failed to create PVC -rfr-redisfailover-persistent-0: PersistentVolumeClaim "-rfr-redisfailover-persistent-0" is invalid: metadata.name: Invalid value: "-rfr-redisfailover-persistent-0": a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')```

Cause:  volumeclaimtemplate metadata of statefulset is empty

```
  volumeClaimTemplates:
    - kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        creationTimestamp: null
      spec:
        accessModes:
```

it seems kubernetes has changed the handling of embedded metadata. prometheus operator was struggling with a similar [issue](https://github.com/prometheus-operator/prometheus-operator/issues/3302)

### Steps to reproduce the behaviour

Deploy operator
kubectl apply -f persistent-storage.yaml

### Environment

How are the pieces configured?
* Redis Operator version: chart 3.1.3, app version: 1.1.0-rc.1
* Kubernetes version: k3s v1.22.5+k3s1
* Kubernetes configuration used: vanilla, rbac active


Pull request description:
Use embedded object in PVC to mantain metadata
Fixes #351 

Metadata for PVC is not being created causing failure for redisfailover with storage enabled. Use EmbeddedMetada Object to workaround the issue https://github.com/kubernetes-sigs/controller-tools/issues/385


Patch:
diff --git a/.gitignore b/.gitignore
index 1a8a47f4..692042ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 /bin
 .bash_history
+.vscode
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 093248fc..a2a218b3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,14 @@
 # Changelog
+##  [v1.1.0-rc.2] - X
+
+
+Update notes:
+
+Ensure you update the CRD definition since CRD is no longer managed by the operator:
+```
+kubectl create -f https://raw.githubusercontent.com/spotahome/redis-operator/master/example/redisfailover/basic.yaml
+```
+
 ## [v1.1.0-rc.1] - 2022-01-12
 
 ### Major Changes
diff --git a/Makefile b/Makefile
index 6500f307..3b6ae8ea 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION := v1.1.0-rc.1
+VERSION := v1.1.0-rc.2
 
 # Name of this service/application
 SERVICE_NAME := redis-operator
diff --git a/README.md b/README.md
index a606a198..e3c85663 100644
--- a/README.md
+++ b/README.md
@@ -10,21 +10,32 @@ Redis Operator creates/configures/manages redis-failovers atop Kubernetes.
 Redis Operator is meant to be run on Kubernetes 1.19+.
 All dependencies have been vendored, so there's no need to any additional download.
 
-### Versions deployed
+## Operator deployment on kubernetes
 
-The image versions deployed by the operator can be found on the [defaults file](api/redisfailover/v1/defaults.go).
+In order to create Redis failovers inside a Kubernetes cluster, the operator has to be deployed. It can be done with [deployment](example/operator) or with the provided [Helm chart](charts/redisoperator).
 
-## Images
+### Using the Helm chart
 
-### Redis Operator
+From the root folder of the project, execute the following:
 
-[![Redis Operator Image](https://quay.io/repository/spotahome/redis-operator/status "Redis Operator Image")](https://quay.io/repository/spotahome/redis-operator)
+```
+helm repo add redis-operator https://spotahome.github.io/redis-operator
+helm repo update
+helm install redis-operator redis-operator/redis-operator
+```
 
-## Operator deployment on kubernetes
+#### Update helm chart
 
-In order to create Redis failovers inside a Kubernetes cluster, the operator has to be deployed. It can be done with [deployment](example/operator) or with the provided [Helm chart](charts/redisoperator).
+Helm chart only manage the creation of CRD in the first install. In order to update the CRD you will need to apply directly.
 
-### Using a Deployment
+```
+kubectl apply -f https://raw.githubusercontent.com/spotahome/redis-operator/master/manifests/databases.spotahome.com_redisfailovers.yaml
+```
+
+```
+helm upgrade redis-operator redis-operator/redis-operator
+```
+### Using kubectl
 
 To create the operator, you can directly create it with kubectl:
 
@@ -34,16 +45,6 @@ kubectl create -f https://raw.githubusercontent.com/spotahome/redis-operator/mas
 
 This will create a deployment named `redisoperator`.
 
-### Using the Helm chart
-
-From the root folder of the project, execute the following:
-
-```
-helm repo add redis-operator https://spotahome.github.io/redis-operator
-helm repo update
-helm install redis-operator redis-operator/redis-operator
-```
-
 ## Usage
 
 Once the operator is deployed inside a Kubernetes cluster, a new API will be accesible, so you'll be able to create, update and delete redisfailovers.
@@ -211,13 +212,16 @@ This allows for ease of bootstrapping from an existing `RedisFailover` instance
 When `allowSentinels` is provided, the Operator will also create the defined Sentinel resources. These sentinels will be configured to point to the provided
 `bootstrapNode` as their monitored master.
 
+### Default versions
+
+The image versions deployed by the operator can be found on the [defaults file](api/redisfailover/v1/defaults.go).
 ## Cleanup
 
 ### Operator and CRD
 
 If you want to delete the operator from your Kubernetes cluster, the operator deployment should be deleted.
 
-Also, the CRD has to be deleted too:
+Also, the CRD has to be deleted. Deleting CRD automatically wil delete all redis failover custom resources and their managed resources:
 
 ```
 kubectl delete crd redisfailovers.databases.spotahome.com
@@ -231,6 +235,11 @@ Thanks to Kubernetes' `OwnerReference`, all the objects created from a redis-fai
 kubectl delete redisfailover <NAME>
 ```
 
+## Docker Images
+
+### Redis Operator
+
+[![Redis Operator Image](https://quay.io/repository/spotahome/redis-operator/status "Redis Operator Image")](https://quay.io/repository/spotahome/redis-operator)
 ## Documentation
 
 For the code documentation, you can lookup on the [GoDoc](https://godoc.org/github.com/spotahome/redis-operator).
diff --git a/api/redisfailover/v1/types.go b/api/redisfailover/v1/types.go
index 024fa934..650e682d 100644
--- a/api/redisfailover/v1/types.go
+++ b/api/redisfailover/v1/types.go
@@ -115,9 +115,56 @@ type SentinelExporter struct {
 
 // RedisStorage defines the structure used to store the Redis Data
 type RedisStorage struct {
-	KeepAfterDeletion     bool                          `json:"keepAfterDeletion,omitempty"`
-	EmptyDir              *corev1.EmptyDirVolumeSource  `json:"emptyDir,omitempty"`
-	PersistentVolumeClaim *corev1.PersistentVolumeClaim `json:"persistentVolumeClaim,omitempty"`
+	KeepAfterDeletion     bool                           `json:"keepAfterDeletion,omitempty"`
+	EmptyDir              *corev1.EmptyDirVolumeSource   `json:"emptyDir,omitempty"`
+	PersistentVolumeClaim *EmbeddedPersistentVolumeClaim `json:"persistentVolumeClaim,omitempty"`
+}
+
+// EmbeddedPersistentVolumeClaim is an embedded version of k8s.io/api/core/v1.PersistentVolumeClaim.
+// It contains TypeMeta and a reduced ObjectMeta.
+type EmbeddedPersistentVolumeClaim struct {
+	metav1.TypeMeta `json:",inline"`
+
+	// EmbeddedMetadata contains metadata relevant to an EmbeddedResource.
+	EmbeddedObjectMetadata `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
+
+	// Spec defines the desired characteristics of a volume requested by a pod author.
+	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+	// +optional
+	Spec corev1.PersistentVolumeClaimSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
+
+	// Status represents the current information/status of a persistent volume claim.
+	// Read-only.
+	// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
+	// +optional
+	Status corev1.PersistentVolumeClaimStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
+}
+
+// EmbeddedObjectMetadata contains a subset of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta
+// Only fields which are relevant to embedded resources are included.
+type EmbeddedObjectMetadata struct {
+	// Name must be unique within a namespace. Is required when creating resources, although
+	// some resources may allow a client to request the generation of an appropriate name
+	// automatically. Name is primarily intended for creation idempotence and configuration
+	// definition.
+	// Cannot be updated.
+	// More info: http://kubernetes.io/docs/user-guide/identifiers#names
+	// +optional
+	Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`
+
+	// Map of string keys and values that can be used to organize and categorize
+	// (scope and select) objects. May match selectors of replication controllers
+	// and services.
+	// More info: http://kubernetes.io/docs/user-guide/labels
+	// +optional
+	Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"`
+
+	// Annotations is an unstructured key value map stored with a resource that may be
+	// set by external tools to store and retrieve arbitrary metadata. They are not
+	// queryable and should be preserved when modifying objects.
+	// More info: http://kubernetes.io/docs/user-guide/annotations
+	// +optional
+	Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"`
 }
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
diff --git a/api/redisfailover/v1/zz_generated.deepcopy.go b/api/redisfailover/v1/zz_generated.deepcopy.go
index f52f3119..9e388d0d 100644
--- a/api/redisfailover/v1/zz_generated.deepcopy.go
+++ b/api/redisfailover/v1/zz_generated.deepcopy.go
@@ -57,6 +57,56 @@ func (in *BootstrapSettings) DeepCopy() *BootstrapSettings {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EmbeddedObjectMetadata) DeepCopyInto(out *EmbeddedObjectMetadata) {
+	*out = *in
+	if in.Labels != nil {
+		in, out := &in.Labels, &out.Labels
+		*out = make(map[string]string, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	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
+		}
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmbeddedObjectMetadata.
+func (in *EmbeddedObjectMetadata) DeepCopy() *EmbeddedObjectMetadata {
+	if in == nil {
+		return nil
+	}
+	out := new(EmbeddedObjectMetadata)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EmbeddedPersistentVolumeClaim) DeepCopyInto(out *EmbeddedPersistentVolumeClaim) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.EmbeddedObjectMetadata.DeepCopyInto(&out.EmbeddedObjectMetadata)
+	in.Spec.DeepCopyInto(&out.Spec)
+	in.Status.DeepCopyInto(&out.Status)
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmbeddedPersistentVolumeClaim.
+func (in *EmbeddedPersistentVolumeClaim) DeepCopy() *EmbeddedPersistentVolumeClaim {
+	if in == nil {
+		return nil
+	}
+	out := new(EmbeddedPersistentVolumeClaim)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *RedisCommandRename) DeepCopyInto(out *RedisCommandRename) {
 	*out = *in
@@ -277,7 +327,7 @@ func (in *RedisStorage) DeepCopyInto(out *RedisStorage) {
 	}
 	if in.PersistentVolumeClaim != nil {
 		in, out := &in.PersistentVolumeClaim, &out.PersistentVolumeClaim
-		*out = new(corev1.PersistentVolumeClaim)
+		*out = new(EmbeddedPersistentVolumeClaim)
 		(*in).DeepCopyInto(*out)
 	}
 	return
diff --git a/charts/redisoperator/Chart.yaml b/charts/redisoperator/Chart.yaml
index 733690d7..3ffa44a2 100644
--- a/charts/redisoperator/Chart.yaml
+++ b/charts/redisoperator/Chart.yaml
@@ -4,7 +4,7 @@ appVersion: 1.1.0-rc.1
 apiVersion: v1
 description: A Helm chart for the Spotahome Redis Operator
 name: redis-operator
-version: 3.1.3
+version: 3.1.4
 home: https://github.com/spotahome/redis-operator
 keywords:
   - "golang"
diff --git a/charts/redisoperator/crds/databases.spotahome.com_redisfailovers.yaml b/charts/redisoperator/crds/databases.spotahome.com_redisfailovers.yaml
index d46d6924..a2e138b7 100644
--- a/charts/redisoperator/crds/databases.spotahome.com_redisfailovers.yaml
+++ b/charts/redisoperator/crds/databases.spotahome.com_redisfailovers.yaml
@@ -1354,8 +1354,9 @@ spec:
                       keepAfterDeletion:
                         type: boolean
                       persistentVolumeClaim:
-                        description: PersistentVolumeClaim is a user's request for
-                          and claim to a persistent volume
+                        description: EmbeddedPersistentVolumeClaim is an embedded
+                          version of k8s.io/api/core/v1.PersistentVolumeClaim. It
+                          contains TypeMeta and a reduced ObjectMeta.
                         properties:
                           apiVersion:
                             description: 'APIVersion defines the versioned schema
@@ -1370,8 +1371,34 @@ spec:
                               Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
                             type: string
                           metadata:
-                            description: 'Standard object''s metadata. More info:
-                              https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata'
+                            description: EmbeddedMetadata contains metadata relevant
+                              to an EmbeddedResource.
+                            properties:
+                              annotations:
+                                additionalProperties:
+                                  type: string
+                                description: 'Annotations is an unstructured key value
+                                  map stored with a resource that may be set by external
+                                  tools to store and retrieve arbitrary metadata.
+                                  They are not queryable and should be preserved when
+                                  modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations'
+                                type: object
+                              labels:
+                                additionalProperties:
+                                  type: string
+                                description: 'Map of string keys and values that can
+                                  be used to organize and categorize (scope and select)
+                                  objects. May match selectors of replication controllers
+                                  and services. More info: http://kubernetes.io/docs/user-guide/labels'
+                                type: object
+                              name:
+                                description: 'Name must be unique within a namespace.
+                                  Is required when creating resources, although some
+                                  resources may allow a client to request the generation
+                                  of an appropriate name automatically. Name is primarily
+                                  intended for creation idempotence and configuration
+                                  definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names'
+                                type: string
                             type: object
                           spec:
                             description: 'Spec defines the desired characteristics
diff --git a/manifests/databases.spotahome.com_redisfailovers.yaml b/manifests/databases.spotahome.com_redisfailovers.yaml
index d46d6924..a2e138b7 100644
--- a/manifests/databases.spotahome.com_redisfailovers.yaml
+++ b/manifests/databases.spotahome.com_redisfailovers.yaml
@@ -1354,8 +1354,9 @@ spec:
                       keepAfterDeletion:
                         type: boolean
                       persistentVolumeClaim:
-                        description: PersistentVolumeClaim is a user's request for
-                          and claim to a persistent volume
+                        description: EmbeddedPersistentVolumeClaim is an embedded
+                          version of k8s.io/api/core/v1.PersistentVolumeClaim. It
+                          contains TypeMeta and a reduced ObjectMeta.
                         properties:
                           apiVersion:
                             description: 'APIVersion defines the versioned schema
@@ -1370,8 +1371,34 @@ spec:
                               Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
                             type: string
                           metadata:
-                            description: 'Standard object''s metadata. More info:
-                              https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata'
+                            description: EmbeddedMetadata contains metadata relevant
+                              to an EmbeddedResource.
+                            properties:
+                              annotations:
+                                additionalProperties:
+                                  type: string
+                                description: 'Annotations is an unstructured key value
+                                  map stored with a resource that may be set by external
+                                  tools to store and retrieve arbitrary metadata.
+                                  They are not queryable and should be preserved when
+                                  modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations'
+                                type: object
+                              labels:
+                                additionalProperties:
+                                  type: string
+                                description: 'Map of string keys and values that can
+                                  be used to organize and categorize (scope and select)
+                                  objects. May match selectors of replication controllers
+                                  and services. More info: http://kubernetes.io/docs/user-guide/labels'
+                                type: object
+                              name:
+                                description: 'Name must be unique within a namespace.
+                                  Is required when creating resources, although some
+                                  resources may allow a client to request the generation
+                                  of an appropriate name automatically. Name is primarily
+                                  intended for creation idempotence and configuration
+                                  definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names'
+                                type: string
                             type: object
                           spec:
                             description: 'Spec defines the desired characteristics
diff --git a/operator/redisfailover/service/generator.go b/operator/redisfailover/service/generator.go
index b5493410..24b8a614 100644
--- a/operator/redisfailover/service/generator.go
+++ b/operator/redisfailover/service/generator.go
@@ -6,7 +6,6 @@ import (
 	"bytes"
 
 	appsv1 "k8s.io/api/apps/v1"
-	v1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	policyv1 "k8s.io/api/policy/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
@@ -263,9 +262,9 @@ func generateRedisStatefulSet(rf *redisfailoverv1.RedisFailover, labels map[stri
 			ServiceName: name,
 			Replicas:    &rf.Spec.Redis.Replicas,
 			UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
-				Type: v1.OnDeleteStatefulSetStrategyType,
+				Type: appsv1.OnDeleteStatefulSetStrategyType,
 			},
-			PodManagementPolicy: v1.ParallelPodManagement,
+			PodManagementPolicy: appsv1.ParallelPodManagement,
 			Selector: &metav1.LabelSelector{
 				MatchLabels: selectorLabels,
 			},
@@ -340,12 +339,26 @@ func generateRedisStatefulSet(rf *redisfailoverv1.RedisFailover, labels map[stri
 	}
 
 	if rf.Spec.Redis.Storage.PersistentVolumeClaim != nil {
+		pvc := corev1.PersistentVolumeClaim{
+			TypeMeta: metav1.TypeMeta{
+				APIVersion: "v1",
+				Kind:       "PersistentVolumeClaim",
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name:              rf.Spec.Redis.Storage.PersistentVolumeClaim.EmbeddedObjectMetadata.Name,
+				Labels:            rf.Spec.Redis.Storage.PersistentVolumeClaim.EmbeddedObjectMetadata.Labels,
+				Annotations:       rf.Spec.Redis.Storage.PersistentVolumeClaim.EmbeddedObjectMetadata.Annotations,
+				CreationTimestamp: metav1.Time{},
+			},
+			Spec:   rf.Spec.Redis.Storage.PersistentVolumeClaim.Spec,
+			Status: rf.Spec.Redis.Storage.PersistentVolumeClaim.Status,
+		}
 		if !rf.Spec.Redis.Storage.KeepAfterDeletion {
 			// Set an owner reference so the persistent volumes are deleted when the RF is
-			rf.Spec.Redis.Storage.PersistentVolumeClaim.OwnerReferences = ownerRefs
+			pvc.OwnerReferences = ownerRefs
 		}
 		ss.Spec.VolumeClaimTemplates = []corev1.PersistentVolumeClaim{
-			*rf.Spec.Redis.Storage.PersistentVolumeClaim,
+			pvc,
 		}
 	}
 


Test patch:
diff --git a/operator/redisfailover/service/generator_test.go b/operator/redisfailover/service/generator_test.go
index e5d51c88..eada6f7a 100644
--- a/operator/redisfailover/service/generator_test.go
+++ b/operator/redisfailover/service/generator_test.go
@@ -248,6 +248,10 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
 					},
 					VolumeClaimTemplates: []corev1.PersistentVolumeClaim{
 						{
+							TypeMeta: metav1.TypeMeta{
+								Kind:       "PersistentVolumeClaim",
+								APIVersion: "v1",
+							},
 							ObjectMeta: metav1.ObjectMeta{
 								Name: "pvc-data",
 							},
@@ -266,8 +270,8 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
 				},
 			},
 			rfRedisStorage: redisfailoverv1.RedisStorage{
-				PersistentVolumeClaim: &corev1.PersistentVolumeClaim{
-					ObjectMeta: metav1.ObjectMeta{
+				PersistentVolumeClaim: &redisfailoverv1.EmbeddedPersistentVolumeClaim{
+					EmbeddedObjectMetadata: redisfailoverv1.EmbeddedObjectMetadata{
 						Name: "pvc-data",
 					},
 					Spec: corev1.PersistentVolumeClaimSpec{
@@ -354,6 +358,10 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
 					},
 					VolumeClaimTemplates: []corev1.PersistentVolumeClaim{
 						{
+							TypeMeta: metav1.TypeMeta{
+								Kind:       "PersistentVolumeClaim",
+								APIVersion: "v1",
+							},
 							ObjectMeta: metav1.ObjectMeta{
 								Name: "pvc-data",
 								OwnerReferences: []metav1.OwnerReference{
@@ -377,8 +385,8 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
 				},
 			},
 			rfRedisStorage: redisfailoverv1.RedisStorage{
-				PersistentVolumeClaim: &corev1.PersistentVolumeClaim{
-					ObjectMeta: metav1.ObjectMeta{
+				PersistentVolumeClaim: &redisfailoverv1.EmbeddedPersistentVolumeClaim{
+					EmbeddedObjectMetadata: redisfailoverv1.EmbeddedObjectMetadata{
 						Name: "pvc-data",
 					},
 					Spec: corev1.PersistentVolumeClaimSpec{
@@ -465,6 +473,10 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
 					},
 					VolumeClaimTemplates: []corev1.PersistentVolumeClaim{
 						{
+							TypeMeta: metav1.TypeMeta{
+								Kind:       "PersistentVolumeClaim",
+								APIVersion: "v1",
+							},
 							ObjectMeta: metav1.ObjectMeta{
 								Name: "pvc-data",
 							},
@@ -484,8 +496,8 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) {
 			},
 			rfRedisStorage: redisfailoverv1.RedisStorage{
 				KeepAfterDeletion: true,
-				PersistentVolumeClaim: &corev1.PersistentVolumeClaim{
-					ObjectMeta: metav1.ObjectMeta{
+				PersistentVolumeClaim: &redisfailoverv1.EmbeddedPersistentVolumeClaim{
+					EmbeddedObjectMetadata: redisfailoverv1.EmbeddedObjectMetadata{
 						Name: "pvc-data",
 					},
 					Spec: corev1.PersistentVolumeClaimSpec{