mirror of
https://github.com/traefik/traefik.git
synced 2026-10-28 08:36:10 +08:00
14833 lines
518 KiB
Go
14833 lines
518 KiB
Go
package gateway
|
|
|
|
import (
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"errors"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
ptypes "github.com/traefik/paerser/types"
|
|
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
|
"github.com/traefik/traefik/v3/pkg/provider"
|
|
traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
|
"github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s"
|
|
"github.com/traefik/traefik/v3/pkg/tls"
|
|
"github.com/traefik/traefik/v3/pkg/types"
|
|
"google.golang.org/grpc/codes"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/meta"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
ktypes "k8s.io/apimachinery/pkg/types"
|
|
kubefake "k8s.io/client-go/kubernetes/fake"
|
|
kscheme "k8s.io/client-go/kubernetes/scheme"
|
|
ktesting "k8s.io/client-go/testing"
|
|
gatev1 "sigs.k8s.io/gateway-api/apis/v1"
|
|
gatefake "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/fake"
|
|
)
|
|
|
|
var _ provider.Provider = (*Provider)(nil)
|
|
|
|
func defaultListenerTLSOptions() tls.Options {
|
|
var opts tls.Options
|
|
opts.SetDefaults()
|
|
return opts
|
|
}
|
|
|
|
func init() {
|
|
// required by k8s.MustParseYaml
|
|
if err := gatev1.Install(kscheme.Scheme); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
const (
|
|
listenerCert string = `-----BEGIN CERTIFICATE-----
|
|
MIIBqDCCAU6gAwIBAgIUYOsr0QgHOBq4kYRCL5+TDdVt6bQwCgYIKoZIzj0EAwIw
|
|
FjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wHhcNMjUxMDEwMDcxNzMwWhcNMzUxMDA4
|
|
MDcxNzMwWjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqG
|
|
SM49AwEHA0IABDOriw3ZQ7wIhWrbPS6JFQT3bToNCF00vSV5fab6TbXyL8tlsGre
|
|
TRIF2EwgsteMOkxGKKSlDvuaDwq8p/qV+0ujejB4MB0GA1UdDgQWBBRMEkuexXQh
|
|
UtDgRg1KBv72CDq+EzAfBgNVHSMEGDAWgBRMEkuexXQhUtDgRg1KBv72CDq+EzAP
|
|
BgNVHRMBAf8EBTADAQH/MCUGA1UdEQQeMByCC2V4YW1wbGUuY29tgg0qLmV4YW1w
|
|
bGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIQDs87Vk0swA6HgOJjROye1mxD83qcGy
|
|
peFgoxV93Dy+cwIgV0MMEJJbVsTyZK3EQ++Xc5rEL78nrJ+YIEV+rCUWj5U=
|
|
-----END CERTIFICATE-----`
|
|
listenerKey string = `-----BEGIN PRIVATE KEY-----
|
|
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgnwgL5DY4UB14sM6f
|
|
DikQdtqh2QW1ArfF4fc1UFzifdGhRANCAAQzq4sN2UO8CIVq2z0uiRUE9206DQhd
|
|
NL0leX2m+k218i/LZbBq3k0SBdhMILLXjDpMRiikpQ77mg8KvKf6lftL
|
|
-----END PRIVATE KEY-----`
|
|
)
|
|
|
|
func TestGatewayClassLabelSelector(t *testing.T) {
|
|
k8sObjects, gwObjects := readResources(t, []string{"gatewayclass_labelselector.yaml"})
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
// This is initialized by the Provider init method but this cannot be called in a unit test.
|
|
client.labelSelector = "name=traefik-internal"
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: map[string]Entrypoint{"http": {Address: ":9080"}},
|
|
StatusAddress: &StatusAddress{IP: "1.2.3.4"},
|
|
client: client,
|
|
}
|
|
|
|
_, statusReport, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
statusReport.Flush(t.Context(), p.client)
|
|
|
|
gw, err := gwClient.GatewayV1().Gateways("default").Get(t.Context(), "traefik-external", metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
|
|
assert.Empty(t, gw.Status.Addresses)
|
|
|
|
gw, err = gwClient.GatewayV1().Gateways("default").Get(t.Context(), "traefik-internal", metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
require.Len(t, gw.Status.Addresses, 1)
|
|
require.NotNil(t, gw.Status.Addresses[0].Type)
|
|
|
|
assert.Equal(t, gatev1.IPAddressType, *gw.Status.Addresses[0].Type)
|
|
assert.Equal(t, "1.2.3.4", gw.Status.Addresses[0].Value)
|
|
}
|
|
|
|
func TestGatewayClassFieldSelector(t *testing.T) {
|
|
// The resources are only there to make the informer emit a first event to wait for.
|
|
_, gwObjects := readResources(t, []string{"gatewayclass_labelselector.yaml"})
|
|
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
client := newClientImpl(kubefake.NewClientset(), gwClient)
|
|
client.gatewayClass = "traefik-internal"
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
<-eventCh
|
|
|
|
// The fake clientset ignores field selectors, so the lister cannot show the filtering.
|
|
// The API server does the filtering. This test only checks the selector is sent to it.
|
|
var (
|
|
listed bool
|
|
watched bool
|
|
)
|
|
for _, action := range gwClient.Actions() {
|
|
if action.GetResource().Resource != "gatewayclasses" {
|
|
continue
|
|
}
|
|
|
|
switch a := action.(type) {
|
|
case ktesting.ListAction:
|
|
listed = true
|
|
assert.Equal(t, "metadata.name=traefik-internal", a.GetListRestrictions().Fields.String())
|
|
case ktesting.WatchAction:
|
|
watched = true
|
|
assert.Equal(t, "metadata.name=traefik-internal", a.GetWatchRestrictions().Fields.String())
|
|
}
|
|
}
|
|
|
|
assert.True(t, listed)
|
|
assert.True(t, watched)
|
|
}
|
|
|
|
func TestGatewayClassAndLabelSelectorExclusive(t *testing.T) {
|
|
p := Provider{
|
|
GatewayClass: "traefik-internal",
|
|
LabelSelector: "name=traefik-internal",
|
|
}
|
|
|
|
_, err := p.newK8sClient(t.Context())
|
|
require.EqualError(t, err, "gatewayClass and labelSelector options are mutually exclusive")
|
|
}
|
|
|
|
func TestGatewayScoping(t *testing.T) {
|
|
k8sObjects, gwObjects := readResources(t, []string{"gateway_scoping.yaml"})
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: map[string]Entrypoint{"http": {Address: ":9080"}},
|
|
StatusAddress: &StatusAddress{IP: "1.2.3.4"},
|
|
// Scope the provider to a single Gateway.
|
|
Gateways: []NamespacedName{{Namespace: "default", Name: "traefik-internal"}},
|
|
client: client,
|
|
}
|
|
|
|
_, statusReport, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
statusReport.Flush(t.Context(), p.client)
|
|
|
|
// The scoped Gateway is managed and gets a status address.
|
|
gw, err := gwClient.GatewayV1().Gateways("default").Get(t.Context(), "traefik-internal", metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
require.Len(t, gw.Status.Addresses, 1)
|
|
assert.Equal(t, "1.2.3.4", gw.Status.Addresses[0].Value)
|
|
|
|
// The other Gateway is ignored.
|
|
gw, err = gwClient.GatewayV1().Gateways("default").Get(t.Context(), "traefik-external", metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
assert.Empty(t, gw.Status.Addresses)
|
|
}
|
|
|
|
func TestLoadHTTPRoutes(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
ingressClass string
|
|
paths []string
|
|
expected *dynamic.Configuration
|
|
entryPoints map[string]Entrypoint
|
|
nativeLB bool
|
|
}{
|
|
{
|
|
desc: "Empty",
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because missing entry point",
|
|
paths: []string{"services.yml", "httproute/simple.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":443",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because no http route defined",
|
|
paths: []string{"services.yml", "httproute/without_httproute.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by missing GatewayClass",
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
paths: []string{"services.yml", "httproute/without_gatewayclass.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by unknown GatewayClass controller desc",
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
paths: []string{"services.yml", "httproute/gatewayclass_with_unknown_controller.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Router with service in error caused by wrong TargetPort",
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
paths: []string{"services.yml", "httproute/with_wrong_service_port.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
Status: new(500),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by HTTPS without TLS",
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":443",
|
|
}},
|
|
paths: []string{"services.yml", "httproute/with_protocol_https_without_tls.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by HTTPS with TLS passthrough",
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":443",
|
|
}},
|
|
paths: []string{"services.yml", "httproute/with_protocol_https_with_tls_passthrough.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by HTTPRoute with protocol TLS",
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":443",
|
|
}},
|
|
paths: []string{"services.yml", "httproute/with_protocol_tls.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by HTTPRoute with protocol TCP",
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":443",
|
|
}},
|
|
paths: []string{"services.yml", "httproute/with_protocol_tcp.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by TCPRoute with protocol HTTP",
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":9000",
|
|
}},
|
|
paths: []string{"services.yml", "tcproute/with_protocol_http.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by TCPRoute with protocol HTTPS",
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":9000",
|
|
}},
|
|
paths: []string{"services.yml", "tcproute/with_protocol_https.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by TLSRoute with protocol TCP",
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":9001",
|
|
}},
|
|
paths: []string{"services.yml", "tlsroute/with_protocol_tcp.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by TLSRoute with protocol HTTP",
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":9001",
|
|
}},
|
|
paths: []string{"services.yml", "tlsroute/with_protocol_http.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by TLSRoute with protocol HTTPS",
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":9001",
|
|
}},
|
|
paths: []string{"services.yml", "tlsroute/with_protocol_https.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused use http entrypoint with tls activated with HTTPRoute",
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":443",
|
|
HasHTTPTLSConf: true,
|
|
}},
|
|
paths: []string{"services.yml", "httproute/simple_with_tls_entrypoint.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because no tcp route defined tls protocol",
|
|
paths: []string{"services.yml", "tcproute/without_tcproute_tls_protocol.yml"},
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8080",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by HTTPRoute with TLS configuration",
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
paths: []string{"services.yml", "httproute/with_tls_configuration.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute",
|
|
paths: []string{"services.yml", "httproute/simple.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Listeners isolation with a specificity chain spread over three Gateways",
|
|
paths: []string{"services.yml", "httproute/listener_isolation_three_gateways.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `(Host("*")) && !(Host("**.example.com") || Host("abc.example.com"))`,
|
|
},
|
|
"listener-web-http-example-com-e7b9da953ca48d642d6b": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `(Host("**.example.com")) && !(Host("abc.example.com"))`,
|
|
},
|
|
"listener-web-http-abc-example-com-05dd4f497bcb27f2cdca": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("abc.example.com")`,
|
|
},
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-web-0-6bf410c47a90e258b1eb": {
|
|
ParentRefs: []string{
|
|
"listener-web-http-5b3226d4ebd42b7200f1",
|
|
"listener-web-http-example-com-e7b9da953ca48d642d6b",
|
|
},
|
|
Service: "httproute-default-http-app-catchall-gw-default-my-gateway-ep-web-0-6bf410c47a90e258b1eb-wrr",
|
|
Rule: `Path("/catchall")`,
|
|
Priority: 100001,
|
|
RuleSyntax: "default",
|
|
},
|
|
"httproute-default-http-app-precise-gw-default-my-gateway-ep-web-0-5b6dacf4c7da9367767b": {
|
|
ParentRefs: []string{"listener-web-http-abc-example-com-05dd4f497bcb27f2cdca"},
|
|
Service: "httproute-default-http-app-precise-gw-default-my-gateway-ep-web-0-5b6dacf4c7da9367767b-wrr",
|
|
Rule: `Host("abc.example.com") && Path("/precise")`,
|
|
Priority: 100016,
|
|
RuleSyntax: "default",
|
|
},
|
|
"httproute-default-http-app-wildcard-gw-default-my-wildcard-gateway-ep-web-0-63284dea2e7614ab00a2": {
|
|
ParentRefs: []string{
|
|
"listener-web-http-example-com-e7b9da953ca48d642d6b",
|
|
"listener-web-http-abc-example-com-05dd4f497bcb27f2cdca",
|
|
},
|
|
Service: "httproute-default-http-app-wildcard-gw-default-my-wildcard-gateway-ep-web-0-63284dea2e7614ab00a2-wrr",
|
|
Rule: `Host("**.example.com") && Path("/wildcard")`,
|
|
Priority: 100014,
|
|
RuleSyntax: "default",
|
|
},
|
|
"httproute-default-http-app-other-gw-default-my-other-gateway-ep-web-0-d7590587db124f0d35ce": {
|
|
ParentRefs: []string{
|
|
"listener-web-http-5b3226d4ebd42b7200f1",
|
|
"listener-web-http-example-com-e7b9da953ca48d642d6b",
|
|
"listener-web-http-abc-example-com-05dd4f497bcb27f2cdca",
|
|
},
|
|
Service: "httproute-default-http-app-other-gw-default-my-other-gateway-ep-web-0-d7590587db124f0d35ce-wrr",
|
|
Rule: `Path("/other")`,
|
|
Priority: 100001,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-web-0-6bf410c47a90e258b1eb-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-catchall-gw-default-my-gateway-ep-web-0-6bf410c47a90e258b1eb-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-web-0-6bf410c47a90e258b1eb-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-precise-gw-default-my-gateway-ep-web-0-5b6dacf4c7da9367767b-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-precise-gw-default-my-gateway-ep-web-0-5b6dacf4c7da9367767b-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-precise-gw-default-my-gateway-ep-web-0-5b6dacf4c7da9367767b-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-wildcard-gw-default-my-wildcard-gateway-ep-web-0-63284dea2e7614ab00a2-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-wildcard-gw-default-my-wildcard-gateway-ep-web-0-63284dea2e7614ab00a2-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-wildcard-gw-default-my-wildcard-gateway-ep-web-0-63284dea2e7614ab00a2-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-other-gw-default-my-other-gateway-ep-web-0-d7590587db124f0d35ce-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-other-gw-default-my-other-gateway-ep-web-0-d7590587db124f0d35ce-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-other-gw-default-my-other-gateway-ep-web-0-d7590587db124f0d35ce-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Listeners isolation with a hostname listener and a catch-all listener on two Gateways",
|
|
paths: []string{"services.yml", "httproute/listener_isolation.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `(Host("*")) && !(Host("abc.example.com"))`,
|
|
},
|
|
"listener-web-http-abc-example-com-05dd4f497bcb27f2cdca": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("abc.example.com")`,
|
|
},
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-web-0-6bf410c47a90e258b1eb": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-catchall-gw-default-my-gateway-ep-web-0-6bf410c47a90e258b1eb-wrr",
|
|
Rule: `Path("/catchall")`,
|
|
Priority: 100001,
|
|
RuleSyntax: "default",
|
|
},
|
|
"httproute-default-http-app-precise-gw-default-my-gateway-ep-web-0-5b6dacf4c7da9367767b": {
|
|
ParentRefs: []string{"listener-web-http-abc-example-com-05dd4f497bcb27f2cdca"},
|
|
Service: "httproute-default-http-app-precise-gw-default-my-gateway-ep-web-0-5b6dacf4c7da9367767b-wrr",
|
|
Rule: `Host("abc.example.com") && Path("/precise")`,
|
|
Priority: 100016,
|
|
RuleSyntax: "default",
|
|
},
|
|
"httproute-default-http-app-other-gw-default-my-other-gateway-ep-web-0-d7590587db124f0d35ce": {
|
|
ParentRefs: []string{
|
|
"listener-web-http-5b3226d4ebd42b7200f1",
|
|
"listener-web-http-abc-example-com-05dd4f497bcb27f2cdca",
|
|
},
|
|
Service: "httproute-default-http-app-other-gw-default-my-other-gateway-ep-web-0-d7590587db124f0d35ce-wrr",
|
|
Rule: `Path("/other")`,
|
|
Priority: 100001,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-web-0-6bf410c47a90e258b1eb-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-catchall-gw-default-my-gateway-ep-web-0-6bf410c47a90e258b1eb-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-web-0-6bf410c47a90e258b1eb-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-precise-gw-default-my-gateway-ep-web-0-5b6dacf4c7da9367767b-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-precise-gw-default-my-gateway-ep-web-0-5b6dacf4c7da9367767b-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-precise-gw-default-my-gateway-ep-web-0-5b6dacf4c7da9367767b-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-other-gw-default-my-other-gateway-ep-web-0-d7590587db124f0d35ce-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-other-gw-default-my-other-gateway-ep-web-0-d7590587db124f0d35ce-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-other-gw-default-my-other-gateway-ep-web-0-d7590587db124f0d35ce-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute with a wildcard listener hostname",
|
|
paths: []string{"services.yml", "httproute/simple_with_wildcard_listener_hostname.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-example-com-e7b9da953ca48d642d6b": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("**.example.com")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-2944dbefe4493e703281": {
|
|
ParentRefs: []string{"listener-web-http-example-com-e7b9da953ca48d642d6b"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-2944dbefe4493e703281-wrr",
|
|
Rule: `Host("**.example.com") && Path("/bar")`,
|
|
Priority: 100014,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-2944dbefe4493e703281-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-2944dbefe4493e703281-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-2944dbefe4493e703281-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, without backendRefs",
|
|
paths: []string{"services.yml", "httproute/without_backendrefs.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-b0d3512b71b7695aa511": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-b0d3512b71b7695aa511-wrr",
|
|
Rule: `Host("foo.com") && Path("/omitted")`,
|
|
Priority: 100009,
|
|
RuleSyntax: "default",
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-28c8ec797c4b0f521cf7": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-28c8ec797c4b0f521cf7-wrr",
|
|
Rule: `Host("foo.com") && Path("/empty")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-b0d3512b71b7695aa511-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "no-backend-refs",
|
|
Status: new(500),
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-28c8ec797c4b0f521cf7-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "no-backend-refs",
|
|
Status: new(500),
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoute with timeouts",
|
|
paths: []string{"services.yml", "httproute/with_request_timeout.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100010,
|
|
RuleSyntax: "default",
|
|
RespondingTimeouts: &dynamic.RouterRespondingTimeouts{ReadTimeout: new(ptypes.Duration(10 * time.Second)), WriteTimeout: new(ptypes.Duration(10 * time.Second))},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-6bebfd4e0e692b59df74": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-6bebfd4e0e692b59df74-wrr",
|
|
Rule: `Host("foo.com") && Path("/baz")`,
|
|
Priority: 100009,
|
|
RuleSyntax: "default",
|
|
RespondingTimeouts: &dynamic.RouterRespondingTimeouts{ReadTimeout: new(ptypes.Duration(0)), WriteTimeout: new(ptypes.Duration(0))},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-c465583028340322911a": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-c465583028340322911a-wrr",
|
|
Rule: `Host("foo.com") && Path("/buz")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-6bebfd4e0e692b59df74-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-6bebfd4e0e692b59df74-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-c465583028340322911a-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-c465583028340322911a-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
ServersTransport: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-6bebfd4e0e692b59df74-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-c465583028340322911a-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
ServersTransport: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-c465583028340322911a-svc-default-whoami-0",
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
|
DialTimeout: ptypes.Duration(30 * time.Second),
|
|
ResponseHeaderTimeout: ptypes.Duration(5 * time.Second),
|
|
IdleConnTimeout: ptypes.Duration(90 * time.Second),
|
|
PingTimeout: ptypes.Duration(15 * time.Second),
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-c465583028340322911a-svc-default-whoami-0": {
|
|
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
|
|
DialTimeout: ptypes.Duration(30 * time.Second),
|
|
ResponseHeaderTimeout: ptypes.Duration(5 * time.Second),
|
|
IdleConnTimeout: ptypes.Duration(90 * time.Second),
|
|
PingTimeout: ptypes.Duration(15 * time.Second),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, with api@internal service",
|
|
paths: []string{"services.yml", "httproute/simple_to_api_internal.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "api@internal",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute with protocol HTTPS",
|
|
paths: []string{"services.yml", "httproute/with_protocol_https.yml"},
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":443",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoute with multiple TLS certificateRefs",
|
|
paths: []string{"services.yml", "httproute/with_multiple_certificaterefs.yml"},
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":443",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoute with multiple certificateRefs, one missing",
|
|
paths: []string{"services.yml", "httproute/with_multiple_certificaterefs_one_missing.yml"},
|
|
entryPoints: map[string]Entrypoint{"websecure": {
|
|
Address: ":443",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, with multiple hosts",
|
|
paths: []string{"services.yml", "httproute/with_multiple_host.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-fe758dd8380cc8acabbc": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-fe758dd8380cc8acabbc-wrr",
|
|
Rule: `(Host("foo.com") || Host("bar.com")) && PathPrefix("/")`,
|
|
Priority: 9,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-fe758dd8380cc8acabbc-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-fe758dd8380cc8acabbc-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-fe758dd8380cc8acabbc-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, with two hosts one wildcard",
|
|
paths: []string{"services.yml", "with_two_hosts_one_wildcard.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-5af0a8dc466bcb103301": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-5af0a8dc466bcb103301-wrr",
|
|
Rule: `(Host("foo.com") || Host("**.bar.com")) && PathPrefix("/")`,
|
|
Priority: 11,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-5af0a8dc466bcb103301-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-5af0a8dc466bcb103301-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-5af0a8dc466bcb103301-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, with one host and a wildcard",
|
|
paths: []string{"services.yml", "with_two_hosts_wildcard.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-764e519b9557509caa7d": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-764e519b9557509caa7d-wrr",
|
|
Rule: `(Host("foo.com") || Host("**.foo.com")) && PathPrefix("/")`,
|
|
Priority: 11,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-764e519b9557509caa7d-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-764e519b9557509caa7d-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-764e519b9557509caa7d-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "One HTTPRoute with two different rules",
|
|
paths: []string{"services.yml", "httproute/two_rules.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100009,
|
|
RuleSyntax: "default",
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-71ae3ac5f5f8583c5cfa": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Rule: `Host("foo.com") && Path("/bir")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-71ae3ac5f5f8583c5cfa-wrr",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-71ae3ac5f5f8583c5cfa-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-71ae3ac5f5f8583c5cfa-svc-default-whoami2-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-71ae3ac5f5f8583c5cfa-svc-default-whoami2-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.3:8080",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.4:8080",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "One HTTPRoute with one rule two targets",
|
|
paths: []string{"services.yml", "httproute/one_rule_two_targets.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami2-1",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami2-1": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.3:8080",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.4:8080",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Two Gateways and one HTTPRoute",
|
|
paths: []string{"services.yml", "httproute/with_two_gateways_one_httproute.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {
|
|
Address: ":80",
|
|
},
|
|
"websecure": {
|
|
Address: ":443",
|
|
},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-http-ep-web-0-779a0bc558422ee1b154": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-http-ep-web-0-779a0bc558422ee1b154-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-https-ep-websecure-0-036eecf3c21d00eac117": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-https-ep-websecure-0-036eecf3c21d00eac117-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-http-ep-web-0-779a0bc558422ee1b154-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-http-ep-web-0-779a0bc558422ee1b154-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-https-ep-websecure-0-036eecf3c21d00eac117-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-https-ep-websecure-0-036eecf3c21d00eac117-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-http-ep-web-0-779a0bc558422ee1b154-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-https-ep-websecure-0-036eecf3c21d00eac117-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Gateway with two listeners and one HTTPRoute",
|
|
paths: []string{"services.yml", "httproute/with_two_listeners_one_httproute.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {
|
|
Address: ":80",
|
|
},
|
|
"websecure": {
|
|
Address: ":443",
|
|
},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, with several rules",
|
|
paths: []string{"services.yml", "httproute/with_several_rules.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-cbebdedef34a6261eced": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Rule: `Host("foo.com") && (Path("/bar") || PathPrefix("/bar/")) && Header("my-header","foo") && Header("my-header2","bar")`,
|
|
Priority: 10610,
|
|
RuleSyntax: "default",
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-cbebdedef34a6261eced-wrr",
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-74d0c698c3be747a738f": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Rule: `Host("foo.com") && PathRegexp("^/buzz/[0-9]+$")`,
|
|
Priority: 11408,
|
|
RuleSyntax: "default",
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-74d0c698c3be747a738f-wrr",
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-d4501fe0597184abd40e": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Rule: `Host("foo.com") && Path("/bar") && Header("my-header","bar")`,
|
|
Priority: 100109,
|
|
RuleSyntax: "default",
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-d4501fe0597184abd40e-wrr",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-cbebdedef34a6261eced-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-cbebdedef34a6261eced-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-74d0c698c3be747a738f-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-74d0c698c3be747a738f-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-d4501fe0597184abd40e-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-d4501fe0597184abd40e-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-cbebdedef34a6261eced-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-74d0c698c3be747a738f-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-d4501fe0597184abd40e-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, with method matching",
|
|
paths: []string{"services.yml", "httproute/with_method_matching.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-eaf4f488cc5127097136": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Rule: `Host("foo.com") && (Path("/foo") || PathPrefix("/foo/")) && Method("GET")`,
|
|
Priority: 11408,
|
|
RuleSyntax: "default",
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-eaf4f488cc5127097136-wrr",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-eaf4f488cc5127097136-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-eaf4f488cc5127097136-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-eaf4f488cc5127097136-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, with query param matching",
|
|
paths: []string{"services.yml", "httproute/with_query_param_matching.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-8dc41dbb469b11d7ce9c": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Rule: `Host("foo.com") && (Path("/foo") || PathPrefix("/foo/")) && Query("foo","bar") && QueryRegexp("baz","buz")`,
|
|
Priority: 10428,
|
|
RuleSyntax: "default",
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-8dc41dbb469b11d7ce9c-wrr",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-8dc41dbb469b11d7ce9c-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-8dc41dbb469b11d7ce9c-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-8dc41dbb469b11d7ce9c-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoute with Same namespace selector",
|
|
paths: []string{"services.yml", "httproute/with_namespace_same.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-71c892303a6d70cb4efe": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-71c892303a6d70cb4efe-wrr",
|
|
Rule: `Host("foo.com") && Path("/foo")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-71c892303a6d70cb4efe-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-71c892303a6d70cb4efe-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-71c892303a6d70cb4efe-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoute with All namespace selector",
|
|
paths: []string{"services.yml", "httproute/with_namespace_all.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-71c892303a6d70cb4efe": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-71c892303a6d70cb4efe-wrr",
|
|
Rule: `Host("foo.com") && Path("/foo")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-eb47eeb38d713d8e351d": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-eb47eeb38d713d8e351d-wrr",
|
|
Rule: `Host("bar.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-71c892303a6d70cb4efe-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-71c892303a6d70cb4efe-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-eb47eeb38d713d8e351d-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-eb47eeb38d713d8e351d-svc-bar-whoami-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-71c892303a6d70cb4efe-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-eb47eeb38d713d8e351d-svc-bar-whoami-bar-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.11:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.12:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoute with namespace selector",
|
|
paths: []string{"services.yml", "httproute/with_namespace_selector.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-eb47eeb38d713d8e351d": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-eb47eeb38d713d8e351d-wrr",
|
|
Rule: `Host("bar.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-eb47eeb38d713d8e351d-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-eb47eeb38d713d8e351d-svc-bar-whoami-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-eb47eeb38d713d8e351d-svc-bar-whoami-bar-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.11:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.12:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, request header modifier",
|
|
paths: []string{"services.yml", "httproute/filter_request_header_modifier.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-wrr",
|
|
Rule: `Host("example.org") && PathPrefix("/")`,
|
|
Priority: 13,
|
|
RuleSyntax: "default",
|
|
Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-requestheadermodifier-0"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-requestheadermodifier-0": {
|
|
RequestHeaderModifier: &dynamic.HeaderModifier{
|
|
Set: map[string]string{"X-Foo": "Bar"},
|
|
Add: map[string]string{"X-Bar": "Foo"},
|
|
Remove: []string{"X-Baz"},
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, response header modifier",
|
|
paths: []string{"services.yml", "httproute/filter_response_header_modifier.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-wrr",
|
|
Rule: `Host("example.org") && PathPrefix("/")`,
|
|
Priority: 13,
|
|
RuleSyntax: "default",
|
|
Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-responseheadermodifier-0"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-responseheadermodifier-0": {
|
|
ResponseHeaderModifier: &dynamic.HeaderModifier{
|
|
Set: map[string]string{"X-Foo": "Bar"},
|
|
Add: map[string]string{"X-Bar": "Foo"},
|
|
Remove: []string{"X-Baz"},
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, backend filter request header modifier",
|
|
paths: []string{"services.yml", "httproute/backend_filter_request_header_modifier.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-78ef4770613eae69b5da": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-78ef4770613eae69b5da-wrr",
|
|
Rule: `Host("foo.com") && (Path("/bar") || PathPrefix("/bar/"))`,
|
|
Priority: 10408,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-78ef4770613eae69b5da-svc-default-whoami-0-requestheadermodifier-0": {
|
|
RequestHeaderModifier: &dynamic.HeaderModifier{
|
|
Set: map[string]string{"X-Foo": "Bar"},
|
|
Add: map[string]string{"X-Bar": "Foo"},
|
|
Remove: []string{"X-Baz"},
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-78ef4770613eae69b5da-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-78ef4770613eae69b5da-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-78ef4770613eae69b5da-svc-default-whoami-0": {
|
|
Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-78ef4770613eae69b5da-svc-default-whoami-0-requestheadermodifier-0"},
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, redirect HTTP to HTTPS",
|
|
paths: []string{"services.yml", "httproute/filter_http_to_https.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-wrr",
|
|
Rule: `Host("example.org") && PathPrefix("/")`,
|
|
Priority: 13,
|
|
RuleSyntax: "default",
|
|
Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-requestredirect-0"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-requestredirect-0": {
|
|
RequestRedirect: &dynamic.RequestRedirect{
|
|
Scheme: new("https"),
|
|
Port: new(""),
|
|
StatusCode: http.StatusMovedPermanently,
|
|
},
|
|
},
|
|
},
|
|
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, redirect HTTP to HTTPS with hostname",
|
|
paths: []string{"services.yml", "httproute/filter_http_to_https_with_hostname_and_port.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-wrr",
|
|
Rule: `Host("example.org") && PathPrefix("/")`,
|
|
Priority: 13,
|
|
RuleSyntax: "default",
|
|
Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-requestredirect-0"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-requestredirect-0": {
|
|
RequestRedirect: &dynamic.RequestRedirect{
|
|
Hostname: new("example.com"),
|
|
Port: new("443"),
|
|
StatusCode: http.StatusFound,
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-c683caccb22c43e5e664-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute URL rewrite FullPath",
|
|
paths: []string{"services.yml", "httproute/filter_url_rewrite_fullpath.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-wrr",
|
|
Rule: `Host("example.com") && (Path("/foo") || PathPrefix("/foo/"))`,
|
|
RuleSyntax: "default",
|
|
Priority: 10412,
|
|
Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-urlrewrite-0"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-urlrewrite-0": {
|
|
URLRewrite: &dynamic.URLRewrite{
|
|
Path: new("/bar"),
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-svc-default-whoami-0",
|
|
Weight: func(i int) *int { return &i }(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute URL rewrite Hostname",
|
|
paths: []string{"services.yml", "httproute/filter_url_rewrite_hostname.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-wrr",
|
|
Rule: `Host("example.com") && (Path("/foo") || PathPrefix("/foo/"))`,
|
|
RuleSyntax: "default",
|
|
Priority: 10412,
|
|
Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-urlrewrite-0"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-urlrewrite-0": {
|
|
URLRewrite: &dynamic.URLRewrite{
|
|
Hostname: new("www.foo.bar"),
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-svc-default-whoami-0",
|
|
Weight: func(i int) *int { return &i }(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute URL rewrite Combined",
|
|
paths: []string{"services.yml", "httproute/filter_url_rewrite_combined.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-wrr",
|
|
Rule: `Host("example.com") && (Path("/foo") || PathPrefix("/foo/"))`,
|
|
RuleSyntax: "default",
|
|
Priority: 10412,
|
|
Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-urlrewrite-0"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-urlrewrite-0": {
|
|
URLRewrite: &dynamic.URLRewrite{
|
|
Hostname: new("www.foo.bar"),
|
|
Path: new("/xyz"),
|
|
PathPrefix: new("/foo"),
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-svc-default-whoami-0",
|
|
Weight: func(i int) *int { return &i }(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-d1e350a646631250e99d-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute and BackendTLSPolicy with CA certificate",
|
|
paths: []string{"services.yml", "httproute/with_backend_tls_policy.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "https://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "https://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
ServersTransport: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
ServerName: "whoami",
|
|
RootCAs: []types.FileOrContent{
|
|
"CA1",
|
|
"CA2",
|
|
"CA1-secret",
|
|
"CA2-secret",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute and BackendTLSPolicy with subjectAltNames",
|
|
paths: []string{"services.yml", "httproute/with_backend_tls_policy_san.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "https://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "https://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
ServersTransport: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
ServerName: "whoami",
|
|
InsecureSkipVerify: true,
|
|
PeerCertSANs: []tls.SAN{
|
|
{Type: tls.SANDNSNameType, Value: "whoami.default.svc.cluster.local"},
|
|
{Type: tls.SANURIType, Value: "spiffe://cluster.local/ns/default/sa/whoami"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute and BackendTLSPolicy with System CA",
|
|
paths: []string{"services.yml", "httproute/with_backend_tls_policy_system.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "https://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "https://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
ServersTransport: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
ServerName: "whoami",
|
|
},
|
|
},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute with NativeLBByDefault enabled",
|
|
paths: []string{"services.yml", "httproute/simple.yml"},
|
|
nativeLB: true,
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.10.1:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute with NativeLB annotation",
|
|
paths: []string{"services.yml", "httproute/simple_nativelb.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-native-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-native-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.10.1:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute with NativeLBByDefault enabled but service has disabled nativelb",
|
|
paths: []string{"services.yml", "httproute/simple_nativelb_disabled.yml"},
|
|
nativeLB: true,
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-native-disabled-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-native-disabled-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.20:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.21:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoute with nil endpointslice port name",
|
|
paths: []string{"services.yml", "httproute/with_nil_endpointslice_port_name.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-nil-port-name-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-nil-port-name-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoute with nil endpointslice port value",
|
|
paths: []string{"services.yml", "httproute/with_nil_endpointslice_port_value.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-nil-port-value-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-nil-port-value-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoutes with identical rules",
|
|
paths: []string{"services.yml", "httproute/with_identical_rules.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-foo-com-5f20d578e2e3eccac466": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("foo.com")`,
|
|
},
|
|
"httproute-default-http-app-catch-all-gw-default-my-gateway-ep-web-0-402d8b0319543c8e637b": {
|
|
Service: "httproute-default-http-app-catch-all-gw-default-my-gateway-ep-web-0-402d8b0319543c8e637b-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 9,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-foo-com-5f20d578e2e3eccac466"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-catch-all-gw-default-my-gateway-ep-web-0-402d8b0319543c8e637b-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-catch-all-gw-default-my-gateway-ep-web-0-402d8b0319543c8e637b-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-catch-all-gw-default-my-gateway-ep-web-0-402d8b0319543c8e637b-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoute attached to a ListenerSet HTTPS listener",
|
|
paths: []string{"services.yml", "httproute/with_listenerset.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
"websecure": {Address: ":443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-wrr",
|
|
Rule: `Host("foo.example.com") && Path("/bar")`,
|
|
ParentRefs: []string{
|
|
"listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
RuleSyntax: "default",
|
|
Priority: 100016,
|
|
},
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{
|
|
"websecure",
|
|
},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
Strategy: dynamic.BalancerStrategy("wrr"),
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100000000),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
CipherSuites: []string{
|
|
"TLS_AES_128_GCM_SHA256",
|
|
"TLS_AES_256_GCM_SHA384",
|
|
"TLS_CHACHA20_POLY1305_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
|
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
|
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
},
|
|
ALPNProtocols: []string{
|
|
"h2",
|
|
"http/1.1",
|
|
"acme-tls/1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Gateway tls.frontend Default and PerPort validation register TLS options",
|
|
paths: []string{"services.yml", "httproute/with_frontend_validation.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"websecure": {Address: ":443"},
|
|
"websecure2": {Address: ":8443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"listener-websecure2-https-dd662c6921e9998d0cca": {
|
|
EntryPoints: []string{"websecure2"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure2-https-dd662c6921e9998d0cca",
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure2-0-e22d24f42cd0b2e1fc86": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure2-0-e22d24f42cd0b2e1fc86-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure2-https-dd662c6921e9998d0cca"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-398c6f76284d21e6e3b3-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure2-0-e22d24f42cd0b2e1fc86-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure2-0-e22d24f42cd0b2e1fc86-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure2-0-e22d24f42cd0b2e1fc86-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": func() tls.Options {
|
|
opts := defaultListenerTLSOptions()
|
|
opts.ClientAuth = tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA1"},
|
|
ClientAuthType: tls.RequireAndVerifyClientCert,
|
|
}
|
|
return opts
|
|
}(),
|
|
"listener-websecure2-https-dd662c6921e9998d0cca": func() tls.Options {
|
|
opts := defaultListenerTLSOptions()
|
|
opts.ClientAuth = tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA1"},
|
|
ClientAuthType: tls.RequestClientCert,
|
|
}
|
|
return opts
|
|
}(),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Gateways sharing an entry point with the same frontend validation keep their listeners isolated",
|
|
paths: []string{"services.yml", "httproute/with_frontend_validation_listener_isolation.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"websecure": {Address: ":443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `(Host("*")) && !(Host("foo.com"))`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"listener-websecure-https-foo-com-c4461032f627a1b9033b": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("foo.com")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-foo-com-c4461032f627a1b9033b",
|
|
},
|
|
},
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-websecure-0-d0a1acd3dc8dc5905269": {
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529", "listener-websecure-https-foo-com-c4461032f627a1b9033b"},
|
|
Service: "httproute-default-http-app-catchall-gw-default-my-gateway-ep-websecure-0-d0a1acd3dc8dc5905269-wrr",
|
|
Rule: `Path("/catchall")`,
|
|
Priority: 100001,
|
|
RuleSyntax: "default",
|
|
},
|
|
"httproute-default-http-app-secure-gw-default-my-secure-gateway-ep-websecure-0-b7eaf4c1f751a09c9658": {
|
|
ParentRefs: []string{"listener-websecure-https-foo-com-c4461032f627a1b9033b"},
|
|
Service: "httproute-default-http-app-secure-gw-default-my-secure-gateway-ep-websecure-0-b7eaf4c1f751a09c9658-wrr",
|
|
Rule: `Host("foo.com") && Path("/secure")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-websecure-0-d0a1acd3dc8dc5905269-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-catchall-gw-default-my-gateway-ep-websecure-0-d0a1acd3dc8dc5905269-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-websecure-0-d0a1acd3dc8dc5905269-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-secure-gw-default-my-secure-gateway-ep-websecure-0-b7eaf4c1f751a09c9658-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-secure-gw-default-my-secure-gateway-ep-websecure-0-b7eaf4c1f751a09c9658-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-secure-gw-default-my-secure-gateway-ep-websecure-0-b7eaf4c1f751a09c9658-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": func() tls.Options {
|
|
opts := defaultListenerTLSOptions()
|
|
opts.ClientAuth = tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA1"},
|
|
ClientAuthType: tls.RequireAndVerifyClientCert,
|
|
}
|
|
return opts
|
|
}(),
|
|
"listener-websecure-https-foo-com-c4461032f627a1b9033b": func() tls.Options {
|
|
opts := defaultListenerTLSOptions()
|
|
opts.ClientAuth = tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA1"},
|
|
ClientAuthType: tls.RequireAndVerifyClientCert,
|
|
}
|
|
return opts
|
|
}(),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Catch-all listeners sharing an entry point with different frontend validations are conflicted, the oldest Gateway wins",
|
|
paths: []string{"services.yml", "httproute/with_frontend_validation_shared_entrypoint.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"websecure": {Address: ":443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-websecure-0-d0a1acd3dc8dc5905269": {
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
Service: "httproute-default-http-app-catchall-gw-default-my-gateway-ep-websecure-0-d0a1acd3dc8dc5905269-wrr",
|
|
Rule: `Path("/catchall")`,
|
|
Priority: 100001,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-websecure-0-d0a1acd3dc8dc5905269-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-catchall-gw-default-my-gateway-ep-websecure-0-d0a1acd3dc8dc5905269-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-catchall-gw-default-my-gateway-ep-websecure-0-d0a1acd3dc8dc5905269-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if test.expected == nil {
|
|
return
|
|
}
|
|
|
|
k8sObjects, gwObjects := readResources(t, test.paths)
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
NativeLBByDefault: test.nativeLB,
|
|
client: client,
|
|
}
|
|
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, test.expected, conf)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
paths []string
|
|
groupKindBackendFuncs map[string]map[string]BuildBackendFunc
|
|
expected *dynamic.Configuration
|
|
entryPoints map[string]Entrypoint
|
|
}{
|
|
{
|
|
desc: "Simple HTTPRoute with TraefikService",
|
|
paths: []string{"services.yml", "httproute/simple_with_TraefikService.yml"},
|
|
groupKindBackendFuncs: map[string]map[string]BuildBackendFunc{
|
|
traefikv1alpha1.GroupName: {"TraefikService": func(name, namespace string) (string, *dynamic.Service, error) {
|
|
return name, nil, nil
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "whoami",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute with TraefikService with service configuration",
|
|
paths: []string{"services.yml", "httproute/simple_with_TraefikService.yml"},
|
|
groupKindBackendFuncs: map[string]map[string]BuildBackendFunc{
|
|
traefikv1alpha1.GroupName: {"TraefikService": func(name, namespace string) (string, *dynamic.Service, error) {
|
|
return name, &dynamic.Service{LoadBalancer: &dynamic.ServersLoadBalancer{Strategy: dynamic.BalancerStrategyWRR, Servers: []dynamic.Server{{URL: "foobar"}}}}, nil
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "whoami",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"whoami": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "foobar"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute with invalid TraefikService kind",
|
|
paths: []string{"services.yml", "httproute/simple_with_TraefikService.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
Status: new(500),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute with backendFunc error",
|
|
paths: []string{"services.yml", "httproute/simple_with_TraefikService.yml"},
|
|
groupKindBackendFuncs: map[string]map[string]BuildBackendFunc{
|
|
traefikv1alpha1.GroupName: {"TraefikService": func(name, namespace string) (string, *dynamic.Service, error) {
|
|
return "", nil, errors.New("BOOM")
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
Status: new(500),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, with myservice@file service",
|
|
paths: []string{"services.yml", "httproute/simple_cross_provider.yml"},
|
|
groupKindBackendFuncs: map[string]map[string]BuildBackendFunc{
|
|
traefikv1alpha1.GroupName: {"TraefikService": func(name, namespace string) (string, *dynamic.Service, error) {
|
|
// func should never be executed in case of cross-provider reference.
|
|
return "", nil, errors.New("BOOM")
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "service@file",
|
|
Weight: new(1),
|
|
},
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-1",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-1": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple HTTPRoute, with appProtocol service",
|
|
paths: []string{"services.yml", "httproute/with_app_protocol_service.yml"},
|
|
groupKindBackendFuncs: map[string]map[string]BuildBackendFunc{
|
|
traefikv1alpha1.GroupName: {"TraefikService": func(name, namespace string) (string, *dynamic.Service, error) {
|
|
// func should never be executed in case of cross-provider reference.
|
|
return "", nil, errors.New("BOOM")
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd": {
|
|
Service: "httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-svc-default-whoami-h2c-0",
|
|
Weight: new(1),
|
|
},
|
|
{
|
|
Name: "httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-svc-default-whoami-ws-1",
|
|
Weight: new(1),
|
|
},
|
|
{
|
|
Name: "httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-svc-default-whoami-wss-2",
|
|
Weight: new(1),
|
|
},
|
|
{
|
|
Name: "httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-svc-default-whoami-HTTP-3",
|
|
Weight: new(1),
|
|
},
|
|
{
|
|
Name: "httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-svc-default-whoami-HTTPS-4",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-svc-default-whoami-h2c-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "h2c://10.10.0.13:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-svc-default-whoami-ws-1": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.14:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-svc-default-whoami-wss-2": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "https://10.10.0.15:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-svc-default-whoami-HTTPS-4": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "https://10.10.0.16:8443",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-bbdaa7d1e726d90930fd-svc-default-whoami-HTTP-3": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.17:8080",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if test.expected == nil {
|
|
return
|
|
}
|
|
|
|
k8sObjects, gwObjects := readResources(t, test.paths)
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
client: client,
|
|
}
|
|
|
|
for group, kindFuncs := range test.groupKindBackendFuncs {
|
|
for kind, backendFunc := range kindFuncs {
|
|
p.RegisterBackendFuncs(group, kind, backendFunc)
|
|
}
|
|
}
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, test.expected, conf)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
groupKindFilterFuncs map[string]map[string]BuildFilterFunc
|
|
expected *dynamic.Configuration
|
|
entryPoints map[string]Entrypoint
|
|
}{
|
|
{
|
|
desc: "ExtensionRef filter",
|
|
groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{
|
|
traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) {
|
|
return namespace + "-" + name, nil, nil
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Middlewares: []string{
|
|
"default-my-first-middleware",
|
|
"default-my-second-middleware",
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-bar-whoami-bar-1",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
// Cross-namespace backendRef: its ExtensionRef filter must resolve to the route's own namespace,
|
|
// not the backendRef's namespace.
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-bar-whoami-bar-1": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.11:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.12:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
Middlewares: []string{"default-my-backend-middleware"},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "ExtensionRef filter with middleware creation",
|
|
groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{
|
|
traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) {
|
|
return namespace + "-" + name, &dynamic.Middleware{Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, nil
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Middlewares: []string{
|
|
"default-my-first-middleware",
|
|
"default-my-second-middleware",
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{
|
|
"default-my-first-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}},
|
|
"default-my-second-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}},
|
|
"default-my-backend-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-bar-whoami-bar-1",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
// Cross-namespace backendRef: its ExtensionRef filter must resolve to the route's own namespace,
|
|
// not the backendRef's namespace.
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-svc-bar-whoami-bar-1": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.11:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.12:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
Middlewares: []string{"default-my-backend-middleware"},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Unknown ExtensionRef filter",
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-err-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-err-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "invalid-httproute-filter",
|
|
Weight: new(1),
|
|
Status: new(500),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "ExtensionRef filter with filterFunc error",
|
|
groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{
|
|
traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) {
|
|
return "", nil, errors.New("BOOM")
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-err-wrr",
|
|
Rule: `Host("foo.com") && Path("/bar")`,
|
|
Priority: 100008,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93-err-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "invalid-httproute-filter",
|
|
Weight: new(1),
|
|
Status: new(500),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if test.expected == nil {
|
|
return
|
|
}
|
|
|
|
k8sObjects, gwObjects := readResources(t, []string{"services.yml", "httproute/filter_extension_ref.yml"})
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
client: client,
|
|
}
|
|
|
|
for group, kindFuncs := range test.groupKindFilterFuncs {
|
|
for kind, filterFunc := range kindFuncs {
|
|
p.RegisterFilterFuncs(group, kind, filterFunc)
|
|
}
|
|
}
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, test.expected, conf)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadGRPCRoutes(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
paths []string
|
|
expected *dynamic.Configuration
|
|
entryPoints map[string]Entrypoint
|
|
}{
|
|
{
|
|
desc: "Simple GRPCRoute and BackendTLSPolicy with CA certificate",
|
|
paths: []string{"services.yml", "grpcroute/with_backend_tls_policy.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "https://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "https://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
ServersTransport: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0",
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0": {
|
|
ServerName: "whoami",
|
|
RootCAs: []types.FileOrContent{
|
|
"CA1",
|
|
"CA2",
|
|
"CA1-secret",
|
|
"CA2-secret",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple GRPCRoute and BackendTLSPolicy with subjectAltNames",
|
|
paths: []string{"services.yml", "grpcroute/with_backend_tls_policy_san.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "https://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "https://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
ServersTransport: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0",
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0": {
|
|
ServerName: "whoami",
|
|
InsecureSkipVerify: true,
|
|
PeerCertSANs: []tls.SAN{
|
|
{Type: tls.SANDNSNameType, Value: "whoami.default.svc.cluster.local"},
|
|
{Type: tls.SANURIType, Value: "spiffe://cluster.local/ns/default/sa/whoami"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple GRPCRoute and BackendTLSPolicy with System CA",
|
|
paths: []string{"services.yml", "grpcroute/with_backend_tls_policy_system.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "https://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "https://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
ServersTransport: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0",
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0": {
|
|
ServerName: "whoami",
|
|
},
|
|
},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "GRPCRoute Gateway tls.frontend Default and PerPort validation register TLS options",
|
|
paths: []string{"services.yml", "grpcroute/with_frontend_validation.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"websecure": {Address: ":443"},
|
|
"websecure2": {Address: ":8443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"listener-websecure2-https-dd662c6921e9998d0cca": {
|
|
EntryPoints: []string{"websecure2"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure2-https-dd662c6921e9998d0cca",
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-websecure-0-5015e40a36a5159a5ca2": {
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-websecure-0-5015e40a36a5159a5ca2-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-websecure2-0-c1153de85fa10a42dc33": {
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-websecure2-0-c1153de85fa10a42dc33-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure2-https-dd662c6921e9998d0cca"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-websecure-0-5015e40a36a5159a5ca2-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-websecure-0-5015e40a36a5159a5ca2-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-websecure-0-5015e40a36a5159a5ca2-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "h2c://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "h2c://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-websecure2-0-c1153de85fa10a42dc33-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-websecure2-0-c1153de85fa10a42dc33-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-websecure2-0-c1153de85fa10a42dc33-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "h2c://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "h2c://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": func() tls.Options {
|
|
opts := defaultListenerTLSOptions()
|
|
opts.ClientAuth = tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA1"},
|
|
ClientAuthType: tls.RequireAndVerifyClientCert,
|
|
}
|
|
return opts
|
|
}(),
|
|
"listener-websecure2-https-dd662c6921e9998d0cca": func() tls.Options {
|
|
opts := defaultListenerTLSOptions()
|
|
opts.ClientAuth = tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA1"},
|
|
ClientAuthType: tls.RequestClientCert,
|
|
}
|
|
return opts
|
|
}(),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "GRPCRoute Gateways sharing an entry point with the same frontend validation keep their listeners isolated",
|
|
paths: []string{"services.yml", "grpcroute/with_frontend_validation_listener_isolation.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"websecure": {Address: ":443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `(Host("*")) && !(Host("foo.com"))`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"listener-websecure-https-foo-com-c4461032f627a1b9033b": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("foo.com")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-foo-com-c4461032f627a1b9033b",
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-catchall-gw-default-my-gateway-ep-websecure-0-4b61347f65fc7f1a8a57": {
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529", "listener-websecure-https-foo-com-c4461032f627a1b9033b"},
|
|
Service: "grpcroute-default-grpc-app-catchall-gw-default-my-gateway-ep-websecure-0-4b61347f65fc7f1a8a57-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 15,
|
|
RuleSyntax: "default",
|
|
},
|
|
"grpcroute-default-grpc-app-secure-gw-default-my-secure-gateway-ep-websecure-0-3aae484bce849b96c90c": {
|
|
ParentRefs: []string{"listener-websecure-https-foo-com-c4461032f627a1b9033b"},
|
|
Service: "grpcroute-default-grpc-app-secure-gw-default-my-secure-gateway-ep-websecure-0-3aae484bce849b96c90c-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-catchall-gw-default-my-gateway-ep-websecure-0-4b61347f65fc7f1a8a57-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-catchall-gw-default-my-gateway-ep-websecure-0-4b61347f65fc7f1a8a57-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-catchall-gw-default-my-gateway-ep-websecure-0-4b61347f65fc7f1a8a57-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "h2c://10.10.0.1:80"},
|
|
{URL: "h2c://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-secure-gw-default-my-secure-gateway-ep-websecure-0-3aae484bce849b96c90c-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-secure-gw-default-my-secure-gateway-ep-websecure-0-3aae484bce849b96c90c-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-secure-gw-default-my-secure-gateway-ep-websecure-0-3aae484bce849b96c90c-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "h2c://10.10.0.1:80"},
|
|
{URL: "h2c://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": func() tls.Options {
|
|
opts := defaultListenerTLSOptions()
|
|
opts.ClientAuth = tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA1"},
|
|
ClientAuthType: tls.RequireAndVerifyClientCert,
|
|
}
|
|
return opts
|
|
}(),
|
|
"listener-websecure-https-foo-com-c4461032f627a1b9033b": func() tls.Options {
|
|
opts := defaultListenerTLSOptions()
|
|
opts.ClientAuth = tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA1"},
|
|
ClientAuthType: tls.RequireAndVerifyClientCert,
|
|
}
|
|
return opts
|
|
}(),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "GRPCRoute catch-all listeners sharing an entry point with different frontend validations are conflicted, the oldest Gateway wins",
|
|
paths: []string{"services.yml", "grpcroute/with_frontend_validation_shared_entrypoint.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"websecure": {Address: ":443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-catchall-gw-default-my-gateway-ep-websecure-0-4b61347f65fc7f1a8a57": {
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
Service: "grpcroute-default-grpc-app-catchall-gw-default-my-gateway-ep-websecure-0-4b61347f65fc7f1a8a57-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 15,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-catchall-gw-default-my-gateway-ep-websecure-0-4b61347f65fc7f1a8a57-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-catchall-gw-default-my-gateway-ep-websecure-0-4b61347f65fc7f1a8a57-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-catchall-gw-default-my-gateway-ep-websecure-0-4b61347f65fc7f1a8a57-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "h2c://10.10.0.1:80"},
|
|
{URL: "h2c://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "GRPCRoute with nil endpointslice port name",
|
|
paths: []string{"services.yml", "grpcroute/with_nil_endpointslice_port_name.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-nil-port-name-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-nil-port-name-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "GRPCRoute with nil endpointslice port value",
|
|
paths: []string{"services.yml", "grpcroute/with_nil_endpointslice_port_value.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-nil-port-value-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-nil-port-value-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "GRPCRoutes with identical rules",
|
|
paths: []string{"services.yml", "grpcroute/with_identical_rules.yml"},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-foo-com-5f20d578e2e3eccac466": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("foo.com")`,
|
|
},
|
|
"grpcroute-default-grpc-app-catch-all-gw-default-my-gateway-ep-web-0-24ad420c9f1560b62d23": {
|
|
Service: "grpcroute-default-grpc-app-catch-all-gw-default-my-gateway-ep-web-0-24ad420c9f1560b62d23-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-foo-com-5f20d578e2e3eccac466"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-catch-all-gw-default-my-gateway-ep-web-0-24ad420c9f1560b62d23-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-catch-all-gw-default-my-gateway-ep-web-0-24ad420c9f1560b62d23-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-catch-all-gw-default-my-gateway-ep-web-0-24ad420c9f1560b62d23-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "h2c://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "h2c://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if test.expected == nil {
|
|
return
|
|
}
|
|
|
|
k8sObjects, gwObjects := readResources(t, test.paths)
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
client: client,
|
|
}
|
|
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, test.expected, conf)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
groupKindFilterFuncs map[string]map[string]BuildFilterFunc
|
|
expected *dynamic.Configuration
|
|
entryPoints map[string]Entrypoint
|
|
}{
|
|
{
|
|
desc: "ExtensionRef filter",
|
|
groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{
|
|
traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) {
|
|
return namespace + "-" + name, nil, nil
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296": {
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Middlewares: []string{
|
|
"default-my-first-middleware",
|
|
"default-my-second-middleware",
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "h2c://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "h2c://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "ExtensionRef filter with middleware creation",
|
|
groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{
|
|
traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) {
|
|
return namespace + "-" + name, &dynamic.Middleware{Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, nil
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296": {
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Middlewares: []string{
|
|
"default-my-first-middleware",
|
|
"default-my-second-middleware",
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{
|
|
"default-my-first-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}},
|
|
"default-my-second-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "h2c://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "h2c://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Unknown ExtensionRef filter",
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296": {
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-err-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-err-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "invalid-grpcroute-filter",
|
|
Weight: new(1),
|
|
GRPCStatus: &dynamic.GRPCStatus{
|
|
Code: codes.Unavailable,
|
|
Msg: "Service Unavailable",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "ExtensionRef filter with filterFunc error",
|
|
groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{
|
|
traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) {
|
|
return "", nil, errors.New("BOOM")
|
|
}},
|
|
},
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":80",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296": {
|
|
Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-err-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-0abda411573f19f36296-err-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "invalid-grpcroute-filter",
|
|
Weight: new(1),
|
|
GRPCStatus: &dynamic.GRPCStatus{
|
|
Code: codes.Unavailable,
|
|
Msg: "Service Unavailable",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if test.expected == nil {
|
|
return
|
|
}
|
|
|
|
k8sObjects, gwObjects := readResources(t, []string{"services.yml", "grpcroute/filter_extension_ref.yml"})
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
client: client,
|
|
}
|
|
|
|
for group, kindFuncs := range test.groupKindFilterFuncs {
|
|
for kind, filterFunc := range kindFuncs {
|
|
p.RegisterFilterFuncs(group, kind, filterFunc)
|
|
}
|
|
}
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, test.expected, conf)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadTCPRoutes(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
ingressClass string
|
|
paths []string
|
|
expected *dynamic.Configuration
|
|
entryPoints map[string]Entrypoint
|
|
nativeLB bool
|
|
}{
|
|
{
|
|
desc: "Empty",
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because missing entry point",
|
|
paths: []string{"services.yml", "tcproute/simple.yml"},
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8000",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because no tcp route defined",
|
|
paths: []string{"services.yml", "tcproute/without_tcproute.yml"},
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8080",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by missing GatewayClass",
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8080",
|
|
}},
|
|
paths: []string{"services.yml", "tcproute/without_gatewayclass.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by unknown GatewayClass controller desc",
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8080",
|
|
}},
|
|
paths: []string{"services.yml", "tcproute/gatewayclass_with_unknown_controller.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by HTTPRoute with TLS configuration",
|
|
entryPoints: map[string]Entrypoint{"web": {
|
|
Address: ":8080",
|
|
}},
|
|
paths: []string{"services.yml", "tcproute/with_tls_configuration.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Router with service in error caused by wrong TargetPort",
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8080",
|
|
}},
|
|
paths: []string{"services.yml", "tcproute/with_wrong_service_port.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-TCP-app-1-gw-default-my-gateway-ep-TCP-0-b06faef5537f5b1e4c70": {
|
|
EntryPoints: []string{"TCP"},
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
Service: "tcproute-default-TCP-app-1-gw-default-my-gateway-ep-TCP-0-b06faef5537f5b1e4c70-wrr",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-TCP-app-1-gw-default-my-gateway-ep-TCP-0-b06faef5537f5b1e4c70-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{{
|
|
Name: "tcproute-default-TCP-app-1-gw-default-my-gateway-ep-TCP-0-b06faef5537f5b1e4c70-err-lb",
|
|
Weight: new(1),
|
|
}},
|
|
},
|
|
},
|
|
"tcproute-default-TCP-app-1-gw-default-my-gateway-ep-TCP-0-b06faef5537f5b1e4c70-err-lb": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TCPRoute",
|
|
paths: []string{"services.yml", "tcproute/simple.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Multiple TCPRoute",
|
|
paths: []string{"services.yml", "tcproute/with_multiple_routes.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp-1": {Address: ":9000"},
|
|
"tcp-2": {Address: ":10000"},
|
|
"not-tcp": {Address: ":11000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-1-0-538fb5c01603fd936dbf": {
|
|
EntryPoints: []string{"tcp-1"},
|
|
Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-1-0-538fb5c01603fd936dbf-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
"tcproute-default-tcp-app-2-gw-default-my-tcp-gateway-ep-tcp-2-0-8eec98026c1dabcb62e0": {
|
|
EntryPoints: []string{"tcp-2"},
|
|
Service: "tcproute-default-tcp-app-2-gw-default-my-tcp-gateway-ep-tcp-2-0-8eec98026c1dabcb62e0-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-1-0-538fb5c01603fd936dbf-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-1-0-538fb5c01603fd936dbf-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-2-gw-default-my-tcp-gateway-ep-tcp-2-0-8eec98026c1dabcb62e0-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-2-gw-default-my-tcp-gateway-ep-tcp-2-0-8eec98026c1dabcb62e0-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-1-0-538fb5c01603fd936dbf-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-2-gw-default-my-tcp-gateway-ep-tcp-2-0-8eec98026c1dabcb62e0-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:10000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:10000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TCPRoute with multiple rules",
|
|
paths: []string{"services.yml", "tcproute/with_multiple_rules.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp-1": {Address: ":9000"},
|
|
"tcp-2": {Address: ":10000"},
|
|
"not-tcp": {Address: ":11000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-0-1767e543195002a45b0b": {
|
|
EntryPoints: []string{"tcp-1"},
|
|
Service: "tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-0-1767e543195002a45b0b-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-0-1767e543195002a45b0b-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-0-1767e543195002a45b0b-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-0-1767e543195002a45b0b-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TCPRoute, with backendRef",
|
|
paths: []string{"services.yml", "tcproute/simple_cross_provider.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "service@file",
|
|
Weight: new(1),
|
|
},
|
|
{
|
|
Name: "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da-svc-default-whoamitcp-1",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da-svc-default-whoamitcp-1": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by TCPRoute attached to a TLS listener",
|
|
paths: []string{"services.yml", "tcproute/with_protocol_tls.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Conflicting TCPRoutes on the same listener, only the oldest is bound",
|
|
paths: []string{"services.yml", "tcproute/with_conflicting_routes.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-older-gw-default-my-tcp-gateway-ep-tcp-0-6aa3057a8ee9e5d61398": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-older-gw-default-my-tcp-gateway-ep-tcp-0-6aa3057a8ee9e5d61398-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-older-gw-default-my-tcp-gateway-ep-tcp-0-6aa3057a8ee9e5d61398-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-older-gw-default-my-tcp-gateway-ep-tcp-0-6aa3057a8ee9e5d61398-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-older-gw-default-my-tcp-gateway-ep-tcp-0-6aa3057a8ee9e5d61398-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TCPRoute with Same namespace selector",
|
|
paths: []string{"services.yml", "tcproute/with_namespace_same.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-9c02509721599badb6c4": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-9c02509721599badb6c4-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-9c02509721599badb6c4-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-9c02509721599badb6c4-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-9c02509721599badb6c4-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TCPRoute with All namespace selector",
|
|
paths: []string{"services.yml", "tcproute/with_namespace_all.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-18313c5ba079a1d9e171": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-18313c5ba079a1d9e171-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-18313c5ba079a1d9e171-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-18313c5ba079a1d9e171-svc-bar-whoamitcp-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-18313c5ba079a1d9e171-svc-bar-whoamitcp-bar-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.13:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.14:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TCPRoute with namespace selector",
|
|
paths: []string{"services.yml", "tcproute/with_namespace_selector.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-18313c5ba079a1d9e171": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-18313c5ba079a1d9e171-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-18313c5ba079a1d9e171-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-18313c5ba079a1d9e171-svc-bar-whoamitcp-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-18313c5ba079a1d9e171-svc-bar-whoamitcp-bar-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.13:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.14:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TCPRoute with NativeLBByDefault",
|
|
paths: []string{"services.yml", "tcproute/simple.yml"},
|
|
nativeLB: true,
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.10.1:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TCPRoute with NativeLB annotation",
|
|
paths: []string{"services.yml", "tcproute/simple_nativelb.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-native-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-native-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.10.1:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TCPRoute with NativeLBByDefault enabled but service has disabled nativelb",
|
|
paths: []string{"services.yml", "tcproute/simple_nativelb_disabled.yml"},
|
|
nativeLB: true,
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-native-disabled-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-native-disabled-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.30:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.31:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TCPRoute with nil endpointslice port name",
|
|
paths: []string{"services.yml", "tcproute/with_nil_endpointslice_port_name.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-nil-port-name-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-nil-port-name-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TCPRoute with nil endpointslice port value",
|
|
paths: []string{"services.yml", "tcproute/with_nil_endpointslice_port_value.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-nil-port-value-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-nil-port-value-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TCPRoutes with identical rules",
|
|
paths: []string{"services.yml", "tcproute/with_identical_rules.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-first-gw-default-my-tcp-gateway-ep-tcp-0-79a3b41b9e16bdaa2841": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-first-gw-default-my-tcp-gateway-ep-tcp-0-79a3b41b9e16bdaa2841-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-first-gw-default-my-tcp-gateway-ep-tcp-0-79a3b41b9e16bdaa2841-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-first-gw-default-my-tcp-gateway-ep-tcp-0-79a3b41b9e16bdaa2841-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-first-gw-default-my-tcp-gateway-ep-tcp-0-79a3b41b9e16bdaa2841-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TCPRoute attached to a ListenerSet listener",
|
|
paths: []string{"services.yml", "tcproute/with_listenerset.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Services: map[string]*dynamic.Service{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf": {
|
|
EntryPoints: []string{
|
|
"tcp",
|
|
},
|
|
Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-b0953a7f472d14e31cbf-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if test.expected == nil {
|
|
return
|
|
}
|
|
|
|
k8sObjects, gwObjects := readResources(t, test.paths)
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
NativeLBByDefault: test.nativeLB,
|
|
client: client,
|
|
}
|
|
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, test.expected, conf)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadTLSRoutes(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
ingressClass string
|
|
paths []string
|
|
entryPoints map[string]Entrypoint
|
|
nativeLB bool
|
|
expected *dynamic.Configuration
|
|
}{
|
|
{
|
|
desc: "Empty",
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because no matching entry point",
|
|
paths: []string{"services.yml", "tlsroute/simple_TLS_to_TCPRoute.yml"},
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8000",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because no tls route defined",
|
|
paths: []string{"services.yml", "tlsroute/without_tlsroute.yml"},
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8080",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by missing GatewayClass",
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8080",
|
|
}},
|
|
paths: []string{"services.yml", "tlsroute/without_gatewayclass.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by unknown GatewayClass controller desc",
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8080",
|
|
}},
|
|
paths: []string{"services.yml", "tlsroute/gatewayclass_with_unknown_controller.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Router with service in error caused by wrong TargetPort",
|
|
entryPoints: map[string]Entrypoint{"TCP": {
|
|
Address: ":8080",
|
|
}},
|
|
paths: []string{"services.yml", "tlsroute/with_wrong_service_port.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-TCP-0-45c28fdcc89d443a020b": {
|
|
EntryPoints: []string{"TCP"},
|
|
Priority: 0,
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-TCP-0-45c28fdcc89d443a020b-wrr",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-TCP-0-45c28fdcc89d443a020b-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-TCP-0-45c28fdcc89d443a020b-err-lb",
|
|
Weight: new(1),
|
|
}},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-TCP-0-45c28fdcc89d443a020b-err-lb": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by mixed routes with wrong parent ref",
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {
|
|
Address: ":9000",
|
|
},
|
|
"tcp-tls": {
|
|
Address: ":9443",
|
|
},
|
|
"http": {
|
|
Address: ":80",
|
|
},
|
|
},
|
|
paths: []string{"services.yml", "mixed/with_wrong_routes_selector.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by TCPRoute attached to a TLS listener in Terminate mode",
|
|
paths: []string{"services.yml", "tlsroute/simple_TLS_to_TCPRoute.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by TCPRoute attached to a TLS listener in Passthrough mode",
|
|
paths: []string{"services.yml", "tlsroute/simple_TLS_to_TCPRoute_passthrough.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLS listener to TLSRoute",
|
|
paths: []string{"services.yml", "tlsroute/simple_TLS_to_TLSRoute.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Multiple TLSRoute",
|
|
paths: []string{"services.yml", "tlsroute/with_multiple_routes_kind.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9000"},
|
|
"tcp": {Address: ":10000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-24d35d31a7578c5062a7": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-24d35d31a7578c5062a7-wrr",
|
|
Priority: 0,
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-24d35d31a7578c5062a7-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-24d35d31a7578c5062a7-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-24d35d31a7578c5062a7-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:10000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:10000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLSRoute, with backendRef",
|
|
paths: []string{"services.yml", "tlsroute/simple_cross_provider.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-efc0f8d903baa9fb6592": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-efc0f8d903baa9fb6592-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-efc0f8d903baa9fb6592-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "service@file",
|
|
Weight: new(1),
|
|
},
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-efc0f8d903baa9fb6592-svc-default-whoamitcp-1",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-efc0f8d903baa9fb6592-svc-default-whoamitcp-1": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLSRoute, with Passthrough and TLS configuration should raise a warn",
|
|
paths: []string{"services.yml", "tlsroute/with_passthrough_tls.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9001"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLSRoute, with Passthrough",
|
|
paths: []string{"services.yml", "tlsroute/with_passthrough.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9001"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLSRoute, with single SNI matching",
|
|
paths: []string{"services.yml", "tlsroute/with_SNI_matching.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9001"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoute attached to TLS listeners with different hostnames on the same entry point",
|
|
paths: []string{"services.yml", "tlsroute/with_multiple_listeners_same_port.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9001"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-276f6c243a7761966c5b": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-276f6c243a7761966c5b-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("bar.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-276f6c243a7761966c5b-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-276f6c243a7761966c5b-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-276f6c243a7761966c5b-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLSRoute, with multiple SNI matching",
|
|
paths: []string{"services.yml", "tlsroute/with_multiple_SNI_matching.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9001"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-035a9ab93ab8d0d12874": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-035a9ab93ab8d0d12874-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("bar.example.com") || HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-035a9ab93ab8d0d12874-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-035a9ab93ab8d0d12874-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-035a9ab93ab8d0d12874-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoute with Same namespace selector",
|
|
paths: []string{"services.yml", "tlsroute/with_namespace_same.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9001"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-76eff62990bc46a9697d": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-76eff62990bc46a9697d-wrr",
|
|
Priority: 11,
|
|
Rule: `HostSNI("foo.default")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-76eff62990bc46a9697d-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-76eff62990bc46a9697d-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-76eff62990bc46a9697d-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoute with All namespace selector",
|
|
paths: []string{"services.yml", "tlsroute/with_namespace_all.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9001"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-76eff62990bc46a9697d": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-76eff62990bc46a9697d-wrr",
|
|
Priority: 11,
|
|
Rule: `HostSNI("foo.default")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
"tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-58a6fd0c8bc014d99d8b": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-58a6fd0c8bc014d99d8b-wrr",
|
|
Priority: 7,
|
|
Rule: `HostSNI("foo.bar")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-76eff62990bc46a9697d-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-76eff62990bc46a9697d-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-58a6fd0c8bc014d99d8b-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-58a6fd0c8bc014d99d8b-svc-bar-whoamitcp-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-76eff62990bc46a9697d-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-58a6fd0c8bc014d99d8b-svc-bar-whoamitcp-bar-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.13:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.14:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoute with namespace selector",
|
|
paths: []string{"services.yml", "tlsroute/with_namespace_selector.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9001"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-58a6fd0c8bc014d99d8b": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-58a6fd0c8bc014d99d8b-wrr",
|
|
Priority: 7,
|
|
Rule: `HostSNI("foo.bar")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-58a6fd0c8bc014d99d8b-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-58a6fd0c8bc014d99d8b-svc-bar-whoamitcp-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-58a6fd0c8bc014d99d8b-svc-bar-whoamitcp-bar-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.13:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.14:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoute with multiple rules",
|
|
paths: []string{"services.yml", "tlsroute/with_multiple_rules.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp-1": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-0-2e99b4a7e81cc622b335": {
|
|
EntryPoints: []string{"tcp-1"},
|
|
Service: "tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-0-2e99b4a7e81cc622b335-wrr",
|
|
Priority: 0,
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-0-2e99b4a7e81cc622b335-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-0-2e99b4a7e81cc622b335-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-0-2e99b4a7e81cc622b335-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLSRoute with NativeLBByDefault",
|
|
paths: []string{"services.yml", "tlsroute/simple_TLS_to_TLSRoute.yml"},
|
|
nativeLB: true,
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.10.1:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLSRoute with NativeLB annotation",
|
|
paths: []string{"services.yml", "tlsroute/simple_nativelb.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-svc-default-whoamitcp-native-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-svc-default-whoamitcp-native-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.10.1:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLSRoute and BackendTLSPolicy with CA certificate",
|
|
paths: []string{"services.yml", "tlsroute/with_backend_tls_policy.yml"},
|
|
entryPoints: map[string]Entrypoint{"tls": {
|
|
Address: ":9001",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-wrr",
|
|
Rule: `HostSNI("foo.com")`,
|
|
Priority: 7,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.1:80",
|
|
TLS: true,
|
|
},
|
|
{
|
|
Address: "10.10.0.2:80",
|
|
TLS: true,
|
|
},
|
|
},
|
|
ServersTransport: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0",
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0": {
|
|
TLS: &dynamic.TLSClientConfig{
|
|
ServerName: "whoami",
|
|
RootCAs: []types.FileOrContent{
|
|
"CA1",
|
|
"CA2",
|
|
"CA1-secret",
|
|
"CA2-secret",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLSRoute and BackendTLSPolicy with subjectAltNames",
|
|
paths: []string{"services.yml", "tlsroute/with_backend_tls_policy_san.yml"},
|
|
entryPoints: map[string]Entrypoint{"tls": {
|
|
Address: ":9001",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-wrr",
|
|
Rule: `HostSNI("foo.com")`,
|
|
Priority: 7,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.1:80",
|
|
TLS: true,
|
|
},
|
|
{
|
|
Address: "10.10.0.2:80",
|
|
TLS: true,
|
|
},
|
|
},
|
|
ServersTransport: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0",
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0": {
|
|
TLS: &dynamic.TLSClientConfig{
|
|
ServerName: "whoami",
|
|
InsecureSkipVerify: true,
|
|
PeerCertSANs: []tls.SAN{
|
|
{Type: tls.SANDNSNameType, Value: "whoami.default.svc.cluster.local"},
|
|
{Type: tls.SANURIType, Value: "spiffe://cluster.local/ns/default/sa/whoami"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Simple TLSRoute and BackendTLSPolicy with System CA",
|
|
paths: []string{"services.yml", "tlsroute/with_backend_tls_policy_system.yml"},
|
|
entryPoints: map[string]Entrypoint{"tls": {
|
|
Address: ":9001",
|
|
}},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-wrr",
|
|
Rule: `HostSNI("foo.com")`,
|
|
Priority: 7,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.1:80",
|
|
TLS: true,
|
|
},
|
|
{
|
|
Address: "10.10.0.2:80",
|
|
TLS: true,
|
|
},
|
|
},
|
|
ServersTransport: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0",
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-5c999a999d12ac0531c5-svc-default-whoami-0": {
|
|
TLS: &dynamic.TLSClientConfig{
|
|
ServerName: "whoami",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoute with nil endpointslice port name",
|
|
paths: []string{"services.yml", "tlsroute/with_nil_endpointslice_port_name.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-svc-default-whoamitcp-nil-port-name-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-svc-default-whoamitcp-nil-port-name-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoute with nil endpointslice port value",
|
|
paths: []string{"services.yml", "tlsroute/with_nil_endpointslice_port_value.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-wrr",
|
|
Priority: 15,
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-svc-default-whoamitcp-nil-port-value-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-d01849ae1c96d9ffe0ef-svc-default-whoamitcp-nil-port-value-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoutes with identical rules",
|
|
paths: []string{"services.yml", "tlsroute/with_identical_rules.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tlsroute-default-tls-app-catch-all-gw-default-my-tls-gateway-ep-tcp-0-60f8cf9276253172d000": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tlsroute-default-tls-app-catch-all-gw-default-my-tls-gateway-ep-tcp-0-60f8cf9276253172d000-wrr",
|
|
Rule: `HostSNI("foo.com")`,
|
|
Priority: 7,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tlsroute-default-tls-app-catch-all-gw-default-my-tls-gateway-ep-tcp-0-60f8cf9276253172d000-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-catch-all-gw-default-my-tls-gateway-ep-tcp-0-60f8cf9276253172d000-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-catch-all-gw-default-my-tls-gateway-ep-tcp-0-60f8cf9276253172d000-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoute attached to a ListenerSet Passthrough listener",
|
|
paths: []string{"services.yml", "tlsroute/with_listenerset.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
"tls": {Address: ":9001"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Services: map[string]*dynamic.Service{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Service: "deny-unknown-host",
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174": {
|
|
EntryPoints: []string{
|
|
"tls",
|
|
},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr",
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
Priority: 15,
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if test.expected == nil {
|
|
return
|
|
}
|
|
|
|
k8sObjects, gwObjects := readResources(t, test.paths)
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
NativeLBByDefault: test.nativeLB,
|
|
client: client,
|
|
}
|
|
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, test.expected, conf)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadMixedRoutes(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
ingressClass string
|
|
paths []string
|
|
expected *dynamic.Configuration
|
|
entryPoints map[string]Entrypoint
|
|
}{
|
|
{
|
|
desc: "Empty",
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by unsupported listener.Protocol",
|
|
paths: []string{"services.yml", "mixed/with_bad_listener_protocol.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by unsupported listener.Route.Kind",
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
},
|
|
paths: []string{"services.yml", "mixed/with_bad_listener_route_kind.yml"},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by listener.Protocol does not support listener.Route.Kind",
|
|
paths: []string{"services.yml", "mixed/with_incompatible_protocol_and_route_kind.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Mixed routes",
|
|
paths: []string{"services.yml", "mixed/simple.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
"websecure": {Address: ":9443"},
|
|
"tcp": {Address: ":9000"},
|
|
"tls-1": {Address: ":10000"},
|
|
"tls-2": {Address: ":11000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-2-0-34e311881843bc2963c9": {
|
|
EntryPoints: []string{"tls-2"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-2-0-34e311881843bc2963c9-wrr",
|
|
Priority: 24,
|
|
Rule: `HostSNI("pass.tls.foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-2-0-34e311881843bc2963c9-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-2-0-34e311881843bc2963c9-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-2-0-34e311881843bc2963c9-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-f20abd7604e9c4caa5f3": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-f20abd7604e9c4caa5f3-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 2,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-c319354d6e97e7ccf839": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-c319354d6e97e7ccf839-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 2,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-f20abd7604e9c4caa5f3-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-f20abd7604e9c4caa5f3-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-c319354d6e97e7ccf839-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-c319354d6e97e7ccf839-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-f20abd7604e9c4caa5f3-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-c319354d6e97e7ccf839-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty caused by mixed routes with multiple listeners using same hostname, port and protocol",
|
|
paths: []string{"services.yml", "mixed/with_multiple_listeners_using_same_hostname_port_protocol.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
"tcp": {Address: ":9000"},
|
|
"tls": {Address: ":9001"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Mixed routes with Same namespace selector",
|
|
paths: []string{"services.yml", "mixed/with_namespace_same.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
"websecure": {Address: ":9443"},
|
|
"tcp": {Address: ":9000"},
|
|
"tls-1": {Address: ":10000"},
|
|
"tls-2": {Address: ":11000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-df24b7f0f1d9b443e55b": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-df24b7f0f1d9b443e55b-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-30cc8c9fb5be933316f8": {
|
|
EntryPoints: []string{"tls-2"},
|
|
Service: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-30cc8c9fb5be933316f8-wrr",
|
|
Priority: 24,
|
|
Rule: `HostSNI("pass.tls.foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-df24b7f0f1d9b443e55b-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-df24b7f0f1d9b443e55b-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-30cc8c9fb5be933316f8-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-30cc8c9fb5be933316f8-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-df24b7f0f1d9b443e55b-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-30cc8c9fb5be933316f8-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-3b55179f1d48675f1432": {
|
|
Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-3b55179f1d48675f1432-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 2,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-4a26538fbaaf60dc52c9": {
|
|
Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-4a26538fbaaf60dc52c9-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 2,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-3b55179f1d48675f1432-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-3b55179f1d48675f1432-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-4a26538fbaaf60dc52c9-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-4a26538fbaaf60dc52c9-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-3b55179f1d48675f1432-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-4a26538fbaaf60dc52c9-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Mixed routes with All namespace selector",
|
|
paths: []string{"services.yml", "mixed/with_namespace_all.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
"websecure": {Address: ":9443"},
|
|
"tcp": {Address: ":9000"},
|
|
"tls-1": {Address: ":10000"},
|
|
"tls-2": {Address: ":11000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-30cc8c9fb5be933316f8": {
|
|
EntryPoints: []string{"tls-2"},
|
|
Service: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-30cc8c9fb5be933316f8-wrr",
|
|
Priority: 24,
|
|
Rule: `HostSNI("pass.tls.foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-c5d9e24bf010118167e7": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-c5d9e24bf010118167e7-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-30cc8c9fb5be933316f8-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-30cc8c9fb5be933316f8-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-30cc8c9fb5be933316f8-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-c5d9e24bf010118167e7-svc-bar-whoamitcp-bar-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.13:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.14:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-c5d9e24bf010118167e7-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-c5d9e24bf010118167e7-svc-bar-whoamitcp-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-cf99cd1374e6056a6755": {
|
|
Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-cf99cd1374e6056a6755-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 2,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-135c6826c1baedf74c13": {
|
|
Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-135c6826c1baedf74c13-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 2,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-cf99cd1374e6056a6755-svc-bar-whoami-bar-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.11:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.12:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-135c6826c1baedf74c13-svc-bar-whoami-bar-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.11:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.12:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-cf99cd1374e6056a6755-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-cf99cd1374e6056a6755-svc-bar-whoami-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-135c6826c1baedf74c13-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-135c6826c1baedf74c13-svc-bar-whoami-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Mixed routes with Selector Route Binding",
|
|
paths: []string{"services.yml", "mixed/with_namespace_selector.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
"websecure": {Address: ":9443"},
|
|
"tcp": {Address: ":9000"},
|
|
"tls-1": {Address: ":10000"},
|
|
"tls-2": {Address: ":11000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-c5d9e24bf010118167e7": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-c5d9e24bf010118167e7-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
"tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-2-0-2a95ae92bba77504addc": {
|
|
EntryPoints: []string{"tls-2"},
|
|
Service: "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-2-0-2a95ae92bba77504addc-wrr",
|
|
Priority: 24,
|
|
Rule: `HostSNI("pass.tls.foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-c5d9e24bf010118167e7-svc-bar-whoamitcp-bar-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.13:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.14:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-2-0-2a95ae92bba77504addc-svc-bar-whoamitcp-bar-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.13:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.14:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-c5d9e24bf010118167e7-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-c5d9e24bf010118167e7-svc-bar-whoamitcp-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-2-0-2a95ae92bba77504addc-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-2-0-2a95ae92bba77504addc-svc-bar-whoamitcp-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-cf99cd1374e6056a6755": {
|
|
Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-cf99cd1374e6056a6755-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 2,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-135c6826c1baedf74c13": {
|
|
Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-135c6826c1baedf74c13-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 2,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-cf99cd1374e6056a6755-svc-bar-whoami-bar-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.11:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.12:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-135c6826c1baedf74c13-svc-bar-whoami-bar-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.11:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.12:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-cf99cd1374e6056a6755-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-cf99cd1374e6056a6755-svc-bar-whoami-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-135c6826c1baedf74c13-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-135c6826c1baedf74c13-svc-bar-whoami-bar-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Mixed routes with core group",
|
|
paths: []string{"services.yml", "mixed/with_core_group.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
"websecure": {Address: ":9443"},
|
|
"tcp": {Address: ":9000"},
|
|
"tls": {Address: ":10000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-df24b7f0f1d9b443e55b": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-df24b7f0f1d9b443e55b-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-df24b7f0f1d9b443e55b-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-df24b7f0f1d9b443e55b-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-df24b7f0f1d9b443e55b-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{"websecure"},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-3b55179f1d48675f1432": {
|
|
Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-3b55179f1d48675f1432-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 2,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-4a26538fbaaf60dc52c9": {
|
|
Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-4a26538fbaaf60dc52c9-wrr",
|
|
Rule: `PathPrefix("/")`,
|
|
Priority: 2,
|
|
RuleSyntax: "default",
|
|
ParentRefs: []string{"listener-websecure-https-439feda8e3f1dbdca529"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-3b55179f1d48675f1432-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-3b55179f1d48675f1432-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-4a26538fbaaf60dc52c9-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-4a26538fbaaf60dc52c9-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-3b55179f1d48675f1432-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-4a26538fbaaf60dc52c9-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": defaultListenerTLSOptions(),
|
|
},
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "GRPCRoute created first wins the conflicting hostname over the HTTPRoute",
|
|
paths: []string{"services.yml", "mixed/with_grpcroute_priority_over_httproute.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"grpcroute-default-grpc-app-priority-gw-default-my-gateway-ep-web-0-46e5641ba0ccfa2eff8a": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "grpcroute-default-grpc-app-priority-gw-default-my-gateway-ep-web-0-46e5641ba0ccfa2eff8a-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 22,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"grpcroute-default-grpc-app-priority-gw-default-my-gateway-ep-web-0-46e5641ba0ccfa2eff8a-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "grpcroute-default-grpc-app-priority-gw-default-my-gateway-ep-web-0-46e5641ba0ccfa2eff8a-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"grpcroute-default-grpc-app-priority-gw-default-my-gateway-ep-web-0-46e5641ba0ccfa2eff8a-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "h2c://10.10.0.1:80"},
|
|
{URL: "h2c://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "HTTPRoute created first wins the conflicting hostname over the GRPCRoute",
|
|
paths: []string{"services.yml", "mixed/with_httproute_priority_over_grpcroute.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":9080"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-web-http-5b3226d4ebd42b7200f1": {
|
|
EntryPoints: []string{"web"},
|
|
Rule: `Host("*")`,
|
|
},
|
|
"httproute-default-http-app-conflict-gw-default-my-gateway-ep-web-0-3fcf93756cef1b546fd2": {
|
|
ParentRefs: []string{"listener-web-http-5b3226d4ebd42b7200f1"},
|
|
Service: "httproute-default-http-app-conflict-gw-default-my-gateway-ep-web-0-3fcf93756cef1b546fd2-wrr",
|
|
Rule: `Host("foo.com") && PathPrefix("/")`,
|
|
Priority: 9,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-conflict-gw-default-my-gateway-ep-web-0-3fcf93756cef1b546fd2-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-conflict-gw-default-my-gateway-ep-web-0-3fcf93756cef1b546fd2-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-conflict-gw-default-my-gateway-ep-web-0-3fcf93756cef1b546fd2-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Strategy: dynamic.BalancerStrategyWRR,
|
|
Servers: []dynamic.Server{
|
|
{URL: "http://10.10.0.1:80"},
|
|
{URL: "http://10.10.0.2:80"},
|
|
},
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoute and TCPRoute with the same rule on the same entry point",
|
|
paths: []string{"services.yml", "mixed/with_tlsroute_and_tcproute_on_same_entrypoint.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tcp": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-gw-default-my-tls-gateway-ep-tcp-0-06fcfb4c19c97feaa646": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tlsroute-default-tls-app-gw-default-my-tls-gateway-ep-tcp-0-06fcfb4c19c97feaa646-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
TLS: &dynamic.RouterTCPTLSConfig{
|
|
Passthrough: true,
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-0-ada211f39fad8759e161": {
|
|
EntryPoints: []string{"tcp"},
|
|
Service: "tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-0-ada211f39fad8759e161-wrr",
|
|
Rule: `HostSNI("*")`,
|
|
RuleSyntax: "default",
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-gw-default-my-tls-gateway-ep-tcp-0-06fcfb4c19c97feaa646-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tlsroute-default-tls-app-gw-default-my-tls-gateway-ep-tcp-0-06fcfb4c19c97feaa646-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-gw-default-my-tls-gateway-ep-tcp-0-06fcfb4c19c97feaa646-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{Address: "10.10.0.9:9000"},
|
|
{Address: "10.10.0.10:9000"},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-0-ada211f39fad8759e161-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{
|
|
{
|
|
Name: "tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-0-ada211f39fad8759e161-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-0-ada211f39fad8759e161-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{Address: "10.10.0.9:9000"},
|
|
{Address: "10.10.0.10:9000"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "ListenerSet listener taking the hostname of a Gateway listener is not loaded",
|
|
paths: []string{"services.yml", "mixed/with_listenerset_conflicts.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
"websecure": {Address: ":443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-ba3a418469df6d6c8b5a": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-ba3a418469df6d6c8b5a-wrr",
|
|
Rule: `Host("baz.example.com") && Path("/bar")`,
|
|
ParentRefs: []string{
|
|
"listener-websecure-https-baz-example-com-dd68422a9ac9bfc6c47e",
|
|
},
|
|
RuleSyntax: "default",
|
|
Priority: 100016,
|
|
},
|
|
"listener-websecure-https-baz-example-com-dd68422a9ac9bfc6c47e": {
|
|
EntryPoints: []string{
|
|
"websecure",
|
|
},
|
|
Rule: `Host("baz.example.com")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-baz-example-com-dd68422a9ac9bfc6c47e",
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-ba3a418469df6d6c8b5a-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
Strategy: dynamic.BalancerStrategy("wrr"),
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100000000),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-ba3a418469df6d6c8b5a-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-ba3a418469df6d6c8b5a-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-baz-example-com-dd68422a9ac9bfc6c47e": {
|
|
CipherSuites: []string{
|
|
"TLS_AES_128_GCM_SHA256",
|
|
"TLS_AES_256_GCM_SHA384",
|
|
"TLS_CHACHA20_POLY1305_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
|
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
|
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
},
|
|
ALPNProtocols: []string{
|
|
"h2",
|
|
"http/1.1",
|
|
"acme-tls/1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Older ListenerSet wins the listener conflict with its sibling",
|
|
paths: []string{"services.yml", "mixed/with_listenerset_precedence.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
"web2": {Address: ":8080"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"httproute-default-http-app-older-gw-default-my-gateway-ep-web2-0-4541b5743d681903cbd4": {
|
|
Service: "httproute-default-http-app-older-gw-default-my-gateway-ep-web2-0-4541b5743d681903cbd4-wrr",
|
|
Rule: `Host("older.example.com") && Path("/bar")`,
|
|
ParentRefs: []string{
|
|
"listener-web2-http-4b299c63a1fd0bffdf3d",
|
|
},
|
|
RuleSyntax: "default",
|
|
Priority: 100018,
|
|
},
|
|
"listener-web2-http-4b299c63a1fd0bffdf3d": {
|
|
EntryPoints: []string{
|
|
"web2",
|
|
},
|
|
Rule: `Host("*")`,
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-older-gw-default-my-gateway-ep-web2-0-4541b5743d681903cbd4-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
Strategy: dynamic.BalancerStrategy("wrr"),
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100000000),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-older-gw-default-my-gateway-ep-web2-0-4541b5743d681903cbd4-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-older-gw-default-my-gateway-ep-web2-0-4541b5743d681903cbd4-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because the ListenerSet is not allowed by the Gateway",
|
|
paths: []string{"services.yml", "mixed/with_listenerset_not_allowed.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
"web2": {Address: ":8080"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Services: map[string]*dynamic.Service{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
// The Gateway declares no valid listener of its own,
|
|
// so it is accepted through the listener its ListenerSet delegates, which serves the route.
|
|
desc: "ListenerSet serving a Gateway without a valid listener of its own",
|
|
paths: []string{"services.yml", "mixed/with_listenerset_delegation.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"websecure": {Address: ":443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-wrr",
|
|
Rule: `Host("foo.example.com") && Path("/bar")`,
|
|
ParentRefs: []string{
|
|
"listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
RuleSyntax: "default",
|
|
Priority: 100016,
|
|
},
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{
|
|
"websecure",
|
|
},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
Strategy: dynamic.BalancerStrategy("wrr"),
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100000000),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
CipherSuites: []string{
|
|
"TLS_AES_128_GCM_SHA256",
|
|
"TLS_AES_256_GCM_SHA384",
|
|
"TLS_CHACHA20_POLY1305_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
|
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
|
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
},
|
|
ALPNProtocols: []string{
|
|
"h2",
|
|
"http/1.1",
|
|
"acme-tls/1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if test.expected == nil {
|
|
return
|
|
}
|
|
|
|
k8sObjects, gwObjects := readResources(t, test.paths)
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
client: client,
|
|
}
|
|
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, test.expected, conf)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadRoutesWithReferenceGrants(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
ingressClass string
|
|
paths []string
|
|
expected *dynamic.Configuration
|
|
entryPoints map[string]Entrypoint
|
|
}{
|
|
{
|
|
desc: "Empty",
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because ReferenceGrant for Secret is missing",
|
|
paths: []string{"services.yml", "referencegrant/for_secret_missing.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because ReferenceGrant spec.from does not match secret",
|
|
paths: []string{"services.yml", "referencegrant/for_secret_not_matching_from.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because ReferenceGrant spec.to does not match secret",
|
|
paths: []string{"services.yml", "referencegrant/for_secret_not_matching_to.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "For Secret",
|
|
paths: []string{"services.yml", "referencegrant/for_secret.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{
|
|
"deny-unknown-host": {
|
|
Rule: "HostSNI(`*`) && !ALPN(`h2`) && !ALPN(`http/1.1`)",
|
|
Priority: 1,
|
|
Service: "deny-unknown-host",
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174": {
|
|
EntryPoints: []string{"tls"},
|
|
Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr",
|
|
Rule: `HostSNI("foo.example.com")`,
|
|
RuleSyntax: "default",
|
|
Priority: 15,
|
|
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{
|
|
"deny-unknown-host": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-wrr": {
|
|
Weighted: &dynamic.TCPWeightedRoundRobin{
|
|
Services: []dynamic.TCPWRRService{{
|
|
Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0",
|
|
Weight: new(1),
|
|
}},
|
|
},
|
|
},
|
|
"tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-85354ef9915a52028174-svc-default-whoamitcp-0": {
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
|
Servers: []dynamic.TCPServer{
|
|
{
|
|
Address: "10.10.0.9:9000",
|
|
},
|
|
{
|
|
Address: "10.10.0.10:9000",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because ReferenceGrant for Service is missing",
|
|
paths: []string{"services.yml", "referencegrant/for_secret_missing.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because ReferenceGrant spec.from does not match service",
|
|
paths: []string{"services.yml", "referencegrant/for_service_not_matching_from.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because ReferenceGrant spec.to does not match service",
|
|
paths: []string{"services.yml", "referencegrant/for_service_not_matching_to.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"tls": {Address: ":9000"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "For Service",
|
|
paths: []string{"services.yml", "referencegrant/for_service.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"http": {Address: ":80"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"listener-http-http-foo-example-com-34297ca2d1326bfcdaad": {
|
|
EntryPoints: []string{"http"},
|
|
Rule: `Host("foo.example.com")`,
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-http-0-f6b84730f282bab89081": {
|
|
Rule: `Host("foo.example.com") && PathPrefix("/")`,
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-http-0-f6b84730f282bab89081-wrr",
|
|
RuleSyntax: "default",
|
|
Priority: 17,
|
|
ParentRefs: []string{"listener-http-http-foo-example-com-34297ca2d1326bfcdaad"},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-http-0-f6b84730f282bab89081-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-http-0-f6b84730f282bab89081-svc-default-whoami-bar-0",
|
|
Weight: new(1),
|
|
Status: new(500),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "For Secret from ListenerSet",
|
|
paths: []string{"services.yml", "referencegrant/for_secret_from_listenerset.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
"websecure": {Address: ":443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282": {
|
|
Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-wrr",
|
|
Rule: `Host("foo.example.com") && Path("/bar")`,
|
|
ParentRefs: []string{
|
|
"listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
RuleSyntax: "default",
|
|
Priority: 100016,
|
|
},
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
EntryPoints: []string{
|
|
"websecure",
|
|
},
|
|
Rule: `Host("*")`,
|
|
TLS: &dynamic.RouterTLSConfig{
|
|
Options: "listener-websecure-https-439feda8e3f1dbdca529",
|
|
},
|
|
},
|
|
},
|
|
Services: map[string]*dynamic.Service{
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-svc-default-whoami-0": {
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
|
Servers: []dynamic.Server{
|
|
{
|
|
URL: "http://10.10.0.1:80",
|
|
},
|
|
{
|
|
URL: "http://10.10.0.2:80",
|
|
},
|
|
},
|
|
Strategy: dynamic.BalancerStrategy("wrr"),
|
|
PassHostHeader: new(true),
|
|
ResponseForwarding: &dynamic.ResponseForwarding{
|
|
FlushInterval: ptypes.Duration(100000000),
|
|
},
|
|
},
|
|
},
|
|
"httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-wrr": {
|
|
Weighted: &dynamic.WeightedRoundRobin{
|
|
Services: []dynamic.WRRService{
|
|
{
|
|
Name: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-3c8b64d308e92f9c9282-svc-default-whoami-0",
|
|
Weight: new(1),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Certificates: []*tls.CertAndStores{
|
|
{
|
|
CertFile: types.FileOrContent(listenerCert),
|
|
KeyFile: types.FileOrContent(listenerKey),
|
|
},
|
|
},
|
|
Options: map[string]tls.Options{
|
|
"listener-websecure-https-439feda8e3f1dbdca529": {
|
|
CipherSuites: []string{
|
|
"TLS_AES_128_GCM_SHA256",
|
|
"TLS_AES_256_GCM_SHA384",
|
|
"TLS_CHACHA20_POLY1305_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
|
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
|
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
},
|
|
ALPNProtocols: []string{
|
|
"h2",
|
|
"http/1.1",
|
|
"acme-tls/1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Empty because ReferenceGrant spec.from does not match ListenerSet",
|
|
paths: []string{"services.yml", "referencegrant/for_secret_not_matching_from_listenerset.yml"},
|
|
entryPoints: map[string]Entrypoint{
|
|
"web": {Address: ":80"},
|
|
"websecure": {Address: ":443"},
|
|
},
|
|
expected: &dynamic.Configuration{
|
|
HTTP: &dynamic.HTTPConfiguration{
|
|
Routers: map[string]*dynamic.Router{},
|
|
Services: map[string]*dynamic.Service{},
|
|
Middlewares: map[string]*dynamic.Middleware{},
|
|
ServersTransports: map[string]*dynamic.ServersTransport{},
|
|
},
|
|
TCP: &dynamic.TCPConfiguration{
|
|
Routers: map[string]*dynamic.TCPRouter{},
|
|
Services: map[string]*dynamic.TCPService{},
|
|
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
|
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
|
},
|
|
UDP: &dynamic.UDPConfiguration{
|
|
Routers: map[string]*dynamic.UDPRouter{},
|
|
Services: map[string]*dynamic.UDPService{},
|
|
},
|
|
TLS: &dynamic.TLSConfiguration{
|
|
Options: map[string]tls.Options{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if test.expected == nil {
|
|
return
|
|
}
|
|
|
|
k8sObjects, gwObjects := readResources(t, test.paths)
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
client: client,
|
|
}
|
|
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, test.expected, conf)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_matchingGatewayListener(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
gateways []gatewayWithListeners
|
|
parentRefs []gatev1.ParentReference
|
|
routeNamespace string
|
|
want []gatewayListenersForParentRef
|
|
}{
|
|
{
|
|
desc: "Unsupported group",
|
|
gateways: []gatewayWithListeners{{
|
|
gateway: &gatev1.Gateway{Name: "gateway", Namespace: "default"},
|
|
listeners: []gatewayListener{{SectionName: "foo"}},
|
|
}},
|
|
parentRefs: []gatev1.ParentReference{{
|
|
Group: new(gatev1.Group("foo")),
|
|
}},
|
|
},
|
|
{
|
|
desc: "Unsupported kind",
|
|
gateways: []gatewayWithListeners{{
|
|
gateway: &gatev1.Gateway{Name: "gateway", Namespace: "default"},
|
|
listeners: []gatewayListener{{SectionName: "foo"}},
|
|
}},
|
|
parentRefs: []gatev1.ParentReference{{
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("foo")),
|
|
}},
|
|
},
|
|
{
|
|
desc: "Namespace does not match the listener",
|
|
gateways: []gatewayWithListeners{{
|
|
gateway: &gatev1.Gateway{Name: "gateway", Namespace: "default"},
|
|
listeners: []gatewayListener{{SectionName: "foo"}},
|
|
}},
|
|
parentRefs: []gatev1.ParentReference{{
|
|
Namespace: new(gatev1.Namespace("foo")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
}},
|
|
},
|
|
{
|
|
desc: "Route namespace defaulting does not match the listener",
|
|
gateways: []gatewayWithListeners{{
|
|
gateway: &gatev1.Gateway{Name: "gateway", Namespace: "default"},
|
|
listeners: []gatewayListener{{SectionName: "foo"}},
|
|
}},
|
|
routeNamespace: "foo",
|
|
parentRefs: []gatev1.ParentReference{{
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
}},
|
|
},
|
|
{
|
|
desc: "Name does not match the listener",
|
|
gateways: []gatewayWithListeners{{
|
|
gateway: &gatev1.Gateway{Name: "gateway", Namespace: "default"},
|
|
listeners: []gatewayListener{{}},
|
|
}},
|
|
parentRefs: []gatev1.ParentReference{{
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Name: "foo",
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
}},
|
|
},
|
|
{
|
|
desc: "Match",
|
|
gateways: []gatewayWithListeners{{
|
|
gateway: &gatev1.Gateway{Name: "gateway", Namespace: "default"},
|
|
listeners: []gatewayListener{{}},
|
|
}},
|
|
parentRefs: []gatev1.ParentReference{{
|
|
Name: "gateway",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
}},
|
|
want: []gatewayListenersForParentRef{{
|
|
ParentRef: gatev1.ParentReference{
|
|
Name: "gateway",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
},
|
|
GatewayName: "gateway",
|
|
GatewayNamespace: "default",
|
|
Listeners: []gatewayListener{{}},
|
|
}},
|
|
},
|
|
{
|
|
desc: "Match with route namespace defaulting",
|
|
gateways: []gatewayWithListeners{{
|
|
gateway: &gatev1.Gateway{Name: "gateway", Namespace: "default"},
|
|
listeners: []gatewayListener{{}},
|
|
}},
|
|
routeNamespace: "default",
|
|
parentRefs: []gatev1.ParentReference{{
|
|
Name: "gateway",
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
}},
|
|
want: []gatewayListenersForParentRef{{
|
|
ParentRef: gatev1.ParentReference{
|
|
Name: "gateway",
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
},
|
|
GatewayName: "gateway",
|
|
GatewayNamespace: "default",
|
|
Listeners: []gatewayListener{{}},
|
|
}},
|
|
},
|
|
{
|
|
// A Route may reference Gateways owned by other controllers; those
|
|
// parentRefs must not be associated to (and thus get status written by)
|
|
// this controller.
|
|
desc: "Only parentRefs targeting our Gateways are returned",
|
|
gateways: []gatewayWithListeners{{
|
|
gateway: &gatev1.Gateway{Name: "gateway", Namespace: "default"},
|
|
listeners: []gatewayListener{{}},
|
|
}},
|
|
parentRefs: []gatev1.ParentReference{
|
|
{
|
|
Name: "gateway",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
},
|
|
{
|
|
Name: "other-gateway",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
},
|
|
},
|
|
want: []gatewayListenersForParentRef{{
|
|
ParentRef: gatev1.ParentReference{
|
|
Name: "gateway",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
},
|
|
GatewayName: "gateway",
|
|
GatewayNamespace: "default",
|
|
Listeners: []gatewayListener{{}},
|
|
}},
|
|
},
|
|
{
|
|
desc: "ParentRef is associated to all the listeners of its Gateway",
|
|
gateways: []gatewayWithListeners{{
|
|
gateway: &gatev1.Gateway{Name: "gateway", Namespace: "default"},
|
|
listeners: []gatewayListener{
|
|
{SectionName: "web"},
|
|
{SectionName: "websecure"},
|
|
},
|
|
}},
|
|
parentRefs: []gatev1.ParentReference{{
|
|
Name: "gateway",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
}},
|
|
want: []gatewayListenersForParentRef{{
|
|
ParentRef: gatev1.ParentReference{
|
|
Name: "gateway",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
},
|
|
GatewayName: "gateway",
|
|
GatewayNamespace: "default",
|
|
Listeners: []gatewayListener{
|
|
{SectionName: "web"},
|
|
{SectionName: "websecure"},
|
|
},
|
|
}},
|
|
},
|
|
{
|
|
// A parentRef must only be associated to the listeners of the Gateway it
|
|
// targets, even when several of our Gateways are known.
|
|
desc: "ParentRef is only associated to the referenced Gateway",
|
|
gateways: []gatewayWithListeners{
|
|
{
|
|
gateway: &gatev1.Gateway{Name: "gateway-a", Namespace: "default"},
|
|
listeners: []gatewayListener{{SectionName: "web"}},
|
|
},
|
|
{
|
|
gateway: &gatev1.Gateway{Name: "gateway-b", Namespace: "default"},
|
|
listeners: []gatewayListener{{SectionName: "web"}},
|
|
},
|
|
},
|
|
parentRefs: []gatev1.ParentReference{{
|
|
Name: "gateway-a",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
}},
|
|
want: []gatewayListenersForParentRef{{
|
|
ParentRef: gatev1.ParentReference{
|
|
Name: "gateway-a",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
},
|
|
GatewayName: "gateway-a",
|
|
GatewayNamespace: "default",
|
|
Listeners: []gatewayListener{{SectionName: "web"}},
|
|
}},
|
|
},
|
|
{
|
|
// A parentRef with a non-matching SectionName or Port still targets the
|
|
// Gateway: all its listeners are returned so the route loader can report
|
|
// ResolvedRefs even though the route attaches to none of them.
|
|
desc: "ParentRef with a non-matching port still returns the Gateway listeners",
|
|
gateways: []gatewayWithListeners{{
|
|
gateway: &gatev1.Gateway{Name: "gateway", Namespace: "default"},
|
|
listeners: []gatewayListener{{SectionName: "web", Port: 80}},
|
|
}},
|
|
parentRefs: []gatev1.ParentReference{{
|
|
Name: "gateway",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
Port: new(gatev1.PortNumber(8080)),
|
|
}},
|
|
want: []gatewayListenersForParentRef{{
|
|
ParentRef: gatev1.ParentReference{
|
|
Name: "gateway",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Group: new(gatev1.Group(gatev1.GroupName)),
|
|
Kind: new(gatev1.Kind("Gateway")),
|
|
Port: new(gatev1.PortNumber(8080)),
|
|
},
|
|
GatewayName: "gateway",
|
|
GatewayNamespace: "default",
|
|
Listeners: []gatewayListener{{SectionName: "web", Port: 80}},
|
|
}},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
matches := matchingGatewayListenersForParentRef(test.gateways, test.routeNamespace, test.parentRefs)
|
|
assert.Equal(t, test.want, matches)
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test_loadRoutes_multipleGatewaysParentRefs ensures that, when a Route
|
|
// references several Gateways (including one owned by another controller), Traefik
|
|
// only manages the parents it is responsible for: it writes a single RouteParentStatus
|
|
// for its own parentRef, writes nothing for a Route that targets only a foreign
|
|
// Gateway, and counts each attached Route only once in the listener AttachedRoutes.
|
|
func Test_loadRoutes_multipleGatewaysParentRefs(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
path string
|
|
entryPoints map[string]Entrypoint
|
|
gatewayName string
|
|
route1, route2 string
|
|
getParents func(t *testing.T, gwClient *gatefake.Clientset, name string) []gatev1.RouteParentStatus
|
|
}{
|
|
{
|
|
desc: "HTTPRoute",
|
|
path: "httproute/with_multiple_gateways_parent_refs.yml",
|
|
entryPoints: map[string]Entrypoint{"web": {Address: ":80"}},
|
|
gatewayName: "my-gateway",
|
|
route1: "http-app-1",
|
|
route2: "http-app-2",
|
|
getParents: func(t *testing.T, gwClient *gatefake.Clientset, name string) []gatev1.RouteParentStatus {
|
|
t.Helper()
|
|
route, err := gwClient.GatewayV1().HTTPRoutes("default").Get(t.Context(), name, metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
return route.Status.Parents
|
|
},
|
|
},
|
|
{
|
|
desc: "GRPCRoute",
|
|
path: "grpcroute/with_multiple_gateways_parent_refs.yml",
|
|
entryPoints: map[string]Entrypoint{"web": {Address: ":80"}},
|
|
gatewayName: "my-gateway",
|
|
route1: "grpc-app-1",
|
|
route2: "grpc-app-2",
|
|
getParents: func(t *testing.T, gwClient *gatefake.Clientset, name string) []gatev1.RouteParentStatus {
|
|
t.Helper()
|
|
route, err := gwClient.GatewayV1().GRPCRoutes("default").Get(t.Context(), name, metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
return route.Status.Parents
|
|
},
|
|
},
|
|
{
|
|
desc: "TCPRoute",
|
|
path: "tcproute/with_multiple_gateways_parent_refs.yml",
|
|
entryPoints: map[string]Entrypoint{"tcp": {Address: ":9000"}},
|
|
gatewayName: "my-tcp-gateway",
|
|
route1: "tcp-app-1",
|
|
route2: "tcp-app-2",
|
|
getParents: func(t *testing.T, gwClient *gatefake.Clientset, name string) []gatev1.RouteParentStatus {
|
|
t.Helper()
|
|
route, err := gwClient.GatewayV1().TCPRoutes("default").Get(t.Context(), name, metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
return route.Status.Parents
|
|
},
|
|
},
|
|
{
|
|
desc: "TLSRoute",
|
|
path: "tlsroute/with_multiple_gateways_parent_refs.yml",
|
|
entryPoints: map[string]Entrypoint{"tls": {Address: ":9000"}},
|
|
gatewayName: "my-tls-gateway",
|
|
route1: "tls-app-1",
|
|
route2: "tls-app-2",
|
|
getParents: func(t *testing.T, gwClient *gatefake.Clientset, name string) []gatev1.RouteParentStatus {
|
|
t.Helper()
|
|
route, err := gwClient.GatewayV1().TLSRoutes("default").Get(t.Context(), name, metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
return route.Status.Parents
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
k8sObjects, gwObjects := readResources(t, []string{"services.yml", test.path})
|
|
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
client := newClientImpl(kubefake.NewClientset(k8sObjects...), gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
<-eventCh
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
client: client,
|
|
}
|
|
|
|
_, statusReport, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
statusReport.Flush(t.Context(), client)
|
|
|
|
// route1 references our Gateway and a foreign one: only our parentRef must
|
|
// get a status entry, written under our controllerName and accepted.
|
|
parents1 := test.getParents(t, gwClient, test.route1)
|
|
require.Len(t, parents1, 1)
|
|
assert.Equal(t, gatev1.GatewayController(controllerName), parents1[0].ControllerName)
|
|
assert.Equal(t, gatev1.ObjectName(test.gatewayName), parents1[0].ParentRef.Name)
|
|
|
|
acceptedCondition := findCondition(parents1[0].Conditions, gatev1.RouteConditionAccepted)
|
|
require.NotNil(t, acceptedCondition)
|
|
assert.Equal(t, metav1.ConditionTrue, acceptedCondition.Status)
|
|
assert.Equal(t, string(gatev1.RouteReasonAccepted), acceptedCondition.Reason)
|
|
|
|
// route2 references only the foreign Gateway: Traefik must not write any status.
|
|
assert.Empty(t, test.getParents(t, gwClient, test.route2))
|
|
|
|
// The listener must count route1 once, ignoring the foreign parentRef and
|
|
// the foreign-only Route.
|
|
gateway, err := gwClient.GatewayV1().Gateways("default").Get(t.Context(), test.gatewayName, metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
require.Len(t, gateway.Status.Listeners, 1)
|
|
assert.Equal(t, int32(1), gateway.Status.Listeners[0].AttachedRoutes)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_loadHTTPAndGRPCRoutes_hostnameConflict(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
path string
|
|
acceptedRoute string
|
|
acceptedIsHTTP bool
|
|
conflictedRoute string
|
|
}{
|
|
{
|
|
desc: "HTTPRoute created first",
|
|
path: "mixed/with_httproute_priority_over_grpcroute.yml",
|
|
acceptedRoute: "http-app-conflict",
|
|
acceptedIsHTTP: true,
|
|
conflictedRoute: "grpc-app-conflict",
|
|
},
|
|
{
|
|
desc: "GRPCRoute created first",
|
|
path: "mixed/with_grpcroute_priority_over_httproute.yml",
|
|
acceptedRoute: "grpc-app-priority",
|
|
conflictedRoute: "http-app-priority",
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
k8sObjects, gwObjects := readResources(t, []string{"services.yml", test.path})
|
|
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
client := newClientImpl(kubefake.NewClientset(k8sObjects...), gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
<-eventCh
|
|
|
|
p := Provider{
|
|
EntryPoints: map[string]Entrypoint{"web": {Address: ":9080"}},
|
|
client: client,
|
|
}
|
|
|
|
_, statusReport, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
statusReport.Flush(t.Context(), client)
|
|
|
|
getParents := func(name string, isHTTP bool) []gatev1.RouteParentStatus {
|
|
t.Helper()
|
|
if isHTTP {
|
|
route, err := gwClient.GatewayV1().HTTPRoutes("default").Get(t.Context(), name, metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
return route.Status.Parents
|
|
}
|
|
route, err := gwClient.GatewayV1().GRPCRoutes("default").Get(t.Context(), name, metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
return route.Status.Parents
|
|
}
|
|
|
|
acceptedParents := getParents(test.acceptedRoute, test.acceptedIsHTTP)
|
|
require.Len(t, acceptedParents, 1)
|
|
acceptedCondition := findCondition(acceptedParents[0].Conditions, gatev1.RouteConditionAccepted)
|
|
require.NotNil(t, acceptedCondition)
|
|
assert.Equal(t, metav1.ConditionTrue, acceptedCondition.Status)
|
|
assert.Equal(t, string(gatev1.RouteReasonAccepted), acceptedCondition.Reason)
|
|
|
|
conflictedParents := getParents(test.conflictedRoute, !test.acceptedIsHTTP)
|
|
require.Len(t, conflictedParents, 1)
|
|
conflictedCondition := findCondition(conflictedParents[0].Conditions, gatev1.RouteConditionAccepted)
|
|
require.NotNil(t, conflictedCondition)
|
|
assert.Equal(t, metav1.ConditionFalse, conflictedCondition.Status)
|
|
assert.Equal(t, string(routeReasonHostnameConflict), conflictedCondition.Reason)
|
|
|
|
gateway, err := gwClient.GatewayV1().Gateways("default").Get(t.Context(), "my-gateway", metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
require.Len(t, gateway.Status.Listeners, 1)
|
|
assert.Equal(t, int32(1), gateway.Status.Listeners[0].AttachedRoutes)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_attachedRoutes_conflicts(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
attachedKind string
|
|
attachedHostnames []gatev1.Hostname
|
|
attachedListener listenerRef
|
|
kind string
|
|
hostnames []gatev1.Hostname
|
|
expected bool
|
|
}{
|
|
{
|
|
desc: "same kind",
|
|
attachedKind: kindHTTPRoute,
|
|
attachedHostnames: []gatev1.Hostname{"foo.com"},
|
|
attachedListener: listenerRef{
|
|
GatewayNamespace: "default",
|
|
GatewayName: "my-gateway",
|
|
SectionName: "web",
|
|
},
|
|
kind: kindHTTPRoute,
|
|
hostnames: []gatev1.Hostname{"foo.com"},
|
|
},
|
|
{
|
|
desc: "another listener",
|
|
attachedKind: kindHTTPRoute,
|
|
attachedHostnames: []gatev1.Hostname{"foo.com"},
|
|
attachedListener: listenerRef{
|
|
GatewayNamespace: "default",
|
|
GatewayName: "my-gateway",
|
|
SectionName: "websecure",
|
|
},
|
|
kind: kindGRPCRoute,
|
|
hostnames: []gatev1.Hostname{"foo.com"},
|
|
},
|
|
{
|
|
desc: "disjoint hostnames",
|
|
attachedKind: kindHTTPRoute,
|
|
attachedHostnames: []gatev1.Hostname{"foo.com"},
|
|
attachedListener: listenerRef{
|
|
GatewayNamespace: "default",
|
|
GatewayName: "my-gateway",
|
|
SectionName: "web",
|
|
},
|
|
kind: kindGRPCRoute,
|
|
hostnames: []gatev1.Hostname{"bar.com"},
|
|
},
|
|
{
|
|
desc: "same hostname",
|
|
attachedKind: kindHTTPRoute,
|
|
attachedHostnames: []gatev1.Hostname{"foo.com"},
|
|
attachedListener: listenerRef{
|
|
GatewayNamespace: "default",
|
|
GatewayName: "my-gateway",
|
|
SectionName: "web",
|
|
},
|
|
kind: kindGRPCRoute,
|
|
hostnames: []gatev1.Hostname{"bar.com", "foo.com"},
|
|
expected: true,
|
|
},
|
|
{
|
|
desc: "attached wildcard hostname",
|
|
attachedKind: kindGRPCRoute,
|
|
attachedHostnames: []gatev1.Hostname{"*.foo.com"},
|
|
attachedListener: listenerRef{
|
|
GatewayNamespace: "default",
|
|
GatewayName: "my-gateway",
|
|
SectionName: "web",
|
|
},
|
|
kind: kindHTTPRoute,
|
|
hostnames: []gatev1.Hostname{"bar.foo.com"},
|
|
expected: true,
|
|
},
|
|
{
|
|
desc: "wildcard hostname",
|
|
attachedKind: kindGRPCRoute,
|
|
attachedHostnames: []gatev1.Hostname{"bar.foo.com"},
|
|
attachedListener: listenerRef{
|
|
GatewayNamespace: "default",
|
|
GatewayName: "my-gateway",
|
|
SectionName: "web",
|
|
},
|
|
kind: kindHTTPRoute,
|
|
hostnames: []gatev1.Hostname{"*.foo.com"},
|
|
expected: true,
|
|
},
|
|
{
|
|
desc: "attached without hostname",
|
|
attachedKind: kindHTTPRoute,
|
|
attachedHostnames: nil,
|
|
attachedListener: listenerRef{
|
|
GatewayNamespace: "default",
|
|
GatewayName: "my-gateway",
|
|
SectionName: "web",
|
|
},
|
|
kind: kindGRPCRoute,
|
|
hostnames: []gatev1.Hostname{"foo.com"},
|
|
expected: true,
|
|
},
|
|
{
|
|
desc: "without hostname",
|
|
attachedKind: kindHTTPRoute,
|
|
attachedHostnames: []gatev1.Hostname{"foo.com"},
|
|
attachedListener: listenerRef{
|
|
GatewayNamespace: "default",
|
|
GatewayName: "my-gateway",
|
|
SectionName: "web",
|
|
},
|
|
kind: kindGRPCRoute,
|
|
hostnames: nil,
|
|
expected: true,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
attached := make(attachedRoutes)
|
|
attached.Record(test.attachedListener, test.attachedKind, test.attachedHostnames)
|
|
|
|
listener := listenerRef{GatewayNamespace: "default", GatewayName: "my-gateway", SectionName: "web"}
|
|
assert.Equal(t, test.expected, attached.Conflicts(listener, test.kind, test.hostnames))
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test_mergeRouteParentStatuses ensures the merge keeps the parentStatuses Traefik
|
|
// does not own: those written by another controller, and those written by another
|
|
// Traefik instance (our controllerName but a parentRef not targeting a managed
|
|
// Gateway), while replacing our stale statuses with the freshly computed ones.
|
|
func Test_mergeRouteParentStatuses(t *testing.T) {
|
|
gateways := []gatewayWithListeners{{gateway: &gatev1.Gateway{Name: "my-gateway", Namespace: "default"}}}
|
|
|
|
otherController := gatev1.RouteParentStatus{
|
|
ControllerName: "example.com/other-controller",
|
|
ParentRef: gatev1.ParentReference{Namespace: new(gatev1.Namespace("default")), Name: "other-gateway"},
|
|
}
|
|
otherTraefik := gatev1.RouteParentStatus{
|
|
ControllerName: controllerName,
|
|
ParentRef: gatev1.ParentReference{Namespace: new(gatev1.Namespace("default")), Name: "other-traefik-gateway"},
|
|
}
|
|
staleManaged := gatev1.RouteParentStatus{
|
|
ControllerName: controllerName,
|
|
ParentRef: gatev1.ParentReference{Namespace: new(gatev1.Namespace("default")), Name: "my-gateway"},
|
|
}
|
|
// A parentRef without an explicit namespace defaults to the Route namespace,
|
|
// and must still be recognized as targeting a managed Gateway.
|
|
staleManagedDefaulted := gatev1.RouteParentStatus{
|
|
ControllerName: controllerName,
|
|
ParentRef: gatev1.ParentReference{Name: "my-gateway"},
|
|
}
|
|
desired := gatev1.RouteParentStatus{
|
|
ControllerName: controllerName,
|
|
ParentRef: gatev1.ParentReference{Namespace: new(gatev1.Namespace("default")), Name: "my-gateway"},
|
|
Conditions: []metav1.Condition{{
|
|
Type: string(gatev1.RouteConditionAccepted),
|
|
Status: metav1.ConditionTrue,
|
|
Reason: string(gatev1.RouteReasonAccepted),
|
|
}},
|
|
}
|
|
|
|
testCases := []struct {
|
|
desc string
|
|
current []gatev1.RouteParentStatus
|
|
want []gatev1.RouteParentStatus
|
|
}{
|
|
{
|
|
desc: "no current status",
|
|
want: []gatev1.RouteParentStatus{desired},
|
|
},
|
|
{
|
|
desc: "keeps status owned by another controller",
|
|
current: []gatev1.RouteParentStatus{otherController},
|
|
want: []gatev1.RouteParentStatus{desired, otherController},
|
|
},
|
|
{
|
|
desc: "keeps our status targeting a Gateway managed by another Traefik instance",
|
|
current: []gatev1.RouteParentStatus{otherTraefik},
|
|
want: []gatev1.RouteParentStatus{desired, otherTraefik},
|
|
},
|
|
{
|
|
desc: "drops our stale status targeting a managed Gateway",
|
|
current: []gatev1.RouteParentStatus{staleManaged},
|
|
want: []gatev1.RouteParentStatus{desired},
|
|
},
|
|
{
|
|
desc: "drops our stale status targeting a managed Gateway via namespace defaulting",
|
|
current: []gatev1.RouteParentStatus{staleManagedDefaulted},
|
|
want: []gatev1.RouteParentStatus{desired},
|
|
},
|
|
{
|
|
desc: "mixed: keeps unmanaged, drops managed",
|
|
current: []gatev1.RouteParentStatus{otherController, otherTraefik, staleManaged},
|
|
want: []gatev1.RouteParentStatus{desired, otherController, otherTraefik},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := mergeRouteParentStatuses("default", test.current, []gatev1.RouteParentStatus{desired}, gateways)
|
|
assert.Equal(t, test.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_managesGateway(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
gateways []NamespacedName
|
|
gw *gatev1.Gateway
|
|
want bool
|
|
}{
|
|
{
|
|
desc: "no scoping manages everything",
|
|
gw: &gatev1.Gateway{
|
|
Namespace: "default",
|
|
Name: "foo",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
desc: "matching ref",
|
|
gateways: []NamespacedName{{Namespace: "default", Name: "foo"}},
|
|
gw: &gatev1.Gateway{
|
|
Namespace: "default",
|
|
Name: "foo",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
desc: "different name",
|
|
gateways: []NamespacedName{{Namespace: "default", Name: "foo"}},
|
|
gw: &gatev1.Gateway{
|
|
Namespace: "default",
|
|
Name: "bar",
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
desc: "different namespace",
|
|
gateways: []NamespacedName{{Namespace: "default", Name: "foo"}},
|
|
gw: &gatev1.Gateway{
|
|
Namespace: "other",
|
|
Name: "foo",
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
desc: "list matches first",
|
|
gateways: []NamespacedName{
|
|
{Namespace: "default", Name: "foo"},
|
|
{Namespace: "other", Name: "bar"},
|
|
},
|
|
gw: &gatev1.Gateway{
|
|
Namespace: "default",
|
|
Name: "foo",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
desc: "list matches none",
|
|
gateways: []NamespacedName{
|
|
{Namespace: "default", Name: "foo"},
|
|
{Namespace: "other", Name: "bar"},
|
|
},
|
|
gw: &gatev1.Gateway{
|
|
Namespace: "default",
|
|
Name: "baz",
|
|
},
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
p := Provider{Gateways: test.gateways}
|
|
assert.Equal(t, test.want, p.managesGateway(test.gw))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_matchListener(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
gwListener gatewayListener
|
|
parentRef gatev1.ParentReference
|
|
wantMatch bool
|
|
}{
|
|
{
|
|
desc: "Section do not match",
|
|
gwListener: gatewayListener{
|
|
SectionName: "foo",
|
|
Port: gatev1.PortNumber(80),
|
|
},
|
|
parentRef: gatev1.ParentReference{
|
|
SectionName: new(gatev1.SectionName("bar")),
|
|
Port: new(gatev1.PortNumber(80)),
|
|
},
|
|
},
|
|
{
|
|
desc: "Section matches",
|
|
gwListener: gatewayListener{
|
|
SectionName: "foo",
|
|
Port: gatev1.PortNumber(80),
|
|
},
|
|
parentRef: gatev1.ParentReference{
|
|
SectionName: new(gatev1.SectionName("foo")),
|
|
Port: new(gatev1.PortNumber(80)),
|
|
},
|
|
wantMatch: true,
|
|
},
|
|
{
|
|
desc: "Port do not match",
|
|
gwListener: gatewayListener{
|
|
SectionName: "foo",
|
|
Port: gatev1.PortNumber(90),
|
|
},
|
|
parentRef: gatev1.ParentReference{
|
|
SectionName: new(gatev1.SectionName("foo")),
|
|
Port: new(gatev1.PortNumber(80)),
|
|
},
|
|
},
|
|
{
|
|
desc: "Port matches",
|
|
gwListener: gatewayListener{
|
|
SectionName: "foo",
|
|
Port: gatev1.PortNumber(80),
|
|
},
|
|
parentRef: gatev1.ParentReference{
|
|
SectionName: new(gatev1.SectionName("foo")),
|
|
Port: new(gatev1.PortNumber(80)),
|
|
},
|
|
wantMatch: true,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
gotMatch := matchListener(test.gwListener, test.parentRef)
|
|
assert.Equal(t, test.wantMatch, gotMatch)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_allowRoute(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
gwListener gatewayListener
|
|
routeNamespace string
|
|
routeKind string
|
|
wantAllow bool
|
|
}{
|
|
{
|
|
desc: "Not allowed Kind",
|
|
gwListener: gatewayListener{
|
|
SectionName: "foo",
|
|
AllowedRouteKinds: []string{
|
|
"foo",
|
|
"bar",
|
|
},
|
|
},
|
|
routeKind: "baz",
|
|
wantAllow: false,
|
|
},
|
|
{
|
|
desc: "Allowed Kind",
|
|
gwListener: gatewayListener{
|
|
SectionName: "foo",
|
|
AllowedRouteKinds: []string{
|
|
"foo",
|
|
"bar",
|
|
},
|
|
AllowedNamespaces: []string{
|
|
corev1.NamespaceAll,
|
|
},
|
|
},
|
|
routeKind: "bar",
|
|
wantAllow: true,
|
|
},
|
|
{
|
|
desc: "Not allowed namespace",
|
|
gwListener: gatewayListener{
|
|
SectionName: "foo",
|
|
AllowedRouteKinds: []string{
|
|
"foo",
|
|
},
|
|
AllowedNamespaces: []string{
|
|
"foo",
|
|
"bar",
|
|
},
|
|
},
|
|
routeKind: "foo",
|
|
routeNamespace: "baz",
|
|
wantAllow: false,
|
|
},
|
|
{
|
|
desc: "Allowed namespace",
|
|
gwListener: gatewayListener{
|
|
SectionName: "foo",
|
|
AllowedRouteKinds: []string{
|
|
"foo",
|
|
},
|
|
AllowedNamespaces: []string{
|
|
"foo",
|
|
"bar",
|
|
},
|
|
},
|
|
routeKind: "foo",
|
|
routeNamespace: "foo",
|
|
wantAllow: true,
|
|
},
|
|
{
|
|
desc: "Allowed namespace",
|
|
gwListener: gatewayListener{
|
|
SectionName: "foo",
|
|
AllowedRouteKinds: []string{
|
|
"foo",
|
|
},
|
|
AllowedNamespaces: []string{
|
|
corev1.NamespaceAll,
|
|
"bar",
|
|
},
|
|
},
|
|
routeKind: "foo",
|
|
routeNamespace: "foo",
|
|
wantAllow: true,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
gotAllow := allowRoute(test.gwListener, test.routeNamespace, test.routeKind)
|
|
assert.Equal(t, test.wantAllow, gotAllow)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_findMatchingHostnames(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
listenerHostname *gatev1.Hostname
|
|
routeHostnames []gatev1.Hostname
|
|
want []gatev1.Hostname
|
|
wantOk bool
|
|
}{
|
|
{
|
|
desc: "Empty",
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Only listener hostname",
|
|
listenerHostname: new(gatev1.Hostname("foo.com")),
|
|
want: []gatev1.Hostname{"foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Only Route hostname",
|
|
routeHostnames: []gatev1.Hostname{"foo.com"},
|
|
want: []gatev1.Hostname{"foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Matching hostname",
|
|
listenerHostname: new(gatev1.Hostname("foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"foo.com"},
|
|
want: []gatev1.Hostname{"foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Matching hostname with wildcard",
|
|
listenerHostname: new(gatev1.Hostname("*.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"*.foo.com"},
|
|
want: []gatev1.Hostname{"*.foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Matching subdomain with listener wildcard",
|
|
listenerHostname: new(gatev1.Hostname("*.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"bar.foo.com"},
|
|
want: []gatev1.Hostname{"bar.foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Matching subdomain wildcard with listener wildcard",
|
|
listenerHostname: new(gatev1.Hostname("*.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"*.bar.foo.com"},
|
|
want: []gatev1.Hostname{"*.bar.foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Matching subsubdomain with listener wildcard",
|
|
listenerHostname: new(gatev1.Hostname("*.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"baz.bar.foo.com"},
|
|
want: []gatev1.Hostname{"baz.bar.foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Matching subdomain with route hostname wildcard",
|
|
listenerHostname: new(gatev1.Hostname("bar.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"*.foo.com"},
|
|
want: []gatev1.Hostname{"bar.foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Matching subsubdomain with route hostname wildcard",
|
|
listenerHostname: new(gatev1.Hostname("baz.bar.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"*.foo.com"},
|
|
want: []gatev1.Hostname{"baz.bar.foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Non matching root domain with listener wildcard",
|
|
listenerHostname: new(gatev1.Hostname("*.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"foo.com"},
|
|
},
|
|
{
|
|
desc: "Non matching root domain with route hostname wildcard",
|
|
listenerHostname: new(gatev1.Hostname("foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"*.foo.com"},
|
|
},
|
|
{
|
|
desc: "Multiple route hostnames with one matching route hostname",
|
|
listenerHostname: new(gatev1.Hostname("*.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"bar.com", "test.foo.com", "test.buz.com"},
|
|
want: []gatev1.Hostname{"test.foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Multiple route hostnames with non matching route hostname",
|
|
listenerHostname: new(gatev1.Hostname("*.fuz.com")),
|
|
routeHostnames: []gatev1.Hostname{"bar.com", "test.foo.com", "test.buz.com"},
|
|
},
|
|
{
|
|
desc: "Multiple route hostnames with multiple matching route hostnames",
|
|
listenerHostname: new(gatev1.Hostname("*.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"toto.foo.com", "test.foo.com", "test.buz.com"},
|
|
want: []gatev1.Hostname{"test.foo.com", "toto.foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Matching wildcard subsubdomain with listener wildcard subdomain",
|
|
listenerHostname: new(gatev1.Hostname("*.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"*.bar.foo.com"},
|
|
want: []gatev1.Hostname{"*.bar.foo.com"},
|
|
wantOk: true,
|
|
},
|
|
{
|
|
desc: "Duplicate intersections are returned once",
|
|
listenerHostname: new(gatev1.Hostname("bar.foo.com")),
|
|
routeHostnames: []gatev1.Hostname{"*.foo.com", "bar.foo.com"},
|
|
want: []gatev1.Hostname{"bar.foo.com"},
|
|
wantOk: true,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got, ok := findMatchingHostnames(test.listenerHostname, test.routeHostnames)
|
|
assert.Equal(t, test.wantOk, ok)
|
|
assert.Equal(t, test.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_allowedRouteKinds(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
listener gatev1.Listener
|
|
supportedRouteKinds []gatev1.RouteGroupKind
|
|
wantKinds []gatev1.RouteGroupKind
|
|
wantErr bool
|
|
}{
|
|
{
|
|
desc: "Empty",
|
|
},
|
|
{
|
|
desc: "Empty AllowedRoutes",
|
|
supportedRouteKinds: []gatev1.RouteGroupKind{
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
},
|
|
wantKinds: []gatev1.RouteGroupKind{
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
},
|
|
},
|
|
{
|
|
desc: "AllowedRoutes with unsupported Group",
|
|
listener: gatev1.Listener{
|
|
AllowedRoutes: &gatev1.AllowedRoutes{
|
|
Kinds: []gatev1.RouteGroupKind{{
|
|
Kind: kindTLSRoute, Group: new(gatev1.Group("foo")),
|
|
}},
|
|
},
|
|
},
|
|
supportedRouteKinds: []gatev1.RouteGroupKind{
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
desc: "AllowedRoutes with nil Group",
|
|
listener: gatev1.Listener{
|
|
AllowedRoutes: &gatev1.AllowedRoutes{
|
|
Kinds: []gatev1.RouteGroupKind{{
|
|
Kind: kindTLSRoute, Group: nil,
|
|
}},
|
|
},
|
|
},
|
|
supportedRouteKinds: []gatev1.RouteGroupKind{
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
desc: "AllowedRoutes with unsupported Kind",
|
|
listener: gatev1.Listener{
|
|
AllowedRoutes: &gatev1.AllowedRoutes{
|
|
Kinds: []gatev1.RouteGroupKind{{
|
|
Kind: "foo", Group: new(gatev1.Group(gatev1.GroupName)),
|
|
}},
|
|
},
|
|
},
|
|
supportedRouteKinds: []gatev1.RouteGroupKind{
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
desc: "Supported AllowedRoutes",
|
|
listener: gatev1.Listener{
|
|
AllowedRoutes: &gatev1.AllowedRoutes{
|
|
Kinds: []gatev1.RouteGroupKind{{
|
|
Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName)),
|
|
}},
|
|
},
|
|
},
|
|
supportedRouteKinds: []gatev1.RouteGroupKind{
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
},
|
|
wantKinds: []gatev1.RouteGroupKind{
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
},
|
|
},
|
|
{
|
|
desc: "Supported AllowedRoutes with duplicates",
|
|
listener: gatev1.Listener{
|
|
AllowedRoutes: &gatev1.AllowedRoutes{
|
|
Kinds: []gatev1.RouteGroupKind{
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
{Kind: kindTCPRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
{Kind: kindTCPRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
},
|
|
},
|
|
},
|
|
supportedRouteKinds: []gatev1.RouteGroupKind{
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
{Kind: kindTCPRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
},
|
|
wantKinds: []gatev1.RouteGroupKind{
|
|
{Kind: kindTLSRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
{Kind: kindTCPRoute, Group: new(gatev1.Group(gatev1.GroupName))},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got, conditions := allowedRouteKinds(0, test.listener, test.supportedRouteKinds)
|
|
if test.wantErr {
|
|
require.NotEmpty(t, conditions, "no conditions")
|
|
return
|
|
}
|
|
|
|
require.Empty(t, conditions)
|
|
assert.Equal(t, test.wantKinds, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_makeListenerKey(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
listener gatev1.Listener
|
|
expectedKey string
|
|
}{
|
|
{
|
|
desc: "empty",
|
|
expectedKey: "||0",
|
|
},
|
|
{
|
|
desc: "listener with port, protocol and hostname",
|
|
listener: gatev1.Listener{
|
|
Port: 443,
|
|
Protocol: gatev1.HTTPSProtocolType,
|
|
Hostname: new(gatev1.Hostname("www.example.com")),
|
|
},
|
|
expectedKey: "HTTPS|www.example.com|443",
|
|
},
|
|
{
|
|
desc: "listener with port, protocol and nil hostname",
|
|
listener: gatev1.Listener{
|
|
Port: 443,
|
|
Protocol: gatev1.HTTPSProtocolType,
|
|
},
|
|
expectedKey: "HTTPS||443",
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
assert.Equal(t, test.expectedKey, makeListenerKey(test.listener))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_referenceGrantMatchesFrom(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
referenceGrant gatev1.ReferenceGrant
|
|
group string
|
|
kind string
|
|
namespace string
|
|
expectedResult bool
|
|
}{
|
|
{
|
|
desc: "matches",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
From: []gatev1.ReferenceGrantFrom{
|
|
{
|
|
Group: "correct-group",
|
|
Kind: "correct-kind",
|
|
Namespace: "correct-namespace",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "correct-group",
|
|
kind: "correct-kind",
|
|
namespace: "correct-namespace",
|
|
expectedResult: true,
|
|
},
|
|
{
|
|
desc: "empty group matches core",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
From: []gatev1.ReferenceGrantFrom{
|
|
{
|
|
Group: "",
|
|
Kind: "correct-kind",
|
|
Namespace: "correct-namespace",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "core",
|
|
kind: "correct-kind",
|
|
namespace: "correct-namespace",
|
|
expectedResult: true,
|
|
},
|
|
{
|
|
desc: "wrong group",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
From: []gatev1.ReferenceGrantFrom{
|
|
{
|
|
Group: "wrong-group",
|
|
Kind: "correct-kind",
|
|
Namespace: "correct-namespace",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "correct-group",
|
|
kind: "correct-kind",
|
|
namespace: "correct-namespace",
|
|
expectedResult: false,
|
|
},
|
|
{
|
|
desc: "wrong kind",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
From: []gatev1.ReferenceGrantFrom{
|
|
{
|
|
Group: "correct-group",
|
|
Kind: "wrong-kind",
|
|
Namespace: "correct-namespace",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "correct-group",
|
|
kind: "correct-kind",
|
|
namespace: "correct-namespace",
|
|
expectedResult: false,
|
|
},
|
|
{
|
|
desc: "wrong namespace",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
From: []gatev1.ReferenceGrantFrom{
|
|
{
|
|
Group: "correct-group",
|
|
Kind: "correct-kind",
|
|
Namespace: "wrong-namespace",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "correct-group",
|
|
kind: "correct-kind",
|
|
namespace: "correct-namespace",
|
|
expectedResult: false,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
assert.Equal(t, test.expectedResult, referenceGrantMatchesFrom(&test.referenceGrant, test.group, test.kind, test.namespace))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_referenceGrantMatchesTo(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
referenceGrant gatev1.ReferenceGrant
|
|
group string
|
|
kind string
|
|
name string
|
|
expectedResult bool
|
|
}{
|
|
{
|
|
desc: "matches",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
To: []gatev1.ReferenceGrantTo{
|
|
{
|
|
Group: "correct-group",
|
|
Kind: "correct-kind",
|
|
Name: new(gatev1.ObjectName("correct-name")),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "correct-group",
|
|
kind: "correct-kind",
|
|
name: "correct-name",
|
|
expectedResult: true,
|
|
},
|
|
{
|
|
desc: "matches without name",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
To: []gatev1.ReferenceGrantTo{
|
|
{
|
|
Group: "correct-group",
|
|
Kind: "correct-kind",
|
|
Name: nil,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "correct-group",
|
|
kind: "correct-kind",
|
|
name: "some-name",
|
|
expectedResult: true,
|
|
},
|
|
{
|
|
desc: "empty group matches core",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
To: []gatev1.ReferenceGrantTo{
|
|
{
|
|
Group: "",
|
|
Kind: "correct-kind",
|
|
Name: new(gatev1.ObjectName("correct-name")),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "core",
|
|
kind: "correct-kind",
|
|
name: "correct-name",
|
|
expectedResult: true,
|
|
},
|
|
{
|
|
desc: "wrong group",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
To: []gatev1.ReferenceGrantTo{
|
|
{
|
|
Group: "wrong-group",
|
|
Kind: "correct-kind",
|
|
Name: new(gatev1.ObjectName("correct-name")),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "correct-group",
|
|
kind: "correct-kind",
|
|
name: "correct-namespace",
|
|
expectedResult: false,
|
|
},
|
|
{
|
|
desc: "wrong kind",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
To: []gatev1.ReferenceGrantTo{
|
|
{
|
|
Group: "correct-group",
|
|
Kind: "wrong-kind",
|
|
Name: new(gatev1.ObjectName("correct-name")),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "correct-group",
|
|
kind: "correct-kind",
|
|
name: "correct-name",
|
|
expectedResult: false,
|
|
},
|
|
{
|
|
desc: "wrong name",
|
|
referenceGrant: gatev1.ReferenceGrant{
|
|
Spec: gatev1.ReferenceGrantSpec{
|
|
To: []gatev1.ReferenceGrantTo{
|
|
{
|
|
Group: "correct-group",
|
|
Kind: "correct-kind",
|
|
Name: new(gatev1.ObjectName("wrong-name")),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
group: "correct-group",
|
|
kind: "correct-kind",
|
|
name: "correct-name",
|
|
expectedResult: false,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
assert.Equal(t, test.expectedResult, referenceGrantMatchesTo(&test.referenceGrant, test.group, test.kind, test.name))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_gatewayAddresses(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
statusAddress *StatusAddress
|
|
paths []string
|
|
wantErr require.ErrorAssertionFunc
|
|
want []gatev1.GatewayStatusAddress
|
|
}{
|
|
{
|
|
desc: "nothing",
|
|
wantErr: require.NoError,
|
|
},
|
|
{
|
|
desc: "empty configuration",
|
|
statusAddress: &StatusAddress{},
|
|
wantErr: require.Error,
|
|
},
|
|
{
|
|
desc: "IP address",
|
|
statusAddress: &StatusAddress{
|
|
IP: "1.2.3.4",
|
|
},
|
|
wantErr: require.NoError,
|
|
want: []gatev1.GatewayStatusAddress{
|
|
{
|
|
Type: new(gatev1.IPAddressType),
|
|
Value: "1.2.3.4",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "hostname address",
|
|
statusAddress: &StatusAddress{
|
|
Hostname: "foo.bar",
|
|
},
|
|
wantErr: require.NoError,
|
|
want: []gatev1.GatewayStatusAddress{
|
|
{
|
|
Type: new(gatev1.HostnameAddressType),
|
|
Value: "foo.bar",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "service",
|
|
statusAddress: &StatusAddress{
|
|
Service: ServiceRef{
|
|
Name: "status-address",
|
|
Namespace: "default",
|
|
},
|
|
},
|
|
paths: []string{"services.yml"},
|
|
wantErr: require.NoError,
|
|
want: []gatev1.GatewayStatusAddress{
|
|
{
|
|
Type: new(gatev1.HostnameAddressType),
|
|
Value: "foo.bar",
|
|
},
|
|
{
|
|
Type: new(gatev1.IPAddressType),
|
|
Value: "1.2.3.4",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "missing service",
|
|
statusAddress: &StatusAddress{
|
|
Service: ServiceRef{
|
|
Name: "status-address2",
|
|
Namespace: "default",
|
|
},
|
|
},
|
|
wantErr: require.Error,
|
|
},
|
|
{
|
|
desc: "service without load-balancer status",
|
|
statusAddress: &StatusAddress{
|
|
Service: ServiceRef{
|
|
Name: "whoamitcp-bar",
|
|
Namespace: "bar",
|
|
},
|
|
},
|
|
paths: []string{"services.yml"},
|
|
wantErr: require.NoError,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
k8sObjects, gwObjects := readResources(t, test.paths)
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
StatusAddress: test.statusAddress,
|
|
client: client,
|
|
}
|
|
|
|
got, err := p.gatewayAddresses()
|
|
test.wantErr(t, err)
|
|
|
|
assert.Equal(t, test.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_makeGatewayStatus(t *testing.T) {
|
|
acceptedListener := func() gatewayListener {
|
|
return gatewayListener{Status: &gatev1.ListenerStatus{Name: "valid"}}
|
|
}
|
|
invalidListener := func() gatewayListener {
|
|
return gatewayListener{Status: &gatev1.ListenerStatus{
|
|
Name: "invalid",
|
|
Conditions: []metav1.Condition{{
|
|
Type: string(gatev1.ListenerConditionAccepted),
|
|
Status: metav1.ConditionFalse,
|
|
Reason: string(gatev1.ListenerReasonUnsupportedProtocol),
|
|
}},
|
|
}}
|
|
}
|
|
|
|
testCases := []struct {
|
|
desc string
|
|
infrastructure *gatev1.GatewayInfrastructure
|
|
listeners []gatewayListener
|
|
wantStatus metav1.ConditionStatus
|
|
wantReason gatev1.GatewayConditionReason
|
|
wantProgrammed metav1.ConditionStatus
|
|
}{
|
|
{
|
|
desc: "all listeners valid",
|
|
listeners: []gatewayListener{acceptedListener()},
|
|
wantStatus: metav1.ConditionTrue,
|
|
wantReason: gatev1.GatewayReasonAccepted,
|
|
wantProgrammed: metav1.ConditionTrue,
|
|
},
|
|
{
|
|
desc: "one listener valid among invalid ones",
|
|
listeners: []gatewayListener{acceptedListener(), invalidListener()},
|
|
wantStatus: metav1.ConditionTrue,
|
|
wantReason: gatev1.GatewayReasonListenersNotValid,
|
|
wantProgrammed: metav1.ConditionTrue,
|
|
},
|
|
{
|
|
desc: "no listener valid",
|
|
listeners: []gatewayListener{invalidListener()},
|
|
wantStatus: metav1.ConditionFalse,
|
|
wantReason: gatev1.GatewayReasonListenersNotValid,
|
|
wantProgrammed: metav1.ConditionFalse,
|
|
},
|
|
{
|
|
desc: "infrastructure parametersRef",
|
|
listeners: []gatewayListener{acceptedListener()},
|
|
infrastructure: &gatev1.GatewayInfrastructure{
|
|
ParametersRef: &gatev1.LocalParametersReference{
|
|
Group: "invalid.io",
|
|
Kind: "InvalidParameters",
|
|
Name: "invalid",
|
|
},
|
|
},
|
|
wantStatus: metav1.ConditionFalse,
|
|
wantReason: gatev1.GatewayReasonInvalidParameters,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
p := Provider{}
|
|
gateway := &gatev1.Gateway{Spec: gatev1.GatewaySpec{Infrastructure: test.infrastructure}}
|
|
|
|
status, _ := p.makeGatewayStatus(gateway, test.listeners, nil, slices.ContainsFunc(test.listeners, func(listener gatewayListener) bool {
|
|
return len(listener.Status.Conditions) == 0
|
|
}))
|
|
|
|
condition := meta.FindStatusCondition(status.Conditions, string(gatev1.GatewayConditionAccepted))
|
|
require.NotNil(t, condition)
|
|
assert.Equal(t, test.wantStatus, condition.Status)
|
|
assert.Equal(t, string(test.wantReason), condition.Reason)
|
|
assert.Len(t, status.Listeners, len(test.listeners))
|
|
|
|
programmed := meta.FindStatusCondition(status.Conditions, string(gatev1.GatewayConditionProgrammed))
|
|
if test.wantProgrammed == "" {
|
|
assert.Nil(t, programmed)
|
|
return
|
|
}
|
|
require.NotNil(t, programmed)
|
|
assert.Equal(t, test.wantProgrammed, programmed.Status)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_resolveFrontendValidation(t *testing.T) {
|
|
k8sObjects, gwObjects := readResources(t, []string{"frontend_validation_ca_refs.yml"})
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{client: client}
|
|
|
|
gateway := &gatev1.Gateway{
|
|
Name: "my-gateway",
|
|
Namespace: "default",
|
|
Generation: 1,
|
|
}
|
|
|
|
testCases := []struct {
|
|
desc string
|
|
validation *gatev1.FrontendTLSValidation
|
|
expected frontendValidation
|
|
}{
|
|
{
|
|
desc: "nil validation returns an empty result",
|
|
validation: nil,
|
|
expected: frontendValidation{},
|
|
},
|
|
{
|
|
desc: "a valid ConfigMap ref is resolved",
|
|
validation: &gatev1.FrontendTLSValidation{
|
|
Mode: gatev1.AllowValidOnly,
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Kind: "ConfigMap", Name: "ca-configmap"},
|
|
},
|
|
},
|
|
expected: frontendValidation{
|
|
clientAuth: &tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA1"},
|
|
ClientAuthType: tls.RequireAndVerifyClientCert,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "AllowInsecureFallback mode maps to RequestClientCert",
|
|
validation: &gatev1.FrontendTLSValidation{
|
|
Mode: gatev1.AllowInsecureFallback,
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Kind: "ConfigMap", Name: "ca-configmap"},
|
|
},
|
|
},
|
|
expected: frontendValidation{
|
|
clientAuth: &tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA1"},
|
|
ClientAuthType: tls.RequestClientCert,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "unsupported kind is rejected and no valid CA certificate remains",
|
|
validation: &gatev1.FrontendTLSValidation{
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Kind: "Service", Name: "whoami"},
|
|
},
|
|
},
|
|
expected: frontendValidation{
|
|
errCondition: &metav1.Condition{
|
|
Type: string(gatev1.ListenerConditionResolvedRefs),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonInvalidCACertificateKind),
|
|
Message: "Unsupported CACertificateRef group/kind: /Service",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "unsupported group is rejected",
|
|
validation: &gatev1.FrontendTLSValidation{
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Group: "example.com", Kind: "ConfigMap", Name: "ca-configmap"},
|
|
},
|
|
},
|
|
expected: frontendValidation{
|
|
errCondition: &metav1.Condition{
|
|
Type: string(gatev1.ListenerConditionResolvedRefs),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonInvalidCACertificateKind),
|
|
Message: "Unsupported CACertificateRef group/kind: example.com/ConfigMap",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "cross-namespace ref without a ReferenceGrant is rejected",
|
|
validation: &gatev1.FrontendTLSValidation{
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Kind: "ConfigMap", Name: "ca-configmap-not-granted", Namespace: new(gatev1.Namespace("other-ns"))},
|
|
},
|
|
},
|
|
expected: frontendValidation{
|
|
errCondition: &metav1.Condition{
|
|
Type: string(gatev1.ListenerConditionResolvedRefs),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonRefNotPermitted),
|
|
Message: "Cannot reference CACertificateRef: /ConfigMap: missing ReferenceGrant",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "cross-namespace ref with a matching ReferenceGrant is resolved",
|
|
validation: &gatev1.FrontendTLSValidation{
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Kind: "ConfigMap", Name: "ca-configmap-granted", Namespace: new(gatev1.Namespace("other-ns"))},
|
|
},
|
|
},
|
|
expected: frontendValidation{
|
|
clientAuth: &tls.ClientAuth{
|
|
CAFiles: []types.FileOrContent{"CA4"},
|
|
ClientAuthType: tls.RequireAndVerifyClientCert,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "Secret ref is rejected as an unsupported kind",
|
|
validation: &gatev1.FrontendTLSValidation{
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Kind: "Secret", Name: "ca-secret"},
|
|
},
|
|
},
|
|
expected: frontendValidation{
|
|
errCondition: &metav1.Condition{
|
|
Type: string(gatev1.ListenerConditionResolvedRefs),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonInvalidCACertificateKind),
|
|
Message: "Unsupported CACertificateRef group/kind: /Secret",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "unresolvable ConfigMap is rejected",
|
|
validation: &gatev1.FrontendTLSValidation{
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Kind: "ConfigMap", Name: "does-not-exist"},
|
|
},
|
|
},
|
|
expected: frontendValidation{
|
|
errCondition: &metav1.Condition{
|
|
Type: string(gatev1.ListenerConditionResolvedRefs),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonInvalidCACertificateRef),
|
|
Message: `Cannot resolve configmap: default/does-not-exist: configmap "does-not-exist" not found`,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "ConfigMap missing the ca.crt key is rejected",
|
|
validation: &gatev1.FrontendTLSValidation{
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Kind: "ConfigMap", Name: "ca-configmap-empty"},
|
|
},
|
|
},
|
|
expected: frontendValidation{
|
|
errCondition: &metav1.Condition{
|
|
Type: string(gatev1.ListenerConditionResolvedRefs),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonInvalidCACertificateRef),
|
|
Message: "Cannot find ca.crt: ConfigMap default/ca-configmap-empty",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "multiple refs are rejected",
|
|
validation: &gatev1.FrontendTLSValidation{
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Kind: "ConfigMap", Name: "ca-configmap"},
|
|
{Kind: "ConfigMap", Name: "ca-configmap-granted", Namespace: new(gatev1.Namespace("other-ns"))},
|
|
},
|
|
},
|
|
expected: frontendValidation{
|
|
errCondition: &metav1.Condition{
|
|
Type: string(gatev1.ListenerConditionResolvedRefs),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonInvalidCACertificateRef),
|
|
Message: "Unsupported number of CACertificateRefs: 2, only one reference is supported",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
got := p.resolveFrontendValidation(gateway, test.validation)
|
|
|
|
// LastTransitionTime is set with metav1.Now() and is not relevant to this test.
|
|
if got.errCondition != nil {
|
|
got.errCondition.LastTransitionTime = metav1.Time{}
|
|
}
|
|
|
|
assert.Equal(t, test.expected, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_loadGatewayListeners(t *testing.T) {
|
|
k8sObjects, gwObjects := readResources(t, []string{"frontend_validation_ca_refs.yml"})
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
<-eventCh
|
|
|
|
p := Provider{
|
|
EntryPoints: map[string]Entrypoint{"websecure": {Address: ":443"}},
|
|
client: client,
|
|
}
|
|
|
|
newGateway := func(caCertificateRefs []gatev1.ObjectReference) *gatev1.Gateway {
|
|
return &gatev1.Gateway{
|
|
Name: "my-gateway",
|
|
Namespace: "default",
|
|
Generation: 1,
|
|
Spec: gatev1.GatewaySpec{
|
|
TLS: &gatev1.GatewayTLSConfig{
|
|
Frontend: &gatev1.FrontendTLSConfig{
|
|
Default: gatev1.TLSConfig{
|
|
Validation: &gatev1.FrontendTLSValidation{
|
|
Mode: gatev1.AllowValidOnly,
|
|
CACertificateRefs: caCertificateRefs,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Listeners: []gatev1.Listener{
|
|
{
|
|
Name: "https",
|
|
Protocol: gatev1.HTTPSProtocolType,
|
|
Port: 443,
|
|
TLS: &gatev1.ListenerTLSConfig{
|
|
CertificateRefs: []gatev1.SecretObjectReference{
|
|
{Kind: new(gatev1.Kind("Secret")), Group: new(gatev1.Group("")), Name: "tls-secret"},
|
|
},
|
|
},
|
|
AllowedRoutes: &gatev1.AllowedRoutes{
|
|
Namespaces: &gatev1.RouteNamespaces{From: new(gatev1.NamespacesFromSame)},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
testCases := []struct {
|
|
desc string
|
|
gateway *gatev1.Gateway
|
|
expectedAttached bool
|
|
expectedConditions []metav1.Condition
|
|
}{
|
|
{
|
|
desc: "fully resolved CACertificateRefs attaches the Listener with no error condition",
|
|
gateway: newGateway([]gatev1.ObjectReference{
|
|
{Kind: "ConfigMap", Name: "ca-configmap"},
|
|
}),
|
|
expectedAttached: true,
|
|
expectedConditions: []metav1.Condition{},
|
|
},
|
|
{
|
|
desc: "multiple CACertificateRefs are rejected and the Listener is not attached",
|
|
gateway: newGateway([]gatev1.ObjectReference{
|
|
{Kind: "ConfigMap", Name: "ca-configmap"},
|
|
{Kind: "ConfigMap", Name: "ca-configmap-empty"},
|
|
}),
|
|
expectedAttached: false,
|
|
expectedConditions: []metav1.Condition{
|
|
{
|
|
Type: string(gatev1.ListenerConditionResolvedRefs),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonInvalidCACertificateRef),
|
|
Message: "Unsupported number of CACertificateRefs: 2, only one reference is supported",
|
|
},
|
|
{
|
|
Type: string(gatev1.ListenerConditionAccepted),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonNoValidCACertificate),
|
|
Message: "No valid CA certificate found in CACertificateRefs",
|
|
},
|
|
{
|
|
Type: string(gatev1.ListenerConditionProgrammed),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonInvalid),
|
|
Message: "Invalid CA certificate configuration",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "no valid CACertificateRefs reports NoValidCACertificate and the Listener is not attached",
|
|
gateway: newGateway([]gatev1.ObjectReference{
|
|
{Kind: "Service", Name: "whoami"},
|
|
}),
|
|
expectedAttached: false,
|
|
expectedConditions: []metav1.Condition{
|
|
{
|
|
Type: string(gatev1.ListenerConditionResolvedRefs),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonInvalidCACertificateKind),
|
|
Message: "Unsupported CACertificateRef group/kind: /Service",
|
|
},
|
|
{
|
|
Type: string(gatev1.ListenerConditionAccepted),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonNoValidCACertificate),
|
|
Message: "No valid CA certificate found in CACertificateRefs",
|
|
},
|
|
{
|
|
Type: string(gatev1.ListenerConditionProgrammed),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(gatev1.ListenerReasonInvalid),
|
|
Message: "Invalid CA certificate configuration",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
conf := &dynamic.Configuration{TLS: &dynamic.TLSConfiguration{}}
|
|
listeners := p.loadGatewayListeners(t.Context(), test.gateway, nil, newListenerClaims(map[gatev1.PortNumber]*tls.ClientAuth{}), conf)
|
|
|
|
require.Len(t, listeners, 1)
|
|
assert.Equal(t, test.expectedAttached, listeners[0].Attached)
|
|
|
|
// LastTransitionTime is set with metav1.Now() and is not relevant to this test.
|
|
for i := range listeners[0].Status.Conditions {
|
|
listeners[0].Status.Conditions[i].LastTransitionTime = metav1.Time{}
|
|
}
|
|
assert.Equal(t, test.expectedConditions, listeners[0].Status.Conditions)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_loadGatewayListeners_frontendValidationConflict(t *testing.T) {
|
|
k8sObjects, gwObjects := readResources(t, []string{"frontend_validation_ca_refs.yml"})
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
<-eventCh
|
|
|
|
p := Provider{
|
|
EntryPoints: map[string]Entrypoint{"websecure": {Address: ":443"}},
|
|
client: client,
|
|
}
|
|
|
|
newValidation := func(caConfigMap string, mode gatev1.FrontendValidationModeType) *gatev1.FrontendTLSValidation {
|
|
return &gatev1.FrontendTLSValidation{
|
|
Mode: mode,
|
|
CACertificateRefs: []gatev1.ObjectReference{
|
|
{Kind: "ConfigMap", Name: gatev1.ObjectName(caConfigMap)},
|
|
},
|
|
}
|
|
}
|
|
|
|
newGateway := func(name string, hostname *gatev1.Hostname, validation *gatev1.FrontendTLSValidation) *gatev1.Gateway {
|
|
return &gatev1.Gateway{
|
|
Name: name,
|
|
Namespace: "default",
|
|
Generation: 1,
|
|
Spec: gatev1.GatewaySpec{
|
|
TLS: &gatev1.GatewayTLSConfig{
|
|
Frontend: &gatev1.FrontendTLSConfig{
|
|
Default: gatev1.TLSConfig{
|
|
Validation: validation,
|
|
},
|
|
},
|
|
},
|
|
Listeners: []gatev1.Listener{
|
|
{
|
|
Name: "https",
|
|
Protocol: gatev1.HTTPSProtocolType,
|
|
Port: 443,
|
|
Hostname: hostname,
|
|
TLS: &gatev1.ListenerTLSConfig{
|
|
CertificateRefs: []gatev1.SecretObjectReference{
|
|
{Kind: new(gatev1.Kind("Secret")), Group: new(gatev1.Group("")), Name: "tls-secret"},
|
|
},
|
|
},
|
|
AllowedRoutes: &gatev1.AllowedRoutes{
|
|
Namespaces: &gatev1.RouteNamespaces{From: new(gatev1.NamespacesFromSame)},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
conflictedConditions := []metav1.Condition{
|
|
{
|
|
Type: string(gatev1.ListenerConditionAccepted),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(listenerReasonFrontendValidationConflict),
|
|
Message: "An older Gateway already applies a different frontend validation on this port",
|
|
},
|
|
{
|
|
Type: string(gatev1.ListenerConditionProgrammed),
|
|
Status: metav1.ConditionFalse,
|
|
ObservedGeneration: 1,
|
|
Reason: string(listenerReasonFrontendValidationConflict),
|
|
Message: "An older Gateway already applies a different frontend validation on this port",
|
|
},
|
|
{
|
|
Type: string(gatev1.ListenerConditionConflicted),
|
|
Status: metav1.ConditionTrue,
|
|
ObservedGeneration: 1,
|
|
Reason: string(listenerReasonFrontendValidationConflict),
|
|
Message: "An older Gateway already applies a different frontend validation on this port",
|
|
},
|
|
}
|
|
|
|
testCases := []struct {
|
|
desc string
|
|
hostname *gatev1.Hostname
|
|
validation *gatev1.FrontendTLSValidation
|
|
expectedAttached bool
|
|
expectedConditions []metav1.Condition
|
|
}{
|
|
{
|
|
desc: "the same validation is shared",
|
|
validation: newValidation("ca-configmap", gatev1.AllowValidOnly),
|
|
expectedAttached: true,
|
|
expectedConditions: []metav1.Condition{},
|
|
},
|
|
{
|
|
desc: "the same validation is shared on another hostname",
|
|
hostname: new(gatev1.Hostname("foo.com")),
|
|
validation: newValidation("ca-configmap", gatev1.AllowValidOnly),
|
|
expectedAttached: true,
|
|
expectedConditions: []metav1.Condition{},
|
|
},
|
|
{
|
|
desc: "a different CA is conflicted",
|
|
validation: newValidation("ca-configmap-2", gatev1.AllowValidOnly),
|
|
expectedConditions: conflictedConditions,
|
|
},
|
|
{
|
|
desc: "a different CA on another hostname is conflicted",
|
|
hostname: new(gatev1.Hostname("foo.com")),
|
|
validation: newValidation("ca-configmap-2", gatev1.AllowValidOnly),
|
|
expectedConditions: conflictedConditions,
|
|
},
|
|
{
|
|
desc: "a different mode is conflicted",
|
|
validation: newValidation("ca-configmap", gatev1.AllowInsecureFallback),
|
|
expectedConditions: conflictedConditions,
|
|
},
|
|
{
|
|
desc: "no validation is conflicted",
|
|
validation: nil,
|
|
expectedConditions: conflictedConditions,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
frontendValidations := map[gatev1.PortNumber]*tls.ClientAuth{}
|
|
conf := &dynamic.Configuration{TLS: &dynamic.TLSConfiguration{}}
|
|
|
|
gateway := newGateway("my-gateway", nil, newValidation("ca-configmap", gatev1.AllowValidOnly))
|
|
listeners := p.loadGatewayListeners(t.Context(), gateway, nil, newListenerClaims(frontendValidations), conf)
|
|
require.Len(t, listeners, 1)
|
|
require.True(t, listeners[0].Attached)
|
|
|
|
gateway = newGateway("my-other-gateway", test.hostname, test.validation)
|
|
listeners = p.loadGatewayListeners(t.Context(), gateway, nil, newListenerClaims(frontendValidations), conf)
|
|
require.Len(t, listeners, 1)
|
|
assert.Equal(t, test.expectedAttached, listeners[0].Attached)
|
|
|
|
// LastTransitionTime is set with metav1.Now() and is not relevant to this test.
|
|
for i := range listeners[0].Status.Conditions {
|
|
listeners[0].Status.Conditions[i].LastTransitionTime = metav1.Time{}
|
|
}
|
|
assert.Equal(t, test.expectedConditions, listeners[0].Status.Conditions)
|
|
|
|
// The certificate of a conflicted listener does not reach the TLS store.
|
|
expectedCertificates := 1
|
|
if test.expectedAttached {
|
|
expectedCertificates = 2
|
|
}
|
|
assert.Len(t, conf.TLS.Certificates, expectedCertificates)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_isCrossProviderNamespaceAllowed(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
allowList []string
|
|
namespace string
|
|
want bool
|
|
}{
|
|
{desc: "nil allowList allows any namespace", allowList: nil, namespace: "ns-a", want: true},
|
|
{desc: "empty allowList denies every namespace", allowList: []string{}, namespace: "ns-a", want: false},
|
|
{desc: "namespace in allowList is accepted", allowList: []string{"ns-a"}, namespace: "ns-a", want: true},
|
|
{desc: "namespace not in allowList is rejected", allowList: []string{"ns-b"}, namespace: "ns-a", want: false},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
got := isCrossProviderNamespaceAllowed(test.allowList, test.namespace)
|
|
assert.Equal(t, test.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test_makeListenerRouterName checks that hostnames normalizing to the same label
|
|
// do not collide, which would collapse the SNI scope they are meant to isolate.
|
|
func Test_makeListenerRouterName(t *testing.T) {
|
|
uniq := uniqListener{epName: "web", protocol: gatev1.HTTPProtocolType}
|
|
|
|
first := makeListenerRouterName(uniq, "*.example.com")
|
|
second := makeListenerRouterName(uniq, "example.com")
|
|
|
|
assert.NotEqual(t, first, second)
|
|
}
|
|
|
|
// TestCrossProviderNamespaces_HTTPRoute verifies that the
|
|
// CrossProviderNamespaces option gates `@otherProvider` TraefikService
|
|
// backendRefs declared on a Gateway HTTPRoute. The check is anchored on the
|
|
// HTTPRoute's namespace; when the route is rejected, the whole router is
|
|
// dropped from the dynamic configuration.
|
|
func TestCrossProviderNamespaces_HTTPRoute(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
fixture string
|
|
crossProviderNamespaces []string
|
|
wantError bool
|
|
}{
|
|
{desc: "nil: cross-provider TraefikService backendRefs accepted (backward compatible)", fixture: "httproute/simple_cross_provider.yml", crossProviderNamespaces: nil, wantError: false},
|
|
{desc: "empty list: cross-provider TraefikService backendRefs are rejected, route dropped", fixture: "httproute/simple_cross_provider.yml", crossProviderNamespaces: []string{}, wantError: true},
|
|
{desc: "namespace allowed: cross-provider TraefikService backendRefs accepted", fixture: "httproute/simple_cross_provider.yml", crossProviderNamespaces: []string{"default"}, wantError: false},
|
|
{desc: "namespace not allowed: cross-provider TraefikService backendRefs rejected, route dropped", fixture: "httproute/simple_cross_provider.yml", crossProviderNamespaces: []string{"other"}, wantError: true},
|
|
{desc: "namespace provided with cross-provider backendRef, route dropped", fixture: "httproute/invalid_cross_provider.yml", crossProviderNamespaces: []string{"other"}, wantError: true},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
k8sObjects, gwObjects := readResources(t, []string{"services.yml", test.fixture})
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: map[string]Entrypoint{"web": {Address: ":80"}},
|
|
CrossProviderNamespaces: test.crossProviderNamespaces,
|
|
client: client,
|
|
}
|
|
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
router, ok := conf.HTTP.Routers["httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-799bcbf0c2317c5d1c93"]
|
|
require.True(t, ok)
|
|
|
|
service, ok := conf.HTTP.Services[router.Service]
|
|
require.True(t, ok)
|
|
require.NotNil(t, service.Weighted)
|
|
require.Len(t, service.Weighted.Services, 2)
|
|
|
|
var hasError bool
|
|
for _, wrrService := range service.Weighted.Services {
|
|
// Whenever a service fails to be loaded, a placeholder service is added to the WRR to server a 500 status code.
|
|
if wrrService.Status != nil && *wrrService.Status == http.StatusInternalServerError {
|
|
hasError = true
|
|
break
|
|
}
|
|
}
|
|
|
|
assert.Equal(t, test.wantError, hasError)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestCrossProviderNamespaces_TCPRoute verifies that the option also gates
|
|
// cross-provider TraefikService backendRefs declared on a Gateway TCPRoute.
|
|
func TestCrossProviderNamespaces_TCPRoute(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
fixture string
|
|
crossProviderNamespaces []string
|
|
wantError bool
|
|
}{
|
|
{desc: "nil: cross-provider TraefikService backendRefs accepted (backward compatible)", fixture: "tcproute/simple_cross_provider.yml", crossProviderNamespaces: nil, wantError: false},
|
|
{desc: "empty list: cross-provider TraefikService backendRefs are rejected, route dropped", fixture: "tcproute/simple_cross_provider.yml", crossProviderNamespaces: []string{}, wantError: true},
|
|
{desc: "namespace allowed: cross-provider TraefikService backendRefs accepted", fixture: "tcproute/simple_cross_provider.yml", crossProviderNamespaces: []string{"default"}, wantError: false},
|
|
{desc: "namespace not allowed: cross-provider TraefikService backendRefs rejected, route dropped", fixture: "tcproute/simple_cross_provider.yml", crossProviderNamespaces: []string{"other"}, wantError: true},
|
|
{desc: "namespace provided with cross-provider backendRef, route dropped", fixture: "tcproute/invalid_cross_provider.yml", crossProviderNamespaces: []string{"other"}, wantError: true},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
k8sObjects, gwObjects := readResources(t, []string{"services.yml", test.fixture})
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: map[string]Entrypoint{"tcp": {Address: ":9000"}},
|
|
CrossProviderNamespaces: test.crossProviderNamespaces,
|
|
client: client,
|
|
}
|
|
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
router, ok := conf.TCP.Routers["tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-5840f3c3c21dcf0402da"]
|
|
require.True(t, ok)
|
|
|
|
service, ok := conf.TCP.Services[router.Service]
|
|
require.True(t, ok)
|
|
require.NotNil(t, service.Weighted)
|
|
require.Len(t, service.Weighted.Services, 2)
|
|
|
|
var hasError bool
|
|
for _, wrrService := range service.Weighted.Services {
|
|
if strings.Contains(wrrService.Name, "@") {
|
|
continue
|
|
}
|
|
|
|
lbService, ok := conf.TCP.Services[wrrService.Name]
|
|
require.True(t, ok)
|
|
require.NotNil(t, lbService)
|
|
require.NotNil(t, lbService.LoadBalancer)
|
|
|
|
if len(lbService.LoadBalancer.Servers) == 0 {
|
|
hasError = true
|
|
}
|
|
}
|
|
|
|
assert.Equal(t, test.wantError, hasError)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestCrossProviderNamespaces_TLSRoute verifies that the option also gates
|
|
// cross-provider TraefikService backendRefs declared on a Gateway TLSRoute.
|
|
func TestCrossProviderNamespaces_TLSRoute(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
fixture string
|
|
crossProviderNamespaces []string
|
|
wantError bool
|
|
}{
|
|
{desc: "nil: cross-provider TraefikService backendRefs accepted (backward compatible)", fixture: "tlsroute/simple_cross_provider.yml", crossProviderNamespaces: nil, wantError: false},
|
|
{desc: "empty list: cross-provider TraefikService backendRefs are rejected, route dropped", fixture: "tlsroute/simple_cross_provider.yml", crossProviderNamespaces: []string{}, wantError: true},
|
|
{desc: "namespace allowed: cross-provider TraefikService backendRefs accepted", fixture: "tlsroute/simple_cross_provider.yml", crossProviderNamespaces: []string{"default"}, wantError: false},
|
|
{desc: "namespace not allowed: cross-provider TraefikService backendRefs rejected, route dropped", fixture: "tlsroute/simple_cross_provider.yml", crossProviderNamespaces: []string{"other"}, wantError: true},
|
|
{desc: "namespace provided with cross-provider backendRef, route dropped", fixture: "tlsroute/invalid_cross_provider.yml", crossProviderNamespaces: []string{"other"}, wantError: true},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
k8sObjects, gwObjects := readResources(t, []string{"services.yml", test.fixture})
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 || len(gwObjects) > 0 {
|
|
// just wait for the first event
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{
|
|
EntryPoints: map[string]Entrypoint{"tls": {Address: ":9000"}},
|
|
CrossProviderNamespaces: test.crossProviderNamespaces,
|
|
client: client,
|
|
}
|
|
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
assert.NoError(t, err)
|
|
|
|
router, ok := conf.TCP.Routers["tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-efc0f8d903baa9fb6592"]
|
|
require.True(t, ok)
|
|
|
|
service, ok := conf.TCP.Services[router.Service]
|
|
require.True(t, ok)
|
|
require.NotNil(t, service.Weighted)
|
|
require.Len(t, service.Weighted.Services, 2)
|
|
|
|
var hasError bool
|
|
for _, wrrService := range service.Weighted.Services {
|
|
if strings.Contains(wrrService.Name, "@") {
|
|
continue
|
|
}
|
|
|
|
lbService, ok := conf.TCP.Services[wrrService.Name]
|
|
require.True(t, ok)
|
|
require.NotNil(t, lbService)
|
|
require.NotNil(t, lbService.LoadBalancer)
|
|
|
|
if len(lbService.LoadBalancer.Servers) == 0 {
|
|
hasError = true
|
|
}
|
|
}
|
|
|
|
assert.Equal(t, test.wantError, hasError)
|
|
})
|
|
}
|
|
}
|
|
|
|
func findCondition(conditions []metav1.Condition, conditionType gatev1.RouteConditionType) *metav1.Condition {
|
|
for i := range conditions {
|
|
if conditions[i].Type == string(conditionType) {
|
|
return &conditions[i]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// We cannot use the gateway-api fake.NewClientset due to Gateway being pluralized as "gatewaies" instead of "gateways".
|
|
func newGatewaySimpleClientSet(t *testing.T, objects ...runtime.Object) *gatefake.Clientset {
|
|
t.Helper()
|
|
|
|
client := gatefake.NewSimpleClientset(objects...)
|
|
for _, object := range objects {
|
|
gateway, ok := object.(*gatev1.Gateway)
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
_, err := client.GatewayV1().Gateways(gateway.Namespace).Create(t.Context(), gateway, metav1.CreateOptions{})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
return client
|
|
}
|
|
|
|
func Test_loadConfigurationFromGateways_TLSCertificatesOrder(t *testing.T) {
|
|
k8sObjects, gwObjects := readResources(t, []string{"multiple_gateways_tls_certificates.yml"})
|
|
|
|
client := newClientImpl(kubefake.NewClientset(k8sObjects...), newGatewaySimpleClientSet(t, gwObjects...))
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
// just wait for the first event
|
|
<-eventCh
|
|
|
|
p := Provider{
|
|
EntryPoints: map[string]Entrypoint{"websecure": {Address: ":443"}},
|
|
client: client,
|
|
}
|
|
|
|
// Gateways are listed from a map, so build the configuration several times to
|
|
// make sure the certificates do not follow the iteration order.
|
|
conf, _, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
var commonNames []string
|
|
for _, cert := range conf.TLS.Certificates {
|
|
commonNames = append(commonNames, certificateCommonName(t, cert.Certificate.CertFile))
|
|
}
|
|
|
|
assert.Equal(t, []string{"bar.example.com", "foo.example.com", "default-b.example.com", "default-a.example.com"}, commonNames)
|
|
}
|
|
|
|
func Test_loadConfigurationFromGateways_BackendTLSPolicyAncestorNamespace(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
path string
|
|
entryPoints map[string]Entrypoint
|
|
sectionName gatev1.SectionName
|
|
}{
|
|
{
|
|
desc: "HTTPRoute",
|
|
path: "httproute/with_backend_tls_policy_cross_namespace.yml",
|
|
entryPoints: map[string]Entrypoint{"web": {Address: ":80"}},
|
|
sectionName: "http",
|
|
},
|
|
{
|
|
desc: "GRPCRoute",
|
|
path: "grpcroute/with_backend_tls_policy_cross_namespace.yml",
|
|
entryPoints: map[string]Entrypoint{"web": {Address: ":80"}},
|
|
sectionName: "web",
|
|
},
|
|
{
|
|
desc: "TLSRoute",
|
|
path: "tlsroute/with_backend_tls_policy_cross_namespace.yml",
|
|
entryPoints: map[string]Entrypoint{"tls": {Address: ":9001"}},
|
|
sectionName: "tls",
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
k8sObjects, gwObjects := readResources(t, []string{"services.yml", test.path})
|
|
|
|
gwClient := newGatewaySimpleClientSet(t, gwObjects...)
|
|
client := newClientImpl(kubefake.NewClientset(k8sObjects...), gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
// just wait for the first event
|
|
<-eventCh
|
|
|
|
p := Provider{
|
|
EntryPoints: test.entryPoints,
|
|
client: client,
|
|
}
|
|
|
|
_, statusReport, err := p.loadConfigurationFromGateways(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
statusReport.Flush(t.Context(), client)
|
|
|
|
policy, err := gwClient.GatewayV1().BackendTLSPolicies("bar").Get(t.Context(), "policy-1", metav1.GetOptions{})
|
|
require.NoError(t, err)
|
|
require.Len(t, policy.Status.Ancestors, 1)
|
|
|
|
assert.Equal(t, gatev1.ParentReference{
|
|
Group: new(gatev1.Group(groupGateway)),
|
|
Kind: new(gatev1.Kind(kindGateway)),
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
Name: "my-gateway",
|
|
SectionName: new(test.sectionName),
|
|
}, policy.Status.Ancestors[0].AncestorRef)
|
|
})
|
|
}
|
|
}
|
|
|
|
func certificateCommonName(t *testing.T, certFile types.FileOrContent) string {
|
|
t.Helper()
|
|
|
|
block, _ := pem.Decode([]byte(certFile))
|
|
require.NotNil(t, block)
|
|
|
|
cert, err := x509.ParseCertificate(block.Bytes)
|
|
require.NoError(t, err)
|
|
|
|
return cert.Subject.CommonName
|
|
}
|
|
|
|
func readResources(t *testing.T, paths []string) ([]runtime.Object, []runtime.Object) {
|
|
t.Helper()
|
|
|
|
var k8sObjects []runtime.Object
|
|
var gwObjects []runtime.Object
|
|
for _, path := range paths {
|
|
yamlContent, err := os.ReadFile(filepath.FromSlash("./fixtures/" + path))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
objects := k8s.MustParseYaml(yamlContent)
|
|
for _, obj := range objects {
|
|
switch obj.GetObjectKind().GroupVersionKind().Group {
|
|
case "gateway.networking.k8s.io":
|
|
gwObjects = append(gwObjects, obj)
|
|
default:
|
|
k8sObjects = append(k8sObjects, obj)
|
|
}
|
|
}
|
|
}
|
|
|
|
return k8sObjects, gwObjects
|
|
}
|
|
|
|
func Test_listenerSetRefsGateway(t *testing.T) {
|
|
gw := &gatev1.Gateway{
|
|
Name: "my-gw",
|
|
Namespace: "default",
|
|
}
|
|
|
|
testCases := []struct {
|
|
desc string
|
|
ls *gatev1.ListenerSet
|
|
expected bool
|
|
}{
|
|
{
|
|
desc: "Matching reference",
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "my-ls",
|
|
Namespace: "default",
|
|
Spec: gatev1.ListenerSetSpec{
|
|
ParentRef: gatev1.ParentGatewayReference{
|
|
Name: "my-gw",
|
|
},
|
|
},
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
desc: "Wrong name",
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "my-ls",
|
|
Namespace: "default",
|
|
Spec: gatev1.ListenerSetSpec{
|
|
ParentRef: gatev1.ParentGatewayReference{
|
|
Name: "other-gw",
|
|
},
|
|
},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
desc: "Wrong namespace",
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "my-ls",
|
|
Namespace: "default",
|
|
Spec: gatev1.ListenerSetSpec{
|
|
ParentRef: gatev1.ParentGatewayReference{
|
|
Name: "my-gw",
|
|
Namespace: new(gatev1.Namespace("other")),
|
|
},
|
|
},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
desc: "Cross-namespace matching",
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "my-ls",
|
|
Namespace: "other",
|
|
Spec: gatev1.ListenerSetSpec{
|
|
ParentRef: gatev1.ParentGatewayReference{
|
|
Name: "my-gw",
|
|
Namespace: new(gatev1.Namespace("default")),
|
|
},
|
|
},
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
desc: "Wrong group",
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "my-ls",
|
|
Namespace: "default",
|
|
Spec: gatev1.ListenerSetSpec{
|
|
ParentRef: gatev1.ParentGatewayReference{
|
|
Group: new(gatev1.Group("wrong.group")),
|
|
Name: "my-gw",
|
|
},
|
|
},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
desc: "Wrong kind",
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "my-ls",
|
|
Namespace: "default",
|
|
Spec: gatev1.ListenerSetSpec{
|
|
ParentRef: gatev1.ParentGatewayReference{
|
|
Kind: new(gatev1.Kind("NotAGateway")),
|
|
Name: "my-gw",
|
|
},
|
|
},
|
|
},
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
assert.Equal(t, test.expected, listenerSetRefsGateway(test.ls, gw))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_isListenerSetAllowed(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
gw *gatev1.Gateway
|
|
ls *gatev1.ListenerSet
|
|
namespaces []*corev1.Namespace
|
|
expected bool
|
|
}{
|
|
{
|
|
desc: "Nil AllowedListeners",
|
|
gw: &gatev1.Gateway{
|
|
Name: "gw", Namespace: "default",
|
|
Spec: gatev1.GatewaySpec{},
|
|
},
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "ls", Namespace: "default",
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
desc: "Nil From",
|
|
gw: &gatev1.Gateway{
|
|
Name: "gw", Namespace: "default",
|
|
Spec: gatev1.GatewaySpec{
|
|
AllowedListeners: &gatev1.AllowedListeners{
|
|
Namespaces: &gatev1.ListenerNamespaces{},
|
|
},
|
|
},
|
|
},
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "ls", Namespace: "default",
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
desc: "FromNone",
|
|
gw: &gatev1.Gateway{
|
|
Name: "gw", Namespace: "default",
|
|
Spec: gatev1.GatewaySpec{
|
|
AllowedListeners: &gatev1.AllowedListeners{
|
|
Namespaces: &gatev1.ListenerNamespaces{
|
|
From: new(gatev1.NamespacesFromNone),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "ls", Namespace: "default",
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
desc: "FromSame - same namespace",
|
|
gw: &gatev1.Gateway{
|
|
Name: "gw", Namespace: "default",
|
|
Spec: gatev1.GatewaySpec{
|
|
AllowedListeners: &gatev1.AllowedListeners{
|
|
Namespaces: &gatev1.ListenerNamespaces{
|
|
From: new(gatev1.NamespacesFromSame),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "ls", Namespace: "default",
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
desc: "FromSame - different namespace",
|
|
gw: &gatev1.Gateway{
|
|
Name: "gw", Namespace: "default",
|
|
Spec: gatev1.GatewaySpec{
|
|
AllowedListeners: &gatev1.AllowedListeners{
|
|
Namespaces: &gatev1.ListenerNamespaces{
|
|
From: new(gatev1.NamespacesFromSame),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "ls", Namespace: "other",
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
desc: "FromAll",
|
|
gw: &gatev1.Gateway{
|
|
Name: "gw", Namespace: "default",
|
|
Spec: gatev1.GatewaySpec{
|
|
AllowedListeners: &gatev1.AllowedListeners{
|
|
Namespaces: &gatev1.ListenerNamespaces{
|
|
From: new(gatev1.NamespacesFromAll),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "ls", Namespace: "any-namespace",
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
desc: "FromSelector - matching namespace labels",
|
|
gw: &gatev1.Gateway{
|
|
Name: "gw", Namespace: "default",
|
|
Spec: gatev1.GatewaySpec{
|
|
AllowedListeners: &gatev1.AllowedListeners{
|
|
Namespaces: &gatev1.ListenerNamespaces{
|
|
From: new(gatev1.NamespacesFromSelector),
|
|
Selector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{"env": "prod"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "ls",
|
|
Namespace: "default",
|
|
},
|
|
namespaces: []*corev1.Namespace{
|
|
{
|
|
Name: "default",
|
|
Labels: map[string]string{"env": "prod"},
|
|
},
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
desc: "FromSelector - non-matching namespace labels",
|
|
gw: &gatev1.Gateway{
|
|
Name: "gw", Namespace: "default",
|
|
Spec: gatev1.GatewaySpec{
|
|
AllowedListeners: &gatev1.AllowedListeners{
|
|
Namespaces: &gatev1.ListenerNamespaces{
|
|
From: new(gatev1.NamespacesFromSelector),
|
|
Selector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{"env": "prod"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ls: &gatev1.ListenerSet{
|
|
Name: "ls",
|
|
Namespace: "default",
|
|
},
|
|
namespaces: []*corev1.Namespace{
|
|
{
|
|
Name: "default",
|
|
Labels: map[string]string{"env": "staging"},
|
|
},
|
|
},
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var k8sObjects []runtime.Object
|
|
for _, ns := range test.namespaces {
|
|
k8sObjects = append(k8sObjects, ns)
|
|
}
|
|
|
|
kubeClient := kubefake.NewClientset(k8sObjects...)
|
|
gwClient := newGatewaySimpleClientSet(t)
|
|
|
|
client := newClientImpl(kubeClient, gwClient)
|
|
|
|
eventCh, err := client.WatchAll(nil, make(chan struct{}))
|
|
require.NoError(t, err)
|
|
|
|
if len(k8sObjects) > 0 {
|
|
<-eventCh
|
|
}
|
|
|
|
p := Provider{client: client}
|
|
|
|
assert.Equal(t, test.expected, p.isListenerSetAllowed(t.Context(), test.gw, test.ls))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_makeListenerSetStatus(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
listeners []gatewayListener
|
|
parentAccepted bool
|
|
wantAccepted bool
|
|
wantAcceptedStatus metav1.ConditionStatus
|
|
wantAcceptedReason string
|
|
wantProgrammedStatus metav1.ConditionStatus
|
|
wantProgrammedReason string
|
|
wantListenerEntryCount int
|
|
// wantEntryName, when set, asserts the first listener entry's name and its entry-level Programmed condition,
|
|
// so the per-listener status is verified and not only the entry count.
|
|
wantEntryName gatev1.SectionName
|
|
wantEntryProgrammedStatus metav1.ConditionStatus
|
|
wantEntryProgrammedReason string
|
|
}{
|
|
{
|
|
desc: "All listeners valid, Gateway accepted",
|
|
listeners: []gatewayListener{
|
|
{
|
|
SectionName: "http",
|
|
ListenerSet: &gatev1.ListenerSet{Namespace: "default", Name: "my-ls"},
|
|
Status: &gatev1.ListenerStatus{
|
|
Name: "http",
|
|
SupportedKinds: []gatev1.RouteGroupKind{{Kind: "HTTPRoute", Group: new(gatev1.Group(gatev1.GroupName))}},
|
|
Conditions: []metav1.Condition{}, // No errors.
|
|
},
|
|
},
|
|
},
|
|
parentAccepted: true,
|
|
wantAccepted: true,
|
|
wantAcceptedStatus: metav1.ConditionTrue,
|
|
wantAcceptedReason: string(gatev1.ListenerSetReasonAccepted),
|
|
wantProgrammedStatus: metav1.ConditionTrue,
|
|
wantProgrammedReason: string(gatev1.ListenerSetReasonProgrammed),
|
|
wantListenerEntryCount: 1,
|
|
wantEntryName: "http",
|
|
wantEntryProgrammedStatus: metav1.ConditionTrue,
|
|
wantEntryProgrammedReason: string(gatev1.ListenerEntryReasonProgrammed),
|
|
},
|
|
{
|
|
// A parent Gateway is not accepted only when no listener serving it is valid, the ListenerSet ones included.
|
|
desc: "Gateway not accepted",
|
|
listeners: []gatewayListener{
|
|
{
|
|
SectionName: "https",
|
|
ListenerSet: &gatev1.ListenerSet{Namespace: "default", Name: "my-ls"},
|
|
Status: &gatev1.ListenerStatus{
|
|
Name: "https",
|
|
Conditions: []metav1.Condition{
|
|
{Type: string(gatev1.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, Reason: string(gatev1.ListenerReasonInvalidCertificateRef)},
|
|
{Type: string(gatev1.ListenerConditionProgrammed), Status: metav1.ConditionFalse, Reason: string(gatev1.ListenerReasonInvalid)},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
parentAccepted: false,
|
|
wantAcceptedStatus: metav1.ConditionFalse,
|
|
wantAcceptedReason: string(gatev1.ListenerSetReasonParentNotAccepted),
|
|
wantProgrammedStatus: metav1.ConditionFalse,
|
|
wantProgrammedReason: "ParentNotProgrammed",
|
|
wantListenerEntryCount: 1,
|
|
wantEntryName: "https",
|
|
wantEntryProgrammedStatus: metav1.ConditionFalse,
|
|
wantEntryProgrammedReason: string(gatev1.ListenerEntryReasonInvalid),
|
|
},
|
|
{
|
|
desc: "No valid listener",
|
|
listeners: []gatewayListener{
|
|
{
|
|
SectionName: "http",
|
|
ListenerSet: &gatev1.ListenerSet{Namespace: "default", Name: "my-ls"},
|
|
Status: &gatev1.ListenerStatus{
|
|
Name: "http",
|
|
Conditions: []metav1.Condition{
|
|
{
|
|
Type: string(gatev1.ListenerConditionAccepted),
|
|
Status: metav1.ConditionFalse,
|
|
Reason: string(gatev1.ListenerReasonPortUnavailable),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
parentAccepted: true,
|
|
wantAcceptedStatus: metav1.ConditionFalse,
|
|
wantAcceptedReason: string(gatev1.ListenerSetReasonListenersNotValid),
|
|
wantProgrammedStatus: metav1.ConditionFalse,
|
|
wantProgrammedReason: string(gatev1.ListenerSetReasonListenersNotValid),
|
|
wantListenerEntryCount: 1,
|
|
},
|
|
{
|
|
desc: "At least one valid listener",
|
|
listeners: []gatewayListener{
|
|
{
|
|
SectionName: "http",
|
|
ListenerSet: &gatev1.ListenerSet{Namespace: "default", Name: "my-ls"},
|
|
Status: &gatev1.ListenerStatus{
|
|
Name: "http",
|
|
Conditions: []metav1.Condition{},
|
|
},
|
|
},
|
|
{
|
|
SectionName: "invalid",
|
|
ListenerSet: &gatev1.ListenerSet{Namespace: "default", Name: "my-ls"},
|
|
Status: &gatev1.ListenerStatus{
|
|
Name: "invalid",
|
|
Conditions: []metav1.Condition{
|
|
{
|
|
Type: string(gatev1.ListenerConditionAccepted),
|
|
Status: metav1.ConditionFalse,
|
|
Reason: string(gatev1.ListenerReasonPortUnavailable),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
parentAccepted: true,
|
|
wantAccepted: true,
|
|
wantAcceptedStatus: metav1.ConditionTrue,
|
|
wantAcceptedReason: string(gatev1.ListenerSetReasonListenersNotValid),
|
|
wantProgrammedStatus: metav1.ConditionTrue,
|
|
wantProgrammedReason: string(gatev1.ListenerSetReasonProgrammed),
|
|
wantListenerEntryCount: 2,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
status, accepted := makeListenerSetStatus(0, test.listeners, test.parentAccepted)
|
|
|
|
assert.Equal(t, test.wantAccepted, accepted)
|
|
assert.Len(t, status.Listeners, test.wantListenerEntryCount)
|
|
|
|
var acceptedCond, programmedCond *metav1.Condition
|
|
for _, c := range status.Conditions {
|
|
switch c.Type {
|
|
case string(gatev1.ListenerSetConditionAccepted):
|
|
acceptedCond = &c
|
|
case string(gatev1.ListenerSetConditionProgrammed):
|
|
programmedCond = &c
|
|
}
|
|
}
|
|
|
|
require.NotNil(t, acceptedCond)
|
|
assert.Equal(t, test.wantAcceptedStatus, acceptedCond.Status)
|
|
assert.Equal(t, test.wantAcceptedReason, acceptedCond.Reason)
|
|
|
|
require.NotNil(t, programmedCond)
|
|
assert.Equal(t, test.wantProgrammedStatus, programmedCond.Status)
|
|
assert.Equal(t, test.wantProgrammedReason, programmedCond.Reason)
|
|
|
|
if test.wantEntryName != "" {
|
|
require.NotEmpty(t, status.Listeners)
|
|
entry := status.Listeners[0]
|
|
assert.Equal(t, test.wantEntryName, entry.Name)
|
|
|
|
var entryProgrammed *metav1.Condition
|
|
for _, c := range entry.Conditions {
|
|
if c.Type == string(gatev1.ListenerEntryConditionProgrammed) {
|
|
entryProgrammed = &c
|
|
}
|
|
}
|
|
require.NotNil(t, entryProgrammed)
|
|
assert.Equal(t, test.wantEntryProgrammedStatus, entryProgrammed.Status)
|
|
assert.Equal(t, test.wantEntryProgrammedReason, entryProgrammed.Reason)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test_loadListenerSetListeners covers the listener-level outcomes of merging the ListenerSet listeners into the Gateway ones:
|
|
// the conflict conditions, the precedence of a ListenerSet over its later siblings,
|
|
// and the status of the ListenerSets the Gateway does not allow.
|
|
func Test_loadListenerSetListeners(t *testing.T) {
|
|
gateway := &gatev1.Gateway{
|
|
Name: "my-gateway", Namespace: "default",
|
|
Spec: gatev1.GatewaySpec{
|
|
AllowedListeners: &gatev1.AllowedListeners{
|
|
Namespaces: &gatev1.ListenerNamespaces{From: new(gatev1.NamespacesFromAll)},
|
|
},
|
|
},
|
|
}
|
|
|
|
listenerSet := func(name string, created time.Time, listeners ...gatev1.ListenerEntry) *gatev1.ListenerSet {
|
|
return &gatev1.ListenerSet{
|
|
Name: name,
|
|
Namespace: "default",
|
|
CreationTimestamp: metav1.NewTime(created),
|
|
Spec: gatev1.ListenerSetSpec{
|
|
ParentRef: gatev1.ParentGatewayReference{Name: "my-gateway"},
|
|
Listeners: listeners,
|
|
},
|
|
}
|
|
}
|
|
|
|
type wantListener struct {
|
|
name string
|
|
attached bool
|
|
reason string
|
|
}
|
|
|
|
testCases := []struct {
|
|
desc string
|
|
allowedListeners *gatev1.AllowedListeners
|
|
gatewayListener *gatev1.Listener
|
|
listenerSets []*gatev1.ListenerSet
|
|
wantListeners []wantListener
|
|
wantNotAllowed []string
|
|
}{
|
|
{
|
|
desc: "ListenerSet not allowed by the Gateway",
|
|
allowedListeners: &gatev1.AllowedListeners{Namespaces: &gatev1.ListenerNamespaces{From: new(gatev1.NamespacesFromNone)}},
|
|
listenerSets: []*gatev1.ListenerSet{
|
|
listenerSet("my-listenerset", time.Time{}, gatev1.ListenerEntry{Name: "http", Protocol: gatev1.HTTPProtocolType, Port: 80}),
|
|
},
|
|
wantNotAllowed: []string{"my-listenerset"},
|
|
},
|
|
{
|
|
desc: "Hostname conflict with a Gateway listener",
|
|
gatewayListener: &gatev1.Listener{Name: "web", Protocol: gatev1.HTTPProtocolType, Port: 80},
|
|
listenerSets: []*gatev1.ListenerSet{
|
|
listenerSet("my-listenerset", time.Time{}, gatev1.ListenerEntry{Name: "http", Protocol: gatev1.HTTPProtocolType, Port: 80}),
|
|
},
|
|
wantListeners: []wantListener{{name: "http", reason: string(gatev1.ListenerReasonHostnameConflict)}},
|
|
},
|
|
{
|
|
desc: "Protocol conflict with a Gateway listener",
|
|
gatewayListener: &gatev1.Listener{Name: "web", Protocol: gatev1.HTTPProtocolType, Port: 80},
|
|
listenerSets: []*gatev1.ListenerSet{
|
|
listenerSet("my-listenerset", time.Time{},
|
|
gatev1.ListenerEntry{Name: "http", Protocol: gatev1.HTTPProtocolType, Port: 80, Hostname: new(gatev1.Hostname("foo.example.com"))},
|
|
gatev1.ListenerEntry{Name: "tcp", Protocol: gatev1.TCPProtocolType, Port: 80},
|
|
),
|
|
},
|
|
wantListeners: []wantListener{
|
|
{name: "http", attached: true},
|
|
{name: "tcp", reason: string(gatev1.ListenerReasonProtocolConflict)},
|
|
},
|
|
},
|
|
{
|
|
desc: "First ListenerSet wins the protocol conflict with a later sibling",
|
|
listenerSets: []*gatev1.ListenerSet{
|
|
listenerSet("ls-first", time.Time{}, gatev1.ListenerEntry{Name: "tcp", Protocol: gatev1.TCPProtocolType, Port: 80}),
|
|
listenerSet("ls-second", time.Time{}, gatev1.ListenerEntry{Name: "http", Protocol: gatev1.HTTPProtocolType, Port: 80}),
|
|
},
|
|
wantListeners: []wantListener{
|
|
{name: "tcp", attached: true},
|
|
{name: "http", reason: string(gatev1.ListenerReasonProtocolConflict)},
|
|
},
|
|
},
|
|
{
|
|
desc: "First ListenerSet wins the conflict with a later sibling",
|
|
listenerSets: []*gatev1.ListenerSet{
|
|
listenerSet("ls-first", time.Time{}, gatev1.ListenerEntry{Name: "http", Protocol: gatev1.HTTPProtocolType, Port: 80}),
|
|
listenerSet("ls-second", time.Time{}, gatev1.ListenerEntry{Name: "http", Protocol: gatev1.HTTPProtocolType, Port: 80}),
|
|
},
|
|
wantListeners: []wantListener{
|
|
{name: "http", attached: true},
|
|
{name: "http", reason: string(gatev1.ListenerReasonHostnameConflict)},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
p := Provider{EntryPoints: map[string]Entrypoint{"web": {Address: ":80"}}}
|
|
|
|
gateway := gateway.DeepCopy()
|
|
if test.allowedListeners != nil {
|
|
gateway.Spec.AllowedListeners = test.allowedListeners
|
|
}
|
|
|
|
claims := newListenerClaims(map[gatev1.PortNumber]*tls.ClientAuth{})
|
|
if test.gatewayListener != nil {
|
|
gatewayWithListener := gateway.DeepCopy()
|
|
gatewayWithListener.Spec.Listeners = []gatev1.Listener{*test.gatewayListener}
|
|
p.loadGatewayListeners(t.Context(), gatewayWithListener, nil, claims, &dynamic.Configuration{TLS: &dynamic.TLSConfiguration{}})
|
|
}
|
|
|
|
statusReport := newStatusReport()
|
|
listeners := p.loadListenerSetListeners(t.Context(), gateway, test.listenerSets, claims, &dynamic.Configuration{TLS: &dynamic.TLSConfiguration{}}, statusReport)
|
|
require.Len(t, listeners, len(test.wantListeners))
|
|
|
|
require.Len(t, statusReport.listenerSets, len(test.wantNotAllowed))
|
|
for _, name := range test.wantNotAllowed {
|
|
status, ok := statusReport.listenerSets[ktypes.NamespacedName{Namespace: "default", Name: name}]
|
|
require.True(t, ok)
|
|
require.Len(t, status.Conditions, 2)
|
|
for _, condition := range status.Conditions {
|
|
assert.Equal(t, string(gatev1.ListenerSetReasonNotAllowed), condition.Reason)
|
|
}
|
|
}
|
|
|
|
for i, want := range test.wantListeners {
|
|
assert.Equal(t, want.name, listeners[i].SectionName)
|
|
assert.Equal(t, want.attached, listeners[i].Attached)
|
|
|
|
if want.reason == "" {
|
|
assert.Empty(t, listeners[i].Status.Conditions)
|
|
continue
|
|
}
|
|
|
|
require.NotEmpty(t, listeners[i].Status.Conditions)
|
|
for _, condition := range listeners[i].Status.Conditions {
|
|
assert.Equal(t, want.reason, condition.Reason)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|