Skip to content

Commit

Permalink
Add ReferenceGrant Support for Routes (#793)
Browse files Browse the repository at this point in the history
  • Loading branch information
danehans authored Dec 17, 2022
1 parent 679c60b commit 71ace36
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 37 deletions.
54 changes: 33 additions & 21 deletions internal/provider/kubernetes/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}{}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
3 changes: 0 additions & 3 deletions internal/provider/kubernetes/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
44 changes: 31 additions & 13 deletions internal/provider/kubernetes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
Expand All @@ -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 {
Expand All @@ -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
}
}
}
Expand Down
1 change: 1 addition & 0 deletions test/conformance/conformance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func TestGatewayAPIConformance(t *testing.T) {
tests.GatewaySecretReferenceGrantSpecific,
tests.GatewaySecretMissingReferenceGrant,
tests.GatewaySecretInvalidReferenceGrant,
tests.HTTPRouteReferenceGrant,
}
cSuite.Run(t, egTests)

Expand Down

0 comments on commit 71ace36

Please sign in to comment.