Skip to content
Merged
8 changes: 8 additions & 0 deletions config/rbac/cluster-role-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ rules:
- get
- patch
- update
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
Expand Down
8 changes: 8 additions & 0 deletions helm/templates/cluster-role-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ rules:
- get
- patch
- update
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
Expand Down
26 changes: 25 additions & 1 deletion pkg/controllers/route_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,14 @@ func (r *routeReconciler) validateRoute(ctx context.Context, route core.Route) e
return fmt.Errorf("validate route: %w", err)
}

if core.HasAllParentRefsRejected(route) {
r.eventRecorder.Event(route.K8sObject(), corev1.EventTypeWarning,
k8s.RouteEventReasonFailedBuildModel,
"No VPC Lattice resources created. Route's parentRefs rejected by all Gateway listeners due to allowedRoutes policies. Check route status conditions for more detail.")
return fmt.Errorf("%w: route has validation errors, see status", ErrValidation)
}

// Additional broader validation check for any issues
if r.hasNotAcceptedCondition(route) {
return fmt.Errorf("%w: route has validation errors, see status", ErrValidation)
}
Expand Down Expand Up @@ -509,8 +517,9 @@ func (r *routeReconciler) hasNotAcceptedCondition(route core.Route) bool {
//
// If parent GW exists will check:
// - NoMatchingParent: parentRef sectionName and port matches Listener name and port
// - NotAllowedByListeners: listener allowedRoutes.namespaces allows route
// - NotAllowedByListeners: listener allowedRoutes.kinds contains route GroupKind
// - TODO: NoMatchingListenerHostname: listener hostname matches one of route hostnames
// - TODO: NotAllowedByListeners: listener allowedRoutes contains route GroupKind
func (r *routeReconciler) validateRouteParentRefs(ctx context.Context, route core.Route) ([]gwv1.RouteParentStatus, error) {
if len(route.Spec().ParentRefs()) == 0 {
return nil, ErrParentRefsNotFound
Expand All @@ -525,6 +534,8 @@ func (r *routeReconciler) validateRouteParentRefs(ctx context.Context, route cor
gw := gws[0]
for _, parentRef := range route.Spec().ParentRefs() {
noMatchingParent := true
notAllowedByAnyMatchingListener := true

for _, listener := range gw.Spec.Listeners {
if parentRef.Port != nil && *parentRef.Port != listener.Port {
continue
Expand All @@ -533,6 +544,16 @@ func (r *routeReconciler) validateRouteParentRefs(ctx context.Context, route cor
continue
}
noMatchingParent = false

allowed, err := core.IsRouteAllowedByListener(ctx, r.client, route, gw, listener)
if err != nil {
return nil, err
}

if allowed {
notAllowedByAnyMatchingListener = false
break
}
}

parentStatus := gwv1.RouteParentStatus{
Expand All @@ -545,6 +566,9 @@ func (r *routeReconciler) validateRouteParentRefs(ctx context.Context, route cor
switch {
case noMatchingParent:
cnd = r.newCondition(route, gwv1.RouteConditionAccepted, gwv1.RouteReasonNoMatchingParent, "")
case notAllowedByAnyMatchingListener:
cnd = r.newCondition(route, gwv1.RouteConditionAccepted, gwv1.RouteReasonNotAllowedByListeners,
"No matching listeners allow this route. Check Gateway listener allowedRoutes policies")
default:
cnd = r.newCondition(route, gwv1.RouteConditionAccepted, gwv1.RouteReasonAccepted, "")
}
Expand Down
25 changes: 24 additions & 1 deletion pkg/gateway/model_build_lattice_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ func (t *latticeServiceModelBuildTask) buildModel(ctx context.Context) error {
return err
}

if modelSvc == nil {
t.log.Debugf(ctx, "Service creation skipped no further processing needed")
return nil
}

err = t.buildListeners(ctx, modelSvc.ID())
if err != nil {
return fmt.Errorf("failed to build listener due to %w", err)
Expand Down Expand Up @@ -103,6 +108,11 @@ func (t *latticeServiceModelBuildTask) buildModel(ctx context.Context) error {
}

func (t *latticeServiceModelBuildTask) buildLatticeService(ctx context.Context) (*model.Service, error) {
if core.HasAllParentRefsRejected(t.route) {
t.log.Debugf(ctx, "Skipping VPC Lattice Service creation all parentRefs rejected")
return nil, nil
}

var routeType core.RouteType
switch t.route.(type) {
case *core.HTTPRoute:
Expand Down Expand Up @@ -141,7 +151,15 @@ func (t *latticeServiceModelBuildTask) buildLatticeService(ctx context.Context)

if !standalone {
// Standard mode: populate ServiceNetworkNames from parent references

// For deduping ServiceNetworkNames since 2 parentRefs can point to same ServiceNetwork(Gateway)
serviceNetworkSet := make(map[string]struct{})
for _, parentRef := range t.route.Spec().ParentRefs() {
if !core.IsParentRefAccepted(t.route, parentRef) {
t.log.Debugf(ctx, "Skipping service network association for rejected parentRef %s", parentRef.Name)
continue
}

gw := &gwv1.Gateway{}
parentNamespace := t.route.Namespace()
if parentRef.Namespace != nil {
Expand All @@ -153,11 +171,16 @@ func (t *latticeServiceModelBuildTask) buildLatticeService(ctx context.Context)
continue
}
if k8s.IsControlledByLatticeGatewayController(ctx, t.client, gw) {
spec.ServiceNetworkNames = append(spec.ServiceNetworkNames, string(parentRef.Name))
serviceNetworkSet[string(parentRef.Name)] = struct{}{}
} else {
t.log.Infof(ctx, "Ignoring route %s because gateway %s is not managed by lattice gateway controller", t.route.Name(), gw.Name)
}
}

for serviceNetwork := range serviceNetworkSet {
spec.ServiceNetworkNames = append(spec.ServiceNetworkNames, serviceNetwork)
}

if config.ServiceNetworkOverrideMode {
spec.ServiceNetworkNames = []string{config.DefaultServiceNetwork}
}
Expand Down
Loading
Loading