Compare commits

...

8 Commits

Author SHA1 Message Date
Ludovic Fernandez
615dc7fd35 Prepare release v2.8.7 2022-09-23 16:22:38 +02:00
Kevin Pollet
7758880f3f Prepare release v2.8.6 2022-09-23 15:24:15 +02:00
Ludovic Fernandez
d04903edb2 fix: query parameter matching with equal 2022-09-23 15:12:29 +02:00
Julien Salleyron
9cd54baca4 Optimize websocket headers handling
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2022-09-22 10:00:09 +02:00
Ludovic Fernandez
7ac687a0a9 providers: simplify AddServer algorithms 2022-09-21 14:54:08 +02:00
t3hchipmunk
83ae1021f6 fix: UDP loadbalancer tags not being used with Consul Catalog 2022-09-21 14:30:09 +02:00
Romain
67e3bc6380 Add documentation for ECS constraints option 2022-09-20 12:22:08 +02:00
Ludovic Fernandez
89870ad539 docs: fix link to RouteNamespaces 2022-09-19 11:26:08 +02:00
15 changed files with 305 additions and 187 deletions

View File

@@ -40,6 +40,8 @@ builds:
goarch: arm64
- goos: freebsd
goarch: arm64
- goos: windows
goarch: arm
changelog:
skip: true

View File

@@ -1,3 +1,24 @@
## [v2.8.7](https://github.com/traefik/traefik/tree/v2.8.7) (2022-09-23)
[All Commits](https://github.com/traefik/traefik/compare/v2.8.5...v2.8.7)
**Bug fixes:**
- **[consulcatalog]** Fix UDP loadbalancer tags not being used with Consul Catalog ([#9357](https://github.com/traefik/traefik/pull/9357) by [t3hchipmunk](https://github.com/t3hchipmunk))
- **[docker,rancher,ecs,provider]** Simplify AddServer algorithm ([#9358](https://github.com/traefik/traefik/pull/9358) by [ldez](https://github.com/ldez))
- **[plugins]** Allow empty plugin configuration ([#9338](https://github.com/traefik/traefik/pull/9338) by [ldez](https://github.com/ldez))
- **[rules]** Fix query parameter matching with equal ([#9369](https://github.com/traefik/traefik/pull/9369) by [ldez](https://github.com/ldez))
- **[server]** Optimize websocket headers handling ([#9360](https://github.com/traefik/traefik/pull/9360) by [juliens](https://github.com/juliens))
**Documentation:**
- **[ecs]** Add documentation for ECS constraints option ([#9354](https://github.com/traefik/traefik/pull/9354) by [rtribotte](https://github.com/rtribotte))
- **[k8s/gatewayapi]** Fix link to RouteNamespaces ([#9349](https://github.com/traefik/traefik/pull/9349) by [ldez](https://github.com/ldez))
- Add documentation for json schema usage to validate config in the FAQ ([#9340](https://github.com/traefik/traefik/pull/9340) by [rtribotte](https://github.com/rtribotte))
- Add a note on case insensitive regex matching ([#9322](https://github.com/traefik/traefik/pull/9322) by [NEwa-05](https://github.com/NEwa-05))
## [v2.8.6](https://github.com/traefik/traefik/tree/v2.8.6) (2022-09-23)
[All Commits](https://github.com/traefik/traefik/compare/v2.8.5...v2.8.6)
Release canceled.
## [v2.8.5](https://github.com/traefik/traefik/tree/v2.8.5) (2022-09-13)
[All Commits](https://github.com/traefik/traefik/compare/v2.8.4...v2.8.5)

View File

@@ -445,7 +445,7 @@ To enable HTTP/3 on an EntryPoint, please check out the [HTTP/3 configuration](.
### Kubernetes Gateway API Provider
In `v2.6`, the [Kubernetes Gateway API provider](../providers/kubernetes-gateway.md) now only supports the version [v1alpha2](https://gateway-api.sigs.k8s.io/v1alpha2/guides/getting-started/) of the specification and
[route namespaces](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.RouteNamespaces) selectors, which requires Traefik to fetch and watch the cluster namespaces.
[route namespaces](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.RouteNamespaces) selectors, which requires Traefik to fetch and watch the cluster namespaces.
Therefore, the [RBAC](../reference/dynamic-configuration/kubernetes-gateway.md#rbac) and [CRD](../reference/dynamic-configuration/kubernetes-gateway.md#definitions) definitions must be updated.
## v2.6.0 to v2.6.1

View File

@@ -137,6 +137,70 @@ providers:
# ...
```
### `constraints`
_Optional, Default=""_
The `constraints` option can be set to an expression that Traefik matches against the container labels (task),
to determine whether to create any route for that container.
If none of the container labels match the expression, no route for that container is created.
If the expression is empty, all detected containers are included.
The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions,
as well as the usual boolean logic, as shown in examples below.
??? example "Constraints Expression Examples"
```toml
# Includes only containers having a label with key `a.label.name` and value `foo`
constraints = "Label(`a.label.name`, `foo`)"
```
```toml
# Excludes containers having any label with key `a.label.name` and value `foo`
constraints = "!Label(`a.label.name`, `value`)"
```
```toml
# With logical AND.
constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)"
```
```toml
# With logical OR.
constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)"
```
```toml
# With logical AND and OR, with precedence set by parentheses.
constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))"
```
```toml
# Includes only containers having a label with key `a.label.name` and a value matching the `a.+` regular expression.
constraints = "LabelRegex(`a.label.name`, `a.+`)"
```
For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
```yaml tab="File (YAML)"
providers:
ecs:
constraints: "Label(`a.label.name`,`foo`)"
# ...
```
```toml tab="File (TOML)"
[providers.ecs]
constraints = "Label(`a.label.name`,`foo`)"
# ...
```
```bash tab="CLI"
--providers.ecs.constraints=Label(`a.label.name`,`foo`)
# ...
```
### `defaultRule`
_Optional, Default=```Host(`{{ normalize .Name }}`)```_

View File

@@ -213,6 +213,7 @@ you can do so in two different ways:
List of providers that support these features:
- [Docker](./docker.md#exposedbydefault)
- [ECS](./ecs.md#exposedbydefault)
- [Consul Catalog](./consul-catalog.md#exposedbydefault)
- [Nomad](./nomad.md#exposedbydefault)
- [Rancher](./rancher.md#exposedbydefault)
@@ -223,6 +224,7 @@ List of providers that support these features:
List of providers that support constraints:
- [Docker](./docker.md#constraints)
- [ECS](./ecs.md#constraints)
- [Consul Catalog](./consul-catalog.md#constraints)
- [Nomad](./nomad.md#constraints)
- [Rancher](./rancher.md#constraints)

View File

@@ -237,7 +237,7 @@ func headersRegexp(route *mux.Route, headers ...string) error {
func query(route *mux.Route, query ...string) error {
var queries []string
for _, elem := range query {
queries = append(queries, strings.Split(elem, "=")...)
queries = append(queries, strings.SplitN(elem, "=", 2)...)
}
route.Queries(queries...)

View File

@@ -252,6 +252,14 @@ func Test_addRoute(t *testing.T) {
"http://localhost/foo?bar=baz": http.StatusNotFound,
},
},
{
desc: "Query with multiple equals",
rule: "Query(`foo=b=ar`)",
expected: map[string]int{
"http://localhost/foo?foo=b=ar": http.StatusOK,
"http://localhost/foo?foo=bar": http.StatusNotFound,
},
},
{
desc: "Rule with simple path",
rule: `Path("/a")`,

View File

@@ -198,29 +198,27 @@ func (p *Provider) addServerTCP(item itemData, loadBalancer *dynamic.TCPServersL
return errors.New("load-balancer is not defined")
}
var port string
if len(loadBalancer.Servers) > 0 {
port = loadBalancer.Servers[0].Port
}
if len(loadBalancer.Servers) == 0 {
loadBalancer.Servers = []dynamic.TCPServer{{}}
}
if item.Port != "" && port == "" {
port = item.Port
}
loadBalancer.Servers[0].Port = ""
if port == "" {
return errors.New("port is missing")
}
if item.Address == "" {
return errors.New("address is missing")
}
port := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
if port == "" {
port = item.Port
}
if port == "" {
return errors.New("port is missing")
}
loadBalancer.Servers[0].Address = net.JoinHostPort(item.Address, port)
return nil
}
@@ -233,21 +231,23 @@ func (p *Provider) addServerUDP(item itemData, loadBalancer *dynamic.UDPServersL
loadBalancer.Servers = []dynamic.UDPServer{{}}
}
var port string
if item.Port != "" {
if item.Address == "" {
return errors.New("address is missing")
}
port := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
if port == "" {
port = item.Port
loadBalancer.Servers[0].Port = ""
}
if port == "" {
return errors.New("port is missing")
}
if item.Address == "" {
return errors.New("address is missing")
}
loadBalancer.Servers[0].Address = net.JoinHostPort(item.Address, port)
return nil
}
@@ -256,11 +256,6 @@ func (p *Provider) addServer(item itemData, loadBalancer *dynamic.ServersLoadBal
return errors.New("load-balancer is not defined")
}
var port string
if len(loadBalancer.Servers) > 0 {
port = loadBalancer.Servers[0].Port
}
if len(loadBalancer.Servers) == 0 {
server := dynamic.Server{}
server.SetDefaults()
@@ -268,17 +263,19 @@ func (p *Provider) addServer(item itemData, loadBalancer *dynamic.ServersLoadBal
loadBalancer.Servers = []dynamic.Server{server}
}
if item.Port != "" && port == "" {
port = item.Port
if item.Address == "" {
return errors.New("address is missing")
}
port := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
if port == "" {
return errors.New("port is missing")
port = item.Port
}
if item.Address == "" {
return errors.New("address is missing")
if port == "" {
return errors.New("port is missing")
}
scheme := loadBalancer.Servers[0].Scheme

View File

@@ -2220,7 +2220,7 @@ func Test_buildConfiguration(t *testing.T) {
Labels: map[string]string{
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
"traefik.tcp.routers.foo.tls.options": "foo",
"traefik.tcp.services.foo.loadbalancer.server.port": "80",
"traefik.tcp.services.foo.loadbalancer.server.port": "8080",
},
Address: "127.0.0.1",
Port: "80",
@@ -2244,7 +2244,7 @@ func Test_buildConfiguration(t *testing.T) {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:80",
Address: "127.0.0.1:8080",
},
},
TerminationDelay: Int(100),
@@ -2611,6 +2611,57 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
{
desc: "UDP service with labels only",
ConnectAware: true,
items: []itemData{
{
ID: "1",
Node: "Node1",
Datacenter: "dc1",
Name: "Test",
Namespace: "ns",
Labels: map[string]string{
"traefik.udp.routers.test-udp-label.service": "test-udp-label-service",
"traefik.udp.routers.test-udp-label.entryPoints": "udp",
"traefik.udp.services.test-udp-label-service.loadBalancer.server.port": "21116",
},
Address: "127.0.0.1",
Port: "80",
Status: api.HealthPassing,
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
},
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{
"test-udp-label": {
EntryPoints: []string{"udp"},
Service: "test-udp-label-service",
},
},
Services: map[string]*dynamic.UDPService{
"test-udp-label-service": {
LoadBalancer: &dynamic.UDPServersLoadBalancer{
Servers: []dynamic.UDPServer{
{Address: "127.0.0.1:21116"},
},
},
},
},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
},
},
}
for _, test := range testCases {

View File

@@ -187,28 +187,24 @@ func (p *Provider) addServerTCP(ctx context.Context, container dockerData, loadB
return errors.New("load-balancer is not defined")
}
var serverPort string
if len(loadBalancer.Servers) > 0 {
serverPort = loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
if len(loadBalancer.Servers) == 0 {
loadBalancer.Servers = []dynamic.TCPServer{{}}
}
serverPort := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
ip, port, err := p.getIPPort(ctx, container, serverPort)
if err != nil {
return err
}
if len(loadBalancer.Servers) == 0 {
server := dynamic.TCPServer{}
loadBalancer.Servers = []dynamic.TCPServer{server}
}
if port == "" {
return errors.New("port is missing")
}
loadBalancer.Servers[0].Address = net.JoinHostPort(ip, port)
return nil
}
@@ -217,28 +213,24 @@ func (p *Provider) addServerUDP(ctx context.Context, container dockerData, loadB
return errors.New("load-balancer is not defined")
}
var serverPort string
if len(loadBalancer.Servers) > 0 {
serverPort = loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
if len(loadBalancer.Servers) == 0 {
loadBalancer.Servers = []dynamic.UDPServer{{}}
}
serverPort := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
ip, port, err := p.getIPPort(ctx, container, serverPort)
if err != nil {
return err
}
if len(loadBalancer.Servers) == 0 {
server := dynamic.UDPServer{}
loadBalancer.Servers = []dynamic.UDPServer{server}
}
if port == "" {
return errors.New("port is missing")
}
loadBalancer.Servers[0].Address = net.JoinHostPort(ip, port)
return nil
}
@@ -247,17 +239,6 @@ func (p *Provider) addServer(ctx context.Context, container dockerData, loadBala
return errors.New("load-balancer is not defined")
}
var serverPort string
if len(loadBalancer.Servers) > 0 {
serverPort = loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
}
ip, port, err := p.getIPPort(ctx, container, serverPort)
if err != nil {
return err
}
if len(loadBalancer.Servers) == 0 {
server := dynamic.Server{}
server.SetDefaults()
@@ -265,6 +246,14 @@ func (p *Provider) addServer(ctx context.Context, container dockerData, loadBala
loadBalancer.Servers = []dynamic.Server{server}
}
serverPort := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
ip, port, err := p.getIPPort(ctx, container, serverPort)
if err != nil {
return err
}
if port == "" {
return errors.New("port is missing")
}

View File

@@ -185,7 +185,7 @@ func (p *Provider) filterInstance(ctx context.Context, instance ecsInstance) boo
matches, err := constraints.MatchLabels(instance.Labels, p.Constraints)
if err != nil {
logger.Errorf("Error matching constraints expression: %v", err)
logger.Errorf("Error matching constraint expression: %v", err)
return false
}
if !matches {
@@ -201,28 +201,24 @@ func (p *Provider) addServerTCP(instance ecsInstance, loadBalancer *dynamic.TCPS
return errors.New("load-balancer is not defined")
}
var serverPort string
if len(loadBalancer.Servers) > 0 {
serverPort = loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
if len(loadBalancer.Servers) == 0 {
loadBalancer.Servers = []dynamic.TCPServer{{}}
}
serverPort := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
ip, port, err := p.getIPPort(instance, serverPort)
if err != nil {
return err
}
if len(loadBalancer.Servers) == 0 {
server := dynamic.TCPServer{}
loadBalancer.Servers = []dynamic.TCPServer{server}
}
if port == "" {
return errors.New("port is missing")
}
loadBalancer.Servers[0].Address = net.JoinHostPort(ip, port)
return nil
}
@@ -231,28 +227,24 @@ func (p *Provider) addServerUDP(instance ecsInstance, loadBalancer *dynamic.UDPS
return errors.New("load-balancer is not defined")
}
var serverPort string
if len(loadBalancer.Servers) > 0 {
serverPort = loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
if len(loadBalancer.Servers) == 0 {
loadBalancer.Servers = []dynamic.UDPServer{{}}
}
serverPort := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
ip, port, err := p.getIPPort(instance, serverPort)
if err != nil {
return err
}
if len(loadBalancer.Servers) == 0 {
server := dynamic.UDPServer{}
loadBalancer.Servers = []dynamic.UDPServer{server}
}
if port == "" {
return errors.New("port is missing")
}
loadBalancer.Servers[0].Address = net.JoinHostPort(ip, port)
return nil
}
@@ -261,17 +253,6 @@ func (p *Provider) addServer(instance ecsInstance, loadBalancer *dynamic.Servers
return errors.New("load-balancer is not defined")
}
var serverPort string
if len(loadBalancer.Servers) > 0 {
serverPort = loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
}
ip, port, err := p.getIPPort(instance, serverPort)
if err != nil {
return err
}
if len(loadBalancer.Servers) == 0 {
server := dynamic.Server{}
server.SetDefaults()
@@ -279,6 +260,14 @@ func (p *Provider) addServer(instance ecsInstance, loadBalancer *dynamic.Servers
loadBalancer.Servers = []dynamic.Server{server}
}
serverPort := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
ip, port, err := p.getIPPort(instance, serverPort)
if err != nil {
return err
}
if port == "" {
return errors.New("port is missing")
}

View File

@@ -172,29 +172,27 @@ func (p *Provider) addServerTCP(i item, lb *dynamic.TCPServersLoadBalancer) erro
return errors.New("load-balancer is missing")
}
var port string
if len(lb.Servers) > 0 {
port = lb.Servers[0].Port
}
if len(lb.Servers) == 0 {
lb.Servers = []dynamic.TCPServer{{}}
}
if i.Port != 0 && port == "" {
port = strconv.Itoa(i.Port)
}
lb.Servers[0].Port = ""
if port == "" {
return errors.New("port is missing")
}
if i.Address == "" {
return errors.New("address is missing")
}
port := lb.Servers[0].Port
lb.Servers[0].Port = ""
if port == "" && i.Port > 0 {
port = strconv.Itoa(i.Port)
}
if port == "" {
return errors.New("port is missing")
}
lb.Servers[0].Address = net.JoinHostPort(i.Address, port)
return nil
}
@@ -203,29 +201,27 @@ func (p *Provider) addServerUDP(i item, lb *dynamic.UDPServersLoadBalancer) erro
return errors.New("load-balancer is missing")
}
var port string
if len(lb.Servers) > 0 {
port = lb.Servers[0].Port
}
if len(lb.Servers) == 0 {
lb.Servers = []dynamic.UDPServer{{}}
}
if i.Port != 0 && port == "" {
port = strconv.Itoa(i.Port)
}
lb.Servers[0].Port = ""
if port == "" {
return errors.New("port is missing")
}
if i.Address == "" {
return errors.New("address is missing")
}
port := lb.Servers[0].Port
lb.Servers[0].Port = ""
if port == "" && i.Port > 0 {
port = strconv.Itoa(i.Port)
}
if port == "" {
return errors.New("port is missing")
}
lb.Servers[0].Address = net.JoinHostPort(i.Address, port)
return nil
}
@@ -234,11 +230,6 @@ func (p *Provider) addServer(i item, lb *dynamic.ServersLoadBalancer) error {
return errors.New("load-balancer is missing")
}
var port string
if len(lb.Servers) > 0 {
port = lb.Servers[0].Port
}
if len(lb.Servers) == 0 {
server := dynamic.Server{}
server.SetDefaults()
@@ -246,19 +237,21 @@ func (p *Provider) addServer(i item, lb *dynamic.ServersLoadBalancer) error {
lb.Servers = []dynamic.Server{server}
}
if i.Port != 0 && port == "" {
if i.Address == "" {
return errors.New("address is missing")
}
port := lb.Servers[0].Port
lb.Servers[0].Port = ""
if port == "" && i.Port > 0 {
port = strconv.Itoa(i.Port)
}
lb.Servers[0].Port = ""
if port == "" {
return errors.New("port is missing")
}
if i.Address == "" {
return errors.New("address is missing")
}
scheme := lb.Servers[0].Scheme
lb.Servers[0].Scheme = ""
lb.Servers[0].URL = fmt.Sprintf("%s://%s", scheme, net.JoinHostPort(i.Address, port))

View File

@@ -160,7 +160,7 @@ func (p *Provider) keepService(ctx context.Context, service rancherData) bool {
matches, err := constraints.MatchLabels(service.Labels, p.Constraints)
if err != nil {
logger.Errorf("Error matching constraints expression: %v", err)
logger.Errorf("Error matching constraint expression: %v", err)
return false
}
if !matches {
@@ -185,23 +185,19 @@ func (p *Provider) keepService(ctx context.Context, service rancherData) bool {
func (p *Provider) addServerTCP(ctx context.Context, service rancherData, loadBalancer *dynamic.TCPServersLoadBalancer) error {
log.FromContext(ctx).Debugf("Trying to add servers for service %s \n", service.Name)
serverPort := ""
if loadBalancer != nil && len(loadBalancer.Servers) > 0 {
serverPort = loadBalancer.Servers[0].Port
if loadBalancer == nil {
return errors.New("load-balancer is not defined")
}
port := getServicePort(service)
if len(loadBalancer.Servers) == 0 {
server := dynamic.TCPServer{}
loadBalancer.Servers = []dynamic.TCPServer{server}
loadBalancer.Servers = []dynamic.TCPServer{{}}
}
if serverPort != "" {
port = serverPort
loadBalancer.Servers[0].Port = ""
port := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
if port == "" {
port = getServicePort(service)
}
if port == "" {
@@ -216,29 +212,26 @@ func (p *Provider) addServerTCP(ctx context.Context, service rancherData, loadBa
}
loadBalancer.Servers = servers
return nil
}
func (p *Provider) addServerUDP(ctx context.Context, service rancherData, loadBalancer *dynamic.UDPServersLoadBalancer) error {
log.FromContext(ctx).Debugf("Trying to add servers for service %s \n", service.Name)
serverPort := ""
if loadBalancer != nil && len(loadBalancer.Servers) > 0 {
serverPort = loadBalancer.Servers[0].Port
if loadBalancer == nil {
return errors.New("load-balancer is not defined")
}
port := getServicePort(service)
if len(loadBalancer.Servers) == 0 {
server := dynamic.UDPServer{}
loadBalancer.Servers = []dynamic.UDPServer{server}
loadBalancer.Servers = []dynamic.UDPServer{{}}
}
if serverPort != "" {
port = serverPort
loadBalancer.Servers[0].Port = ""
port := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
if port == "" {
port = getServicePort(service)
}
if port == "" {
@@ -253,14 +246,16 @@ func (p *Provider) addServerUDP(ctx context.Context, service rancherData, loadBa
}
loadBalancer.Servers = servers
return nil
}
func (p *Provider) addServers(ctx context.Context, service rancherData, loadBalancer *dynamic.ServersLoadBalancer) error {
log.FromContext(ctx).Debugf("Trying to add servers for service %s \n", service.Name)
serverPort := getLBServerPort(loadBalancer)
port := getServicePort(service)
if loadBalancer == nil {
return errors.New("load-balancer is not defined")
}
if len(loadBalancer.Servers) == 0 {
server := dynamic.Server{}
@@ -269,9 +264,11 @@ func (p *Provider) addServers(ctx context.Context, service rancherData, loadBala
loadBalancer.Servers = []dynamic.Server{server}
}
if serverPort != "" {
port = serverPort
loadBalancer.Servers[0].Port = ""
port := loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
if port == "" {
port = getServicePort(service)
}
if port == "" {
@@ -286,14 +283,8 @@ func (p *Provider) addServers(ctx context.Context, service rancherData, loadBala
}
loadBalancer.Servers = servers
return nil
}
func getLBServerPort(loadBalancer *dynamic.ServersLoadBalancer) string {
if loadBalancer != nil && len(loadBalancer.Servers) > 0 {
return loadBalancer.Servers[0].Port
}
return ""
return nil
}
func getServicePort(data rancherData) string {

View File

@@ -15,6 +15,7 @@ import (
ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/log"
"golang.org/x/net/http/httpguts"
)
// StatusClientClosedRequest non-standard HTTP status code for client disconnection.
@@ -67,16 +68,18 @@ func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwar
// some servers need Sec-WebSocket-Key, Sec-WebSocket-Extensions, Sec-WebSocket-Accept,
// Sec-WebSocket-Protocol and Sec-WebSocket-Version to be case-sensitive.
// https://tools.ietf.org/html/rfc6455#page-20
outReq.Header["Sec-WebSocket-Key"] = outReq.Header["Sec-Websocket-Key"]
outReq.Header["Sec-WebSocket-Extensions"] = outReq.Header["Sec-Websocket-Extensions"]
outReq.Header["Sec-WebSocket-Accept"] = outReq.Header["Sec-Websocket-Accept"]
outReq.Header["Sec-WebSocket-Protocol"] = outReq.Header["Sec-Websocket-Protocol"]
outReq.Header["Sec-WebSocket-Version"] = outReq.Header["Sec-Websocket-Version"]
delete(outReq.Header, "Sec-Websocket-Key")
delete(outReq.Header, "Sec-Websocket-Extensions")
delete(outReq.Header, "Sec-Websocket-Accept")
delete(outReq.Header, "Sec-Websocket-Protocol")
delete(outReq.Header, "Sec-Websocket-Version")
if isWebSocketUpgrade(outReq) {
outReq.Header["Sec-WebSocket-Key"] = outReq.Header["Sec-Websocket-Key"]
outReq.Header["Sec-WebSocket-Extensions"] = outReq.Header["Sec-Websocket-Extensions"]
outReq.Header["Sec-WebSocket-Accept"] = outReq.Header["Sec-Websocket-Accept"]
outReq.Header["Sec-WebSocket-Protocol"] = outReq.Header["Sec-Websocket-Protocol"]
outReq.Header["Sec-WebSocket-Version"] = outReq.Header["Sec-Websocket-Version"]
delete(outReq.Header, "Sec-Websocket-Key")
delete(outReq.Header, "Sec-Websocket-Extensions")
delete(outReq.Header, "Sec-Websocket-Accept")
delete(outReq.Header, "Sec-Websocket-Protocol")
delete(outReq.Header, "Sec-Websocket-Version")
}
},
Transport: roundTripper,
FlushInterval: time.Duration(flushInterval),
@@ -112,6 +115,14 @@ func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwar
return proxy, nil
}
func isWebSocketUpgrade(req *http.Request) bool {
if !httpguts.HeaderValuesContainsToken(req.Header["Connection"], "Upgrade") {
return false
}
return strings.EqualFold(req.Header.Get("Upgrade"), "websocket")
}
func statusText(statusCode int) string {
if statusCode == StatusClientClosedRequest {
return StatusClientClosedRequestText

View File

@@ -4,11 +4,11 @@ RepositoryName = "traefik"
OutputType = "file"
FileName = "traefik_changelog.md"
# example new bugfix v2.8.5
# example new bugfix v2.8.7
CurrentRef = "v2.8"
PreviousRef = "v2.8.4"
PreviousRef = "v2.8.6"
BaseBranch = "v2.8"
FutureCurrentRefName = "v2.8.5"
FutureCurrentRefName = "v2.8.7"
ThresholdPreviousRef = 10
ThresholdCurrentRef = 10