diff --git a/controller/konnect/ops/ops.go b/controller/konnect/ops/ops.go index c6b6127a62..c838129679 100644 --- a/controller/konnect/ops/ops.go +++ b/controller/konnect/ops/ops.go @@ -795,15 +795,20 @@ func getMatchingEntryFromListResponseData[ ]( data []T, entity entity, -) (string, error) { - var id string +) (T, string, error) { + var ( + id string + ret T + ) for _, entry := range data { entryID := entry.GetID() switch entryID := any(entryID).(type) { case string: if entryID != "" { id = entryID + ret = entry break + } case *string: if entryID != nil && *entryID != "" { @@ -814,12 +819,12 @@ func getMatchingEntryFromListResponseData[ } if id == "" { - return "", EntityWithMatchingUIDNotFoundError{ + return ret, "", EntityWithMatchingUIDNotFoundError{ Entity: entity, } } - return id, nil + return ret, id, nil } // ClearInstanceFromError clears the instance field from the error. diff --git a/controller/konnect/ops/ops_controlplane.go b/controller/konnect/ops/ops_controlplane.go index 1970ec4fb6..72e32ae43b 100644 --- a/controller/konnect/ops/ops_controlplane.go +++ b/controller/konnect/ops/ops_controlplane.go @@ -11,10 +11,12 @@ import ( "github.com/sourcegraph/conc/iter" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + ctrllog "sigs.k8s.io/controller-runtime/pkg/log" commonv1alpha1 "github.com/kong/kong-operator/v2/api/common/v1alpha1" konnectv1alpha1 "github.com/kong/kong-operator/v2/api/konnect/v1alpha1" konnectv1alpha2 "github.com/kong/kong-operator/v2/api/konnect/v1alpha2" + "github.com/kong/kong-operator/v2/controller/pkg/patch" ) // ensureControlPlane ensures that the Konnect ControlPlane exists in Konnect. It is created @@ -40,8 +42,12 @@ func ensureControlPlane( if err != nil { return err } + old := cp.DeepCopy() cp.SetKonnectID(string(cp.Spec.Mirror.Konnect.ID)) - cp.Status.ClusterType = resp.Config.ClusterType + if fillKonnectGatewayControlPlaneStatusFromResponse(cp, resp.Config) { + _, err = patch.ApplyStatusPatchIfNotEmpty(ctx, cl, ctrllog.FromContext(ctx), cp, old) + return err + } return nil default: // This should never happen, as the source type is validated by CEL rules. @@ -74,8 +80,14 @@ func createControlPlane( // At this point, the ControlPlane has been created in Konnect. id := resp.ControlPlane.ID + old := cp.DeepCopy() cp.SetKonnectID(id) - cp.Status.ClusterType = resp.ControlPlane.Config.ClusterType + if fillKonnectGatewayControlPlaneStatusFromResponse(cp, resp.ControlPlane.Config) { + _, err = patch.ApplyStatusPatchIfNotEmpty(ctx, cl, ctrllog.FromContext(ctx), cp, old) + if err != nil { + return err + } + } if err := setGroupMembers(ctx, cl, cp, id, sdkGroups); err != nil { // If we failed to set group membership, we should return a specific error with a reason @@ -145,8 +157,16 @@ func updateControlPlane( if resp == nil || resp.ControlPlane == nil { return fmt.Errorf("failed updating ControlPlane: %w", ErrNilResponse) } - id = resp.ControlPlane.ID + old := cp.DeepCopy() + if fillKonnectGatewayControlPlaneStatusFromResponse(cp, resp.ControlPlane.Config) { + _, err = patch.ApplyStatusPatchIfNotEmpty(ctx, cl, ctrllog.FromContext(ctx), cp, old) + if err != nil { + return err + } + } + + id = resp.ControlPlane.ID if err := setGroupMembers(ctx, cl, cp, id, sdkGroups); err != nil { // If we failed to set group membership, we should return a specific error with a reason // so the downstream can handle it properly. @@ -265,11 +285,19 @@ func getControlPlaneForUID( return "", fmt.Errorf("failed listing %s: %w", cp.GetTypeName(), ErrNilResponse) } - id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDSlice(resp.ListControlPlanesResponse.Data), cp) + entry, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDSlice(resp.ListControlPlanesResponse.Data), cp) if err != nil { return "", err } + old := cp.DeepCopy() + if fillKonnectGatewayControlPlaneStatusFromResponse(cp, entry.Config) { + _, err = patch.ApplyStatusPatchIfNotEmpty(ctx, cl, ctrllog.FromContext(ctx), cp, old) + if err != nil { + return id, err + } + } + if err := setGroupMembers(ctx, cl, cp, id, sdkGroups); err != nil { // If we failed to set group membership, we should return a specific error with a reason // so the downstream can handle it properly. @@ -313,3 +341,30 @@ func GetControlPlaneByID( return &resp.ListControlPlanesResponse.Data[0], nil } + +func fillKonnectGatewayControlPlaneStatusFromResponse( + cp *konnectv1alpha2.KonnectGatewayControlPlane, + respConfig sdkkonnectcomp.ControlPlaneConfig, +) bool { + if cp == nil { + return false + } + + var updated bool + if respConfig.ClusterType != "" { + cp.Status.ClusterType = respConfig.ClusterType + updated = true + } + if respConfig.ControlPlaneEndpoint != "" && + (cp.Status.Endpoints == nil || respConfig.ControlPlaneEndpoint != cp.Status.Endpoints.ControlPlaneEndpoint) || + respConfig.TelemetryEndpoint != "" && + (cp.Status.Endpoints == nil || respConfig.TelemetryEndpoint != cp.Status.Endpoints.TelemetryEndpoint) { + cp.Status.Endpoints = &konnectv1alpha2.KonnectEndpoints{ + ControlPlaneEndpoint: respConfig.ControlPlaneEndpoint, + TelemetryEndpoint: respConfig.TelemetryEndpoint, + } + updated = true + } + + return updated +} diff --git a/controller/konnect/ops/ops_credentialacl.go b/controller/konnect/ops/ops_credentialacl.go index fb3d34f75d..e322bc68d4 100644 --- a/controller/konnect/ops/ops_credentialacl.go +++ b/controller/konnect/ops/ops_credentialacl.go @@ -204,7 +204,8 @@ func getKongCredentialACLForUID( } x := sliceToEntityWithIDPtrSlice(resp.Object.Data) - return getMatchingEntryFromListResponseData(x, cred) + _, id, err := getMatchingEntryFromListResponseData(x, cred) + return id, err } func credentialACLMatch( diff --git a/controller/konnect/ops/ops_credentialapikey.go b/controller/konnect/ops/ops_credentialapikey.go index 08dc53e9e5..3c6c121b8e 100644 --- a/controller/konnect/ops/ops_credentialapikey.go +++ b/controller/konnect/ops/ops_credentialapikey.go @@ -201,7 +201,8 @@ func getKongCredentialAPIKeyForUID( return "", fmt.Errorf("failed listing %s: %w", cred.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cred) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cred) + return id, err } func credentialAPIKeyMatch( diff --git a/controller/konnect/ops/ops_credentialbasicauth.go b/controller/konnect/ops/ops_credentialbasicauth.go index 0ad07145d7..56ec5d9be2 100644 --- a/controller/konnect/ops/ops_credentialbasicauth.go +++ b/controller/konnect/ops/ops_credentialbasicauth.go @@ -200,7 +200,8 @@ func getKongCredentialBasicAuthForUID( return "", fmt.Errorf("failed listing %s: %w", cred.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cred) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cred) + return id, err } func credentialBasicAuthMatch( diff --git a/controller/konnect/ops/ops_credentialhmac.go b/controller/konnect/ops/ops_credentialhmac.go index 694cfb4c44..92a6509cc9 100644 --- a/controller/konnect/ops/ops_credentialhmac.go +++ b/controller/konnect/ops/ops_credentialhmac.go @@ -205,7 +205,8 @@ func getKongCredentialHMACForUID( return "", fmt.Errorf("failed listing %s: %w", cred.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cred) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cred) + return id, err } func credentialHMACMatch( diff --git a/controller/konnect/ops/ops_credentialjwt.go b/controller/konnect/ops/ops_credentialjwt.go index c8354b4fd5..bcf4b87a7a 100644 --- a/controller/konnect/ops/ops_credentialjwt.go +++ b/controller/konnect/ops/ops_credentialjwt.go @@ -204,7 +204,8 @@ func getKongCredentialJWTForUID( return "", fmt.Errorf("failed listing %s: %w", cred.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cred) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cred) + return id, err } func credentialJWTMatch( diff --git a/controller/konnect/ops/ops_kongcacertificate.go b/controller/konnect/ops/ops_kongcacertificate.go index f9c914ee1b..77ad415cff 100644 --- a/controller/konnect/ops/ops_kongcacertificate.go +++ b/controller/konnect/ops/ops_kongcacertificate.go @@ -239,7 +239,8 @@ func getKongCACertificateForUID( return "", fmt.Errorf("failed listing %s: %w", cert.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cert) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cert) + return id, err } func caCertificateMatch( diff --git a/controller/konnect/ops/ops_kongcertificate.go b/controller/konnect/ops/ops_kongcertificate.go index a5580b1b70..77a9bc204e 100644 --- a/controller/konnect/ops/ops_kongcertificate.go +++ b/controller/konnect/ops/ops_kongcertificate.go @@ -289,7 +289,8 @@ func getKongCertificateForUID( return "", fmt.Errorf("failed listing %s: %w", cert.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cert) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cert) + return id, err } func certificateMatch( diff --git a/controller/konnect/ops/ops_kongconsumer.go b/controller/konnect/ops/ops_kongconsumer.go index 041da4f842..ef99283564 100644 --- a/controller/konnect/ops/ops_kongconsumer.go +++ b/controller/konnect/ops/ops_kongconsumer.go @@ -460,5 +460,6 @@ func getKongConsumerForUID( return "", fmt.Errorf("failed listing %s: %w", consumer.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), consumer) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), consumer) + return id, err } diff --git a/controller/konnect/ops/ops_kongconsumergroup.go b/controller/konnect/ops/ops_kongconsumergroup.go index cdfe9c18aa..5cba3babac 100644 --- a/controller/konnect/ops/ops_kongconsumergroup.go +++ b/controller/konnect/ops/ops_kongconsumergroup.go @@ -188,5 +188,6 @@ func getKongConsumerGroupForUID( return "", fmt.Errorf("failed listing %s: %w", cg.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cg) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), cg) + return id, err } diff --git a/controller/konnect/ops/ops_kongkey.go b/controller/konnect/ops/ops_kongkey.go index fe49b29230..590a259b9e 100644 --- a/controller/konnect/ops/ops_kongkey.go +++ b/controller/konnect/ops/ops_kongkey.go @@ -202,7 +202,8 @@ func getKongKeyForUID( return "", fmt.Errorf("failed to list KongKeys: %w", ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), key) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), key) + return id, err } func keyMatch(konnectKey *sdkkonnectcomp.Key, key *configurationv1alpha1.KongKey) bool { diff --git a/controller/konnect/ops/ops_kongkeyset.go b/controller/konnect/ops/ops_kongkeyset.go index 47472bf073..e7117498e1 100644 --- a/controller/konnect/ops/ops_kongkeyset.go +++ b/controller/konnect/ops/ops_kongkeyset.go @@ -178,7 +178,8 @@ func getKongKeySetForUID( return "", fmt.Errorf("failed listing %s: %w", keySet.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), keySet) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), keySet) + return id, err } func keySetMatch(konnectKeySet *sdkkonnectcomp.KeySet, keySet *configurationv1alpha1.KongKeySet) bool { diff --git a/controller/konnect/ops/ops_kongpluginbinding.go b/controller/konnect/ops/ops_kongpluginbinding.go index ae6a5c9909..3f78202ba6 100644 --- a/controller/konnect/ops/ops_kongpluginbinding.go +++ b/controller/konnect/ops/ops_kongpluginbinding.go @@ -139,7 +139,8 @@ func getPluginForUID( return "", fmt.Errorf("failed listing %s: %w", pluginBinding.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), pluginBinding) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), pluginBinding) + return id, err } func adoptPluginBinding( diff --git a/controller/konnect/ops/ops_kongroute.go b/controller/konnect/ops/ops_kongroute.go index 5b344ac78a..1ce02d68e7 100644 --- a/controller/konnect/ops/ops_kongroute.go +++ b/controller/konnect/ops/ops_kongroute.go @@ -245,12 +245,13 @@ func getKongRouteForUID( return "", fmt.Errorf("failed listing %s: %w", r.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData( + _, id, err := getMatchingEntryFromListResponseData( sliceToEntityWithIDPtrSlice( lo.Map(resp.Object.Data, func(route sdkkonnectcomp.Route, _ int) sdkkonnectcomp.RouteJSON { return *route.RouteJSON }), ), r) + return id, err } // routeHeadersMatch compares two header matches in the two routes. diff --git a/controller/konnect/ops/ops_kongservice.go b/controller/konnect/ops/ops_kongservice.go index 66efd9c2da..558bf553fd 100644 --- a/controller/konnect/ops/ops_kongservice.go +++ b/controller/konnect/ops/ops_kongservice.go @@ -208,7 +208,8 @@ func getKongServiceForUID( return "", fmt.Errorf("failed listing %s: %w", svc.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), svc) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), svc) + return id, err } // serviceMatch compares the existing service fetched from Konnect and the spec of the KongService diff --git a/controller/konnect/ops/ops_kongsni.go b/controller/konnect/ops/ops_kongsni.go index d46732117d..bc40f2aff7 100644 --- a/controller/konnect/ops/ops_kongsni.go +++ b/controller/konnect/ops/ops_kongsni.go @@ -209,7 +209,8 @@ func getKongSNIForUID(ctx context.Context, sdk sdkkonnectgo.SNIsSDK, sni *config return "", fmt.Errorf("failed listing %s: %w", sni.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), sni) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), sni) + return id, err } func sniMatch(konnectSNI *sdkkonnectcomp.Sni, sni *configurationv1alpha1.KongSNI) bool { diff --git a/controller/konnect/ops/ops_kongtarget.go b/controller/konnect/ops/ops_kongtarget.go index d6240a0a6a..ce677e70fd 100644 --- a/controller/konnect/ops/ops_kongtarget.go +++ b/controller/konnect/ops/ops_kongtarget.go @@ -194,7 +194,8 @@ func getKongTargetForUID( return "", fmt.Errorf("failed listing %s: %w", target.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), target) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), target) + return id, err } func targetMatch(konnectTarget *sdkkonnectcomp.Target, target *configurationv1alpha1.KongTarget) bool { diff --git a/controller/konnect/ops/ops_kongupstream.go b/controller/konnect/ops/ops_kongupstream.go index c53ae765c1..0df3f40eb3 100644 --- a/controller/konnect/ops/ops_kongupstream.go +++ b/controller/konnect/ops/ops_kongupstream.go @@ -187,7 +187,8 @@ func getKongUpstreamForUID( return "", fmt.Errorf("failed listing %s: %w", u.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), u) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), u) + return id, err } func upstreamMatch(konnectUpstream *sdkkonnectcomp.Upstream, upstream *configurationv1alpha1.KongUpstream) bool { diff --git a/controller/konnect/ops/ops_kongvault.go b/controller/konnect/ops/ops_kongvault.go index aa07fe47a2..4780a1f49b 100644 --- a/controller/konnect/ops/ops_kongvault.go +++ b/controller/konnect/ops/ops_kongvault.go @@ -195,5 +195,6 @@ func getKongVaultForUID( return "", fmt.Errorf("failed to list KongVaults: %w", ErrNilResponse) } - return getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), vault) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDPtrSlice(resp.Object.Data), vault) + return id, err } diff --git a/controller/konnect/ops/ops_konnectnetwork.go b/controller/konnect/ops/ops_konnectnetwork.go index 1fc51aeff4..25bd4357e1 100644 --- a/controller/konnect/ops/ops_konnectnetwork.go +++ b/controller/konnect/ops/ops_konnectnetwork.go @@ -109,7 +109,7 @@ func getKonnectNetworkMatchingSpecName( return "", fmt.Errorf("failed listing %s: %w", n.GetTypeName(), ErrNilResponse) } - id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDSlice(resp.ListNetworksResponse.Data), n) + _, id, err := getMatchingEntryFromListResponseData(sliceToEntityWithIDSlice(resp.ListNetworksResponse.Data), n) if err != nil { return "", err } diff --git a/controller/konnect/ops/ops_konnecttransitgateway.go b/controller/konnect/ops/ops_konnecttransitgateway.go index 3ba969ec94..4798981c03 100644 --- a/controller/konnect/ops/ops_konnecttransitgateway.go +++ b/controller/konnect/ops/ops_konnecttransitgateway.go @@ -139,7 +139,8 @@ func getKonnectTransitGatewayMatchingSpecName( return "", fmt.Errorf("failed listing %s: %w", tg.GetTypeName(), ErrNilResponse) } - return getMatchingEntryFromListResponseData(listTransitGatewayResponseDataToEntityWithIDSlice(resp.ListTransitGatewaysResponse.Data), tg) + _, id, err := getMatchingEntryFromListResponseData(listTransitGatewayResponseDataToEntityWithIDSlice(resp.ListTransitGatewaysResponse.Data), tg) + return id, err } var transitGatewayTypeToSDKTransitGatewayType = map[konnectv1alpha1.TransitGatewayType]sdkkonnectcomp.CreateTransitGatewayRequestType{ diff --git a/controller/konnect/reconciler_generic.go b/controller/konnect/reconciler_generic.go index e86964d255..33985c4974 100644 --- a/controller/konnect/reconciler_generic.go +++ b/controller/konnect/reconciler_generic.go @@ -525,7 +525,7 @@ func (r *KonnectEntityReconciler[T, TEnt]) Reconcile( // Handle type specific operations and stop reconciliation if needed. // This can happen for instance when KongConsumer references credentials Secrets // that do not exist or populate some Status fields based on Konnect API. - if stop, res, err := handleTypeSpecific(ctx, sdk, r.Client, ent); err != nil { + if stop, res, err := handleTypeSpecific(ctx, r.Client, ent); err != nil { // If the error was a network error, handle it here, there's no need to proceed, // as no state has changed. // Status conditions are updated in handleOpsErr. diff --git a/controller/konnect/reconciler_generic_type_specific.go b/controller/konnect/reconciler_generic_type_specific.go index 9ddf248b1e..866db0c78d 100644 --- a/controller/konnect/reconciler_generic_type_specific.go +++ b/controller/konnect/reconciler_generic_type_specific.go @@ -3,7 +3,6 @@ package konnect import ( "context" "errors" - "fmt" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -13,10 +12,7 @@ import ( kcfgconsts "github.com/kong/kong-operator/v2/api/common/consts" configurationv1 "github.com/kong/kong-operator/v2/api/configuration/v1" - konnectv1alpha2 "github.com/kong/kong-operator/v2/api/konnect/v1alpha2" "github.com/kong/kong-operator/v2/controller/konnect/constraints" - "github.com/kong/kong-operator/v2/controller/konnect/ops" - sdkops "github.com/kong/kong-operator/v2/controller/konnect/ops/sdk" "github.com/kong/kong-operator/v2/controller/pkg/patch" ) @@ -28,7 +24,6 @@ func handleTypeSpecific[ TEnt constraints.EntityType[T], ]( ctx context.Context, - sdk sdkops.SDKWrapper, cl client.Client, ent TEnt, ) (bool, ctrl.Result, error) { @@ -41,11 +36,6 @@ func handleTypeSpecific[ switch e := any(ent).(type) { case *configurationv1.KongConsumer: updated, isProblem = handleKongConsumerSpecific(ctx, cl, e) - case *konnectv1alpha2.KonnectGatewayControlPlane: - updated, err = handleKonnectGatewayControlPlaneSpecific(ctx, sdk, e) - if err != nil { - return false, ctrl.Result{}, err - } default: } @@ -56,29 +46,6 @@ func handleTypeSpecific[ return isProblem, res, err } -func handleKonnectGatewayControlPlaneSpecific( - ctx context.Context, - sdk sdkops.SDKWrapper, - kgcp *konnectv1alpha2.KonnectGatewayControlPlane, -) (updated bool, err error) { - // If it's not set it means that first time we are reconciling the KonnectGatewayControlPlane, - // in subsequent reconciliations it should be set. Otherwise it will be reported and everything - // in this helper is irrelevant. - kgcpID := kgcp.GetKonnectID() - if kgcpID == "" { - return false, nil - } - konnectCP, err := ops.GetControlPlaneByID(ctx, sdk.GetControlPlaneSDK(), kgcpID) - if err != nil { - return false, fmt.Errorf("can't read KonnectGatewayControlPlane with ID: %s from Konnect API: %w", kgcpID, err) - } - kgcp.Status.Endpoints = &konnectv1alpha2.KonnectEndpoints{ - TelemetryEndpoint: konnectCP.Config.TelemetryEndpoint, - ControlPlaneEndpoint: konnectCP.Config.ControlPlaneEndpoint, - } - return true, nil -} - func handleKongConsumerSpecific( ctx context.Context, cl client.Client, diff --git a/test/envtest/konnect_entities_gatewaycontrolplane_test.go b/test/envtest/konnect_entities_gatewaycontrolplane_test.go index 0a0d4d23ce..59a2a66cba 100644 --- a/test/envtest/konnect_entities_gatewaycontrolplane_test.go +++ b/test/envtest/konnect_entities_gatewaycontrolplane_test.go @@ -35,8 +35,8 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ deploy.KonnectGatewayControlPlane(t, ctx, cl, auth, func(obj client.Object) { cp := obj.(*konnectv1alpha2.KonnectGatewayControlPlane) - cp.Name = "cp-1" - cp.SetKonnectName("cp-1") + cp.Name = "cp-001" + cp.SetKonnectName("cp-001") cp.SetKonnectDescription(new("test control plane 1")) }, ) @@ -46,42 +46,46 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ CreateControlPlane( mock.Anything, mock.MatchedBy(func(req sdkkonnectcomp.CreateControlPlaneRequest) bool { - return req.Name == "cp-1" && + return req.Name == "cp-001" && req.Description != nil && *req.Description == "test control plane 1" }), ). Return( &sdkkonnectops.CreateControlPlaneResponse{ ControlPlane: &sdkkonnectcomp.ControlPlane{ - ID: "12345", + ID: "001-12345", + Name: "cp-001", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlane, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, }, }, nil, ) sdk.ControlPlaneSDK.EXPECT(). - ListControlPlanes( + UpdateControlPlane( mock.Anything, - mock.MatchedBy(func(r sdkkonnectops.ListControlPlanesRequest) bool { - return *r.Filter.ID.Eq == "12345" + "001-12345", + mock.MatchedBy(func(req sdkkonnectcomp.UpdateControlPlaneRequest) bool { + return req.Name != nil && *req.Name == "cp-001" }), ). Return( - &sdkkonnectops.ListControlPlanesResponse{ - ListControlPlanesResponse: &sdkkonnectcomp.ListControlPlanesResponse{ - Data: []sdkkonnectcomp.ControlPlane{ - { - ID: "12345", - Config: sdkkonnectcomp.ControlPlaneConfig{ - ControlPlaneEndpoint: "https://control-plane-endpoint", - TelemetryEndpoint: "https://telemetry-endpoint", - }, - }, + &sdkkonnectops.UpdateControlPlaneResponse{ + ControlPlane: &sdkkonnectcomp.ControlPlane{ + ID: "001-12345", + Name: "cp-001", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlane, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", }, }, }, - nil, - ) + nil) }, eventuallyPredicate: func(ctx context.Context, t *assert.CollectT, cl client.Client, ns *corev1.Namespace) { cp := &konnectv1alpha2.KonnectGatewayControlPlane{} @@ -89,13 +93,13 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ cl.Get(ctx, k8stypes.NamespacedName{ Namespace: ns.Name, - Name: "cp-1", + Name: "cp-001", }, cp, ), ) - assert.Equal(t, "12345", cp.Status.ID) + assert.Equal(t, "001-12345", cp.Status.ID) assert.True(t, conditionsContainProgrammedTrue(cp.Status.Conditions), "Programmed condition should be set and it status should be true", ) @@ -114,19 +118,19 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ deploy.KonnectGatewayControlPlane(t, ctx, cl, auth, func(obj client.Object) { cp := obj.(*konnectv1alpha2.KonnectGatewayControlPlane) - cp.Name = "cp-groupmember-1" - cp.SetKonnectName("cp-groupmember-1") + cp.Name = "cp-groupmember-001" + cp.SetKonnectName("cp-groupmember-001") }, ) deploy.KonnectGatewayControlPlane(t, ctx, cl, auth, func(obj client.Object) { cp := obj.(*konnectv1alpha2.KonnectGatewayControlPlane) - cp.Name = "cp-2" - cp.SetKonnectName("cp-2") + cp.Name = "cp-002" + cp.SetKonnectName("cp-002") cp.SetKonnectClusterType(new(sdkkonnectcomp.CreateControlPlaneRequestClusterTypeClusterTypeControlPlaneGroup)) cp.Spec.Members = []corev1.LocalObjectReference{ { - Name: "cp-groupmember-1", + Name: "cp-groupmember-001", }, } }, @@ -137,13 +141,19 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ CreateControlPlane( mock.Anything, mock.MatchedBy(func(req sdkkonnectcomp.CreateControlPlaneRequest) bool { - return req.Name == "cp-groupmember-1" + return req.Name == "cp-groupmember-001" }), ). Return( &sdkkonnectops.CreateControlPlaneResponse{ ControlPlane: &sdkkonnectcomp.ControlPlane{ - ID: "12345", + ID: "001-12345-001", + Name: "cp-groupmember-001", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlane, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, }, }, nil) @@ -151,50 +161,33 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ CreateControlPlane( mock.Anything, mock.MatchedBy(func(req sdkkonnectcomp.CreateControlPlaneRequest) bool { - return req.Name == "cp-2" && - req.ClusterType != nil && *req.ClusterType == sdkkonnectcomp.CreateControlPlaneRequestClusterTypeClusterTypeControlPlaneGroup + return req.Name == "cp-002" && + req.ClusterType != nil && + *req.ClusterType == sdkkonnectcomp.CreateControlPlaneRequestClusterTypeClusterTypeControlPlaneGroup }), ). Return( &sdkkonnectops.CreateControlPlaneResponse{ ControlPlane: &sdkkonnectcomp.ControlPlane{ - ID: "12346", - }, - }, - nil) - - sdk.ControlPlaneSDK.EXPECT(). - ListControlPlanes( - mock.Anything, - mock.MatchedBy(func(r sdkkonnectops.ListControlPlanesRequest) bool { - return *r.Filter.ID.Eq == "12346" - }), - ). - Return( - &sdkkonnectops.ListControlPlanesResponse{ - ListControlPlanesResponse: &sdkkonnectcomp.ListControlPlanesResponse{ - Data: []sdkkonnectcomp.ControlPlane{ - { - ID: "12346", - Config: sdkkonnectcomp.ControlPlaneConfig{ - ControlPlaneEndpoint: "https://control-plane-endpoint", - TelemetryEndpoint: "https://telemetry-endpoint", - }, - }, + ID: "002-12346", + Name: "cp-002", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlaneGroup, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", }, }, }, - nil, - ) + nil) sdk.ControlPlaneGroupSDK.EXPECT(). PutControlPlanesIDGroupMemberships( mock.Anything, - "12346", + "002-12346", &sdkkonnectcomp.GroupMembership{ Members: []sdkkonnectcomp.Members{ { - ID: "12345", + ID: "001-12345-001", }, }, }, @@ -207,15 +200,46 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ sdk.ControlPlaneSDK.EXPECT(). UpdateControlPlane( mock.Anything, - "12346", + "002-12346", + mock.MatchedBy(func(req sdkkonnectcomp.UpdateControlPlaneRequest) bool { + return req.Name != nil && *req.Name == "cp-002" + }), + ). + Return( + &sdkkonnectops.UpdateControlPlaneResponse{ + ControlPlane: &sdkkonnectcomp.ControlPlane{ + ID: "002-12346", + Name: "cp-002", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlaneGroup, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, + }, + }, + nil). + // NOTE: UpdateControlPlane can be called depending on the order + // of the events in the queue: either the group itself or the member + // control plane can be created first. + Maybe() + sdk.ControlPlaneSDK.EXPECT(). + UpdateControlPlane( + mock.Anything, + "001-12345-001", mock.MatchedBy(func(req sdkkonnectcomp.UpdateControlPlaneRequest) bool { - return req.Name != nil && *req.Name == "cp-2" + return req.Name != nil && *req.Name == "cp-groupmember-001" }), ). Return( &sdkkonnectops.UpdateControlPlaneResponse{ ControlPlane: &sdkkonnectcomp.ControlPlane{ - ID: "12346", + ID: "001-12345-001", + Name: "cp-groupmember-001", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlane, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, }, }, nil). @@ -230,13 +254,13 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ cl.Get(ctx, k8stypes.NamespacedName{ Namespace: ns.Name, - Name: "cp-groupmember-1", + Name: "cp-groupmember-001", }, cp, ), ) - assert.Equal(t, "12345", cp.Status.ID) + assert.Equal(t, "001-12345-001", cp.Status.ID) assert.True(t, conditionsContainProgrammedTrue(cp.Status.Conditions), "Programmed condition should be set and it status should be true", ) @@ -252,13 +276,13 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ cl.Get(ctx, k8stypes.NamespacedName{ Namespace: ns.Name, - Name: "cp-2", + Name: "cp-002", }, cpGroup, ), ) - assert.Equal(t, "12346", cpGroup.Status.ID) + assert.Equal(t, "002-12346", cpGroup.Status.ID) assert.True(t, conditionsContainProgrammedTrue(cpGroup.Status.Conditions), "Programmed condition should be set and it status should be true", ) @@ -287,8 +311,8 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ deploy.KonnectGatewayControlPlane(t, ctx, cl, auth, func(obj client.Object) { cp := obj.(*konnectv1alpha2.KonnectGatewayControlPlane) - cp.Name = "cp-3" - cp.SetKonnectName("cp-3") + cp.Name = "003-cp" + cp.SetKonnectName("003-cp") cp.SetKonnectClusterType(new(sdkkonnectcomp.CreateControlPlaneRequestClusterTypeClusterTypeControlPlaneGroup)) cp.Spec.Members = []corev1.LocalObjectReference{ { @@ -309,7 +333,13 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ Return( &sdkkonnectops.CreateControlPlaneResponse{ ControlPlane: &sdkkonnectcomp.ControlPlane{ - ID: "12345", + ID: "id-cp-groupmember-2", + Name: "cp-groupmember-2", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlane, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, }, }, nil, @@ -318,7 +348,7 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ CreateControlPlane( mock.Anything, mock.MatchedBy(func(req sdkkonnectcomp.CreateControlPlaneRequest) bool { - return req.Name == "cp-3" && + return req.Name == "003-cp" && req.ClusterType != nil && *req.ClusterType == sdkkonnectcomp.CreateControlPlaneRequestClusterTypeClusterTypeControlPlaneGroup }), @@ -326,7 +356,13 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ Return( &sdkkonnectops.CreateControlPlaneResponse{ ControlPlane: &sdkkonnectcomp.ControlPlane{ - ID: "123467", + ID: "003-cp", + Name: "003-cp", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlaneGroup, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, }, }, nil, @@ -335,11 +371,11 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ sdk.ControlPlaneGroupSDK.EXPECT(). PutControlPlanesIDGroupMemberships( mock.Anything, - "123467", + "003-cp", &sdkkonnectcomp.GroupMembership{ Members: []sdkkonnectcomp.Members{ { - ID: "12345", + ID: "id-cp-groupmember-2", }, }, }, @@ -350,41 +386,49 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ ) sdk.ControlPlaneSDK.EXPECT(). - ListControlPlanes( + UpdateControlPlane( mock.Anything, - mock.MatchedBy(func(r sdkkonnectops.ListControlPlanesRequest) bool { - return *r.Filter.ID.Eq == "123467" + "003-cp", + mock.MatchedBy(func(req sdkkonnectcomp.UpdateControlPlaneRequest) bool { + return req.Name != nil && *req.Name == "003-cp" }), ). Return( - &sdkkonnectops.ListControlPlanesResponse{ - ListControlPlanesResponse: &sdkkonnectcomp.ListControlPlanesResponse{ - Data: []sdkkonnectcomp.ControlPlane{ - { - ID: "123467", - Config: sdkkonnectcomp.ControlPlaneConfig{ - ControlPlaneEndpoint: "https://control-plane-endpoint", - TelemetryEndpoint: "https://telemetry-endpoint", - }, - }, + &sdkkonnectops.UpdateControlPlaneResponse{ + ControlPlane: &sdkkonnectcomp.ControlPlane{ + ID: "003-cp", + Name: "003-cp", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlaneGroup, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", }, }, }, nil, - ) - + ). + // NOTE: UpdateControlPlane can be called depending on the order + // of the events in the queue: either the group itself or the member + // control plane can be created first. + Maybe() sdk.ControlPlaneSDK.EXPECT(). UpdateControlPlane( mock.Anything, - "123467", + "id-cp-groupmember-2", mock.MatchedBy(func(req sdkkonnectcomp.UpdateControlPlaneRequest) bool { - return req.Name != nil && *req.Name == "cp-3" + return req.Name != nil && *req.Name == "cp-groupmember-2" }), ). Return( &sdkkonnectops.UpdateControlPlaneResponse{ ControlPlane: &sdkkonnectcomp.ControlPlane{ - ID: "123467", + ID: "id-cp-groupmember-2", + Name: "cp-groupmember-2", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlaneGroup, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, }, }, nil, @@ -418,13 +462,13 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ cl.Get(ctx, k8stypes.NamespacedName{ Namespace: ns.Name, - Name: "cp-3", + Name: "003-cp", }, cpGroup, ), ) - assert.Equal(t, "123467", cpGroup.Status.ID) + assert.Equal(t, "003-cp", cpGroup.Status.ID) assert.True(t, conditionsContainProgrammedFalse(cpGroup.Status.Conditions), "Programmed condition should be set and its status should be false because of an error returned by Konnect API when setting group members", ) @@ -443,8 +487,8 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ deploy.KonnectGatewayControlPlane(t, ctx, cl, auth, func(obj client.Object) { cp := obj.(*konnectv1alpha2.KonnectGatewayControlPlane) - cp.Name = "cp-4" - cp.SetKonnectName("cp-4") + cp.Name = "cp-004" + cp.SetKonnectName("cp-004") }, ) }, @@ -453,7 +497,7 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ CreateControlPlane( mock.Anything, mock.MatchedBy(func(req sdkkonnectcomp.CreateControlPlaneRequest) bool { - return req.Name == "cp-4" + return req.Name == "cp-004" }), ). Return( @@ -466,7 +510,7 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ mock.Anything, mock.MatchedBy(func(r sdkkonnectops.ListControlPlanesRequest) bool { var cp konnectv1alpha2.KonnectGatewayControlPlane - require.NoError(t, cl.Get(t.Context(), client.ObjectKey{Name: "cp-4"}, &cp)) + require.NoError(t, cl.Get(t.Context(), client.ObjectKey{Name: "cp-004"}, &cp)) // On conflict, we list cps by UID and check if there is already one created. return r.FilterLabels != nil && *r.FilterLabels == ops.KubernetesUIDLabelKey+":"+string(cp.UID) }), @@ -476,32 +520,10 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ ListControlPlanesResponse: &sdkkonnectcomp.ListControlPlanesResponse{ Data: []sdkkonnectcomp.ControlPlane{ { - ID: "123456", - Config: sdkkonnectcomp.ControlPlaneConfig{ - ControlPlaneEndpoint: "https://control-plane-endpoint", - TelemetryEndpoint: "https://telemetry-endpoint", - }, - }, - }, - }, - }, - nil, - ) - - sdk.ControlPlaneSDK.EXPECT(). - ListControlPlanes( - mock.Anything, - mock.MatchedBy(func(r sdkkonnectops.ListControlPlanesRequest) bool { - return *r.Filter.ID.Eq == "123456" - }), - ). - Return( - &sdkkonnectops.ListControlPlanesResponse{ - ListControlPlanesResponse: &sdkkonnectcomp.ListControlPlanesResponse{ - Data: []sdkkonnectcomp.ControlPlane{ - { - ID: "123456", + ID: "004-123456", + Name: "cp-004", Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlane, ControlPlaneEndpoint: "https://control-plane-endpoint", TelemetryEndpoint: "https://telemetry-endpoint", }, @@ -518,13 +540,13 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ cl.Get(ctx, k8stypes.NamespacedName{ Namespace: ns.Name, - Name: "cp-4", + Name: "cp-004", }, cp, ), ) - assert.Equal(t, "123456", cp.Status.ID, "ID should be set") + assert.Equal(t, "004-123456", cp.Status.ID, "ID should be set") assert.True(t, conditionsContainProgrammedTrue(cp.Status.Conditions), "Programmed condition should be set and its status should be true", ) @@ -543,19 +565,19 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ deploy.KonnectGatewayControlPlane(t, ctx, cl, auth, func(obj client.Object) { cp := obj.(*konnectv1alpha2.KonnectGatewayControlPlane) - cp.Name = "cp-5" - cp.SetKonnectName("cp-5") + cp.Name = "005-cp-001" + cp.SetKonnectName("005-cp-001") }, ) deploy.KonnectGatewayControlPlane(t, ctx, cl, auth, func(obj client.Object) { cp := obj.(*konnectv1alpha2.KonnectGatewayControlPlane) - cp.Name = "cp-group-1" - cp.SetKonnectName("cp-group-1") + cp.Name = "005-cp-group" + cp.SetKonnectName("005-cp-group") cp.SetKonnectClusterType(new(sdkkonnectcomp.CreateControlPlaneRequestClusterTypeClusterTypeControlPlaneGroup)) cp.Spec.Members = []corev1.LocalObjectReference{ - {Name: "cp-5"}, + {Name: "005-cp-001"}, } }, ) @@ -565,13 +587,19 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ CreateControlPlane( mock.Anything, mock.MatchedBy(func(req sdkkonnectcomp.CreateControlPlaneRequest) bool { - return req.Name == "cp-5" + return req.Name == "005-cp-001" }), ). Return( &sdkkonnectops.CreateControlPlaneResponse{ ControlPlane: &sdkkonnectcomp.ControlPlane{ - ID: "123456", + ID: "005-cp-001", + Name: "005-cp-001", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlane, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, }, }, nil, ) @@ -580,7 +608,7 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ CreateControlPlane( mock.Anything, mock.MatchedBy(func(req sdkkonnectcomp.CreateControlPlaneRequest) bool { - return req.Name == "cp-group-1" + return req.Name == "005-cp-group" }), ). Return( @@ -593,7 +621,7 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ mock.Anything, mock.MatchedBy(func(r sdkkonnectops.ListControlPlanesRequest) bool { var cp konnectv1alpha2.KonnectGatewayControlPlane - require.NoError(t, cl.Get(t.Context(), client.ObjectKey{Name: "cp-group-1"}, &cp)) + require.NoError(t, cl.Get(t.Context(), client.ObjectKey{Name: "005-cp-group"}, &cp)) // On conflict, we list cps by UID and check if there is already one created. return r.FilterLabels != nil && *r.FilterLabels == ops.KubernetesUIDLabelKey+":"+string(cp.UID) }), @@ -603,56 +631,10 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ ListControlPlanesResponse: &sdkkonnectcomp.ListControlPlanesResponse{ Data: []sdkkonnectcomp.ControlPlane{ { - ID: "group-123456", - Config: sdkkonnectcomp.ControlPlaneConfig{ - ControlPlaneEndpoint: "https://control-plane-endpoint", - TelemetryEndpoint: "https://telemetry-endpoint", - }, - }, - }, - }, - }, - nil, - ) - - sdk.ControlPlaneSDK.EXPECT(). - ListControlPlanes( - mock.Anything, - mock.MatchedBy(func(r sdkkonnectops.ListControlPlanesRequest) bool { - return *r.Filter.ID.Eq == "group-123456" - }), - ). - Return( - &sdkkonnectops.ListControlPlanesResponse{ - ListControlPlanesResponse: &sdkkonnectcomp.ListControlPlanesResponse{ - Data: []sdkkonnectcomp.ControlPlane{ - { - ID: "group-123456", - Config: sdkkonnectcomp.ControlPlaneConfig{ - ControlPlaneEndpoint: "https://control-plane-endpoint", - TelemetryEndpoint: "https://telemetry-endpoint", - }, - }, - }, - }, - }, - nil, - ) - - sdk.ControlPlaneSDK.EXPECT(). - ListControlPlanes( - mock.Anything, - mock.MatchedBy(func(r sdkkonnectops.ListControlPlanesRequest) bool { - return *r.Filter.ID.Eq == "123456" - }), - ). - Return( - &sdkkonnectops.ListControlPlanesResponse{ - ListControlPlanesResponse: &sdkkonnectcomp.ListControlPlanesResponse{ - Data: []sdkkonnectcomp.ControlPlane{ - { - ID: "123456", + ID: "005-cp-group", + Name: "005-cp-group", Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlaneGroup, ControlPlaneEndpoint: "https://control-plane-endpoint", TelemetryEndpoint: "https://telemetry-endpoint", }, @@ -666,11 +648,11 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ sdk.ControlPlaneGroupSDK.EXPECT(). PutControlPlanesIDGroupMemberships( mock.Anything, - "group-123456", + "005-cp-group", &sdkkonnectcomp.GroupMembership{ Members: []sdkkonnectcomp.Members{ { - ID: "123456", + ID: "005-cp-001", }, }, }, @@ -680,15 +662,21 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ sdk.ControlPlaneSDK.EXPECT(). UpdateControlPlane( mock.Anything, - "group-123456", + "005-cp-001", mock.MatchedBy(func(req sdkkonnectcomp.UpdateControlPlaneRequest) bool { - return req.Name != nil && *req.Name == "cp-group-1" + return req.Name != nil && *req.Name == "005-cp-001" }), ). Return( &sdkkonnectops.UpdateControlPlaneResponse{ ControlPlane: &sdkkonnectcomp.ControlPlane{ - ID: "group-123456", + ID: "005-cp-001", + Name: "005-cp-001", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlane, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, }, }, nil, @@ -704,13 +692,13 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ cl.Get(ctx, k8stypes.NamespacedName{ Namespace: ns.Name, - Name: "cp-group-1", + Name: "005-cp-group", }, cpGroup, ), ) - assert.Equal(t, "group-123456", cpGroup.Status.ID, "ID should be set") + assert.Equal(t, "005-cp-group", cpGroup.Status.ID, "ID should be set") assert.True(t, conditionsContainProgrammedTrue(cpGroup.Status.Conditions), "Programmed condition should be set and its status should be true", ) @@ -723,8 +711,7 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ }, }, { - enabled: true, - name: "control plane group members set are set to 0 members when no members are listed in the spec", + name: "control plane group members set are set to 0 members when no members are listed in the spec", objectOps: func(ctx context.Context, t *testing.T, cl client.Client, ns *corev1.Namespace) { auth := deploy.KonnectAPIAuthConfigurationWithProgrammed(t, ctx, cl) deploy.KonnectGatewayControlPlane(t, ctx, cl, auth, @@ -737,30 +724,6 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ ) }, mockExpectations: func(t *testing.T, sdk *sdkmocks.MockSDKWrapper, cl client.Client, ns *corev1.Namespace) { - sdk.ControlPlaneSDK.EXPECT(). - ListControlPlanes( - mock.Anything, - mock.MatchedBy(func(r sdkkonnectops.ListControlPlanesRequest) bool { - return *r.Filter.ID.Eq == "cpg-id" - }), - ). - Return( - &sdkkonnectops.ListControlPlanesResponse{ - ListControlPlanesResponse: &sdkkonnectcomp.ListControlPlanesResponse{ - Data: []sdkkonnectcomp.ControlPlane{ - { - ID: "cpg-id", - Config: sdkkonnectcomp.ControlPlaneConfig{ - ControlPlaneEndpoint: "https://control-plane-endpoint", - TelemetryEndpoint: "https://telemetry-endpoint", - }, - }, - }, - }, - }, - nil, - ) - sdk.ControlPlaneSDK.EXPECT(). CreateControlPlane( mock.Anything, @@ -771,7 +734,13 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ Return( &sdkkonnectops.CreateControlPlaneResponse{ ControlPlane: &sdkkonnectcomp.ControlPlane{ - ID: "cpg-id", + ID: "cpg-id-no-members", + Name: "cp-group-no-members", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlane, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, }, }, nil, @@ -780,12 +749,39 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ sdk.ControlPlaneGroupSDK.EXPECT(). PutControlPlanesIDGroupMemberships( mock.Anything, - "cpg-id", + "cpg-id-no-members", &sdkkonnectcomp.GroupMembership{ Members: []sdkkonnectcomp.Members{}, }, ). Return(&sdkkonnectops.PutControlPlanesIDGroupMembershipsResponse{}, nil) + + sdk.ControlPlaneSDK.EXPECT(). + UpdateControlPlane( + mock.Anything, + "cpg-id-no-members", + mock.MatchedBy(func(req sdkkonnectcomp.UpdateControlPlaneRequest) bool { + return req.Name != nil && *req.Name == "cp-group-no-members" + }), + ). + Return( + &sdkkonnectops.UpdateControlPlaneResponse{ + ControlPlane: &sdkkonnectcomp.ControlPlane{ + ID: "cpg-id-no-members", + Name: "cp-group-no-members", + Config: sdkkonnectcomp.ControlPlaneConfig{ + ClusterType: sdkkonnectcomp.ControlPlaneClusterTypeClusterTypeControlPlaneGroup, + ControlPlaneEndpoint: "https://control-plane-endpoint", + TelemetryEndpoint: "https://telemetry-endpoint", + }, + }, + }, + nil, + ). + // NOTE: UpdateControlPlane can be called depending on the order + // of the events in the queue: either the group itself or the member + // control plane can be created first. + Maybe() }, eventuallyPredicate: func(ctx context.Context, t *assert.CollectT, cl client.Client, ns *corev1.Namespace) { cpGroup := &konnectv1alpha2.KonnectGatewayControlPlane{} @@ -799,7 +795,7 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ ), ) - assert.Equal(t, "cpg-id", cpGroup.Status.ID, "ID should be set") + assert.Equal(t, "cpg-id-no-members", cpGroup.Status.ID, "ID should be set") assert.True(t, conditionsContainProgrammedTrue(cpGroup.Status.Conditions), "Programmed condition should be set and its status should be true", ) @@ -812,8 +808,7 @@ var konnectGatewayControlPlaneTestCases = []konnectEntityReconcilerTestCase{ }, }, { - enabled: true, - name: "network error sets Programmed condition to False", + name: "network error sets Programmed condition to False", objectOps: func(ctx context.Context, t *testing.T, cl client.Client, ns *corev1.Namespace) { auth := deploy.KonnectAPIAuthConfigurationWithProgrammed(t, ctx, cl) deploy.KonnectGatewayControlPlane(t, ctx, cl, auth, diff --git a/test/envtest/konnect_entities_suite_test.go b/test/envtest/konnect_entities_suite_test.go index c2b863be6f..24b6cf3c8c 100644 --- a/test/envtest/konnect_entities_suite_test.go +++ b/test/envtest/konnect_entities_suite_test.go @@ -30,7 +30,6 @@ func TestKonnectEntityReconcilers(t *testing.T) { } type konnectEntityReconcilerTestCase struct { - enabled bool name string objectOps func(ctx context.Context, t *testing.T, cl client.Client, ns *corev1.Namespace) mockExpectations func(t *testing.T, sdk *sdkmocks.MockSDKWrapper, cl client.Client, ns *corev1.Namespace) @@ -81,9 +80,6 @@ func testNewKonnectEntityReconciler[ for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - if !tc.enabled { - t.Skip("test case disabled") - } tc.mockExpectations(t, sdk, cl, ns) tc.objectOps(ctx, t, cl, ns) require.EventuallyWithT(t, func(collect *assert.CollectT) {