Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Multiple RequestMirrors Filters per HTTPRoute Rule #1819

Merged
merged 15 commits into from
Sep 17, 2023
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
35 changes: 9 additions & 26 deletions internal/gatewayapi/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
processRedirectFilter(redirect *v1beta1.HTTPRequestRedirectFilter, filterContext *HTTPFiltersContext)
processRequestHeaderModifierFilter(headerModifier *v1beta1.HTTPHeaderFilter, filterContext *HTTPFiltersContext)
processResponseHeaderModifierFilter(headerModifier *v1beta1.HTTPHeaderFilter, filterContext *HTTPFiltersContext)
processRequestMirrorFilter(mirror *v1beta1.HTTPRequestMirrorFilter, filterContext *HTTPFiltersContext, resources *Resources)
processRequestMirrorFilter(filterIdx int, mirror *v1beta1.HTTPRequestMirrorFilter, filterContext *HTTPFiltersContext, resources *Resources)
processExtensionRefHTTPFilter(extRef *v1beta1.LocalObjectReference, filterContext *HTTPFiltersContext, resources *Resources)
processUnsupportedHTTPFilter(filterType string, filterContext *HTTPFiltersContext)
}
Expand All @@ -56,7 +56,7 @@
AddResponseHeaders []ir.AddHeader
RemoveResponseHeaders []string

Mirror *ir.RouteDestination
Mirrors []*ir.RouteDestination

RequestAuthentication *ir.RequestAuthentication
RateLimit *ir.RateLimit
Expand All @@ -76,7 +76,6 @@
RuleIdx: ruleIdx,
HTTPFilterIR: &HTTPFilterIR{},
}

for i := range filters {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just use i

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just use i

Yes, I can use 'i' if I don't need to match the value with the index of Mirror list.

filter := filters[i]
// If an invalid filter type has been configured then skip processing any more filters
Expand All @@ -98,7 +97,7 @@
case v1beta1.HTTPRouteFilterResponseHeaderModifier:
t.processResponseHeaderModifierFilter(filter.ResponseHeaderModifier, httpFiltersContext)
case v1beta1.HTTPRouteFilterRequestMirror:
t.processRequestMirrorFilter(filter.RequestMirror, httpFiltersContext, resources)
t.processRequestMirrorFilter(i, filter.RequestMirror, httpFiltersContext, resources)
case v1beta1.HTTPRouteFilterExtensionRef:
t.processExtensionRefHTTPFilter(filter.ExtensionRef, httpFiltersContext, resources)
default:
Expand All @@ -120,7 +119,6 @@

HTTPFilterIR: &HTTPFilterIR{},
}

for i := range filters {
filter := filters[i]
// If an invalid filter type has been configured then skip processing any more filters
Expand All @@ -138,7 +136,7 @@
case v1alpha2.GRPCRouteFilterResponseHeaderModifier:
t.processResponseHeaderModifierFilter(filter.ResponseHeaderModifier, httpFiltersContext)
case v1alpha2.GRPCRouteFilterRequestMirror:
t.processRequestMirrorFilter(filter.RequestMirror, httpFiltersContext, resources)
t.processRequestMirrorFilter(i, filter.RequestMirror, httpFiltersContext, resources)

Check warning on line 139 in internal/gatewayapi/filters.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/filters.go#L139

Added line #L139 was not covered by tests
case v1alpha2.GRPCRouteFilterExtensionRef:
t.processExtensionRefHTTPFilter(filter.ExtensionRef, httpFiltersContext, resources)
default:
Expand Down Expand Up @@ -808,6 +806,7 @@
}

func (t *Translator) processRequestMirrorFilter(
filterIdx int,
mirrorFilter *v1beta1.HTTPRequestMirrorFilter,
filterContext *HTTPFiltersContext,
resources *Resources) {
Expand Down Expand Up @@ -836,27 +835,11 @@

mirrorEndpoints, _ := t.processDestEndpoints(mirrorBackendRef, filterContext.ParentRef, filterContext.Route, resources)

// Only add missing mirror destinations
for _, mirrorEp := range mirrorEndpoints {
var found bool
if filterContext.Mirror != nil {
for _, mirror := range filterContext.Mirror.Endpoints {
if mirror != nil {
if mirror.Host == mirrorEp.Host && mirror.Port == mirrorEp.Port {
found = true
}
}
}
}
if !found {
if filterContext.Mirror == nil {
filterContext.Mirror = &ir.RouteDestination{
Name: fmt.Sprintf("%s-mirror", irRouteDestinationName(filterContext.Route, filterContext.RuleIdx)),
}
}
filterContext.Mirror.Endpoints = append(filterContext.Mirror.Endpoints, mirrorEp)
}
newMirror := &ir.RouteDestination{
Name: fmt.Sprintf("%s-mirror-%d", irRouteDestinationName(filterContext.Route, filterContext.RuleIdx), filterIdx),
Endpoints: mirrorEndpoints,
}
filterContext.Mirrors = append(filterContext.Mirrors, newMirror)
}

func (t *Translator) processUnresolvedHTTPFilter(errMsg string, filterContext *HTTPFiltersContext) {
Expand Down
6 changes: 3 additions & 3 deletions internal/gatewayapi/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,8 @@ func applyHTTPFiltersContextToIRRoute(httpFiltersContext *HTTPFiltersContext, ir
if len(httpFiltersContext.RemoveResponseHeaders) > 0 {
irRoute.RemoveResponseHeaders = httpFiltersContext.RemoveResponseHeaders
}
if httpFiltersContext.Mirror != nil {
irRoute.Mirror = httpFiltersContext.Mirror
if httpFiltersContext.Mirrors != nil {
irRoute.Mirrors = httpFiltersContext.Mirrors
}
if httpFiltersContext.RequestAuthentication != nil {
irRoute.RequestAuthentication = httpFiltersContext.RequestAuthentication
Expand Down Expand Up @@ -533,7 +533,7 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route
Redirect: routeRoute.Redirect,
DirectResponse: routeRoute.DirectResponse,
URLRewrite: routeRoute.URLRewrite,
Mirror: routeRoute.Mirror,
Mirrors: routeRoute.Mirrors,
RequestAuthentication: routeRoute.RequestAuthentication,
RateLimit: routeRoute.RateLimit,
ExtensionRefs: routeRoute.ExtensionRefs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,17 @@ xdsIR:
weight: 1
name: httproute/default/httproute-1/rule/0
hostname: gateway.envoyproxy.io
mirror:
endpoints:
mirrors:
- endpoints:
- host: 7.7.7.7
port: 8080
weight: 1
name: httproute/default/httproute-1/rule/0-mirror-0
- endpoints:
- host: 7.7.7.7
port: 8080
weight: 1
name: httproute/default/httproute-1/rule/0-mirror
name: httproute/default/httproute-1/rule/0-mirror-1
name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
pathMatch:
distinct: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ httpRoutes:
- name: service-1
port: 8080
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: X-Header-Set
value: set-overwrites-values
add:
- name: X-Header-Add
value: header-val-1
- name: X-Header-Add-Append
value: header-val-2
remove:
- X-Header-Remove
- type: RequestMirror
requestMirror:
backendRef:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ httpRoutes:
- name: service-1
port: 8080
filters:
- requestHeaderModifier:
add:
- name: X-Header-Add
value: header-val-1
- name: X-Header-Add-Append
value: header-val-2
remove:
- X-Header-Remove
set:
- name: X-Header-Set
value: set-overwrites-values
type: RequestHeaderModifier
- requestMirror:
backendRef:
kind: Service
Expand Down Expand Up @@ -115,7 +127,17 @@ xdsIR:
name: envoy-gateway/gateway-1/http
port: 10080
routes:
- backendWeights:
- addRequestHeaders:
- append: true
name: X-Header-Add
value: header-val-1
- append: true
name: X-Header-Add-Append
value: header-val-2
- append: false
name: X-Header-Set
value: set-overwrites-values
backendWeights:
invalid: 0
valid: 0
destination:
Expand All @@ -125,17 +147,21 @@ xdsIR:
weight: 1
name: httproute/default/httproute-1/rule/0
hostname: gateway.envoyproxy.io
mirror:
endpoints:
mirrors:
- endpoints:
- host: 7.7.7.7
port: 8080
weight: 1
name: httproute/default/httproute-1/rule/0-mirror-1
- endpoints:
- host: 7.6.5.4
port: 8080
weight: 1
name: httproute/default/httproute-1/rule/0-mirror
name: httproute/default/httproute-1/rule/0-mirror-2
name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
pathMatch:
distinct: false
name: ""
prefix: /
removeRequestHeaders:
- X-Header-Remove
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ xdsIR:
weight: 1
name: httproute/default/httproute-1/rule/0
hostname: gateway.envoyproxy.io
mirror:
endpoints:
mirrors:
- endpoints:
- host: 7.7.7.7
port: 8080
weight: 1
name: httproute/default/httproute-1/rule/0-mirror
name: httproute/default/httproute-1/rule/0-mirror-0
name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
pathMatch:
distinct: false
Expand Down
10 changes: 6 additions & 4 deletions internal/ir/xds.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@
// Redirections to be returned for this route. Takes precedence over Destinations.
Redirect *Redirect `json:"redirect,omitempty" yaml:"redirect,omitempty"`
// Destination that requests to this HTTPRoute will be mirrored to
Mirror *RouteDestination `json:"mirror,omitempty" yaml:"mirror,omitempty"`
Mirrors []*RouteDestination `json:"mirrors,omitempty" yaml:"mirrors,omitempty"`
// Destination associated with this matched route.
Destination *RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"`
// Rewrite to be changed for this route.
Expand Down Expand Up @@ -353,9 +353,11 @@
errs = multierror.Append(errs, err)
}
}
if h.Mirror != nil {
if err := h.Mirror.Validate(); err != nil {
errs = multierror.Append(errs, err)
if h.Mirrors != nil {
for _, mirror := range h.Mirrors {
if err := mirror.Validate(); err != nil {
errs = multierror.Append(errs, err)
}

Check warning on line 360 in internal/ir/xds.go

View check run for this annotation

Codecov / codecov/patch

internal/ir/xds.go#L359-L360

Added lines #L359 - L360 were not covered by tests
}
}
if len(h.AddRequestHeaders) > 0 {
Expand Down
2 changes: 1 addition & 1 deletion internal/ir/xds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ var (
PathMatch: &StringMatch{
Exact: ptrTo("mirrorfilter"),
},
Mirror: &happyRouteDestination,
Mirrors: []*RouteDestination{&happyRouteDestination},
}

// RouteDestination
Expand Down
14 changes: 10 additions & 4 deletions internal/ir/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 13 additions & 11 deletions internal/xds/translator/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,23 @@
router.Action = &routev3.Route_Redirect{Redirect: buildXdsRedirectAction(httpRoute.Redirect)}
case httpRoute.URLRewrite != nil:
routeAction := buildXdsURLRewriteAction(httpRoute.Destination.Name, httpRoute.URLRewrite)
if httpRoute.Mirror != nil {
routeAction.RequestMirrorPolicies = buildXdsRequestMirrorPolicies(httpRoute.Mirror.Name)
if httpRoute.Mirrors != nil {
routeAction.RequestMirrorPolicies = buildXdsRequestMirrorPolicies(httpRoute.Mirrors)

Check warning on line 47 in internal/xds/translator/route.go

View check run for this annotation

Codecov / codecov/patch

internal/xds/translator/route.go#L47

Added line #L47 was not covered by tests
}

router.Action = &routev3.Route_Route{Route: routeAction}
default:
if httpRoute.BackendWeights.Invalid != 0 {
// If there are invalid backends then a weighted cluster is required for the route
routeAction := buildXdsWeightedRouteAction(httpRoute)
if httpRoute.Mirror != nil {
routeAction.RequestMirrorPolicies = buildXdsRequestMirrorPolicies(httpRoute.Mirror.Name)
if httpRoute.Mirrors != nil {
routeAction.RequestMirrorPolicies = buildXdsRequestMirrorPolicies(httpRoute.Mirrors)

Check warning on line 56 in internal/xds/translator/route.go

View check run for this annotation

Codecov / codecov/patch

internal/xds/translator/route.go#L56

Added line #L56 was not covered by tests
}
router.Action = &routev3.Route_Route{Route: routeAction}
} else {
routeAction := buildXdsRouteAction(httpRoute.Destination.Name)
if httpRoute.Mirror != nil {
routeAction.RequestMirrorPolicies = buildXdsRequestMirrorPolicies(httpRoute.Mirror.Name)
if httpRoute.Mirrors != nil {
routeAction.RequestMirrorPolicies = buildXdsRequestMirrorPolicies(httpRoute.Mirrors)
}
router.Action = &routev3.Route_Route{Route: routeAction}
}
Expand Down Expand Up @@ -292,11 +292,13 @@
return routeAction
}

func buildXdsRequestMirrorPolicies(destName string) []*routev3.RouteAction_RequestMirrorPolicy {
mirrorPolicies := []*routev3.RouteAction_RequestMirrorPolicy{
{
Cluster: destName,
},
func buildXdsRequestMirrorPolicies(mirrorDestinations []*ir.RouteDestination) []*routev3.RouteAction_RequestMirrorPolicy {
var mirrorPolicies []*routev3.RouteAction_RequestMirrorPolicy

for _, mirrorDest := range mirrorDestinations {
mirrorPolicies = append(mirrorPolicies, &routev3.RouteAction_RequestMirrorPolicy{
Cluster: mirrorDest.Name,
})
}

return mirrorPolicies
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: "http-route"
http:
- name: "first-listener"
address: "0.0.0.0"
port: 10080
hostnames:
- "*"
routes:
- name: "mirror-route"
hostname: "*"
destination:
name: "route-dest"
endpoints:
- host: "1.2.3.4"
port: 50000
mirrors:
- name: "mirror-route-dest"
endpoints:
- host: "2.3.4.5"
- name: "mirror-route-dest1"
endpoints:
- host: "3.4.5.6"
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,3 @@
outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
- commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
dnsLookupFamily: V4_ONLY
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: mirror-route-dest
name: mirror-route-dest
outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,3 @@
portValue: 50000
loadBalancingWeight: 1
locality: {}
- clusterName: mirror-route-dest
endpoints:
- lbEndpoints:
- endpoint:
address:
socketAddress:
address: 2.3.4.5
portValue: 0
loadBalancingWeight: 1
locality: {}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,3 @@
name: mirror-route
route:
cluster: route-dest
requestMirrorPolicies:
- cluster: mirror-route-dest
Loading