From 188ef84c4f5147946a14df19eb50f886630c93a1 Mon Sep 17 00:00:00 2001 From: "kalle (jag)" Date: Tue, 11 Oct 2022 09:36:08 +0200 Subject: [PATCH] Allow to define default entrypoints (for HTTP/TCP) --- cmd/traefik/traefik.go | 18 ++++- cmd/traefik/traefik_test.go | 77 +++++++++++++++++++ .../reference/static-configuration/cli-ref.md | 3 + .../reference/static-configuration/env-ref.md | 3 + .../reference/static-configuration/file.toml | 1 + .../reference/static-configuration/file.yaml | 1 + docs/content/routing/entrypoints.md | 48 ++++++++++++ docs/content/routing/routers/index.md | 24 +++--- pkg/config/static/entrypoints.go | 1 + 9 files changed, 163 insertions(+), 13 deletions(-) diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index f6866aa59..42b48b2d8 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -366,8 +366,24 @@ func getHTTPChallengeHandler(acmeProviders []*acme.Provider, httpChallengeProvid func getDefaultsEntrypoints(staticConfiguration *static.Configuration) []string { var defaultEntryPoints []string + + // Determines if at least one EntryPoint is configured to be used by default. + var hasDefinedDefaults bool + for _, ep := range staticConfiguration.EntryPoints { + if ep.AsDefault { + hasDefinedDefaults = true + break + } + } + for name, cfg := range staticConfiguration.EntryPoints { - // Traefik Hub entryPoint should not be part of the set of default entryPoints. + // By default all entrypoints are considered. + // If at least one is flagged, then only flagged entrypoints are included. + if hasDefinedDefaults && !cfg.AsDefault { + continue + } + + // Traefik Hub entryPoint should not be used as a default entryPoint. if hub.APIEntrypoint == name || hub.TunnelEntrypoint == name { continue } diff --git a/cmd/traefik/traefik_test.go b/cmd/traefik/traefik_test.go index 26bc8643c..c1d677058 100644 --- a/cmd/traefik/traefik_test.go +++ b/cmd/traefik/traefik_test.go @@ -9,6 +9,7 @@ import ( "github.com/go-kit/kit/metrics" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traefik/traefik/v2/pkg/config/static" ) // FooCert is a PEM-encoded TLS cert. @@ -114,3 +115,79 @@ func TestAppendCertMetric(t *testing.T) { }) } } + +func TestGetDefaultsEntrypoints(t *testing.T) { + testCases := []struct { + desc string + entrypoints static.EntryPoints + expected []string + }{ + { + desc: "Skips special names", + entrypoints: map[string]*static.EntryPoint{ + "web": { + Address: ":80", + }, + "traefik": { + Address: ":8080", + }, + "traefikhub-api": { + Address: ":9900", + }, + "traefikhub-tunl": { + Address: ":9901", + }, + }, + expected: []string{"web"}, + }, + { + desc: "Two EntryPoints not attachable", + entrypoints: map[string]*static.EntryPoint{ + "web": { + Address: ":80", + }, + "websecure": { + Address: ":443", + }, + }, + expected: []string{"web", "websecure"}, + }, + { + desc: "Two EntryPoints only one attachable", + entrypoints: map[string]*static.EntryPoint{ + "web": { + Address: ":80", + }, + "websecure": { + Address: ":443", + AsDefault: true, + }, + }, + expected: []string{"websecure"}, + }, + { + desc: "Two attachable EntryPoints", + entrypoints: map[string]*static.EntryPoint{ + "web": { + Address: ":80", + AsDefault: true, + }, + "websecure": { + Address: ":443", + AsDefault: true, + }, + }, + expected: []string{"web", "websecure"}, + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + actual := getDefaultsEntrypoints(&static.Configuration{ + EntryPoints: test.entrypoints, + }) + + assert.ElementsMatch(t, test.expected, actual) + }) + } +} diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index 6511cce35..3e048d2d3 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -108,6 +108,9 @@ Entry points definition. (Default: ```false```) `--entrypoints..address`: Entry point address. +`--entrypoints..asdefault`: +Adds this EntryPoint to the list of default EntryPoints to be used on routers that don't have any Entrypoint defined. (Default: ```false```) + `--entrypoints..forwardedheaders.insecure`: Trust all forwarded headers. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index 6f55fdf8c..088312ec3 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -108,6 +108,9 @@ Entry points definition. (Default: ```false```) `TRAEFIK_ENTRYPOINTS__ADDRESS`: Entry point address. +`TRAEFIK_ENTRYPOINTS__ASDEFAULT`: +Adds this EntryPoint to the list of default EntryPoints to be used on routers that don't have any Entrypoint defined. (Default: ```false```) + `TRAEFIK_ENTRYPOINTS__FORWARDEDHEADERS_INSECURE`: Trust all forwarded headers. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index 4fff202b2..698e39493 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -14,6 +14,7 @@ [entryPoints] [entryPoints.EntryPoint0] address = "foobar" + asDefault = true [entryPoints.EntryPoint0.transport] [entryPoints.EntryPoint0.transport.lifeCycle] requestAcceptGraceTimeout = "42s" diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml index 38b0e2637..a2c753ef1 100644 --- a/docs/content/reference/static-configuration/file.yaml +++ b/docs/content/reference/static-configuration/file.yaml @@ -14,6 +14,7 @@ serversTransport: entryPoints: EntryPoint0: address: foobar + asDefault: true transport: lifeCycle: requestAcceptGraceTimeout: 42s diff --git a/docs/content/routing/entrypoints.md b/docs/content/routing/entrypoints.md index f20c0b456..119fa60e3 100644 --- a/docs/content/routing/entrypoints.md +++ b/docs/content/routing/entrypoints.md @@ -233,6 +233,54 @@ If both TCP and UDP are wanted for the same port, two entryPoints definitions ar Full details for how to specify `address` can be found in [net.Listen](https://golang.org/pkg/net/#Listen) (and [net.Dial](https://golang.org/pkg/net/#Dial)) of the doc for go. +### AsDefault + +_Optional, Default=false_ + +The `AsDefault` option marks the EntryPoint to be in the list of default EntryPoints. +EntryPoints in this list are used (by default) on HTTP and TCP routers that do not define their own [EntryPoints option](./routers/index.md#entrypoints). + +!!! info "List of default EntryPoints" + + If there is no EntryPoint with the `AsDefault` option set to `true`, + then the list of default EntryPoints includes all HTTP/TCP EntryPoints. + + If at least one EntryPoint has the `AsDefault` option set to `true`, + then the list of default EntryPoints includes only EntryPoints that have the `AsDefault` option set to `true`. + + Some built-in EntryPoints are always excluded from the list, namely: `traefik`, `traefikhub-api`, and `traefikhub-tunl`. + +!!! warning "Only TCP and HTTP" + + The `AsDefault` option has no effect on UDP EntryPoints. + When a UDP router does not define the [EntryPoints option](./routers/index.md#entrypoints_2), + it is attached to all available UDP EntryPoints. + +??? example "Defining only one EntryPoint as default" + + ```yaml tab="File (yaml)" + entryPoints: + web: + address: ":80" + websecure: + address: ":443" + asDefault: true + ``` + + ```toml tab="File (TOML)" + [entryPoints.web] + address = ":80" + [entryPoints.websecure] + address = ":443" + asDefault = true + ``` + + ```bash tab="CLI" + --entrypoints.web.address=:80 + --entrypoints.websecure.address=:443 + --entrypoints.websecure.asDefault=true + ``` + ### HTTP/2 #### `maxConcurrentStreams` diff --git a/docs/content/routing/routers/index.md b/docs/content/routing/routers/index.md index 3a5045a27..446857266 100644 --- a/docs/content/routing/routers/index.md +++ b/docs/content/routing/routers/index.md @@ -94,7 +94,7 @@ or act before forwarding the request to the service. ### EntryPoints -If not specified, HTTP routers will accept requests from all defined entry points. +If not specified, HTTP routers will accept requests from all EntryPoints in the [list of default EntryPoints](../entrypoints.md#asdefault). If you want to limit the router scope to a set of entry points, set the `entryPoints` option. ??? example "Listens to Every EntryPoint" @@ -106,7 +106,7 @@ If you want to limit the router scope to a set of entry points, set the `entryPo http: routers: Router-1: - # By default, routers listen to every entry points + # By default, routers listen to every EntryPoints. rule: "Host(`example.com`)" service: "service-1" ``` @@ -115,7 +115,7 @@ If you want to limit the router scope to a set of entry points, set the `entryPo ## Dynamic configuration [http.routers] [http.routers.Router-1] - # By default, routers listen to every entry points + # By default, routers listen to every EntryPoints. rule = "Host(`example.com`)" service = "service-1" ``` @@ -666,12 +666,12 @@ The [supported `provider` table](../../https/acme.md#providers) indicates if the ### General -If both HTTP routers and TCP routers listen to the same entry points, the TCP routers will apply *before* the HTTP routers. +If both HTTP routers and TCP routers listen to the same EntryPoint, the TCP routers will apply *before* the HTTP routers. If no matching route is found for the TCP routers, then the HTTP routers will take over. ### EntryPoints -If not specified, TCP routers will accept requests from all defined entry points. +If not specified, TCP routers will accept requests from all EntryPoints in the [list of default EntryPoints](../entrypoints.md#asdefault).. If you want to limit the router scope to a set of entry points, set the entry points option. ??? info "How to handle Server First protocols?" @@ -699,7 +699,7 @@ If you want to limit the router scope to a set of entry points, set the entry po tcp: routers: Router-1: - # By default, routers listen to every entrypoints + # By default, routers listen to every EntryPoints. rule: "HostSNI(`example.com`)" service: "service-1" # will route TLS requests (and ignore non tls requests) @@ -711,7 +711,7 @@ If you want to limit the router scope to a set of entry points, set the entry po [tcp.routers] [tcp.routers.Router-1] - # By default, routers listen to every entrypoints + # By default, routers listen to every EntryPoints. rule = "HostSNI(`example.com`)" service = "service-1" # will route TLS requests (and ignore non tls requests) @@ -751,7 +751,7 @@ If you want to limit the router scope to a set of entry points, set the entry po --entrypoints.other.address=:9090 ``` -??? example "Listens to Specific Entry Points" +??? example "Listens to Specific EntryPoints" **Dynamic Configuration** @@ -1198,12 +1198,12 @@ So UDP "routers" at this time are pretty much only load-balancers in one form or As expected, a `timeout` is associated to each of these sessions, so that they get cleaned out if they go through a period of inactivity longer than a given duration. Timeout can be configured using the `entryPoints.name.udp.timeout` option as described - under [entry points](../entrypoints/#udp-options). + under [EntryPoints](../entrypoints/#udp-options). ### EntryPoints -If not specified, UDP routers will accept packets from all defined (UDP) entry points. -If one wants to limit the router scope to a set of entry points, one should set the entry points option. +If not specified, UDP routers will accept packets from all defined (UDP) EntryPoints. +If one wants to limit the router scope to a set of EntryPoints, one should set the `entryPoints` option. ??? example "Listens to Every Entry Point" @@ -1267,7 +1267,7 @@ If one wants to limit the router scope to a set of entry points, one should set --entrypoints.streaming.address=":9191/udp" ``` -??? example "Listens to Specific Entry Points" +??? example "Listens to Specific EntryPoints" **Dynamic Configuration** diff --git a/pkg/config/static/entrypoints.go b/pkg/config/static/entrypoints.go index f97d78e22..7863f1bcb 100644 --- a/pkg/config/static/entrypoints.go +++ b/pkg/config/static/entrypoints.go @@ -12,6 +12,7 @@ import ( // EntryPoint holds the entry point configuration. type EntryPoint struct { Address string `description:"Entry point address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` + AsDefault bool `description:"Adds this EntryPoint to the list of default EntryPoints to be used on routers that don't have any Entrypoint defined." json:"asDefault,omitempty" toml:"asDefault,omitempty" yaml:"asDefault,omitempty"` Transport *EntryPointsTransport `description:"Configures communication between clients and Traefik." json:"transport,omitempty" toml:"transport,omitempty" yaml:"transport,omitempty" export:"true"` ProxyProtocol *ProxyProtocol `description:"Proxy-Protocol configuration." json:"proxyProtocol,omitempty" toml:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` ForwardedHeaders *ForwardedHeaders `description:"Trust client forwarding headers." json:"forwardedHeaders,omitempty" toml:"forwardedHeaders,omitempty" yaml:"forwardedHeaders,omitempty" export:"true"`