From 365610bf5a01be3265e805b4f01a547b97e4cefe Mon Sep 17 00:00:00 2001 From: danehans Date: Wed, 14 Dec 2022 11:49:07 -0800 Subject: [PATCH] Adds ReferenceGrant Support for Routes Signed-off-by: danehans --- internal/provider/kubernetes/controller.go | 54 +++++++++++++--------- internal/provider/kubernetes/helpers.go | 3 -- internal/provider/kubernetes/routes.go | 44 ++++++++++++------ test/conformance/conformance_test.go | 1 + 4 files changed, 65 insertions(+), 37 deletions(-) diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index 522290ce53..2a4c8a7d23 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -290,15 +290,29 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, request reconcile. r.log.Info("processing Secret", "namespace", secretNamespace, "name", string(certRef.Name)) if secretNamespace != gtw.Namespace { - from := ObjectKindNamespacedName{kind: gatewayapi.KindGateway, namespace: gtw.Namespace, name: gtw.Name} - to := ObjectKindNamespacedName{kind: gatewayapi.KindSecret, namespace: secretNamespace, name: string(certRef.Name)} + from := ObjectKindNamespacedName{ + kind: gatewayapi.KindGateway, + namespace: gtw.Namespace, + name: gtw.Name, + } + to := ObjectKindNamespacedName{ + kind: gatewayapi.KindSecret, + namespace: secretNamespace, + name: string(certRef.Name), + } refGrant, err := r.findReferenceGrant(ctx, from, to) - if err != nil { - r.log.Error(err, "unable to find ReferenceGrant that links the Secret to Gateway") - continue + switch { + case err != nil: + r.log.Error(err, "failed to find ReferenceGrant") + case refGrant == nil: + r.log.Info("no matching ReferenceGrants found", "from", from.kind, + "from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace) + default: + // RefGrant found + resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant + r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace, + "name", refGrant.Name) } - - resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant } resourceMap.allAssociatedNamespaces[secretNamespace] = struct{}{} @@ -329,15 +343,14 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, request reconcile. service := new(corev1.Service) err := r.client.Get(ctx, serviceNamespaceName, service) if err != nil { - r.log.Error(err, "unable to find associated Services") - if kerrors.IsNotFound(err) { - return reconcile.Result{}, nil - } - return reconcile.Result{}, err + r.log.Error(err, "failed to get Service", "namespace", serviceNamespaceName.Namespace, + "name", serviceNamespaceName.Name) + } else { + resourceMap.allAssociatedNamespaces[service.Namespace] = struct{}{} + resourceTree.Services = append(resourceTree.Services, service) + r.log.Info("added Service to resource tree", "namespace", serviceNamespaceName.Namespace, + "name", serviceNamespaceName.Name) } - - resourceMap.allAssociatedNamespaces[service.Namespace] = struct{}{} - resourceTree.Services = append(resourceTree.Services, service) } // Add all ReferenceGrants to the resourceTree @@ -437,10 +450,9 @@ func (r *gatewayAPIReconciler) statusUpdateForGateway(gtw *gwapiv1b1.Gateway, sv func (r *gatewayAPIReconciler) findReferenceGrant(ctx context.Context, from, to ObjectKindNamespacedName) (*gwapiv1a2.ReferenceGrant, error) { refGrantList := new(gwapiv1a2.ReferenceGrantList) - if err := r.client.List(ctx, refGrantList, &client.ListOptions{ - FieldSelector: fields.OneTermEqualSelector(targetRefGrantRouteIndex, to.kind), - }); err != nil { - return nil, err + opts := &client.ListOptions{FieldSelector: fields.OneTermEqualSelector(targetRefGrantRouteIndex, to.kind)} + if err := r.client.List(ctx, refGrantList, opts); err != nil { + return nil, fmt.Errorf("failed to list ReferenceGrants: %v", err) } for _, refGrant := range refGrantList.Items { @@ -453,8 +465,8 @@ func (r *gatewayAPIReconciler) findReferenceGrant(ctx context.Context, from, to } } - return nil, fmt.Errorf("no reference grants found that target %s in namespace %s for kind %s in namespace %s", - to.kind, to.namespace, from.kind, from.namespace) + // No ReferenceGrant found. + return nil, nil } func addReferenceGrantIndexers(ctx context.Context, mgr manager.Manager) error { diff --git a/internal/provider/kubernetes/helpers.go b/internal/provider/kubernetes/helpers.go index aa7348bf0c..1f710e7ff7 100644 --- a/internal/provider/kubernetes/helpers.go +++ b/internal/provider/kubernetes/helpers.go @@ -209,7 +209,6 @@ func infraDeploymentName(gateway *gwapiv1b1.Gateway) string { // - Validating weights. // - Validating ports. // - Referencing HTTPRoutes. -// - Referencing Services/HTTPRoutes from other namespaces using ReferenceGrant. func validateBackendRef(ref *gwapiv1b1.BackendRef) error { switch { case ref == nil: @@ -219,8 +218,6 @@ func validateBackendRef(ref *gwapiv1b1.BackendRef) error { case ref.Kind != nil && *ref.Kind != gatewayapi.KindService: return fmt.Errorf("invalid kind %q; must be %q", *ref.BackendObjectReference.Kind, gatewayapi.KindService) - case ref.Namespace != nil: - return fmt.Errorf("invalid namespace; must be nil") } return nil diff --git a/internal/provider/kubernetes/routes.go b/internal/provider/kubernetes/routes.go index b13a494f81..3c3587d648 100644 --- a/internal/provider/kubernetes/routes.go +++ b/internal/provider/kubernetes/routes.go @@ -52,12 +52,17 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName from := ObjectKindNamespacedName{kind: gatewayapi.KindTLSRoute, namespace: tlsRoute.Namespace, name: tlsRoute.Name} to := ObjectKindNamespacedName{kind: gatewayapi.KindService, namespace: backendNamespace, name: string(backendRef.Name)} refGrant, err := r.findReferenceGrant(ctx, from, to) - if err != nil { - r.log.Error(err, "unable to find ReferenceGrant that links the Service to TLSRoute") - continue + switch { + case err != nil: + r.log.Error(err, "failed to find ReferenceGrant") + case refGrant == nil: + r.log.Info("no matching ReferenceGrants found", "from", from.kind, + "from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace) + default: + resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant + r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace, + "name", refGrant.Name) } - - resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant } } } @@ -77,7 +82,7 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam if err := r.client.List(ctx, httpRouteList, &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector(gatewayHTTPRouteIndex, gatewayNamespaceName), }); err != nil { - r.log.Error(err, "unable to find associated HTTPRoutes") + r.log.Error(err, "failed to list HTTPRoutes") return err } for _, httpRoute := range httpRouteList.Items { @@ -99,15 +104,28 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam }] = struct{}{} if backendNamespace != httpRoute.Namespace { - from := ObjectKindNamespacedName{kind: gatewayapi.KindHTTPRoute, namespace: httpRoute.Namespace, name: httpRoute.Name} - to := ObjectKindNamespacedName{kind: gatewayapi.KindService, namespace: backendNamespace, name: string(backendRef.Name)} + from := ObjectKindNamespacedName{ + kind: gatewayapi.KindHTTPRoute, + namespace: httpRoute.Namespace, + name: httpRoute.Name, + } + to := ObjectKindNamespacedName{ + kind: gatewayapi.KindService, + namespace: backendNamespace, + name: string(backendRef.Name), + } refGrant, err := r.findReferenceGrant(ctx, from, to) - if err != nil { - r.log.Error(err, "unable to find ReferenceGrant that links the Service to HTTPRoute") - continue + switch { + case err != nil: + r.log.Error(err, "failed to find ReferenceGrant") + case refGrant == nil: + r.log.Info("no matching ReferenceGrants found", "from", from.kind, + "from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace) + default: + resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant + r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace, + "name", refGrant.Name) } - - resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant } } } diff --git a/test/conformance/conformance_test.go b/test/conformance/conformance_test.go index 721cfb378c..ff9f4b3f7e 100644 --- a/test/conformance/conformance_test.go +++ b/test/conformance/conformance_test.go @@ -79,6 +79,7 @@ func TestGatewayAPIConformance(t *testing.T) { tests.GatewaySecretReferenceGrantSpecific, tests.GatewaySecretMissingReferenceGrant, tests.GatewaySecretInvalidReferenceGrant, + tests.HTTPRouteReferenceGrant, } cSuite.Run(t, egTests)