From 35adf2981781b27c8917e779fde218f7daf99c01 Mon Sep 17 00:00:00 2001 From: Rory Z <16801068+Rory-Z@users.noreply.github.com> Date: Sat, 29 Jul 2023 23:33:47 +0800 Subject: [PATCH] fix(v2beta1): fix status machine error --- controllers/apps/v2beta1/status_machine.go | 17 +- .../apps/v2beta1/status_machine_test.go | 335 ------------------ controllers/apps/v2beta1/suite_test.go | 2 +- .../apps/v2beta1/update_emqx_status.go | 2 +- 4 files changed, 14 insertions(+), 342 deletions(-) delete mode 100644 controllers/apps/v2beta1/status_machine_test.go diff --git a/controllers/apps/v2beta1/status_machine.go b/controllers/apps/v2beta1/status_machine.go index ca6a14dff..66bc5348b 100644 --- a/controllers/apps/v2beta1/status_machine.go +++ b/controllers/apps/v2beta1/status_machine.go @@ -17,8 +17,11 @@ limitations under the License. package v2beta1 import ( + "context" + appsv2beta1 "github.com/emqx/emqx-operator/apis/apps/v2beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" ) type status interface { @@ -26,7 +29,8 @@ type status interface { } type emqxStatusMachine struct { - emqx *appsv2beta1.EMQX + emqx *appsv2beta1.EMQX + client client.Client // EMQX cluster status initialized status @@ -40,9 +44,10 @@ type emqxStatusMachine struct { currentStatus status } -func newEMQXStatusMachine(emqx *appsv2beta1.EMQX) *emqxStatusMachine { +func newEMQXStatusMachine(k8sClient client.Client, emqx *appsv2beta1.EMQX) *emqxStatusMachine { emqxStatusMachine := &emqxStatusMachine{ - emqx: emqx, + client: k8sClient, + emqx: emqx, } initializedStatus := &initializedStatus{emqxStatusMachine: emqxStatusMachine} @@ -133,7 +138,8 @@ type coreNodesProgressingStatus struct { func (s *coreNodesProgressingStatus) nextStatus() { emqx := s.emqxStatusMachine.GetEMQX() - if emqx.Status.CoreNodesStatus.UpdateReplicas == emqx.Status.CoreNodesStatus.Replicas { + updateSts, _, _ := getStateFulSetList(context.Background(), s.emqxStatusMachine.client, emqx) + if updateSts.Status.ReadyReplicas == emqx.Status.CoreNodesStatus.Replicas { emqx.Status.SetCondition(metav1.Condition{ Type: appsv2beta1.CoreNodesReady, Status: metav1.ConditionTrue, @@ -184,7 +190,8 @@ func (s *replicantNodesProgressingStatus) nextStatus() { return } - if emqx.Status.ReplicantNodesStatus.UpdateReplicas == emqx.Status.ReplicantNodesStatus.Replicas { + updateRs, _, _ := getReplicaSetList(context.Background(), s.emqxStatusMachine.client, emqx) + if updateRs.Status.ReadyReplicas == emqx.Status.ReplicantNodesStatus.Replicas { emqx.Status.SetCondition(metav1.Condition{ Type: appsv2beta1.ReplicantNodesReady, Status: metav1.ConditionTrue, diff --git a/controllers/apps/v2beta1/status_machine_test.go b/controllers/apps/v2beta1/status_machine_test.go deleted file mode 100644 index 333ece8cf..000000000 --- a/controllers/apps/v2beta1/status_machine_test.go +++ /dev/null @@ -1,335 +0,0 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v2beta1 - -import ( - "testing" - - appsv2beta1 "github.com/emqx/emqx-operator/apis/apps/v2beta1" - "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/pointer" -) - -var instance = &appsv2beta1.EMQX{ - Spec: appsv2beta1.EMQXSpec{ - CoreTemplate: appsv2beta1.EMQXCoreTemplate{ - Spec: appsv2beta1.EMQXCoreTemplateSpec{ - EMQXReplicantTemplateSpec: appsv2beta1.EMQXReplicantTemplateSpec{ - Replicas: pointer.Int32Ptr(3), - }, - }, - }, - ReplicantTemplate: &appsv2beta1.EMQXReplicantTemplate{ - Spec: appsv2beta1.EMQXReplicantTemplateSpec{ - Replicas: pointer.Int32Ptr(3), - }, - }, - }, - Status: appsv2beta1.EMQXStatus{ - CoreNodesStatus: appsv2beta1.EMQXNodesStatus{ - Replicas: 3, - }, - ReplicantNodesStatus: &appsv2beta1.EMQXNodesStatus{ - Replicas: 3, - }, - }, -} - -func TestNewStatusMachine(t *testing.T) { - t.Run("initialized", func(t *testing.T) { - emqx := instance.DeepCopy() - emqxStatusMachine := newEMQXStatusMachine(emqx) - assert.Equal(t, emqxStatusMachine.initialized, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.Initialized, emqxStatusMachine.emqx.Status.Conditions[0].Type) - }) - - t.Run("coreNodesProgressing", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - {Type: appsv2beta1.CoreNodesProgressing, Status: metav1.ConditionTrue}, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - assert.Equal(t, emqxStatusMachine.coreNodesProgressing, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.CoreNodesProgressing, emqxStatusMachine.emqx.Status.Conditions[0].Type) - }) - - t.Run("coreNodesReady", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - {Type: appsv2beta1.CoreNodesReady, Status: metav1.ConditionTrue}, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - assert.Equal(t, emqxStatusMachine.coreNodesReady, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.CoreNodesReady, emqxStatusMachine.emqx.Status.Conditions[0].Type) - }) - - t.Run("replicantNodesProgressing", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - {Type: appsv2beta1.ReplicantNodesProgressing, Status: metav1.ConditionTrue}, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - assert.Equal(t, emqxStatusMachine.replicantNodesProgressing, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.ReplicantNodesProgressing, emqxStatusMachine.emqx.Status.Conditions[0].Type) - }) - - t.Run("replicantNodesReady", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - {Type: appsv2beta1.ReplicantNodesReady, Status: metav1.ConditionTrue}, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - assert.Equal(t, emqxStatusMachine.replicantNodesReady, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.ReplicantNodesReady, emqxStatusMachine.emqx.Status.Conditions[0].Type) - }) - - t.Run("available", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - {Type: appsv2beta1.Available, Status: metav1.ConditionTrue}, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - assert.Equal(t, emqxStatusMachine.available, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.Available, emqxStatusMachine.emqx.Status.Conditions[0].Type) - }) - - t.Run("ready", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - {Type: appsv2beta1.Ready, Status: metav1.ConditionTrue}, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - assert.Equal(t, emqxStatusMachine.ready, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.Ready, emqxStatusMachine.emqx.Status.Conditions[0].Type) - }) -} - -func TestNextStatusForInit(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.Initialized, - Status: metav1.ConditionTrue, - }, - } - - emqxStatusMachine := newEMQXStatusMachine(emqx) - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.coreNodesProgressing, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.CoreNodesProgressing, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) -} - -func TestNextStatusForCoreNodeProgressing(t *testing.T) { - t.Run("still status when core nodes not ready", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.CoreNodesProgressing, - Status: metav1.ConditionTrue, - }, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - - emqx.Status.CoreNodesStatus.UpdateReplicas = 0 - emqxStatusMachine.NextStatus() - - assert.Equal(t, emqxStatusMachine.coreNodesProgressing, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.CoreNodesProgressing, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) - - t.Run("next status", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.CoreNodesProgressing, - Status: metav1.ConditionTrue, - }, - } - - emqxStatusMachine := newEMQXStatusMachine(emqx) - emqx.Status.CoreNodesStatus.UpdateReplicas = emqx.Status.CoreNodesStatus.Replicas - - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.coreNodesReady, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.CoreNodesReady, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) -} - -func TestNextStatusForCodeNodesReady(t *testing.T) { - t.Run("next status when replicant template is not nil", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.CoreNodesReady, - Status: metav1.ConditionTrue, - }, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.replicantNodesProgressing, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.ReplicantNodesProgressing, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) - - t.Run("next status when replicant template is nil", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.CoreNodesReady, - Status: metav1.ConditionTrue, - }, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - - emqx.Spec.ReplicantTemplate = nil - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.available, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.Available, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) -} - -func TestNextStatusForReplicantNodeProgressing(t *testing.T) { - t.Run("replicant template is nil, need roll back to initialized next status", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Spec.ReplicantTemplate = nil - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.ReplicantNodesProgressing, - Status: metav1.ConditionTrue, - }, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.coreNodesProgressing, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.CoreNodesProgressing, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) - - t.Run("still status when replicant nodes not ready", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.ReplicantNodesProgressing, - Status: metav1.ConditionTrue, - }, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - emqx.Status.ReplicantNodesStatus.UpdateReplicas = 0 - - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.replicantNodesProgressing, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.ReplicantNodesProgressing, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) - - t.Run("next status", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.ReplicantNodesProgressing, - Status: metav1.ConditionTrue, - }, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - emqx.Status.ReplicantNodesStatus.UpdateReplicas = emqx.Status.ReplicantNodesStatus.Replicas - - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.replicantNodesReady, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.ReplicantNodesReady, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) -} - -func TestNextStatusForReplicantNodesReady(t *testing.T) { - t.Run("replicant template is nil, need roll back to initialized next status", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Spec.ReplicantTemplate = nil - emqx.Status.Conditions = []metav1.Condition{ - {Type: appsv2beta1.ReplicantNodesReady, Status: metav1.ConditionTrue}, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.coreNodesProgressing, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.CoreNodesProgressing, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) - - t.Run("next status", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.ReplicantNodesReady, - Status: metav1.ConditionTrue, - }, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - emqx.Status.ReplicantNodesStatus.UpdateReplicas = emqx.Status.ReplicantNodesStatus.Replicas - - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.available, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.Available, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) -} - -func TestNextStatusForAvailable(t *testing.T) { - t.Run("still status when core nodes ready replicas not equal replicas", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.Available, - Status: metav1.ConditionTrue, - }, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - emqx.Status.CoreNodesStatus.ReadyReplicas = 5 - - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.available, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.Available, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) - - t.Run("still status when replicant nodes ready replicas not equal replicas", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.Available, - Status: metav1.ConditionTrue, - }, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - emqx.Status.ReplicantNodesStatus.ReadyReplicas = 5 - - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.available, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.Available, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) - - t.Run("next status", func(t *testing.T) { - emqx := instance.DeepCopy() - emqx.Status.Conditions = []metav1.Condition{ - { - Type: appsv2beta1.Available, - Status: metav1.ConditionTrue, - }, - } - emqxStatusMachine := newEMQXStatusMachine(emqx) - emqx.Status.CoreNodesStatus.ReadyReplicas = emqx.Status.CoreNodesStatus.Replicas - emqx.Status.ReplicantNodesStatus.ReadyReplicas = emqx.Status.ReplicantNodesStatus.Replicas - - emqxStatusMachine.NextStatus() - assert.Equal(t, emqxStatusMachine.ready, emqxStatusMachine.currentStatus) - assert.Equal(t, appsv2beta1.Ready, emqxStatusMachine.GetEMQX().Status.Conditions[0].Type) - }) -} diff --git a/controllers/apps/v2beta1/suite_test.go b/controllers/apps/v2beta1/suite_test.go index af2d3cb6a..9b52771a5 100644 --- a/controllers/apps/v2beta1/suite_test.go +++ b/controllers/apps/v2beta1/suite_test.go @@ -55,7 +55,7 @@ var emqx *appsv2beta1.EMQX = &appsv2beta1.EMQX{ Name: "emqx", Labels: map[string]string{ appsv2beta1.ManagerByLabelKey: "emqx-operator", - appsv2beta1.InstanceNameLabelKey: instance.Name, + appsv2beta1.InstanceNameLabelKey: "emqx", }, }, Spec: appsv2beta1.EMQXSpec{ diff --git a/controllers/apps/v2beta1/update_emqx_status.go b/controllers/apps/v2beta1/update_emqx_status.go index 48bc7da86..ae14a3a58 100644 --- a/controllers/apps/v2beta1/update_emqx_status.go +++ b/controllers/apps/v2beta1/update_emqx_status.go @@ -117,7 +117,7 @@ func (u *updateStatus) reconcile(ctx context.Context, instance *appsv2beta1.EMQX } // update status condition - newEMQXStatusMachine(instance).NextStatus() + newEMQXStatusMachine(u.Client, instance).NextStatus() if err := u.Client.Status().Update(ctx, instance); err != nil { return subResult{err: emperror.Wrap(err, "failed to update status")}