Entry point redirection and default routers configuration
Co-authored-by: Julien Salleyron <julien.salleyron@gmail.com> Co-authored-by: Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
This commit is contained in:
parent
93a7af270f
commit
a6040c623b
46 changed files with 1016 additions and 126 deletions
|
@ -41,7 +41,8 @@
|
|||
},
|
||||
"services": {
|
||||
"api": {},
|
||||
"dashboard": {}
|
||||
"dashboard": {},
|
||||
"noop": {}
|
||||
}
|
||||
},
|
||||
"tcp": {},
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
}
|
||||
},
|
||||
"services": {
|
||||
"api": {}
|
||||
"api": {},
|
||||
"noop": {}
|
||||
}
|
||||
},
|
||||
"tcp": {},
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
"http": {
|
||||
"services": {
|
||||
"api": {},
|
||||
"dashboard": {}
|
||||
"dashboard": {},
|
||||
"noop": {}
|
||||
}
|
||||
},
|
||||
"tcp": {},
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"http": {
|
||||
"services": {
|
||||
"api": {}
|
||||
"api": {},
|
||||
"noop": {}
|
||||
}
|
||||
},
|
||||
"tcp": {},
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
"services": {
|
||||
"api": {},
|
||||
"dashboard": {},
|
||||
"noop": {},
|
||||
"ping": {},
|
||||
"prometheus": {},
|
||||
"rest": {}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"services": {
|
||||
"api": {},
|
||||
"dashboard": {},
|
||||
"noop": {},
|
||||
"ping": {},
|
||||
"prometheus": {},
|
||||
"rest": {}
|
||||
|
|
36
pkg/provider/traefik/fixtures/models.json
Normal file
36
pkg/provider/traefik/fixtures/models.json
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"http": {
|
||||
"services": {
|
||||
"noop": {}
|
||||
},
|
||||
"models": {
|
||||
"websecure": {
|
||||
"middlewares": [
|
||||
"test"
|
||||
],
|
||||
"tls": {
|
||||
"options": "opt",
|
||||
"certResolver": "le",
|
||||
"domains": [
|
||||
{
|
||||
"main": "mainA",
|
||||
"sans": [
|
||||
"sanA1",
|
||||
"sanA2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"main": "mainB",
|
||||
"sans": [
|
||||
"sanB1",
|
||||
"sanB2"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tcp": {},
|
||||
"tls": {}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"http": {
|
||||
"services": {
|
||||
"noop": {},
|
||||
"ping": {}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
}
|
||||
},
|
||||
"services": {
|
||||
"noop": {},
|
||||
"ping": {}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"http": {
|
||||
"services": {
|
||||
"noop": {},
|
||||
"prometheus": {}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
}
|
||||
},
|
||||
"services": {
|
||||
"noop": {},
|
||||
"prometheus": {}
|
||||
}
|
||||
},
|
||||
|
|
30
pkg/provider/traefik/fixtures/redirection.json
Normal file
30
pkg/provider/traefik/fixtures/redirection.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"http": {
|
||||
"routers": {
|
||||
"web-to-websecure": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"middlewares": [
|
||||
"redirect-web-to-websecure"
|
||||
],
|
||||
"service": "noop@internal",
|
||||
"rule": "HostRegexp(`{host:.+}`)"
|
||||
}
|
||||
},
|
||||
"middlewares": {
|
||||
"redirect-web-to-websecure": {
|
||||
"redirectScheme": {
|
||||
"scheme": "https",
|
||||
"port": "443",
|
||||
"permanent": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"noop": {}
|
||||
}
|
||||
},
|
||||
"tcp": {},
|
||||
"tls": {}
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
}
|
||||
},
|
||||
"services": {
|
||||
"noop": {},
|
||||
"rest": {}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"http": {
|
||||
"services": {
|
||||
"noop": {},
|
||||
"rest": {}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package traefik
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
|
||||
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||
"github.com/containous/traefik/v2/pkg/config/static"
|
||||
"github.com/containous/traefik/v2/pkg/log"
|
||||
"github.com/containous/traefik/v2/pkg/provider"
|
||||
"github.com/containous/traefik/v2/pkg/safe"
|
||||
"github.com/containous/traefik/v2/pkg/tls"
|
||||
|
@ -43,6 +47,7 @@ func (i *Provider) createConfiguration() *dynamic.Configuration {
|
|||
Routers: make(map[string]*dynamic.Router),
|
||||
Middlewares: make(map[string]*dynamic.Middleware),
|
||||
Services: make(map[string]*dynamic.Service),
|
||||
Models: make(map[string]*dynamic.Model),
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: make(map[string]*dynamic.TCPRouter),
|
||||
|
@ -58,10 +63,73 @@ func (i *Provider) createConfiguration() *dynamic.Configuration {
|
|||
i.pingConfiguration(cfg)
|
||||
i.restConfiguration(cfg)
|
||||
i.prometheusConfiguration(cfg)
|
||||
i.entryPointModels(cfg)
|
||||
i.redirection(cfg)
|
||||
|
||||
cfg.HTTP.Services["noop"] = &dynamic.Service{}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (i *Provider) redirection(cfg *dynamic.Configuration) {
|
||||
for name, ep := range i.staticCfg.EntryPoints {
|
||||
if ep.HTTP.Redirections == nil || ep.HTTP.Redirections.EntryPoint == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
def := ep.HTTP.Redirections
|
||||
rtName := provider.Normalize(name + "-to-" + def.EntryPoint.To)
|
||||
mdName := "redirect-" + rtName
|
||||
|
||||
rt := &dynamic.Router{
|
||||
Rule: "HostRegexp(`{host:.+}`)",
|
||||
EntryPoints: []string{name},
|
||||
Middlewares: []string{mdName},
|
||||
Service: "noop@internal",
|
||||
}
|
||||
|
||||
port, err := i.getEntryPointPort(name, def)
|
||||
if err != nil {
|
||||
log.FromContext(context.Background()).WithField(log.EntryPointName, name).Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
cfg.HTTP.Routers[rtName] = rt
|
||||
|
||||
rs := &dynamic.Middleware{
|
||||
RedirectScheme: &dynamic.RedirectScheme{
|
||||
Scheme: def.EntryPoint.Scheme,
|
||||
Port: port,
|
||||
Permanent: true,
|
||||
},
|
||||
}
|
||||
|
||||
cfg.HTTP.Middlewares[mdName] = rs
|
||||
}
|
||||
}
|
||||
|
||||
func (i *Provider) entryPointModels(cfg *dynamic.Configuration) {
|
||||
for name, ep := range i.staticCfg.EntryPoints {
|
||||
if len(ep.HTTP.Middlewares) == 0 && ep.HTTP.TLS == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
m := &dynamic.Model{
|
||||
Middlewares: ep.HTTP.Middlewares,
|
||||
}
|
||||
|
||||
if ep.HTTP.TLS != nil {
|
||||
m.TLS = &dynamic.RouterTLSConfig{
|
||||
Options: ep.HTTP.TLS.Options,
|
||||
CertResolver: ep.HTTP.TLS.CertResolver,
|
||||
Domains: ep.HTTP.TLS.Domains,
|
||||
}
|
||||
}
|
||||
|
||||
cfg.HTTP.Models[name] = m
|
||||
}
|
||||
}
|
||||
|
||||
func (i *Provider) apiConfiguration(cfg *dynamic.Configuration) {
|
||||
if i.staticCfg.API == nil {
|
||||
return
|
||||
|
@ -163,3 +231,18 @@ func (i *Provider) prometheusConfiguration(cfg *dynamic.Configuration) {
|
|||
|
||||
cfg.HTTP.Services["prometheus"] = &dynamic.Service{}
|
||||
}
|
||||
|
||||
func (i *Provider) getEntryPointPort(name string, def *static.Redirections) (string, error) {
|
||||
dst, ok := i.staticCfg.EntryPoints[def.EntryPoint.To]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("'to' entry point field references a non-existing entry point: %s", name)
|
||||
}
|
||||
|
||||
_, port, err := net.SplitHostPort(dst.Address)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid entry point %q address %q: %v",
|
||||
name, i.staticCfg.EntryPoints[def.EntryPoint.To].Address, err)
|
||||
}
|
||||
|
||||
return port, nil
|
||||
}
|
||||
|
|
|
@ -167,6 +167,47 @@ func Test_createConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "models.json",
|
||||
staticCfg: static.Configuration{
|
||||
EntryPoints: map[string]*static.EntryPoint{
|
||||
"websecure": {
|
||||
HTTP: static.HTTPConfig{
|
||||
Middlewares: []string{"test"},
|
||||
TLS: &static.TLSConfig{
|
||||
Options: "opt",
|
||||
CertResolver: "le",
|
||||
Domains: []types.Domain{
|
||||
{Main: "mainA", SANs: []string{"sanA1", "sanA2"}},
|
||||
{Main: "mainB", SANs: []string{"sanB1", "sanB2"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "redirection.json",
|
||||
staticCfg: static.Configuration{
|
||||
EntryPoints: map[string]*static.EntryPoint{
|
||||
"web": {
|
||||
Address: ":80",
|
||||
HTTP: static.HTTPConfig{
|
||||
Redirections: &static.Redirections{
|
||||
EntryPoint: &static.RedirectEntryPoint{
|
||||
To: "websecure",
|
||||
Scheme: "https",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"websecure": {
|
||||
Address: ":443",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue