From 5eb3b6a2115230c0bfd83a01338bda45b9314b28 Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Wed, 4 Dec 2024 18:58:13 -0600 Subject: [PATCH 1/2] fix: EnvoyExtensionPolicy reference grant Signed-off-by: Guy Daich --- internal/provider/kubernetes/controller.go | 2 +- .../provider/kubernetes/controller_test.go | 164 ++++++++++++++++++ internal/provider/kubernetes/indexers.go | 12 +- 3 files changed, 173 insertions(+), 5 deletions(-) diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index 28a0eafaa77..f71ebee9520 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -2088,7 +2088,7 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs( if backendNamespace != policy.Namespace { from := ObjectKindNamespacedName{ - kind: resource.KindHTTPRoute, + kind: resource.KindEnvoyExtensionPolicy, namespace: policy.Namespace, name: policy.Name, } diff --git a/internal/provider/kubernetes/controller_test.go b/internal/provider/kubernetes/controller_test.go index c1cece27733..53ac5f83bdd 100644 --- a/internal/provider/kubernetes/controller_test.go +++ b/internal/provider/kubernetes/controller_test.go @@ -9,11 +9,16 @@ import ( "context" "testing" + + "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/envoygateway" @@ -288,3 +293,162 @@ func TestProcessGatewayClassParamsRef(t *testing.T) { }) } } + +func TestProcessEnvoyExtensionPolicyObjectRefs(t *testing.T) { + testCases := []struct { + name string + envoyExtensionPolicy *egv1a1.EnvoyExtensionPolicy + backend *egv1a1.Backend + referenceGrant *gwapiv1b1.ReferenceGrant + shouldBeAdded bool + }{ + { + name: "valid envoy extension policy with proper ref grant to backend", + envoyExtensionPolicy: &egv1a1.EnvoyExtensionPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns-1", + Name: "test-policy", + }, + Spec: egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Namespace: gatewayapi.NamespacePtr("ns-2"), + Name: "test-backend", + Kind: gatewayapi.KindPtr(resource.KindBackend), + Group: gatewayapi.GroupPtr(egv1a1.GroupName), + }, + }, + }, + }, + }, + }, + }, + }, + backend: &egv1a1.Backend{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns-2", + Name: "test-backend", + }, + }, + referenceGrant: &gwapiv1b1.ReferenceGrant{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns-2", + Name: "test-grant", + }, + Spec: gwapiv1b1.ReferenceGrantSpec{ + From: []gwapiv1b1.ReferenceGrantFrom{ + { + Namespace: gwapiv1.Namespace("ns-1"), + Kind: gwapiv1.Kind(resource.KindEnvoyExtensionPolicy), + Group: gwapiv1.Group(egv1a1.GroupName), + }, + }, + To: []gwapiv1b1.ReferenceGrantTo{ + { + Name: gatewayapi.ObjectNamePtr("test-backend"), + Kind: gwapiv1.Kind(resource.KindBackend), + Group: gwapiv1.Group(egv1a1.GroupName), + }, + }, + }, + }, + shouldBeAdded: true, + }, + { + name: "valid envoy extension policy with wrong from kind in ref grant to backend", + envoyExtensionPolicy: &egv1a1.EnvoyExtensionPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns-1", + Name: "test-policy", + }, + Spec: egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Namespace: gatewayapi.NamespacePtr("ns-2"), + Name: "test-backend", + Kind: gatewayapi.KindPtr(resource.KindBackend), + Group: gatewayapi.GroupPtr(egv1a1.GroupName), + }, + }, + }, + }, + }, + }, + }, + }, + backend: &egv1a1.Backend{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns-2", + Name: "test-backend", + }, + }, + referenceGrant: &gwapiv1b1.ReferenceGrant{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns-2", + Name: "test-grant", + }, + Spec: gwapiv1b1.ReferenceGrantSpec{ + From: []gwapiv1b1.ReferenceGrantFrom{ + { + Namespace: gwapiv1.Namespace("ns-1"), + Kind: gwapiv1.Kind(resource.KindHTTPRoute), + Group: gwapiv1.Group(gwapiv1.GroupName), + }, + }, + To: []gwapiv1b1.ReferenceGrantTo{ + { + Name: gatewayapi.ObjectNamePtr("test-backend"), + Kind: gwapiv1.Kind(resource.KindBackend), + Group: gwapiv1.Group(egv1a1.GroupName), + }, + }, + }, + }, + shouldBeAdded: false, + }, + } + + for i := range testCases { + tc := testCases[i] + // Run the test cases. + t.Run(tc.name, func(t *testing.T) { + // Add objects referenced by test cases. + objs := []client.Object{tc.envoyExtensionPolicy, tc.backend, tc.referenceGrant} + + // Create the reconciler. + logger := logging.DefaultLogger(egv1a1.LogLevelInfo) + + ctx := context.Background() + + r := &gatewayAPIReconciler{ + log: logger, + classController: "some-gateway-class", + } + + r.client = fakeclient.NewClientBuilder(). + WithScheme(envoygateway.GetScheme()). + WithObjects(objs...). + WithIndex(&gwapiv1b1.ReferenceGrant{}, targetRefGrantRouteIndex, getReferenceGrantIndexerFunc()). + Build() + + resourceTree := resource.NewResources() + resourceMap := newResourceMapping() + + err := r.processEnvoyExtensionPolicies(ctx, resourceTree, resourceMap) + require.NoError(t, err) + if tc.shouldBeAdded { + require.Contains(t, resourceTree.ReferenceGrants, tc.referenceGrant) + } else { + require.NotContains(t, resourceTree.ReferenceGrants, tc.referenceGrant) + } + }) + } +} diff --git a/internal/provider/kubernetes/indexers.go b/internal/provider/kubernetes/indexers.go index 031a2657a9c..7626ea32d52 100644 --- a/internal/provider/kubernetes/indexers.go +++ b/internal/provider/kubernetes/indexers.go @@ -52,17 +52,21 @@ const ( ) func addReferenceGrantIndexers(ctx context.Context, mgr manager.Manager) error { - if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1b1.ReferenceGrant{}, targetRefGrantRouteIndex, func(rawObj client.Object) []string { + if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1b1.ReferenceGrant{}, targetRefGrantRouteIndex, getReferenceGrantIndexerFunc()); err != nil { + return err + } + return nil +} + +func getReferenceGrantIndexerFunc() func(rawObj client.Object) []string { + return func(rawObj client.Object) []string { refGrant := rawObj.(*gwapiv1b1.ReferenceGrant) var referredServices []string for _, target := range refGrant.Spec.To { referredServices = append(referredServices, string(target.Kind)) } return referredServices - }); err != nil { - return err } - return nil } // addHTTPRouteIndexers adds indexing on HTTPRoute. From 75aa10483b499cfc5c1bf9091dee05685b952149 Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Wed, 4 Dec 2024 19:13:55 -0600 Subject: [PATCH 2/2] fix lint, add release note Signed-off-by: Guy Daich --- internal/provider/kubernetes/controller_test.go | 3 --- release-notes/current.yaml | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/provider/kubernetes/controller_test.go b/internal/provider/kubernetes/controller_test.go index 53ac5f83bdd..d008e7b2f70 100644 --- a/internal/provider/kubernetes/controller_test.go +++ b/internal/provider/kubernetes/controller_test.go @@ -9,9 +9,6 @@ import ( "context" "testing" - - "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" diff --git a/release-notes/current.yaml b/release-notes/current.yaml index d1c6dd95c06..6ba9c2ee5cb 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -17,6 +17,7 @@ new features: | # Fixes for bugs identified in previous versions. bug fixes: | + Fixed reference grant from EnvoyExtensionPolicy to referenced ext-proc backend not respected # Enhancements that improve performance. performance improvements: |