Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions internal/gatewayapi/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@
}

func validateBackend(backend *egv1a1.Backend) status.Error {
if backend.Spec.Type != nil &&
*backend.Spec.Type == egv1a1.BackendTypeDynamicResolver {
if len(backend.Spec.Endpoints) > 0 || len(backend.Spec.AppProtocols) > 0 {
return status.NewRouteStatusError(
fmt.Errorf("DynamicResolver type cannot have endpoints or appProtocols specified"),
status.RouteReasonInvalidBackendRef,
)
}

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

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/backend.go#L46-L50

Added lines #L46 - L50 were not covered by tests
}

for _, ep := range backend.Spec.Endpoints {
if ep.FQDN != nil {
hostname := ep.FQDN.Hostname
Expand Down
27 changes: 27 additions & 0 deletions internal/gatewayapi/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe
destName := irRouteDestinationName(httpRoute, ruleIdx)
allDs := []*ir.DestinationSetting{}
failedProcessDestination := false
hasDynamicResolver := false

// process each backendRef, and calculate the destination settings for this rule
for i, backendRef := range rule.BackendRefs {
Expand All @@ -231,6 +232,11 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe
continue
}
allDs = append(allDs, ds)

// check if there is a dynamic resolver in the backendRefs
if ds.IsDynamicResolver {
hasDynamicResolver = true
}
}

// process each ir route
Expand All @@ -254,13 +260,28 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe
irRoute.DirectResponse = &ir.CustomResponse{
StatusCode: ptr.To(uint32(500)),
}
// A route can only have one destination if this destination is a dynamic resolver, because the behavior of
// multiple destinations with one being a dynamic resolver just doesn't make sense.
case hasDynamicResolver && len(rule.BackendRefs) > 1:
irRoute.DirectResponse = &ir.CustomResponse{
StatusCode: ptr.To(uint32(500)),
}
default:
destination.Name = destName
destination.Settings = allDs
irRoute.Destination = destination
}
}

if hasDynamicResolver && len(rule.BackendRefs) > 1 {
errs.Add(status.NewRouteStatusError(
fmt.Errorf(
"failed to process route rule %d: dynamic resolver is not supported for multiple backendRefs",
ruleIdx),
status.RouteReasonInvalidBackendRef,
))
}

// TODO handle:
// - sum of weights for valid backend refs is 0
// - etc.
Expand Down Expand Up @@ -1821,6 +1842,12 @@ func (t *Translator) processBackendDestinationSetting(
backend := resources.GetBackend(backendNamespace, string(backendRef.Name))
ds := &ir.DestinationSetting{Name: name}

// There is only one backend if it is a dynamic resolver
if backend.Spec.Type != nil && *backend.Spec.Type == egv1a1.BackendTypeDynamicResolver {
ds.IsDynamicResolver = true
return ds
}

for _, bep := range backend.Spec.Endpoints {
var irde *ir.DestinationEndpoint
switch {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-1
spec:
hostnames:
- gateway.envoyproxy.io
parentRefs:
- namespace: envoy-gateway
name: gateway-1
sectionName: http
rules:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
name: backend-1
- group: gateway.envoyproxy.io
kind: Backend
name: backend-2
backends:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
name: backend-1
namespace: default
spec:
type: DynamicResolver
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
name: backend-2
namespace: default
spec:
endpoints:
- ip:
address: 1.1.1.1
port: 3001
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
backends:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
creationTimestamp: null
name: backend-1
namespace: default
spec:
type: DynamicResolver
status:
conditions:
- lastTransitionTime: null
message: The Backend was accepted
reason: Accepted
status: "True"
type: Accepted
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
creationTimestamp: null
name: backend-2
namespace: default
spec:
endpoints:
- ip:
address: 1.1.1.1
port: 3001
status:
conditions:
- lastTransitionTime: null
message: The Backend was accepted
reason: Accepted
status: "True"
type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
creationTimestamp: null
name: gateway-1
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- allowedRoutes:
namespaces:
from: All
name: http
port: 80
protocol: HTTP
status:
listeners:
- attachedRoutes: 1
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: null
message: Listener has been successfully translated
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: Listener references have been resolved
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: http
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: httproute-1
namespace: default
spec:
hostnames:
- gateway.envoyproxy.io
parentRefs:
- name: gateway-1
namespace: envoy-gateway
sectionName: http
rules:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
name: backend-1
- group: gateway.envoyproxy.io
kind: Backend
name: backend-2
status:
parents:
- conditions:
- lastTransitionTime: null
message: Route is accepted
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: 'Failed to process route rule 0: dynamic resolver is not supported
for multiple backendRefs.'
reason: InvalidBackendRef
status: "False"
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
name: gateway-1
namespace: envoy-gateway
sectionName: http
infraIR:
envoy-gateway/gateway-1:
proxy:
listeners:
- address: null
name: envoy-gateway/gateway-1/http
ports:
- containerPort: 10080
name: http-80
protocol: HTTP
servicePort: 80
metadata:
labels:
gateway.envoyproxy.io/owning-gateway-name: gateway-1
gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
name: envoy-gateway/gateway-1
xdsIR:
envoy-gateway/gateway-1:
accessLog:
json:
- path: /dev/stdout
http:
- address: 0.0.0.0
hostnames:
- '*'
isHTTP2: false
metadata:
kind: Gateway
name: gateway-1
namespace: envoy-gateway
sectionName: http
name: envoy-gateway/gateway-1/http
path:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 10080
routes:
- directResponse:
statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
kind: HTTPRoute
name: httproute-1
namespace: default
name: httproute/default/httproute-1/rule/0/match/-1/gateway_envoyproxy_io
readyListener:
address: 0.0.0.0
ipFamily: IPv4
path: /ready
port: 19003
41 changes: 41 additions & 0 deletions internal/gatewayapi/testdata/httproute-dynamic-resolver.in.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-1
spec:
hostnames:
- gateway.envoyproxy.io
parentRefs:
- namespace: envoy-gateway
name: gateway-1
sectionName: http
rules:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
name: backend-1
backends:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
name: backend-1
namespace: default
spec:
type: DynamicResolver
Loading
Loading