From 5fb52c7d539ec20dbd104c172087d47b2142ec33 Mon Sep 17 00:00:00 2001 From: Yi Tao Date: Tue, 29 Oct 2024 15:44:58 +0800 Subject: [PATCH] add MembersReferenceResolved condition for cp groups --- controller/konnect/ops/conditions.go | 57 ++++++++++++++++++++++ controller/konnect/ops/errors.go | 29 +++++++++++ controller/konnect/ops/ops_controlplane.go | 22 ++++++++- 3 files changed, 106 insertions(+), 2 deletions(-) diff --git a/controller/konnect/ops/conditions.go b/controller/konnect/ops/conditions.go index 88bbb74dc..7837c1866 100644 --- a/controller/konnect/ops/conditions.go +++ b/controller/konnect/ops/conditions.go @@ -1,6 +1,7 @@ package ops import ( + sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/kong/gateway-operator/pkg/consts" @@ -60,3 +61,59 @@ func _setKonnectEntityProgrammedConditon( obj, ) } + +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 + // are created and attached to the group in Konnect. + ControlPlaneGroupMembersReferenceResolvedReasonResolved consts.ConditionReason = "Resolved" +) + +// SetControlPlaneGroupMembersReferenceResolvedCondition sets MembersReferenceResolved condition of control plane to True. +func SetControlPlaneGroupMembersReferenceResolvedCondition( + cpGroup *konnectv1alpha1.KonnectGatewayControlPlane, +) { + _setControlPlaneGroupMembersReferenceResolvedCondition( + cpGroup, + metav1.ConditionTrue, + ControlPlaneGroupMembersReferenceResolvedReasonResolved, + "", + ) +} + +// SetControlPlaneGroupMembersReferenceResolvedConditionFalse sets MembersReferenceResolved condition of control plane to False. +func SetControlPlaneGroupMembersReferenceResolvedConditionFalse( + cpGroup *konnectv1alpha1.KonnectGatewayControlPlane, + reason consts.ConditionReason, + msg string, +) { + _setControlPlaneGroupMembersReferenceResolvedCondition( + cpGroup, + metav1.ConditionFalse, + reason, + msg, + ) +} + +func _setControlPlaneGroupMembersReferenceResolvedCondition( + cpGroup *konnectv1alpha1.KonnectGatewayControlPlane, + status metav1.ConditionStatus, + reason consts.ConditionReason, + msg string, +) { + if cpGroup.Spec.ClusterType == nil || *cpGroup.Spec.ClusterType != sdkkonnectcomp.ClusterTypeClusterTypeControlPlaneGroup { + return + } + k8sutils.SetCondition( + k8sutils.NewConditionWithGeneration( + ControlPlaneGroupMembersReferenceResolvedConditionType, + status, + reason, + msg, + cpGroup.GetGeneration(), + ), + cpGroup, + ) +} diff --git a/controller/konnect/ops/errors.go b/controller/konnect/ops/errors.go index 7d1472e51..a547addf4 100644 --- a/controller/konnect/ops/errors.go +++ b/controller/konnect/ops/errors.go @@ -39,3 +39,32 @@ type KonnectEntityCreatedButRelationsFailedError struct { func (e KonnectEntityCreatedButRelationsFailedError) Error() string { return fmt.Sprintf("Konnect entity (ID: %s) created but relations failed: %s: %v", e.KonnectID, e.Reason, e.Err) } + +// GetControlPlaneGroupMemberFailedError is an error type returned when +// failed to get member of control plane group. +type GetControlPlaneGroupMemberFailedError struct { + MemberName string + Err error +} + +// Error implements the error interface. +func (e GetControlPlaneGroupMemberFailedError) Error() string { + return fmt.Sprintf("failed to get control plane group member %s: %v", e.MemberName, e.Err.Error()) +} + +// Unwrap returns the underlying error. +func (e GetControlPlaneGroupMemberFailedError) Unwrap() error { + return e.Err +} + +// ControlPlaneGroupMemberNoKonnectIDError is an error type returned when +// member of control plane group does not have a Konnect ID. +type ControlPlaneGroupMemberNoKonnectIDError struct { + GroupName string + MemberName string +} + +// Error implements the error interface. +func (e ControlPlaneGroupMemberNoKonnectIDError) Error() string { + return fmt.Sprintf("control plane group %s member %s has no Konnect ID", e.GroupName, e.MemberName) +} diff --git a/controller/konnect/ops/ops_controlplane.go b/controller/konnect/ops/ops_controlplane.go index 9c1a6e5fe..57457f4b6 100644 --- a/controller/konnect/ops/ops_controlplane.go +++ b/controller/konnect/ops/ops_controlplane.go @@ -128,6 +128,7 @@ 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 || *cp.Spec.ClusterType != sdkkonnectcomp.CreateControlPlaneRequestClusterTypeClusterTypeControlPlaneGroup { @@ -145,17 +146,28 @@ func setGroupMembers( ) if err := cl.Get(ctx, nn, &memberCP); err != nil { return sdkkonnectcomp.Members{}, - fmt.Errorf("failed to get control plane group member %s: %w", member.Name, err) + GetControlPlaneGroupMemberFailedError{ + MemberName: memberCP.Name, + Err: err, + } } if memberCP.GetKonnectID() == "" { return sdkkonnectcomp.Members{}, - fmt.Errorf("control plane group %s member %s has no Konnect ID", cp.Name, member.Name) + ControlPlaneGroupMemberNoKonnectIDError{ + GroupName: cp.Name, + MemberName: memberCP.Name, + } } return sdkkonnectcomp.Members{ ID: lo.ToPtr(memberCP.GetKonnectID()), }, nil }) if err != nil { + SetControlPlaneGroupMembersReferenceResolvedConditionFalse( + cp, + "SomeMemberNotResolved", + err.Error(), + ) return fmt.Errorf("failed to set group members, some members couldn't be found: %w", err) } @@ -165,11 +177,17 @@ func setGroupMembers( } _, err = sdkGroups.PutControlPlanesIDGroupMemberships(ctx, id, &gm) if err != nil { + SetControlPlaneGroupMembersReferenceResolvedConditionFalse( + cp, + "SetGroupMemberFailed", + err.Error(), + ) return fmt.Errorf("failed to set members on control plane group %s: %w", client.ObjectKeyFromObject(cp), err, ) } + SetControlPlaneGroupMembersReferenceResolvedCondition(cp) return nil }