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

ingress/gateway-api: sort virtual hosts in CEC #31493

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions operator/pkg/model/translation/cec_translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
package translation

import (
"cmp"
"fmt"
goslices "slices"
"sort"

envoy_config_cluster_v3 "github.com/cilium/proxy/go/envoy/config/cluster/v3"
Expand Down Expand Up @@ -292,6 +294,7 @@ func (i *cecTranslator) getEnvoyHTTPRouteConfiguration(m *model.Model) []ciliumv
// the route name should match the value in http connection manager
// otherwise the request will be dropped by envoy
routeName := fmt.Sprintf("listener-%s", port)
goslices.SortStableFunc(virtualhosts, func(a, b *envoy_config_route_v3.VirtualHost) int { return cmp.Compare(a.Name, b.Name) })
rc, _ := NewRouteConfiguration(routeName, virtualhosts)
res = append(res, rc)
}
Expand Down
56 changes: 56 additions & 0 deletions operator/pkg/model/translation/cec_translator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,62 @@ func TestSharedIngressTranslator_getClusters(t *testing.T) {
}
}

func TestGetEnvoyHTTPRouteConfiguration_VirtualHostSorted(t *testing.T) {
defT := &cecTranslator{}

routes := []model.HTTPRoute{
{
Backends: []model.Backend{
{
Name: "default-backend",
Namespace: "random-namespace",
Port: &model.BackendPort{
Port: 8080,
},
},
},
},
}

l1 := []model.HTTPListener{
{
Port: 443,
Hostname: "foo.bar",
ForceHTTPtoHTTPSRedirect: true,
Routes: routes,
},
{
Port: 443,
Hostname: "bar.foo",
Routes: routes,
},
}

l2 := []model.HTTPListener{
{
Port: 443,
Hostname: "bar.foo",
Routes: routes,
},
{
Port: 443,
Hostname: "foo.bar",
ForceHTTPtoHTTPSRedirect: true,
Routes: routes,
},
}

res1 := defT.getEnvoyHTTPRouteConfiguration(&model.Model{HTTP: l1})
res2 := defT.getEnvoyHTTPRouteConfiguration(&model.Model{HTTP: l2})

diffOutput := cmp.Diff(res1, res2, protocmp.Transform())
if len(diffOutput) != 0 {
t.Errorf("CiliumEnvoyConfigs did not match:\n%s\n", diffOutput)
}

// assert.Equal(t, res1, res2)
}

func TestSharedIngressTranslator_getEnvoyHTTPRouteConfiguration(t *testing.T) {
type args struct {
m *model.Model
Expand Down
59 changes: 30 additions & 29 deletions operator/pkg/model/translation/fixture_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,22 +315,22 @@ var hostRulesExpectedConfigEnforceHTTPS = []*envoy_config_route_v3.RouteConfigur
Name: "listener-insecure",
VirtualHosts: []*envoy_config_route_v3.VirtualHost{
{
Name: "foo.bar.com",
Domains: domainsHelper("foo.bar.com"),
Name: "*.foo.com",
Domains: domainsHelper("*.foo.com"),
Routes: []*envoy_config_route_v3.Route{
{
Match: envoyRouteMatchRootPath(),
Action: envoyHTTPSRouteRedirect(),
Match: withAuthority(envoyRouteMatchRootPath(), "^[^.]+[.]foo[.]com$"),
Action: envoyRouteAction("random-namespace", "wildcard-foo-com", "8080"),
},
},
},
{
Name: "*.foo.com",
Domains: domainsHelper("*.foo.com"),
Name: "foo.bar.com",
Domains: domainsHelper("foo.bar.com"),
Routes: []*envoy_config_route_v3.Route{
{
Match: withAuthority(envoyRouteMatchRootPath(), "^[^.]+[.]foo[.]com$"),
Action: envoyRouteAction("random-namespace", "wildcard-foo-com", "8080"),
Match: envoyRouteMatchRootPath(),
Action: envoyHTTPSRouteRedirect(),
},
},
},
Expand Down Expand Up @@ -573,7 +573,8 @@ var pathRulesExpectedConfig = []*envoy_config_route_v3.RouteConfiguration{
{
Match: envoyRouteMatchPrefixPath("/aaa"),
Action: envoyRouteAction("random-namespace", "aaa-prefix", "8080"),
}},
},
},
},
{
Name: "trailing-slash-path-rules",
Expand Down Expand Up @@ -1019,26 +1020,26 @@ var complexIngressExpectedConfigEnforceHTTPS = []*envoy_config_route_v3.RouteCon
Name: "listener-insecure",
VirtualHosts: []*envoy_config_route_v3.VirtualHost{
{
Name: "another-very-secure.server.com",
Domains: domainsHelper("another-very-secure.server.com"),
Name: "*",
Domains: domainsHelper("*"),
Routes: []*envoy_config_route_v3.Route{
{
Match: envoyRouteMatchExactPath("/dummy-path"),
Action: envoyHTTPSRouteRedirect(),
Action: envoyRouteAction("dummy-namespace", "dummy-backend", "8080"),
},
{
Match: envoyRouteMatchPrefixPath("/another-dummy-path"),
Action: envoyHTTPSRouteRedirect(),
Action: envoyRouteAction("dummy-namespace", "another-dummy-backend", "8081"),
},
{
Match: envoyRouteMatchRootPath(),
Action: envoyHTTPSRouteRedirect(),
Action: envoyRouteAction("dummy-namespace", "default-backend", "8080"),
},
},
},
{
Name: "very-secure.server.com",
Domains: domainsHelper("very-secure.server.com"),
Name: "another-very-secure.server.com",
Domains: domainsHelper("another-very-secure.server.com"),
Routes: []*envoy_config_route_v3.Route{
{
Match: envoyRouteMatchExactPath("/dummy-path"),
Expand All @@ -1055,20 +1056,20 @@ var complexIngressExpectedConfigEnforceHTTPS = []*envoy_config_route_v3.RouteCon
},
},
{
Name: "*",
Domains: domainsHelper("*"),
Name: "very-secure.server.com",
Domains: domainsHelper("very-secure.server.com"),
Routes: []*envoy_config_route_v3.Route{
{
Match: envoyRouteMatchExactPath("/dummy-path"),
Action: envoyRouteAction("dummy-namespace", "dummy-backend", "8080"),
Action: envoyHTTPSRouteRedirect(),
},
{
Match: envoyRouteMatchPrefixPath("/another-dummy-path"),
Action: envoyRouteAction("dummy-namespace", "another-dummy-backend", "8081"),
Action: envoyHTTPSRouteRedirect(),
},
{
Match: envoyRouteMatchRootPath(),
Action: envoyRouteAction("dummy-namespace", "default-backend", "8080"),
Action: envoyHTTPSRouteRedirect(),
},
},
},
Expand Down Expand Up @@ -1270,8 +1271,8 @@ var multipleRouteHostnamesExpectedConfig = []*envoy_config_route_v3.RouteConfigu
Name: "listener-insecure",
VirtualHosts: []*envoy_config_route_v3.VirtualHost{
{
Name: "foo.example.com",
Domains: domainsHelper("foo.example.com"),
Name: "bar.example.com",
Domains: domainsHelper("bar.example.com"),
Routes: []*envoy_config_route_v3.Route{
{
Match: envoyRouteMatchRootPath(),
Expand All @@ -1280,22 +1281,22 @@ var multipleRouteHostnamesExpectedConfig = []*envoy_config_route_v3.RouteConfigu
},
},
{
Name: "bar.example.com",
Domains: domainsHelper("bar.example.com"),
Name: "baz.example.com",
Domains: domainsHelper("baz.example.com"),
Routes: []*envoy_config_route_v3.Route{
{
Match: envoyRouteMatchRootPath(),
Action: envoyRouteAction("dummy-namespace", "dummy-backend", "8080"),
Action: envoyRouteAction("dummy-namespace", "another-dummy-backend", "8081"),
},
},
},
{
Name: "baz.example.com",
Domains: domainsHelper("baz.example.com"),
Name: "foo.example.com",
Domains: domainsHelper("foo.example.com"),
Routes: []*envoy_config_route_v3.Route{
{
Match: envoyRouteMatchRootPath(),
Action: envoyRouteAction("dummy-namespace", "another-dummy-backend", "8081"),
Action: envoyRouteAction("dummy-namespace", "dummy-backend", "8080"),
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1323,25 +1323,17 @@ var hostnameIntersectionHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyCo
Name: "listener-insecure",
VirtualHosts: []*envoy_config_route_v3.VirtualHost{
{
Name: "very.specific.com",
Domains: []string{"very.specific.com", "very.specific.com:*"},
Name: "*.anotherwildcard.io",
Domains: []string{"*.anotherwildcard.io", "*.anotherwildcard.io:*"},
Routes: []*envoy_config_route_v3.Route{
{
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
PathSeparatedPrefix: "/s1",
PathSeparatedPrefix: "/s4",
},
},
Action: routeActionBackendV1,
},
{
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
PathSeparatedPrefix: "/s3",
},
},
Action: routeActionBackendV3,
},
},
},
{
Expand Down Expand Up @@ -1387,17 +1379,25 @@ var hostnameIntersectionHTTPListenersCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyCo
},
},
{
Name: "*.anotherwildcard.io",
Domains: []string{"*.anotherwildcard.io", "*.anotherwildcard.io:*"},
Name: "very.specific.com",
Domains: []string{"very.specific.com", "very.specific.com:*"},
Routes: []*envoy_config_route_v3.Route{
{
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
PathSeparatedPrefix: "/s4",
PathSeparatedPrefix: "/s1",
},
},
Action: routeActionBackendV1,
},
{
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_PathSeparatedPrefix{
PathSeparatedPrefix: "/s3",
},
},
Action: routeActionBackendV3,
},
},
},
},
Expand Down Expand Up @@ -1561,58 +1561,58 @@ var listenerHostNameMatchingCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfig{
Name: "listener-insecure",
VirtualHosts: []*envoy_config_route_v3.VirtualHost{
{
Name: "bar.com",
Domains: []string{"bar.com", "bar.com:*"},
Name: "*.bar.com",
Domains: []string{"*.bar.com", "*.bar.com:*"},
Routes: []*envoy_config_route_v3.Route{
{
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
Prefix: "/",
},
},
Action: routeActionBackendV1,
Action: routeActionBackendV3,
},
},
},
{
Name: "foo.bar.com",
Domains: []string{"foo.bar.com", "foo.bar.com:*"},
Name: "*.foo.com",
Domains: []string{"*.foo.com", "*.foo.com:*"},
Routes: []*envoy_config_route_v3.Route{
{
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
Prefix: "/",
},
},
Action: routeActionBackendV2,
Action: routeActionBackendV3,
},
},
},
{
Name: "*.bar.com",
Domains: []string{"*.bar.com", "*.bar.com:*"},
Name: "bar.com",
Domains: []string{"bar.com", "bar.com:*"},
Routes: []*envoy_config_route_v3.Route{
{
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
Prefix: "/",
},
},
Action: routeActionBackendV3,
Action: routeActionBackendV1,
},
},
},
{
Name: "*.foo.com",
Domains: []string{"*.foo.com", "*.foo.com:*"},
Name: "foo.bar.com",
Domains: []string{"foo.bar.com", "foo.bar.com:*"},
Routes: []*envoy_config_route_v3.Route{
{
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
Prefix: "/",
},
},
Action: routeActionBackendV3,
Action: routeActionBackendV2,
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,20 +478,6 @@ var hostRulesListenersEnforceHTTPSCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfi
Any: toAny(&envoy_config_route_v3.RouteConfiguration{
Name: "listener-insecure",
VirtualHosts: []*envoy_config_route_v3.VirtualHost{
{
Name: "foo.bar.com",
Domains: []string{"foo.bar.com", "foo.bar.com:*"},
Routes: []*envoy_config_route_v3.Route{
{
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
Prefix: "/",
},
},
Action: toHTTPSRedirectAction(),
},
},
},
{
Name: "*.foo.com",
Domains: []string{"*.foo.com", "*.foo.com:*"},
Expand Down Expand Up @@ -521,6 +507,20 @@ var hostRulesListenersEnforceHTTPSCiliumEnvoyConfig = &ciliumv2.CiliumEnvoyConfi
},
},
},
{
Name: "foo.bar.com",
Domains: []string{"foo.bar.com", "foo.bar.com:*"},
Routes: []*envoy_config_route_v3.Route{
{
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
Prefix: "/",
},
},
Action: toHTTPSRedirectAction(),
},
},
},
},
}),
},
Expand Down