Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ httpRoutes:
status: "False"
type: Accepted
- lastTransitionTime: null
message: Service envoy-gateway-system/backend not found
message: 'Failed to process route rule 0 backendRef 0: service envoy-gateway-system/backend
not found.'
reason: BackendNotFound
status: "False"
type: ResolvedRefs
Expand Down
27 changes: 21 additions & 6 deletions internal/gatewayapi/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,42 @@
return res
}

func validateBackend(backend *egv1a1.Backend) error {
func validateBackend(backend *egv1a1.Backend) status.Error {
for _, ep := range backend.Spec.Endpoints {
if ep.FQDN != nil {
hostname := ep.FQDN.Hostname
// must be a valid hostname
if errs := validation.IsDNS1123Subdomain(hostname); errs != nil {
return fmt.Errorf("hostname %s is not a valid FQDN", hostname)
return status.NewRouteStatusError(
fmt.Errorf("hostname %s is not a valid FQDN", hostname),
status.RouteReasonInvalidAddress,
)
}
if len(strings.Split(hostname, ".")) < 2 {
return fmt.Errorf("hostname %s should be a domain with at least two segments separated by dots", hostname)
return status.NewRouteStatusError(
fmt.Errorf("hostname %s should be a domain with at least two segments separated by dots", hostname),
status.RouteReasonInvalidAddress,
)
}
// IP addresses are not allowed so parsing the hostname as an address needs to fail
if _, err := netip.ParseAddr(hostname); err == nil {
return fmt.Errorf("hostname %s is an IP address", hostname)
return status.NewRouteStatusError(
fmt.Errorf("hostname %s is an IP address", hostname),
status.RouteReasonInvalidAddress,
)

Check warning on line 64 in internal/gatewayapi/backend.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/backend.go#L61-L64

Added lines #L61 - L64 were not covered by tests
}
} else if ep.IP != nil {
ip, err := netip.ParseAddr(ep.IP.Address)
if err != nil {
return fmt.Errorf("IP address %s is invalid", ep.IP.Address)
return status.NewRouteStatusError(
fmt.Errorf("IP address %s is invalid", ep.IP.Address),
status.RouteReasonInvalidAddress,
)
} else if ip.IsLoopback() {
return fmt.Errorf("IP address %s in the loopback range is not supported", ep.IP.Address)
return status.NewRouteStatusError(
fmt.Errorf("IP address %s in the loopback range is not supported", ep.IP.Address),
status.RouteReasonInvalidAddress,
)
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions internal/gatewayapi/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type HTTPFiltersTranslator interface {
processRedirectFilter(redirect *gwapiv1.HTTPRequestRedirectFilter, filterContext *HTTPFiltersContext)
processRequestHeaderModifierFilter(headerModifier *gwapiv1.HTTPHeaderFilter, filterContext *HTTPFiltersContext)
processResponseHeaderModifierFilter(headerModifier *gwapiv1.HTTPHeaderFilter, filterContext *HTTPFiltersContext)
processRequestMirrorFilter(filterIdx int, mirror *gwapiv1.HTTPRequestMirrorFilter, filterContext *HTTPFiltersContext, resources *resource.Resources) error
processRequestMirrorFilter(filterIdx int, mirror *gwapiv1.HTTPRequestMirrorFilter, filterContext *HTTPFiltersContext, resources *resource.Resources) status.Error
processUnsupportedHTTPFilter(filterType string, filterContext *HTTPFiltersContext)
}

Expand Down Expand Up @@ -72,14 +72,14 @@ func (t *Translator) ProcessHTTPFilters(parentRef *RouteParentContext,
filters []gwapiv1.HTTPRouteFilter,
ruleIdx int,
resources *resource.Resources,
) (*HTTPFiltersContext, error) {
) (*HTTPFiltersContext, status.Error) {
httpFiltersContext := &HTTPFiltersContext{
ParentRef: parentRef,
Route: route,
RuleIdx: ruleIdx,
HTTPFilterIR: &HTTPFilterIR{},
}
var err error
var err status.Error
for i := range filters {
filter := filters[i]
// If an invalid filter type has been configured then skip processing any more filters
Expand Down Expand Up @@ -881,7 +881,7 @@ func (t *Translator) processRequestMirrorFilter(
mirrorFilter *gwapiv1.HTTPRequestMirrorFilter,
filterContext *HTTPFiltersContext,
resources *resource.Resources,
) error {
) (err status.Error) {
// Make sure the config actually exists
if mirrorFilter == nil {
return nil
Expand All @@ -901,10 +901,11 @@ func (t *Translator) processRequestMirrorFilter(
// This sets the status on the HTTPRoute, should the usage be changed so that the status message reflects that the backendRef is from the filter?
filterNs := filterContext.Route.GetNamespace()
serviceNamespace := NamespaceDerefOr(mirrorBackend.Namespace, filterNs)
err := t.validateBackendRef(mirrorBackendRef, filterContext.ParentRef, filterContext.Route,
err = t.validateBackendRef(mirrorBackendRef, filterContext.ParentRef, filterContext.Route,
resources, serviceNamespace, resource.KindHTTPRoute)
if err != nil {
return err
return status.NewRouteStatusError(
fmt.Errorf("failed to validate the RequestMirror filter: %w", err), err.Reason())
}

destName := fmt.Sprintf("%s-mirror-%d", irRouteDestinationName(filterContext.Route, filterContext.RuleIdx), filterIdx)
Expand Down
4 changes: 2 additions & 2 deletions internal/gatewayapi/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,13 +565,13 @@ func (t *Translator) processBackendRefs(name string, backendCluster egv1a1.Backe
kind := KindDerefOr(ref.Kind, resource.KindService)
switch kind {
case resource.KindService:
if _, err := validateBackendRefService(ref.BackendObjectReference, resources, ns, corev1.ProtocolTCP); err != nil {
if err := validateBackendRefService(ref.BackendObjectReference, resources, ns, corev1.ProtocolTCP); err != nil {
return nil, nil, err
}
ds := t.processServiceDestinationSetting(name, ref.BackendObjectReference, ns, ir.TCP, resources, envoyProxy)
result = append(result, ds)
case resource.KindBackend:
if _, err := t.validateBackendRefBackend(ref.BackendObjectReference, resources, ns, true); err != nil {
if err := t.validateBackendRefBackend(ref.BackendObjectReference, resources, ns, true); err != nil {
return nil, nil, err
}
ds := t.processBackendDestinationSetting(name, ref.BackendObjectReference, ns, ir.TCP, resources)
Expand Down
Loading