Skip to content

Commit

Permalink
feat: Multiple RequestMirrors Filters per HTTPRoute Rule (#1819)
Browse files Browse the repository at this point in the history
* initial code change

draft coding

Signed-off-by: Ronnie Personal <76408835+Ronnie-personal@users.noreply.github.com>

* update test cases

Signed-off-by: Ronnie Personal <76408835+Ronnie-personal@users.noreply.github.com>

* update mirror to mirrors

Signed-off-by: Ronnie Personal <76408835+Ronnie-personal@users.noreply.github.com>

* update test file

Signed-off-by: Ronnie Personal <76408835+Ronnie-personal@users.noreply.github.com>

* fix conformance test

Signed-off-by: Ronnie Personal <76408835+Ronnie-personal@users.noreply.github.com>

* update gatewayapi testdata

Signed-off-by: Ronnie Personal <76408835+Ronnie-personal@users.noreply.github.com>

* address review comments

Signed-off-by: Ronnie-personal <76408835+Ronnie-personal@users.noreply.github.com>

* update mirror to mirrors

Signed-off-by: Ronnie-personal <76408835+Ronnie-personal@users.noreply.github.com>

* Mirror to Mirrors

Signed-off-by: Ronnie-personal <76408835+Ronnie-personal@users.noreply.github.com>

* add conformance test back

Signed-off-by: Ronnie-personal <76408835+Ronnie-personal@users.noreply.github.com>

---------

Signed-off-by: Ronnie Personal <76408835+Ronnie-personal@users.noreply.github.com>
Signed-off-by: Ronnie-personal <76408835+Ronnie-personal@users.noreply.github.com>
Co-authored-by: zirain <zirain2009@gmail.com>
  • Loading branch information
Ronnie-personal and zirain authored Sep 17, 2023
1 parent 1f08e46 commit 14a395a
Show file tree
Hide file tree
Showing 22 changed files with 252 additions and 103 deletions.
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 @@ type HTTPFiltersTranslator interface {
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 @@ type HTTPFilterIR struct {
AddResponseHeaders []ir.AddHeader
RemoveResponseHeaders []string

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

RequestAuthentication *ir.RequestAuthentication
RateLimit *ir.RateLimit
Expand All @@ -76,7 +76,6 @@ func (t *Translator) ProcessHTTPFilters(parentRef *RouteParentContext,
RuleIdx: ruleIdx,
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 @@ -98,7 +97,7 @@ func (t *Translator) ProcessHTTPFilters(parentRef *RouteParentContext,
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 @@ func (t *Translator) ProcessGRPCFilters(parentRef *RouteParentContext,

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 @@ func (t *Translator) ProcessGRPCFilters(parentRef *RouteParentContext,
case v1alpha2.GRPCRouteFilterResponseHeaderModifier:
t.processResponseHeaderModifierFilter(filter.ResponseHeaderModifier, httpFiltersContext)
case v1alpha2.GRPCRouteFilterRequestMirror:
t.processRequestMirrorFilter(filter.RequestMirror, httpFiltersContext, resources)
t.processRequestMirrorFilter(i, filter.RequestMirror, httpFiltersContext, resources)
case v1alpha2.GRPCRouteFilterExtensionRef:
t.processExtensionRefHTTPFilter(filter.ExtensionRef, httpFiltersContext, resources)
default:
Expand Down Expand Up @@ -808,6 +806,7 @@ func (t *Translator) processExtensionRefHTTPFilter(extFilter *v1beta1.LocalObjec
}

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

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 @@ type HTTPRoute struct {
// 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 @@ func (h HTTPRoute) Validate() error {
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)
}
}
}
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 @@ func buildXdsRoute(httpRoute *ir.HTTPRoute) *routev3.Route {
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)
}

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)
}
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 @@ func buildXdsDirectResponseAction(res *ir.DirectResponse) *routev3.DirectRespons
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

0 comments on commit 14a395a

Please sign in to comment.