diff --git a/internal/mode/static/nginx/config/servers_test.go b/internal/mode/static/nginx/config/servers_test.go index 04fd0298c..e3d57bc2b 100644 --- a/internal/mode/static/nginx/config/servers_test.go +++ b/internal/mode/static/nginx/config/servers_test.go @@ -650,19 +650,16 @@ func TestCreateServers(t *testing.T) { Path: "@rule0-route0", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "@rule0-route1", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "@rule0-route2", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "/", @@ -672,7 +669,6 @@ func TestCreateServers(t *testing.T) { Path: "@rule1-route0", ProxyPass: "http://$test__route1_rule1$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "/test/", @@ -682,13 +678,11 @@ func TestCreateServers(t *testing.T) { Path: "/path-only/", ProxyPass: "http://invalid-backend-ref$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "= /path-only", ProxyPass: "http://invalid-backend-ref$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "/backend-tls-policy/", @@ -756,21 +750,18 @@ func TestCreateServers(t *testing.T) { Rewrites: []string{"^ /replacement break"}, ProxyPass: "http://test_foo_80", ProxySetHeaders: rewriteProxySetHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "= /rewrite", Rewrites: []string{"^ /replacement break"}, ProxyPass: "http://test_foo_80", ProxySetHeaders: rewriteProxySetHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "@rule8-route0", Rewrites: []string{"^/rewrite-with-headers(.*)$ /prefix-replacement$1 break"}, ProxyPass: "http://test_foo_80", ProxySetHeaders: rewriteProxySetHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "/rewrite-with-headers/", @@ -810,13 +801,11 @@ func TestCreateServers(t *testing.T) { Path: "= /exact", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "@rule12-route0", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "= /test", @@ -1029,13 +1018,11 @@ func TestCreateServersConflicts(t *testing.T) { Path: "/coffee/", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "= /coffee", ProxyPass: "http://test_bar_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, createDefaultRootLocation(), }, @@ -1069,13 +1056,11 @@ func TestCreateServersConflicts(t *testing.T) { Path: "= /coffee", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "/coffee/", ProxyPass: "http://test_bar_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, createDefaultRootLocation(), }, @@ -1119,13 +1104,11 @@ func TestCreateServersConflicts(t *testing.T) { Path: "/coffee/", ProxyPass: "http://test_bar_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "= /coffee", ProxyPass: "http://test_baz_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, createDefaultRootLocation(), }, @@ -1244,13 +1227,11 @@ func TestCreateLocationsRootPath(t *testing.T) { Path: "/path-1", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "/path-2", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "/", @@ -1297,19 +1278,16 @@ func TestCreateLocationsRootPath(t *testing.T) { Path: "/path-1", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "/path-2", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, { Path: "/", ProxyPass: "http://test_foo_80$request_uri", ProxySetHeaders: httpBaseHeaders, - ResponseHeaders: http.ResponseHeaders{}, }, }, }, diff --git a/internal/mode/static/state/graph/grpcroute.go b/internal/mode/static/state/graph/grpcroute.go index 1d67cdf55..287e00254 100644 --- a/internal/mode/static/state/graph/grpcroute.go +++ b/internal/mode/static/state/graph/grpcroute.go @@ -258,12 +258,15 @@ func validateGRPCFilter( switch filter.Type { case v1alpha2.GRPCRouteFilterRequestHeaderModifier: return validateFilterHeaderModifier(validator, filter.RequestHeaderModifier, filterPath.Child(string(filter.Type))) + case v1alpha2.GRPCRouteFilterResponseHeaderModifier: + return validateFilterHeaderModifier(validator, filter.ResponseHeaderModifier, filterPath.Child(string(filter.Type))) default: valErr := field.NotSupported( filterPath.Child("type"), filter.Type, []string{ string(v1alpha2.GRPCRouteFilterRequestHeaderModifier), + string(v1alpha2.GRPCRouteFilterResponseHeaderModifier), }, ) allErrs = append(allErrs, valErr) @@ -286,6 +289,12 @@ func convertGRPCFilters(filters []v1alpha2.GRPCRouteFilter) []v1.HTTPRouteFilter RequestHeaderModifier: filter.RequestHeaderModifier, } httpFilters = append(httpFilters, httpRequestHeaderFilter) + case v1alpha2.GRPCRouteFilterResponseHeaderModifier: + httpResponseHeaderFilter := v1.HTTPRouteFilter{ + Type: v1.HTTPRouteFilterResponseHeaderModifier, + ResponseHeaderModifier: filter.ResponseHeaderModifier, + } + httpFilters = append(httpFilters, httpResponseHeaderFilter) default: continue } diff --git a/internal/mode/static/state/graph/grpcroute_test.go b/internal/mode/static/state/graph/grpcroute_test.go index 4d3800319..165a491db 100644 --- a/internal/mode/static/state/graph/grpcroute_test.go +++ b/internal/mode/static/state/graph/grpcroute_test.go @@ -256,6 +256,14 @@ func TestBuildGRPCRoute(t *testing.T) { Remove: []string{"header"}, }, }, + { + Type: "ResponseHeaderModifier", + ResponseHeaderModifier: &v1.HTTPHeaderFilter{ + Add: []v1.HTTPHeader{ + {Name: "Accept-Encoding", Value: "gzip"}, + }, + }, + }, } grValidFilter := createGRPCRoute( @@ -272,6 +280,14 @@ func TestBuildGRPCRoute(t *testing.T) { Remove: []string{"header"}, }, }, + { + Type: v1.HTTPRouteFilterResponseHeaderModifier, + ResponseHeaderModifier: &v1.HTTPHeaderFilter{ + Add: []v1.HTTPHeader{ + {Name: "Accept-Encoding", Value: "gzip"}, + }, + }, + }, } createAllValidValidator := func() *validationfakes.FakeHTTPFieldsValidator { @@ -616,7 +632,7 @@ func TestBuildGRPCRoute(t *testing.T) { Conditions: []conditions.Condition{ staticConds.NewRouteUnsupportedValue( `All rules are invalid: spec.rules[0].filters[0].type: ` + - `Unsupported value: "RequestMirror": supported values: "RequestHeaderModifier"`, + `Unsupported value: "RequestMirror": supported values: "RequestHeaderModifier", "ResponseHeaderModifier"`, ), }, Spec: L7RouteSpec{ @@ -755,6 +771,14 @@ func TestConvertGRPCFilters(t *testing.T) { Remove: []string{"header"}, }, }, + { + Type: "ResponseHeaderModifier", + ResponseHeaderModifier: &v1.HTTPHeaderFilter{ + Add: []v1.HTTPHeader{ + {Name: "Accept-Encoding", Value: "gzip"}, + }, + }, + }, { Type: "RequestMirror", }, @@ -765,6 +789,10 @@ func TestConvertGRPCFilters(t *testing.T) { Type: v1.HTTPRouteFilterRequestHeaderModifier, RequestHeaderModifier: grFilters[0].RequestHeaderModifier, }, + { + Type: v1.HTTPRouteFilterResponseHeaderModifier, + ResponseHeaderModifier: grFilters[1].ResponseHeaderModifier, + }, } g := NewWithT(t) diff --git a/site/content/overview/gateway-api-compatibility.md b/site/content/overview/gateway-api-compatibility.md index dff2e713b..c8106ac8f 100644 --- a/site/content/overview/gateway-api-compatibility.md +++ b/site/content/overview/gateway-api-compatibility.md @@ -187,7 +187,7 @@ See the [static-mode]({{< relref "/reference/cli-help.md#static-mode">}}) comman {{< bootstrap-table "table table-striped table-bordered" >}} | Resource | Core Support Level | Extended Support Level | Implementation-Specific Support Level | API Version | | --------- | ------------------- | ---------------------- | ------------------------------------- | ----------- | -| GRPCRoute | Partially Supported | Not supported | Not supported | v1alpha2 | +| GRPCRoute | Supported | Not supported | Not supported | v1alpha2 | {{< /bootstrap-table >}} **Fields**: @@ -202,7 +202,8 @@ See the [static-mode]({{< relref "/reference/cli-help.md#static-mode">}}) comman - `filters` - `type`: Supported. - `requestHeaderModifier`: Supported. If multiple filters are configured, NGINX Gateway Fabric will choose the first and ignore the rest. - - `responseHeaderModifier`, `requestMirror`, `extensionRef`: Not supported. + - `responseHeaderModifier`: Supported. If multiple filters are configured, NGINX Gateway Fabric will choose the first and ignore the rest. + - `requestMirror`, `extensionRef`: Not supported. - `backendRefs`: Partially supported. Backend ref `filters` are not supported. - `status` - `parents`