diff --git a/api/status/redis-replication_status.go b/api/status/redis-replication_status.go new file mode 100644 index 000000000..9c6d1db81 --- /dev/null +++ b/api/status/redis-replication_status.go @@ -0,0 +1,17 @@ +package status + +type RedisReplicationState string + +const ( + ReadyReplicationReason string = "RedisReplication is ready" + InitializingReplicationReason string = "RedisReplication is initializing" + BootstrapReplicationReason string = "RedisReplication is bootstrapping" +) + +// Status Field of the Redis Replication +const ( + RedisReplicationReady RedisReplicationState = "Ready" + RedisReplicationInitializing RedisReplicationState = "Initializing" + RedisReplicationBootstrap RedisReplicationState = "Bootstrap" + // RedisReplicationFailed RedisReplicationState = "Failed" +) diff --git a/api/status/redis-senitnel_status.go b/api/status/redis-senitnel_status.go new file mode 100644 index 000000000..7d52ce72f --- /dev/null +++ b/api/status/redis-senitnel_status.go @@ -0,0 +1,16 @@ +package status + +type RedisSentinelState string + +const ( + ReadySentinelReason string = "RedisSenitnel is ready" + InitializingSentinelReason string = "RedisSentinel is initializing" + BootstrapSentinelReason string = "RedisSenitnel is bootstrapping" +) + +// Status Field of the Redis Senitnel +const ( + RedisSenitnelReady RedisSentinelState = "Ready" + RedisSentinelInitializing RedisSentinelState = "Initializing" + RedisSentinelBootstrap RedisSentinelState = "Bootstrap" +) diff --git a/api/status/redis-standalone_status.go b/api/status/redis-standalone_status.go new file mode 100644 index 000000000..f7441c726 --- /dev/null +++ b/api/status/redis-standalone_status.go @@ -0,0 +1,15 @@ +package status + +type RedisStandaloneState string + +const ( + ReadyStandaloneReason string = "RedisStandalone is ready" + InitializingStandaloneReason string = "RedisStandalone is initializing" +) + +// Status Field of the Redis Standalone +const ( + RedisStandaloneReady RedisStandaloneState = "Ready" + RedisStandaloneInitializing RedisStandaloneState = "Initializing" + // RedisStandaloneFailed RedisStandaloneState = "Failed" +) diff --git a/api/v1beta2/redis_types.go b/api/v1beta2/redis_types.go index 091cb19ea..33d06dd1a 100644 --- a/api/v1beta2/redis_types.go +++ b/api/v1beta2/redis_types.go @@ -17,6 +17,7 @@ limitations under the License. package v1beta2 import ( + status "github.com/OT-CONTAINER-KIT/redis-operator/api/status" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -51,6 +52,8 @@ type RedisSpec struct { // RedisStatus defines the observed state of Redis type RedisStatus struct { + State status.RedisStandaloneState `json:"state,omitempty"` + Reason string `json:"reason,omitempty"` } // +kubebuilder:object:root=true diff --git a/api/v1beta2/redisreplication_types.go b/api/v1beta2/redisreplication_types.go index cb04c169d..d7901d058 100644 --- a/api/v1beta2/redisreplication_types.go +++ b/api/v1beta2/redisreplication_types.go @@ -1,6 +1,7 @@ package v1beta2 import ( + "github.com/OT-CONTAINER-KIT/redis-operator/api/status" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -37,6 +38,8 @@ func (cr *RedisReplicationSpec) GetReplicationCounts(t string) int32 { // RedisStatus defines the observed state of Redis type RedisReplicationStatus struct { + State status.RedisReplicationState `json:"state,omitempty"` + Reason string `json:"reason,omitempty"` } // +kubebuilder:object:root=true diff --git a/api/v1beta2/redissentinel_types.go b/api/v1beta2/redissentinel_types.go index b40ee6e10..45d8d3933 100644 --- a/api/v1beta2/redissentinel_types.go +++ b/api/v1beta2/redissentinel_types.go @@ -2,6 +2,7 @@ package v1beta2 import ( common "github.com/OT-CONTAINER-KIT/redis-operator/api" + status "github.com/OT-CONTAINER-KIT/redis-operator/api/status" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -42,6 +43,8 @@ type RedisSentinelConfig struct { } type RedisSentinelStatus struct { + State status.RedisSentinelState `json:"state,omitempty"` + Reason string `json:"reason,omitempty"` } // +kubebuilder:object:root=true diff --git a/config/crd/bases/redis.redis.opstreelabs.in_redis.yaml b/config/crd/bases/redis.redis.opstreelabs.in_redis.yaml index 4032fa9cf..4b5e01ce9 100644 --- a/config/crd/bases/redis.redis.opstreelabs.in_redis.yaml +++ b/config/crd/bases/redis.redis.opstreelabs.in_redis.yaml @@ -4563,6 +4563,110 @@ spec: type: array type: object type: object + env: + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array initContainer: description: InitContainer for each Redis pods properties: @@ -7597,6 +7701,11 @@ spec: type: object status: description: RedisStatus defines the observed state of Redis + properties: + reason: + type: string + state: + type: string type: object required: - spec diff --git a/config/crd/bases/redis.redis.opstreelabs.in_redisreplications.yaml b/config/crd/bases/redis.redis.opstreelabs.in_redisreplications.yaml index 11f780c4f..55771c1e5 100644 --- a/config/crd/bases/redis.redis.opstreelabs.in_redisreplications.yaml +++ b/config/crd/bases/redis.redis.opstreelabs.in_redisreplications.yaml @@ -4568,6 +4568,110 @@ spec: clusterSize: format: int32 type: integer + env: + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array initContainer: description: InitContainer for each Redis pods properties: @@ -7603,6 +7707,11 @@ spec: type: object status: description: RedisStatus defines the observed state of Redis + properties: + reason: + type: string + state: + type: string type: object required: - spec diff --git a/config/crd/bases/redis.redis.opstreelabs.in_redissentinels.yaml b/config/crd/bases/redis.redis.opstreelabs.in_redissentinels.yaml index 7a273ffa4..24c2d8c59 100644 --- a/config/crd/bases/redis.redis.opstreelabs.in_redissentinels.yaml +++ b/config/crd/bases/redis.redis.opstreelabs.in_redissentinels.yaml @@ -2452,6 +2452,110 @@ spec: format: int32 minimum: 1 type: integer + env: + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array initContainer: description: InitContainer for each Redis pods properties: @@ -3587,6 +3691,11 @@ spec: - kubernetesConfig type: object status: + properties: + reason: + type: string + state: + type: string type: object required: - spec diff --git a/controllers/redis_controller.go b/controllers/redis_controller.go index a1d8be2b7..2bed2ee5c 100644 --- a/controllers/redis_controller.go +++ b/controllers/redis_controller.go @@ -20,6 +20,7 @@ import ( "context" "time" + "github.com/OT-CONTAINER-KIT/redis-operator/api/status" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" "github.com/OT-CONTAINER-KIT/redis-operator/k8sutils" "github.com/go-logr/logr" @@ -61,6 +62,13 @@ func (r *RedisReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl return ctrl.Result{}, err } + if instance.Status.State != status.RedisStandaloneReady { + err = k8sutils.UpdateRedisStandaloneStatus(instance, status.RedisStandaloneInitializing, status.InitializingStandaloneReason) + if err != nil { + return ctrl.Result{RequeueAfter: time.Second * 10}, err + } + } + err = k8sutils.CreateStandaloneRedis(instance) if err != nil { return ctrl.Result{}, err @@ -70,6 +78,13 @@ func (r *RedisReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl return ctrl.Result{}, err } + if instance.Status.State != status.RedisStandaloneReady && k8sutils.CheckRedisStandaloneReady(instance) { + err = k8sutils.UpdateRedisStandaloneStatus(instance, status.RedisStandaloneReady, status.ReadyStandaloneReason) + if err != nil { + return ctrl.Result{RequeueAfter: time.Second * 10}, err + } + } + reqLogger.Info("Will reconcile redis operator in again 10 seconds") return ctrl.Result{RequeueAfter: time.Second * 10}, nil } diff --git a/controllers/redisreplication_controller.go b/controllers/redisreplication_controller.go index d0e4f30e8..b4886c7d9 100644 --- a/controllers/redisreplication_controller.go +++ b/controllers/redisreplication_controller.go @@ -5,6 +5,7 @@ import ( "strconv" "time" + "github.com/OT-CONTAINER-KIT/redis-operator/api/status" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" "github.com/OT-CONTAINER-KIT/redis-operator/k8sutils" "github.com/go-logr/logr" @@ -52,6 +53,13 @@ func (r *RedisReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Req return ctrl.Result{}, err } + if instance.Status.State != status.RedisReplicationReady { + err = k8sutils.UpdateRedisReplicationStatus(instance, status.RedisReplicationInitializing, status.InitializingReplicationReason) + if err != nil { + return ctrl.Result{RequeueAfter: time.Second * 10}, err + } + } + err = k8sutils.CreateReplicationRedis(instance) if err != nil { return ctrl.Result{}, err @@ -76,6 +84,13 @@ func (r *RedisReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Req reqLogger.Info("Creating redis replication by executing replication creation commands", "Replication.Ready", strconv.Itoa(int(redisReplicationInfo.Status.ReadyReplicas))) + if instance.Status.State != status.RedisReplicationInitializing { + err = k8sutils.UpdateRedisReplicationStatus(instance, status.RedisReplicationBootstrap, status.BootstrapClusterReason) + if err != nil { + return ctrl.Result{RequeueAfter: time.Second * 10}, err + } + } + if len(k8sutils.GetRedisNodesByRole(instance, "master")) > int(leaderReplicas) { masterNodes := k8sutils.GetRedisNodesByRole(instance, "master") @@ -87,6 +102,13 @@ func (r *RedisReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Req } + if instance.Status.State != status.RedisReplicationReady && k8sutils.CheckRedisReplicationReady(instance) { + err = k8sutils.UpdateRedisReplicationStatus(instance, status.RedisReplicationReady, status.ReadyReplicationReason) + if err != nil { + return ctrl.Result{RequeueAfter: time.Second * 10}, err + } + } + reqLogger.Info("Will reconcile redis operator in again 10 seconds") return ctrl.Result{RequeueAfter: time.Second * 10}, nil diff --git a/controllers/redissentinel_controller.go b/controllers/redissentinel_controller.go index b4b0b02bf..1304f6866 100644 --- a/controllers/redissentinel_controller.go +++ b/controllers/redissentinel_controller.go @@ -4,6 +4,7 @@ import ( "context" "time" + "github.com/OT-CONTAINER-KIT/redis-operator/api/status" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" "github.com/OT-CONTAINER-KIT/redis-operator/k8sutils" "github.com/go-logr/logr" @@ -50,6 +51,13 @@ func (r *RedisSentinelReconciler) Reconcile(ctx context.Context, req ctrl.Reques return ctrl.Result{RequeueAfter: time.Second * 60}, err } + if instance.Status.State != status.RedisSenitnelReady { + err = k8sutils.UpdateRedisSentinelStatus(instance, status.RedisSentinelInitializing, status.InitializingSentinelReason) + if err != nil { + return ctrl.Result{RequeueAfter: time.Second * 10}, err + } + } + // Create Redis Sentinel err = k8sutils.CreateRedisSentinel(instance) if err != nil { @@ -67,6 +75,13 @@ func (r *RedisSentinelReconciler) Reconcile(ctx context.Context, req ctrl.Reques return ctrl.Result{}, err } + if instance.Status.State != status.RedisSenitnelReady && k8sutils.CheckRedisSentinelReady(instance) { + err = k8sutils.UpdateRedisSentinelStatus(instance, status.RedisSenitnelReady, status.ReadySentinelReason) + if err != nil { + return ctrl.Result{RequeueAfter: time.Second * 10}, err + } + } + reqLogger.Info("Will reconcile redis operator in again 10 seconds") return ctrl.Result{RequeueAfter: time.Second * 10}, nil } diff --git a/k8sutils/redis.go b/k8sutils/redis.go index d9a77abfa..fb341f6cc 100644 --- a/k8sutils/redis.go +++ b/k8sutils/redis.go @@ -578,3 +578,59 @@ func CreateMasterSlaveReplication(cr *redisv1beta2.RedisReplication, masterPods return nil } + +func CheckRedisStandaloneReady(cr *redisv1beta2.Redis) bool { + objName := cr.Name + objNamespace := cr.Namespace + client := generateK8sClient() + sts, err := client.AppsV1().StatefulSets(objNamespace).Get(context.Background(), objName, metav1.GetOptions{}) + if err != nil { + // Handle error + return false + } + + // Check if the pod status is Running and all containers are ready + desiredReplica := 1 + + if sts.Status.ReadyReplicas == int32(desiredReplica) { + return true + } + + return false + +} + +func CheckRedisSentinelReady(cr *redisv1beta2.RedisSentinel) bool { + objName := cr.Name + objNamespace := cr.Namespace + client := generateK8sClient() + sts, err := client.AppsV1().StatefulSets(objNamespace).Get(context.Background(), objName, metav1.GetOptions{}) + if err != nil { + // Handle error + return false + } + + if sts.Status.ReadyReplicas == *cr.Spec.Size { + return true + } + + return false + +} + +func CheckRedisReplicationReady(cr *redisv1beta2.RedisReplication) bool { + objName := cr.Name + objNamespace := cr.Namespace + client := generateK8sClient() + sts, err := client.AppsV1().StatefulSets(objNamespace).Get(context.Background(), objName, metav1.GetOptions{}) + if err != nil { + // Handle error + return false + } + + if sts.Status.ReadyReplicas == *cr.Spec.Size { + return true + } + + return false +} diff --git a/k8sutils/status.go b/k8sutils/status.go index 1232b2384..179b9d5cd 100644 --- a/k8sutils/status.go +++ b/k8sutils/status.go @@ -46,3 +46,81 @@ func UpdateRedisClusterStatus(cr *redisv1beta2.RedisCluster, status status.Redis } return nil } + +func UpdateRedisStandaloneStatus(cr *redisv1beta2.Redis, status status.RedisStandaloneState, resaon string) error { + logger := statusLogger(cr.Namespace, cr.Name) + cr.Status.State = status + cr.Status.Reason = resaon + + client := generateK8sDynamicClient() + gvr := schema.GroupVersionResource{ + Group: "redis.redis.opstreelabs.in", + Version: "v1beta2", + Resource: "redis", + } + unstructuredObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(cr) + if err != nil { + logger.Error(err, "Failed to convert CR to unstructured object") + return err + } + unstructuredRedisStandalone := &unstructured.Unstructured{Object: unstructuredObj} + + _, err = client.Resource(gvr).Namespace(cr.Namespace).UpdateStatus(context.TODO(), unstructuredRedisStandalone, metav1.UpdateOptions{}) + if err != nil { + logger.Error(err, "Failed to update status") + return err + } + return nil +} + +func UpdateRedisSentinelStatus(cr *redisv1beta2.RedisSentinel, status status.RedisSentinelState, resaon string) error { + logger := statusLogger(cr.Namespace, cr.Name) + cr.Status.State = status + cr.Status.Reason = resaon + + client := generateK8sDynamicClient() + gvr := schema.GroupVersionResource{ + Group: "redis.redis.opstreelabs.in", + Version: "v1beta2", + Resource: "redissentinels", + } + unstructuredObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(cr) + if err != nil { + logger.Error(err, "Failed to convert CR to unstructured object") + return err + } + unstructuredRedisSentinel := &unstructured.Unstructured{Object: unstructuredObj} + + _, err = client.Resource(gvr).Namespace(cr.Namespace).UpdateStatus(context.TODO(), unstructuredRedisSentinel, metav1.UpdateOptions{}) + if err != nil { + logger.Error(err, "Failed to update status") + return err + } + return nil +} + +func UpdateRedisReplicationStatus(cr *redisv1beta2.RedisReplication, status status.RedisReplicationState, resaon string) error { + logger := statusLogger(cr.Namespace, cr.Name) + cr.Status.State = status + cr.Status.Reason = resaon + + client := generateK8sDynamicClient() + gvr := schema.GroupVersionResource{ + Group: "redis.redis.opstreelabs.in", + Version: "v1beta2", + Resource: "redisreplications", + } + unstructuredObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(cr) + if err != nil { + logger.Error(err, "Failed to convert CR to unstructured object") + return err + } + unstructuredRedisReplication := &unstructured.Unstructured{Object: unstructuredObj} + + _, err = client.Resource(gvr).Namespace(cr.Namespace).UpdateStatus(context.TODO(), unstructuredRedisReplication, metav1.UpdateOptions{}) + if err != nil { + logger.Error(err, "Failed to update status") + return err + } + return nil +}