From 9e722e64561a6f3738e93e2ac807989f4cea1379 Mon Sep 17 00:00:00 2001 From: Mattia Lavacca Date: Wed, 9 Oct 2024 17:15:25 +0200 Subject: [PATCH] chore Signed-off-by: Mattia Lavacca --- controller/dataplane/controller_utils.go | 24 ++++-- controller/dataplane/konnect_extension.go | 7 +- .../dataplane/konnect_extension_test.go | 74 +++++++++++++++++-- 3 files changed, 88 insertions(+), 17 deletions(-) diff --git a/controller/dataplane/controller_utils.go b/controller/dataplane/controller_utils.go index 97d44f29c..fe1f25a77 100644 --- a/controller/dataplane/controller_utils.go +++ b/controller/dataplane/controller_utils.go @@ -3,6 +3,7 @@ package dataplane import ( "context" "encoding/json" + "errors" "fmt" "os" @@ -313,26 +314,35 @@ func isDeploymentReady(deploymentStatus appsv1.DeploymentStatus) (metav1.Conditi // DataPlane - Private Functions - extensions // ----------------------------------------------------------------------------- +// applyExtensions patches the dataplane spec by taking into account customizations from the referenced extensions. +// In case any extension is referenced, it adds a resolvedRefs condition to the dataplane, indicating the status of the +// extension reference. it returns 3 values: +// - patched: a boolean indicating if the dataplane was patched. If the dataplane was patched, a reconciliation loop will be automatically re-triggered. +// - requeue: a boolean indicating if the dataplane should be requeued. If the error was unexpected (e.g., because of API server error), the dataplane should be requeued. +// In case the error is related to a misconfiguration, the dataplane does not need to be requeued, and feedback is provided into the dataplane status. +// - err: an error in case of failure. func applyExtensions(ctx context.Context, cl client.Client, logger logr.Logger, dataplane *operatorv1beta1.DataPlane) (patched bool, requeue bool, err error) { + if len(dataplane.Spec.Extensions) == 0 { + return false, false, nil + } condition := k8sutils.NewConditionWithGeneration(consts.ResolvedRefsType, metav1.ConditionTrue, consts.ResolvedRefsReason, "", dataplane.GetGeneration()) err = applyDataPlaneKonnectExtension(ctx, cl, dataplane) if err != nil { - switch err { - case ErrCrossNamespaceReference: + switch { + case errors.Is(err, ErrCrossNamespaceReference): condition.Status = metav1.ConditionFalse condition.Reason = string(consts.RefNotPermittedReason) condition.Message = consts.RefNotPermittedMessage - case ErrKonnectExtensionNotFound: + case errors.Is(err, ErrKonnectExtensionNotFound): condition.Status = metav1.ConditionFalse condition.Reason = string(consts.InvalidExtensionRefReason) condition.Message = consts.InvalidExtensionRefMessage - case ErrClusterCertificateNotFound: + case errors.Is(err, ErrClusterCertificateNotFound): condition.Status = metav1.ConditionFalse condition.Reason = string(consts.InvalidSecretRefReason) condition.Message = consts.InvalidSecretRefMessage default: - requeue = false - return + return patched, true, err } } newDataPlane := dataplane.DeepCopy() @@ -341,5 +351,5 @@ func applyExtensions(ctx context.Context, cl client.Client, logger logr.Logger, if patchErr != nil { return false, true, fmt.Errorf("failed patching status for DataPlane %s/%s: %w", dataplane.Namespace, dataplane.Name, patchErr) } - return + return patched, false, nil } diff --git a/controller/dataplane/konnect_extension.go b/controller/dataplane/konnect_extension.go index 14190cc7c..6365c037b 100644 --- a/controller/dataplane/konnect_extension.go +++ b/controller/dataplane/konnect_extension.go @@ -19,8 +19,11 @@ import ( ) var ( - ErrCrossNamespaceReference = errors.New("cross-namespace reference is not currently supported for Konnect extensions") - ErrKonnectExtensionNotFound = errors.New("konnect extension not found") + // ErrCrossNamespaceReference is returned when a Konnect extension references a different namespace. + ErrCrossNamespaceReference = errors.New("cross-namespace reference is not currently supported for Konnect extensions") + // ErrKonnectExtensionNotFound is returned when a Konnect extension is not found. + ErrKonnectExtensionNotFound = errors.New("konnect extension not found") + // ErrClusterCertificateNotFound is returned when a cluster certificate secret referenced in the KonnectExtension is not found. ErrClusterCertificateNotFound = errors.New("cluster certificate not found") ) diff --git a/controller/dataplane/konnect_extension_test.go b/controller/dataplane/konnect_extension_test.go index 947263941..780b17466 100644 --- a/controller/dataplane/konnect_extension_test.go +++ b/controller/dataplane/konnect_extension_test.go @@ -32,7 +32,8 @@ func TestApplyDataPlaneKonnectExtension(t *testing.T) { name string dataplane *operatorv1beta1.DataPlane konnectExt *operatorv1alpha1.DataPlaneKonnectExtension - expectedError bool + secret *corev1.Secret + expectedError error }{ { name: "no extensions", @@ -43,7 +44,6 @@ func TestApplyDataPlaneKonnectExtension(t *testing.T) { }, }, }, - expectedError: false, }, { name: "cross-namespace reference", @@ -89,7 +89,7 @@ func TestApplyDataPlaneKonnectExtension(t *testing.T) { ServerHostname: "konnect.example.com", }, }, - expectedError: true, + expectedError: ErrCrossNamespaceReference, }, { name: "Extension not found", @@ -116,7 +116,52 @@ func TestApplyDataPlaneKonnectExtension(t *testing.T) { }, }, }, - expectedError: true, + expectedError: ErrKonnectExtensionNotFound, + }, + { + name: "Extension properly referenced, secret not found", + dataplane: &operatorv1beta1.DataPlane{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + }, + Spec: operatorv1beta1.DataPlaneSpec{ + DataPlaneOptions: operatorv1beta1.DataPlaneOptions{ + Extensions: []operatorv1alpha1.ExtensionRef{ + { + Group: operatorv1alpha1.SchemeGroupVersion.Group, + Kind: operatorv1alpha1.DataPlaneKonnectExtensionKind, + NamespacedRef: operatorv1alpha1.NamespacedRef{ + Name: "konnect-ext", + }, + }, + }, + Deployment: operatorv1beta1.DataPlaneDeploymentOptions{ + DeploymentOptions: operatorv1beta1.DeploymentOptions{ + PodTemplateSpec: &corev1.PodTemplateSpec{}, + }, + }, + }, + }, + }, + konnectExt: &operatorv1alpha1.DataPlaneKonnectExtension{ + ObjectMeta: metav1.ObjectMeta{ + Name: "konnect-ext", + Namespace: "default", + }, + Spec: operatorv1alpha1.DataPlaneKonnectExtensionSpec{ + AuthConfiguration: operatorv1alpha1.KonnectControlPlaneAPIAuthConfiguration{ + ClusterCertificateSecretRef: operatorv1alpha1.ClusterCertificateSecretRef{ + Name: "cluster-cert-secret", + }, + }, + ControlPlaneRef: configurationv1alpha1.ControlPlaneRef{ + KonnectID: lo.ToPtr("konnect-id"), + }, + ControlPlaneRegion: "us-west", + ServerHostname: "konnect.example.com", + }, + }, + expectedError: ErrClusterCertificateNotFound, }, { name: "Extension properly referenced, no deployment Options set.", @@ -161,7 +206,12 @@ func TestApplyDataPlaneKonnectExtension(t *testing.T) { ServerHostname: "konnect.example.com", }, }, - expectedError: false, + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-cert-secret", + Namespace: "default", + }, + }, }, { name: "Extension properly referenced, with deployment Options set.", @@ -220,7 +270,12 @@ func TestApplyDataPlaneKonnectExtension(t *testing.T) { ServerHostname: "konnect.example.com", }, }, - expectedError: false, + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-cert-secret", + Namespace: "default", + }, + }, }, } @@ -230,12 +285,15 @@ func TestApplyDataPlaneKonnectExtension(t *testing.T) { if tt.konnectExt != nil { objs = append(objs, tt.konnectExt) } + if tt.secret != nil { + objs = append(objs, tt.secret) + } cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() dataplane := tt.dataplane.DeepCopy() err := applyDataPlaneKonnectExtension(context.Background(), cl, dataplane) - if tt.expectedError { - require.Error(t, err) + if tt.expectedError != nil { + require.ErrorIs(t, err, tt.expectedError) } else { require.NoError(t, err) requiredEnv := []corev1.EnvVar{}