Experimental: Update traefik Host() rules for v3

This commit is contained in:
Tom Wiesing 2023-04-12 19:21:11 +02:00
parent 34db2e1923
commit 285aaff77d
No known key found for this signature in database
10 changed files with 60 additions and 13 deletions

3
go.mod
View file

@ -21,6 +21,7 @@ require (
github.com/yuin/goldmark-meta v1.1.0
golang.org/x/crypto v0.8.0
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
golang.org/x/net v0.9.0
golang.org/x/sync v0.1.0
golang.org/x/term v0.7.0
gopkg.in/yaml.v3 v3.0.1
@ -63,8 +64,8 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/time v0.1.0 // indirect
golang.org/x/tools v0.7.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect

2
go.sum
View file

@ -180,6 +180,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View file

@ -5,7 +5,7 @@ import (
"net/url"
"strings"
"github.com/tkw1536/pkglib/collection"
"golang.org/x/net/idna"
)
type HTTPConfig struct {
@ -80,10 +80,7 @@ func (hcfg HTTPConfig) Domains(sub string) []string {
// HostRule returns a HostRule for the provided subdomain.
// See Domains() for usage of sub.
func (hcfg HTTPConfig) HostRule(sub string) string {
quoted := collection.MapSlice(hcfg.Domains(sub), func(name string) string {
return "`" + name + "`"
})
return fmt.Sprintf("Host(%s)", strings.Join(quoted, ","))
return MakeHostRule(hcfg.Domains(sub)...)
}
// HTTPSEnabledEnv returns "true" if https is enabled, and "false" otherwise.
@ -141,3 +138,36 @@ func TrimSuffixFold(s string, suffix string) string {
func (cfg HTTPConfig) DefaultHostRule() string {
return cfg.HostRule("")
}
// MakeHostRule builds a new Host() rule string to be used by traefik.
func MakeHostRule(hosts ...string) string {
var builder strings.Builder
first := true
for _, host := range hosts {
// HACK HACK HACK: Very minimal domain validation to prevent validation.
// Just skip everything that isn't a domain.
if strings.Contains(host, "`") {
continue
}
if first {
builder.WriteString("||Host(`")
} else {
builder.WriteString("Host(`")
}
// domain should be punycode!
domain, err := idna.ToASCII(host)
if err != nil {
domain = host
}
builder.WriteString(domain)
builder.WriteString("`)")
first = false
}
return builder.String()
}

View file

@ -2,7 +2,8 @@ DATA_PATH=${DATA_PATH}
RUNTIME_DIR=${RUNTIME_DIR}
SLUG=${SLUG}
VIRTUAL_HOST=${VIRTUAL_HOST}
HOSTNAME=${HOSTNAME}
HOST_RULE=${HOST_RULE}
DOCKER_NETWORK_NAME=${DOCKER_NETWORK_NAME}
HTTPS_ENABLED=${HTTPS_ENABLED}

View file

@ -4,14 +4,14 @@ services:
barrel:
build: .
restart: always
hostname: ${VIRTUAL_HOST}.wisski
hostname: ${HOSTNAME}
# label it with the current slug
labels:
- "traefik.enable=True"
- "eu.wiss-ki.barrel.distillery=${DOCKER_NETWORK_NAME}"
- "traefik.http.routers.wisski_${SLUG}.rule=Host(`${VIRTUAL_HOST}`)"
- "traefik.http.routers.wisski_${SLUG}.rule=${HOST_RULE}"
- "traefik.http.routers.wisski_${SLUG}.tls=${HTTPS_ENABLED}"
- "traefik.http.routers.wisski_${SLUG}.tls.certresolver=distillery"
- "traefik.http.services.wisski_${SLUG}.loadbalancer.server.port=8080"

View file

@ -25,7 +25,8 @@ func (barrel *Barrel) Stack() component.StackWithResources {
"DOCKER_NETWORK_NAME": barrel.Malt.Config.Docker.Network(),
"SLUG": barrel.Slug,
"VIRTUAL_HOST": barrel.Domain(),
"HOST_RULE": barrel.HostRule(),
"HOSTNAME": barrel.Hostname(),
"HTTPS_ENABLED": barrel.Malt.Config.HTTP.HTTPSEnabledEnv(),
"DATA_PATH": filepath.Join(barrel.FilesystemBase, "data"),

View file

@ -1,5 +1,5 @@
SLUG=${SLUG}
VIRTUAL_HOST=${VIRTUAL_HOST}
HOST_RULE=${HOST_RULE}
DOCKER_NETWORK_NAME=${DOCKER_NETWORK_NAME}
HTTPS_ENABLED=${HTTPS_ENABLED}

View file

@ -32,7 +32,8 @@ func (reserve *Reserve) Stack() component.StackWithResources {
"DOCKER_NETWORK_NAME": reserve.Malt.Config.Docker.Network(),
"SLUG": reserve.Slug,
"VIRTUAL_HOST": reserve.Domain(),
"HOST_RULE": reserve.HostRule(),
"HOSTNAME": reserve.Hostname(),
"HTTPS_ENABLED": reserve.Malt.Config.HTTP.HTTPSEnabledEnv(),
},
}

View file

@ -11,7 +11,7 @@ services:
- "traefik.enable=True"
- "eu.wiss-ki.barrel.distillery=${DOCKER_NETWORK_NAME}"
- "traefik.http.routers.reserve_${SLUG}.rule=Host(`${VIRTUAL_HOST}`)"
- "traefik.http.routers.reserve_${SLUG}.rule=${HOST_RULE}"
- "traefik.http.routers.reserve_${SLUG}.tls=${HTTPS_ENABLED}"
- "traefik.http.routers.reserve_${SLUG}.tls.certresolver=distillery"
- "traefik.http.services.reserve_${SLUG}.loadbalancer.server.port=8043"

View file

@ -2,6 +2,8 @@ package liquid
import (
"net/url"
"github.com/FAU-CDI/wisski-distillery/internal/config"
)
// Domain returns the full domain name of this WissKI
@ -9,6 +11,15 @@ func (liquid *Liquid) Domain() string {
return liquid.Config.HTTP.HostFromSlug(liquid.Slug)
}
func (liquid *Liquid) Hostname() string {
return liquid.Domain() + ".wisski"
}
// HostRule returns a host rule for this wisski
func (liquid *Liquid) HostRule() string {
return config.MakeHostRule(liquid.Domain())
}
// URL returns the public URL of this instance
func (liquid *Liquid) URL() *url.URL {
// setup domain and path