diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go
index 875eff503..47f409a0b 100644
--- a/cmd/traefik/traefik.go
+++ b/cmd/traefik/traefik.go
@@ -34,6 +34,7 @@ import (
"github.com/traefik/traefik/v2/pkg/pilot"
"github.com/traefik/traefik/v2/pkg/provider/acme"
"github.com/traefik/traefik/v2/pkg/provider/aggregator"
+ "github.com/traefik/traefik/v2/pkg/provider/hub"
"github.com/traefik/traefik/v2/pkg/provider/traefik"
"github.com/traefik/traefik/v2/pkg/safe"
"github.com/traefik/traefik/v2/pkg/server"
@@ -215,8 +216,6 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
}
if staticConfiguration.Pilot != nil {
- log.WithoutContext().Warn("Traefik Pilot is deprecated and will be removed soon. Please check our Blog for migration instructions later this year")
-
version.PilotEnabled = staticConfiguration.Pilot.Dashboard
}
@@ -363,7 +362,7 @@ func getDefaultsEntrypoints(staticConfiguration *static.Configuration) []string
var defaultEntryPoints []string
for name, cfg := range staticConfiguration.EntryPoints {
// Traefik Hub entryPoint should not be part of the set of default entryPoints.
- if staticConfiguration.Hub != nil && staticConfiguration.Hub.EntryPoint == name {
+ if hub.APIEntrypoint == name || hub.TunnelEntrypoint == name {
continue
}
diff --git a/docs/content/migration/v2.md b/docs/content/migration/v2.md
index d3f80dcde..fa5b87112 100644
--- a/docs/content/migration/v2.md
+++ b/docs/content/migration/v2.md
@@ -457,10 +457,3 @@ the value for the method label becomes `EXTENSION_METHOD`, instead of the reques
### Tracing
In `v2.6.1`, the Datadog tags added to a span changed from `service.name` to `traefik.service.name` and from `router.name` to `traefik.router.name`.
-
-## v2.7
-
-### Traefik Pilot
-
-In `v2.7`, the `pilot.token` and `pilot.dashboard` options are deprecated.
-Please check the [feature deprecation page](../deprecation/features.md) and our Blog for migration instructions later this year.
diff --git a/docs/content/plugins/index.md b/docs/content/plugins/index.md
index 421044278..f5062b21f 100644
--- a/docs/content/plugins/index.md
+++ b/docs/content/plugins/index.md
@@ -5,11 +5,6 @@ description: "Learn how to connect Traefik Proxy with Pilot, a SaaS platform tha
# Plugins and Traefik Pilot
-!!! warning "Traefik Pilot Deprecation"
-
- Traefik Pilot is deprecated and will be removed soon.
- Please check our Blog for migration instructions later this year.
-
Traefik Pilot is a software-as-a-service (SaaS) platform that connects to Traefik to extend its capabilities.
It offers a number of features to enhance observability and control of Traefik through a global control plane and dashboard, including:
diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md
index 9345cded4..bcd6fc904 100644
--- a/docs/content/reference/static-configuration/cli-ref.md
+++ b/docs/content/reference/static-configuration/cli-ref.md
@@ -222,9 +222,6 @@ The maximal depth of DNS recursive resolving (Default: ```5```)
`--hub`:
Traefik Hub configuration. (Default: ```false```)
-`--hub.entrypoint`:
-Entrypoint that exposes data for Traefik Hub. It should be a dedicated one, and not used by any router. (Default: ```traefik-hub```)
-
`--hub.tls.ca`:
The certificate authority authenticates the Traefik Hub Agent certificate.
diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md
index 340917400..ccaacfe1f 100644
--- a/docs/content/reference/static-configuration/env-ref.md
+++ b/docs/content/reference/static-configuration/env-ref.md
@@ -222,9 +222,6 @@ The maximal depth of DNS recursive resolving (Default: ```5```)
`TRAEFIK_HUB`:
Traefik Hub configuration. (Default: ```false```)
-`TRAEFIK_HUB_ENTRYPOINT`:
-Entrypoint that exposes data for Traefik Hub. It should be a dedicated one, and not used by any router. (Default: ```traefik-hub```)
-
`TRAEFIK_HUB_TLS_CA`:
The certificate authority authenticates the Traefik Hub Agent certificate.
diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml
index cab590f6f..d81a6b7d9 100644
--- a/docs/content/reference/static-configuration/file.toml
+++ b/docs/content/reference/static-configuration/file.toml
@@ -426,7 +426,6 @@
dashboard = true
[hub]
- entrypoint = "foobar"
[hub.tls]
insecure = true
ca = "foobar"
diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml
index 88e602f1d..5da697177 100644
--- a/docs/content/reference/static-configuration/file.yaml
+++ b/docs/content/reference/static-configuration/file.yaml
@@ -447,7 +447,6 @@ pilot:
token: foobar
dashboard: true
hub:
- entrypoint: foobar
tls:
insecure: true
ca: foobar
diff --git a/docs/content/traefik-hub/index.md b/docs/content/traefik-hub/index.md
deleted file mode 100644
index d6fa92dfe..000000000
--- a/docs/content/traefik-hub/index.md
+++ /dev/null
@@ -1,295 +0,0 @@
-# Traefik Hub (Experimental)
-
-## Overview
-
-Once the Traefik Hub Experimental feature is enabled in Traefik,
-Traefik and its local agent communicate together.
-This agent can:
-
-* get the Traefik metrics to display them in the Traefik Hub UI
-* secure the Traefik routers
-* provide ACME certificates to Traefik
-* transfer requests from the SaaS Platform to Traefik (and then avoid the users to expose directly their infrastructure on the internet)
-
-!!! warning "Traefik Hub EntryPoint"
-
- When the Traefik Hub feature is enabled, Traefik exposes some services meant for the Traefik Hub Agent on a dedicated entryPoint (on port `9900` by default).
- Given their sensitive nature, those services should not be publicly exposed.
- Also this dedicated entryPoint, regardless of how it is created (default, or user-defined), should not be used by anything other than the Hub Agent.
-
-!!! important "Learn More About Traefik Hub"
-
- This section is intended only as a brief overview for Traefik users who are not familiar with Traefik Hub.
- To explore all that Traefik Hub has to offer, please consult the [Traefik Hub Documentation](https://doc.traefik.io/traefik-hub).
-
-!!! Note "Prerequisites"
-
- * Traefik Hub is compatible with Traefik Proxy 2.7 or later.
- * The Traefik Hub Agent must be installed to connect to the Traefik Hub platform.
- * Activate this feature in the experimental section of the static configuration.
-
-!!! example "Minimal Static Configuration to Activate Traefik Hub"
-
- ```yaml tab="File (YAML)"
- experimental:
- hub: true
-
- hub:
- tls:
- insecure: true
-
- metrics:
- prometheus: {}
- ```
-
- ```toml tab="File (TOML)"
- [experimental]
- hub = true
-
- [hub]
- [hub.tls]
- insecure = true
-
- [metrics]
- [metrics.prometheus]
- ```
-
- ```bash tab="CLI"
- --experimental.hub
- --hub.tls.insecure=true
- --metrics.prometheus=true
- ```
-
-## Configuration
-
-### `entryPoint`
-
-_Optional, Default="traefik-hub"_
-
-Defines the entryPoint that exposes data for Traefik Hub Agent.
-
-!!! info
-
- * If no entryPoint is defined, a default `traefik-hub` entryPoint is created (on port `9900`).
- * If defined, the value must match an existing entryPoint name.
- * This dedicated Traefik Hub entryPoint should not be used by anything other than Traefik Hub.
-
-```yaml tab="File (YAML)"
-entryPoints:
- hub-ep: ":8000"
-
-hub:
- entryPoint: "hub-ep"
-```
-
-```toml tab="File (TOML)"
-[entryPoints.hub-ep]
- address = ":8000"
-
-[hub]
- entryPoint = "hub-ep"
-```
-
-```bash tab="CLI"
---entrypoints.hub-ep.address=:8000
---hub.entrypoint=hub-ep
-```
-
-### `tls`
-
-_Required, Default=None_
-
-This section allows configuring mutual TLS connection between Traefik Proxy and the Traefik Hub Agent.
-The key and the certificate are the credentials for Traefik Proxy as a TLS client.
-The certificate authority authenticates the Traefik Hub Agent certificate.
-
-!!! note "Certificate Domain"
-
- The certificate must be valid for the `proxy.traefik` domain.
-
-!!! note "Certificates Definition"
-
- Certificates can be defined either by their content or their path.
-
-!!! note "Insecure Mode"
-
- The `insecure` option is mutually exclusive with any other option.
-
-```yaml tab="File (YAML)"
-hub:
- tls:
- ca: /path/to/ca.pem
- cert: /path/to/cert.pem
- key: /path/to/key.pem
-```
-
-```toml tab="File (TOML)"
-[hub.tls]
- ca= "/path/to/ca.pem"
- cert= "/path/to/cert.pem"
- key= "/path/to/key.pem"
-```
-
-```bash tab="CLI"
---hub.tls.ca=/path/to/ca.pem
---hub.tls.cert=/path/to/cert.pem
---hub.tls.key=/path/to/key.pem
-```
-
-### `tls.ca`
-
-The certificate authority authenticates the Traefik Hub Agent certificate.
-
-```yaml tab="File (YAML)"
-hub:
- tls:
- ca: |-
- -----BEGIN CERTIFICATE-----
- MIIBcjCCARegAwIBAgIQaewCzGdRz5iNnjAiEoO5AzAKBggqhkjOPQQDAjASMRAw
- DgYDVQQKEwdBY21lIENvMCAXDTIyMDMyMTE2MTY0NFoYDzIxMjIwMjI1MTYxNjQ0
- WjASMRAwDgYDVQQKEwdBY21lIENvMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
- ZaKYPj2G8Hnmju6jbHt+vODwKqNDVQMH5nxhtAgSUZS61mLWwZvvUhIYLNPwHz8a
- x8C7+cuihEC6Tzvn8DeGeKNNMEswDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG
- CCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w
- CgYIKoZIzj0EAwIDSQAwRgIhAO8sucDGY+JOrNgQg1a9ZqqYvbxPFnYsSZr7F/vz
- aUX2AiEAilZ+M5eX4RiMFc3nlm9qVs1LZhV3dZW/u80/mPQ/oaY=
- -----END CERTIFICATE-----
-```
-
-```toml tab="File (TOML)"
-[hub.tls]
- ca = """-----BEGIN CERTIFICATE-----
-MIIBcjCCARegAwIBAgIQaewCzGdRz5iNnjAiEoO5AzAKBggqhkjOPQQDAjASMRAw
-DgYDVQQKEwdBY21lIENvMCAXDTIyMDMyMTE2MTY0NFoYDzIxMjIwMjI1MTYxNjQ0
-WjASMRAwDgYDVQQKEwdBY21lIENvMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
-ZaKYPj2G8Hnmju6jbHt+vODwKqNDVQMH5nxhtAgSUZS61mLWwZvvUhIYLNPwHz8a
-x8C7+cuihEC6Tzvn8DeGeKNNMEswDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG
-CCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w
-CgYIKoZIzj0EAwIDSQAwRgIhAO8sucDGY+JOrNgQg1a9ZqqYvbxPFnYsSZr7F/vz
-aUX2AiEAilZ+M5eX4RiMFc3nlm9qVs1LZhV3dZW/u80/mPQ/oaY=
------END CERTIFICATE-----"""
-```
-
-```bash tab="CLI"
---hub.tls.ca=-----BEGIN CERTIFICATE-----
-MIIBcjCCARegAwIBAgIQaewCzGdRz5iNnjAiEoO5AzAKBggqhkjOPQQDAjASMRAw
-DgYDVQQKEwdBY21lIENvMCAXDTIyMDMyMTE2MTY0NFoYDzIxMjIwMjI1MTYxNjQ0
-WjASMRAwDgYDVQQKEwdBY21lIENvMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
-ZaKYPj2G8Hnmju6jbHt+vODwKqNDVQMH5nxhtAgSUZS61mLWwZvvUhIYLNPwHz8a
-x8C7+cuihEC6Tzvn8DeGeKNNMEswDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG
-CCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w
-CgYIKoZIzj0EAwIDSQAwRgIhAO8sucDGY+JOrNgQg1a9ZqqYvbxPFnYsSZr7F/vz
-aUX2AiEAilZ+M5eX4RiMFc3nlm9qVs1LZhV3dZW/u80/mPQ/oaY=
------END CERTIFICATE-----
-```
-
-### `tls.cert`
-
-The TLS certificate for Traefik Proxy as a TLS client.
-
-!!! note "Certificate Domain"
-
- The certificate must be valid for the `proxy.traefik` domain.
-
-```yaml tab="File (YAML)"
-hub:
- tls:
- cert: |-
- -----BEGIN CERTIFICATE-----
- MIIBcjCCARegAwIBAgIQaewCzGdRz5iNnjAiEoO5AzAKBggqhkjOPQQDAjASMRAw
- DgYDVQQKEwdBY21lIENvMCAXDTIyMDMyMTE2MTY0NFoYDzIxMjIwMjI1MTYxNjQ0
- WjASMRAwDgYDVQQKEwdBY21lIENvMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
- ZaKYPj2G8Hnmju6jbHt+vODwKqNDVQMH5nxhtAgSUZS61mLWwZvvUhIYLNPwHz8a
- x8C7+cuihEC6Tzvn8DeGeKNNMEswDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG
- CCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w
- CgYIKoZIzj0EAwIDSQAwRgIhAO8sucDGY+JOrNgQg1a9ZqqYvbxPFnYsSZr7F/vz
- aUX2AiEAilZ+M5eX4RiMFc3nlm9qVs1LZhV3dZW/u80/mPQ/oaY=
- -----END CERTIFICATE-----
-```
-
-```toml tab="File (TOML)"
-[hub.tls]
- cert = """-----BEGIN CERTIFICATE-----
-MIIBcjCCARegAwIBAgIQaewCzGdRz5iNnjAiEoO5AzAKBggqhkjOPQQDAjASMRAw
-DgYDVQQKEwdBY21lIENvMCAXDTIyMDMyMTE2MTY0NFoYDzIxMjIwMjI1MTYxNjQ0
-WjASMRAwDgYDVQQKEwdBY21lIENvMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
-ZaKYPj2G8Hnmju6jbHt+vODwKqNDVQMH5nxhtAgSUZS61mLWwZvvUhIYLNPwHz8a
-x8C7+cuihEC6Tzvn8DeGeKNNMEswDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG
-CCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w
-CgYIKoZIzj0EAwIDSQAwRgIhAO8sucDGY+JOrNgQg1a9ZqqYvbxPFnYsSZr7F/vz
-aUX2AiEAilZ+M5eX4RiMFc3nlm9qVs1LZhV3dZW/u80/mPQ/oaY=
------END CERTIFICATE-----"""
-```
-
-```bash tab="CLI"
---hub.tls.cert=-----BEGIN CERTIFICATE-----
-MIIBcjCCARegAwIBAgIQaewCzGdRz5iNnjAiEoO5AzAKBggqhkjOPQQDAjASMRAw
-DgYDVQQKEwdBY21lIENvMCAXDTIyMDMyMTE2MTY0NFoYDzIxMjIwMjI1MTYxNjQ0
-WjASMRAwDgYDVQQKEwdBY21lIENvMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
-ZaKYPj2G8Hnmju6jbHt+vODwKqNDVQMH5nxhtAgSUZS61mLWwZvvUhIYLNPwHz8a
-x8C7+cuihEC6Tzvn8DeGeKNNMEswDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG
-CCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w
-CgYIKoZIzj0EAwIDSQAwRgIhAO8sucDGY+JOrNgQg1a9ZqqYvbxPFnYsSZr7F/vz
-aUX2AiEAilZ+M5eX4RiMFc3nlm9qVs1LZhV3dZW/u80/mPQ/oaY=
------END CERTIFICATE-----
-```
-
-### `tls.key`
-
-The TLS key for Traefik Proxy as a TLS client.
-
-```yaml tab="File (YAML)"
-hub:
- tls:
- key: |-
- -----BEGIN PRIVATE KEY-----
- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgm+XJ3LVrTbbirJea
- O+Crj2ADVsVHjMuiyd72VE3lgxihRANCAARlopg+PYbweeaO7qNse3684PAqo0NV
- AwfmfGG0CBJRlLrWYtbBm+9SEhgs0/AfPxrHwLv5y6KEQLpPO+fwN4Z4
- -----END PRIVATE KEY-----
-```
-
-```toml tab="File (TOML)"
-[hub.tls]
- key = """-----BEGIN PRIVATE KEY-----
-MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgm+XJ3LVrTbbirJea
-O+Crj2ADVsVHjMuiyd72VE3lgxihRANCAARlopg+PYbweeaO7qNse3684PAqo0NV
-AwfmfGG0CBJRlLrWYtbBm+9SEhgs0/AfPxrHwLv5y6KEQLpPO+fwN4Z4
------END PRIVATE KEY-----"""
-```
-
-```bash tab="CLI"
---hub.tls.key=-----BEGIN PRIVATE KEY-----
-MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgm+XJ3LVrTbbirJea
-O+Crj2ADVsVHjMuiyd72VE3lgxihRANCAARlopg+PYbweeaO7qNse3684PAqo0NV
-AwfmfGG0CBJRlLrWYtbBm+9SEhgs0/AfPxrHwLv5y6KEQLpPO+fwN4Z4
------END PRIVATE KEY-----
-```
-
-### `tls.insecure`
-
-_Optional, Default=false_
-
-Enables an insecure TLS connection that uses default credentials,
-and which has no peer authentication between Traefik Proxy and the Traefik Hub Agent.
-The `insecure` option is mutually exclusive with any other option.
-
-!!! warning "Security Consideration"
-
- Do not use this setup in production.
- This option implies sensitive data can be exposed to potential malicious third-party programs.
-
-```yaml tab="File (YAML)"
-hub:
- tls:
- insecure: true
-```
-
-```toml tab="File (TOML)"
-[hub.tls]
- insecure = true
-```
-
-```bash tab="CLI"
---hub.tls.insecure=true
-```
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index a3a8a0497..08c78cae2 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -136,7 +136,6 @@ nav:
- 'InFlightConn': 'middlewares/tcp/inflightconn.md'
- 'IpWhitelist': 'middlewares/tcp/ipwhitelist.md'
- 'Plugins & Traefik Pilot': 'plugins/index.md'
- - 'Traefik Hub': 'traefik-hub/index.md'
- 'Operations':
- 'CLI': 'operations/cli.md'
- 'Dashboard' : 'operations/dashboard.md'
diff --git a/pkg/config/static/hub.go b/pkg/config/static/hub.go
new file mode 100644
index 000000000..ee78de975
--- /dev/null
+++ b/pkg/config/static/hub.go
@@ -0,0 +1,53 @@
+package static
+
+import (
+ "errors"
+
+ "github.com/traefik/traefik/v2/pkg/log"
+ "github.com/traefik/traefik/v2/pkg/provider/hub"
+)
+
+func (c *Configuration) initHubProvider() error {
+ // Hub provider is an experimental feature. It requires the experimental flag to be enabled before continuing.
+ if c.Experimental == nil || !c.Experimental.Hub {
+ return errors.New("the experimental flag for Hub is not set")
+ }
+
+ if _, ok := c.EntryPoints[hub.TunnelEntrypoint]; !ok {
+ var ep EntryPoint
+ ep.SetDefaults()
+ ep.Address = ":9901"
+ c.EntryPoints[hub.TunnelEntrypoint] = &ep
+ log.WithoutContext().Infof("The entryPoint %q is created on port 9901 to allow exposition of services.", hub.TunnelEntrypoint)
+ }
+
+ if c.Hub.TLS == nil {
+ return nil
+ }
+
+ if c.Hub.TLS.Insecure && (c.Hub.TLS.CA != "" || c.Hub.TLS.Cert != "" || c.Hub.TLS.Key != "") {
+ return errors.New("mTLS configuration for Hub and insecure TLS for Hub are mutually exclusive")
+ }
+
+ if !c.Hub.TLS.Insecure && (c.Hub.TLS.CA == "" || c.Hub.TLS.Cert == "" || c.Hub.TLS.Key == "") {
+ return errors.New("incomplete mTLS configuration for Hub")
+ }
+
+ if c.Hub.TLS.Insecure {
+ log.WithoutContext().Warn("Hub is in `insecure` mode. Do not run in production with this setup.")
+ }
+
+ if _, ok := c.EntryPoints[hub.APIEntrypoint]; !ok {
+ var ep EntryPoint
+ ep.SetDefaults()
+ ep.Address = ":9900"
+ c.EntryPoints[hub.APIEntrypoint] = &ep
+ log.WithoutContext().Infof("The entryPoint %q is created on port 9900 to allow Traefik to communicate with the Hub Agent for Traefik.", hub.APIEntrypoint)
+ }
+
+ c.EntryPoints[hub.APIEntrypoint].HTTP.TLS = &TLSConfig{
+ Options: "traefik-hub",
+ }
+
+ return nil
+}
diff --git a/pkg/config/static/pilot.go b/pkg/config/static/pilot.go
index f3699a729..147c8917b 100644
--- a/pkg/config/static/pilot.go
+++ b/pkg/config/static/pilot.go
@@ -1,7 +1,6 @@
package static
// Pilot Configuration related to Traefik Pilot.
-// Deprecated.
type Pilot struct {
Token string `description:"Traefik Pilot token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"`
Dashboard bool `description:"Enable Traefik Pilot in the dashboard." json:"dashboard,omitempty" toml:"dashboard,omitempty" yaml:"dashboard,omitempty"`
diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go
index 961786f94..b285996f8 100644
--- a/pkg/config/static/static_config.go
+++ b/pkg/config/static/static_config.go
@@ -1,7 +1,6 @@
package static
import (
- "errors"
"fmt"
stdlog "log"
"strings"
@@ -78,7 +77,6 @@ type Configuration struct {
CertificatesResolvers map[string]CertificateResolver `description:"Certificates resolvers configuration." json:"certificatesResolvers,omitempty" toml:"certificatesResolvers,omitempty" yaml:"certificatesResolvers,omitempty" export:"true"`
- // Deprecated.
Pilot *Pilot `description:"Traefik Pilot configuration." json:"pilot,omitempty" toml:"pilot,omitempty" yaml:"pilot,omitempty" export:"true"`
Hub *hub.Provider `description:"Traefik Hub configuration." json:"hub,omitempty" toml:"hub,omitempty" yaml:"hub,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
@@ -201,7 +199,7 @@ type Providers struct {
// It also takes care of maintaining backwards compatibility.
func (c *Configuration) SetEffectiveConfiguration() {
// Creates the default entry point if needed
- if len(c.EntryPoints) == 0 || (c.Hub != nil && len(c.EntryPoints) == 1 && c.EntryPoints[c.Hub.EntryPoint] != nil) {
+ if !c.hasUserDefinedEntrypoint() {
ep := &EntryPoint{Address: ":80"}
ep.SetDefaults()
// TODO: double check this tomorrow
@@ -287,6 +285,21 @@ func (c *Configuration) SetEffectiveConfiguration() {
c.initACMEProvider()
}
+func (c *Configuration) hasUserDefinedEntrypoint() bool {
+ if len(c.EntryPoints) == 0 {
+ return false
+ }
+
+ switch len(c.EntryPoints) {
+ case 1:
+ return c.EntryPoints[hub.TunnelEntrypoint] == nil
+ case 2:
+ return c.EntryPoints[hub.TunnelEntrypoint] == nil || c.EntryPoints[hub.APIEntrypoint] == nil
+ default:
+ return true
+ }
+}
+
func (c *Configuration) initACMEProvider() {
for _, resolver := range c.CertificatesResolvers {
if resolver.ACME != nil {
@@ -297,46 +310,6 @@ func (c *Configuration) initACMEProvider() {
legolog.Logger = stdlog.New(log.WithoutContext().WriterLevel(logrus.DebugLevel), "legolog: ", 0)
}
-func (c *Configuration) initHubProvider() error {
- // Hub provider is an experimental feature. Require the experimental flag to be enabled before continuing.
- if c.Experimental == nil || !c.Experimental.Hub {
- return errors.New("experimental flag for Hub not set")
- }
-
- if c.Hub.TLS == nil {
- return errors.New("no TLS configuration defined for Hub")
- }
-
- if c.Hub.TLS.Insecure && (c.Hub.TLS.CA != "" || c.Hub.TLS.Cert != "" || c.Hub.TLS.Key != "") {
- return errors.New("mTLS configuration for Hub and insecure TLS for Hub are mutually exclusive")
- }
-
- if !c.Hub.TLS.Insecure && (c.Hub.TLS.CA == "" || c.Hub.TLS.Cert == "" || c.Hub.TLS.Key == "") {
- return errors.New("incomplete mTLS configuration for Hub")
- }
-
- if c.Hub.TLS.Insecure {
- log.WithoutContext().Warn("Hub is in `insecure` mode. Do not run in production with this setup.")
- }
-
- // Creates the internal Hub entry point if needed.
- if c.Hub.EntryPoint == hub.DefaultEntryPointName {
- if _, ok := c.EntryPoints[hub.DefaultEntryPointName]; !ok {
- var ep EntryPoint
- ep.SetDefaults()
- ep.Address = ":9900"
- c.EntryPoints[hub.DefaultEntryPointName] = &ep
- log.WithoutContext().Infof("The entryPoint %q is created on port 9900 to allow Traefik to communicate with the Hub Agent for Traefik.", hub.DefaultEntryPointName)
- }
- }
-
- c.EntryPoints[c.Hub.EntryPoint].HTTP.TLS = &TLSConfig{
- Options: "traefik-hub",
- }
-
- return nil
-}
-
// ValidateConfiguration validate that configuration is coherent.
func (c *Configuration) ValidateConfiguration() error {
var acmeEmail string
diff --git a/pkg/config/static/static_config_test.go b/pkg/config/static/static_config_test.go
new file mode 100644
index 000000000..9680233dd
--- /dev/null
+++ b/pkg/config/static/static_config_test.go
@@ -0,0 +1,88 @@
+package static
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/traefik/traefik/v2/pkg/provider/hub"
+)
+
+func TestHasEntrypoint(t *testing.T) {
+ tests := []struct {
+ desc string
+ entryPoints map[string]*EntryPoint
+ assert assert.BoolAssertionFunc
+ }{
+ {
+ desc: "no user defined entryPoints",
+ assert: assert.False,
+ },
+ {
+ desc: "user defined entryPoints",
+ entryPoints: map[string]*EntryPoint{
+ "foo": {},
+ },
+ assert: assert.True,
+ },
+ {
+ desc: "user defined entryPoints + hub entryPoint (tunnel)",
+ entryPoints: map[string]*EntryPoint{
+ "foo": {},
+ hub.TunnelEntrypoint: {},
+ },
+ assert: assert.True,
+ },
+ {
+ desc: "hub entryPoint (tunnel)",
+ entryPoints: map[string]*EntryPoint{
+ hub.TunnelEntrypoint: {},
+ },
+ assert: assert.False,
+ },
+ {
+ desc: "user defined entryPoints + hub entryPoint (api)",
+ entryPoints: map[string]*EntryPoint{
+ "foo": {},
+ hub.APIEntrypoint: {},
+ },
+ assert: assert.True,
+ },
+ {
+ desc: "hub entryPoint (api)",
+ entryPoints: map[string]*EntryPoint{
+ hub.APIEntrypoint: {},
+ },
+ assert: assert.True,
+ },
+ {
+ desc: "user defined entryPoints + hub entryPoints (tunnel, api)",
+ entryPoints: map[string]*EntryPoint{
+ "foo": {},
+ hub.TunnelEntrypoint: {},
+ hub.APIEntrypoint: {},
+ },
+ assert: assert.True,
+ },
+ {
+ desc: "hub entryPoints (tunnel, api)",
+ entryPoints: map[string]*EntryPoint{
+ hub.TunnelEntrypoint: {},
+ hub.APIEntrypoint: {},
+ },
+ assert: assert.False,
+ },
+ }
+
+ for _, test := range tests {
+ test := test
+ t.Run(test.desc, func(t *testing.T) {
+ t.Parallel()
+
+ cfg := &Configuration{
+ EntryPoints: test.entryPoints,
+ }
+
+ test.assert(t, cfg.hasUserDefinedEntrypoint())
+ })
+ }
+}
diff --git a/pkg/provider/hub/hub.go b/pkg/provider/hub/hub.go
index 1643a0980..62e2ace88 100644
--- a/pkg/provider/hub/hub.go
+++ b/pkg/provider/hub/hub.go
@@ -17,13 +17,15 @@ import (
var _ provider.Provider = (*Provider)(nil)
-// DefaultEntryPointName is the name of the default internal entry point.
-const DefaultEntryPointName = "traefik-hub"
+// Entrypoints created for Hub.
+const (
+ APIEntrypoint = "traefikhub-api"
+ TunnelEntrypoint = "traefikhub-tunl"
+)
// Provider holds configurations of the provider.
type Provider struct {
- EntryPoint string `description:"Entrypoint that exposes data for Traefik Hub. It should be a dedicated one, and not used by any router." json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty" export:"true"`
- TLS *TLS `description:"TLS configuration for mTLS communication between Traefik and Hub Agent." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"`
+ TLS *TLS `description:"TLS configuration for mTLS communication between Traefik and Hub Agent." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"`
server *http.Server
}
@@ -36,11 +38,6 @@ type TLS struct {
Key ttls.FileOrContent `description:"The TLS key for Traefik Proxy as a TLS client." json:"key,omitempty" toml:"key,omitempty" yaml:"key,omitempty" loggable:"false"`
}
-// SetDefaults sets the default values.
-func (p *Provider) SetDefaults() {
- p.EntryPoint = DefaultEntryPointName
-}
-
// Init the provider.
func (p *Provider) Init() error {
return nil
@@ -59,7 +56,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, _ *safe.Poo
return fmt.Errorf("creating Hub Agent HTTP client: %w", err)
}
- p.server = &http.Server{Handler: newHandler(p.EntryPoint, port, configurationChan, p.TLS, client)}
+ p.server = &http.Server{Handler: newHandler(APIEntrypoint, port, configurationChan, p.TLS, client)}
// TODO: this is going to be leaky (because no context to make it terminate)
// if/when Provide lifecycle differs with Traefik lifecycle.
@@ -70,7 +67,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, _ *safe.Poo
}
}()
- exposeAPIAndMetrics(configurationChan, p.EntryPoint, port, p.TLS)
+ exposeAPIAndMetrics(configurationChan, APIEntrypoint, port, p.TLS)
return nil
}
diff --git a/webui/Dockerfile b/webui/Dockerfile
index edb9593bc..643f12f8e 100644
--- a/webui/Dockerfile
+++ b/webui/Dockerfile
@@ -2,6 +2,8 @@ FROM node:14.16
# Current Active LTS release according to (https://nodejs.org/en/about/releases/)
ENV WEBUI_DIR /src/webui
+ARG ARG_PLATFORM_URL=https://pilot.traefik.io
+ENV PLATFORM_URL=${ARG_PLATFORM_URL}
RUN mkdir -p $WEBUI_DIR
COPY package.json $WEBUI_DIR/
diff --git a/webui/quasar.conf.js b/webui/quasar.conf.js
index 07eec1a8d..c7dc90513 100644
--- a/webui/quasar.conf.js
+++ b/webui/quasar.conf.js
@@ -118,11 +118,13 @@ module.exports = function (ctx) {
env: process.env.APP_ENV === 'development'
? { // staging:
APP_ENV: JSON.stringify(process.env.APP_ENV),
- APP_API: JSON.stringify(process.env.APP_API || '/api')
+ APP_API: JSON.stringify(process.env.APP_API || '/api'),
+ PLATFORM_URL: JSON.stringify(process.env.PLATFORM_URL || 'https://pilot.traefik.io')
}
: { // production:
APP_ENV: JSON.stringify(process.env.APP_ENV),
- APP_API: JSON.stringify(process.env.APP_API || '/api')
+ APP_API: JSON.stringify(process.env.APP_API || '/api'),
+ PLATFORM_URL: JSON.stringify(process.env.PLATFORM_URL || 'https://pilot.traefik.io')
},
uglifyOptions: {
compress: {
diff --git a/webui/src/App.vue b/webui/src/App.vue
index d655741b1..bb6e93e60 100644
--- a/webui/src/App.vue
+++ b/webui/src/App.vue
@@ -1,17 +1,26 @@
+
+
diff --git a/webui/src/components/platform/PlatformPanel.vue b/webui/src/components/platform/PlatformPanel.vue
new file mode 100644
index 000000000..a24f2bb1a
--- /dev/null
+++ b/webui/src/components/platform/PlatformPanel.vue
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+