diff --git a/controller/konnect/ops/conditions.go b/controller/konnect/ops/conditions.go index 7837c1866..77687d312 100644 --- a/controller/konnect/ops/conditions.go +++ b/controller/konnect/ops/conditions.go @@ -66,9 +66,17 @@ const ( // ControlPlaneGroupMembersReferenceResolvedConditionType sets the condition for control plane groups // to show whether all of its members are programmed and attached to the group. ControlPlaneGroupMembersReferenceResolvedConditionType = "MembersReferenceResolved" - // ControlPlaneGroupMembersReferenceResolvedReasonResolved indicates that all members of the control plane groups + // ControlPlaneGroupMembersReferenceResolvedReasonNoMembers indicates that there are no members specified in the control plane group. + ControlPlaneGroupMembersReferenceResolvedReasonNoMembers consts.ConditionReason = "NoMembers" + // ControlPlaneGroupMembersReferenceResolvedReasonResolved indicates that all members of the control plane group // are created and attached to the group in Konnect. ControlPlaneGroupMembersReferenceResolvedReasonResolved consts.ConditionReason = "Resolved" + // ControlPlaneGroupMembersReferenceResolvedReasonPartialNotResolved indicates that some members of the control plane group + // are not resolved (not found or not created in Konnect). + ControlPlaneGroupMembersReferenceResolvedReasonPartialNotResolved consts.ConditionReason = "SomeMemberNotResolved" + // ControlPlaneGroupMembersReferenceResolvedReasonFailedToSet indicates that error happened on setting control plane as + // member of the control plane. + ControlPlaneGroupMembersReferenceResolvedReasonFailedToSet consts.ConditionReason = "SetGroupMemberFailed" ) // SetControlPlaneGroupMembersReferenceResolvedCondition sets MembersReferenceResolved condition of control plane to True. diff --git a/controller/konnect/ops/ops_controlplane.go b/controller/konnect/ops/ops_controlplane.go index d6d6403c7..719be8ad1 100644 --- a/controller/konnect/ops/ops_controlplane.go +++ b/controller/konnect/ops/ops_controlplane.go @@ -128,13 +128,21 @@ func setGroupMembers( id string, sdkGroups sdkops.ControlPlaneGroupSDK, ) error { - // REVIEW: should we add MembersReferenceResolved condition for CP groups with 0 members? - if len(cp.Spec.Members) == 0 || - cp.Spec.ClusterType == nil || + if cp.Spec.ClusterType == nil || *cp.Spec.ClusterType != sdkkonnectcomp.ClusterTypeClusterTypeControlPlaneGroup { return nil } + // Set MembersReferenceResolved condition to False if there are no members in the CP group. + if len(cp.Spec.Members) == 0 { + SetControlPlaneGroupMembersReferenceResolvedConditionFalse( + cp, + ControlPlaneGroupMembersReferenceResolvedReasonNoMembers, + "No members in the control plane group", + ) + return nil + } + members, err := iter.MapErr(cp.Spec.Members, func(member *corev1.LocalObjectReference) (sdkkonnectcomp.Members, error) { var ( @@ -165,7 +173,7 @@ func setGroupMembers( if err != nil { SetControlPlaneGroupMembersReferenceResolvedConditionFalse( cp, - "SomeMemberNotResolved", + ControlPlaneGroupMembersReferenceResolvedReasonPartialNotResolved, err.Error(), ) return fmt.Errorf("failed to set group members, some members couldn't be found: %w", err) @@ -179,7 +187,7 @@ func setGroupMembers( if err != nil { SetControlPlaneGroupMembersReferenceResolvedConditionFalse( cp, - "SetGroupMemberFailed", + ControlPlaneGroupMembersReferenceResolvedReasonFailedToSet, err.Error(), ) return fmt.Errorf("failed to set members on control plane group %s: %w", @@ -187,7 +195,9 @@ func setGroupMembers( ) } - SetControlPlaneGroupMembersReferenceResolvedCondition(cp) + SetControlPlaneGroupMembersReferenceResolvedCondition( + cp, + ) return nil } diff --git a/controller/konnect/ops/ops_controlplane_test.go b/controller/konnect/ops/ops_controlplane_test.go index be4ec4ffb..2da033945 100644 --- a/controller/konnect/ops/ops_controlplane_test.go +++ b/controller/konnect/ops/ops_controlplane_test.go @@ -22,6 +22,7 @@ import ( sdkmocks "github.com/kong/gateway-operator/controller/konnect/ops/sdk/mocks" "github.com/kong/gateway-operator/modules/manager/scheme" + "github.com/kong/gateway-operator/pkg/consts" konnectv1alpha1 "github.com/kong/kubernetes-configuration/api/konnect/v1alpha1" ) @@ -638,11 +639,13 @@ func TestCreateAndUpdateControlPlane_KubernetesMetadataConsistency(t *testing.T) func TestSetGroupMembers(t *testing.T) { testcases := []struct { - name string - group *konnectv1alpha1.KonnectGatewayControlPlane - cps []client.Object - sdk func(t *testing.T) *sdkmocks.MockControlPlaneGroupSDK - expectedErr bool + name string + group *konnectv1alpha1.KonnectGatewayControlPlane + cps []client.Object + sdk func(t *testing.T) *sdkmocks.MockControlPlaneGroupSDK + expectedErr bool + memberRefResolvedStatus metav1.ConditionStatus + memberRefResolvedReason consts.ConditionReason }{ { name: "no members", @@ -662,6 +665,8 @@ func TestSetGroupMembers(t *testing.T) { sdk := sdkmocks.NewMockControlPlaneGroupSDK(t) return sdk }, + memberRefResolvedStatus: metav1.ConditionFalse, + memberRefResolvedReason: ControlPlaneGroupMembersReferenceResolvedReasonNoMembers, }, { name: "1 member with Konnect Status ID", @@ -715,6 +720,8 @@ func TestSetGroupMembers(t *testing.T) { ) return sdk }, + memberRefResolvedStatus: metav1.ConditionTrue, + memberRefResolvedReason: ControlPlaneGroupMembersReferenceResolvedReasonResolved, }, { name: "1 member without Konnect Status ID", @@ -748,7 +755,9 @@ func TestSetGroupMembers(t *testing.T) { sdk := sdkmocks.NewMockControlPlaneGroupSDK(t) return sdk }, - expectedErr: true, + expectedErr: true, + memberRefResolvedStatus: metav1.ConditionFalse, + memberRefResolvedReason: ControlPlaneGroupMembersReferenceResolvedReasonPartialNotResolved, }, { name: "2 member with Konnect Status IDs", @@ -819,6 +828,8 @@ func TestSetGroupMembers(t *testing.T) { ) return sdk }, + memberRefResolvedStatus: metav1.ConditionTrue, + memberRefResolvedReason: ControlPlaneGroupMembersReferenceResolvedReasonResolved, }, { name: "2 member, 1 with Konnect Status IDs, 1 without it", @@ -865,7 +876,9 @@ func TestSetGroupMembers(t *testing.T) { sdk := sdkmocks.NewMockControlPlaneGroupSDK(t) return sdk }, - expectedErr: true, + expectedErr: true, + memberRefResolvedStatus: metav1.ConditionFalse, + memberRefResolvedReason: ControlPlaneGroupMembersReferenceResolvedReasonPartialNotResolved, }, } @@ -885,6 +898,13 @@ func TestSetGroupMembers(t *testing.T) { } assert.NoError(t, err) assert.True(t, sdk.AssertExpectations(t)) + + membersRefResolvedCondition, conditionFound := lo.Find(tc.group.Status.Conditions, func(c metav1.Condition) bool { + return c.Type == ControlPlaneGroupMembersReferenceResolvedConditionType + }) + assert.True(t, conditionFound, "Should find MembersReferenceResolved condition") + assert.Equal(t, tc.memberRefResolvedStatus, membersRefResolvedCondition.Status, "Should have expected MembersReferenceResolved status") + assert.Equal(t, string(tc.memberRefResolvedReason), membersRefResolvedCondition.Reason, "Should have expected MembersReferenceResolved reason") }) } }