From 8f01dc226b2b142a52c445bd07fc70936ea60de7 Mon Sep 17 00:00:00 2001 From: Vittorio Rigamonti Date: Wed, 10 Apr 2024 11:59:20 +0200 Subject: [PATCH] Emit event and log warning if service is Cache. Fixes #2042 --- api/v1/infinispan_types.go | 10 ++++++++++ api/v1/infinispan_webhook.go | 7 +++++++ api/v1/zz_generated.deepcopy.go | 16 ++++++++++++++++ .../crd/bases/infinispan.org_infinispans.yaml | 7 +++++++ ...inispan-operator.clusterserviceversion.yaml | 3 +++ pkg/kubernetes/k8sutil.go | 6 +++++- .../infinispan/handler/manage/conditions.go | 18 ++++++++++++++++++ .../pipeline/infinispan/pipeline/pipeline.go | 2 ++ 8 files changed, 68 insertions(+), 1 deletion(-) diff --git a/api/v1/infinispan_types.go b/api/v1/infinispan_types.go index 60d0ad3c3..234346431 100644 --- a/api/v1/infinispan_types.go +++ b/api/v1/infinispan_types.go @@ -590,6 +590,10 @@ type InfinispanStatus struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Operand Status" Operand OperandStatus `json:"operand,omitempty"` + // The Operator status + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Operator Status" + Operator Operator `json:"operator,omitempty"` } type OperandPhase string @@ -631,6 +635,12 @@ const ( HotRodRollingStageCleanup HotRodRollingUpgradeStage = "HotRodRollingStageCleanup" ) +type Operator struct { + // The name of the pod reconciling this resource + // +optional + Pod string `json:"pod,omitempty"` +} + // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +operator-sdk:csv:customresourcedefinitions:displayName="Infinispan Cluster" diff --git a/api/v1/infinispan_webhook.go b/api/v1/infinispan_webhook.go index 39520f6e8..45ec854ac 100644 --- a/api/v1/infinispan_webhook.go +++ b/api/v1/infinispan_webhook.go @@ -222,6 +222,13 @@ func (i *Infinispan) ValidateUpdate(oldRuntimeObj runtime.Object) error { if old.Spec.Jmx != nil && old.Spec.Jmx.Enabled != i.Spec.Jmx.Enabled { allErrs = append(allErrs, field.Forbidden(field.NewPath("spec").Child("jmx"), "JMX configuration is immutable and cannot be updated after initial Infinispan creation")) } + + if old.IsDataGrid() && i.IsCache() { + errMsg := "ServiceType Cache configured is deprecated and will be removed in future releases. ServiceType DataGrid is recomended." + eventRec.Event(i, corev1.EventTypeWarning, "DeprecatedCacheService", errMsg) + log.Info(errMsg, "Request.Namespace", i.Namespace, "Request.Name", i.Name) + } + return errorListToError(i, allErrs) } diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index beffa7996..ba9cbe0d9 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -769,6 +769,7 @@ func (in *InfinispanStatus) DeepCopyInto(out *InfinispanStatus) { **out = **in } out.Operand = in.Operand + out.Operator = in.Operator } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfinispanStatus. @@ -826,6 +827,21 @@ func (in *OperandStatus) DeepCopy() *OperandStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Operator) DeepCopyInto(out *Operator) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Operator. +func (in *Operator) DeepCopy() *Operator { + if in == nil { + return nil + } + out := new(Operator) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SchedulingSpec) DeepCopyInto(out *SchedulingSpec) { *out = *in diff --git a/config/crd/bases/infinispan.org_infinispans.yaml b/config/crd/bases/infinispan.org_infinispans.yaml index 4f4ab1d7e..a302230f3 100644 --- a/config/crd/bases/infinispan.org_infinispans.yaml +++ b/config/crd/bases/infinispan.org_infinispans.yaml @@ -2332,6 +2332,13 @@ spec: description: The Operand version to be reconciled type: string type: object + operator: + description: The Operator status + properties: + pod: + description: The name of the pod reconciling this resource + type: string + type: object podStatus: description: The Pod's currently in the cluster properties: diff --git a/config/manifests/bases/infinispan-operator.clusterserviceversion.yaml b/config/manifests/bases/infinispan-operator.clusterserviceversion.yaml index 2f2d83318..3e0b626b4 100644 --- a/config/manifests/bases/infinispan-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/infinispan-operator.clusterserviceversion.yaml @@ -219,6 +219,9 @@ spec: - description: The Operand status displayName: Operand Status path: operand + - description: The Operator status + displayName: Operator Status + path: operator - description: The Pod's currently in the cluster displayName: Pod Status path: podStatus diff --git a/pkg/kubernetes/k8sutil.go b/pkg/kubernetes/k8sutil.go index b1536381e..57ad3da49 100644 --- a/pkg/kubernetes/k8sutil.go +++ b/pkg/kubernetes/k8sutil.go @@ -107,7 +107,7 @@ func GetPod(ctx context.Context, client crclient.Client, ns string) (*corev1.Pod if isRunModeLocal() { return nil, ErrRunLocal } - podName := os.Getenv(PodNameEnvVar) + podName := GetOperatorPodName() if podName == "" { return nil, fmt.Errorf("required env %s not set, please configure downward API", PodNameEnvVar) } @@ -132,6 +132,10 @@ func GetPod(ctx context.Context, client crclient.Client, ns string) (*corev1.Pod return pod, nil } +func GetOperatorPodName() string { + return os.Getenv(PodNameEnvVar) +} + func isRunModeLocal() bool { return os.Getenv(ForceRunModeEnv) == string(LocalRunMode) } diff --git a/pkg/reconcile/pipeline/infinispan/handler/manage/conditions.go b/pkg/reconcile/pipeline/infinispan/handler/manage/conditions.go index 0a4a8ef09..db576967b 100644 --- a/pkg/reconcile/pipeline/infinispan/handler/manage/conditions.go +++ b/pkg/reconcile/pipeline/infinispan/handler/manage/conditions.go @@ -41,6 +41,24 @@ func PreliminaryChecks(i *ispnv1.Infinispan, ctx pipeline.Context) { } } +func OperatorStatusChecks(i *ispnv1.Infinispan, ctx pipeline.Context) { + operatorPod := kube.GetOperatorPodName() + // Pod name is changed, means operator restarted + if i.Status.Operator.Pod != operatorPod { + if i.IsCache() { + errMsg := "ServiceType Cache configured is deprecated and will be removed in future releases. ServiceType DataGrid is recomended." + ctx.EventRecorder().Event(i, corev1.EventTypeWarning, "DeprecatedCacheService", errMsg) + ctx.Log().Info(errMsg) + } + ctx.Requeue( + ctx.UpdateInfinispan(func() { + i.Status.Operator.Pod = operatorPod + }), + ) + } + +} + func PodStatus(i *ispnv1.Infinispan, ctx pipeline.Context) { ss := &appsv1.StatefulSet{} if err := ctx.Resources().Load(i.GetStatefulSetName(), ss, pipeline.RetryOnErr); err != nil { diff --git a/pkg/reconcile/pipeline/infinispan/pipeline/pipeline.go b/pkg/reconcile/pipeline/infinispan/pipeline/pipeline.go index b4f78e5b5..3d31161bc 100644 --- a/pkg/reconcile/pipeline/infinispan/pipeline/pipeline.go +++ b/pkg/reconcile/pipeline/infinispan/pipeline/pipeline.go @@ -144,6 +144,8 @@ func (b *builder) Build() pipeline.Pipeline { handlers: make([]pipeline.HandlerFunc, 0), } + // Do operator status checks + handlers.Add(manage.OperatorStatusChecks) // Apply default meta before doing anything else handlers.Add(manage.InitialiseOperandVersion) handlers.Add(manage.PreliminaryChecks)