1
0
Fork 0

Merge current branch v2.4 into master

This commit is contained in:
Jean-Baptiste Doumenjou 2021-03-31 09:43:04 +02:00
commit cb4fb973b2
41 changed files with 1857 additions and 1424 deletions

View file

@ -2,5 +2,11 @@ package static
// Pilot Configuration related to Traefik Pilot.
type Pilot struct {
Token string `description:"Traefik Pilot token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty"`
Token string `description:"Traefik Pilot token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty"`
Dashboard bool `description:"Enable Traefik Pilot in the dashboard." json:"dashboard,omitempty" toml:"dashboard,omitempty" yaml:"dashboard,omitempty"`
}
// SetDefaults sets the default values.
func (p *Pilot) SetDefaults() {
p.Dashboard = true
}

View file

@ -235,6 +235,12 @@ func (c *Configuration) SetEffectiveConfiguration() {
c.Global.SendAnonymousUsage = true
}
// Create Pilot struct to apply default value on undefined configuration.
if c.Pilot == nil {
c.Pilot = &Pilot{}
c.Pilot.SetDefaults()
}
// Disable Gateway API provider if not enabled in experimental
if c.Experimental == nil || !c.Experimental.KubernetesGateway {
c.Providers.KubernetesGateway = nil

View file

@ -16,9 +16,9 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/service-apis/apis/v1alpha1"
"sigs.k8s.io/service-apis/pkg/client/clientset/versioned"
"sigs.k8s.io/service-apis/pkg/client/informers/externalversions"
"sigs.k8s.io/gateway-api/apis/v1alpha1"
"sigs.k8s.io/gateway-api/pkg/client/clientset/versioned"
"sigs.k8s.io/gateway-api/pkg/client/informers/externalversions"
)
const resyncPeriod = 10 * time.Minute
@ -236,7 +236,7 @@ func (c *clientWrapper) GetHTTPRoutes(namespace string, selector labels.Selector
}
if len(httpRoutes) == 0 {
return nil, fmt.Errorf("failed to get HTTPRoute %s with labels selector %s: namespace is not within watched namespaces", namespace, selector)
log.WithoutContext().Debugf("No HTTPRoute found in %q namespace with labels selector %s", namespace, selector)
}
return httpRoutes, nil

View file

@ -10,7 +10,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/service-apis/apis/v1alpha1"
"sigs.k8s.io/gateway-api/apis/v1alpha1"
)
var _ Client = (*clientMock)(nil)

View file

@ -5,7 +5,7 @@ import (
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/service-apis/apis/v1alpha1"
"sigs.k8s.io/gateway-api/apis/v1alpha1"
)
func TestStatusEquals(t *testing.T) {

View file

@ -25,7 +25,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"sigs.k8s.io/service-apis/apis/v1alpha1"
"sigs.k8s.io/gateway-api/apis/v1alpha1"
)
const (
@ -809,12 +809,12 @@ func loadServices(client Client, namespace string, targets []v1alpha1.HTTPRouteF
return nil, nil, errors.New("service not found")
}
if len(service.Spec.Ports) > 1 && forwardTo.Port == 0 {
if len(service.Spec.Ports) > 1 && forwardTo.Port == nil {
// If the port is unspecified and the backend is a Service
// object consisting of multiple port definitions, the route
// must be dropped from the Gateway. The controller should
// raise the "ResolvedRefs" condition on the Gateway with the
// "DroppedRoutes" reason. The gateway status for this route
// "DroppedRoutes" reason. The gateway status for this route
// should be updated with a condition that describes the error
// more specifically.
log.WithoutContext().Errorf("A multiple ports Kubernetes Service cannot be used if unspecified forwardTo.Port")
@ -826,7 +826,7 @@ func loadServices(client Client, namespace string, targets []v1alpha1.HTTPRouteF
var match bool
for _, p := range service.Spec.Ports {
if forwardTo.Port == 0 || p.Port == int32(forwardTo.Port) {
if forwardTo.Port == nil || p.Port == int32(*forwardTo.Port) {
portName = p.Name
portSpec = p
match = true

View file

@ -9,7 +9,7 @@ import (
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/provider"
"github.com/traefik/traefik/v2/pkg/tls"
"sigs.k8s.io/service-apis/apis/v1alpha1"
"sigs.k8s.io/gateway-api/apis/v1alpha1"
)
var _ provider.Provider = (*Provider)(nil)

View file

@ -4,6 +4,7 @@ import (
"fmt"
"net/http"
"strings"
"unicode/utf8"
"github.com/gorilla/mux"
"github.com/traefik/traefik/v2/pkg/log"
@ -102,6 +103,10 @@ func pathPrefix(route *mux.Route, paths ...string) error {
func host(route *mux.Route, hosts ...string) error {
for i, host := range hosts {
if !IsASCII(host) {
return fmt.Errorf("invalid value %q for \"Host\" matcher, non-ASCII characters are not allowed", host)
}
hosts[i] = strings.ToLower(host)
}
@ -152,6 +157,10 @@ func host(route *mux.Route, hosts ...string) error {
func hostRegexp(route *mux.Route, hosts ...string) error {
router := route.Subrouter()
for _, host := range hosts {
if !IsASCII(host) {
return fmt.Errorf("invalid value %q for HostRegexp matcher, non-ASCII characters are not allowed", host)
}
tmpRt := router.Host(host)
if tmpRt.GetError() != nil {
return tmpRt.GetError()
@ -250,3 +259,14 @@ func checkRule(rule *tree) error {
}
return nil
}
// IsASCII checks if the given string contains only ASCII characters.
func IsASCII(s string) bool {
for i := 0; i < len(s); i++ {
if s[i] >= utf8.RuneSelf {
return false
}
}
return true
}

View file

@ -60,6 +60,16 @@ func Test_addRoute(t *testing.T) {
"http://localhost/foo": http.StatusOK,
},
},
{
desc: "Non-ASCII Host",
rule: "Host(`locàlhost`)",
expectedError: true,
},
{
desc: "Non-ASCII HostRegexp",
rule: "HostRegexp(`locàlhost`)",
expectedError: true,
},
{
desc: "HostHeader equivalent to Host",
rule: "HostHeader(`localhost`)",

View file

@ -258,28 +258,36 @@ func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string
logger.Debugf("Adding route %s on TCP", domain)
switch {
case routerConfig.TLS != nil:
if !rules.IsASCII(domain) {
asciiError := fmt.Errorf("invalid domain name value %q, non-ASCII characters are not allowed", domain)
routerConfig.AddError(asciiError, true)
logger.Debug(asciiError)
continue
}
if routerConfig.TLS.Passthrough {
router.AddRoute(domain, handler)
} else {
tlsOptionsName := routerConfig.TLS.Options
if len(tlsOptionsName) == 0 {
tlsOptionsName = defaultTLSConfigName
}
if tlsOptionsName != defaultTLSConfigName {
tlsOptionsName = provider.GetQualifiedName(ctxRouter, tlsOptionsName)
}
tlsConf, err := m.tlsManager.Get(defaultTLSStoreName, tlsOptionsName)
if err != nil {
routerConfig.AddError(err, true)
logger.Debug(err)
continue
}
router.AddRouteTLS(domain, handler, tlsConf)
continue
}
tlsOptionsName := routerConfig.TLS.Options
if len(tlsOptionsName) == 0 {
tlsOptionsName = defaultTLSConfigName
}
if tlsOptionsName != defaultTLSConfigName {
tlsOptionsName = provider.GetQualifiedName(ctxRouter, tlsOptionsName)
}
tlsConf, err := m.tlsManager.Get(defaultTLSStoreName, tlsOptionsName)
if err != nil {
routerConfig.AddError(err, true)
logger.Debug(err)
continue
}
router.AddRouteTLS(domain, handler, tlsConf)
case domain == "*":
router.AddCatchAllNoTLS(handler)
default:

View file

@ -71,6 +71,37 @@ func TestRuntimeConfiguration(t *testing.T) {
},
expectedError: 0,
},
{
desc: "Non-ASCII domain error",
tcpServiceConfig: map[string]*runtime.TCPServiceInfo{
"foo-service": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Port: "8085",
Address: "127.0.0.1:8085",
},
},
},
},
},
},
tcpRouterConfig: map[string]*runtime.TCPRouterInfo{
"foo": {
TCPRouter: &dynamic.TCPRouter{
EntryPoints: []string{"web"},
Service: "foo-service",
Rule: "HostSNI(`bàr.foo`)",
TLS: &dynamic.RouterTCPTLSConfig{
Passthrough: false,
Options: "foo",
},
},
},
},
expectedError: 1,
},
{
desc: "HTTP routers with same domain but different TLS options",
httpServiceConfig: map[string]*runtime.ServiceInfo{

View file

@ -24,6 +24,8 @@ var (
StartDate = time.Now()
// UUID instance uuid.
UUID string
// PilotEnabled activate integration of pilot into the dashboard.
PilotEnabled bool
)
// Handler expose version routes.
@ -38,15 +40,17 @@ func (v Handler) Append(router *mux.Router) {
router.Methods(http.MethodGet).Path("/api/version").
HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
v := struct {
Version string
Codename string
StartDate time.Time `json:"startDate"`
UUID string `json:"uuid,omitempty"`
Version string
Codename string
StartDate time.Time `json:"startDate"`
UUID string `json:"uuid,omitempty"`
PilotEnabled bool `json:"pilotEnabled"`
}{
Version: Version,
Codename: Codename,
StartDate: StartDate,
UUID: UUID,
Version: Version,
Codename: Codename,
StartDate: StartDate,
UUID: UUID,
PilotEnabled: PilotEnabled,
}
if err := templatesRenderer.JSON(response, http.StatusOK, v); err != nil {