diff --git a/README.md b/README.md index 544eddb92..7d0faa8ce 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [![Twitter](https://img.shields.io/twitter/follow/traefik.svg?style=social)](https://twitter.com/intent/follow?screen_name=traefik) Traefik (pronounced _traffic_) is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. -Traefik integrates with your existing infrastructure components ([Docker](https://www.docker.com/), [Swarm mode](https://docs.docker.com/engine/swarm/), [Kubernetes](https://kubernetes.io), [Marathon](https://mesosphere.github.io/marathon/), [Consul](https://www.consul.io/), [Etcd](https://coreos.com/etcd/), [Rancher](https://rancher.com), [Amazon ECS](https://aws.amazon.com/ecs), ...) and configures itself automatically and dynamically. +Traefik integrates with your existing infrastructure components ([Docker](https://www.docker.com/), [Swarm mode](https://docs.docker.com/engine/swarm/), [Kubernetes](https://kubernetes.io), [Consul](https://www.consul.io/), [Etcd](https://coreos.com/etcd/), [Rancher v2](https://rancher.com), [Amazon ECS](https://aws.amazon.com/ecs), ...) and configures itself automatically and dynamically. Pointing Traefik at your orchestrator should be the _only_ configuration step you need. --- @@ -58,7 +58,7 @@ _(But if you'd rather configure some of your routes manually, Traefik supports t - Circuit breakers, retry - See the magic through its clean web UI - Websocket, HTTP/2, gRPC ready -- Provides metrics (Rest, Prometheus, Datadog, Statsd, InfluxDB) +- Provides metrics (Rest, Prometheus, Datadog, Statsd, InfluxDB 2.X) - Keeps access logs (JSON, CLF) - Fast - Exposes a Rest API @@ -68,8 +68,6 @@ _(But if you'd rather configure some of your routes manually, Traefik supports t - [Docker](https://doc.traefik.io/traefik/providers/docker/) / [Swarm mode](https://doc.traefik.io/traefik/providers/docker/) - [Kubernetes](https://doc.traefik.io/traefik/providers/kubernetes-crd/) -- [Marathon](https://doc.traefik.io/traefik/providers/marathon/) -- [Rancher](https://doc.traefik.io/traefik/providers/rancher/) (Metadata) - [File](https://doc.traefik.io/traefik/providers/file/) ## Quickstart diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index 89580c553..434144db5 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -523,16 +523,6 @@ func registerMetricClients(metricsConfig *types.Metrics) []metrics.Registry { Msg("Configured StatsD metrics") } - if metricsConfig.InfluxDB != nil { - logger := log.With().Str(logs.MetricsProviderName, "influxdb").Logger() - - registries = append(registries, metrics.RegisterInfluxDB(logger.WithContext(context.Background()), metricsConfig.InfluxDB)) - logger.Debug(). - Str("address", metricsConfig.InfluxDB.Address). - Str("pushInterval", metricsConfig.InfluxDB.PushInterval.String()). - Msg("Configured InfluxDB metrics") - } - if metricsConfig.InfluxDB2 != nil { logger := log.With().Str(logs.MetricsProviderName, "influxdb2").Logger() diff --git a/contrib/grafana/traefik-kubernetes.json b/contrib/grafana/traefik-kubernetes.json index 75cf074fb..6774af097 100644 --- a/contrib/grafana/traefik-kubernetes.json +++ b/contrib/grafana/traefik-kubernetes.json @@ -15,7 +15,7 @@ "type": "grafana", "id": "grafana", "name": "Grafana", - "version": "9.2.2" + "version": "9.3.1" }, { "type": "panel", @@ -64,8 +64,10 @@ } ] }, - "editable": true, + "description": "Official dashboard for Traefik on Kubernetes", + "editable": false, "fiscalYearStartMonth": 0, + "gnetId": 17347, "graphTooltip": 0, "id": null, "links": [], @@ -133,7 +135,7 @@ }, "textMode": "auto" }, - "pluginVersion": "9.2.2", + "pluginVersion": "9.3.1", "targets": [ { "datasource": { @@ -818,7 +820,7 @@ "type": "row" }, { - "collapsed": true, + "collapsed": false, "gridPos": { "h": 1, "w": 24, @@ -826,607 +828,706 @@ "y": 18 }, "id": 16, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "reqps" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 27 - }, - "id": 17, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Mean", - "sortDesc": true - }, - "tooltip": { - "mode": "multi", - "sort": "desc" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code=~\"2..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", - "legendFormat": "{{method}}[{{code}}] on {{service}}", - "range": true, - "refId": "A" - } - ], - "title": "2xx over 5 min", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisGridShow": true, - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "reqps" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 27 - }, - "id": 18, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Mean", - "sortDesc": true - }, - "tooltip": { - "mode": "multi", - "sort": "desc" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code=~\"5..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", - "legendFormat": "{{method}}[{{code}}] on {{service}}", - "range": true, - "refId": "A" - } - ], - "title": "5xx over 5 min", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisGridShow": true, - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "reqps" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 35 - }, - "id": 19, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Mean", - "sortDesc": true - }, - "tooltip": { - "mode": "multi", - "sort": "desc" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code!~\"2..|5..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", - "legendFormat": "{{method}}[{{code}}] on {{service}}", - "range": true, - "refId": "A" - } - ], - "title": "Other codes over 5 min", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisGridShow": true, - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "binBps" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 35 - }, - "id": 20, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Mean", - "sortDesc": true - }, - "tooltip": { - "mode": "multi", - "sort": "desc" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "topk(15,\n label_replace(\n sum by (service,method) \n (rate(traefik_service_requests_bytes_total{service=~\"$service.*\",protocol=\"http\"}[1m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", - "legendFormat": "{{method}} on {{service}}", - "range": true, - "refId": "A" - } - ], - "title": "Requests Size", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 43 - }, - "id": 2, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Max", - "sortDesc": true - }, - "tooltip": { - "mode": "multi", - "sort": "desc" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "label_replace(\n sum(traefik_service_open_connections{service=~\"$service.*\"}) by (service),\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")", - "legendFormat": "{{service}}", - "range": true, - "refId": "A" - } - ], - "title": "Connections per Service", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 43 - }, - "id": 21, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Max", - "sortDesc": true - }, - "tooltip": { - "mode": "multi", - "sort": "desc" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(traefik_entrypoint_open_connections{entrypoint=~\"$entrypoint\"}) by (entrypoint)\n", - "legendFormat": "{{entrypoint}}", - "range": true, - "refId": "A" - } - ], - "title": "Connections per Entrypoint", - "type": "timeseries" - } - ], + "panels": [], "title": "HTTP Details", "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 8, + "x": 0, + "y": 19 + }, + "id": 17, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code=~\"2..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}}[{{code}}] on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "2xx over 5 min", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 8, + "x": 8, + "y": 19 + }, + "id": 18, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code=~\"5..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}}[{{code}}] on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "5xx over 5 min", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 8, + "x": 16, + "y": 19 + }, + "id": 19, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code!~\"2..|5..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}}[{{code}}] on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "Other codes over 5 min", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 31 + }, + "id": 20, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method) \n (rate(traefik_service_requests_bytes_total{service=~\"$service.*\",protocol=\"http\"}[1m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}} on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "Requests Size", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 31 + }, + "id": 24, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method) \n (rate(traefik_service_responses_bytes_total{service=~\"$service.*\",protocol=\"http\"}[1m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}} on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "Responses Size", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 39 + }, + "id": 2, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Max", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "label_replace(\n sum(traefik_service_open_connections{service=~\"$service.*\"}) by (service),\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")", + "legendFormat": "{{service}}", + "range": true, + "refId": "A" + } + ], + "title": "Connections per Service", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 39 + }, + "id": 21, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Max", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(traefik_entrypoint_open_connections{entrypoint=~\"$entrypoint\"}) by (entrypoint)\n", + "legendFormat": "{{entrypoint}}", + "range": true, + "refId": "A" + } + ], + "title": "Connections per Entrypoint", + "type": "timeseries" } ], "refresh": false, @@ -1504,8 +1605,8 @@ }, "timepicker": {}, "timezone": "", - "title": "Traefik Official Standalone Dashboard", + "title": "Traefik Official Kubernetes Dashboard", "uid": "n5bu_kv4k", - "version": 3, + "version": 5, "weekStart": "" } diff --git a/contrib/grafana/traefik.json b/contrib/grafana/traefik.json index 75cf074fb..34a1e8127 100644 --- a/contrib/grafana/traefik.json +++ b/contrib/grafana/traefik.json @@ -15,7 +15,7 @@ "type": "grafana", "id": "grafana", "name": "Grafana", - "version": "9.2.2" + "version": "9.3.1" }, { "type": "panel", @@ -64,8 +64,10 @@ } ] }, - "editable": true, + "description": "Official dashboard for Standalone Traefik", + "editable": false, "fiscalYearStartMonth": 0, + "gnetId": 17346, "graphTooltip": 0, "id": null, "links": [], @@ -133,7 +135,7 @@ }, "textMode": "auto" }, - "pluginVersion": "9.2.2", + "pluginVersion": "9.3.1", "targets": [ { "datasource": { @@ -669,8 +671,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" } ] }, @@ -764,8 +765,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" } ] }, @@ -873,8 +873,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -887,10 +886,10 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 12, + "h": 12, + "w": 8, "x": 0, - "y": 27 + "y": 19 }, "id": 17, "options": { @@ -900,7 +899,7 @@ "max" ], "displayMode": "table", - "placement": "right", + "placement": "bottom", "showLegend": true, "sortBy": "Mean", "sortDesc": true @@ -973,8 +972,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -987,10 +985,10 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 27 + "h": 12, + "w": 8, + "x": 8, + "y": 19 }, "id": 18, "options": { @@ -1000,7 +998,7 @@ "max" ], "displayMode": "table", - "placement": "right", + "placement": "bottom", "showLegend": true, "sortBy": "Mean", "sortDesc": true @@ -1073,8 +1071,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -1087,10 +1084,10 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 35 + "h": 12, + "w": 8, + "x": 16, + "y": 19 }, "id": 19, "options": { @@ -1100,7 +1097,7 @@ "max" ], "displayMode": "table", - "placement": "right", + "placement": "bottom", "showLegend": true, "sortBy": "Mean", "sortDesc": true @@ -1173,8 +1170,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -1189,8 +1185,8 @@ "gridPos": { "h": 8, "w": 12, - "x": 12, - "y": 35 + "x": 0, + "y": 31 }, "id": 20, "options": { @@ -1240,6 +1236,7 @@ "custom": { "axisCenteredZero": false, "axisColorMode": "text", + "axisGridShow": true, "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -1272,8 +1269,105 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 31 + }, + "id": 24, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method) \n (rate(traefik_service_responses_bytes_total{service=~\"$service.*\",protocol=\"http\"}[1m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}} on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "Responses Size", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" }, { "color": "red", @@ -1289,7 +1383,7 @@ "h": 8, "w": 12, "x": 0, - "y": 43 + "y": 39 }, "id": 2, "options": { @@ -1371,8 +1465,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -1388,7 +1481,7 @@ "h": 8, "w": 12, "x": 12, - "y": 43 + "y": 39 }, "id": 21, "options": { @@ -1491,7 +1584,7 @@ "refId": "StandardVariableQuery" }, "refresh": 2, - "regex": "/([^-]+-[^-]+).*/", + "regex": "", "skipUrlSync": false, "sort": 1, "type": "query" @@ -1505,7 +1598,7 @@ "timepicker": {}, "timezone": "", "title": "Traefik Official Standalone Dashboard", - "uid": "n5bu_kv4k", - "version": 3, + "uid": "n5bu_kv45", + "version": 5, "weekStart": "" } diff --git a/docs/content/contributing/maintainers.md b/docs/content/contributing/maintainers.md index eee5ec69a..cfad7eb7a 100644 --- a/docs/content/contributing/maintainers.md +++ b/docs/content/contributing/maintainers.md @@ -107,7 +107,6 @@ The `status/*` labels represent the desired state in the workflow. * `area/provider/kv`: KV related. * `area/provider/marathon`: Marathon related. * `area/provider/mesos`: Mesos related. -* `area/provider/rancher`: Rancher related. * `area/provider/servicefabric`: Azure service fabric related. * `area/provider/zk`: Zoo Keeper related. * `area/rules`: Rules related. diff --git a/docs/content/https/include-acme-multiple-domains-example.md b/docs/content/https/include-acme-multiple-domains-example.md index 8107eb24f..8395887eb 100644 --- a/docs/content/https/include-acme-multiple-domains-example.md +++ b/docs/content/https/include-acme-multiple-domains-example.md @@ -43,27 +43,6 @@ spec: - '*.example.org' ``` -```json tab="Marathon" -labels: { - "traefik.http.routers.blog.rule": "Host(`example.com`) && Path(`/blog`)", - "traefik.http.routers.blog.tls": "true", - "traefik.http.routers.blog.tls.certresolver": "myresolver", - "traefik.http.routers.blog.tls.domains[0].main": "example.com", - "traefik.http.routers.blog.tls.domains[0].sans": "*.example.com", - "traefik.http.services.blog-svc.loadbalancer.server.port": "8080" -} -``` - -```yaml tab="Rancher" -## Dynamic configuration -labels: - - traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`) - - traefik.http.routers.blog.tls=true - - traefik.http.routers.blog.tls.certresolver=myresolver - - traefik.http.routers.blog.tls.domains[0].main=example.org - - traefik.http.routers.blog.tls.domains[0].sans=*.example.org -``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: diff --git a/docs/content/https/include-acme-multiple-domains-from-rule-example.md b/docs/content/https/include-acme-multiple-domains-from-rule-example.md index 01252360b..9a758ab20 100644 --- a/docs/content/https/include-acme-multiple-domains-from-rule-example.md +++ b/docs/content/https/include-acme-multiple-domains-from-rule-example.md @@ -35,23 +35,6 @@ spec: certResolver: myresolver ``` -```json tab="Marathon" -labels: { - "traefik.http.routers.blog.rule": "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)", - "traefik.http.routers.blog.tls": "true", - "traefik.http.routers.blog.tls.certresolver": "myresolver", - "traefik.http.services.blog-svc.loadbalancer.server.port": "8080" -} -``` - -```yaml tab="Rancher" -## Dynamic configuration -labels: - - traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`) - - traefik.http.routers.blog.tls=true - - traefik.http.routers.blog.tls.certresolver=myresolver -``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: diff --git a/docs/content/https/include-acme-single-domain-example.md b/docs/content/https/include-acme-single-domain-example.md index 30bfa9229..b7f5c84f0 100644 --- a/docs/content/https/include-acme-single-domain-example.md +++ b/docs/content/https/include-acme-single-domain-example.md @@ -35,23 +35,6 @@ spec: certResolver: myresolver ``` -```json tab="Marathon" -labels: { - "traefik.http.routers.blog.rule": "Host(`example.com`) && Path(`/blog`)", - "traefik.http.routers.blog.tls": "true", - "traefik.http.routers.blog.tls.certresolver": "myresolver", - "traefik.http.services.blog-svc.loadbalancer.server.port": "8080" -} -``` - -```yaml tab="Rancher" -## Dynamic configuration -labels: - - traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`) - - traefik.http.routers.blog.tls=true - - traefik.http.routers.blog.tls.certresolver=myresolver -``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: diff --git a/docs/content/https/tailscale.md b/docs/content/https/tailscale.md index abc742b83..a4ab0a79c 100644 --- a/docs/content/https/tailscale.md +++ b/docs/content/https/tailscale.md @@ -120,20 +120,6 @@ A certificate resolver requests certificates for a set of domain names inferred certResolver: myresolver ``` - ```json tab="Marathon" - labels: { - "traefik.http.routers.blog.rule": "Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)", - "traefik.http.routers.blog.tls.certresolver": "myresolver", - } - ``` - - ```yaml tab="Rancher" - ## Dynamic configuration - labels: - - traefik.http.routers.blog.rule=Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`) - - traefik.http.routers.blog.tls.certresolver=myresolver - ``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: @@ -192,22 +178,6 @@ A certificate resolver requests certificates for a set of domain names inferred - main: monitoring.yak-bebop.ts.net ``` - ```json tab="Marathon" - labels: { - "traefik.http.routers.blog.rule": "Path(`/metrics`)", - "traefik.http.routers.blog.tls.certresolver": "myresolver", - "traefik.http.routers.blog.tls.domains[0].main": "monitoring.yak-bebop.ts.net", - } - ``` - - ```yaml tab="Rancher" - ## Dynamic configuration - labels: - - traefik.http.routers.blog.rule=Path(`/metrics`) - - traefik.http.routers.blog.tls.certresolver=myresolver - - traefik.http.routers.blog.tls.domains[0].main=monitoring.yak-bebop.ts.net - ``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md index dd756dd44..f6d84f5ce 100644 --- a/docs/content/https/tls.md +++ b/docs/content/https/tls.md @@ -219,14 +219,6 @@ labels: - "traefik.tls.stores.default.defaultgeneratedcert.domain.sans=foo.example.org, bar.example.org" ``` -```json tab="Marathon" -labels: { - "traefik.tls.stores.default.defaultgeneratedcert.resolver": "myresolver", - "traefik.tls.stores.default.defaultgeneratedcert.domain.main": "example.org", - "traefik.tls.stores.default.defaultgeneratedcert.domain.sans": "foo.example.org, bar.example.org", -} -``` - ## TLS Options The TLS options allow one to configure some parameters of the TLS connection. diff --git a/docs/content/index.md b/docs/content/index.md index b882fb148..3ee028a79 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -13,7 +13,7 @@ It receives requests on behalf of your system and finds out which components are What sets Traefik apart, besides its many features, is that it automatically discovers the right configuration for your services. The magic happens when Traefik inspects your infrastructure, where it finds relevant information and discovers which service serves which request. -Traefik is natively compliant with every major cluster technology, such as Kubernetes, Docker, Docker Swarm, AWS, Mesos, Marathon, and [the list goes on](providers/overview.md); and can handle many at the same time. (It even works for legacy software running on bare metal.) +Traefik is natively compliant with every major cluster technology, such as Kubernetes, Docker, Docker Swarm, AWS, and [the list goes on](providers/overview.md); and can handle many at the same time. (It even works for legacy software running on bare metal.) With Traefik, there is no need to maintain and synchronize a separate configuration file: everything happens automatically, in real time (no restarts, no connection interruptions). With Traefik, you spend time developing and deploying new features to your system, not on configuring and maintaining its working state. diff --git a/docs/content/middlewares/http/addprefix.md b/docs/content/middlewares/http/addprefix.md index 9f909aa8f..995524ff2 100644 --- a/docs/content/middlewares/http/addprefix.md +++ b/docs/content/middlewares/http/addprefix.md @@ -36,18 +36,6 @@ spec: - "traefik.http.middlewares.add-foo.addprefix.prefix=/foo" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.add-foo.addprefix.prefix": "/foo" -} -``` - -```yaml tab="Rancher" -# Prefixing with /foo -labels: - - "traefik.http.middlewares.add-foo.addprefix.prefix=/foo" -``` - ```yaml tab="File (YAML)" # Prefixing with /foo http: diff --git a/docs/content/middlewares/http/basicauth.md b/docs/content/middlewares/http/basicauth.md index c9ef0e212..7707f270b 100644 --- a/docs/content/middlewares/http/basicauth.md +++ b/docs/content/middlewares/http/basicauth.md @@ -41,18 +41,6 @@ spec: - "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" -} -``` - -```yaml tab="Rancher" -# Declaring the user list -labels: - - "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" -``` - ```yaml tab="File (YAML)" # Declaring the user list http: @@ -157,18 +145,6 @@ data: - "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" -} -``` - -```yaml tab="Rancher" -# Declaring the user list -labels: - - "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" -``` - ```yaml tab="File (YAML)" # Declaring the user list http: @@ -232,17 +208,6 @@ data: - "traefik.http.middlewares.test-auth.basicauth.usersfile=/path/to/my/usersfile" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.basicauth.usersfile": "/path/to/my/usersfile" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.basicauth.usersfile=/path/to/my/usersfile" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -287,17 +252,6 @@ spec: - "traefik.http.middlewares.test-auth.basicauth.realm=MyRealm" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.basicauth.realm": "MyRealm" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.basicauth.realm=MyRealm" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -336,12 +290,6 @@ spec: - "traefik.http.middlewares.my-auth.basicauth.headerField=X-WebAuth-User" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.my-auth.basicauth.headerField": "X-WebAuth-User" -} -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -380,17 +328,6 @@ spec: - "traefik.http.middlewares.test-auth.basicauth.removeheader=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.basicauth.removeheader": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.basicauth.removeheader=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/buffering.md b/docs/content/middlewares/http/buffering.md index f172faffa..6e9d7b9ab 100644 --- a/docs/content/middlewares/http/buffering.md +++ b/docs/content/middlewares/http/buffering.md @@ -40,18 +40,6 @@ spec: - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes": "2000000" -} -``` - -```yaml tab="Rancher" -# Sets the maximum request body to 2MB -labels: - - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000" -``` - ```yaml tab="File (YAML)" # Sets the maximum request body to 2MB http: @@ -97,17 +85,6 @@ spec: - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes": "2000000" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -147,17 +124,6 @@ spec: - "traefik.http.middlewares.limit.buffering.memRequestBodyBytes=2000000" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.limit.buffering.memRequestBodyBytes": "2000000" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.limit.buffering.memRequestBodyBytes=2000000" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -199,17 +165,6 @@ spec: - "traefik.http.middlewares.limit.buffering.maxResponseBodyBytes=2000000" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.limit.buffering.maxResponseBodyBytes": "2000000" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.limit.buffering.maxResponseBodyBytes=2000000" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -249,17 +204,6 @@ spec: - "traefik.http.middlewares.limit.buffering.memResponseBodyBytes=2000000" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.limit.buffering.memResponseBodyBytes": "2000000" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.limit.buffering.memResponseBodyBytes=2000000" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -301,17 +245,6 @@ You can have the Buffering middleware replay the request using `retryExpression` - "traefik.http.middlewares.limit.buffering.retryExpression=IsNetworkError() && Attempts() < 2" ``` - ```json tab="Marathon" - "labels": { - "traefik.http.middlewares.limit.buffering.retryExpression": "IsNetworkError() && Attempts() < 2" - } - ``` - - ```yaml tab="Rancher" - labels: - - "traefik.http.middlewares.limit.buffering.retryExpression=IsNetworkError() && Attempts() < 2" - ``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/chain.md b/docs/content/middlewares/http/chain.md index f9768adfb..ce3806a5d 100644 --- a/docs/content/middlewares/http/chain.md +++ b/docs/content/middlewares/http/chain.md @@ -97,31 +97,6 @@ spec: - "traefik.http.services.service1.loadbalancer.server.port=80" ``` -```json tab="Marathon" -"labels": { - "traefik.http.routers.router1.service": "service1", - "traefik.http.routers.router1.middlewares": "secured", - "traefik.http.routers.router1.rule": "Host(`mydomain`)", - "traefik.http.middlewares.secured.chain.middlewares": "https-only,known-ips,auth-users", - "traefik.http.middlewares.auth-users.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "traefik.http.middlewares.https-only.redirectscheme.scheme": "https", - "traefik.http.middlewares.known-ips.ipallowlist.sourceRange": "192.168.1.7,127.0.0.1/32", - "traefik.http.services.service1.loadbalancer.server.port": "80" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.routers.router1.service=service1" - - "traefik.http.routers.router1.middlewares=secured" - - "traefik.http.routers.router1.rule=Host(`mydomain`)" - - "traefik.http.middlewares.secured.chain.middlewares=https-only,known-ips,auth-users" - - "traefik.http.middlewares.auth-users.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" - - "traefik.http.middlewares.https-only.redirectscheme.scheme=https" - - "traefik.http.middlewares.known-ips.ipallowlist.sourceRange=192.168.1.7,127.0.0.1/32" - - "traefik.http.services.service1.loadbalancer.server.port=80" -``` - ```yaml tab="File (YAML)" # ... http: diff --git a/docs/content/middlewares/http/circuitbreaker.md b/docs/content/middlewares/http/circuitbreaker.md index 4399be1e1..7ff406c17 100644 --- a/docs/content/middlewares/http/circuitbreaker.md +++ b/docs/content/middlewares/http/circuitbreaker.md @@ -52,18 +52,6 @@ spec: - "traefik.http.middlewares.latency-check.circuitbreaker.expression=LatencyAtQuantileMS(50.0) > 100" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.latency-check.circuitbreaker.expression": "LatencyAtQuantileMS(50.0) > 100" -} -``` - -```yaml tab="Rancher" -# Latency Check -labels: - - "traefik.http.middlewares.latency-check.circuitbreaker.expression=LatencyAtQuantileMS(50.0) > 100" -``` - ```yaml tab="File (YAML)" # Latency Check http: diff --git a/docs/content/middlewares/http/compress.md b/docs/content/middlewares/http/compress.md index 7e4b79613..4a17c9430 100644 --- a/docs/content/middlewares/http/compress.md +++ b/docs/content/middlewares/http/compress.md @@ -36,18 +36,6 @@ spec: - "traefik.http.middlewares.test-compress.compress=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-compress.compress": "true" -} -``` - -```yaml tab="Rancher" -# Enable compression -labels: - - "traefik.http.middlewares.test-compress.compress=true" -``` - ```yaml tab="File (YAML)" # Enable compression http: @@ -114,17 +102,6 @@ spec: - "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-compress.compress.excludedcontenttypes": "text/event-stream" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -167,17 +144,6 @@ spec: - "traefik.http.middlewares.test-compress.compress.minresponsebodybytes=1200" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-compress.compress.minresponsebodybytes": 1200 -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-compress.compress.minresponsebodybytes=1200" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/contenttype.md b/docs/content/middlewares/http/contenttype.md index 38072958a..b74bfa6c2 100644 --- a/docs/content/middlewares/http/contenttype.md +++ b/docs/content/middlewares/http/contenttype.md @@ -39,18 +39,6 @@ spec: - "traefik.http.middlewares.autodetect.contenttype=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.autodetect.contenttype": "true" -} -``` - -```yaml tab="Rancher" -# Enable auto-detection -labels: - - "traefik.http.middlewares.autodetect.contenttype=true" -``` - ```yaml tab="File (YAML)" # Enable auto-detection http: @@ -63,4 +51,4 @@ http: # Enable auto-detection [http.middlewares] [http.middlewares.autodetect.contentType] -``` \ No newline at end of file +``` diff --git a/docs/content/middlewares/http/digestauth.md b/docs/content/middlewares/http/digestauth.md index 14e3982b5..d49d8f581 100644 --- a/docs/content/middlewares/http/digestauth.md +++ b/docs/content/middlewares/http/digestauth.md @@ -36,18 +36,6 @@ spec: - "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.digestauth.users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" -} -``` - -```yaml tab="Rancher" -# Declaring the user list -labels: - - "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" -``` - ```yaml tab="File (YAML)" # Declaring the user list http: @@ -114,17 +102,6 @@ data: - "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.digestauth.users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -186,17 +163,6 @@ data: - "traefik.http.middlewares.test-auth.digestauth.usersfile=/path/to/my/usersfile" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.digestauth.usersfile": "/path/to/my/usersfile" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.digestauth.usersfile=/path/to/my/usersfile" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -241,17 +207,6 @@ spec: - "traefik.http.middlewares.test-auth.digestauth.realm=MyRealm" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.digestauth.realm": "MyRealm" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.digestauth.realm=MyRealm" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -290,17 +245,6 @@ spec: - "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.my-auth.digestauth.headerField": "X-WebAuth-User" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -339,17 +283,6 @@ spec: - "traefik.http.middlewares.test-auth.digestauth.removeheader=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.digestauth.removeheader": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.digestauth.removeheader=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/errorpages.md b/docs/content/middlewares/http/errorpages.md index 81986d667..3ec1c1e20 100644 --- a/docs/content/middlewares/http/errorpages.md +++ b/docs/content/middlewares/http/errorpages.md @@ -48,22 +48,6 @@ spec: - "traefik.http.middlewares.test-errors.errors.query=/{status}.html" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-errors.errors.status": "500-599", - "traefik.http.middlewares.test-errors.errors.service": "serviceError", - "traefik.http.middlewares.test-errors.errors.query": "/{status}.html" -} -``` - -```yaml tab="Rancher" -# Dynamic Custom Error Page for 5XX Status Code -labels: - - "traefik.http.middlewares.test-errors.errors.status=500-599" - - "traefik.http.middlewares.test-errors.errors.service=serviceError" - - "traefik.http.middlewares.test-errors.errors.query=/{status}.html" -``` - ```yaml tab="File (YAML)" # Custom Error Page for 5XX http: diff --git a/docs/content/middlewares/http/forwardauth.md b/docs/content/middlewares/http/forwardauth.md index fdcff0321..f7a038020 100644 --- a/docs/content/middlewares/http/forwardauth.md +++ b/docs/content/middlewares/http/forwardauth.md @@ -38,18 +38,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.address": "https://example.com/auth" -} -``` - -```yaml tab="Rancher" -# Forward authentication to example.com -labels: - - "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth" -``` - ```yaml tab="File (YAML)" # Forward authentication to example.com http: @@ -103,17 +91,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.address": "https://example.com/auth" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -152,17 +129,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -206,17 +172,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders": "X-Auth-User,X-Secret" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -262,17 +217,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex": "^X-" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -323,17 +267,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders=Accept,X-CustomHeader" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders": "Accept,X-CustomHeader" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders=Accept,X-CustomHeader" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -397,17 +330,6 @@ data: - "traefik.http.middlewares.test-auth.forwardauth.tls.ca=path/to/local.crt" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.tls.ca": "path/to/local.crt" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.tls.ca=path/to/local.crt" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -467,19 +389,6 @@ data: - "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert", - "traefik.http.middlewares.test-auth.forwardauth.tls.key": "path/to/foo.key" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert" - - "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -545,19 +454,6 @@ data: - "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert", - "traefik.http.middlewares.test-auth.forwardauth.tls.key": "path/to/foo.key" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert" - - "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -609,17 +505,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.tls.InsecureSkipVerify=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.tls.insecureSkipVerify": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.tls.InsecureSkipVerify=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/grpcweb.md b/docs/content/middlewares/http/grpcweb.md index d6d2c9a6b..c76153a26 100644 --- a/docs/content/middlewares/http/grpcweb.md +++ b/docs/content/middlewares/http/grpcweb.md @@ -37,17 +37,6 @@ spec: - "traefik.http.middlewares.test-grpcweb.grpcWeb.allowOrigins=*" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-grpcweb.grpcweb.alloworigins": "*" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-grpcweb.grpcweb.alloworigins=*" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/headers.md b/docs/content/middlewares/http/headers.md index a8532e6be..739380b42 100644 --- a/docs/content/middlewares/http/headers.md +++ b/docs/content/middlewares/http/headers.md @@ -44,19 +44,6 @@ spec: - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=value" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test", - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header": "value" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test" - - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=value" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -109,21 +96,6 @@ spec: - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test", - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Custom-Request-Header": "", - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header": "", -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test" - - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Custom-Request-Header=" - - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -173,19 +145,6 @@ spec: - "traefik.http.middlewares.testheader.headers.browserxssfilter=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.testheader.headers.framedeny": "true", - "traefik.http.middlewares.testheader.headers.browserxssfilter": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.testheader.headers.framedeny=true" - - "traefik.http.middlewares.testheader.headers.browserxssfilter=true" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -242,23 +201,6 @@ spec: - "traefik.http.middlewares.testheader.headers.addvaryheader=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods": "GET,OPTIONS,PUT", - "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist": "https://foo.bar.org,https://example.org", - "traefik.http.middlewares.testheader.headers.accesscontrolmaxage": "100", - "traefik.http.middlewares.testheader.headers.addvaryheader": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT" - - "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist=https://foo.bar.org,https://example.org" - - "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100" - - "traefik.http.middlewares.testheader.headers.addvaryheader=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/inflightreq.md b/docs/content/middlewares/http/inflightreq.md index b3712b148..71190631e 100644 --- a/docs/content/middlewares/http/inflightreq.md +++ b/docs/content/middlewares/http/inflightreq.md @@ -34,18 +34,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10" -} -``` - -```yaml tab="Rancher" -# Limiting to 10 simultaneous connections -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10" -``` - ```yaml tab="File (YAML)" # Limiting to 10 simultaneous connections http: @@ -89,18 +77,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10" -} -``` - -```yaml tab="Rancher" -# Limiting to 10 simultaneous connections -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10" -``` - ```yaml tab="File (YAML)" # Limiting to 10 simultaneous connections http: @@ -165,17 +141,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth": "2" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -232,17 +197,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -286,17 +240,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername": "username" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -337,17 +280,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/ipallowlist.md b/docs/content/middlewares/http/ipallowlist.md index 56450d736..703293d32 100644 --- a/docs/content/middlewares/http/ipallowlist.md +++ b/docs/content/middlewares/http/ipallowlist.md @@ -35,18 +35,6 @@ spec: - "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange": "127.0.0.1/32,192.168.1.7" -} -``` - -```yaml tab="Rancher" -# Accepts request from defined IP -labels: - - "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" -``` - ```yaml tab="File (YAML)" # Accepts request from defined IP http: @@ -120,20 +108,6 @@ spec: - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth=2" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange": "127.0.0.1/32, 192.168.1.7", - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth": "2" -} -``` - -```yaml tab="Rancher" -# Allowlisting Based on `X-Forwarded-For` with `depth=2` -labels: - - "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" - - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth=2" -``` - ```yaml tab="File (YAML)" # Allowlisting Based on `X-Forwarded-For` with `depth=2` http: @@ -197,18 +171,6 @@ spec: - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7" -} -``` - -```yaml tab="Rancher" -# Exclude from `X-Forwarded-For` -labels: - - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" -``` - ```yaml tab="File (YAML)" # Exclude from `X-Forwarded-For` http: diff --git a/docs/content/middlewares/http/overview.md b/docs/content/middlewares/http/overview.md index c4a9f9791..5757b3335 100644 --- a/docs/content/middlewares/http/overview.md +++ b/docs/content/middlewares/http/overview.md @@ -69,22 +69,6 @@ spec: - "traefik.http.routers.router1.middlewares=foo-add-prefix@consulcatalog" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix": "/foo", - "traefik.http.routers.router1.middlewares": "foo-add-prefix@marathon" -} -``` - -```yaml tab="Rancher" -# As a Rancher Label -labels: - # Create a middleware named `foo-add-prefix` - - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo" - # Apply the middleware named `foo-add-prefix` to the router named `router1` - - "traefik.http.routers.router1.middlewares=foo-add-prefix@rancher" -``` - ```toml tab="File (TOML)" # As TOML Configuration File [http.routers] diff --git a/docs/content/middlewares/http/passtlsclientcert.md b/docs/content/middlewares/http/passtlsclientcert.md index 28c5f7fff..4264dd711 100644 --- a/docs/content/middlewares/http/passtlsclientcert.md +++ b/docs/content/middlewares/http/passtlsclientcert.md @@ -39,18 +39,6 @@ spec: - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem": "true" -} -``` - -```yaml tab="Rancher" -# Pass the pem in the `X-Forwarded-Tls-Client-Cert` header. -labels: - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true" -``` - ```yaml tab="File (YAML)" # Pass the pem in the `X-Forwarded-Tls-Client-Cert` header. http: @@ -146,52 +134,6 @@ http: - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true" ``` - ```json tab="Marathon" - "labels": { - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organizationalunit": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber": "true" - } - ``` - - ```yaml tab="Rancher" - # Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header - labels: - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organizationalunit=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true" - ``` - ```yaml tab="File (YAML)" # Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header http: diff --git a/docs/content/middlewares/http/ratelimit.md b/docs/content/middlewares/http/ratelimit.md index 8d62afd9c..48057fe85 100644 --- a/docs/content/middlewares/http/ratelimit.md +++ b/docs/content/middlewares/http/ratelimit.md @@ -40,21 +40,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.burst=50" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.average": "100", - "traefik.http.middlewares.test-ratelimit.ratelimit.burst": "50" -} -``` - -```yaml tab="Rancher" -# Here, an average of 100 requests per second is allowed. -# In addition, a burst of 50 requests is allowed. -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.average=100" - - "traefik.http.middlewares.test-ratelimit.ratelimit.burst=50" -``` - ```yaml tab="File (YAML)" # Here, an average of 100 requests per second is allowed. # In addition, a burst of 50 requests is allowed. @@ -108,17 +93,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.average=100" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.average": "100", -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.average=100" -``` - ```yaml tab="File (YAML)" # 100 reqs/s http: @@ -170,20 +144,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.period=1m" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.average": "6", - "traefik.http.middlewares.test-ratelimit.ratelimit.period": "1m", -} -``` - -```yaml tab="Rancher" -# 6 reqs/minute -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.average=6" - - "traefik.http.middlewares.test-ratelimit.ratelimit.period=1m" -``` - ```yaml tab="File (YAML)" # 6 reqs/minute http: @@ -227,17 +187,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.burst": "100", -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -300,17 +249,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.depth=2" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.depth": "2" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.depth=2" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -394,17 +332,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -448,17 +375,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername=username" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername": "username" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername=username" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -499,17 +415,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/redirectregex.md b/docs/content/middlewares/http/redirectregex.md index 97d2d83e6..fe4da4b30 100644 --- a/docs/content/middlewares/http/redirectregex.md +++ b/docs/content/middlewares/http/redirectregex.md @@ -43,21 +43,6 @@ spec: - "traefik.http.middlewares.test-redirectregex.redirectregex.replacement=http://mydomain/$${1}" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-redirectregex.redirectregex.regex": "^http://localhost/(.*)", - "traefik.http.middlewares.test-redirectregex.redirectregex.replacement": "http://mydomain/${1}" -} -``` - -```yaml tab="Rancher" -# Redirect with domain replacement -# Note: all dollar signs need to be doubled for escaping. -labels: - - "traefik.http.middlewares.test-redirectregex.redirectregex.regex=^http://localhost/(.*)" - - "traefik.http.middlewares.test-redirectregex.redirectregex.replacement=http://mydomain/$${1}" -``` - ```yaml tab="File (YAML)" # Redirect with domain replacement http: diff --git a/docs/content/middlewares/http/redirectscheme.md b/docs/content/middlewares/http/redirectscheme.md index 9c7a67ec1..14e715add 100644 --- a/docs/content/middlewares/http/redirectscheme.md +++ b/docs/content/middlewares/http/redirectscheme.md @@ -51,20 +51,6 @@ labels: - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme": "https" - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent": "true" -} -``` - -```yaml tab="Rancher" -# Redirect to https -labels: - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https" - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true" -``` - ```yaml tab="File (YAML)" # Redirect to https http: @@ -115,20 +101,6 @@ labels: - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true" ``` -```json tab="Marathon" -"labels": { - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent": "true" -} -``` - -```yaml tab="Rancher" -# Redirect to https -labels: - # ... - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true" -``` - ```yaml tab="File (YAML)" # Redirect to https http: @@ -174,18 +146,6 @@ labels: - "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme": "https" -} -``` - -```yaml tab="Rancher" -# Redirect to https -labels: - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https" -``` - ```yaml tab="File (YAML)" # Redirect to https http: @@ -232,20 +192,6 @@ labels: - "traefik.http.middlewares.test-redirectscheme.redirectscheme.port=443" ``` -```json tab="Marathon" -"labels": { - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.port": "443" -} -``` - -```yaml tab="Rancher" -# Redirect to https -labels: - # ... - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.port=443" -``` - ```yaml tab="File (YAML)" # Redirect to https http: diff --git a/docs/content/middlewares/http/replacepath.md b/docs/content/middlewares/http/replacepath.md index 0617508e9..f2ddf0758 100644 --- a/docs/content/middlewares/http/replacepath.md +++ b/docs/content/middlewares/http/replacepath.md @@ -38,18 +38,6 @@ spec: - "traefik.http.middlewares.test-replacepath.replacepath.path=/foo" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-replacepath.replacepath.path": "/foo" -} -``` - -```yaml tab="Rancher" -# Replace the path with /foo -labels: - - "traefik.http.middlewares.test-replacepath.replacepath.path=/foo" -``` - ```yaml tab="File (YAML)" # Replace the path with /foo http: diff --git a/docs/content/middlewares/http/replacepathregex.md b/docs/content/middlewares/http/replacepathregex.md index b729a30ab..1acd76591 100644 --- a/docs/content/middlewares/http/replacepathregex.md +++ b/docs/content/middlewares/http/replacepathregex.md @@ -41,20 +41,6 @@ spec: - "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$1" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex": "^/foo/(.*)", - "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement": "/bar/$1" -} -``` - -```yaml tab="Rancher" -# Replace path with regex -labels: - - "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex=^/foo/(.*)" - - "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$1" -``` - ```yaml tab="File (YAML)" # Replace path with regex http: diff --git a/docs/content/middlewares/http/retry.md b/docs/content/middlewares/http/retry.md index 956bdc498..187d107a6 100644 --- a/docs/content/middlewares/http/retry.md +++ b/docs/content/middlewares/http/retry.md @@ -43,20 +43,6 @@ spec: - "traefik.http.middlewares.test-retry.retry.initialinterval=100ms" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-retry.retry.attempts": "4", - "traefik.http.middlewares.test-retry.retry.initialinterval": "100ms", -} -``` - -```yaml tab="Rancher" -# Retry 4 times with exponential backoff -labels: - - "traefik.http.middlewares.test-retry.retry.attempts=4" - - "traefik.http.middlewares.test-retry.retry.initialinterval=100ms" -``` - ```yaml tab="File (YAML)" # Retry 4 times with exponential backoff http: diff --git a/docs/content/middlewares/http/stripprefix.md b/docs/content/middlewares/http/stripprefix.md index afc20f2ac..135f7e08a 100644 --- a/docs/content/middlewares/http/stripprefix.md +++ b/docs/content/middlewares/http/stripprefix.md @@ -40,18 +40,6 @@ spec: - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar,/fiibar" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes": "/foobar,/fiibar" -} -``` - -```yaml tab="Rancher" -# Strip prefix /foobar and /fiibar -labels: - - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar,/fiibar" -``` - ```yaml tab="File (YAML)" # Strip prefix /foobar and /fiibar http: diff --git a/docs/content/middlewares/http/stripprefixregex.md b/docs/content/middlewares/http/stripprefixregex.md index d560a5d12..f6e58d871 100644 --- a/docs/content/middlewares/http/stripprefixregex.md +++ b/docs/content/middlewares/http/stripprefixregex.md @@ -32,17 +32,6 @@ spec: - "traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex=/foo/[a-z0-9]+/[0-9]+/" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex": "/foo/[a-z0-9]+/[0-9]+/" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex=/foo/[a-z0-9]+/[0-9]+/" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/overview.md b/docs/content/middlewares/overview.md index 90748ef6c..eeb70ea4f 100644 --- a/docs/content/middlewares/overview.md +++ b/docs/content/middlewares/overview.md @@ -66,22 +66,6 @@ spec: - "traefik.http.routers.router1.middlewares=foo-add-prefix@consulcatalog" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix": "/foo", - "traefik.http.routers.router1.middlewares": "foo-add-prefix@marathon" -} -``` - -```yaml tab="Rancher" -# As a Rancher Label -labels: - # Create a middleware named `foo-add-prefix` - - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo" - # Apply the middleware named `foo-add-prefix` to the router named `router1` - - "traefik.http.routers.router1.middlewares=foo-add-prefix@rancher" -``` - ```yaml tab="File (YAML)" # As YAML Configuration File http: diff --git a/docs/content/middlewares/tcp/inflightconn.md b/docs/content/middlewares/tcp/inflightconn.md index 036ca74e1..9619cd63e 100644 --- a/docs/content/middlewares/tcp/inflightconn.md +++ b/docs/content/middlewares/tcp/inflightconn.md @@ -27,18 +27,6 @@ spec: - "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10" ``` -```json tab="Marathon" -"labels": { - "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount": "10" -} -``` - -```yaml tab="Rancher" -# Limiting to 10 simultaneous connections. -labels: - - "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10" -``` - ```yaml tab="File (YAML)" # Limiting to 10 simultaneous connections. tcp: diff --git a/docs/content/middlewares/tcp/ipallowlist.md b/docs/content/middlewares/tcp/ipallowlist.md index 2cc51fd57..fad1f9cbf 100644 --- a/docs/content/middlewares/tcp/ipallowlist.md +++ b/docs/content/middlewares/tcp/ipallowlist.md @@ -35,18 +35,6 @@ spec: - "traefik.tcp.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" ``` -```json tab="Marathon" -"labels": { - "traefik.tcp.middlewares.test-ipallowlist.ipallowlist.sourcerange": "127.0.0.1/32,192.168.1.7" -} -``` - -```yaml tab="Rancher" -# Accepts request from defined IP -labels: - - "traefik.tcp.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" -``` - ```toml tab="File (TOML)" # Accepts request from defined IP [tcp.middlewares] diff --git a/docs/content/middlewares/tcp/overview.md b/docs/content/middlewares/tcp/overview.md index cc1302530..dfbdd3f9b 100644 --- a/docs/content/middlewares/tcp/overview.md +++ b/docs/content/middlewares/tcp/overview.md @@ -70,22 +70,6 @@ spec: - "traefik.tcp.routers.router1.middlewares=foo-ip-allowlist@consulcatalog" ``` -```json tab="Marathon" -"labels": { - "traefik.tcp.middlewares.foo-ip-allowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7", - "traefik.tcp.routers.router1.middlewares=foo-ip-allowlist@marathon" -} -``` - -```yaml tab="Rancher" -# As a Rancher Label -labels: - # Create a middleware named `foo-ip-allowlist` - - "traefik.tcp.middlewares.foo-ip-allowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" - # Apply the middleware named `foo-ip-allowlist` to the router named `router1` - - "traefik.tcp.routers.router1.middlewares=foo-ip-allowlist@rancher" -``` - ```toml tab="File (TOML)" # As TOML Configuration File [tcp.routers] diff --git a/docs/content/migration/v2-to-v3.md b/docs/content/migration/v2-to-v3.md index b8f600d54..3a9c7e4c4 100644 --- a/docs/content/migration/v2-to-v3.md +++ b/docs/content/migration/v2-to-v3.md @@ -26,10 +26,10 @@ In v3, the reported status code for gRPC requests is now the value of the `Grpc- - The `pilot` option has been removed from the static configuration. - The `tracing.datadog.globaltag` option has been removed. - The `namespace` option of Consul, Consul Catalog and Nomad providers has been removed. -- The `tls.caOptional` option has been removed from the ForwardAuth middleware, as well as from the HTTP, Consul, Etcd, Redis, ZooKeeper, Marathon, Consul Catalog, and Docker providers. +- The `tls.caOptional` option has been removed from the ForwardAuth middleware, as well as from the HTTP, Consul, Etcd, Redis, ZooKeeper, Consul Catalog, and Docker providers. - `sslRedirect`, `sslTemporaryRedirect`, `sslHost`, `sslForceHost` and `featurePolicy` options of the Headers middleware have been removed. - The `forceSlash` option of the StripPrefix middleware has been removed. -- the `preferServerCipherSuites` option has been removed. +- The `preferServerCipherSuites` option has been removed. ## Matchers @@ -65,3 +65,18 @@ When using the KubernetesCRD provider, it is therefore necessary to update [RBAC The TCP LoadBalancer `terminationDelay` option has been removed. This option can now be configured directly on the `TCPServersTransport` level, please take a look at this [documentation](../routing/services/index.md#terminationdelay) + +## Rancher v1 + +In v3, the rancher v1 provider has been removed because Rancher v1 is [no longer actively maintaned](https://rancher.com/docs/os/v1.x/en/support/) and v2 is supported as a standard Kubernetes provider. + +Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query. +As such, Rancher 2.x users should utilize the [Kubernetes CRD provider](../providers/kubernetes-crd.md) directly. + +## Marathon provider + +In v3, the Marathon provider has been removed. + +## InfluxDB v1 + +In v3, the InfluxDB v1 metrics provider has been removed because InfluxDB v1.x maintenance [ended in 2021](https://www.influxdata.com/blog/influxdb-oss-and-enterprise-roadmap-update-from-influxdays-emea/). diff --git a/docs/content/observability/metrics/influxdb.md b/docs/content/observability/metrics/influxdb.md deleted file mode 100644 index 0eb05e23c..000000000 --- a/docs/content/observability/metrics/influxdb.md +++ /dev/null @@ -1,268 +0,0 @@ ---- -title: "Traefik InfluxDB Documentation" -description: "Traefik supports several metrics backends, including InfluxDB. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation." ---- - -# InfluxDB - -To enable the InfluxDB: - -```yaml tab="File (YAML)" -metrics: - influxDB: {} -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] -``` - -```bash tab="CLI" ---metrics.influxdb=true -``` - -#### `address` - -_Required, Default="localhost:8089"_ - -Address instructs exporter to send metrics to influxdb at this address. - -```yaml tab="File (YAML)" -metrics: - influxDB: - address: localhost:8089 -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - address = "localhost:8089" -``` - -```bash tab="CLI" ---metrics.influxdb.address=localhost:8089 -``` - -#### `protocol` - -_Required, Default="udp"_ - -InfluxDB's address protocol (udp or http). - -```yaml tab="File (YAML)" -metrics: - influxDB: - protocol: udp -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - protocol = "udp" -``` - -```bash tab="CLI" ---metrics.influxdb.protocol=udp -``` - -#### `database` - -_Optional, Default=""_ - -InfluxDB database used when protocol is http. - -```yaml tab="File (YAML)" -metrics: - influxDB: - database: db -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - database = "db" -``` - -```bash tab="CLI" ---metrics.influxdb.database=db -``` - -#### `retentionPolicy` - -_Optional, Default=""_ - -InfluxDB retention policy used when protocol is http. - -```yaml tab="File (YAML)" -metrics: - influxDB: - retentionPolicy: two_hours -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - retentionPolicy = "two_hours" -``` - -```bash tab="CLI" ---metrics.influxdb.retentionPolicy=two_hours -``` - -#### `username` - -_Optional, Default=""_ - -InfluxDB username (only with http). - -```yaml tab="File (YAML)" -metrics: - influxDB: - username: john -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - username = "john" -``` - -```bash tab="CLI" ---metrics.influxdb.username=john -``` - -#### `password` - -_Optional, Default=""_ - -InfluxDB password (only with http). - -```yaml tab="File (YAML)" -metrics: - influxDB: - password: secret -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - password = "secret" -``` - -```bash tab="CLI" ---metrics.influxdb.password=secret -``` - -#### `addEntryPointsLabels` - -_Optional, Default=true_ - -Enable metrics on entry points. - -```yaml tab="File (YAML)" -metrics: - influxDB: - addEntryPointsLabels: true -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - addEntryPointsLabels = true -``` - -```bash tab="CLI" ---metrics.influxdb.addEntryPointsLabels=true -``` - -#### `addRoutersLabels` - -_Optional, Default=false_ - -Enable metrics on routers. - -```yaml tab="File (YAML)" -metrics: - influxDB: - addRoutersLabels: true -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - addRoutersLabels = true -``` - -```bash tab="CLI" ---metrics.influxdb.addrouterslabels=true -``` - -#### `addServicesLabels` - -_Optional, Default=true_ - -Enable metrics on services. - -```yaml tab="File (YAML)" -metrics: - influxDB: - addServicesLabels: true -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - addServicesLabels = true -``` - -```bash tab="CLI" ---metrics.influxdb.addServicesLabels=true -``` - -#### `pushInterval` - -_Optional, Default=10s_ - -The interval used by the exporter to push metrics to influxdb. - -```yaml tab="File (YAML)" -metrics: - influxDB: - pushInterval: 10s -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - pushInterval = "10s" -``` - -```bash tab="CLI" ---metrics.influxdb.pushInterval=10s -``` - -#### `additionalLabels` - -_Optional, Default={}_ - -Additional labels (influxdb tags) on all metrics. - -```yaml tab="File (YAML)" -metrics: - influxDB: - additionalLabels: - host: example.com - environment: production -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - [metrics.influxDB.additionalLabels] - host = "example.com" - environment = "production" -``` - -```bash tab="CLI" ---metrics.influxdb.additionallabels.host=example.com --metrics.influxdb.additionallabels.environment=production -``` diff --git a/docs/content/observability/metrics/overview.md b/docs/content/observability/metrics/overview.md index 0fce7e76c..2a3e1d9c7 100644 --- a/docs/content/observability/metrics/overview.md +++ b/docs/content/observability/metrics/overview.md @@ -1,6 +1,6 @@ --- title: "Traefik Metrics Overview" -description: "Traefik Proxy supports these metrics backend systems: Datadog, InfluxDB, Prometheus, and StatsD. Read the full documentation to get started." +description: "Traefik Proxy supports these metrics backend systems: Datadog, InfluxDB 2.X, Prometheus, and StatsD. Read the full documentation to get started." --- # Metrics @@ -8,7 +8,6 @@ description: "Traefik Proxy supports these metrics backend systems: Datadog, Inf Traefik supports these metrics backends: - [Datadog](./datadog.md) -- [InfluxDB](./influxdb.md) - [InfluxDB2](./influxdb2.md) - [Prometheus](./prometheus.md) - [StatsD](./statsd.md) @@ -35,7 +34,7 @@ config.reload.lastSuccessTimestamp tls.certs.notAfterTimestamp ``` -```influxdb tab="InfluxDB / InfluxDB2" +```influxdb tab="InfluxDB2" traefik.config.reload.total traefik.config.reload.lastSuccessTimestamp traefik.tls.certs.notAfterTimestamp @@ -77,7 +76,7 @@ entrypoint.requests.bytes.total entrypoint.responses.bytes.total ``` -```influxdb tab="InfluxDB / InfluxDB2" +```influxdb tab="InfluxDB2" traefik.entrypoint.requests.total traefik.entrypoint.requests.tls.total traefik.entrypoint.request.duration @@ -125,7 +124,7 @@ router.requests.bytes.total router.responses.bytes.total ``` -```influxdb tab="InfluxDB / InfluxDB2" +```influxdb tab="InfluxDB2" traefik.router.requests.total traefik.router.requests.tls.total traefik.router.request.duration @@ -179,7 +178,7 @@ service.requests.bytes.total service.responses.bytes.total ``` -```influxdb tab="InfluxDB / InfluxDB2" +```influxdb tab="InfluxDB2" traefik.service.requests.total traefik.service.requests.tls.total traefik.service.request.duration diff --git a/docs/content/operations/include-api-examples.md b/docs/content/operations/include-api-examples.md index 33fc71a09..aa49dae33 100644 --- a/docs/content/operations/include-api-examples.md +++ b/docs/content/operations/include-api-examples.md @@ -51,24 +51,6 @@ spec: - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" ``` -```json tab="Marathon" -"labels": { - "traefik.http.routers.api.rule": "Host(`traefik.example.com`)", - "traefik.http.routers.api.service": "api@internal", - "traefik.http.routers.api.middlewares": "auth", - "traefik.http.middlewares.auth.basicauth.users": "test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" -} -``` - -```yaml tab="Rancher" -# Dynamic Configuration -labels: - - "traefik.http.routers.api.rule=Host(`traefik.example.com`)" - - "traefik.http.routers.api.service=api@internal" - - "traefik.http.routers.api.middlewares=auth" - - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" -``` - ```yaml tab="File (YAML)" # Dynamic Configuration http: diff --git a/docs/content/operations/include-dashboard-examples.md b/docs/content/operations/include-dashboard-examples.md index eb72d3a0a..9d90c42c4 100644 --- a/docs/content/operations/include-dashboard-examples.md +++ b/docs/content/operations/include-dashboard-examples.md @@ -51,24 +51,6 @@ spec: - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" ``` -```json tab="Marathon" -"labels": { - "traefik.http.routers.dashboard.rule": "Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))", - "traefik.http.routers.dashboard.service": "api@internal", - "traefik.http.routers.dashboard.middlewares": "auth", - "traefik.http.middlewares.auth.basicauth.users": "test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" -} -``` - -```yaml tab="Rancher" -# Dynamic Configuration -labels: - - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))" - - "traefik.http.routers.dashboard.service=api@internal" - - "traefik.http.routers.dashboard.middlewares=auth" - - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" -``` - ```yaml tab="File (YAML)" # Dynamic Configuration http: diff --git a/docs/content/providers/marathon.md b/docs/content/providers/marathon.md deleted file mode 100644 index a0ab85ccb..000000000 --- a/docs/content/providers/marathon.md +++ /dev/null @@ -1,583 +0,0 @@ ---- -title: "Traefik Configuration for Marathon" -description: "Traefik Proxy can be configured to use Marathon as a provider. Read the technical documentation to learn how." ---- - -# Traefik & Marathon - -Traefik can be configured to use Marathon as a provider. -{: .subtitle } - -For additional information, refer to [Marathon user guide](../user-guides/marathon.md). - -## Configuration Examples - -??? example "Configuring Marathon & Deploying / Exposing Applications" - - Enabling the Marathon provider - - ```yaml tab="File (YAML)" - providers: - marathon: {} - ``` - - ```toml tab="File (TOML)" - [providers.marathon] - ``` - - ```bash tab="CLI" - --providers.marathon=true - ``` - - Attaching labels to Marathon applications - - ```json - { - "id": "/whoami", - "container": { - "type": "DOCKER", - "docker": { - "image": "traefik/whoami", - "network": "BRIDGE", - "portMappings": [ - { - "containerPort": 80, - "hostPort": 0, - "protocol": "tcp" - } - ] - } - }, - "labels": { - "traefik.http.Routers.app.Rule": "PathPrefix(`/app`)" - } - } - ``` - -## Routing Configuration - -See the dedicated section in [routing](../routing/providers/marathon.md). - -## Provider Configuration - -### `basic` - -_Optional_ - -Enables Marathon basic authentication. - -```yaml tab="File (YAML)" -providers: - marathon: - basic: - httpBasicAuthUser: foo - httpBasicPassword: bar -``` - -```toml tab="File (TOML)" -[providers.marathon.basic] - httpBasicAuthUser = "foo" - httpBasicPassword = "bar" -``` - -```bash tab="CLI" ---providers.marathon.basic.httpbasicauthuser=foo ---providers.marathon.basic.httpbasicpassword=bar -``` - -### `dcosToken` - -_Optional_ - -Datacenter Operating System (DCOS) Token for DCOS environment. - -If set, it overrides the Authorization header. - -```toml tab="File (YAML)" -providers: - marathon: - dcosToken: "xxxxxx" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - dcosToken = "xxxxxx" - # ... -``` - -```bash tab="CLI" ---providers.marathon.dcosToken=xxxxxx -``` - -### `defaultRule` - -_Optional, Default=```Host(`{{ normalize .Name }}`)```_ - -The default host rule for all services. - -For a given application, if no routing rule was defined by a label, it is defined by this `defaultRule` instead. - -It must be a valid [Go template](https://pkg.go.dev/text/template/), -and can include [sprig template functions](https://masterminds.github.io/sprig/). - -The app ID can be accessed with the `Name` identifier, -and the template has access to all the labels defined on this Marathon application. - -```yaml tab="File (YAML)" -providers: - marathon: - defaultRule: "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" - # ... -``` - -```bash tab="CLI" ---providers.marathon.defaultRule=Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`) -# ... -``` - -### `dialerTimeout` - -_Optional, Default=5s_ - -Amount of time the Marathon provider should wait before timing out, -when trying to open a TCP connection to a Marathon master. - -The value of `dialerTimeout` should be provided in seconds or as a valid duration format, -see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration). - -```yaml tab="File (YAML)" -providers: - marathon: - dialerTimeout: "10s" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - dialerTimeout = "10s" - # ... -``` - -```bash tab="CLI" ---providers.marathon.dialerTimeout=10s -``` - -### `endpoint` - -_Optional, Default=http://127.0.0.1:8080_ - -Marathon server endpoint. - -You can optionally specify multiple endpoints. - -```yaml tab="File (YAML)" -providers: - marathon: - endpoint: "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - endpoint = "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" - # ... -``` - -```bash tab="CLI" ---providers.marathon.endpoint=http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080 -``` - -### `exposedByDefault` - -_Optional, Default=true_ - -Exposes Marathon applications by default through Traefik. - -If set to `false`, applications that do not have a `traefik.enable=true` label are ignored from the resulting routing configuration. - -For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). - -```yaml tab="File (YAML)" -providers: - marathon: - exposedByDefault: false - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - exposedByDefault = false - # ... -``` - -```bash tab="CLI" ---providers.marathon.exposedByDefault=false -# ... -``` - -### `constraints` - -_Optional, Default=""_ - -The `constraints` option can be set to an expression that Traefik matches against the application labels to determine whether -to create any route for that application. If none of the application labels match the expression, no route for that application is -created. In addition, the expression is also matched against the application constraints, such as described -in [Marathon constraints](https://mesosphere.github.io/marathon/docs/constraints.html). -If the expression is empty, all detected applications are included. - -The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions, as well as the usual boolean logic. -In addition, to match against Marathon constraints, the function `MarathonConstraint("field:operator:value")` can be used, where the field, operator, and value parts are concatenated in a single string using the `:` separator. - -??? example "Constraints Expression Examples" - - ```toml - # Includes only applications having a label with key `a.label.name` and value `foo` - constraints = "Label(`a.label.name`, `foo`)" - ``` - - ```toml - # Excludes applications 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 applications having a label with key `a.label.name` and a value matching the `a.+` regular expression. - constraints = "LabelRegex(`a.label.name`, `a.+`)" - ``` - - ```toml - # Includes only applications having a Marathon constraint with field `A`, operator `B`, and value `C`. - constraints = "MarathonConstraint(`A:B:C`)" - ``` - - ```toml - # Uses both Marathon constraint and application label with logical operator. - constraints = "MarathonConstraint(`A:B:C`) && Label(`a.label.name`, `value`)" - ``` - -For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). - -```yaml tab="File (YAML)" -providers: - marathon: - constraints: "Label(`a.label.name`,`foo`)" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - constraints = "Label(`a.label.name`,`foo`)" - # ... -``` - -```bash tab="CLI" ---providers.marathon.constraints=Label(`a.label.name`,`foo`) -# ... -``` - -### `forceTaskHostname` - -_Optional, Default=false_ - -By default, the task IP address (as returned by the Marathon API) is used as backend server if an IP-per-task configuration can be found; -otherwise, the name of the host running the task is used. -The latter behavior can be enforced by setting this option to `true`. - -```yaml tab="File (YAML)" -providers: - marathon: - forceTaskHostname: true - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - forceTaskHostname = true - # ... -``` - -```bash tab="CLI" ---providers.marathon.forceTaskHostname=true -# ... -``` - -### `keepAlive` - -_Optional, Default=10s_ - -Set the TCP Keep Alive duration for the Marathon HTTP Client. -The value of `keepAlive` should be provided in seconds or as a valid duration format, -see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration). - -```yaml tab="File (YAML)" -providers: - marathon: - keepAlive: "30s" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - keepAlive = "30s" - # ... -``` - -```bash tab="CLI" ---providers.marathon.keepAlive=30s -# ... -``` - -### `respectReadinessChecks` - -_Optional, Default=false_ - -Applications may define readiness checks which are probed by Marathon during deployments periodically, and these check results are exposed via the API. -Enabling `respectReadinessChecks` causes Traefik to filter out tasks whose readiness checks have not succeeded. -Note that the checks are only valid during deployments. - -See the Marathon guide for details. - -```yaml tab="File (YAML)" -providers: - marathon: - respectReadinessChecks: true - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - respectReadinessChecks = true - # ... -``` - -```bash tab="CLI" ---providers.marathon.respectReadinessChecks=true -# ... -``` - -### `responseHeaderTimeout` - -_Optional, Default=60s_ - -Amount of time the Marathon provider should wait before timing out when waiting for the first response header -from a Marathon master. - -The value of `responseHeaderTimeout` should be provided in seconds or as a valid duration format, -see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration). - -```yaml tab="File (YAML)" -providers: - marathon: - responseHeaderTimeout: "66s" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - responseHeaderTimeout = "66s" - # ... -``` - -```bash tab="CLI" ---providers.marathon.responseHeaderTimeout=66s -# ... -``` - -### `tls` - -_Optional_ - -Defines the TLS configuration used for the secure connection to Marathon. - -#### `ca` - -`ca` is the path to the certificate authority used for the secure connection to Marathon, -it defaults to the system bundle. - -```yaml tab="File (YAML)" -providers: - marathon: - tls: - ca: path/to/ca.crt -``` - -```toml tab="File (TOML)" -[providers.marathon.tls] - ca = "path/to/ca.crt" -``` - -```bash tab="CLI" ---providers.marathon.tls.ca=path/to/ca.crt -``` - -#### `cert` - -_Optional_ - -`cert` is the path to the public certificate used for the secure connection to Marathon. -When using this option, setting the `key` option is required. - -```yaml tab="File (YAML)" -providers: - marathon: - tls: - cert: path/to/foo.cert - key: path/to/foo.key -``` - -```toml tab="File (TOML)" -[providers.marathon.tls] - cert = "path/to/foo.cert" - key = "path/to/foo.key" -``` - -```bash tab="CLI" ---providers.marathon.tls.cert=path/to/foo.cert ---providers.marathon.tls.key=path/to/foo.key -``` - -#### `key` - -_Optional_ - -`key` is the path to the private key used for the secure connection to Marathon. -When using this option, setting the `cert` option is required. - -```yaml tab="File (YAML)" -providers: - marathon: - tls: - cert: path/to/foo.cert - key: path/to/foo.key -``` - -```toml tab="File (TOML)" -[providers.marathon.tls] - cert = "path/to/foo.cert" - key = "path/to/foo.key" -``` - -```bash tab="CLI" ---providers.marathon.tls.cert=path/to/foo.cert ---providers.marathon.tls.key=path/to/foo.key -``` - -#### `insecureSkipVerify` - -_Optional, Default=false_ - -If `insecureSkipVerify` is `true`, the TLS connection to Marathon accepts any certificate presented by the server regardless of the hostnames it covers. - -```yaml tab="File (YAML)" -providers: - marathon: - tls: - insecureSkipVerify: true -``` - -```toml tab="File (TOML)" -[providers.marathon.tls] - insecureSkipVerify = true -``` - -```bash tab="CLI" ---providers.marathon.tls.insecureSkipVerify=true -``` - -### `tlsHandshakeTimeout` - -_Optional, Default=5s_ - -Amount of time the Marathon provider should wait before timing out, -when waiting for the TLS handshake to complete. - -The value of `tlsHandshakeTimeout` should be provided in seconds or as a valid duration format, -see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration). - -```yaml tab="File (YAML)" -providers: - marathon: - tlsHandshakeTimeout: "10s" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - tlsHandshakeTimeout = "10s" - # ... -``` - -```bash tab="CLI" ---providers.marathon.tlsHandshakeTimeout=10s -# ... -``` - -### `trace` - -_Optional, Default=false_ - -Displays additional provider logs when available. - -```yaml tab="File (YAML)" -providers: - marathon: - trace: true - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - trace = true - # ... -``` - -```bash tab="CLI" ---providers.marathon.trace=true -# ... -``` - -### `watch` - -_Optional, Default=true_ - -When set to `true`, watches for Marathon changes. - -```yaml tab="File (YAML)" -providers: - marathon: - watch: false - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - watch = false - # ... -``` - -```bash tab="CLI" ---providers.marathon.watch=false -# ... -``` diff --git a/docs/content/providers/overview.md b/docs/content/providers/overview.md index de0af45fe..47d6178e8 100644 --- a/docs/content/providers/overview.md +++ b/docs/content/providers/overview.md @@ -141,8 +141,6 @@ Below is the list of the currently supported providers in Traefik. | [Consul Catalog](./consul-catalog.md) | Orchestrator | Label | `consulcatalog` | | [Nomad](./nomad.md) | Orchestrator | Label | `nomad` | | [ECS](./ecs.md) | Orchestrator | Label | `ecs` | -| [Marathon](./marathon.md) | Orchestrator | Label | `marathon` | -| [Rancher](./rancher.md) | Orchestrator | Label | `rancher` | | [File](./file.md) | Manual | YAML/TOML format | `file` | | [Consul](./consul.md) | KV | KV | `consul` | | [Etcd](./etcd.md) | KV | KV | `etcd` | @@ -216,8 +214,6 @@ List of providers that support these features: - [ECS](./ecs.md#exposedbydefault) - [Consul Catalog](./consul-catalog.md#exposedbydefault) - [Nomad](./nomad.md#exposedbydefault) -- [Rancher](./rancher.md#exposedbydefault) -- [Marathon](./marathon.md#exposedbydefault) ### Constraints @@ -227,8 +223,6 @@ List of providers that support constraints: - [ECS](./ecs.md#constraints) - [Consul Catalog](./consul-catalog.md#constraints) - [Nomad](./nomad.md#constraints) -- [Rancher](./rancher.md#constraints) -- [Marathon](./marathon.md#constraints) - [Kubernetes CRD](./kubernetes-crd.md#labelselector) - [Kubernetes Ingress](./kubernetes-ingress.md#labelselector) - [Kubernetes Gateway](./kubernetes-gateway.md#labelselector) diff --git a/docs/content/providers/rancher.md b/docs/content/providers/rancher.md deleted file mode 100644 index b709a5329..000000000 --- a/docs/content/providers/rancher.md +++ /dev/null @@ -1,286 +0,0 @@ ---- -title: ""Traefik Configuration Discovery: Rancher"" -description: "Read the official Traefik documentation to learn how to expose Rancher services by default in Traefik Proxy." ---- - -# Traefik & Rancher - -A Story of Labels, Services & Containers -{: .subtitle } - -![Rancher](../assets/img/providers/rancher.png) - -Attach labels to your services and let Traefik do the rest! - -!!! important "This provider is specific to Rancher 1.x." - - Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query. - As such, Rancher 2.x users should utilize the [Kubernetes CRD provider](./kubernetes-crd.md) directly. - -## Configuration Examples - -??? example "Configuring Rancher & Deploying / Exposing Services" - - Enabling the Rancher provider - - ```yaml tab="File (YAML)" - providers: - rancher: {} - ``` - - ```toml tab="File (TOML)" - [providers.rancher] - ``` - - ```bash tab="CLI" - --providers.rancher=true - ``` - - Attaching labels to services - - ```yaml - labels: - - traefik.http.services.my-service.rule=Host(`example.com`) - ``` - -## Routing Configuration - -See the dedicated section in [routing](../routing/providers/rancher.md). - -## Provider Configuration - -??? tip "Browse the Reference" - - For an overview of all the options that can be set with the Rancher provider, see the following snippets: - - ```yaml tab="File (YAML)" - --8<-- "content/providers/rancher.yml" - ``` - - ```toml tab="File (TOML)" - --8<-- "content/providers/rancher.toml" - ``` - - ```bash tab="CLI" - --8<-- "content/providers/rancher.txt" - ``` - -### `exposedByDefault` - -_Optional, Default=true_ - -Expose Rancher services by default in Traefik. -If set to `false`, services that do not have a `traefik.enable=true` label are ignored from the resulting routing configuration. - -For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). - -```yaml tab="File (YAML)" -providers: - rancher: - exposedByDefault: false - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - exposedByDefault = false - # ... -``` - -```bash tab="CLI" ---providers.rancher.exposedByDefault=false -# ... -``` - -### `defaultRule` - -_Optional, Default=```Host(`{{ normalize .Name }}`)```_ - -The default host rule for all services. - -The `defaultRule` option defines what routing rule to apply to a container if no rule is defined by a label. - -It must be a valid [Go template](https://pkg.go.dev/text/template/), and can use -[sprig template functions](https://masterminds.github.io/sprig/). -The service name can be accessed with the `Name` identifier, -and the template has access to all the labels defined on this container. - -This option can be overridden on a container basis with the `traefik.http.routers.Router1.rule` label. - -```yaml tab="File (YAML)" -providers: - rancher: - defaultRule: "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" - # ... -``` - -```bash tab="CLI" ---providers.rancher.defaultRule=Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`) -# ... -``` - -### `enableServiceHealthFilter` - -_Optional, Default=true_ - -Filter out services with unhealthy states and inactive states. - -```yaml tab="File (YAML)" -providers: - rancher: - enableServiceHealthFilter: false - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - enableServiceHealthFilter = false - # ... -``` - -```bash tab="CLI" ---providers.rancher.enableServiceHealthFilter=false -# ... -``` - -### `refreshSeconds` - -_Optional, Default=15_ - -Defines the polling interval (in seconds). - -```yaml tab="File (YAML)" -providers: - rancher: - refreshSeconds: 30 - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - refreshSeconds = 30 - # ... -``` - -```bash tab="CLI" ---providers.rancher.refreshSeconds=30 -# ... -``` - -### `intervalPoll` - -_Optional, Default=false_ - -Poll the Rancher metadata service for changes every `rancher.refreshSeconds`, -which is less accurate than the default long polling technique which provides near instantaneous updates to Traefik. - -```yaml tab="File (YAML)" -providers: - rancher: - intervalPoll: true - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - intervalPoll = true - # ... -``` - -```bash tab="CLI" ---providers.rancher.intervalPoll=true -# ... -``` - -### `prefix` - -_Optional, Default="/latest"_ - -Prefix used for accessing the Rancher metadata service. - -```yaml tab="File (YAML)" -providers: - rancher: - prefix: "/test" - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - prefix = "/test" - # ... -``` - -```bash tab="CLI" ---providers.rancher.prefix=/test -# ... -``` - -### `constraints` - -_Optional, Default=""_ - -The `constraints` option can be set to an expression that Traefik matches against the container labels to determine whether -to create any route for that container. If none of the container tags 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: - rancher: - constraints: "Label(`a.label.name`,`foo`)" - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - constraints = "Label(`a.label.name`,`foo`)" - # ... -``` - -```bash tab="CLI" ---providers.rancher.constraints=Label(`a.label.name`,`foo`) -# ... -``` diff --git a/docs/content/providers/rancher.toml b/docs/content/providers/rancher.toml deleted file mode 100644 index e809d737d..000000000 --- a/docs/content/providers/rancher.toml +++ /dev/null @@ -1,20 +0,0 @@ -# Enable Rancher Provider. -[providers.rancher] - - # Expose Rancher services by default in Traefik. - exposedByDefault = true - - # Enable watch Rancher changes. - watch = true - - # Filter services with unhealthy states and inactive states. - enableServiceHealthFilter = true - - # Defines the polling interval (in seconds). - refreshSeconds = 15 - - # Poll the Rancher metadata service for changes every `rancher.refreshSeconds`, which is less accurate - intervalPoll = false - - # Prefix used for accessing the Rancher metadata service - prefix = "/latest" diff --git a/docs/content/providers/rancher.txt b/docs/content/providers/rancher.txt deleted file mode 100644 index 158826cda..000000000 --- a/docs/content/providers/rancher.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Enable Rancher Provider. ---providers.rancher=true - -# Expose Rancher services by default in Traefik. ---providers.rancher.exposedByDefault=true - -# Enable watch Rancher changes. ---providers.rancher.watch=true - -# Filter services with unhealthy states and inactive states. ---providers.rancher.enableServiceHealthFilter=true - -# Defines the polling interval (in seconds). ---providers.rancher.refreshSeconds=15 - -# Poll the Rancher metadata service for changes every `rancher.refreshSeconds`, which is less accurate ---providers.rancher.intervalPoll=false - -# Prefix used for accessing the Rancher metadata service ---providers.rancher.prefix=/latest diff --git a/docs/content/providers/rancher.yml b/docs/content/providers/rancher.yml deleted file mode 100644 index 227b352c3..000000000 --- a/docs/content/providers/rancher.yml +++ /dev/null @@ -1,21 +0,0 @@ -# Enable Rancher Provider. -providers: - rancher: - - # Expose Rancher services by default in Traefik. - exposedByDefault: true - - # Enable watch Rancher changes. - watch: true - - # Filter services with unhealthy states and inactive states. - enableServiceHealthFilter: true - - # Defines the polling interval (in seconds). - refreshSeconds: 15 - - # Poll the Rancher metadata service for changes every `rancher.refreshSeconds`, which is less accurate - intervalPoll: false - - # Prefix used for accessing the Rancher metadata service - prefix: /latest diff --git a/docs/content/reference/dynamic-configuration/marathon-labels.json b/docs/content/reference/dynamic-configuration/marathon-labels.json deleted file mode 100644 index afac8bb13..000000000 --- a/docs/content/reference/dynamic-configuration/marathon-labels.json +++ /dev/null @@ -1,210 +0,0 @@ -"traefik.http.middlewares.middleware00.addprefix.prefix": "foobar", -"traefik.http.middlewares.middleware01.basicauth.headerfield": "foobar", -"traefik.http.middlewares.middleware01.basicauth.realm": "foobar", -"traefik.http.middlewares.middleware01.basicauth.removeheader": "true", -"traefik.http.middlewares.middleware01.basicauth.users": "foobar, foobar", -"traefik.http.middlewares.middleware01.basicauth.usersfile": "foobar", -"traefik.http.middlewares.middleware02.buffering.maxrequestbodybytes": "42", -"traefik.http.middlewares.middleware02.buffering.maxresponsebodybytes": "42", -"traefik.http.middlewares.middleware02.buffering.memrequestbodybytes": "42", -"traefik.http.middlewares.middleware02.buffering.memresponsebodybytes": "42", -"traefik.http.middlewares.middleware02.buffering.retryexpression": "foobar", -"traefik.http.middlewares.middleware03.chain.middlewares": "foobar, foobar", -"traefik.http.middlewares.middleware04.circuitbreaker.expression": "foobar", -"traefik.http.middlewares.middleware04.circuitbreaker.checkperiod": "42s", -"traefik.http.middlewares.middleware04.circuitbreaker.fallbackduration": "42s", -"traefik.http.middlewares.middleware04.circuitbreaker.recoveryduration": "42s", -"traefik.http.middlewares.middleware05.compress": "true", -"traefik.http.middlewares.middleware05.compress.excludedcontenttypes": "foobar, foobar", -"traefik.http.middlewares.middleware05.compress.minresponsebodybytes": "42", -"traefik.http.middlewares.middleware06.contenttype": "true", -"traefik.http.middlewares.middleware07.digestauth.headerfield": "foobar", -"traefik.http.middlewares.middleware07.digestauth.realm": "foobar", -"traefik.http.middlewares.middleware07.digestauth.removeheader": "true", -"traefik.http.middlewares.middleware07.digestauth.users": "foobar, foobar", -"traefik.http.middlewares.middleware07.digestauth.usersfile": "foobar", -"traefik.http.middlewares.middleware08.errors.query": "foobar", -"traefik.http.middlewares.middleware08.errors.service": "foobar", -"traefik.http.middlewares.middleware08.errors.status": "foobar, foobar", -"traefik.http.middlewares.middleware09.forwardauth.address": "foobar", -"traefik.http.middlewares.middleware09.forwardauth.authrequestheaders": "foobar, foobar", -"traefik.http.middlewares.middleware09.forwardauth.authresponseheaders": "foobar, foobar", -"traefik.http.middlewares.middleware09.forwardauth.authresponseheadersregex": "foobar", -"traefik.http.middlewares.middleware09.forwardauth.tls.ca": "foobar", -"traefik.http.middlewares.middleware09.forwardauth.tls.cert": "foobar", -"traefik.http.middlewares.middleware09.forwardauth.tls.insecureskipverify": "true", -"traefik.http.middlewares.middleware09.forwardauth.tls.key": "foobar", -"traefik.http.middlewares.middleware09.forwardauth.trustforwardheader": "true", -"traefik.http.middlewares.middleware10.headers.accesscontrolallowcredentials": "true", -"traefik.http.middlewares.middleware10.headers.accesscontrolallowheaders": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.accesscontrolallowmethods": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.accesscontrolalloworiginlist": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.accesscontrolalloworiginlistregex": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.accesscontrolexposeheaders": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.accesscontrolmaxage": "42", -"traefik.http.middlewares.middleware10.headers.addvaryheader": "true", -"traefik.http.middlewares.middleware10.headers.allowedhosts": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.browserxssfilter": "true", -"traefik.http.middlewares.middleware10.headers.contentsecuritypolicy": "foobar", -"traefik.http.middlewares.middleware10.headers.contenttypenosniff": "true", -"traefik.http.middlewares.middleware10.headers.custombrowserxssvalue": "foobar", -"traefik.http.middlewares.middleware10.headers.customframeoptionsvalue": "foobar", -"traefik.http.middlewares.middleware10.headers.customrequestheaders.name0": "foobar", -"traefik.http.middlewares.middleware10.headers.customrequestheaders.name1": "foobar", -"traefik.http.middlewares.middleware10.headers.customresponseheaders.name0": "foobar", -"traefik.http.middlewares.middleware10.headers.customresponseheaders.name1": "foobar", -"traefik.http.middlewares.middleware10.headers.forcestsheader": "true", -"traefik.http.middlewares.middleware10.headers.framedeny": "true", -"traefik.http.middlewares.middleware10.headers.hostsproxyheaders": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.isdevelopment": "true", -"traefik.http.middlewares.middleware10.headers.permissionspolicy": "foobar", -"traefik.http.middlewares.middleware10.headers.publickey": "foobar", -"traefik.http.middlewares.middleware10.headers.referrerpolicy": "foobar", -"traefik.http.middlewares.middleware10.headers.sslproxyheaders.name0": "foobar", -"traefik.http.middlewares.middleware10.headers.sslproxyheaders.name1": "foobar", -"traefik.http.middlewares.middleware10.headers.stsincludesubdomains": "true", -"traefik.http.middlewares.middleware10.headers.stspreload": "true", -"traefik.http.middlewares.middleware10.headers.stsseconds": "42", -"traefik.http.middlewares.middleware11.ipallowlist.ipstrategy.depth": "42", -"traefik.http.middlewares.middleware11.ipallowlist.ipstrategy.excludedips": "foobar, foobar", -"traefik.http.middlewares.middleware11.ipallowlist.sourcerange": "foobar, foobar", -"traefik.http.middlewares.middleware12.inflightreq.amount": "42", -"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.depth": "42", -"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.excludedips": "foobar, foobar", -"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requestheadername": "foobar", -"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requesthost": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.commonname": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.country": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.domaincomponent": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.locality": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.organization": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.province": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.serialnumber": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.notafter": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.notbefore": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.sans": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.serialnumber": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.commonname": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.country": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.domaincomponent": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.locality": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.organization": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.organizationalunit": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.province": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.serialnumber": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.pem": "true", -"traefik.http.middlewares.middleware14.plugin.foobar.foo": "bar", -"traefik.http.middlewares.middleware15.ratelimit.average": "42", -"traefik.http.middlewares.middleware15.ratelimit.burst": "42", -"traefik.http.middlewares.middleware15.ratelimit.period": "42", -"traefik.http.middlewares.middleware15.ratelimit.sourcecriterion.ipstrategy.depth": "42", -"traefik.http.middlewares.middleware15.ratelimit.sourcecriterion.ipstrategy.excludedips": "foobar, foobar", -"traefik.http.middlewares.middleware15.ratelimit.sourcecriterion.requestheadername": "foobar", -"traefik.http.middlewares.middleware15.ratelimit.sourcecriterion.requesthost": "true", -"traefik.http.middlewares.middleware16.redirectregex.permanent": "true", -"traefik.http.middlewares.middleware16.redirectregex.regex": "foobar", -"traefik.http.middlewares.middleware16.redirectregex.replacement": "foobar", -"traefik.http.middlewares.middleware17.redirectscheme.permanent": "true", -"traefik.http.middlewares.middleware17.redirectscheme.port": "foobar", -"traefik.http.middlewares.middleware17.redirectscheme.scheme": "foobar", -"traefik.http.middlewares.middleware18.replacepath.path": "foobar", -"traefik.http.middlewares.middleware19.replacepathregex.regex": "foobar", -"traefik.http.middlewares.middleware19.replacepathregex.replacement": "foobar", -"traefik.http.middlewares.middleware20.retry.attempts": "42", -"traefik.http.middlewares.middleware20.retry.initialinterval": "42", -"traefik.http.middlewares.middleware21.stripprefix.prefixes": "foobar, foobar", -"traefik.http.middlewares.middleware22.stripprefixregex.regex": "foobar, foobar", -"traefik.http.middlewares.middleware23.grpcweb.alloworigins": "foobar, foobar", -"traefik.http.routers.router0.entrypoints": "foobar, foobar", -"traefik.http.routers.router0.middlewares": "foobar, foobar", -"traefik.http.routers.router0.priority": "42", -"traefik.http.routers.router0.rule": "foobar", -"traefik.http.routers.router0.service": "foobar", -"traefik.http.routers.router0.tls": "true", -"traefik.http.routers.router0.tls.certresolver": "foobar", -"traefik.http.routers.router0.tls.domains[0].main": "foobar", -"traefik.http.routers.router0.tls.domains[0].sans": "foobar, foobar", -"traefik.http.routers.router0.tls.domains[1].main": "foobar", -"traefik.http.routers.router0.tls.domains[1].sans": "foobar, foobar", -"traefik.http.routers.router0.tls.options": "foobar", -"traefik.http.routers.router1.entrypoints": "foobar, foobar", -"traefik.http.routers.router1.middlewares": "foobar, foobar", -"traefik.http.routers.router1.priority": "42", -"traefik.http.routers.router1.rule": "foobar", -"traefik.http.routers.router1.service": "foobar", -"traefik.http.routers.router1.tls": "true", -"traefik.http.routers.router1.tls.certresolver": "foobar", -"traefik.http.routers.router1.tls.domains[0].main": "foobar", -"traefik.http.routers.router1.tls.domains[0].sans": "foobar, foobar", -"traefik.http.routers.router1.tls.domains[1].main": "foobar", -"traefik.http.routers.router1.tls.domains[1].sans": "foobar, foobar", -"traefik.http.routers.router1.tls.options": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.followredirects": "true", -"traefik.http.services.service01.loadbalancer.healthcheck.headers.name0": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.headers.name1": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.hostname": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.interval": "42s", -"traefik.http.services.service01.loadbalancer.healthcheck.path": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.method": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.status": "42", -"traefik.http.services.service01.loadbalancer.healthcheck.port": "42", -"traefik.http.services.service01.loadbalancer.healthcheck.scheme": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.mode": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.timeout": "42s", -"traefik.http.services.service01.loadbalancer.passhostheader": "true", -"traefik.http.services.service01.loadbalancer.responseforwarding.flushinterval": "42s", -"traefik.http.services.service01.loadbalancer.serverstransport": "foobar", -"traefik.http.services.service01.loadbalancer.sticky.cookie": "true", -"traefik.http.services.service01.loadbalancer.sticky.cookie.httponly": "true", -"traefik.http.services.service01.loadbalancer.sticky.cookie.name": "foobar", -"traefik.http.services.service01.loadbalancer.sticky.cookie.samesite": "foobar", -"traefik.http.services.service01.loadbalancer.sticky.cookie.secure": "true", -"traefik.http.services.service01.loadbalancer.server.port": "foobar", -"traefik.http.services.service01.loadbalancer.server.scheme": "foobar", -"traefik.tcp.middlewares.tcpmiddleware00.ipallowlist.sourcerange": "foobar, foobar", -"traefik.tcp.middlewares.tcpmiddleware01.inflightconn.amount": "42", -"traefik.tcp.routers.tcprouter0.entrypoints": "foobar, foobar", -"traefik.tcp.routers.tcprouter0.middlewares": "foobar, foobar", -"traefik.tcp.routers.tcprouter0.rule": "foobar", -"traefik.tcp.routers.tcprouter0.priority": "42", -"traefik.tcp.routers.tcprouter0.service": "foobar", -"traefik.tcp.routers.tcprouter0.tls": "true", -"traefik.tcp.routers.tcprouter0.tls.certresolver": "foobar", -"traefik.tcp.routers.tcprouter0.tls.domains[0].main": "foobar", -"traefik.tcp.routers.tcprouter0.tls.domains[0].sans": "foobar, foobar", -"traefik.tcp.routers.tcprouter0.tls.domains[1].main": "foobar", -"traefik.tcp.routers.tcprouter0.tls.domains[1].sans": "foobar, foobar", -"traefik.tcp.routers.tcprouter0.tls.options": "foobar", -"traefik.tcp.routers.tcprouter0.tls.passthrough": "true", -"traefik.tcp.routers.tcprouter1.entrypoints": "foobar, foobar", -"traefik.tcp.routers.tcprouter1.middlewares": "foobar, foobar", -"traefik.tcp.routers.tcprouter1.rule": "foobar", -"traefik.tcp.routers.tcprouter1.priority": "42", -"traefik.tcp.routers.tcprouter1.service": "foobar", -"traefik.tcp.routers.tcprouter1.tls": "true", -"traefik.tcp.routers.tcprouter1.tls.certresolver": "foobar", -"traefik.tcp.routers.tcprouter1.tls.domains[0].main": "foobar", -"traefik.tcp.routers.tcprouter1.tls.domains[0].sans": "foobar, foobar", -"traefik.tcp.routers.tcprouter1.tls.domains[1].main": "foobar", -"traefik.tcp.routers.tcprouter1.tls.domains[1].sans": "foobar, foobar", -"traefik.tcp.routers.tcprouter1.tls.options": "foobar", -"traefik.tcp.routers.tcprouter1.tls.passthrough": "true", -"traefik.tcp.services.tcpservice01.loadbalancer.proxyprotocol.version": "42", -"traefik.tcp.services.tcpservice01.loadbalancer.server.port": "foobar", -"traefik.tcp.services.tcpservice01.loadbalancer.server.tls": "true", -"traefik.tcp.services.tcpservice01.loadbalancer.serverstransport": "foobar", -"traefik.udp.routers.udprouter0.entrypoints": "foobar, foobar", -"traefik.udp.routers.udprouter0.service": "foobar", -"traefik.udp.routers.udprouter1.entrypoints": "foobar, foobar", -"traefik.udp.routers.udprouter1.service": "foobar", -"traefik.udp.services.udpservice01.loadbalancer.server.port": "foobar", -"traefik.tls.stores.Store0.defaultcertificate.certfile": "foobar", -"traefik.tls.stores.Store0.defaultcertificate.keyfile": "foobar", -"traefik.tls.stores.Store0.defaultgeneratedcert.domain.main": "foobar", -"traefik.tls.stores.Store0.defaultgeneratedcert.domain.sans": "foobar, foobar", -"traefik.tls.stores.Store0.defaultgeneratedcert.resolver": "foobar", -"traefik.tls.stores.Store1.defaultcertificate.certfile": "foobar", -"traefik.tls.stores.Store1.defaultcertificate.keyfile": "foobar", -"traefik.tls.stores.Store1.defaultgeneratedcert.domain.main": "foobar", -"traefik.tls.stores.Store1.defaultgeneratedcert.domain.sans": "foobar, foobar", -"traefik.tls.stores.Store1.defaultgeneratedcert.resolver": "foobar", diff --git a/docs/content/reference/dynamic-configuration/marathon.json b/docs/content/reference/dynamic-configuration/marathon.json deleted file mode 100644 index 131344a7e..000000000 --- a/docs/content/reference/dynamic-configuration/marathon.json +++ /dev/null @@ -1,2 +0,0 @@ -"traefik.enable": "true", -"traefik.marathon.ipaddressidx": "42", diff --git a/docs/content/reference/dynamic-configuration/marathon.md b/docs/content/reference/dynamic-configuration/marathon.md deleted file mode 100644 index 0e20679f8..000000000 --- a/docs/content/reference/dynamic-configuration/marathon.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: "Dynamic Configuration with Marathon Labels" -description: "Traefik Proxy can be configured to use Marathon as a provider. Read the technical documentation on the Traefik dynamic configuration with Marathon Labels." ---- - -# Marathon Configuration Reference - -Dynamic configuration with Marathon Labels -{: .subtitle } - -```json -"labels": { - --8<-- "content/reference/dynamic-configuration/marathon.json" - --8<-- "content/reference/dynamic-configuration/marathon-labels.json" -} -``` diff --git a/docs/content/reference/dynamic-configuration/rancher.md b/docs/content/reference/dynamic-configuration/rancher.md deleted file mode 100644 index c2762999d..000000000 --- a/docs/content/reference/dynamic-configuration/rancher.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: "Traefik Dynamic Configuration with Rancher" -description: "Read the official Traefik documentation to learn more on dynamic configuration in Traefik Proxy with Rancher Labels." ---- - -# Rancher Configuration Reference - -Dynamic configuration with Rancher Labels -{: .subtitle } - -The labels are case insensitive. - -```yaml -labels: - --8<-- "content/reference/dynamic-configuration/rancher.yml" - --8<-- "content/reference/dynamic-configuration/docker-labels.yml" -``` diff --git a/docs/content/reference/dynamic-configuration/rancher.yml b/docs/content/reference/dynamic-configuration/rancher.yml deleted file mode 100644 index 23efc00c6..000000000 --- a/docs/content/reference/dynamic-configuration/rancher.yml +++ /dev/null @@ -1 +0,0 @@ -- "traefik.enable=true" diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index 3a200ac6b..00bb3af7f 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -288,42 +288,6 @@ Prefix to use for metrics collection. (Default: ```traefik```) `--metrics.datadog.pushinterval`: Datadog push interval. (Default: ```10```) -`--metrics.influxdb`: -InfluxDB metrics exporter type. (Default: ```false```) - -`--metrics.influxdb.addentrypointslabels`: -Enable metrics on entry points. (Default: ```true```) - -`--metrics.influxdb.additionallabels.`: -Additional labels (influxdb tags) on all metrics - -`--metrics.influxdb.address`: -InfluxDB address. (Default: ```localhost:8089```) - -`--metrics.influxdb.addrouterslabels`: -Enable metrics on routers. (Default: ```false```) - -`--metrics.influxdb.addserviceslabels`: -Enable metrics on services. (Default: ```true```) - -`--metrics.influxdb.database`: -InfluxDB database used when protocol is http. - -`--metrics.influxdb.password`: -InfluxDB password (only with http). - -`--metrics.influxdb.protocol`: -InfluxDB address protocol (udp or http). (Default: ```udp```) - -`--metrics.influxdb.pushinterval`: -InfluxDB push interval. (Default: ```10```) - -`--metrics.influxdb.retentionpolicy`: -InfluxDB retention policy used when protocol is http. - -`--metrics.influxdb.username`: -InfluxDB username (only with http). - `--metrics.influxdb2`: InfluxDB v2 metrics exporter type. (Default: ```false```) @@ -798,66 +762,6 @@ Ingress refresh throttle duration (Default: ```0```) `--providers.kubernetesingress.token`: Kubernetes bearer token (not needed for in-cluster client). -`--providers.marathon`: -Enable Marathon backend with default settings. (Default: ```false```) - -`--providers.marathon.basic.httpbasicauthuser`: -Basic authentication User. - -`--providers.marathon.basic.httpbasicpassword`: -Basic authentication Password. - -`--providers.marathon.constraints`: -Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application. - -`--providers.marathon.dcostoken`: -DCOSToken for DCOS environment, This will override the Authorization header. - -`--providers.marathon.defaultrule`: -Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) - -`--providers.marathon.dialertimeout`: -Set a dialer timeout for Marathon. (Default: ```5```) - -`--providers.marathon.endpoint`: -Marathon server endpoint. You can also specify multiple endpoint for Marathon. (Default: ```http://127.0.0.1:8080```) - -`--providers.marathon.exposedbydefault`: -Expose Marathon apps by default. (Default: ```true```) - -`--providers.marathon.forcetaskhostname`: -Force to use the task's hostname. (Default: ```false```) - -`--providers.marathon.keepalive`: -Set a TCP Keep Alive time. (Default: ```10```) - -`--providers.marathon.respectreadinesschecks`: -Filter out tasks with non-successful readiness checks during deployments. (Default: ```false```) - -`--providers.marathon.responseheadertimeout`: -Set a response header timeout for Marathon. (Default: ```60```) - -`--providers.marathon.tls.ca`: -TLS CA - -`--providers.marathon.tls.cert`: -TLS cert - -`--providers.marathon.tls.insecureskipverify`: -TLS insecure skip verify (Default: ```false```) - -`--providers.marathon.tls.key`: -TLS key - -`--providers.marathon.tlshandshaketimeout`: -Set a TLS handshake timeout for Marathon. (Default: ```5```) - -`--providers.marathon.trace`: -Display additional provider logs. (Default: ```false```) - -`--providers.marathon.watch`: -Watch provider. (Default: ```true```) - `--providers.nomad`: Enable Nomad backend with default settings. (Default: ```false```) @@ -912,33 +816,6 @@ Plugins configuration. `--providers.providersthrottleduration`: Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```2```) -`--providers.rancher`: -Enable Rancher backend with default settings. (Default: ```false```) - -`--providers.rancher.constraints`: -Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container. - -`--providers.rancher.defaultrule`: -Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) - -`--providers.rancher.enableservicehealthfilter`: -Filter services with unhealthy states and inactive states. (Default: ```true```) - -`--providers.rancher.exposedbydefault`: -Expose containers by default. (Default: ```true```) - -`--providers.rancher.intervalpoll`: -Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate). (Default: ```false```) - -`--providers.rancher.prefix`: -Prefix used for accessing the Rancher metadata service. (Default: ```latest```) - -`--providers.rancher.refreshseconds`: -Defines the polling interval in seconds. (Default: ```15```) - -`--providers.rancher.watch`: -Watch provider. (Default: ```true```) - `--providers.redis`: Enable Redis backend with default settings. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index 0e28c8313..b6a7429a8 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -288,9 +288,6 @@ Prefix to use for metrics collection. (Default: ```traefik```) `TRAEFIK_METRICS_DATADOG_PUSHINTERVAL`: Datadog push interval. (Default: ```10```) -`TRAEFIK_METRICS_INFLUXDB`: -InfluxDB metrics exporter type. (Default: ```false```) - `TRAEFIK_METRICS_INFLUXDB2`: InfluxDB v2 metrics exporter type. (Default: ```false```) @@ -321,39 +318,6 @@ InfluxDB v2 push interval. (Default: ```10```) `TRAEFIK_METRICS_INFLUXDB2_TOKEN`: InfluxDB v2 access token. -`TRAEFIK_METRICS_INFLUXDB_ADDENTRYPOINTSLABELS`: -Enable metrics on entry points. (Default: ```true```) - -`TRAEFIK_METRICS_INFLUXDB_ADDITIONALLABELS_`: -Additional labels (influxdb tags) on all metrics - -`TRAEFIK_METRICS_INFLUXDB_ADDRESS`: -InfluxDB address. (Default: ```localhost:8089```) - -`TRAEFIK_METRICS_INFLUXDB_ADDROUTERSLABELS`: -Enable metrics on routers. (Default: ```false```) - -`TRAEFIK_METRICS_INFLUXDB_ADDSERVICESLABELS`: -Enable metrics on services. (Default: ```true```) - -`TRAEFIK_METRICS_INFLUXDB_DATABASE`: -InfluxDB database used when protocol is http. - -`TRAEFIK_METRICS_INFLUXDB_PASSWORD`: -InfluxDB password (only with http). - -`TRAEFIK_METRICS_INFLUXDB_PROTOCOL`: -InfluxDB address protocol (udp or http). (Default: ```udp```) - -`TRAEFIK_METRICS_INFLUXDB_PUSHINTERVAL`: -InfluxDB push interval. (Default: ```10```) - -`TRAEFIK_METRICS_INFLUXDB_RETENTIONPOLICY`: -InfluxDB retention policy used when protocol is http. - -`TRAEFIK_METRICS_INFLUXDB_USERNAME`: -InfluxDB username (only with http). - `TRAEFIK_METRICS_OPENTELEMETRY`: OpenTelemetry metrics exporter type. (Default: ```false```) @@ -798,66 +762,6 @@ Ingress refresh throttle duration (Default: ```0```) `TRAEFIK_PROVIDERS_KUBERNETESINGRESS_TOKEN`: Kubernetes bearer token (not needed for in-cluster client). -`TRAEFIK_PROVIDERS_MARATHON`: -Enable Marathon backend with default settings. (Default: ```false```) - -`TRAEFIK_PROVIDERS_MARATHON_BASIC_HTTPBASICAUTHUSER`: -Basic authentication User. - -`TRAEFIK_PROVIDERS_MARATHON_BASIC_HTTPBASICPASSWORD`: -Basic authentication Password. - -`TRAEFIK_PROVIDERS_MARATHON_CONSTRAINTS`: -Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application. - -`TRAEFIK_PROVIDERS_MARATHON_DCOSTOKEN`: -DCOSToken for DCOS environment, This will override the Authorization header. - -`TRAEFIK_PROVIDERS_MARATHON_DEFAULTRULE`: -Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) - -`TRAEFIK_PROVIDERS_MARATHON_DIALERTIMEOUT`: -Set a dialer timeout for Marathon. (Default: ```5```) - -`TRAEFIK_PROVIDERS_MARATHON_ENDPOINT`: -Marathon server endpoint. You can also specify multiple endpoint for Marathon. (Default: ```http://127.0.0.1:8080```) - -`TRAEFIK_PROVIDERS_MARATHON_EXPOSEDBYDEFAULT`: -Expose Marathon apps by default. (Default: ```true```) - -`TRAEFIK_PROVIDERS_MARATHON_FORCETASKHOSTNAME`: -Force to use the task's hostname. (Default: ```false```) - -`TRAEFIK_PROVIDERS_MARATHON_KEEPALIVE`: -Set a TCP Keep Alive time. (Default: ```10```) - -`TRAEFIK_PROVIDERS_MARATHON_RESPECTREADINESSCHECKS`: -Filter out tasks with non-successful readiness checks during deployments. (Default: ```false```) - -`TRAEFIK_PROVIDERS_MARATHON_RESPONSEHEADERTIMEOUT`: -Set a response header timeout for Marathon. (Default: ```60```) - -`TRAEFIK_PROVIDERS_MARATHON_TLSHANDSHAKETIMEOUT`: -Set a TLS handshake timeout for Marathon. (Default: ```5```) - -`TRAEFIK_PROVIDERS_MARATHON_TLS_CA`: -TLS CA - -`TRAEFIK_PROVIDERS_MARATHON_TLS_CERT`: -TLS cert - -`TRAEFIK_PROVIDERS_MARATHON_TLS_INSECURESKIPVERIFY`: -TLS insecure skip verify (Default: ```false```) - -`TRAEFIK_PROVIDERS_MARATHON_TLS_KEY`: -TLS key - -`TRAEFIK_PROVIDERS_MARATHON_TRACE`: -Display additional provider logs. (Default: ```false```) - -`TRAEFIK_PROVIDERS_MARATHON_WATCH`: -Watch provider. (Default: ```true```) - `TRAEFIK_PROVIDERS_NOMAD`: Enable Nomad backend with default settings. (Default: ```false```) @@ -912,33 +816,6 @@ Plugins configuration. `TRAEFIK_PROVIDERS_PROVIDERSTHROTTLEDURATION`: Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```2```) -`TRAEFIK_PROVIDERS_RANCHER`: -Enable Rancher backend with default settings. (Default: ```false```) - -`TRAEFIK_PROVIDERS_RANCHER_CONSTRAINTS`: -Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container. - -`TRAEFIK_PROVIDERS_RANCHER_DEFAULTRULE`: -Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) - -`TRAEFIK_PROVIDERS_RANCHER_ENABLESERVICEHEALTHFILTER`: -Filter services with unhealthy states and inactive states. (Default: ```true```) - -`TRAEFIK_PROVIDERS_RANCHER_EXPOSEDBYDEFAULT`: -Expose containers by default. (Default: ```true```) - -`TRAEFIK_PROVIDERS_RANCHER_INTERVALPOLL`: -Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate). (Default: ```false```) - -`TRAEFIK_PROVIDERS_RANCHER_PREFIX`: -Prefix used for accessing the Rancher metadata service. (Default: ```latest```) - -`TRAEFIK_PROVIDERS_RANCHER_REFRESHSECONDS`: -Defines the polling interval in seconds. (Default: ```15```) - -`TRAEFIK_PROVIDERS_RANCHER_WATCH`: -Watch provider. (Default: ```true```) - `TRAEFIK_PROVIDERS_REDIS`: Enable Redis backend with default settings. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index cce2f600f..29ccadce7 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -98,28 +98,6 @@ watch = true filename = "foobar" debugLogGeneratedTemplate = true - [providers.marathon] - constraints = "foobar" - trace = true - watch = true - endpoint = "foobar" - defaultRule = "foobar" - exposedByDefault = true - dcosToken = "foobar" - dialerTimeout = "42s" - responseHeaderTimeout = "42s" - tlsHandshakeTimeout = "42s" - keepAlive = "42s" - forceTaskHostname = true - respectReadinessChecks = true - [providers.marathon.tls] - ca = "foobar" - cert = "foobar" - key = "foobar" - insecureSkipVerify = true - [providers.marathon.basic] - httpBasicAuthUser = "foobar" - httpBasicPassword = "foobar" [providers.kubernetesIngress] endpoint = "foobar" token = "foobar" @@ -154,15 +132,6 @@ throttleDuration = "42s" [providers.rest] insecure = true - [providers.rancher] - constraints = "foobar" - watch = true - defaultRule = "foobar" - exposedByDefault = true - enableServiceHealthFilter = true - refreshSeconds = 42 - intervalPoll = true - prefix = "foobar" [providers.consulCatalog] constraints = "foobar" prefix = "foobar" @@ -300,20 +269,6 @@ addRoutersLabels = true addServicesLabels = true prefix = "foobar" - [metrics.influxDB] - address = "foobar" - protocol = "foobar" - pushInterval = "42s" - database = "foobar" - retentionPolicy = "foobar" - username = "foobar" - password = "foobar" - addEntryPointsLabels = true - addRoutersLabels = true - addServicesLabels = true - [metrics.influxDB.additionalLabels] - name0 = "foobar" - name1 = "foobar" [metrics.influxDB2] address = "foobar" token = "foobar" diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml index ee7eb4ff3..10284c874 100644 --- a/docs/content/reference/static-configuration/file.yaml +++ b/docs/content/reference/static-configuration/file.yaml @@ -105,28 +105,6 @@ providers: watch: true filename: foobar debugLogGeneratedTemplate: true - marathon: - constraints: foobar - trace: true - watch: true - endpoint: foobar - defaultRule: foobar - exposedByDefault: true - dcosToken: foobar - tls: - ca: foobar - cert: foobar - key: foobar - insecureSkipVerify: true - dialerTimeout: 42s - responseHeaderTimeout: 42s - tlsHandshakeTimeout: 42s - keepAlive: 42s - forceTaskHostname: true - basic: - httpBasicAuthUser: foobar - httpBasicPassword: foobar - respectReadinessChecks: true kubernetesIngress: endpoint: foobar token: foobar @@ -167,15 +145,6 @@ providers: throttleDuration: 42s rest: insecure: true - rancher: - constraints: foobar - watch: true - defaultRule: foobar - exposedByDefault: true - enableServiceHealthFilter: true - refreshSeconds: 42 - intervalPoll: true - prefix: foobar consulCatalog: constraints: foobar prefix: foobar @@ -329,20 +298,6 @@ metrics: addRoutersLabels: true addServicesLabels: true prefix: foobar - influxDB: - address: foobar - protocol: foobar - pushInterval: 42s - database: foobar - retentionPolicy: foobar - username: foobar - password: foobar - addEntryPointsLabels: true - addRoutersLabels: true - addServicesLabels: true - additionalLabels: - name0: foobar - name1: foobar influxDB2: address: foobar token: foobar diff --git a/docs/content/routing/providers/marathon.md b/docs/content/routing/providers/marathon.md deleted file mode 100644 index ea13368ad..000000000 --- a/docs/content/routing/providers/marathon.md +++ /dev/null @@ -1,545 +0,0 @@ ---- -title: "Traefik Routing Configuration for Marathon" -description: "Traefik Proxy can be configured to use Marathon as a provider. Read the technical documentation to understand the Traefik routing configuration for Marathon." ---- - -# Traefik & Marathon - -Traefik can be configured to use Marathon as a provider. -{: .subtitle } - -See also [Marathon user guide](../../user-guides/marathon.md). - -## Routing Configuration - -!!! info "Labels" - - - Labels are case insensitive. - - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/marathon.md). - -### General - -Traefik creates, for each Marathon application, a corresponding [service](../services/index.md) and [router](../routers/index.md). - -The Service automatically gets a server per instance of the application, -and the router automatically gets a rule defined by defaultRule (if no rule for it was defined in labels). - -#### Service definition - ---8<-- "content/routing/providers/service-by-label.md" - -??? example "Automatic service assignment with labels" - - Service myservice gets automatically assigned to router myproxy. - - ```json - labels: { - "traefik.http.routers.myproxy.rule": "Host(`example.net`)", - "traefik.http.services.myservice.loadbalancer.server.port": "80" - } - ``` - -??? example "Automatic service creation and assignment with labels" - - No service specified or defined, and yet one gets automatically created. - and assigned to router myproxy. - - ```json - labels: { - "traefik.http.routers.myproxy.rule": "Host(`example.net`)" - } - ``` - -### Routers - -To update the configuration of the Router automatically attached to the application, -add labels starting with `traefik.http.routers.{router-name-of-your-choice}.` and followed by the option you want to change. - -For example, to change the routing rule, you could add the label ```"traefik.http.routers.routername.rule": "Host(`example.com`)"```. - -!!! warning "The character `@` is not authorized in the router name ``." - -??? info "`traefik.http.routers..rule`" - - See [rule](../routers/index.md#rule) for more information. - - ```json - "traefik.http.routers.myrouter.rule": "Host(`example.com`)" - ``` - -??? info "`traefik.http.routers..entrypoints`" - - See [entry points](../routers/index.md#entrypoints) for more information. - - ```json - "traefik.http.routers.myrouter.entrypoints": "ep1,ep2" - ``` - -??? info "`traefik.http.routers..middlewares`" - - See [middlewares](../routers/index.md#middlewares) and [middlewares overview](../../middlewares/overview.md) for more information. - - ```json - "traefik.http.routers.myrouter.middlewares": "auth,prefix,cb" - ``` - -??? info "`traefik.http.routers..service`" - - See [rule](../routers/index.md#service) for more information. - - ```json - "traefik.http.routers.myrouter.service": "myservice" - ``` - -??? info "`traefik.http.routers..tls`" - - See [tls](../routers/index.md#tls) for more information. - - ```json - "traefik.http.routers.myrouter.tls": "true" - ``` - -??? info "`traefik.http.routers..tls.certresolver`" - - See [certResolver](../routers/index.md#certresolver) for more information. - - ```json - "traefik.http.routers.myrouter.tls.certresolver": "myresolver" - ``` - -??? info "`traefik.http.routers..tls.domains[n].main`" - - See [domains](../routers/index.md#domains) for more information. - - ```json - "traefik.http.routers.myrouter.tls.domains[0].main": "example.org" - ``` - -??? info "`traefik.http.routers..tls.domains[n].sans`" - - See [domains](../routers/index.md#domains) for more information. - - ```json - "traefik.http.routers.myrouter.tls.domains[0].sans": "test.example.org,dev.example.org" - ``` - -??? info "`traefik.http.routers..tls.options`" - - See [options](../routers/index.md#options) for more information. - - ```json - "traefik.http.routers.myrouter.tls.options": "foobar" - ``` - -??? info "`traefik.http.routers..priority`" - - See [priority](../routers/index.md#priority) for more information. - - ```json - "traefik.http.routers.myrouter.priority": "42" - ``` - -### Services - -To update the configuration of the Service automatically attached to the container, -add labels starting with `traefik.http.services.{service-name-of-your-choice}.`, followed by the option you want to change. - -For example, to change the passHostHeader behavior, you'd add the label `"traefik.http.services.servicename.loadbalancer.passhostheader": "false"`. - -!!! warning "The character `@` is not authorized in the service name ``." - -??? info "`traefik.http.services..loadbalancer.server.port`" - - Registers a port. - Useful when the container exposes multiples ports. - - ```json - "traefik.http.services.myservice.loadbalancer.server.port": "8080" - ``` - -??? info "`traefik.http.services..loadbalancer.server.scheme`" - - Overrides the default scheme. - - ```json - "traefik.http.services.myservice.loadbalancer.server.scheme": "http" - ``` - -??? info "`traefik.http.services..loadbalancer.serverstransport`" - - Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. - See [serverstransport](../services/index.md#serverstransport) for more information. - - ```json - "traefik.http.services..loadbalancer.serverstransport": "foobar@file" - ``` - -??? info "`traefik.http.services..loadbalancer.passhostheader`" - - See [pass Host header](../services/index.md#pass-host-header) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.passhostheader": "true" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.headers.`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.headers.X-Foo": "foobar" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.hostname`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.hostname": "example.org" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.interval`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.interval": "10" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.path`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.path": "/foo" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.method`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.method": "foobar" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.status`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.status": "42" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.port`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.port": "42" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.scheme`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.scheme": "http" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.timeout`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.timeout": "10" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.followredirects`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.followredirects": "true" - ``` - -??? info "`traefik.http.services..loadbalancer.sticky.cookie`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.sticky.cookie": "true" - ``` - -??? info "`traefik.http.services..loadbalancer.sticky.cookie.httponly`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.sticky.cookie.httponly": "true" - ``` - -??? info "`traefik.http.services..loadbalancer.sticky.cookie.name`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.sticky.cookie.name": "foobar" - ``` - -??? info "`traefik.http.services..loadbalancer.sticky.cookie.secure`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure": "true" - ``` - -??? info "`traefik.http.services..loadbalancer.sticky.cookie.samesite`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite": "none" - ``` - -??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" - - See [response forwarding](../services/index.md#response-forwarding) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval": "10" - ``` - -### Middleware - -You can declare pieces of middleware using labels starting with `traefik.http.middlewares.{middleware-name-of-your-choice}.`, followed by the middleware type/options. - -For example, to declare a middleware [`redirectscheme`](../../middlewares/http/redirectscheme.md) named `my-redirect`, you'd write `"traefik.http.middlewares.my-redirect.redirectscheme.scheme": "https"`. - -More information about available middlewares in the dedicated [middlewares section](../../middlewares/overview.md). - -!!! warning "The character `@` is not authorized in the middleware name." - -??? example "Declaring and Referencing a Middleware" - - ```json - { - ... - "labels": { - "traefik.http.middlewares.my-redirect.redirectscheme.scheme": "https", - "traefik.http.routers.my-container.middlewares": "my-redirect" - } - } - ``` - -!!! warning "Conflicts in Declaration" - - If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared. - -### TCP - -You can declare TCP Routers and/or Services using labels. - -??? example "Declaring TCP Routers and Services" - - ```json - { - ... - "labels": { - "traefik.tcp.routers.my-router.rule": "HostSNI(`example.com`)", - "traefik.tcp.routers.my-router.tls": "true", - "traefik.tcp.services.my-service.loadbalancer.server.port": "4123" - } - } - ``` - -!!! warning "TCP and HTTP" - - If you declare a TCP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no TCP Router/Service is defined). - You can declare both a TCP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually). - -#### TCP Routers - -??? info "`traefik.tcp.routers..entrypoints`" - - See [entry points](../routers/index.md#entrypoints_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.entrypoints": "ep1,ep2" - ``` - - -??? info "`traefik.tcp.routers..rule`" - - See [rule](../routers/index.md#rule_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.rule": "HostSNI(`example.com`)" - ``` - -??? info "`traefik.tcp.routers..service`" - - See [service](../routers/index.md#services) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.service": "myservice" - ``` - -??? info "`traefik.tcp.routers..tls`" - - See [TLS](../routers/index.md#tls_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls": "true - ``` - -??? info "`traefik.tcp.routers..tls.certresolver`" - - See [certResolver](../routers/index.md#certresolver_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls.certresolver": "myresolver" - ``` - -??? info "`traefik.tcp.routers..tls.domains[n].main`" - - See [domains](../routers/index.md#domains_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls.domains[0].main": "example.org" - ``` - -??? info "`traefik.tcp.routers..tls.domains[n].sans`" - - See [domains](../routers/index.md#domains_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls.domains[0].sans": "test.example.org,dev.example.org" - ``` - -??? info "`traefik.tcp.routers..tls.options`" - - See [options](../routers/index.md#options_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls.options": "mysoptions" - ``` - -??? info "`traefik.tcp.routers..tls.passthrough`" - - See [TLS](../routers/index.md#tls_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls.passthrough": "true" - ``` - -??? info "`traefik.tcp.routers..priority`" - - See [priority](../routers/index.md#priority_1) for more information. - - ```json - "traefik.tcp.routers.myrouter.priority": "42" - ``` - -#### TCP Services - -??? info "`traefik.tcp.services..loadbalancer.server.port`" - - Registers a port of the application. - - ```json - "traefik.tcp.services.mytcpservice.loadbalancer.server.port": "423" - ``` - -??? info "`traefik.tcp.services..loadbalancer.server.tls`" - - Determines whether to use TLS when dialing with the backend. - - ```json - "traefik.tcp.services.mytcpservice.loadbalancer.server.tls": "true" - ``` - -??? info "`traefik.tcp.services..loadbalancer.proxyprotocol.version`" - - See [PROXY protocol](../services/index.md#proxy-protocol) for more information. - - ```json - "traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version": "1" - ``` - -??? info "`traefik.tcp.services..loadbalancer.serverstransport`" - - Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. - See [serverstransport](../services/index.md#serverstransport_2) for more information. - - ```json - "traefik.tcp.services..loadbalancer.serverstransport": "foobar@file" - ``` - -### UDP - -You can declare UDP Routers and/or Services using labels. - -??? example "Declaring UDP Routers and Services" - - ```json - { - ... - "labels": { - "traefik.udp.routers.my-router.entrypoints": "udp", - "traefik.udp.services.my-service.loadbalancer.server.port": "4123" - } - } - ``` - -!!! warning "UDP and HTTP" - - If you declare a UDP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no UDP Router/Service is defined). - You can declare both a UDP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually). - -#### UDP Routers - -??? info "`traefik.udp.routers..entrypoints`" - - See [entry points](../routers/index.md#entrypoints_2) for more information. - - ```json - "traefik.udp.routers.myudprouter.entrypoints": "ep1,ep2" - ``` - -??? info "`traefik.udp.routers..service`" - - See [service](../routers/index.md#services_1) for more information. - - ```json - "traefik.udp.routers.myudprouter.service": "myservice" - ``` - -#### UDP Services - -??? info "`traefik.udp.services..loadbalancer.server.port`" - - Registers a port of the application. - - ```json - "traefik.udp.services.myudpservice.loadbalancer.server.port": "423" - ``` - -### Specific Provider Options - -#### `traefik.enable` - -```json -"traefik.enable": "true" -``` - -Setting this option controls whether Traefik exposes the application. -It overrides the value of `exposedByDefault`. - -#### `traefik.marathon.ipadressidx` - -```json -"traefik.marathon.ipadressidx": "1" -``` - -If a task has several IP addresses, this option specifies which one, in the list of available addresses, to select. diff --git a/docs/content/routing/providers/rancher.md b/docs/content/routing/providers/rancher.md deleted file mode 100644 index 5e711ed5e..000000000 --- a/docs/content/routing/providers/rancher.md +++ /dev/null @@ -1,545 +0,0 @@ ---- -title: "Routing & Load Balancing Providers: Rancher" -description: "Traefik Proxy creates a corresponding service and router for each Rancher Service. Read the full documentation to learn more." ---- - -# Traefik & Rancher - -A Story of Labels, Services & Containers -{: .subtitle } - -![Rancher](../../assets/img/providers/rancher.png) - -Attach labels to your services and let Traefik do the rest! - -!!! important "This provider is specific to Rancher 1.x." - - Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query. - As such, Rancher 2.x users should utilize the [Kubernetes provider](./kubernetes-crd.md) directly. - -## Routing Configuration - -!!! info "Labels" - - - Labels are case insensitive. - - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/rancher.md). - -### General - -Traefik creates, for each rancher service, a corresponding [service](../services/index.md) and [router](../routers/index.md). - -The Service automatically gets a server per container in this rancher service, and the router gets a default rule attached to it, based on the service name. - -#### Service definition - ---8<-- "content/routing/providers/service-by-label.md" - -??? example "Automatic service assignment with labels" - - With labels in a compose file - - ```yaml - labels: - - "traefik.http.routers.myproxy.rule=Host(`example.net`)" - # service myservice gets automatically assigned to router myproxy - - "traefik.http.services.myservice.loadbalancer.server.port=80" - ``` - -??? example "Automatic service creation and assignment with labels" - - With labels in a compose file - - ```yaml - labels: - # no service specified or defined and yet one gets automatically created - # and assigned to router myproxy. - - "traefik.http.routers.myproxy.rule=Host(`example.net`)" - ``` - -### Routers - -To update the configuration of the Router automatically attached to the container, add labels starting with `traefik.routers.{name-of-your-choice}.` and followed by the option you want to change. - -For example, to change the rule, you could add the label ```traefik.http.routers.my-container.rule=Host(`example.com`)```. - -!!! warning "The character `@` is not authorized in the router name ``." - -??? info "`traefik.http.routers..rule`" - - See [rule](../routers/index.md#rule) for more information. - - ```yaml - - "traefik.http.routers.myrouter.rule=Host(`example.com`)" - ``` - -??? info "`traefik.http.routers..entrypoints`" - - See [entry points](../routers/index.md#entrypoints) for more information. - - ```yaml - - "traefik.http.routers.myrouter.entrypoints=ep1,ep2" - ``` - -??? info "`traefik.http.routers..middlewares`" - - See [middlewares](../routers/index.md#middlewares) and [middlewares overview](../../middlewares/overview.md) for more information. - - ```yaml - - "traefik.http.routers.myrouter.middlewares=auth,prefix,cb" - ``` - -??? info "`traefik.http.routers..service`" - - See [rule](../routers/index.md#service) for more information. - - ```yaml - - "traefik.http.routers.myrouter.service=myservice" - ``` - -??? info "`traefik.http.routers..tls`" - - See [tls](../routers/index.md#tls) for more information. - - ```yaml - - "traefik.http.routers.myrouter>.tls=true" - ``` - -??? info "`traefik.http.routers..tls.certresolver`" - - See [certResolver](../routers/index.md#certresolver) for more information. - - ```yaml - - "traefik.http.routers.myrouter.tls.certresolver=myresolver" - ``` - -??? info "`traefik.http.routers..tls.domains[n].main`" - - See [domains](../routers/index.md#domains) for more information. - - ```yaml - - "traefik.http.routers.myrouter.tls.domains[0].main=example.org" - ``` - -??? info "`traefik.http.routers..tls.domains[n].sans`" - - See [domains](../routers/index.md#domains) for more information. - - ```yaml - - "traefik.http.routers.myrouter.tls.domains[0].sans=test.example.org,dev.example.org" - ``` - -??? info "`traefik.http.routers..tls.options`" - - See [options](../routers/index.md#options) for more information. - - ```yaml - - "traefik.http.routers.myrouter.tls.options=foobar" - ``` - -??? info "`traefik.http.routers..priority`" - - See [priority](../routers/index.md#priority) for more information. - - ```yaml - - "traefik.http.routers.myrouter.priority=42" - ``` - -### Services - -To update the configuration of the Service automatically attached to the container, -add labels starting with `traefik.http.services.{name-of-your-choice}.`, followed by the option you want to change. - -For example, to change the `passHostHeader` behavior, -you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.passhostheader=false`. - -!!! warning "The character `@` is not authorized in the service name ``." - -??? info "`traefik.http.services..loadbalancer.server.port`" - - Registers a port. - Useful when the container exposes multiples ports. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.server.port=8080" - ``` - -??? info "`traefik.http.services..loadbalancer.server.scheme`" - - Overrides the default scheme. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.server.scheme=http" - ``` - -??? info "`traefik.http.services..loadbalancer.serverstransport`" - - Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. - See [serverstransport](../services/index.md#serverstransport) for more information. - - ```yaml - - "traefik.http.services..loadbalancer.serverstransport=foobar@file" - ``` - -??? info "`traefik.http.services..loadbalancer.passhostheader`" - - See [pass Host header](../services/index.md#pass-host-header) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.passhostheader=true" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.headers.`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.headers.X-Foo=foobar" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.hostname`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.hostname=example.org" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.interval`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.path`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.path=/foo" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.method`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.method=foobar" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.status`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.status=42" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.port`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.port=42" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.scheme`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.scheme=http" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.timeout`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.timeout=10" - ``` - -??? info "`traefik.http.services..loadbalancer.healthcheck.followredirects`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true" - ``` - -??? info "`traefik.http.services..loadbalancer.sticky.cookie`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky.cookie=true" - ``` - -??? info "`traefik.http.services..loadbalancer.sticky.cookie.httponly`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky.cookie.httponly=true" - ``` - -??? info "`traefik.http.services..loadbalancer.sticky.cookie.name`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar" - ``` - -??? info "`traefik.http.services..loadbalancer.sticky.cookie.secure`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true" - ``` - -??? info "`traefik.http.services..loadbalancer.sticky.cookie.samesite`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none" - ``` - -??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" - - See [response forwarding](../services/index.md#response-forwarding) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10" - ``` - -### Middleware - -You can declare pieces of middleware using labels starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options. - -For example, to declare a middleware [`redirectscheme`](../../middlewares/http/redirectscheme.md) named `my-redirect`, you'd write `traefik.http.middlewares.my-redirect.redirectscheme.scheme: https`. - -More information about available middlewares in the dedicated [middlewares section](../../middlewares/overview.md). - -!!! warning "The character `@` is not authorized in the middleware name." - -??? example "Declaring and Referencing a Middleware" - - ```yaml - # ... - labels: - # Declaring a middleware - - traefik.http.middlewares.my-redirect.redirectscheme.scheme=https - # Referencing a middleware - - traefik.http.routers.my-container.middlewares=my-redirect - ``` - -!!! warning "Conflicts in Declaration" - - If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared. - -### TCP - -You can declare TCP Routers and/or Services using labels. - -??? example "Declaring TCP Routers and Services" - - ```yaml - services: - my-container: - # ... - labels: - - "traefik.tcp.routers.my-router.rule=HostSNI(`example.com`)" - - "traefik.tcp.routers.my-router.tls=true" - - "traefik.tcp.services.my-service.loadbalancer.server.port=4123" - ``` - -!!! warning "TCP and HTTP" - - If you declare a TCP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no TCP Router/Service is defined). - You can declare both a TCP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually). - -#### TCP Routers - -??? info "`traefik.tcp.routers..entrypoints`" - - See [entry points](../routers/index.md#entrypoints_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.entrypoints=ep1,ep2" - ``` - -??? info "`traefik.tcp.routers..rule`" - - See [rule](../routers/index.md#rule_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.rule=HostSNI(`example.com`)" - ``` - -??? info "`traefik.tcp.routers..service`" - - See [service](../routers/index.md#services) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.service=myservice" - ``` - -??? info "`traefik.tcp.routers..tls`" - - See [TLS](../routers/index.md#tls_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls=true" - ``` - -??? info "`traefik.tcp.routers..tls.certresolver`" - - See [certResolver](../routers/index.md#certresolver_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls.certresolver=myresolver" - ``` - -??? info "`traefik.tcp.routers..tls.domains[n].main`" - - See [domains](../routers/index.md#domains_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls.domains[0].main=example.org" - ``` - -??? info "`traefik.tcp.routers..tls.domains[n].sans`" - - See [domains](../routers/index.md#domains_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls.domains[0].sans=test.example.org,dev.example.org" - ``` - -??? info "`traefik.tcp.routers..tls.options`" - - See [options](../routers/index.md#options_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls.options=mysoptions" - ``` - -??? info "`traefik.tcp.routers..tls.passthrough`" - - See [TLS](../routers/index.md#tls_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls.passthrough=true" - ``` - -??? info "`traefik.tcp.routers..priority`" - - See [priority](../routers/index.md#priority_1) for more information. - - ```yaml - - "traefik.tcp.routers.myrouter.priority=42" - ``` - -#### TCP Services - -??? info "`traefik.tcp.services..loadbalancer.server.port`" - - Registers a port of the application. - - ```yaml - - "traefik.tcp.services.mytcpservice.loadbalancer.server.port=423" - ``` - -??? info "`traefik.tcp.services..loadbalancer.server.tls`" - - Determines whether to use TLS when dialing with the backend. - - ```yaml - - "traefik.tcp.services.mytcpservice.loadbalancer.server.tls=true" - ``` - -??? info "`traefik.tcp.services..loadbalancer.proxyprotocol.version`" - - See [PROXY protocol](../services/index.md#proxy-protocol) for more information. - - ```yaml - - "traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version=1" - ``` - -??? info "`traefik.tcp.services..loadbalancer.serverstransport`" - - Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. - See [serverstransport](../services/index.md#serverstransport_2) for more information. - - ```yaml - - "traefik.tcp.services..loadbalancer.serverstransport=foobar@file" - ``` - -### UDP - -You can declare UDP Routers and/or Services using labels. - -??? example "Declaring UDP Routers and Services" - - ```yaml - services: - my-container: - # ... - labels: - - "traefik.udp.routers.my-router.entrypoints=udp" - - "traefik.udp.services.my-service.loadbalancer.server.port=4123" - ``` - -!!! warning "UDP and HTTP" - - If you declare a UDP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no UDP Router/Service is defined). - You can declare both a UDP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually). - -#### UDP Routers - -??? info "`traefik.udp.routers..entrypoints`" - - See [entry points](../routers/index.md#entrypoints_2) for more information. - - ```yaml - - "traefik.udp.routers.myudprouter.entrypoints=ep1,ep2" - ``` - -??? info "`traefik.udp.routers..service`" - - See [service](../routers/index.md#services_1) for more information. - - ```yaml - - "traefik.udp.routers.myudprouter.service=myservice" - ``` - -#### UDP Services - -??? info "`traefik.udp.services..loadbalancer.server.port`" - - Registers a port of the application. - - ```yaml - - "traefik.udp.services.myudpservice.loadbalancer.server.port=423" - ``` - -### Specific Provider Options - -#### `traefik.enable` - -```yaml -- "traefik.enable=true" -``` - -You can tell Traefik to consider (or not) the container by setting `traefik.enable` to true or false. - -This option overrides the value of `exposedByDefault`. - -#### Port Lookup - -Traefik is capable of detecting the port to use, by following the default rancher flow. -That means, if you just expose lets say port `:1337` on the rancher ui, traefik will pick up this port and use it. diff --git a/docs/content/routing/routers/index.md b/docs/content/routing/routers/index.md index 51328317b..12bc83f60 100644 --- a/docs/content/routing/routers/index.md +++ b/docs/content/routing/routers/index.md @@ -557,8 +557,7 @@ which is basically where the request will be passed along to. In general, a service assigned to a router should have been defined, but there are exceptions for label-based providers. -See the specific [docker](../providers/docker.md#service-definition), [rancher](../providers/rancher.md#service-definition), -or [marathon](../providers/marathon.md#service-definition) documentation. +See the specific [docker](../providers/docker.md#service-definition) documentation. !!! warning "The character `@` is not authorized in the service name." diff --git a/docs/content/user-guides/marathon.md b/docs/content/user-guides/marathon.md deleted file mode 100644 index 2b374ca24..000000000 --- a/docs/content/user-guides/marathon.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: "Traefik Proxy and Marathon Integration Guide |Traefik Docs" -description: "This guide explains how to integrate Marathon and operate the cluster in a reliable way from the Traefik Proxy standpoint." ---- - -# Marathon - -This guide explains how to integrate Marathon and operate the cluster in a reliable way from Traefik's standpoint. - -## Host detection - -Marathon offers multiple ways to run (Docker-containerized) applications, the most popular ones being - -- BRIDGE-networked containers with dynamic high ports exposed -- HOST-networked containers with host machine ports -- containers with dedicated IP addresses ([IP-per-task](https://mesosphere.github.io/marathon/docs/ip-per-task.html)). - -Traefik tries to detect the configured mode and route traffic to the right IP addresses. It is possible to force using task hosts with the `forceTaskHostname` option. - -## Port detection - -Traefik also attempts to determine the right port (which is a [non-trivial matter in Marathon](https://mesosphere.github.io/marathon/docs/ports.html)) from the following sources: - -1. An arbitrary port specified through label `traefik.http.services.serviceName.loadbalancer.server.port=8080` -1. The task port. -1. The port from the application's `portDefinitions` field. -1. The port from the application's `ipAddressPerTask` field. - -### Port label syntax - -To select a port, you can either - -- specify the port directly: `traefik.http.services.serviceName.loadbalancer.server.port=8080` -- specify a port index: `traefik.http.services.serviceName.loadbalancer.server.port=index:0` -- specify a port name: `traefik.http.services.serviceName.loadbalancer.server.port=name:http` -- otherwise the first one is selected. - -## Achieving high availability - -### Scenarios - -There are three scenarios where the availability of a Marathon application could be impaired along with the risk of losing or failing requests: - -- During the startup phase when Traefik already routes requests to the backend even though it has not completed its bootstrapping process yet. -- During the shutdown phase when Traefik still routes requests to the backend while the backend is already terminating. -- During a failure of the application when Traefik has not yet identified the backend as being erroneous. - -The first two scenarios are common with every rolling upgrade of an application (i.e. a new version release or configuration update). - -The following sub-sections describe how to resolve or mitigate each scenario. - -#### Startup - -It is possible to define [readiness checks](https://mesosphere.github.io/marathon/docs/readiness-checks.html) (available since Marathon version 1.1) per application and have Marathon take these into account during the startup phase. - -The idea is that each application provides an HTTP endpoint that Marathon queries periodically during an ongoing deployment in order to mark the associated readiness check result as successful if and only if the endpoint returns a response within the configured HTTP code range. -As long as the check keeps failing, Marathon will not proceed with the deployment (within the configured upgrade strategy bounds). - -Beginning with version 1.4, Traefik respects readiness check results if the Traefik option is set and checks are configured on the applications accordingly. - -!!! note - Due to the way readiness check results are currently exposed by the Marathon API, ready tasks may be taken into rotation with a small delay. - It is on the order of one readiness check timeout interval (as configured on the application specification) and guarantees that non-ready tasks do not receive traffic prematurely. - -If readiness checks are not possible, a current mitigation strategy is to enable [retries](../middlewares/http/retry.md) and make sure that a sufficient number of healthy application tasks exist so that one retry will likely hit one of those. -Apart from its probabilistic nature, the workaround comes at the price of increased latency. - -#### Shutdown - -It is possible to install a [termination handler](https://mesosphere.github.io/marathon/docs/health-checks.html) (available since Marathon version 1.3) with each application whose responsibility it is to delay the shutdown process long enough until the backend has been taken out of load-balancing rotation with reasonable confidence (i.e., Traefik has received an update from the Marathon event bus, recomputes the available Marathon backends, and applies the new configuration). -Specifically, each termination handler should install a signal handler listening for a SIGTERM signal and implement the following steps on signal reception: - -1. Disable Keep-Alive HTTP connections. -1. Keep accepting HTTP requests for a certain period of time. -1. Stop accepting new connections. -1. Finish serving any in-flight requests. -1. Shut down. - -Traefik already ignores Marathon tasks whose state does not match `TASK_RUNNING`; since terminating tasks transition into the `TASK_KILLING` and eventually `TASK_KILLED` state, there is nothing further that needs to be done on Traefik's end. - -How long HTTP requests should continue to be accepted in step 2 depends on how long Traefik needs to receive and process the Marathon configuration update. -Under regular operational conditions, it should be on the order of seconds, with 10 seconds possibly being a good default value. - -Again, configuring Traefik to do retries (as discussed in the previous section) can serve as a decent workaround strategy. -Paired with termination handlers, they would cover for those cases where either the termination sequence or Traefik cannot complete their part of the orchestration process in time. - -#### Failure - -A failing application always happens unexpectedly, and hence, it is very difficult or even impossible to rule out the adversal effects categorically. - -Failure reasons vary broadly and could stretch from unacceptable slowness, a task crash, or a network split. - -There are two mitigation efforts: - -1. Configure [Marathon health checks](https://mesosphere.github.io/marathon/docs/health-checks.html) on each application. -2. Configure Traefik health checks (possibly via the `traefik.http.services.yourServiceName.loadbalancer.healthcheck.*` labels) and make sure they probe with proper frequency. - -The Marathon health check makes sure that applications once deemed dysfunctional are being rescheduled to different slaves. -However, they might take a while to get triggered and the follow-up processes to complete. - -For that reason, the Traefik health check provides an additional check that responds more rapidly and does not require a configuration reload to happen. -Additionally, it protects from cases that the Marathon health check may not be able to cover, such as a network split. - -### (Non-)Alternatives - -There are a few alternatives of varying quality that are frequently asked for. - -The remaining section is going to explore them along with a benefit/cost trade-off. - -#### Reusing Marathon health checks - -It may seem obvious to reuse the Marathon health checks as a signal to Traefik whether an application should be taken into load-balancing rotation or not. - -Apart from the increased latency a failing health check may have, a major problem with this is that Marathon does not persist the health check results. -Consequently, if a master re-election occurs in the Marathon clusters, all health check results will revert to the _unknown_ state, effectively causing all applications inside the cluster to become unavailable and leading to a complete cluster failure. -Re-elections do not only happen during regular maintenance work (often requiring rolling upgrades of the Marathon nodes) but also when the Marathon leader fails spontaneously. -As such, there is no way to handle this situation deterministically. - -Finally, Marathon health checks are not mandatory (the default is to use the task state as reported by Mesos), so requiring them for Traefik would raise the entry barrier for Marathon users. - -Traefik used to use the health check results as a strict requirement but moved away from it as [users reported the dramatic consequences](https://github.com/traefik/traefik/issues/653). - -#### Draining - -Another common approach is to let a proxy drain backends that are supposed to shut down. -That is, once a backend is supposed to shut down, Traefik would stop forwarding requests. - -On the plus side, this would not require any modifications to the application in question. -However, implementing this fully within Traefik seems like a non-trivial undertaking. - -Additionally, the approach is less flexible compared to a custom termination handler since only the latter allows for the implementation of custom termination sequences that go beyond simple request draining (e.g., persisting a snapshot state to disk prior to terminating). - -The feature is currently not implemented; a request for draining in general is at [issue 41](https://github.com/traefik/traefik/issues/41). diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 91b163347..179be7ae5 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -81,8 +81,6 @@ nav: - 'Consul Catalog': 'providers/consul-catalog.md' - 'Nomad': 'providers/nomad.md' - 'ECS': 'providers/ecs.md' - - 'Marathon': 'providers/marathon.md' - - 'Rancher': 'providers/rancher.md' - 'File': 'providers/file.md' - 'Consul': 'providers/consul.md' - 'Etcd': 'providers/etcd.md' @@ -102,8 +100,6 @@ nav: - 'Consul Catalog': 'routing/providers/consul-catalog.md' - 'Nomad': 'routing/providers/nomad.md' - 'ECS': 'routing/providers/ecs.md' - - 'Marathon': 'routing/providers/marathon.md' - - 'Rancher': 'routing/providers/rancher.md' - 'KV': 'routing/providers/kv.md' - 'HTTPS & TLS': - 'Overview': 'https/overview.md' @@ -155,7 +151,6 @@ nav: - 'Metrics': - 'Overview': 'observability/metrics/overview.md' - 'Datadog': 'observability/metrics/datadog.md' - - 'InfluxDB': 'observability/metrics/influxdb.md' - 'InfluxDB2': 'observability/metrics/influxdb2.md' - 'OpenTelemetry': 'observability/metrics/opentelemetry.md' - 'Prometheus': 'observability/metrics/prometheus.md' @@ -172,7 +167,6 @@ nav: - 'User Guides': - 'Kubernetes and Let''s Encrypt': 'user-guides/crd-acme/index.md' - 'gRPC Examples': 'user-guides/grpc.md' - - 'Marathon': 'user-guides/marathon.md' - 'Docker': - 'Basic Example': 'user-guides/docker-compose/basic-example/index.md' - 'HTTPS with Let''s Encrypt': @@ -208,8 +202,6 @@ nav: - 'Nomad': "reference/dynamic-configuration/nomad.md" - 'ECS': 'reference/dynamic-configuration/ecs.md' - 'KV': 'reference/dynamic-configuration/kv.md' - - 'Marathon': 'reference/dynamic-configuration/marathon.md' - - 'Rancher': 'reference/dynamic-configuration/rancher.md' - 'Deprecation Notices': - 'Releases': 'deprecation/releases.md' - 'Features': 'deprecation/features.md' diff --git a/go.mod b/go.mod index 47c37943d..bca864e5b 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000 github.com/andybalholm/brotli v1.0.4 github.com/aws/aws-sdk-go v1.44.47 - github.com/cenkalti/backoff/v4 v4.1.3 + github.com/cenkalti/backoff/v4 v4.2.0 github.com/compose-spec/compose-go v1.0.3 github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf @@ -19,7 +19,6 @@ require ( github.com/docker/docker v20.10.7+incompatible github.com/docker/go-connections v0.4.0 github.com/fatih/structs v1.1.0 - github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 github.com/go-acme/lego/v4 v4.9.1 github.com/go-check/check v0.0.0-00010101000000-000000000000 github.com/go-kit/kit v0.10.1-0.20200915143503-439c4d2ed3ea @@ -59,7 +58,6 @@ require ( github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_golang v1.12.2-0.20220704083116-e8f91604d835 github.com/prometheus/client_model v0.2.0 - github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac github.com/rs/zerolog v1.28.0 github.com/sirupsen/logrus v1.9.0 github.com/spiffe/go-spiffe/v2 v2.1.1 @@ -78,24 +76,24 @@ require ( go.elastic.co/apm v1.13.1 go.elastic.co/apm/module/apmot v1.13.1 go.opentelemetry.io/collector/pdata v0.64.1 - go.opentelemetry.io/otel v1.11.1 - go.opentelemetry.io/otel/bridge/opentracing v1.11.1 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.33.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.33.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.1 - go.opentelemetry.io/otel/metric v0.33.0 - go.opentelemetry.io/otel/sdk v1.11.1 - go.opentelemetry.io/otel/sdk/metric v0.33.0 - go.opentelemetry.io/otel/trace v1.11.1 + go.opentelemetry.io/otel v1.11.2 + go.opentelemetry.io/otel/bridge/opentracing v1.11.2 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.2 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.2 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.2 + go.opentelemetry.io/otel/metric v0.34.0 + go.opentelemetry.io/otel/sdk v1.11.2 + go.opentelemetry.io/otel/sdk/metric v0.34.0 + go.opentelemetry.io/otel/trace v1.11.2 golang.org/x/exp v0.0.0-20221114191408-850992195362 golang.org/x/mod v0.6.0 - golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 + golang.org/x/net v0.4.0 golang.org/x/text v0.5.0 golang.org/x/time v0.0.0-20220609170525-579cf78fd858 golang.org/x/tools v0.2.0 - google.golang.org/grpc v1.50.1 + google.golang.org/grpc v1.51.0 gopkg.in/DataDog/dd-trace-go.v1 v1.43.1 gopkg.in/fsnotify.v1 v1.4.7 gopkg.in/yaml.v3 v3.0.1 @@ -109,7 +107,7 @@ require ( ) require ( - cloud.google.com/go v0.97.0 // indirect + cloud.google.com/go/compute/metadata v0.2.0 // indirect github.com/AlecAivazis/survey/v2 v2.2.3 // indirect github.com/Azure/azure-sdk-for-go v40.3.0+incompatible // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect @@ -174,7 +172,6 @@ require ( github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.4.0 // indirect - github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/elastic/go-licenser v0.3.1 // indirect github.com/elastic/go-sysinfo v1.1.1 // indirect @@ -211,12 +208,13 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/gax-go/v2 v2.1.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.6.0 // indirect github.com/gophercloud/gophercloud v1.0.0 // indirect github.com/gophercloud/utils v0.0.0-20210216074907-f6de111f2eae // indirect github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0 // indirect github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect github.com/hashicorp/consul/sdk v0.10.0 // indirect github.com/hashicorp/cronexpr v1.1.1 // indirect @@ -347,8 +345,8 @@ require ( go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect go.etcd.io/etcd/client/v3 v3.5.4 // indirect go.opencensus.io v0.23.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.33.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.34.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect @@ -358,14 +356,14 @@ require ( go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect golang.org/x/crypto v0.1.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect - golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect + golang.org/x/oauth2 v0.2.0 // indirect + golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 // indirect golang.org/x/sys v0.3.0 // indirect golang.org/x/term v0.3.0 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - google.golang.org/api v0.57.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.100.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect + google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect diff --git a/go.sum b/go.sum index 629581f80..8d94db2f0 100644 --- a/go.sum +++ b/go.sum @@ -25,23 +25,19 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute/metadata v0.2.0 h1:nBbNSZyDpkNlo3DepaaLKVuO7ClyifSAmNloSCZrHnQ= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -294,8 +290,8 @@ github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= +github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -593,8 +589,6 @@ github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNE github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e h1:rMOGp6HPeMHbdLrZkX2nD+94uqDunc27tXVuS+ey4mQ= -github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -669,8 +663,6 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 h1:df6OFl8WNXk82xxP3R9ZPZ5seOA8XZkwLdbEzZF1/xI= -github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.87.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= @@ -851,7 +843,6 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= @@ -897,7 +888,6 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -911,8 +901,6 @@ github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -923,12 +911,14 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0 h1:6DWmvNpomjL1+3liNSZbVns3zsYzzCjm6pRBO1tLeso= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -968,8 +958,9 @@ github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpg github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0 h1:t7uX3JBHdVwAi3G7sSSdbsk8NfgA+LnUS88V/2EKaA0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0/go.mod h1:4OGVnY4qf2+gw+ssiHbW+pq4mo2yko94YxxMmXZ7jCA= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= @@ -1668,8 +1659,6 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/qri-io/jsonpointer v0.1.0/go.mod h1:DnJPaYgiKu56EuDp8TU5wFLdZIcAnb/uH9v37ZaMV64= github.com/qri-io/jsonschema v0.1.1/go.mod h1:QpzJ6gBQ0GYgGmh7mDQ1YsvvhSgE4rYj0k8t5MBOmUY= -github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac h1:wBGhHdXKICZmvAPWS8gQoMyOWDH7QAi9bU4Z1nDWnFU= -github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac/go.mod h1:67sLWL17mVlO1HFROaTBmU71NB4R8UNCesFHhg0f6LQ= github.com/rboyer/safeio v0.2.1/go.mod h1:Cq/cEPK+YXFn622lsQ0K4KsPZSPtaptHHEldsy7Fmig= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1998,32 +1987,32 @@ go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/collector/pdata v0.64.1 h1:8E06uHr0nnenGftFwhwdenA88QhVnF4dJam+qVXgdVg= go.opentelemetry.io/collector/pdata v0.64.1/go.mod h1:IzvXUGQml2mrnvdb8zIlEW3qQs9oFLdD2hLwJdZ+pek= -go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= -go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= -go.opentelemetry.io/otel/bridge/opentracing v1.11.1 h1:/ZBsgjXWUpiZ5M9zm+Ft3kuDUGErIGcEJbKRIsFN6jA= -go.opentelemetry.io/otel/bridge/opentracing v1.11.1/go.mod h1:vw9hN4H+G0ek+XQtxP+Mm1McLcmdx2FXHNrWn2bBqxU= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 h1:X2GndnMCsUPh6CiY2a+frAbNsXaPLbB0soHRYhAZ5Ig= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1/go.mod h1:i8vjiSzbiUC7wOQplijSXMYUpNM93DtlS5CbUT+C6oQ= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.33.0 h1:OT/UjHcjog4A1s1UMCtyehIKS+vpjM5Du0r7KGsH6TE= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.33.0/go.mod h1:0XctNDHEWmiSDIU8NPbJElrK05gBJFcYlGP4FMGo4g4= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.33.0 h1:1SVtGtRsNyGgv1fRfNXfh+sJowIwzF0gkf+61lvTgdg= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.33.0/go.mod h1:ryB27ubOBXsiqfh6MwtSdx5knzbSZtjvPnMMmt3AykQ= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.33.0 h1:NoG4v01cdLZfOeNGBQmSe4f4SeP+fx8I/0qzRgTKsGI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.33.0/go.mod h1:6anbDXBcTp3Qit87pfFmT0paxTJ8sWRccTNYVywN/H8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1 h1:MEQNafcNCB0uQIti/oHgU7CZpUMYQ7qigBwMVKycHvc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1/go.mod h1:19O5I2U5iys38SsmT2uDJja/300woyzE1KPIQxEUBUc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1 h1:LYyG/f1W/jzAix16jbksJfMQFpOH/Ma6T639pVPMgfI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1/go.mod h1:QrRRQiY3kzAoYPNLP0W/Ikg0gR6V3LMc+ODSxr7yyvg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.1 h1:tFl63cpAAcD9TOU6U8kZU7KyXuSRYAZlbx1C61aaB74= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.1/go.mod h1:X620Jww3RajCJXw/unA+8IRTgxkdS7pi+ZwK9b7KUJk= -go.opentelemetry.io/otel/metric v0.33.0 h1:xQAyl7uGEYvrLAiV/09iTJlp1pZnQ9Wl793qbVvED1E= -go.opentelemetry.io/otel/metric v0.33.0/go.mod h1:QlTYc+EnYNq/M2mNk1qDDMRLpqCOj2f/r5c7Fd5FYaI= -go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZpKxs= -go.opentelemetry.io/otel/sdk v1.11.1/go.mod h1:/l3FE4SupHJ12TduVjUkZtlfFqDCQJlOlithYrdktys= -go.opentelemetry.io/otel/sdk/metric v0.33.0 h1:oTqyWfksgKoJmbrs2q7O7ahkJzt+Ipekihf8vhpa9qo= -go.opentelemetry.io/otel/sdk/metric v0.33.0/go.mod h1:xdypMeA21JBOvjjzDUtD0kzIcHO/SPez+a8HOzJPGp0= -go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= -go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= +go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0= +go.opentelemetry.io/otel v1.11.2/go.mod h1:7p4EUV+AqgdlNV9gL97IgUZiVR3yrFXYo53f9BM3tRI= +go.opentelemetry.io/otel/bridge/opentracing v1.11.2 h1:Wx51zQDSZDNo5wxMPhkPwzgpUZLQYYDtT41LCcl7opg= +go.opentelemetry.io/otel/bridge/opentracing v1.11.2/go.mod h1:kBrIQ2vqDIqtuS7Np7ALjmm8Tml7yxgsAGQwBhNvuU0= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2 h1:htgM8vZIF8oPSCxa341e3IZ4yr/sKxgu8KZYllByiVY= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2/go.mod h1:rqbht/LlhVBgn5+k3M5QK96K5Xb0DvXpMJ5SFQpY6uw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.34.0 h1:kpskzLZ60cJ48SJ4uxWa6waBL+4kSV6nVK8rP+QM8Wg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.34.0/go.mod h1:4+x3i62TEegDHuzNva0bMcAN8oUi5w4liGb1d/VgPYo= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.34.0 h1:e7kFb4pJLbhJgAwUdoVTHzB9pGujs5O8/7gFyZL88fg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.34.0/go.mod h1:3x00m9exjIbhK+zTO4MsCSlfbVmgvLP0wjDgDKa/8bw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.34.0 h1:t4Ajxj8JGjxkqoBtbkCOY2cDUl9RwiNE9LPQavooi9U= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.34.0/go.mod h1:WO7omosl4P7JoanH9NgInxDxEn2F2M5YinIh8EyeT8w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.2 h1:fqR1kli93643au1RKo0Uma3d2aPQKT+WBKfTSBaKbOc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.2/go.mod h1:5Qn6qvgkMsLDX+sYK64rHb1FPhpn0UtxF+ouX1uhyJE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.2 h1:ERwKPn9Aer7Gxsc0+ZlutlH1bEEAUXAUhqm3Y45ABbk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.2/go.mod h1:jWZUM2MWhWCJ9J9xVbRx7tzK1mXKpAlze4CeulycwVY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.2 h1:Us8tbCmuN16zAnK5TC69AtODLycKbwnskQzaB6DfFhc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.2/go.mod h1:GZWSQQky8AgdJj50r1KJm8oiQiIPaAX7uZCFQX9GzC8= +go.opentelemetry.io/otel/metric v0.34.0 h1:MCPoQxcg/26EuuJwpYN1mZTeCYAUGx8ABxfW07YkjP8= +go.opentelemetry.io/otel/metric v0.34.0/go.mod h1:ZFuI4yQGNCupurTXCwkeD/zHBt+C2bR7bw5JqUm/AP8= +go.opentelemetry.io/otel/sdk v1.11.2 h1:GF4JoaEx7iihdMFu30sOyRx52HDHOkl9xQ8SMqNXUiU= +go.opentelemetry.io/otel/sdk v1.11.2/go.mod h1:wZ1WxImwpq+lVRo4vsmSOxdd+xwoUJ6rqyLc3SyX9aU= +go.opentelemetry.io/otel/sdk/metric v0.34.0 h1:7ElxfQpXCFZlRTvVRTkcUvK8Gt5DC8QzmzsLsO2gdzo= +go.opentelemetry.io/otel/sdk/metric v0.34.0/go.mod h1:l4r16BIqiqPy5rd14kkxllPy/fOI4tWo1jkpD9Z3ffQ= +go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0= +go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -2213,7 +2202,6 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -2224,8 +2212,8 @@ golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 h1:Frnccbp+ok2GkUS2tC84yAq/U9Vg+0sIO7aRL3T4Xnc= -golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -2242,13 +2230,10 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= +golang.org/x/oauth2 v0.2.0/go.mod h1:Cwn6afJ8jrQwYMxQDTpISoXmXW9I6qF6vDeuuoX3Ibs= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2261,8 +2246,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 h1:cu5kTvlzcw1Q5S9f5ip1/cpiB4nXvw1XYzFPGgzLUOY= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2376,16 +2361,12 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2499,8 +2480,6 @@ golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= @@ -2508,8 +2487,9 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= @@ -2544,14 +2524,8 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0 h1:4t9zuDlHLcIx0ZEhmXEeFVCRsiOgpgn2QOH9N0MNjPI= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.100.0 h1:LGUYIrbW9pzYQQ8NWXlaIVkgnfubVBZbMFb9P8TK374= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2618,25 +2592,11 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 h1:jmIfw8+gSvXcZSgaFAGyInDXeWzUhvYH57G/5GKMn70= +google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= @@ -2667,18 +2627,13 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc/examples v0.0.0-20201130180447-c456688b1860/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/integration/fixtures/marathon/simple.toml b/integration/fixtures/marathon/simple.toml deleted file mode 100644 index d43cdbc2e..000000000 --- a/integration/fixtures/marathon/simple.toml +++ /dev/null @@ -1,22 +0,0 @@ -[global] - checkNewVersion = false - sendAnonymousUsage = false - -[log] - level = "DEBUG" - noColor = true - -[entryPoints] - [entryPoints.web] - address = ":8000" - [entryPoints.traefik] - address = ":9090" - -[api] - insecure = true - -[providers] - [providers.marathon] - endpoint = "{{.MarathonURL}}" - watch = true - exposedByDefault = true diff --git a/integration/integration_test.go b/integration/integration_test.go index d71409d38..8e7f19e25 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -91,8 +91,6 @@ func Test(t *testing.T) { } check.Suite(&KeepAliveSuite{}) check.Suite(&LogRotationSuite{}) - check.Suite(&MarathonSuite{}) - check.Suite(&MarathonSuite15{}) if !useVPN { check.Suite(&ProxyProtocolSuite{}) } diff --git a/integration/marathon15_test.go b/integration/marathon15_test.go deleted file mode 100644 index 493db256a..000000000 --- a/integration/marathon15_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package integration - -import ( - "net/http" - "os" - "time" - - "github.com/gambol99/go-marathon" - "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" - checker "github.com/vdemeester/shakers" -) - -// Marathon test suites. -type MarathonSuite15 struct { - BaseSuite - marathonURL string -} - -func (s *MarathonSuite15) SetUpSuite(c *check.C) { - s.createComposeProject(c, "marathon15") - s.composeUp(c) - - s.marathonURL = "http://" + s.getComposeServiceIP(c, containerNameMarathon) + ":8080" - - // Wait for Marathon readiness prior to creating the client so that we - // don't run into the "all cluster members down" state right from the - // start. - err := try.GetRequest(s.marathonURL+"/v2/leader", 1*time.Minute, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) -} - -func (s *MarathonSuite15) TestConfigurationUpdate(c *check.C) { - // Start Traefik. - file := s.adaptFile(c, "fixtures/marathon/simple.toml", struct { - MarathonURL string - }{s.marathonURL}) - defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file)) - defer display(c) - err := cmd.Start() - c.Assert(err, checker.IsNil) - defer s.killCmd(cmd) - - // Wait for Traefik to turn ready. - err = try.GetRequest("http://127.0.0.1:8000/", 2*time.Second, try.StatusCodeIs(http.StatusNotFound)) - c.Assert(err, checker.IsNil) - - // Prepare Marathon client. - config := marathon.NewDefaultConfig() - config.URL = s.marathonURL - client, err := marathon.NewClient(config) - c.Assert(err, checker.IsNil) - - // Create test application to be deployed. - app := marathon.NewDockerApplication(). - Name("/whoami"). - CPU(0.1). - Memory(32). - EmptyNetworks(). - AddLabel("traefik.http.Routers.rt.Rule", "PathPrefix(`/service`)") - app.Container. - Expose(80). - Docker. - Container("traefik/whoami") - *app.Networks = append(*app.Networks, *marathon.NewBridgePodNetwork()) - - // Deploy the test application. - deployApplication(c, client, app) - - // Query application via Traefik. - err = try.GetRequest("http://127.0.0.1:8000/service", 30*time.Second, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) - - // Create test application with services to be deployed. - app = marathon.NewDockerApplication(). - Name("/whoami"). - CPU(0.1). - Memory(32). - EmptyNetworks(). - AddLabel("traefik.http.Routers.app.Rule", "PathPrefix(`/app`)") - app.Container. - Expose(80). - Docker. - Container("traefik/whoami") - *app.Networks = append(*app.Networks, *marathon.NewBridgePodNetwork()) - - // Deploy the test application. - deployApplication(c, client, app) - - // Query application via Traefik. - err = try.GetRequest("http://127.0.0.1:8000/app", 30*time.Second, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) -} diff --git a/integration/marathon_test.go b/integration/marathon_test.go deleted file mode 100644 index 5552e0d0b..000000000 --- a/integration/marathon_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package integration - -import ( - "net/http" - "os" - "time" - - "github.com/gambol99/go-marathon" - "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" - checker "github.com/vdemeester/shakers" -) - -const containerNameMarathon = "marathon" - -// Marathon test suites. -type MarathonSuite struct { - BaseSuite - marathonURL string -} - -func (s *MarathonSuite) SetUpSuite(c *check.C) { - s.createComposeProject(c, "marathon") - s.composeUp(c) - - s.marathonURL = "http://" + s.getComposeServiceIP(c, containerNameMarathon) + ":8080" - - // Wait for Marathon readiness prior to creating the client so that we - // don't run into the "all cluster members down" state right from the - // start. - err := try.GetRequest(s.marathonURL+"/v2/leader", 1*time.Minute, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) -} - -func deployApplication(c *check.C, client marathon.Marathon, application *marathon.Application) { - deploy, err := client.UpdateApplication(application, false) - c.Assert(err, checker.IsNil) - // Wait for deployment to complete. - c.Assert(client.WaitOnDeployment(deploy.DeploymentID, 1*time.Minute), checker.IsNil) -} - -func (s *MarathonSuite) TestConfigurationUpdate(c *check.C) { - // Start Traefik. - file := s.adaptFile(c, "fixtures/marathon/simple.toml", struct { - MarathonURL string - }{s.marathonURL}) - defer os.Remove(file) - - cmd, display := s.traefikCmd(withConfigFile(file)) - defer display(c) - err := cmd.Start() - c.Assert(err, checker.IsNil) - defer s.killCmd(cmd) - - // Wait for Traefik to turn ready. - err = try.GetRequest("http://127.0.0.1:8000/", 2*time.Second, try.StatusCodeIs(http.StatusNotFound)) - c.Assert(err, checker.IsNil) - - // Prepare Marathon client. - config := marathon.NewDefaultConfig() - config.URL = s.marathonURL - client, err := marathon.NewClient(config) - c.Assert(err, checker.IsNil) - - // Create test application to be deployed. - app := marathon.NewDockerApplication(). - Name("/whoami"). - CPU(0.1). - Memory(32). - AddLabel("traefik.http.Routers.rt.Rule", "PathPrefix(`/service`)") - app.Container.Docker.Bridged(). - Expose(80). - Container("traefik/whoami") - - // Deploy the test application. - deployApplication(c, client, app) - - // Query application via Traefik. - err = try.GetRequest("http://127.0.0.1:8000/service", 30*time.Second, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) - - // Create test application with services to be deployed. - app = marathon.NewDockerApplication(). - Name("/whoami"). - CPU(0.1). - Memory(32). - AddLabel("traefik.http.Routers.app.Rule", "PathPrefix(`/app`)") - app.Container.Docker.Bridged(). - Expose(80). - Container("traefik/whoami") - - // Deploy the test application. - deployApplication(c, client, app) - - // Query application via Traefik. - err = try.GetRequest("http://127.0.0.1:8000/app", 30*time.Second, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) -} diff --git a/integration/resources/compose/marathon.yml b/integration/resources/compose/marathon.yml deleted file mode 100644 index 5a2be1e67..000000000 --- a/integration/resources/compose/marathon.yml +++ /dev/null @@ -1,60 +0,0 @@ -version: "3.8" -services: - zookeeper: - image: zookeeper:3.4.10 - - mesos-master: - image: mesosphere/mesos-master:1.0.1-2.0.93.ubuntu1404 - # Uncomment published ports for interactive debugging. - # ports: - # - "5050:5050" - environment: - MESOS_HOSTNAME: mesos-master - MESOS_CLUSTER: local - MESOS_REGISTRY: in_memory - MESOS_LOG_DIR: /var/log - MESOS_WORK_DIR: /var/lib/mesos - MESOS_ZK: zk://zookeeper:2181/mesos - - mesos-slave: - image: docker:dind - privileged: true - # Uncomment published ports for interactive debugging. - # ports: - # - "5051:5051" - # docker version in mesosphere/mesos-slave-dind:0.3.0_mesos-1.0.1_docker-1.10.3_ubuntu-14.04.5 is too old and can't - # pull images on new kernels. - command: - - "/bin/sh" - - "-c" - - "(/usr/local/bin/dockerd-entrypoint.sh &); sleep 10; set -x; \ - docker -H unix:///var/run/docker.sock run -d --net=host --privileged \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /cgroup:/cgroup -v /sys:/sys \ - -v /usr/local/bin/docker:/usr/local/bin/docker \ - -e MESOS_HOSTNAME=$$(hostname -i) \ - -e MESOS_CONTAINERIZERS=docker,mesos \ - -e MESOS_ISOLATOR=cgroups/cpu,cgroups/mem \ - -e MESOS_LOG_DIR=/var/log \ - -e MESOS_MASTER=zk://zookeeper:2181/mesos \ - -e MESOS_PORT=5051 \ - -e MESOS_WORK_DIR=/var/lib/mesos \ - -e MESOS_EXECUTOR_REGISTRATION_TIMEOUT=5mins \ - -e MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD=90secs \ - -e MESOS_DOCKER_STOP_TIMEOUT=60secs \ - -e MESOS_RESOURCES='cpus:2;mem:2048;disk:20480;ports(*):[12000-12999]' \ - mesosphere/mesos-slave:1.0.3; sleep 600" - - marathon: - image: mesosphere/marathon:v1.3.12 - # Uncomment published ports for interactive debugging. - # ports: - # - "8080:8080" - environment: - MARATHON_ZK: zk://zookeeper:2181/marathon - MARATHON_MASTER: zk://zookeeper:2181/mesos - -networks: - default: - name: traefik-test-network - external: true diff --git a/integration/resources/compose/marathon15.yml b/integration/resources/compose/marathon15.yml deleted file mode 100644 index 6a5774fc7..000000000 --- a/integration/resources/compose/marathon15.yml +++ /dev/null @@ -1,59 +0,0 @@ -version: "3.8" -services: - zookeeper: - image: zookeeper:3.4.10 - - mesos-master: - image: mesosphere/mesos-master:1.4.1 - # Uncomment published ports for interactive debugging. - # ports: - # - "5050:5050" - environment: - MESOS_HOSTNAME: mesos-master - MESOS_CLUSTER: local - MESOS_REGISTRY: in_memory - MESOS_LOG_DIR: /var/log - MESOS_WORK_DIR: /var/lib/mesos - MESOS_ZK: zk://zookeeper:2181/mesos - - mesos-slave: - image: docker:dind - privileged: true - # Uncomment published ports for interactive debugging. - # ports: - # - "5051:5051" - command: - - "/bin/sh" - - "-c" - - "(/usr/local/bin/dockerd-entrypoint.sh &); sleep 10; set -x; \ - docker -H unix:///var/run/docker.sock run -d --net=host --privileged \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /cgroup:/cgroup -v /sys:/sys \ - -v /usr/local/bin/docker:/usr/local/bin/docker \ - -e MESOS_HOSTNAME=$$(hostname -i) \ - -e MESOS_CONTAINERIZERS=docker,mesos \ - -e MESOS_ISOLATOR=cgroups/cpu,cgroups/mem \ - -e MESOS_LOG_DIR=/var/log \ - -e MESOS_MASTER=zk://zookeeper:2181/mesos \ - -e MESOS_PORT=5051 \ - -e MESOS_WORK_DIR=/var/lib/mesos \ - -e MESOS_EXECUTOR_REGISTRATION_TIMEOUT=5mins \ - -e MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD=90secs \ - -e MESOS_DOCKER_STOP_TIMEOUT=60secs \ - -e MESOS_RESOURCES='cpus:2;mem:2048;disk:20480;ports(*):[12000-12999]' \ - -e MESOS_SYSTEMD_ENABLE_SUPPORT=false \ - mesosphere/mesos-slave:1.4.1; sleep 600" - - marathon: - image: mesosphere/marathon:v1.5.9 - # Uncomment published ports for interactive debugging. - # ports: - # - "8080:8080" - environment: - MARATHON_ZK: zk://zookeeper:2181/marathon - MARATHON_MASTER: zk://zookeeper:2181/mesos - -networks: - default: - name: traefik-test-network - external: true diff --git a/pkg/api/handler_overview_test.go b/pkg/api/handler_overview_test.go index b7f96c6b9..2985d93ae 100644 --- a/pkg/api/handler_overview_test.go +++ b/pkg/api/handler_overview_test.go @@ -18,8 +18,6 @@ import ( "github.com/traefik/traefik/v2/pkg/provider/hub" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/ingress" - "github.com/traefik/traefik/v2/pkg/provider/marathon" - "github.com/traefik/traefik/v2/pkg/provider/rancher" "github.com/traefik/traefik/v2/pkg/provider/rest" "github.com/traefik/traefik/v2/pkg/tracing/jaeger" "github.com/traefik/traefik/v2/pkg/types" @@ -238,11 +236,9 @@ func TestHandler_Overview(t *testing.T) { Providers: &static.Providers{ Docker: &docker.Provider{}, File: &file.Provider{}, - Marathon: &marathon.Provider{}, KubernetesIngress: &ingress.Provider{}, KubernetesCRD: &crd.Provider{}, Rest: &rest.Provider{}, - Rancher: &rancher.Provider{}, Plugin: map[string]static.PluginConf{ "test": map[string]interface{}{}, }, diff --git a/pkg/api/testdata/overview-providers.json b/pkg/api/testdata/overview-providers.json index 95d4d10d2..20f134354 100644 --- a/pkg/api/testdata/overview-providers.json +++ b/pkg/api/testdata/overview-providers.json @@ -25,11 +25,9 @@ "providers": [ "Docker", "File", - "Marathon", "KubernetesIngress", "KubernetesCRD", "Rest", - "Rancher", "plugin-test" ], "tcp": { diff --git a/pkg/config/dynamic/fixtures/sample.toml b/pkg/config/dynamic/fixtures/sample.toml index 6f5137f4c..6d37b8ab7 100644 --- a/pkg/config/dynamic/fixtures/sample.toml +++ b/pkg/config/dynamic/fixtures/sample.toml @@ -54,28 +54,6 @@ watch = true filename = "foobar" debugLogGeneratedTemplate = true - [providers.marathon] - constraints = "foobar" - trace = true - watch = true - endpoint = "foobar" - defaultRule = "foobar" - exposedByDefault = true - dcosToken = "foobar" - dialerTimeout = 42 - responseHeaderTimeout = 42 - tlsHandshakeTimeout = 42 - keepAlive = 42 - forceTaskHostname = true - respectReadinessChecks = true - [providers.marathon.tls] - ca = "foobar" - cert = "foobar" - key = "foobar" - insecureSkipVerify = true - [providers.marathon.basic] - httpBasicAuthUser = "foobar" - httpBasicPassword = "foobar" [providers.kubernetesIngress] endpoint = "foobar" token = "foobar" @@ -96,15 +74,6 @@ ingressClass = "foobar" [providers.rest] entryPoint = "foobar" - [providers.rancher] - constraints = "foobar" - watch = true - defaultRule = "foobar" - exposedByDefault = true - enableServiceHealthFilter = true - refreshSeconds = 42 - intervalPoll = true - prefix = "foobar" [api] entryPoint = "foobar" @@ -124,14 +93,6 @@ [metrics.statsD] address = "foobar" pushInterval = "10s" - [metrics.influxDB] - address = "foobar" - protocol = "foobar" - pushInterval = "10s" - database = "foobar" - retentionPolicy = "foobar" - username = "foobar" - password = "foobar" [ping] entryPoint = "foobar" diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go index eba224bd1..943e2cdec 100644 --- a/pkg/config/static/static_config.go +++ b/pkg/config/static/static_config.go @@ -25,9 +25,7 @@ import ( "github.com/traefik/traefik/v2/pkg/provider/kv/etcd" "github.com/traefik/traefik/v2/pkg/provider/kv/redis" "github.com/traefik/traefik/v2/pkg/provider/kv/zk" - "github.com/traefik/traefik/v2/pkg/provider/marathon" "github.com/traefik/traefik/v2/pkg/provider/nomad" - "github.com/traefik/traefik/v2/pkg/provider/rancher" "github.com/traefik/traefik/v2/pkg/provider/rest" "github.com/traefik/traefik/v2/pkg/tls" "github.com/traefik/traefik/v2/pkg/tracing/datadog" @@ -214,12 +212,10 @@ type Providers struct { Docker *docker.Provider `description:"Enable Docker backend with default settings." json:"docker,omitempty" toml:"docker,omitempty" yaml:"docker,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` File *file.Provider `description:"Enable File backend with default settings." json:"file,omitempty" toml:"file,omitempty" yaml:"file,omitempty" export:"true"` - Marathon *marathon.Provider `description:"Enable Marathon backend with default settings." json:"marathon,omitempty" toml:"marathon,omitempty" yaml:"marathon,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` KubernetesIngress *ingress.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesIngress,omitempty" toml:"kubernetesIngress,omitempty" yaml:"kubernetesIngress,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesCRD,omitempty" toml:"kubernetesCRD,omitempty" yaml:"kubernetesCRD,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` KubernetesGateway *gateway.Provider `description:"Enable Kubernetes gateway api provider with default settings." json:"kubernetesGateway,omitempty" toml:"kubernetesGateway,omitempty" yaml:"kubernetesGateway,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Rest *rest.Provider `description:"Enable Rest backend with default settings." json:"rest,omitempty" toml:"rest,omitempty" yaml:"rest,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - Rancher *rancher.Provider `description:"Enable Rancher backend with default settings." json:"rancher,omitempty" toml:"rancher,omitempty" yaml:"rancher,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` ConsulCatalog *consulcatalog.ProviderBuilder `description:"Enable ConsulCatalog backend with default settings." json:"consulCatalog,omitempty" toml:"consulCatalog,omitempty" yaml:"consulCatalog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Nomad *nomad.ProviderBuilder `description:"Enable Nomad backend with default settings." json:"nomad,omitempty" toml:"nomad,omitempty" yaml:"nomad,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Ecs *ecs.Provider `description:"Enable AWS ECS backend with default settings." json:"ecs,omitempty" toml:"ecs,omitempty" yaml:"ecs,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` @@ -278,12 +274,6 @@ func (c *Configuration) SetEffectiveConfiguration() { } } - if c.Providers.Rancher != nil { - if c.Providers.Rancher.RefreshSeconds <= 0 { - c.Providers.Rancher.RefreshSeconds = 15 - } - } - // Disable Gateway API provider if not enabled in experimental. if c.Experimental == nil || !c.Experimental.KubernetesGateway { c.Providers.KubernetesGateway = nil diff --git a/pkg/metrics/influxdb.go b/pkg/metrics/influxdb.go deleted file mode 100644 index d90ec75fc..000000000 --- a/pkg/metrics/influxdb.go +++ /dev/null @@ -1,249 +0,0 @@ -package metrics - -import ( - "bytes" - "context" - "fmt" - "net/url" - "regexp" - "time" - - "github.com/go-kit/kit/metrics/influx" - influxdb "github.com/influxdata/influxdb1-client/v2" - "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" -) - -var ( - influxDBClient *influx.Influx - influxDBTicker *time.Ticker -) - -const ( - influxDBConfigReloadsName = "traefik.config.reload.total" - influxDBConfigReloadsFailureName = influxDBConfigReloadsName + ".failure" - influxDBLastConfigReloadSuccessName = "traefik.config.reload.lastSuccessTimestamp" - influxDBLastConfigReloadFailureName = "traefik.config.reload.lastFailureTimestamp" - - influxDBTLSCertsNotAfterTimestampName = "traefik.tls.certs.notAfterTimestamp" - - influxDBEntryPointReqsName = "traefik.entrypoint.requests.total" - influxDBEntryPointReqsTLSName = "traefik.entrypoint.requests.tls.total" - influxDBEntryPointReqDurationName = "traefik.entrypoint.request.duration" - influxDBEntryPointOpenConnsName = "traefik.entrypoint.connections.open" - influxDBEntryPointReqsBytesName = "traefik.entrypoint.requests.bytes.total" - influxDBEntryPointRespsBytesName = "traefik.entrypoint.responses.bytes.total" - - influxDBRouterReqsName = "traefik.router.requests.total" - influxDBRouterReqsTLSName = "traefik.router.requests.tls.total" - influxDBRouterReqsDurationName = "traefik.router.request.duration" - influxDBORouterOpenConnsName = "traefik.router.connections.open" - influxDBRouterReqsBytesName = "traefik.router.requests.bytes.total" - influxDBRouterRespsBytesName = "traefik.router.responses.bytes.total" - - influxDBServiceReqsName = "traefik.service.requests.total" - influxDBServiceReqsTLSName = "traefik.service.requests.tls.total" - influxDBServiceReqsDurationName = "traefik.service.request.duration" - influxDBServiceRetriesTotalName = "traefik.service.retries.total" - influxDBServiceOpenConnsName = "traefik.service.connections.open" - influxDBServiceServerUpName = "traefik.service.server.up" - influxDBServiceReqsBytesName = "traefik.service.requests.bytes.total" - influxDBServiceRespsBytesName = "traefik.service.responses.bytes.total" -) - -const ( - protocolHTTP = "http" - protocolUDP = "udp" -) - -// RegisterInfluxDB registers the metrics pusher if this didn't happen yet and creates a InfluxDB Registry instance. -func RegisterInfluxDB(ctx context.Context, config *types.InfluxDB) Registry { - if influxDBClient == nil { - influxDBClient = initInfluxDBClient(ctx, config) - } - if influxDBTicker == nil { - influxDBTicker = initInfluxDBTicker(ctx, config) - } - - registry := &standardRegistry{ - configReloadsCounter: influxDBClient.NewCounter(influxDBConfigReloadsName), - configReloadsFailureCounter: influxDBClient.NewCounter(influxDBConfigReloadsFailureName), - lastConfigReloadSuccessGauge: influxDBClient.NewGauge(influxDBLastConfigReloadSuccessName), - lastConfigReloadFailureGauge: influxDBClient.NewGauge(influxDBLastConfigReloadFailureName), - tlsCertsNotAfterTimestampGauge: influxDBClient.NewGauge(influxDBTLSCertsNotAfterTimestampName), - } - - if config.AddEntryPointsLabels { - registry.epEnabled = config.AddEntryPointsLabels - registry.entryPointReqsCounter = influxDBClient.NewCounter(influxDBEntryPointReqsName) - registry.entryPointReqsTLSCounter = influxDBClient.NewCounter(influxDBEntryPointReqsTLSName) - registry.entryPointReqDurationHistogram, _ = NewHistogramWithScale(influxDBClient.NewHistogram(influxDBEntryPointReqDurationName), time.Second) - registry.entryPointOpenConnsGauge = influxDBClient.NewGauge(influxDBEntryPointOpenConnsName) - registry.entryPointReqsBytesCounter = influxDBClient.NewCounter(influxDBEntryPointReqsBytesName) - registry.entryPointRespsBytesCounter = influxDBClient.NewCounter(influxDBEntryPointRespsBytesName) - } - - if config.AddRoutersLabels { - registry.routerEnabled = config.AddRoutersLabels - registry.routerReqsCounter = influxDBClient.NewCounter(influxDBRouterReqsName) - registry.routerReqsTLSCounter = influxDBClient.NewCounter(influxDBRouterReqsTLSName) - registry.routerReqDurationHistogram, _ = NewHistogramWithScale(influxDBClient.NewHistogram(influxDBRouterReqsDurationName), time.Second) - registry.routerOpenConnsGauge = influxDBClient.NewGauge(influxDBORouterOpenConnsName) - registry.routerReqsBytesCounter = influxDBClient.NewCounter(influxDBRouterReqsBytesName) - registry.routerRespsBytesCounter = influxDBClient.NewCounter(influxDBRouterRespsBytesName) - } - - if config.AddServicesLabels { - registry.svcEnabled = config.AddServicesLabels - registry.serviceReqsCounter = influxDBClient.NewCounter(influxDBServiceReqsName) - registry.serviceReqsTLSCounter = influxDBClient.NewCounter(influxDBServiceReqsTLSName) - registry.serviceReqDurationHistogram, _ = NewHistogramWithScale(influxDBClient.NewHistogram(influxDBServiceReqsDurationName), time.Second) - registry.serviceRetriesCounter = influxDBClient.NewCounter(influxDBServiceRetriesTotalName) - registry.serviceOpenConnsGauge = influxDBClient.NewGauge(influxDBServiceOpenConnsName) - registry.serviceServerUpGauge = influxDBClient.NewGauge(influxDBServiceServerUpName) - registry.serviceReqsBytesCounter = influxDBClient.NewCounter(influxDBServiceReqsBytesName) - registry.serviceRespsBytesCounter = influxDBClient.NewCounter(influxDBServiceRespsBytesName) - } - - return registry -} - -// initInfluxDBClient creates a influxDBClient. -func initInfluxDBClient(ctx context.Context, config *types.InfluxDB) *influx.Influx { - logger := log.Ctx(ctx) - - // TODO deprecated: move this switch into configuration.SetEffectiveConfiguration when web provider will be removed. - switch config.Protocol { - case protocolUDP: - if len(config.Database) > 0 || len(config.RetentionPolicy) > 0 { - logger.Warn().Msg("Database and RetentionPolicy options have no effect with UDP.") - config.Database = "" - config.RetentionPolicy = "" - } - case protocolHTTP: - if u, err := url.Parse(config.Address); err == nil { - if u.Scheme != "http" && u.Scheme != "https" { - logger.Warn().Msgf("InfluxDB address %s should specify a scheme (http or https): falling back on HTTP.", config.Address) - config.Address = "http://" + config.Address - } - } else { - logger.Error().Err(err).Msg("Unable to parse the InfluxDB address: falling back on UDP.") - config.Protocol = protocolUDP - config.Database = "" - config.RetentionPolicy = "" - } - default: - logger.Warn().Msgf("Unsupported protocol %s: falling back on UDP.", config.Protocol) - config.Protocol = protocolUDP - config.Database = "" - config.RetentionPolicy = "" - } - - return influx.New( - config.AdditionalLabels, - influxdb.BatchPointsConfig{ - Database: config.Database, - RetentionPolicy: config.RetentionPolicy, - }, - logs.NewGoKitWrapper(*logger), - ) -} - -// initInfluxDBTicker initializes metrics pusher. -func initInfluxDBTicker(ctx context.Context, config *types.InfluxDB) *time.Ticker { - report := time.NewTicker(time.Duration(config.PushInterval)) - - safe.Go(func() { - var buf bytes.Buffer - influxDBClient.WriteLoop(ctx, report.C, &influxDBWriter{buf: buf, config: config}) - }) - - return report -} - -// StopInfluxDB stops internal influxDBTicker which controls the pushing of metrics to InfluxDB Agent and resets it to `nil`. -func StopInfluxDB() { - if influxDBTicker != nil { - influxDBTicker.Stop() - } - influxDBTicker = nil -} - -type influxDBWriter struct { - buf bytes.Buffer - config *types.InfluxDB -} - -// Write creates a http or udp client and attempts to write BatchPoints. -// If a "database not found" error is encountered, a CREATE DATABASE -// query is attempted when using protocol http. -func (w *influxDBWriter) Write(bp influxdb.BatchPoints) error { - c, err := w.initWriteClient() - if err != nil { - return err - } - - defer c.Close() - - if writeErr := c.Write(bp); writeErr != nil { - logger := log.With().Str(logs.MetricsProviderName, "influxdb").Logger() - logger.Error().Err(writeErr).Msg("Error while writing to InfluxDB") - - if handleErr := w.handleWriteError(logger.WithContext(context.Background()), c, writeErr); handleErr != nil { - return handleErr - } - // Retry write after successful handling of writeErr - return c.Write(bp) - } - return nil -} - -func (w *influxDBWriter) initWriteClient() (influxdb.Client, error) { - if w.config.Protocol == "http" { - return influxdb.NewHTTPClient(influxdb.HTTPConfig{ - Addr: w.config.Address, - Username: w.config.Username, - Password: w.config.Password, - }) - } - - return influxdb.NewUDPClient(influxdb.UDPConfig{ - Addr: w.config.Address, - }) -} - -func (w *influxDBWriter) handleWriteError(ctx context.Context, c influxdb.Client, writeErr error) error { - if w.config.Protocol != protocolHTTP { - return writeErr - } - - match, matchErr := regexp.MatchString("database not found", writeErr.Error()) - - if matchErr != nil || !match { - return writeErr - } - - qStr := fmt.Sprintf("CREATE DATABASE \"%s\"", w.config.Database) - if w.config.RetentionPolicy != "" { - qStr = fmt.Sprintf("%s WITH NAME \"%s\"", qStr, w.config.RetentionPolicy) - } - - logger := log.Ctx(ctx) - - logger.Debug().Msgf("InfluxDB database not found: attempting to create one with %s", qStr) - - q := influxdb.NewQuery(qStr, "", "") - response, queryErr := c.Query(q) - if queryErr == nil && response.Error() != nil { - queryErr = response.Error() - } - if queryErr != nil { - logger.Error().Err(queryErr).Msg("Error while creating the InfluxDB database") - return queryErr - } - - logger.Debug().Msgf("Successfully created the InfluxDB database %s", w.config.Database) - return nil -} diff --git a/pkg/metrics/influxdb2.go b/pkg/metrics/influxdb2.go index 6cf02e8f7..b23bcc31e 100644 --- a/pkg/metrics/influxdb2.go +++ b/pkg/metrics/influxdb2.go @@ -23,6 +23,38 @@ var ( influxDB2Client influxdb2.Client ) +const ( + influxDBConfigReloadsName = "traefik.config.reload.total" + influxDBConfigReloadsFailureName = influxDBConfigReloadsName + ".failure" + influxDBLastConfigReloadSuccessName = "traefik.config.reload.lastSuccessTimestamp" + influxDBLastConfigReloadFailureName = "traefik.config.reload.lastFailureTimestamp" + + influxDBTLSCertsNotAfterTimestampName = "traefik.tls.certs.notAfterTimestamp" + + influxDBEntryPointReqsName = "traefik.entrypoint.requests.total" + influxDBEntryPointReqsTLSName = "traefik.entrypoint.requests.tls.total" + influxDBEntryPointReqDurationName = "traefik.entrypoint.request.duration" + influxDBEntryPointOpenConnsName = "traefik.entrypoint.connections.open" + influxDBEntryPointReqsBytesName = "traefik.entrypoint.requests.bytes.total" + influxDBEntryPointRespsBytesName = "traefik.entrypoint.responses.bytes.total" + + influxDBRouterReqsName = "traefik.router.requests.total" + influxDBRouterReqsTLSName = "traefik.router.requests.tls.total" + influxDBRouterReqsDurationName = "traefik.router.request.duration" + influxDBORouterOpenConnsName = "traefik.router.connections.open" + influxDBRouterReqsBytesName = "traefik.router.requests.bytes.total" + influxDBRouterRespsBytesName = "traefik.router.responses.bytes.total" + + influxDBServiceReqsName = "traefik.service.requests.total" + influxDBServiceReqsTLSName = "traefik.service.requests.tls.total" + influxDBServiceReqsDurationName = "traefik.service.request.duration" + influxDBServiceRetriesTotalName = "traefik.service.retries.total" + influxDBServiceOpenConnsName = "traefik.service.connections.open" + influxDBServiceServerUpName = "traefik.service.server.up" + influxDBServiceReqsBytesName = "traefik.service.requests.bytes.total" + influxDBServiceRespsBytesName = "traefik.service.responses.bytes.total" +) + // RegisterInfluxDB2 creates metrics exporter for InfluxDB2. func RegisterInfluxDB2(ctx context.Context, config *types.InfluxDB2) Registry { logger := log.Ctx(ctx) diff --git a/pkg/metrics/influxdb2_test.go b/pkg/metrics/influxdb2_test.go index 3fc628d67..441137999 100644 --- a/pkg/metrics/influxdb2_test.go +++ b/pkg/metrics/influxdb2_test.go @@ -6,6 +6,7 @@ import ( "io" "net/http" "net/http/httptest" + "regexp" "strconv" "testing" "time" @@ -155,3 +156,14 @@ func TestInfluxDB2(t *testing.T) { assertMessage(t, *msgServiceOpenConns, expectedServiceOpenConns) } + +func assertMessage(t *testing.T, msg string, patterns []string) { + t.Helper() + for _, pattern := range patterns { + re := regexp.MustCompile(pattern) + match := re.FindStringSubmatch(msg) + if len(match) != 2 { + t.Errorf("Got %q %v, want %q", msg, match, pattern) + } + } +} diff --git a/pkg/metrics/influxdb_test.go b/pkg/metrics/influxdb_test.go deleted file mode 100644 index 38a146697..000000000 --- a/pkg/metrics/influxdb_test.go +++ /dev/null @@ -1,267 +0,0 @@ -package metrics - -import ( - "context" - "fmt" - "io" - "net/http" - "net/http/httptest" - "regexp" - "strconv" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/stvp/go-udp-testing" - ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/types" -) - -func TestInfluxDB(t *testing.T) { - udp.SetAddr(":8089") - // This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond - udp.Timeout = 5 * time.Second - - influxDBClient = nil - influxDBRegistry := RegisterInfluxDB(context.Background(), - &types.InfluxDB{ - Address: ":8089", - PushInterval: ptypes.Duration(time.Second), - AddEntryPointsLabels: true, - AddRoutersLabels: true, - AddServicesLabels: true, - AdditionalLabels: map[string]string{"tag1": "val1"}, - }) - defer StopInfluxDB() - - if !influxDBRegistry.IsEpEnabled() || !influxDBRegistry.IsRouterEnabled() || !influxDBRegistry.IsSvcEnabled() { - t.Fatalf("InfluxDBRegistry should return true for IsEnabled(), IsRouterEnabled() and IsSvcEnabled()") - } - - expectedServer := []string{ - `(traefik\.config\.reload\.total,tag1=val1 count=1) [\d]{19}`, - `(traefik\.config\.reload\.total\.failure,tag1=val1 count=1) [\d]{19}`, - `(traefik\.config\.reload\.lastSuccessTimestamp,tag1=val1 value=1) [\d]{19}`, - `(traefik\.config\.reload\.lastFailureTimestamp,tag1=val1 value=1) [\d]{19}`, - } - - msgServer := udp.ReceiveString(t, func() { - influxDBRegistry.ConfigReloadsCounter().Add(1) - influxDBRegistry.ConfigReloadsFailureCounter().Add(1) - influxDBRegistry.LastConfigReloadSuccessGauge().Set(1) - influxDBRegistry.LastConfigReloadFailureGauge().Set(1) - }) - - assertMessage(t, msgServer, expectedServer) - - expectedTLS := []string{ - `(traefik\.tls\.certs\.notAfterTimestamp,key=value,tag1=val1 value=1) [\d]{19}`, - } - - msgTLS := udp.ReceiveString(t, func() { - influxDBRegistry.TLSCertsNotAfterTimestampGauge().With("key", "value").Set(1) - }) - - assertMessage(t, msgTLS, expectedTLS) - - expectedEntrypoint := []string{ - `(traefik\.entrypoint\.requests\.total,code=200,entrypoint=test,method=GET,tag1=val1 count=1) [\d]{19}`, - `(traefik\.entrypoint\.requests\.tls\.total,entrypoint=test,tag1=val1,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.entrypoint\.request\.duration(?:,code=[\d]{3})?,entrypoint=test,tag1=val1 p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.entrypoint\.connections\.open,entrypoint=test,tag1=val1 value=1) [\d]{19}`, - `(traefik\.entrypoint\.requests\.bytes\.total,code=200,entrypoint=test,method=GET,tag1=val1 count=1) [\d]{19}`, - `(traefik\.entrypoint\.responses\.bytes\.total,code=200,entrypoint=test,method=GET,tag1=val1 count=1) [\d]{19}`, - } - - msgEntrypoint := udp.ReceiveString(t, func() { - influxDBRegistry.EntryPointReqsCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.EntryPointReqsTLSCounter().With("entrypoint", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.EntryPointReqDurationHistogram().With("entrypoint", "test").Observe(10000) - influxDBRegistry.EntryPointOpenConnsGauge().With("entrypoint", "test").Set(1) - influxDBRegistry.EntryPointReqsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.EntryPointRespsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - }) - - assertMessage(t, msgEntrypoint, expectedEntrypoint) - - expectedRouter := []string{ - `(traefik\.router\.requests\.total,code=200,method=GET,router=demo,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.router\.requests\.total,code=404,method=GET,router=demo,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.router\.requests\.tls\.total,router=demo,service=test,tag1=val1,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.router\.request\.duration,code=200,router=demo,service=test,tag1=val1 p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.router\.connections\.open,router=demo,service=test,tag1=val1 value=1) [\d]{19}`, - `(traefik\.router\.requests\.bytes\.total,code=200,method=GET,router=demo,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.router\.responses\.bytes\.total,code=200,method=GET,router=demo,service=test,tag1=val1 count=1) [\d]{19}`, - } - - msgRouter := udp.ReceiveString(t, func() { - influxDBRegistry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterReqsTLSCounter().With("router", "demo", "service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.RouterReqDurationHistogram().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - influxDBRegistry.RouterOpenConnsGauge().With("router", "demo", "service", "test").Set(1) - influxDBRegistry.RouterReqsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterRespsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - }) - - assertMessage(t, msgRouter, expectedRouter) - - expectedService := []string{ - `(traefik\.service\.requests\.total,code=200,method=GET,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.service\.requests\.total,code=404,method=GET,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.service\.requests\.tls\.total,service=test,tag1=val1,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.service\.request\.duration,code=200,service=test,tag1=val1 p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.service\.retries\.total(?:,code=[\d]{3},method=GET)?,service=test,tag1=val1 count=2) [\d]{19}`, - `(traefik\.service\.server\.up,service=test,tag1=val1,url=http://127.0.0.1 value=1) [\d]{19}`, - `(traefik\.service\.connections\.open,service=test,tag1=val1 value=1) [\d]{19}`, - `(traefik\.service\.requests\.bytes\.total,code=200,method=GET,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.service\.responses\.bytes\.total,code=200,method=GET,service=test,tag1=val1 count=1) [\d]{19}`, - } - - msgService := udp.ReceiveString(t, func() { - influxDBRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceReqsTLSCounter().With("service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - influxDBRegistry.ServiceOpenConnsGauge().With("service", "test").Set(1) - influxDBRegistry.ServiceRetriesCounter().With("service", "test").Add(1) - influxDBRegistry.ServiceRetriesCounter().With("service", "test").Add(1) - influxDBRegistry.ServiceServerUpGauge().With("service", "test", "url", "http://127.0.0.1").Set(1) - influxDBRegistry.ServiceReqsBytesCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceRespsBytesCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - }) - - assertMessage(t, msgService, expectedService) -} - -func TestInfluxDBHTTP(t *testing.T) { - c := make(chan *string) - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - body, err := io.ReadAll(r.Body) - require.NoError(t, err) - - bodyStr := string(body) - c <- &bodyStr - _, _ = fmt.Fprintln(w, "ok") - })) - defer ts.Close() - - influxDBClient = nil - influxDBRegistry := RegisterInfluxDB(context.Background(), - &types.InfluxDB{ - Address: ts.URL, - Protocol: "http", - PushInterval: ptypes.Duration(10 * time.Millisecond), - Database: "test", - RetentionPolicy: "autogen", - AddEntryPointsLabels: true, - AddServicesLabels: true, - AddRoutersLabels: true, - }) - defer StopInfluxDB() - - if !influxDBRegistry.IsEpEnabled() || !influxDBRegistry.IsRouterEnabled() || !influxDBRegistry.IsSvcEnabled() { - t.Fatalf("InfluxDB registry must be epEnabled") - } - - expectedServer := []string{ - `(traefik\.config\.reload\.total count=1) [\d]{19}`, - `(traefik\.config\.reload\.total\.failure count=1) [\d]{19}`, - `(traefik\.config\.reload\.lastSuccessTimestamp value=1) [\d]{19}`, - `(traefik\.config\.reload\.lastFailureTimestamp value=1) [\d]{19}`, - } - - influxDBRegistry.ConfigReloadsCounter().Add(1) - influxDBRegistry.ConfigReloadsFailureCounter().Add(1) - influxDBRegistry.LastConfigReloadSuccessGauge().Set(1) - influxDBRegistry.LastConfigReloadFailureGauge().Set(1) - msgServer := <-c - - assertMessage(t, *msgServer, expectedServer) - - expectedTLS := []string{ - `(traefik\.tls\.certs\.notAfterTimestamp,key=value value=1) [\d]{19}`, - } - - influxDBRegistry.TLSCertsNotAfterTimestampGauge().With("key", "value").Set(1) - msgTLS := <-c - - assertMessage(t, *msgTLS, expectedTLS) - - expectedEntrypoint := []string{ - `(traefik\.entrypoint\.requests\.total,code=200,entrypoint=test,method=GET count=1) [\d]{19}`, - `(traefik\.entrypoint\.requests\.tls\.total,entrypoint=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.entrypoint\.request\.duration(?:,code=[\d]{3})?,entrypoint=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.entrypoint\.connections\.open,entrypoint=test value=1) [\d]{19}`, - `(traefik\.entrypoint\.requests\.bytes\.total,code=200,entrypoint=test,method=GET count=1) [\d]{19}`, - `(traefik\.entrypoint\.responses\.bytes\.total,code=200,entrypoint=test,method=GET count=1) [\d]{19}`, - } - - influxDBRegistry.EntryPointReqsCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.EntryPointReqsTLSCounter().With("entrypoint", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.EntryPointReqDurationHistogram().With("entrypoint", "test").Observe(10000) - influxDBRegistry.EntryPointOpenConnsGauge().With("entrypoint", "test").Set(1) - influxDBRegistry.EntryPointReqsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.EntryPointRespsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - msgEntrypoint := <-c - - assertMessage(t, *msgEntrypoint, expectedEntrypoint) - - expectedRouter := []string{ - `(traefik\.router\.requests\.total,code=200,method=GET,router=demo,service=test count=1) [\d]{19}`, - `(traefik\.router\.requests\.total,code=404,method=GET,router=demo,service=test count=1) [\d]{19}`, - `(traefik\.router\.requests\.tls\.total,router=demo,service=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.router\.request\.duration,code=200,router=demo,service=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.router\.connections\.open,router=demo,service=test value=1) [\d]{19}`, - `(traefik\.router\.requests\.bytes\.total,code=200,method=GET,router=demo,service=test count=1) [\d]{19}`, - `(traefik\.router\.responses\.bytes\.total,code=200,method=GET,router=demo,service=test count=1) [\d]{19}`, - } - - influxDBRegistry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterReqsTLSCounter().With("router", "demo", "service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.RouterReqDurationHistogram().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - influxDBRegistry.RouterOpenConnsGauge().With("router", "demo", "service", "test").Set(1) - influxDBRegistry.RouterReqsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterRespsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - msgRouter := <-c - - assertMessage(t, *msgRouter, expectedRouter) - - expectedService := []string{ - `(traefik\.service\.requests\.total,code=200,method=GET,service=test count=1) [\d]{19}`, - `(traefik\.service\.requests\.total,code=404,method=GET,service=test count=1) [\d]{19}`, - `(traefik\.service\.requests\.tls\.total,service=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.service\.request\.duration,code=200,service=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.service\.retries\.total(?:,code=[\d]{3},method=GET)?,service=test count=2) [\d]{19}`, - `(traefik\.service\.server\.up,service=test,url=http://127.0.0.1 value=1) [\d]{19}`, - `(traefik\.service\.connections\.open,service=test value=1) [\d]{19}`, - `(traefik\.service\.requests\.bytes\.total,code=200,method=GET,service=test count=1) [\d]{19}`, - `(traefik\.service\.responses\.bytes\.total,code=200,method=GET,service=test count=1) [\d]{19}`, - } - - influxDBRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceReqsTLSCounter().With("service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - influxDBRegistry.ServiceOpenConnsGauge().With("service", "test").Set(1) - influxDBRegistry.ServiceRetriesCounter().With("service", "test").Add(1) - influxDBRegistry.ServiceRetriesCounter().With("service", "test").Add(1) - influxDBRegistry.ServiceServerUpGauge().With("service", "test", "url", "http://127.0.0.1").Set(1) - influxDBRegistry.ServiceReqsBytesCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceRespsBytesCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - msgService := <-c - - assertMessage(t, *msgService, expectedService) -} - -func assertMessage(t *testing.T, msg string, patterns []string) { - t.Helper() - for _, pattern := range patterns { - re := regexp.MustCompile(pattern) - match := re.FindStringSubmatch(msg) - if len(match) != 2 { - t.Errorf("Got %q %v, want %q", msg, match, pattern) - } - } -} diff --git a/pkg/metrics/opentelemetry.go b/pkg/metrics/opentelemetry.go index 328f6fc54..94f170132 100644 --- a/pkg/metrics/opentelemetry.go +++ b/pkg/metrics/opentelemetry.go @@ -23,7 +23,6 @@ import ( "go.opentelemetry.io/otel/metric/unit" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/aggregation" - "go.opentelemetry.io/otel/sdk/metric/view" "google.golang.org/grpc/credentials" "google.golang.org/grpc/encoding/gzip" ) @@ -144,23 +143,16 @@ func newOpenTelemetryMeterProvider(ctx context.Context, config *types.OpenTeleme sdkmetric.WithInterval(time.Duration(config.PushInterval)), } - // View to customize histogram buckets and rename a single histogram instrument. - customBucketsView, err := view.New( - // Match* to match instruments - view.MatchInstrumentName("traefik_*_request_duration_seconds"), - - view.WithSetAggregation(aggregation.ExplicitBucketHistogram{ - Boundaries: config.ExplicitBoundaries, - }), + meterProvider := sdkmetric.NewMeterProvider( + sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exporter, opts...)), + // View to customize histogram buckets and rename a single histogram instrument. + sdkmetric.WithView(sdkmetric.NewView( + sdkmetric.Instrument{Name: "traefik_*_request_duration_seconds"}, + sdkmetric.Stream{Aggregation: aggregation.ExplicitBucketHistogram{ + Boundaries: config.ExplicitBoundaries, + }}, + )), ) - if err != nil { - return nil, fmt.Errorf("creating histogram view: %w", err) - } - - meterProvider := sdkmetric.NewMeterProvider(sdkmetric.WithReader( - sdkmetric.NewPeriodicReader(exporter, opts...), - customBucketsView, - )) global.SetMeterProvider(meterProvider) diff --git a/pkg/provider/aggregator/aggregator.go b/pkg/provider/aggregator/aggregator.go index 8001711fc..ccdaa3d5f 100644 --- a/pkg/provider/aggregator/aggregator.go +++ b/pkg/provider/aggregator/aggregator.go @@ -80,10 +80,6 @@ func NewProviderAggregator(conf static.Providers) ProviderAggregator { p.quietAddProvider(conf.Docker) } - if conf.Marathon != nil { - p.quietAddProvider(conf.Marathon) - } - if conf.Rest != nil { p.quietAddProvider(conf.Rest) } @@ -100,10 +96,6 @@ func NewProviderAggregator(conf static.Providers) ProviderAggregator { p.quietAddProvider(conf.KubernetesGateway) } - if conf.Rancher != nil { - p.quietAddProvider(conf.Rancher) - } - if conf.Ecs != nil { p.quietAddProvider(conf.Ecs) } diff --git a/pkg/provider/constraints/constraints_labels.go b/pkg/provider/constraints/constraints_labels.go index 6f194ba33..6d74bfbab 100644 --- a/pkg/provider/constraints/constraints_labels.go +++ b/pkg/provider/constraints/constraints_labels.go @@ -3,22 +3,16 @@ package constraints import ( "errors" "regexp" - "strings" "github.com/vulcand/predicate" ) -// MarathonConstraintPrefix is the prefix for each label's key created from a Marathon application constraint. -// It is used in order to create a specific and unique pattern for these labels. -const MarathonConstraintPrefix = "Traefik-Marathon-505F9E15-BDC7-45E7-828D-C06C7BAB8091" - type constraintLabelFunc func(map[string]string) bool // MatchLabels reports whether the expression matches with the given labels. // The expression must match any logical boolean combination of: // - `Label(labelName, labelValue)` -// - `LabelRegex(labelName, regexValue)` -// - `MarathonConstraint(field:operator:value)`. +// - `LabelRegex(labelName, regexValue)`. func MatchLabels(labels map[string]string, expr string) (bool, error) { if expr == "" { return true, nil @@ -31,9 +25,8 @@ func MatchLabels(labels map[string]string, expr string) (bool, error) { OR: orLabelFunc, }, Functions: map[string]interface{}{ - "Label": labelFn, - "LabelRegex": labelRegexFn, - "MarathonConstraint": marathonFn, + "Label": labelFn, + "LabelRegex": labelRegexFn, }, }) if err != nil { @@ -68,19 +61,6 @@ func labelRegexFn(name, expr string) constraintLabelFunc { } } -func marathonFn(value string) constraintLabelFunc { - return func(labels map[string]string) bool { - for k, v := range labels { - if strings.HasPrefix(k, MarathonConstraintPrefix) { - if v == value { - return true - } - } - } - return false - } -} - func andLabelFunc(a, b constraintLabelFunc) constraintLabelFunc { return func(labels map[string]string) bool { return a(labels) && b(labels) diff --git a/pkg/provider/constraints/constraints_labels_test.go b/pkg/provider/constraints/constraints_labels_test.go index 43fb9e0c6..8068735eb 100644 --- a/pkg/provider/constraints/constraints_labels_test.go +++ b/pkg/provider/constraints/constraints_labels_test.go @@ -118,33 +118,6 @@ func TestMatchLabels(t *testing.T) { expr: ``, expected: true, }, - { - expr: `MarathonConstraint("bar")`, - labels: map[string]string{ - "hello": "world", - MarathonConstraintPrefix + "-1": "bar", - MarathonConstraintPrefix + "-2": "foo", - }, - expected: true, - }, - { - expr: `MarathonConstraint("bur")`, - labels: map[string]string{ - "hello": "world", - MarathonConstraintPrefix + "-1": "bar", - MarathonConstraintPrefix + "-2": "foo", - }, - expected: false, - }, - { - expr: `Label("hello", "world") && MarathonConstraint("bar")`, - labels: map[string]string{ - "hello": "world", - MarathonConstraintPrefix + "-1": "bar", - MarathonConstraintPrefix + "-2": "foo", - }, - expected: true, - }, { expr: `LabelRegex("hello", "w\\w+")`, labels: map[string]string{ diff --git a/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_invalid_SNI_matching.yml b/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_invalid_SNI_matching.yml index 004e1a4b9..512e39770 100644 --- a/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_invalid_SNI_matching.yml +++ b/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_invalid_SNI_matching.yml @@ -39,7 +39,7 @@ spec: kind: Gateway group: gateway.networking.k8s.io hostnames: - - "*.foo.bar" + - "*.foo.*.bar" rules: - backendRefs: - name: whoamitcp diff --git a/pkg/provider/kubernetes/gateway/kubernetes.go b/pkg/provider/kubernetes/gateway/kubernetes.go index fc620ae69..847d1c09b 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes.go +++ b/pkg/provider/kubernetes/gateway/kubernetes.go @@ -839,7 +839,7 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. } router := dynamic.TCPRouter{ - Rule: "HostSNI(`*`)", // Gateway listener hostname not available in TCP + Rule: "HostSNI(`*`)", EntryPoints: []string{ep}, } @@ -970,8 +970,16 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. hostnames := matchingHostnames(listener, route.Spec.Hostnames) if len(hostnames) == 0 && listener.Hostname != nil && *listener.Hostname != "" && len(route.Spec.Hostnames) > 0 { - // TODO update the corresponding route parent status - // https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute + for _, parent := range route.Status.Parents { + parent.Conditions = append(parent.Conditions, metav1.Condition{ + Type: string(v1alpha2.GatewayClassConditionStatusAccepted), + Status: metav1.ConditionFalse, + Reason: string(v1alpha2.ListenerReasonRouteConflict), + Message: fmt.Sprintf("No hostname match between listener: %v and route: %v", listener.Hostname, route.Spec.Hostnames), + LastTransitionTime: metav1.Now(), + }) + } + continue } @@ -1207,7 +1215,7 @@ func hostRule(hostnames []v1alpha2.Hostname) (string, error) { } func hostSNIRule(hostnames []v1alpha2.Hostname) (string, error) { - var matchers []string + rules := make([]string, 0, len(hostnames)) uniqHostnames := map[v1alpha2.Hostname]struct{}{} for _, hostname := range hostnames { @@ -1219,25 +1227,28 @@ func hostSNIRule(hostnames []v1alpha2.Hostname) (string, error) { continue } - h := string(hostname) + host := string(hostname) + uniqHostnames[hostname] = struct{}{} - // TODO support wildcard hostnames with an HostSNI regexp matcher - if strings.Contains(h, "*") { - return "", fmt.Errorf("wildcard hostname is not supported: %q", h) + wildcard := strings.Count(host, "*") + if wildcard == 0 { + rules = append(rules, fmt.Sprintf("HostSNI(`%s`)", host)) + continue } - matchers = append(matchers, fmt.Sprintf("HostSNI(`%s`)", h)) - uniqHostnames[hostname] = struct{}{} + if !strings.HasPrefix(host, "*.") || wildcard > 1 { + return "", fmt.Errorf("invalid rule: %q", host) + } + + host = strings.Replace(regexp.QuoteMeta(host), `\*\.`, `[a-zA-Z0-9-]+\.`, 1) + rules = append(rules, fmt.Sprintf("HostSNIRegexp(`^%s$`)", host)) } - switch len(matchers) { - case 0: + if len(hostnames) == 0 || len(rules) == 0 { return "HostSNI(`*`)", nil - case 1: - return matchers[0], nil - default: - return fmt.Sprintf("(%s)", strings.Join(matchers, " || ")), nil } + + return strings.Join(rules, " || "), nil } func extractRule(routeRule v1alpha2.HTTPRouteRule, hostRule string) (string, error) { diff --git a/pkg/provider/kubernetes/gateway/kubernetes_test.go b/pkg/provider/kubernetes/gateway/kubernetes_test.go index f7b6b9cd9..28946ba7b 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes_test.go +++ b/pkg/provider/kubernetes/gateway/kubernetes_test.go @@ -3076,10 +3076,10 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-tls-dfc5c7506ac1b172c8b7": { + "default-tls-app-1-my-gateway-tls-d5342d75658583f03593": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-1-my-gateway-tls-dfc5c7506ac1b172c8b7-wrr-0", - Rule: "(HostSNI(`foo.example.com`) || HostSNI(`bar.example.com`))", + Service: "default-tls-app-1-my-gateway-tls-d5342d75658583f03593-wrr-0", + Rule: "HostSNI(`foo.example.com`) || HostSNI(`bar.example.com`)", TLS: &dynamic.RouterTCPTLSConfig{ Passthrough: true, }, @@ -3087,7 +3087,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-tls-dfc5c7506ac1b172c8b7-wrr-0": { + "default-tls-app-1-my-gateway-tls-d5342d75658583f03593-wrr-0": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4780,6 +4780,11 @@ func Test_hostSNIRule(t *testing.T) { hostnames: []v1alpha2.Hostname{"*"}, expectError: true, }, + { + desc: "Supported wildcard", + hostnames: []v1alpha2.Hostname{"*.foo"}, + expectedRule: "HostSNIRegexp(`^[a-zA-Z0-9-]+\\.foo$`)", + }, { desc: "Multiple malformed wildcard", hostnames: []v1alpha2.Hostname{"*.foo.*"}, @@ -4788,7 +4793,7 @@ func Test_hostSNIRule(t *testing.T) { { desc: "Some empty hostnames", hostnames: []v1alpha2.Hostname{"foo", "", "bar"}, - expectedRule: "(HostSNI(`foo`) || HostSNI(`bar`))", + expectedRule: "HostSNI(`foo`) || HostSNI(`bar`)", }, { desc: "Valid hostname", @@ -4798,12 +4803,17 @@ func Test_hostSNIRule(t *testing.T) { { desc: "Multiple valid hostnames", hostnames: []v1alpha2.Hostname{"foo", "bar"}, - expectedRule: "(HostSNI(`foo`) || HostSNI(`bar`))", + expectedRule: "HostSNI(`foo`) || HostSNI(`bar`)", + }, + { + desc: "Multiple valid hostnames with wildcard", + hostnames: []v1alpha2.Hostname{"bar.foo", "foo.foo", "*.foo"}, + expectedRule: "HostSNI(`bar.foo`) || HostSNI(`foo.foo`) || HostSNIRegexp(`^[a-zA-Z0-9-]+\\.foo$`)", }, { desc: "Multiple overlapping hostnames", hostnames: []v1alpha2.Hostname{"foo", "bar", "foo", "baz"}, - expectedRule: "(HostSNI(`foo`) || HostSNI(`bar`) || HostSNI(`baz`))", + expectedRule: "HostSNI(`foo`) || HostSNI(`bar`) || HostSNI(`baz`)", }, } diff --git a/pkg/provider/marathon/builder_test.go b/pkg/provider/marathon/builder_test.go deleted file mode 100644 index e18110787..000000000 --- a/pkg/provider/marathon/builder_test.go +++ /dev/null @@ -1,205 +0,0 @@ -package marathon - -import ( - "strings" - "time" - - "github.com/gambol99/go-marathon" -) - -const testTaskName = "taskID" - -// Functions related to building applications. - -func withApplications(apps ...marathon.Application) *marathon.Applications { - return &marathon.Applications{Apps: apps} -} - -func application(ops ...func(*marathon.Application)) marathon.Application { - app := marathon.Application{} - app.EmptyLabels() - app.Deployments = []map[string]string{} - app.ReadinessChecks = &[]marathon.ReadinessCheck{} - app.ReadinessCheckResults = &[]marathon.ReadinessCheckResult{} - - for _, op := range ops { - op(&app) - } - - return app -} - -func appID(name string) func(*marathon.Application) { - return func(app *marathon.Application) { - app.Name(name) - } -} - -func appPorts(ports ...int) func(*marathon.Application) { - return func(app *marathon.Application) { - app.Ports = append(app.Ports, ports...) - } -} - -func withLabel(key, value string) func(*marathon.Application) { - return func(app *marathon.Application) { - app.AddLabel(key, value) - } -} - -func constraint(value string) func(*marathon.Application) { - return func(app *marathon.Application) { - app.AddConstraint(strings.Split(value, ":")...) - } -} - -func portDefinition(port int, name string) func(*marathon.Application) { - return func(app *marathon.Application) { - app.AddPortDefinition(marathon.PortDefinition{ - Port: &port, - Name: name, - }) - } -} - -func bridgeNetwork() func(*marathon.Application) { - return func(app *marathon.Application) { - app.SetNetwork("bridge", marathon.BridgeNetworkMode) - } -} - -func containerNetwork() func(*marathon.Application) { - return func(app *marathon.Application) { - app.SetNetwork("cni", marathon.ContainerNetworkMode) - } -} - -func ipAddrPerTask(port int) func(*marathon.Application) { - return func(app *marathon.Application) { - p := marathon.Port{ - Number: port, - Name: "port", - } - disc := marathon.Discovery{} - disc.AddPort(p) - ipAddr := marathon.IPAddressPerTask{} - ipAddr.SetDiscovery(disc) - app.SetIPAddressPerTask(ipAddr) - } -} - -func deployments(ids ...string) func(*marathon.Application) { - return func(app *marathon.Application) { - for _, id := range ids { - app.Deployments = append(app.Deployments, map[string]string{ - "ID": id, - }) - } - } -} - -func readinessCheck(timeout time.Duration) func(*marathon.Application) { - return func(app *marathon.Application) { - app.ReadinessChecks = &[]marathon.ReadinessCheck{ - { - Path: "/ready", - TimeoutSeconds: int(timeout.Seconds()), - }, - } - } -} - -func readinessCheckResult(taskID string, ready bool) func(*marathon.Application) { - return func(app *marathon.Application) { - *app.ReadinessCheckResults = append(*app.ReadinessCheckResults, marathon.ReadinessCheckResult{ - TaskID: taskID, - Ready: ready, - }) - } -} - -func withTasks(tasks ...marathon.Task) func(*marathon.Application) { - return func(application *marathon.Application) { - for _, task := range tasks { - tu := task - application.Tasks = append(application.Tasks, &tu) - } - } -} - -// Functions related to building tasks. - -func task(ops ...func(*marathon.Task)) marathon.Task { - t := &marathon.Task{ - ID: testTaskName, - // The vast majority of tests expect the task state to be TASK_RUNNING. - State: string(taskStateRunning), - } - - for _, op := range ops { - op(t) - } - - return *t -} - -func withTaskID(id string) func(*marathon.Task) { - return func(task *marathon.Task) { - task.ID = id - } -} - -func localhostTask(ops ...func(*marathon.Task)) marathon.Task { - t := task( - host("localhost"), - ipAddresses("127.0.0.1"), - taskState(taskStateRunning), - ) - - for _, op := range ops { - op(&t) - } - - return t -} - -func taskPorts(ports ...int) func(*marathon.Task) { - return func(t *marathon.Task) { - t.Ports = append(t.Ports, ports...) - } -} - -func taskState(state TaskState) func(*marathon.Task) { - return func(t *marathon.Task) { - t.State = string(state) - } -} - -func host(h string) func(*marathon.Task) { - return func(t *marathon.Task) { - t.Host = h - } -} - -func ipAddresses(addresses ...string) func(*marathon.Task) { - return func(t *marathon.Task) { - for _, addr := range addresses { - t.IPAddresses = append(t.IPAddresses, &marathon.IPAddress{ - IPAddress: addr, - Protocol: "tcp", - }) - } - } -} - -func startedAt(timestamp string) func(*marathon.Task) { - return func(t *marathon.Task) { - t.StartedAt = timestamp - } -} - -func startedAtFromNow(offset time.Duration) func(*marathon.Task) { - return func(t *marathon.Task) { - t.StartedAt = time.Now().Add(-offset).Format(time.RFC3339) - } -} diff --git a/pkg/provider/marathon/config.go b/pkg/provider/marathon/config.go deleted file mode 100644 index 5c7e0b059..000000000 --- a/pkg/provider/marathon/config.go +++ /dev/null @@ -1,473 +0,0 @@ -package marathon - -import ( - "context" - "errors" - "fmt" - "math" - "net" - "strconv" - "strings" - - "github.com/gambol99/go-marathon" - "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/label" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/constraints" -) - -func (p *Provider) buildConfiguration(ctx context.Context, applications *marathon.Applications) *dynamic.Configuration { - configurations := make(map[string]*dynamic.Configuration) - - for _, app := range applications.Apps { - logger := log.Ctx(ctx).With().Str("applicationID", app.ID).Logger() - ctxApp := logger.WithContext(ctx) - - extraConf, err := p.getConfiguration(app) - if err != nil { - logger.Error().Err(err).Msg("Skip application") - continue - } - - labels := stringValueMap(app.Labels) - - if app.Constraints != nil { - for i, constraintParts := range *app.Constraints { - key := constraints.MarathonConstraintPrefix + "-" + strconv.Itoa(i) - labels[key] = strings.Join(constraintParts, ":") - } - } - - if !p.keepApplication(ctxApp, extraConf, labels) { - continue - } - - confFromLabel, err := label.DecodeConfiguration(labels) - if err != nil { - logger.Error().Err(err).Send() - continue - } - - var tcpOrUDP bool - if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 { - tcpOrUDP = true - - err := p.buildTCPServiceConfiguration(ctxApp, app, extraConf, confFromLabel.TCP) - if err != nil { - logger.Error().Err(err).Send() - continue - } - provider.BuildTCPRouterConfiguration(ctxApp, confFromLabel.TCP) - } - - if len(confFromLabel.UDP.Routers) > 0 || len(confFromLabel.UDP.Services) > 0 { - tcpOrUDP = true - - err := p.buildUDPServiceConfiguration(ctxApp, app, extraConf, confFromLabel.UDP) - if err != nil { - logger.Error().Err(err).Send() - } else { - provider.BuildUDPRouterConfiguration(ctxApp, confFromLabel.UDP) - } - } - - if tcpOrUDP && len(confFromLabel.HTTP.Routers) == 0 && - len(confFromLabel.HTTP.Middlewares) == 0 && - len(confFromLabel.HTTP.Services) == 0 { - configurations[app.ID] = confFromLabel - continue - } - - err = p.buildServiceConfiguration(ctxApp, app, extraConf, confFromLabel.HTTP) - if err != nil { - logger.Error().Err(err).Send() - continue - } - - model := struct { - Name string - Labels map[string]string - }{ - Name: app.ID, - Labels: labels, - } - - serviceName := getServiceName(app) - - provider.BuildRouterConfiguration(ctxApp, confFromLabel.HTTP, serviceName, p.defaultRuleTpl, model) - - configurations[app.ID] = confFromLabel - } - - return provider.Merge(ctx, configurations) -} - -func getServiceName(app marathon.Application) string { - return strings.ReplaceAll(strings.TrimPrefix(app.ID, "/"), "/", "_") -} - -func (p *Provider) buildServiceConfiguration(ctx context.Context, app marathon.Application, extraConf configuration, conf *dynamic.HTTPConfiguration) error { - appName := getServiceName(app) - - logger := log.Ctx(ctx).With().Str("applicationName", appName).Logger() - - if len(conf.Services) == 0 { - conf.Services = make(map[string]*dynamic.Service) - lb := &dynamic.ServersLoadBalancer{} - lb.SetDefaults() - conf.Services[appName] = &dynamic.Service{ - LoadBalancer: lb, - } - } - - for serviceName, service := range conf.Services { - var servers []dynamic.Server - - defaultServer := dynamic.Server{} - defaultServer.SetDefaults() - - if len(service.LoadBalancer.Servers) > 0 { - defaultServer = service.LoadBalancer.Servers[0] - } - - for _, task := range app.Tasks { - if !p.taskFilter(ctx, *task, app) { - continue - } - server, err := p.getServer(app, *task, extraConf, defaultServer) - if err != nil { - logger.Error().Err(err).Msg("Skip task") - continue - } - servers = append(servers, server) - } - if len(servers) == 0 { - return fmt.Errorf("no server for the service %s", serviceName) - } - service.LoadBalancer.Servers = servers - } - - return nil -} - -func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, app marathon.Application, extraConf configuration, conf *dynamic.TCPConfiguration) error { - appName := getServiceName(app) - - logger := log.Ctx(ctx).With().Str("applicationName", appName).Logger() - - if len(conf.Services) == 0 { - conf.Services = map[string]*dynamic.TCPService{ - appName: { - LoadBalancer: new(dynamic.TCPServersLoadBalancer), - }, - } - } - - for serviceName, service := range conf.Services { - var servers []dynamic.TCPServer - - defaultServer := dynamic.TCPServer{} - - if len(service.LoadBalancer.Servers) > 0 { - defaultServer = service.LoadBalancer.Servers[0] - } - - for _, task := range app.Tasks { - if p.taskFilter(ctx, *task, app) { - server, err := p.getTCPServer(app, *task, extraConf, defaultServer) - if err != nil { - logger.Error().Err(err).Msg("Skip task") - continue - } - servers = append(servers, server) - } - } - if len(servers) == 0 { - return fmt.Errorf("no server for the service %s", serviceName) - } - service.LoadBalancer.Servers = servers - } - - return nil -} - -func (p *Provider) buildUDPServiceConfiguration(ctx context.Context, app marathon.Application, extraConf configuration, conf *dynamic.UDPConfiguration) error { - appName := getServiceName(app) - logger := log.Ctx(ctx).With().Str("applicationName", appName).Logger() - - if len(conf.Services) == 0 { - conf.Services = make(map[string]*dynamic.UDPService) - lb := &dynamic.UDPServersLoadBalancer{} - - conf.Services[appName] = &dynamic.UDPService{ - LoadBalancer: lb, - } - } - - for serviceName, service := range conf.Services { - var servers []dynamic.UDPServer - - defaultServer := dynamic.UDPServer{} - - if len(service.LoadBalancer.Servers) > 0 { - defaultServer = service.LoadBalancer.Servers[0] - } - - for _, task := range app.Tasks { - if p.taskFilter(ctx, *task, app) { - server, err := p.getUDPServer(app, *task, extraConf, defaultServer) - if err != nil { - logger.Error().Err(err).Msg("Skip task") - continue - } - servers = append(servers, server) - } - } - if len(servers) == 0 { - return fmt.Errorf("no server for the service %s", serviceName) - } - service.LoadBalancer.Servers = servers - } - - return nil -} - -func (p *Provider) keepApplication(ctx context.Context, extraConf configuration, labels map[string]string) bool { - logger := log.Ctx(ctx) - - // Filter disabled application. - if !extraConf.Enable { - logger.Debug().Msg("Filtering disabled Marathon application") - return false - } - - // Filter by constraints. - matches, err := constraints.MatchLabels(labels, p.Constraints) - if err != nil { - logger.Error().Err(err).Msg("Error matching constraints expression") - return false - } - if !matches { - logger.Debug().Msgf("Marathon application filtered by constraint expression: %q", p.Constraints) - return false - } - - return true -} - -func (p *Provider) taskFilter(ctx context.Context, task marathon.Task, application marathon.Application) bool { - if task.State != string(taskStateRunning) { - return false - } - - if ready := p.readyChecker.Do(task, application); !ready { - log.Ctx(ctx).Info().Msgf("Filtering unready task %s from application %s", task.ID, application.ID) - return false - } - - return true -} - -func (p *Provider) getTCPServer(app marathon.Application, task marathon.Task, extraConf configuration, defaultServer dynamic.TCPServer) (dynamic.TCPServer, error) { - host, err := p.getServerHost(task, app, extraConf) - if len(host) == 0 { - return dynamic.TCPServer{}, err - } - - port, err := getPort(task, app, defaultServer.Port) - if err != nil { - return dynamic.TCPServer{}, err - } - - server := dynamic.TCPServer{ - Address: net.JoinHostPort(host, port), - } - - return server, nil -} - -func (p *Provider) getUDPServer(app marathon.Application, task marathon.Task, extraConf configuration, defaultServer dynamic.UDPServer) (dynamic.UDPServer, error) { - host, err := p.getServerHost(task, app, extraConf) - if len(host) == 0 { - return dynamic.UDPServer{}, err - } - - port, err := getPort(task, app, defaultServer.Port) - if err != nil { - return dynamic.UDPServer{}, err - } - - server := dynamic.UDPServer{ - Address: net.JoinHostPort(host, port), - } - - return server, nil -} - -func (p *Provider) getServer(app marathon.Application, task marathon.Task, extraConf configuration, defaultServer dynamic.Server) (dynamic.Server, error) { - host, err := p.getServerHost(task, app, extraConf) - if len(host) == 0 { - return dynamic.Server{}, err - } - - port, err := getPort(task, app, defaultServer.Port) - if err != nil { - return dynamic.Server{}, err - } - - server := dynamic.Server{ - URL: fmt.Sprintf("%s://%s", defaultServer.Scheme, net.JoinHostPort(host, port)), - } - - return server, nil -} - -func (p *Provider) getServerHost(task marathon.Task, app marathon.Application, extraConf configuration) (string, error) { - networks := app.Networks - var hostFlag bool - - if networks == nil { - hostFlag = app.IPAddressPerTask == nil - } else { - hostFlag = (*networks)[0].Mode != marathon.ContainerNetworkMode - } - - if hostFlag || p.ForceTaskHostname { - if len(task.Host) == 0 { - return "", fmt.Errorf("host is undefined for task %q app %q", task.ID, app.ID) - } - return task.Host, nil - } - - numTaskIPAddresses := len(task.IPAddresses) - switch numTaskIPAddresses { - case 0: - return "", fmt.Errorf("missing IP address for Marathon application %s on task %s", app.ID, task.ID) - case 1: - return task.IPAddresses[0].IPAddress, nil - default: - if extraConf.Marathon.IPAddressIdx == math.MinInt32 { - return "", fmt.Errorf("found %d task IP addresses but missing IP address index for Marathon application %s on task %s", - numTaskIPAddresses, app.ID, task.ID) - } - if extraConf.Marathon.IPAddressIdx < 0 || extraConf.Marathon.IPAddressIdx > numTaskIPAddresses { - return "", fmt.Errorf("cannot use IP address index to select from %d task IP addresses for Marathon application %s on task %s", - numTaskIPAddresses, app.ID, task.ID) - } - - return task.IPAddresses[extraConf.Marathon.IPAddressIdx].IPAddress, nil - } -} - -func getPort(task marathon.Task, app marathon.Application, serverPort string) (string, error) { - port, err := processPorts(app, task, serverPort) - if err != nil { - return "", fmt.Errorf("unable to process ports for %s %s: %w", app.ID, task.ID, err) - } - - return strconv.Itoa(port), nil -} - -// processPorts returns the configured port. -// An explicitly specified port is preferred. If none is specified, it selects -// one of the available port. The first such found port is returned unless an -// optional index is provided. -func processPorts(app marathon.Application, task marathon.Task, serverPort string) (int, error) { - if len(serverPort) > 0 && !(strings.HasPrefix(serverPort, "index:") || strings.HasPrefix(serverPort, "name:")) { - port, err := strconv.Atoi(serverPort) - if err != nil { - return 0, err - } - - if port <= 0 { - return 0, fmt.Errorf("explicitly specified port %d must be greater than zero", port) - } else if port > 0 { - return port, nil - } - } - - if strings.HasPrefix(serverPort, "name:") { - name := strings.TrimPrefix(serverPort, "name:") - port := retrieveNamedPort(app, name) - - if port == 0 { - return 0, fmt.Errorf("no port with name %s", name) - } - - return port, nil - } - - ports := retrieveAvailablePorts(app, task) - if len(ports) == 0 { - return 0, errors.New("no port found") - } - - portIndex := 0 - if strings.HasPrefix(serverPort, "index:") { - indexString := strings.TrimPrefix(serverPort, "index:") - index, err := strconv.Atoi(indexString) - if err != nil { - return 0, err - } - - if index < 0 || index > len(ports)-1 { - return 0, fmt.Errorf("index %d must be within range (0, %d)", index, len(ports)-1) - } - - portIndex = index - } - - return ports[portIndex], nil -} - -func retrieveNamedPort(app marathon.Application, name string) int { - // Using port definition if available - if app.PortDefinitions != nil && len(*app.PortDefinitions) > 0 { - for _, def := range *app.PortDefinitions { - if def.Port != nil && *def.Port > 0 && def.Name == name { - return *def.Port - } - } - } - - // If using IP-per-task using this port definition - if app.IPAddressPerTask != nil && app.IPAddressPerTask.Discovery != nil && len(*(app.IPAddressPerTask.Discovery.Ports)) > 0 { - for _, def := range *(app.IPAddressPerTask.Discovery.Ports) { - if def.Number > 0 && def.Name == name { - return def.Number - } - } - } - - return 0 -} - -func retrieveAvailablePorts(app marathon.Application, task marathon.Task) []int { - // Using default port configuration - if len(task.Ports) > 0 { - return task.Ports - } - - // Using port definition if available - if app.PortDefinitions != nil && len(*app.PortDefinitions) > 0 { - var ports []int - for _, def := range *app.PortDefinitions { - if def.Port != nil { - ports = append(ports, *def.Port) - } - } - return ports - } - - // If using IP-per-task using this port definition - if app.IPAddressPerTask != nil && app.IPAddressPerTask.Discovery != nil && len(*(app.IPAddressPerTask.Discovery.Ports)) > 0 { - var ports []int - for _, def := range *(app.IPAddressPerTask.Discovery.Ports) { - ports = append(ports, def.Number) - } - return ports - } - - return []int{} -} diff --git a/pkg/provider/marathon/config_test.go b/pkg/provider/marathon/config_test.go deleted file mode 100644 index 8648c7e84..000000000 --- a/pkg/provider/marathon/config_test.go +++ /dev/null @@ -1,2447 +0,0 @@ -package marathon - -import ( - "context" - "math" - "testing" - "time" - - "github.com/gambol99/go-marathon" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" -) - -func Int(v int) *int { return &v } -func Bool(v bool) *bool { return &v } - -func TestGetConfigurationAPIErrors(t *testing.T) { - fakeClient := newFakeClient(true, marathon.Applications{}) - - p := &Provider{ - marathonClient: fakeClient, - } - - actualConfig := p.getConfigurations(context.Background()) - fakeClient.AssertExpectations(t) - - if actualConfig != nil { - t.Errorf("configuration should have been nil, got %v", actualConfig) - } -} - -func TestBuildConfiguration(t *testing.T) { - testCases := []struct { - desc string - applications *marathon.Applications - constraints string - defaultRule string - expected *dynamic.Configuration - }{ - { - desc: "simple application", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "filtered task", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80), taskState(taskStateStaging))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "multiple ports", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "with basic auth", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - withLabel("traefik.http.middlewares.Middleware1.basicauth.users", "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), - withLabel("traefik.http.routers.app.middlewares", "Middleware1"), - withTasks(localhostTask(taskPorts(80))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - Middlewares: []string{"Middleware1"}, - }, - }, - Middlewares: map[string]*dynamic.Middleware{ - "Middleware1": { - BasicAuth: &dynamic.BasicAuth{ - Users: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - }, - }, - }, - Services: map[string]*dynamic.Service{ - "app": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "TCP with IP allowlist", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - - withLabel("traefik.tcp.routers.Test.rule", "HostSNI(`foo.bar`)"), - withLabel("traefik.tcp.middlewares.Middleware1.ipallowlist.sourcerange", "foobar, fiibar"), - withLabel("traefik.tcp.routers.Test.middlewares", "Middleware1"), - withTasks(localhostTask(taskPorts(80))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "Test": { - Service: "app", - Rule: "HostSNI(`foo.bar`)", - Middlewares: []string{"Middleware1"}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{ - "Middleware1": { - IPAllowList: &dynamic.TCPIPAllowList{ - SourceRange: []string{"foobar", "fiibar"}, - }, - }, - }, - Services: map[string]*dynamic.TCPService{ - "app": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:80", - }, - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "2 applications in the same service", - applications: withApplications( - application( - appID("/foo-v000"), - withTasks(localhostTask(taskPorts(8080))), - - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"), - withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"), - ), - application( - appID("/foo-v001"), - withTasks(localhostTask(taskPorts(8081))), - - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"), - withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"), - ), - ), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:8080", - }, - { - URL: "http://localhost:8081", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "2 applications with 2 tasks in the same service", - applications: withApplications( - application( - appID("/foo-v000"), - withTasks(localhostTask(taskPorts(8080))), - withTasks(localhostTask(taskPorts(8081))), - - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"), - withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"), - ), - application( - appID("/foo-v001"), - withTasks(localhostTask(taskPorts(8082))), - withTasks(localhostTask(taskPorts(8083))), - - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"), - withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"), - ), - ), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:8080", - }, - { - URL: "http://localhost:8081", - }, - { - URL: "http://localhost:8082", - }, - { - URL: "http://localhost:8083", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "2 applications", - applications: withApplications( - application( - appID("/foo"), - withTasks(localhostTask(taskPorts(8080))), - ), - application( - appID("/bar"), - withTasks(localhostTask(taskPorts(8081))), - ), - ), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "foo": { - Service: "foo", - Rule: "Host(`foo.marathon.localhost`)", - }, - "bar": { - Service: "bar", - Rule: "Host(`bar.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "foo": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:8080", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - "bar": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:8081", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two tasks no labels", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80)), localhostTask(taskPorts(81))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - { - URL: "http://localhost:81", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "simple application with label on service", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "Service1", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with labels", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.routers.Router1.service", "Service1"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`foo.com`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with rule label", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "app", - Rule: "Host(`foo.com`)", - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with rule label and one service", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`foo.com`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with rule label and two services", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), - withLabel("traefik.http.services.Service2.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "Service2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with same service name and different passhostheader", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "false"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "Service1", - Rule: "Host(`app.marathon.localhost`)", - }, - "app2": { - Service: "Service1", - Rule: "Host(`app2.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with two identical middleware", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.middlewares.Middleware1.inflightreq.amount", "42"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.middlewares.Middleware1.inflightreq.amount", "42"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - "app2": { - Service: "app2", - Rule: "Host(`app2.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{ - "Middleware1": { - InFlightReq: &dynamic.InFlightReq{ - Amount: 42, - }, - }, - }, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "app2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with two different middlewares", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.middlewares.Middleware1.inflightreq.amount", "42"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.middlewares.Middleware1.inflightreq.amount", "41"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - "app2": { - Service: "app2", - Rule: "Host(`app2.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "app2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with two different routers with same name", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`bar.com`)"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "app2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with two identical routers with same name", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.LoadBalancer.passhostheader", "true"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.LoadBalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`foo.com`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with two identical routers with same name", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "app2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with wrong label", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.wrong.label", "tchouk"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with label port", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.LoadBalancer.server.scheme", "h2c"), - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "90"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "Service1", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "h2c://localhost:90", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with label port on two services", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", ""), - withLabel("traefik.http.services.Service2.LoadBalancer.server.port", "8080"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "Service2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:8080", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app without port", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask()), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app without port with middleware", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask()), - withLabel("traefik.http.middlewares.Middleware1.basicauth.users", "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with traefik.enable=false", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask()), - withLabel("traefik.enable", "false"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with traefik.enable=false", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask()), - withLabel("traefik.enable", "false"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with non matching constraint", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tags", "foo"), - )), - constraints: `Label("traefik.tags", "bar")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with non matching marathon constraint", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - constraint("rack_id:CLUSTER:rack-1"), - )), - constraints: `MarathonConstraint("rack_id:CLUSTER:rack-2")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with matching marathon constraint", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - constraint("rack_id:CLUSTER:rack-1"), - )), - constraints: `MarathonConstraint("rack_id:CLUSTER:rack-1")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with matching constraint", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tags", "bar"), - )), - constraints: `Label("traefik.tags", "bar")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with group as subdomain rule", - defaultRule: `Host("{{ .Name | trimPrefix "/" | splitList "/" | strsToItfs | reverse | join "." }}.marathon.localhost")`, - applications: withApplications( - application( - appID("/a/b/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "a_b_app": { - Service: "a_b_app", - Rule: `Host("app.b.a.marathon.localhost")`, - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "a_b_app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with tcp labels", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tcp.routers.foo.rule", "HostSNI(`foo.bar`)"), - withLabel("traefik.tcp.routers.foo.tls", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "app", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "app": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:80", - }, - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with udp labels", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.udp.routers.foo.entrypoints", "mydns"), - )), - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "app", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "app": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "localhost:80", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with tcp labels without rule", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tcp.routers.foo.tls", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "app": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:80", - }, - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with tcp labels with port", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tcp.routers.foo.rule", "HostSNI(`foo.bar`)"), - withLabel("traefik.tcp.routers.foo.tls", "true"), - withLabel("traefik.tcp.services.foo.loadbalancer.server.port", "8080"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "foo", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:8080", - }, - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with udp labels with port", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.udp.routers.foo.entrypoints", "mydns"), - withLabel("traefik.udp.services.foo.loadbalancer.server.port", "8080"), - )), - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "foo", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "foo": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "localhost:8080", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - // TODO: replace or delete? - desc: "one app with tcp labels with port, with termination delay", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tcp.routers.foo.rule", "HostSNI(`foo.bar`)"), - withLabel("traefik.tcp.routers.foo.tls", "true"), - withLabel("traefik.tcp.services.foo.loadbalancer.server.port", "8080"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "foo", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:8080", - }, - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with tcp labels with port and http service", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tcp.routers.foo.rule", "HostSNI(`foo.bar`)"), - withLabel("traefik.tcp.routers.foo.tls", "true"), - withLabel("traefik.tcp.services.foo.loadbalancer.server.port", "8080"), - withLabel("traefik.http.services.bar.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "foo", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:8080", - }, - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "bar", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "bar": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with udp labels with port and http service", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.udp.routers.foo.entrypoints", "mydns"), - withLabel("traefik.udp.services.foo.loadbalancer.server.port", "8080"), - withLabel("traefik.http.services.bar.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "foo", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "foo": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "localhost:8080", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: map[string]*dynamic.TCPServersTransport{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "bar", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "bar": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - defaultRule := "Host(`{{ normalize .Name }}.marathon.localhost`)" - if len(test.defaultRule) > 0 { - defaultRule = test.defaultRule - } - - p := &Provider{ - DefaultRule: defaultRule, - ExposedByDefault: true, - } - p.Constraints = test.constraints - - err := p.Init() - require.NoError(t, err) - - actualConfig := p.buildConfiguration(context.Background(), test.applications) - - assert.NotNil(t, actualConfig) - assert.Equal(t, test.expected, actualConfig) - }) - } -} - -func TestApplicationFilterEnabled(t *testing.T) { - testCases := []struct { - desc string - exposedByDefault bool - enabledLabel string - expected bool - }{ - { - desc: "exposed and tolerated by valid label value", - exposedByDefault: true, - enabledLabel: "true", - expected: true, - }, - { - desc: "exposed but overridden by label", - exposedByDefault: true, - enabledLabel: "false", - expected: false, - }, - { - desc: "non-exposed but overridden by label", - exposedByDefault: false, - enabledLabel: "true", - expected: true, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - provider := &Provider{ExposedByDefault: true} - - app := application(withLabel("traefik.enable", test.enabledLabel)) - - extraConf, err := provider.getConfiguration(app) - require.NoError(t, err) - - if provider.keepApplication(context.Background(), extraConf, stringValueMap(app.Labels)) != test.expected { - t.Errorf("got unexpected filtering = %t", !test.expected) - } - }) - } -} - -func TestGetServer(t *testing.T) { - type expected struct { - server dynamic.Server - error string - } - - testCases := []struct { - desc string - provider Provider - app marathon.Application - extraConf configuration - defaultServer dynamic.Server - expected expected - }{ - { - desc: "undefined host", - provider: Provider{}, - app: application(), - extraConf: configuration{}, - defaultServer: dynamic.Server{}, - expected: expected{ - error: `host is undefined for task "taskID" app ""`, - }, - }, - { - desc: "with task port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:80", - }, - }, - }, - { - desc: "without task port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask()), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - error: "unable to process ports for /app taskID: no port found", - }, - }, - { - desc: "with default server port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "88", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:88", - }, - }, - }, - { - desc: "with invalid default server port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "aaaa", - }, - expected: expected{ - error: `unable to process ports for /app taskID: strconv.Atoi: parsing "aaaa": invalid syntax`, - }, - }, - { - desc: "with negative default server port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "-6", - }, - expected: expected{ - error: `unable to process ports for /app taskID: explicitly specified port -6 must be greater than zero`, - }, - }, - { - desc: "with port index", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80, 81))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "index:1", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:81", - }, - }, - }, - { - desc: "with out of range port index", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80, 81))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "index:2", - }, - expected: expected{ - error: "unable to process ports for /app taskID: index 2 must be within range (0, 1)", - }, - }, - { - desc: "with invalid port index", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80, 81))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "index:aaa", - }, - expected: expected{ - error: `unable to process ports for /app taskID: strconv.Atoi: parsing "aaa": invalid syntax`, - }, - }, - { - desc: "with port name", - provider: Provider{}, - app: application( - appID("/app"), - portDefinition(80, "fist-port"), - portDefinition(81, "second-port"), - portDefinition(82, "third-port"), - withTasks(localhostTask()), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "name:third-port", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:82", - }, - }, - }, - { - desc: "with port name not found", - provider: Provider{}, - app: application( - appID("/app"), - portDefinition(80, "fist-port"), - portDefinition(81, "second-port"), - portDefinition(82, "third-port"), - withTasks(localhostTask()), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "name:other-name", - }, - expected: expected{ - error: `unable to process ports for /app taskID: no port with name other-name`, - }, - }, - { - desc: "with application port and no task port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - portDefinition(80, "http"), - withTasks(localhostTask()), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:80", - }, - }, - }, - { - desc: "with IP per task", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - ipAddrPerTask(88), - withTasks(localhostTask()), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://127.0.0.1:88", - }, - }, - }, - { - desc: "with container network", - provider: Provider{}, - app: application( - containerNetwork(), - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80, 81))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://127.0.0.1:80", - }, - }, - }, - { - desc: "with bridge network", - provider: Provider{}, - app: application( - bridgeNetwork(), - appID("/app"), - appPorts(83), - withTasks(localhostTask(taskPorts(80, 81))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:80", - }, - }, - }, - { - desc: "with several IP addresses on task", - provider: Provider{}, - app: application( - ipAddrPerTask(88), - appID("/app"), - appPorts(83), - withTasks( - task( - withTaskID("myTask"), - host("localhost"), - ipAddresses("127.0.0.1", "127.0.0.2"), - taskState(taskStateRunning), - )), - ), - extraConf: configuration{ - Marathon: specificConfiguration{ - IPAddressIdx: 0, - }, - }, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://127.0.0.1:88", - }, - }, - }, - { - desc: "with several IP addresses on task, undefined [MinInt32] IPAddressIdx", - provider: Provider{}, - app: application( - ipAddrPerTask(88), - appID("/app"), - appPorts(83), - withTasks( - task( - host("localhost"), - ipAddresses("127.0.0.1", "127.0.0.2"), - taskState(taskStateRunning), - )), - ), - extraConf: configuration{ - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - error: "found 2 task IP addresses but missing IP address index for Marathon application /app on task taskID", - }, - }, - { - desc: "with several IP addresses on task, IPAddressIdx out of range", - provider: Provider{}, - app: application( - ipAddrPerTask(88), - appID("/app"), - appPorts(83), - withTasks( - task( - host("localhost"), - ipAddresses("127.0.0.1", "127.0.0.2"), - taskState(taskStateRunning), - )), - ), - extraConf: configuration{ - Marathon: specificConfiguration{ - IPAddressIdx: 3, - }, - }, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - error: "cannot use IP address index to select from 2 task IP addresses for Marathon application /app on task taskID", - }, - }, - { - desc: "with task without IP address", - provider: Provider{}, - app: application( - ipAddrPerTask(88), - appID("/app"), - appPorts(83), - withTasks( - task( - host("localhost"), - taskState(taskStateRunning), - )), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - error: "missing IP address for Marathon application /app on task taskID", - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - task := task() - if len(test.app.Tasks) > 0 { - task = *test.app.Tasks[0] - } - - server, err := test.provider.getServer(test.app, task, test.extraConf, test.defaultServer) - if len(test.expected.error) > 0 { - require.EqualError(t, err, test.expected.error) - } else { - require.NoError(t, err) - - assert.Equal(t, test.expected.server, server) - } - }) - } -} diff --git a/pkg/provider/marathon/fake_client_test.go b/pkg/provider/marathon/fake_client_test.go deleted file mode 100644 index c30941482..000000000 --- a/pkg/provider/marathon/fake_client_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package marathon - -import ( - "errors" - - "github.com/gambol99/go-marathon" - "github.com/stretchr/testify/mock" - "github.com/traefik/traefik/v2/pkg/provider/marathon/mocks" -) - -type fakeClient struct { - mocks.Marathon -} - -func newFakeClient(applicationsError bool, applications marathon.Applications) *fakeClient { - // create an instance of our test object - fakeClient := new(fakeClient) - if applicationsError { - fakeClient.On("Applications", mock.Anything).Return(nil, errors.New("fake Marathon server error")) - } else { - fakeClient.On("Applications", mock.Anything).Return(&applications, nil) - } - return fakeClient -} diff --git a/pkg/provider/marathon/label.go b/pkg/provider/marathon/label.go deleted file mode 100644 index f6da87870..000000000 --- a/pkg/provider/marathon/label.go +++ /dev/null @@ -1,42 +0,0 @@ -package marathon - -import ( - "math" - - "github.com/gambol99/go-marathon" - "github.com/traefik/traefik/v2/pkg/config/label" -) - -type configuration struct { - Enable bool - Marathon specificConfiguration -} - -type specificConfiguration struct { - IPAddressIdx int -} - -func (p *Provider) getConfiguration(app marathon.Application) (configuration, error) { - labels := stringValueMap(app.Labels) - - conf := configuration{ - Enable: p.ExposedByDefault, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - } - - err := label.Decode(labels, &conf, "traefik.marathon.", "traefik.enable") - if err != nil { - return configuration{}, err - } - - return conf, nil -} - -func stringValueMap(mp *map[string]string) map[string]string { - if mp != nil { - return *mp - } - return make(map[string]string) -} diff --git a/pkg/provider/marathon/label_test.go b/pkg/provider/marathon/label_test.go deleted file mode 100644 index 472b91d23..000000000 --- a/pkg/provider/marathon/label_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package marathon - -import ( - "math" - "testing" - - "github.com/gambol99/go-marathon" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestGetConfiguration(t *testing.T) { - testCases := []struct { - desc string - app marathon.Application - p Provider - expected configuration - }{ - { - desc: "Empty labels", - app: marathon.Application{ - Constraints: &[][]string{}, - Labels: &map[string]string{}, - }, - p: Provider{ - ExposedByDefault: false, - }, - expected: configuration{ - Enable: false, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - }, - { - desc: "label enable", - app: marathon.Application{ - Constraints: &[][]string{}, - Labels: &map[string]string{ - "traefik.enable": "true", - }, - }, - p: Provider{ - ExposedByDefault: false, - }, - expected: configuration{ - Enable: true, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - }, - { - desc: "Use ip address index", - app: marathon.Application{ - Constraints: &[][]string{}, - Labels: &map[string]string{ - "traefik.marathon.IPAddressIdx": "4", - }, - }, - p: Provider{ - ExposedByDefault: false, - }, - expected: configuration{ - Enable: false, - Marathon: specificConfiguration{ - IPAddressIdx: 4, - }, - }, - }, - { - desc: "Use marathon constraints", - app: marathon.Application{ - Constraints: &[][]string{ - {"key", "value"}, - }, - Labels: &map[string]string{}, - }, - p: Provider{ - ExposedByDefault: false, - }, - expected: configuration{ - Enable: false, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - }, - { - desc: "ExposedByDefault and no enable label", - app: marathon.Application{ - Constraints: &[][]string{}, - Labels: &map[string]string{}, - }, - p: Provider{ - ExposedByDefault: true, - }, - expected: configuration{ - Enable: true, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - }, - { - desc: "ExposedByDefault and enable label false", - app: marathon.Application{ - Constraints: &[][]string{}, - Labels: &map[string]string{ - "traefik.enable": "false", - }, - }, - p: Provider{ - ExposedByDefault: true, - }, - expected: configuration{ - Enable: false, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - extraConf, err := test.p.getConfiguration(test.app) - require.NoError(t, err) - - assert.Equal(t, test.expected, extraConf) - }) - } -} diff --git a/pkg/provider/marathon/marathon.go b/pkg/provider/marathon/marathon.go deleted file mode 100644 index d4e8cccd8..000000000 --- a/pkg/provider/marathon/marathon.go +++ /dev/null @@ -1,221 +0,0 @@ -package marathon - -import ( - "context" - "fmt" - "net" - "net/http" - "net/url" - "text/template" - "time" - - "github.com/cenkalti/backoff/v4" - "github.com/gambol99/go-marathon" - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" - ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" -) - -const ( - // DefaultTemplateRule The default template for the default rule. - DefaultTemplateRule = "Host(`{{ normalize .Name }}`)" - marathonEventIDs = marathon.EventIDApplications | - marathon.EventIDAddHealthCheck | - marathon.EventIDDeploymentSuccess | - marathon.EventIDDeploymentFailed | - marathon.EventIDDeploymentInfo | - marathon.EventIDDeploymentStepSuccess | - marathon.EventIDDeploymentStepFailed -) - -// TaskState denotes the Mesos state a task can have. -type TaskState string - -const ( - taskStateRunning TaskState = "TASK_RUNNING" - taskStateStaging TaskState = "TASK_STAGING" -) - -var _ provider.Provider = (*Provider)(nil) - -// Provider holds configuration of the provider. -type Provider struct { - Constraints string `description:"Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` - Trace bool `description:"Display additional provider logs." json:"trace,omitempty" toml:"trace,omitempty" yaml:"trace,omitempty" export:"true"` - Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"` - Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"` - DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` - ExposedByDefault bool `description:"Expose Marathon apps by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` - DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header." json:"dcosToken,omitempty" toml:"dcosToken,omitempty" yaml:"dcosToken,omitempty" loggable:"false"` - TLS *types.ClientTLS `description:"Enable TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"` - DialerTimeout ptypes.Duration `description:"Set a dialer timeout for Marathon." json:"dialerTimeout,omitempty" toml:"dialerTimeout,omitempty" yaml:"dialerTimeout,omitempty" export:"true"` - ResponseHeaderTimeout ptypes.Duration `description:"Set a response header timeout for Marathon." json:"responseHeaderTimeout,omitempty" toml:"responseHeaderTimeout,omitempty" yaml:"responseHeaderTimeout,omitempty" export:"true"` - TLSHandshakeTimeout ptypes.Duration `description:"Set a TLS handshake timeout for Marathon." json:"tlsHandshakeTimeout,omitempty" toml:"tlsHandshakeTimeout,omitempty" yaml:"tlsHandshakeTimeout,omitempty" export:"true"` - KeepAlive ptypes.Duration `description:"Set a TCP Keep Alive time." json:"keepAlive,omitempty" toml:"keepAlive,omitempty" yaml:"keepAlive,omitempty" export:"true"` - ForceTaskHostname bool `description:"Force to use the task's hostname." json:"forceTaskHostname,omitempty" toml:"forceTaskHostname,omitempty" yaml:"forceTaskHostname,omitempty" export:"true"` - Basic *Basic `description:"Enable basic authentication." json:"basic,omitempty" toml:"basic,omitempty" yaml:"basic,omitempty" export:"true"` - RespectReadinessChecks bool `description:"Filter out tasks with non-successful readiness checks during deployments." json:"respectReadinessChecks,omitempty" toml:"respectReadinessChecks,omitempty" yaml:"respectReadinessChecks,omitempty" export:"true"` - readyChecker *readinessChecker - marathonClient marathon.Marathon - defaultRuleTpl *template.Template -} - -// SetDefaults sets the default values. -func (p *Provider) SetDefaults() { - p.Watch = true - p.Endpoint = "http://127.0.0.1:8080" - p.ExposedByDefault = true - p.DialerTimeout = ptypes.Duration(5 * time.Second) - p.ResponseHeaderTimeout = ptypes.Duration(60 * time.Second) - p.TLSHandshakeTimeout = ptypes.Duration(5 * time.Second) - p.KeepAlive = ptypes.Duration(10 * time.Second) - p.DefaultRule = DefaultTemplateRule -} - -// Basic holds basic authentication specific configurations. -type Basic struct { - HTTPBasicAuthUser string `description:"Basic authentication User." json:"httpBasicAuthUser,omitempty" toml:"httpBasicAuthUser,omitempty" yaml:"httpBasicAuthUser,omitempty" loggable:"false"` - HTTPBasicPassword string `description:"Basic authentication Password." json:"httpBasicPassword,omitempty" toml:"httpBasicPassword,omitempty" yaml:"httpBasicPassword,omitempty" loggable:"false"` -} - -// Init the provider. -func (p *Provider) Init() error { - fm := template.FuncMap{ - "strsToItfs": func(values []string) []interface{} { - var r []interface{} - for _, v := range values { - r = append(r, v) - } - return r - }, - } - - defaultRuleTpl, err := provider.MakeDefaultRuleTemplate(p.DefaultRule, fm) - if err != nil { - return fmt.Errorf("error while parsing default rule: %w", err) - } - - p.defaultRuleTpl = defaultRuleTpl - return nil -} - -// Provide allows the marathon provider to provide configurations to traefik -// using the given configuration channel. -func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error { - logger := log.With().Str(logs.ProviderName, "marathon").Logger() - ctx := logger.WithContext(context.Background()) - - operation := func() error { - confg := marathon.NewDefaultConfig() - confg.URL = p.Endpoint - confg.EventsTransport = marathon.EventsTransportSSE - - if p.Trace { - confg.LogOutput = logs.NoLevel(logger, zerolog.DebugLevel) - } - - if p.Basic != nil { - confg.HTTPBasicAuthUser = p.Basic.HTTPBasicAuthUser - confg.HTTPBasicPassword = p.Basic.HTTPBasicPassword - } - var rc *readinessChecker - if p.RespectReadinessChecks { - logger.Debug().Msg("Enabling Marathon readiness checker") - rc = defaultReadinessChecker(p.Trace) - } - p.readyChecker = rc - - if len(p.DCOSToken) > 0 { - confg.DCOSToken = p.DCOSToken - } - TLSConfig, err := p.TLS.CreateTLSConfig(ctx) - if err != nil { - return fmt.Errorf("unable to create client TLS configuration: %w", err) - } - confg.HTTPClient = &http.Client{ - Transport: &http.Transport{ - DialContext: (&net.Dialer{ - KeepAlive: time.Duration(p.KeepAlive), - Timeout: time.Duration(p.DialerTimeout), - }).DialContext, - ResponseHeaderTimeout: time.Duration(p.ResponseHeaderTimeout), - TLSHandshakeTimeout: time.Duration(p.TLSHandshakeTimeout), - TLSClientConfig: TLSConfig, - }, - } - client, err := marathon.NewClient(confg) - if err != nil { - logger.Error().Err(err).Msg("Failed to create a client for marathon") - return err - } - p.marathonClient = client - - if p.Watch { - update, err := client.AddEventsListener(marathonEventIDs) - if err != nil { - logger.Error().Err(err).Msg("Failed to register for events") - return err - } - pool.GoCtx(func(ctxPool context.Context) { - defer close(update) - for { - select { - case <-ctxPool.Done(): - return - case event := <-update: - logger.Debug().Msgf("Received provider event %s", event) - - conf := p.getConfigurations(ctx) - if conf != nil { - configurationChan <- dynamic.Message{ - ProviderName: "marathon", - Configuration: conf, - } - } - } - } - }) - } - - configuration := p.getConfigurations(ctx) - configurationChan <- dynamic.Message{ - ProviderName: "marathon", - Configuration: configuration, - } - return nil - } - - notify := func(err error, time time.Duration) { - logger.Error().Err(err).Msgf("Provider error, retrying in %s", time) - } - err := backoff.RetryNotify(safe.OperationWithRecover(operation), backoff.WithContext(job.NewBackOff(backoff.NewExponentialBackOff()), ctx), notify) - if err != nil { - logger.Error().Err(err).Msg("Cannot retrieve data") - } - return nil -} - -func (p *Provider) getConfigurations(ctx context.Context) *dynamic.Configuration { - applications, err := p.getApplications() - if err != nil { - log.Ctx(ctx).Error().Err(err).Msg("Failed to retrieve Marathon applications") - return nil - } - - return p.buildConfiguration(ctx, applications) -} - -func (p *Provider) getApplications() (*marathon.Applications, error) { - v := url.Values{} - v.Add("embed", "apps.tasks") - v.Add("embed", "apps.deployments") - v.Add("embed", "apps.readiness") - - return p.marathonClient.Applications(v) -} diff --git a/pkg/provider/marathon/mocks/Marathon.go b/pkg/provider/marathon/mocks/Marathon.go deleted file mode 100644 index d2506bc79..000000000 --- a/pkg/provider/marathon/mocks/Marathon.go +++ /dev/null @@ -1,1286 +0,0 @@ -// Package mocks Code generated by mockery v1.0.0. DO NOT EDIT. -// mockery -recursive -dir=vendor/github.com/gambol99/ -name=Marathon -output=provider/marathon/mocks -package mocks - -import ( - "net/url" - "time" - - "github.com/gambol99/go-marathon" - "github.com/stretchr/testify/mock" -) - -// Marathon is an autogenerated mock type for the Marathon type -type Marathon struct { - mock.Mock -} - -// AbdicateLeader provides a mock function with given fields: -func (_m *Marathon) AbdicateLeader() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// AddEventsListener provides a mock function with given fields: filter -func (_m *Marathon) AddEventsListener(filter int) (marathon.EventsChannel, error) { - ret := _m.Called(filter) - - var r0 marathon.EventsChannel - if rf, ok := ret.Get(0).(func(int) marathon.EventsChannel); ok { - r0 = rf(filter) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(marathon.EventsChannel) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(int) error); ok { - r1 = rf(filter) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// AllTasks provides a mock function with given fields: opts -func (_m *Marathon) AllTasks(opts *marathon.AllTasksOpts) (*marathon.Tasks, error) { - ret := _m.Called(opts) - - var r0 *marathon.Tasks - if rf, ok := ret.Get(0).(func(*marathon.AllTasksOpts) *marathon.Tasks); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Tasks) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.AllTasksOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Application provides a mock function with given fields: name -func (_m *Marathon) Application(name string) (*marathon.Application, error) { - ret := _m.Called(name) - - var r0 *marathon.Application - if rf, ok := ret.Get(0).(func(string) *marathon.Application); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Application) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ApplicationBy provides a mock function with given fields: name, opts -func (_m *Marathon) ApplicationBy(name string, opts *marathon.GetAppOpts) (*marathon.Application, error) { - ret := _m.Called(name, opts) - - var r0 *marathon.Application - if rf, ok := ret.Get(0).(func(string, *marathon.GetAppOpts) *marathon.Application); ok { - r0 = rf(name, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Application) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.GetAppOpts) error); ok { - r1 = rf(name, opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ApplicationByVersion provides a mock function with given fields: name, version -func (_m *Marathon) ApplicationByVersion(name, version string) (*marathon.Application, error) { - ret := _m.Called(name, version) - - var r0 *marathon.Application - if rf, ok := ret.Get(0).(func(string, string) *marathon.Application); ok { - r0 = rf(name, version) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Application) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(name, version) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ApplicationDeployments provides a mock function with given fields: name -func (_m *Marathon) ApplicationDeployments(name string) ([]*marathon.DeploymentID, error) { - ret := _m.Called(name) - - var r0 []*marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string) []*marathon.DeploymentID); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ApplicationOK provides a mock function with given fields: name -func (_m *Marathon) ApplicationOK(name string) (bool, error) { - ret := _m.Called(name) - - var r0 bool - if rf, ok := ret.Get(0).(func(string) bool); ok { - r0 = rf(name) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ApplicationVersions provides a mock function with given fields: name -func (_m *Marathon) ApplicationVersions(name string) (*marathon.ApplicationVersions, error) { - ret := _m.Called(name) - - var r0 *marathon.ApplicationVersions - if rf, ok := ret.Get(0).(func(string) *marathon.ApplicationVersions); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.ApplicationVersions) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Applications provides a mock function with given fields: _a0 -func (_m *Marathon) Applications(_a0 url.Values) (*marathon.Applications, error) { - ret := _m.Called(_a0) - - var r0 *marathon.Applications - if rf, ok := ret.Get(0).(func(url.Values) *marathon.Applications); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Applications) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(url.Values) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CreateApplication provides a mock function with given fields: application -func (_m *Marathon) CreateApplication(application *marathon.Application) (*marathon.Application, error) { - ret := _m.Called(application) - - var r0 *marathon.Application - if rf, ok := ret.Get(0).(func(*marathon.Application) *marathon.Application); ok { - r0 = rf(application) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Application) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.Application) error); ok { - r1 = rf(application) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CreateGroup provides a mock function with given fields: group -func (_m *Marathon) CreateGroup(group *marathon.Group) error { - ret := _m.Called(group) - - var r0 error - if rf, ok := ret.Get(0).(func(*marathon.Group) error); ok { - r0 = rf(group) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// CreatePod provides a mock function with given fields: pod -func (_m *Marathon) CreatePod(pod *marathon.Pod) (*marathon.Pod, error) { - ret := _m.Called(pod) - - var r0 *marathon.Pod - if rf, ok := ret.Get(0).(func(*marathon.Pod) *marathon.Pod); ok { - r0 = rf(pod) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Pod) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.Pod) error); ok { - r1 = rf(pod) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteApplication provides a mock function with given fields: name, force -func (_m *Marathon) DeleteApplication(name string, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(name, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok { - r0 = rf(name, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(name, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteDeployment provides a mock function with given fields: id, force -func (_m *Marathon) DeleteDeployment(id string, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(id, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok { - r0 = rf(id, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(id, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteGroup provides a mock function with given fields: name, force -func (_m *Marathon) DeleteGroup(name string, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(name, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok { - r0 = rf(name, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(name, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeletePod provides a mock function with given fields: name, force -func (_m *Marathon) DeletePod(name string, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(name, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok { - r0 = rf(name, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(name, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeletePodInstance provides a mock function with given fields: name, instance -func (_m *Marathon) DeletePodInstance(name, instance string) (*marathon.PodInstance, error) { - ret := _m.Called(name, instance) - - var r0 *marathon.PodInstance - if rf, ok := ret.Get(0).(func(string, string) *marathon.PodInstance); ok { - r0 = rf(name, instance) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.PodInstance) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(name, instance) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeletePodInstances provides a mock function with given fields: name, instances -func (_m *Marathon) DeletePodInstances(name string, instances []string) ([]*marathon.PodInstance, error) { - ret := _m.Called(name, instances) - - var r0 []*marathon.PodInstance - if rf, ok := ret.Get(0).(func(string, []string) []*marathon.PodInstance); ok { - r0 = rf(name, instances) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*marathon.PodInstance) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, []string) error); ok { - r1 = rf(name, instances) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteQueueDelay provides a mock function with given fields: appID -func (_m *Marathon) DeleteQueueDelay(appID string) error { - ret := _m.Called(appID) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(appID) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Deployments provides a mock function with given fields: -func (_m *Marathon) Deployments() ([]*marathon.Deployment, error) { - ret := _m.Called() - - var r0 []*marathon.Deployment - if rf, ok := ret.Get(0).(func() []*marathon.Deployment); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*marathon.Deployment) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetMarathonURL provides a mock function with given fields: -func (_m *Marathon) GetMarathonURL() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// Group provides a mock function with given fields: name -func (_m *Marathon) Group(name string) (*marathon.Group, error) { - ret := _m.Called(name) - - var r0 *marathon.Group - if rf, ok := ret.Get(0).(func(string) *marathon.Group); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Group) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GroupBy provides a mock function with given fields: name, opts -func (_m *Marathon) GroupBy(name string, opts *marathon.GetGroupOpts) (*marathon.Group, error) { - ret := _m.Called(name, opts) - - var r0 *marathon.Group - if rf, ok := ret.Get(0).(func(string, *marathon.GetGroupOpts) *marathon.Group); ok { - r0 = rf(name, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Group) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.GetGroupOpts) error); ok { - r1 = rf(name, opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Groups provides a mock function with given fields: -func (_m *Marathon) Groups() (*marathon.Groups, error) { - ret := _m.Called() - - var r0 *marathon.Groups - if rf, ok := ret.Get(0).(func() *marathon.Groups); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Groups) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GroupsBy provides a mock function with given fields: opts -func (_m *Marathon) GroupsBy(opts *marathon.GetGroupOpts) (*marathon.Groups, error) { - ret := _m.Called(opts) - - var r0 *marathon.Groups - if rf, ok := ret.Get(0).(func(*marathon.GetGroupOpts) *marathon.Groups); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Groups) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.GetGroupOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// HasApplicationVersion provides a mock function with given fields: name, version -func (_m *Marathon) HasApplicationVersion(name, version string) (bool, error) { - ret := _m.Called(name, version) - - var r0 bool - if rf, ok := ret.Get(0).(func(string, string) bool); ok { - r0 = rf(name, version) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(name, version) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// HasDeployment provides a mock function with given fields: id -func (_m *Marathon) HasDeployment(id string) (bool, error) { - ret := _m.Called(id) - - var r0 bool - if rf, ok := ret.Get(0).(func(string) bool); ok { - r0 = rf(id) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// HasGroup provides a mock function with given fields: name -func (_m *Marathon) HasGroup(name string) (bool, error) { - ret := _m.Called(name) - - var r0 bool - if rf, ok := ret.Get(0).(func(string) bool); ok { - r0 = rf(name) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Info provides a mock function with given fields: -func (_m *Marathon) Info() (*marathon.Info, error) { - ret := _m.Called() - - var r0 *marathon.Info - if rf, ok := ret.Get(0).(func() *marathon.Info); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Info) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// KillApplicationTasks provides a mock function with given fields: applicationID, opts -func (_m *Marathon) KillApplicationTasks(applicationID string, opts *marathon.KillApplicationTasksOpts) (*marathon.Tasks, error) { - ret := _m.Called(applicationID, opts) - - var r0 *marathon.Tasks - if rf, ok := ret.Get(0).(func(string, *marathon.KillApplicationTasksOpts) *marathon.Tasks); ok { - r0 = rf(applicationID, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Tasks) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.KillApplicationTasksOpts) error); ok { - r1 = rf(applicationID, opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// KillTask provides a mock function with given fields: taskID, opts -func (_m *Marathon) KillTask(taskID string, opts *marathon.KillTaskOpts) (*marathon.Task, error) { - ret := _m.Called(taskID, opts) - - var r0 *marathon.Task - if rf, ok := ret.Get(0).(func(string, *marathon.KillTaskOpts) *marathon.Task); ok { - r0 = rf(taskID, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Task) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.KillTaskOpts) error); ok { - r1 = rf(taskID, opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// KillTasks provides a mock function with given fields: taskIDs, opts -func (_m *Marathon) KillTasks(taskIDs []string, opts *marathon.KillTaskOpts) error { - ret := _m.Called(taskIDs, opts) - - var r0 error - if rf, ok := ret.Get(0).(func([]string, *marathon.KillTaskOpts) error); ok { - r0 = rf(taskIDs, opts) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Leader provides a mock function with given fields: -func (_m *Marathon) Leader() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListApplications provides a mock function with given fields: _a0 -func (_m *Marathon) ListApplications(_a0 url.Values) ([]string, error) { - ret := _m.Called(_a0) - - var r0 []string - if rf, ok := ret.Get(0).(func(url.Values) []string); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(url.Values) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Ping provides a mock function with given fields: -func (_m *Marathon) Ping() (bool, error) { - ret := _m.Called() - - var r0 bool - if rf, ok := ret.Get(0).(func() bool); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Pod provides a mock function with given fields: name -func (_m *Marathon) Pod(name string) (*marathon.Pod, error) { - ret := _m.Called(name) - - var r0 *marathon.Pod - if rf, ok := ret.Get(0).(func(string) *marathon.Pod); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Pod) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PodByVersion provides a mock function with given fields: name, version -func (_m *Marathon) PodByVersion(name, version string) (*marathon.Pod, error) { - ret := _m.Called(name, version) - - var r0 *marathon.Pod - if rf, ok := ret.Get(0).(func(string, string) *marathon.Pod); ok { - r0 = rf(name, version) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Pod) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(name, version) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PodIsRunning provides a mock function with given fields: name -func (_m *Marathon) PodIsRunning(name string) bool { - ret := _m.Called(name) - - var r0 bool - if rf, ok := ret.Get(0).(func(string) bool); ok { - r0 = rf(name) - } else { - r0 = ret.Get(0).(bool) - } - - return r0 -} - -// PodStatus provides a mock function with given fields: name -func (_m *Marathon) PodStatus(name string) (*marathon.PodStatus, error) { - ret := _m.Called(name) - - var r0 *marathon.PodStatus - if rf, ok := ret.Get(0).(func(string) *marathon.PodStatus); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.PodStatus) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PodStatuses provides a mock function with given fields: -func (_m *Marathon) PodStatuses() ([]*marathon.PodStatus, error) { - ret := _m.Called() - - var r0 []*marathon.PodStatus - if rf, ok := ret.Get(0).(func() []*marathon.PodStatus); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*marathon.PodStatus) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PodVersions provides a mock function with given fields: name -func (_m *Marathon) PodVersions(name string) ([]string, error) { - ret := _m.Called(name) - - var r0 []string - if rf, ok := ret.Get(0).(func(string) []string); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Pods provides a mock function with given fields: -func (_m *Marathon) Pods() ([]marathon.Pod, error) { - ret := _m.Called() - - var r0 []marathon.Pod - if rf, ok := ret.Get(0).(func() []marathon.Pod); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]marathon.Pod) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Queue provides a mock function with given fields: -func (_m *Marathon) Queue() (*marathon.Queue, error) { - ret := _m.Called() - - var r0 *marathon.Queue - if rf, ok := ret.Get(0).(func() *marathon.Queue); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Queue) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RemoveEventsListener provides a mock function with given fields: channel -func (_m *Marathon) RemoveEventsListener(channel marathon.EventsChannel) { - _m.Called(channel) -} - -// RestartApplication provides a mock function with given fields: name, force -func (_m *Marathon) RestartApplication(name string, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(name, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok { - r0 = rf(name, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(name, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ScaleApplicationInstances provides a mock function with given fields: name, instances, force -func (_m *Marathon) ScaleApplicationInstances(name string, instances int, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(name, instances, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, int, bool) *marathon.DeploymentID); ok { - r0 = rf(name, instances, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, int, bool) error); ok { - r1 = rf(name, instances, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// SetApplicationVersion provides a mock function with given fields: name, version -func (_m *Marathon) SetApplicationVersion(name string, version *marathon.ApplicationVersion) (*marathon.DeploymentID, error) { - ret := _m.Called(name, version) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, *marathon.ApplicationVersion) *marathon.DeploymentID); ok { - r0 = rf(name, version) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.ApplicationVersion) error); ok { - r1 = rf(name, version) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Subscribe provides a mock function with given fields: _a0 -func (_m *Marathon) Subscribe(_a0 string) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Subscriptions provides a mock function with given fields: -func (_m *Marathon) Subscriptions() (*marathon.Subscriptions, error) { - ret := _m.Called() - - var r0 *marathon.Subscriptions - if rf, ok := ret.Get(0).(func() *marathon.Subscriptions); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Subscriptions) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// SupportsPods provides a mock function with given fields: -func (_m *Marathon) SupportsPods() (bool, error) { - ret := _m.Called() - - var r0 bool - if rf, ok := ret.Get(0).(func() bool); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// TaskEndpoints provides a mock function with given fields: name, port, healthCheck -func (_m *Marathon) TaskEndpoints(name string, port int, healthCheck bool) ([]string, error) { - ret := _m.Called(name, port, healthCheck) - - var r0 []string - if rf, ok := ret.Get(0).(func(string, int, bool) []string); ok { - r0 = rf(name, port, healthCheck) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, int, bool) error); ok { - r1 = rf(name, port, healthCheck) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Tasks provides a mock function with given fields: application -func (_m *Marathon) Tasks(application string) (*marathon.Tasks, error) { - ret := _m.Called(application) - - var r0 *marathon.Tasks - if rf, ok := ret.Get(0).(func(string) *marathon.Tasks); ok { - r0 = rf(application) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Tasks) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(application) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Unsubscribe provides a mock function with given fields: _a0 -func (_m *Marathon) Unsubscribe(_a0 string) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// UpdateApplication provides a mock function with given fields: application, force -func (_m *Marathon) UpdateApplication(application *marathon.Application, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(application, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(*marathon.Application, bool) *marathon.DeploymentID); ok { - r0 = rf(application, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.Application, bool) error); ok { - r1 = rf(application, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// UpdateGroup provides a mock function with given fields: id, group, force -func (_m *Marathon) UpdateGroup(id string, group *marathon.Group, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(id, group, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, *marathon.Group, bool) *marathon.DeploymentID); ok { - r0 = rf(id, group, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.Group, bool) error); ok { - r1 = rf(id, group, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// UpdatePod provides a mock function with given fields: pod, force -func (_m *Marathon) UpdatePod(pod *marathon.Pod, force bool) (*marathon.Pod, error) { - ret := _m.Called(pod, force) - - var r0 *marathon.Pod - if rf, ok := ret.Get(0).(func(*marathon.Pod, bool) *marathon.Pod); ok { - r0 = rf(pod, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Pod) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.Pod, bool) error); ok { - r1 = rf(pod, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// WaitOnApplication provides a mock function with given fields: name, timeout -func (_m *Marathon) WaitOnApplication(name string, timeout time.Duration) error { - ret := _m.Called(name, timeout) - - var r0 error - if rf, ok := ret.Get(0).(func(string, time.Duration) error); ok { - r0 = rf(name, timeout) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// WaitOnDeployment provides a mock function with given fields: id, timeout -func (_m *Marathon) WaitOnDeployment(id string, timeout time.Duration) error { - ret := _m.Called(id, timeout) - - var r0 error - if rf, ok := ret.Get(0).(func(string, time.Duration) error); ok { - r0 = rf(id, timeout) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// WaitOnGroup provides a mock function with given fields: name, timeout -func (_m *Marathon) WaitOnGroup(name string, timeout time.Duration) error { - ret := _m.Called(name, timeout) - - var r0 error - if rf, ok := ret.Get(0).(func(string, time.Duration) error); ok { - r0 = rf(name, timeout) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// WaitOnPod provides a mock function with given fields: name, timeout -func (_m *Marathon) WaitOnPod(name string, timeout time.Duration) error { - ret := _m.Called(name, timeout) - - var r0 error - if rf, ok := ret.Get(0).(func(string, time.Duration) error); ok { - r0 = rf(name, timeout) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/pkg/provider/marathon/readiness.go b/pkg/provider/marathon/readiness.go deleted file mode 100644 index 76785df13..000000000 --- a/pkg/provider/marathon/readiness.go +++ /dev/null @@ -1,122 +0,0 @@ -package marathon - -import ( - "time" - - "github.com/gambol99/go-marathon" - "github.com/rs/zerolog/log" -) - -const ( - // readinessCheckDefaultTimeout is the default timeout for a readiness - // check if no check timeout is specified on the application spec. This - // should really never be the case, but better be safe than sorry. - readinessCheckDefaultTimeout = 10 * time.Second - // readinessCheckSafetyMargin is some buffer duration to account for - // small offsets in readiness check execution. - readinessCheckSafetyMargin = 5 * time.Second - readinessLogHeader = "Marathon readiness check: " -) - -type readinessChecker struct { - checkDefaultTimeout time.Duration - checkSafetyMargin time.Duration - traceLogging bool -} - -func defaultReadinessChecker(isTraceLogging bool) *readinessChecker { - return &readinessChecker{ - checkDefaultTimeout: readinessCheckDefaultTimeout, - checkSafetyMargin: readinessCheckSafetyMargin, - traceLogging: isTraceLogging, - } -} - -func (rc *readinessChecker) Do(task marathon.Task, app marathon.Application) bool { - if rc == nil { - // Readiness checker disabled. - return true - } - - switch { - case len(app.Deployments) == 0: - // We only care about readiness during deployments; post-deployment readiness - // can be covered by a periodic post-deployment probe (i.e., Traefik health checks). - rc.tracef("task %s app %s: ready = true [no deployment ongoing]", task.ID, app.ID) - return true - - case app.ReadinessChecks == nil || len(*app.ReadinessChecks) == 0: - // Applications without configured readiness checks are always considered - // ready. - rc.tracef("task %s app %s: ready = true [no readiness checks on app]", task.ID, app.ID) - return true - } - - // Loop through all readiness check results and return the results for - // matching task IDs. - if app.ReadinessCheckResults != nil { - for _, readinessCheckResult := range *app.ReadinessCheckResults { - if readinessCheckResult.TaskID == task.ID { - rc.tracef("task %s app %s: ready = %t [evaluating readiness check ready state]", task.ID, app.ID, readinessCheckResult.Ready) - return readinessCheckResult.Ready - } - } - } - - // There's a corner case sometimes hit where the first new task of a - // deployment goes from TASK_STAGING to TASK_RUNNING without a corresponding - // readiness check result being included in the API response. This only happens - // in a very short (yet unlucky) time frame and does not repeat for subsequent - // tasks of the same deployment. - // Complicating matters, the situation may occur for both initially deploying - // applications as well as rolling-upgraded ones where one or more tasks from - // a previous deployment exist already and are joined by new tasks from a - // subsequent deployment. We must always make sure that pre-existing tasks - // maintain their ready state while newly launched tasks must be considered - // unready until a check result appears. - // We distinguish the two cases by comparing the current time with the start - // time of the task: It should take Marathon at most one readiness check timeout - // interval (plus some safety margin to account for the delayed nature of - // distributed systems) for readiness check results to be returned along the API - // response. Once the task turns old enough, we assume it to be part of a - // pre-existing deployment and mark it as ready. Note that it is okay to err - // on the side of caution and consider a task unready until the safety time - // window has elapsed because a newly created task should be readiness-checked - // and be given a result fairly shortly after its creation (i.e., on the scale - // of seconds). - readinessCheckTimeoutSecs := (*app.ReadinessChecks)[0].TimeoutSeconds - readinessCheckTimeout := time.Duration(readinessCheckTimeoutSecs) * time.Second - if readinessCheckTimeout == 0 { - rc.tracef("task %s app %s: readiness check timeout not set, using default value %s", task.ID, app.ID, rc.checkDefaultTimeout) - readinessCheckTimeout = rc.checkDefaultTimeout - } else { - readinessCheckTimeout += rc.checkSafetyMargin - } - - startTime, err := time.Parse(time.RFC3339, task.StartedAt) - if err != nil { - // An unparseable start time should never occur; if it does, we assume the - // problem should be surfaced as quickly as possible, which is easiest if - // we shun the task from rotation. - log.Warn().Err(err).Msgf("Failed to parse start-time %s of task %s from application %s (assuming unready)", task.StartedAt, task.ID, app.ID) - return false - } - - since := time.Since(startTime) - if since < readinessCheckTimeout { - rc.tracef("task %s app %s: ready = false [task with start-time %s not within assumed check timeout window of %s (elapsed time since task start: %s)]", task.ID, app.ID, startTime.Format(time.RFC3339), readinessCheckTimeout, since) - return false - } - - // Finally, we can be certain this task is not part of the deployment (i.e., - // it's an old task that's going to transition into the TASK_KILLING and/or - // TASK_KILLED state as new tasks' readiness checks gradually turn green.) - rc.tracef("task %s app %s: ready = true [task with start-time %s not involved in deployment (elapsed time since task start: %s)]", task.ID, app.ID, startTime.Format(time.RFC3339), since) - return true -} - -func (rc *readinessChecker) tracef(format string, args ...interface{}) { - if rc.traceLogging { - log.Debug().Msgf(readinessLogHeader+format, args...) - } -} diff --git a/pkg/provider/marathon/readiness_test.go b/pkg/provider/marathon/readiness_test.go deleted file mode 100644 index 8d61c01c4..000000000 --- a/pkg/provider/marathon/readiness_test.go +++ /dev/null @@ -1,134 +0,0 @@ -package marathon - -import ( - "testing" - "time" - - "github.com/gambol99/go-marathon" -) - -func testReadinessChecker() *readinessChecker { - return defaultReadinessChecker(false) -} - -func TestDisabledReadinessChecker(t *testing.T) { - var rc *readinessChecker - tsk := task() - app := application( - deployments("deploymentId"), - readinessCheck(0), - readinessCheckResult(testTaskName, false), - ) - - if ready := rc.Do(tsk, app); !ready { - t.Error("expected ready = true") - } -} - -func TestEnabledReadinessChecker(t *testing.T) { - tests := []struct { - desc string - task marathon.Task - app marathon.Application - rc readinessChecker - expectedReady bool - }{ - { - desc: "no deployment running", - task: task(), - app: application(), - expectedReady: true, - }, - { - desc: "no readiness checks defined", - task: task(), - app: application(deployments("deploymentId")), - expectedReady: true, - }, - { - desc: "readiness check result negative", - task: task(), - app: application( - deployments("deploymentId"), - readinessCheck(0), - readinessCheckResult("otherTaskID", true), - readinessCheckResult(testTaskName, false), - ), - expectedReady: false, - }, - { - desc: "readiness check result positive", - task: task(), - app: application( - deployments("deploymentId"), - readinessCheck(0), - readinessCheckResult("otherTaskID", false), - readinessCheckResult(testTaskName, true), - ), - expectedReady: true, - }, - { - desc: "no readiness check result with default timeout", - task: task(startedAtFromNow(3 * time.Minute)), - app: application( - deployments("deploymentId"), - readinessCheck(0), - ), - rc: readinessChecker{ - checkDefaultTimeout: 5 * time.Minute, - }, - expectedReady: false, - }, - { - desc: "no readiness check result with readiness check timeout", - task: task(startedAtFromNow(4 * time.Minute)), - app: application( - deployments("deploymentId"), - readinessCheck(3*time.Minute), - ), - rc: readinessChecker{ - checkSafetyMargin: 3 * time.Minute, - }, - expectedReady: false, - }, - { - desc: "invalid task start time", - task: task(startedAt("invalid")), - app: application( - deployments("deploymentId"), - readinessCheck(0), - ), - expectedReady: false, - }, - { - desc: "task not involved in deployment", - task: task(startedAtFromNow(1 * time.Hour)), - app: application( - deployments("deploymentId"), - readinessCheck(0), - ), - rc: readinessChecker{ - checkDefaultTimeout: 10 * time.Second, - }, - expectedReady: true, - }, - } - - for _, test := range tests { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - rc := testReadinessChecker() - if test.rc.checkDefaultTimeout > 0 { - rc.checkDefaultTimeout = test.rc.checkDefaultTimeout - } - if test.rc.checkSafetyMargin > 0 { - rc.checkSafetyMargin = test.rc.checkSafetyMargin - } - actualReady := test.rc.Do(test.task, test.app) - if actualReady != test.expectedReady { - t.Errorf("actual ready = %t, expected ready = %t", actualReady, test.expectedReady) - } - }) - } -} diff --git a/pkg/provider/rancher/config.go b/pkg/provider/rancher/config.go deleted file mode 100644 index e61c2784d..000000000 --- a/pkg/provider/rancher/config.go +++ /dev/null @@ -1,299 +0,0 @@ -package rancher - -import ( - "context" - "errors" - "fmt" - "net" - "strings" - - "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/label" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/constraints" -) - -func (p *Provider) buildConfiguration(ctx context.Context, services []rancherData) *dynamic.Configuration { - configurations := make(map[string]*dynamic.Configuration) - - for _, service := range services { - logger := log.Ctx(ctx).With().Str("service", service.Name).Logger() - ctxService := logger.WithContext(ctx) - - if !p.keepService(ctx, service) { - continue - } - - confFromLabel, err := label.DecodeConfiguration(service.Labels) - if err != nil { - logger.Error().Err(err).Send() - continue - } - - var tcpOrUDP bool - if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 { - tcpOrUDP = true - - err := p.buildTCPServiceConfiguration(ctxService, service, confFromLabel.TCP) - if err != nil { - logger.Error().Err(err).Send() - continue - } - provider.BuildTCPRouterConfiguration(ctxService, confFromLabel.TCP) - } - - if len(confFromLabel.UDP.Routers) > 0 || len(confFromLabel.UDP.Services) > 0 { - tcpOrUDP = true - - err := p.buildUDPServiceConfiguration(ctxService, service, confFromLabel.UDP) - if err != nil { - logger.Error().Err(err).Send() - continue - } - provider.BuildUDPRouterConfiguration(ctxService, confFromLabel.UDP) - } - - if tcpOrUDP && len(confFromLabel.HTTP.Routers) == 0 && - len(confFromLabel.HTTP.Middlewares) == 0 && - len(confFromLabel.HTTP.Services) == 0 { - configurations[service.Name] = confFromLabel - continue - } - - err = p.buildServiceConfiguration(ctx, service, confFromLabel.HTTP) - if err != nil { - logger.Error().Err(err).Send() - continue - } - - model := struct { - Name string - Labels map[string]string - }{ - Name: service.Name, - Labels: service.Labels, - } - - provider.BuildRouterConfiguration(ctx, confFromLabel.HTTP, service.Name, p.defaultRuleTpl, model) - - configurations[service.Name] = confFromLabel - } - - return provider.Merge(ctx, configurations) -} - -func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, service rancherData, configuration *dynamic.TCPConfiguration) error { - serviceName := service.Name - - if len(configuration.Services) == 0 { - configuration.Services = map[string]*dynamic.TCPService{ - serviceName: { - LoadBalancer: new(dynamic.TCPServersLoadBalancer), - }, - } - } - - for _, confService := range configuration.Services { - err := p.addServerTCP(ctx, service, confService.LoadBalancer) - if err != nil { - return err - } - } - - return nil -} - -func (p *Provider) buildUDPServiceConfiguration(ctx context.Context, service rancherData, configuration *dynamic.UDPConfiguration) error { - serviceName := service.Name - - if len(configuration.Services) == 0 { - configuration.Services = make(map[string]*dynamic.UDPService) - lb := &dynamic.UDPServersLoadBalancer{} - - configuration.Services[serviceName] = &dynamic.UDPService{ - LoadBalancer: lb, - } - } - - for _, confService := range configuration.Services { - err := p.addServerUDP(ctx, service, confService.LoadBalancer) - if err != nil { - return err - } - } - - return nil -} - -func (p *Provider) buildServiceConfiguration(ctx context.Context, service rancherData, configuration *dynamic.HTTPConfiguration) error { - serviceName := service.Name - - if len(configuration.Services) == 0 { - configuration.Services = make(map[string]*dynamic.Service) - lb := &dynamic.ServersLoadBalancer{} - lb.SetDefaults() - configuration.Services[serviceName] = &dynamic.Service{ - LoadBalancer: lb, - } - } - - for _, confService := range configuration.Services { - err := p.addServers(ctx, service, confService.LoadBalancer) - if err != nil { - return err - } - } - - return nil -} - -func (p *Provider) keepService(ctx context.Context, service rancherData) bool { - logger := log.Ctx(ctx) - - if !service.ExtraConf.Enable { - logger.Debug().Msg("Filtering disabled service") - return false - } - - matches, err := constraints.MatchLabels(service.Labels, p.Constraints) - if err != nil { - logger.Error().Err(err).Msg("Error matching constraint expression") - return false - } - if !matches { - logger.Debug().Msgf("Service pruned by constraint expression: %q", p.Constraints) - return false - } - - if p.EnableServiceHealthFilter { - if service.Health != "" && service.Health != healthy && service.Health != updatingHealthy { - logger.Debug().Msgf("Filtering service %s with healthState of %s", service.Name, service.Health) - return false - } - if service.State != "" && service.State != active && service.State != updatingActive && service.State != upgraded && service.State != upgrading { - logger.Debug().Msgf("Filtering service %s with state of %s", service.Name, service.State) - return false - } - } - - return true -} - -func (p *Provider) addServerTCP(ctx context.Context, service rancherData, loadBalancer *dynamic.TCPServersLoadBalancer) error { - log.Ctx(ctx).Debug().Msgf("Trying to add servers for service %s", service.Name) - - if loadBalancer == nil { - return errors.New("load-balancer is not defined") - } - - if len(loadBalancer.Servers) == 0 { - loadBalancer.Servers = []dynamic.TCPServer{{}} - } - - port := loadBalancer.Servers[0].Port - loadBalancer.Servers[0].Port = "" - - if port == "" { - port = getServicePort(service) - } - - if port == "" { - return errors.New("port is missing") - } - - var servers []dynamic.TCPServer - for _, containerIP := range service.Containers { - servers = append(servers, dynamic.TCPServer{ - Address: net.JoinHostPort(containerIP, port), - }) - } - - loadBalancer.Servers = servers - - return nil -} - -func (p *Provider) addServerUDP(ctx context.Context, service rancherData, loadBalancer *dynamic.UDPServersLoadBalancer) error { - log.Ctx(ctx).Debug().Msgf("Trying to add servers for service %s", service.Name) - - if loadBalancer == nil { - return errors.New("load-balancer is not defined") - } - - if len(loadBalancer.Servers) == 0 { - loadBalancer.Servers = []dynamic.UDPServer{{}} - } - - port := loadBalancer.Servers[0].Port - loadBalancer.Servers[0].Port = "" - - if port == "" { - port = getServicePort(service) - } - - if port == "" { - return errors.New("port is missing") - } - - var servers []dynamic.UDPServer - for _, containerIP := range service.Containers { - servers = append(servers, dynamic.UDPServer{ - Address: net.JoinHostPort(containerIP, port), - }) - } - - loadBalancer.Servers = servers - - return nil -} - -func (p *Provider) addServers(ctx context.Context, service rancherData, loadBalancer *dynamic.ServersLoadBalancer) error { - log.Ctx(ctx).Debug().Msgf("Trying to add servers for service %s", service.Name) - - if loadBalancer == nil { - return errors.New("load-balancer is not defined") - } - - if len(loadBalancer.Servers) == 0 { - server := dynamic.Server{} - server.SetDefaults() - - loadBalancer.Servers = []dynamic.Server{server} - } - - port := loadBalancer.Servers[0].Port - loadBalancer.Servers[0].Port = "" - - if port == "" { - port = getServicePort(service) - } - - if port == "" { - return errors.New("port is missing") - } - - var servers []dynamic.Server - for _, containerIP := range service.Containers { - servers = append(servers, dynamic.Server{ - URL: fmt.Sprintf("%s://%s", loadBalancer.Servers[0].Scheme, net.JoinHostPort(containerIP, port)), - }) - } - - loadBalancer.Servers = servers - - return nil -} - -func getServicePort(data rancherData) string { - rawPort := strings.Split(data.Port, "/")[0] - hostPort := strings.Split(rawPort, ":") - - if len(hostPort) >= 2 { - return hostPort[1] - } - if len(hostPort) > 0 && hostPort[0] != "" { - return hostPort[0] - } - return rawPort -} diff --git a/pkg/provider/rancher/config_test.go b/pkg/provider/rancher/config_test.go deleted file mode 100644 index 20b8940b4..000000000 --- a/pkg/provider/rancher/config_test.go +++ /dev/null @@ -1,1203 +0,0 @@ -package rancher - -import ( - "context" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" -) - -func Int(v int) *int { return &v } -func Bool(v bool) *bool { return &v } - -func Test_buildConfiguration(t *testing.T) { - testCases := []struct { - desc string - containers []rancherData - constraints string - expected *dynamic.Configuration - }{ - { - desc: "one service no label", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{}, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two services no label", - containers: []rancherData{ - { - Name: "Test1", - Labels: map[string]string{}, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - { - Name: "Test2", - Labels: map[string]string{}, - Port: "80/tcp", - Containers: []string{"127.0.0.2"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test1": { - Service: "Test1", - Rule: "Host(`Test1.traefik.wtf`)", - }, - "Test2": { - Service: "Test2", - Rule: "Host(`Test2.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "Test2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.2:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two services no label multiple containers", - containers: []rancherData{ - { - Name: "Test1", - Labels: map[string]string{}, - Port: "80/tcp", - Containers: []string{"127.0.0.1", "127.0.0.2"}, - Health: "", - State: "", - }, - { - Name: "Test2", - Labels: map[string]string{}, - Port: "80/tcp", - Containers: []string{"128.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test1": { - Service: "Test1", - Rule: "Host(`Test1.traefik.wtf`)", - }, - "Test2": { - Service: "Test2", - Rule: "Host(`Test2.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - { - URL: "http://127.0.0.2:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "Test2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://128.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service some labels", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.passhostheader": "true", - "traefik.http.routers.Router1.rule": "Host(`foo.com`)", - "traefik.http.routers.Router1.service": "Service1", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`foo.com`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service which is unhealthy", - containers: []rancherData{ - { - Name: "Test", - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "broken", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service which is upgrading", - containers: []rancherData{ - { - Name: "Test", - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "upgradefailed", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service with rule label and has a host exposed port", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.http.routers.Router1.rule": "Host(`foo.com`)", - }, - Port: "12345:80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Test", - Rule: "Host(`foo.com`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service with non matching constraints", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.http.routers.Router1.rule": "Host(`foo.com`)", - }, - Port: "12345:80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - constraints: `Label("traefik.tags", "bar")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service with matching constraints", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tags": "foo", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - constraints: `Label("traefik.tags", "foo")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "Middlewares used in router", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.http.middlewares.Middleware1.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - "traefik.http.routers.Test.middlewares": "Middleware1", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - Middlewares: []string{"Middleware1"}, - }, - }, - Middlewares: map[string]*dynamic.Middleware{ - "Middleware1": { - BasicAuth: &dynamic.BasicAuth{ - Users: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - }, - }, - }, - Services: map[string]*dynamic.Service{ - "Test": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "Middlewares used in TCP router", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.routers.Test.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.middlewares.Middleware1.ipallowlist.sourcerange": "foobar, fiibar", - "traefik.tcp.routers.Test.middlewares": "Middleware1", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "Test": { - Service: "Test", - Rule: "HostSNI(`foo.bar`)", - Middlewares: []string{"Middleware1"}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{ - "Middleware1": { - IPAllowList: &dynamic.TCPIPAllowList{ - SourceRange: []string{"foobar", "fiibar"}, - }, - }, - }, - Services: map[string]*dynamic.TCPService{ - "Test": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:80", - }, - }, - }, - }, - }, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "Port in labels", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.http.services.Test.loadbalancer.server.port": "80", - }, - Port: "", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.routers.foo.tls": "true", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "Test", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "Test": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:80", - }, - }, - }, - }, - }, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "udp with label", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.udp.routers.foo.entrypoints": "mydns", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "Test", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "Test": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "127.0.0.1:80", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label without rule", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.routers.foo.tls": "true", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "Test": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:80", - }, - }, - }, - }, - }, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label and port", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "foo", - Rule: "HostSNI(`foo.bar`)", - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:8080", - }, - }, - }, - }, - }, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "udp with label and port", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.udp.routers.foo.entrypoints": "mydns", - "traefik.udp.services.foo.loadbalancer.server.port": "8080", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "foo", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "foo": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "127.0.0.1:8080", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label and port and http service", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.routers.foo.tls": "true", - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - "traefik.http.services.Service1.loadbalancer.passhostheader": "true", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1", "127.0.0.2"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "foo", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:8080", - }, - { - Address: "127.0.0.2:8080", - }, - }, - }, - }, - }, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Service1", - Rule: "Host(`Test.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - { - URL: "http://127.0.0.2:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "udp with label and port and http service", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.udp.routers.foo.entrypoints": "mydns", - "traefik.udp.services.foo.loadbalancer.server.port": "8080", - "traefik.http.services.Service1.loadbalancer.passhostheader": "true", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1", "127.0.0.2"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "foo", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "foo": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "127.0.0.1:8080", - }, - { - Address: "127.0.0.2:8080", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Service1", - Rule: "Host(`Test.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - { - URL: "http://127.0.0.2:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label for tcp service", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:8080", - }, - }, - }, - }, - }, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "udp with label for tcp service", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.udp.services.foo.loadbalancer.server.port": "8080", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{ - "foo": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "127.0.0.1:8080", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - // TODO: replace or delete? - desc: "tcp with label for tcp service, with termination delay", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:8080", - }, - }, - }, - }, - }, - ServersTransports: make(map[string]*dynamic.TCPServersTransport), - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - 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 { - test := test - - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - p := Provider{ - ExposedByDefault: true, - DefaultRule: "Host(`{{ normalize .Name }}.traefik.wtf`)", - EnableServiceHealthFilter: true, - } - - p.Constraints = test.constraints - - err := p.Init() - require.NoError(t, err) - - for i := 0; i < len(test.containers); i++ { - var err error - test.containers[i].ExtraConf, err = p.getConfiguration(test.containers[i]) - require.NoError(t, err) - } - - configuration := p.buildConfiguration(context.Background(), test.containers) - - assert.Equal(t, test.expected, configuration) - }) - } -} diff --git a/pkg/provider/rancher/label.go b/pkg/provider/rancher/label.go deleted file mode 100644 index 6e90a6098..000000000 --- a/pkg/provider/rancher/label.go +++ /dev/null @@ -1,22 +0,0 @@ -package rancher - -import ( - "github.com/traefik/traefik/v2/pkg/config/label" -) - -type configuration struct { - Enable bool -} - -func (p *Provider) getConfiguration(service rancherData) (configuration, error) { - conf := configuration{ - Enable: p.ExposedByDefault, - } - - err := label.Decode(service.Labels, &conf, "traefik.rancher.", "traefik.enable") - if err != nil { - return configuration{}, err - } - - return conf, nil -} diff --git a/pkg/provider/rancher/rancher.go b/pkg/provider/rancher/rancher.go deleted file mode 100644 index 212c6607c..000000000 --- a/pkg/provider/rancher/rancher.go +++ /dev/null @@ -1,232 +0,0 @@ -package rancher - -import ( - "context" - "fmt" - "text/template" - "time" - - "github.com/cenkalti/backoff/v4" - rancher "github.com/rancher/go-rancher-metadata/metadata" - "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" -) - -const ( - // DefaultTemplateRule The default template for the default rule. - DefaultTemplateRule = "Host(`{{ normalize .Name }}`)" -) - -// Health. -const ( - healthy = "healthy" - updatingHealthy = "updating-healthy" -) - -// States. -const ( - active = "active" - running = "running" - upgraded = "upgraded" - upgrading = "upgrading" - updatingActive = "updating-active" - updatingRunning = "updating-running" -) - -var _ provider.Provider = (*Provider)(nil) - -// Provider holds configurations of the provider. -type Provider struct { - Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` - Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"` - DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` - ExposedByDefault bool `description:"Expose containers by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` - EnableServiceHealthFilter bool `description:"Filter services with unhealthy states and inactive states." json:"enableServiceHealthFilter,omitempty" toml:"enableServiceHealthFilter,omitempty" yaml:"enableServiceHealthFilter,omitempty" export:"true"` - RefreshSeconds int `description:"Defines the polling interval in seconds." json:"refreshSeconds,omitempty" toml:"refreshSeconds,omitempty" yaml:"refreshSeconds,omitempty" export:"true"` - IntervalPoll bool `description:"Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate)." json:"intervalPoll,omitempty" toml:"intervalPoll,omitempty" yaml:"intervalPoll,omitempty" export:"true"` - Prefix string `description:"Prefix used for accessing the Rancher metadata service." json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty"` - defaultRuleTpl *template.Template -} - -// SetDefaults sets the default values. -func (p *Provider) SetDefaults() { - p.Watch = true - p.ExposedByDefault = true - p.EnableServiceHealthFilter = true - p.RefreshSeconds = 15 - p.DefaultRule = DefaultTemplateRule - p.Prefix = "latest" -} - -type rancherData struct { - Name string - Labels map[string]string - Containers []string - Health string - State string - Port string - ExtraConf configuration -} - -// Init the provider. -func (p *Provider) Init() error { - defaultRuleTpl, err := provider.MakeDefaultRuleTemplate(p.DefaultRule, nil) - if err != nil { - return fmt.Errorf("error while parsing default rule: %w", err) - } - - p.defaultRuleTpl = defaultRuleTpl - return nil -} - -func (p *Provider) createClient(ctx context.Context) (rancher.Client, error) { - metadataServiceURL := fmt.Sprintf("http://rancher-metadata.rancher.internal/%s", p.Prefix) - client, err := rancher.NewClientAndWait(metadataServiceURL) - if err != nil { - log.Ctx(ctx).Error().Err(err).Msg("Failed to create Rancher metadata service client") - return nil, err - } - - return client, nil -} - -// Provide allows the rancher provider to provide configurations to traefik using the given configuration channel. -func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error { - pool.GoCtx(func(routineCtx context.Context) { - logger := log.Ctx(routineCtx).With().Str(logs.ProviderName, "rancher").Logger() - ctxLog := logger.WithContext(routineCtx) - - operation := func() error { - client, err := p.createClient(ctxLog) - if err != nil { - logger.Error().Err(err).Msg("Failed to create the metadata client metadata service") - return err - } - - updateConfiguration := func(_ string) { - stacks, err := client.GetStacks() - if err != nil { - logger.Error().Err(err).Msg("Failed to query Rancher metadata service") - return - } - - rancherData := p.parseMetadataSourcedRancherData(ctxLog, stacks) - - logger.Printf("Received Rancher data %+v", rancherData) - - configuration := p.buildConfiguration(ctxLog, rancherData) - configurationChan <- dynamic.Message{ - ProviderName: "rancher", - Configuration: configuration, - } - } - updateConfiguration("init") - - if p.Watch { - if p.IntervalPoll { - p.intervalPoll(ctxLog, client, updateConfiguration) - } else { - // Long polling should be favored for the most accurate configuration updates. - // Holds the connection until there is either a change in the metadata repository or `p.RefreshSeconds` has elapsed. - client.OnChangeCtx(ctxLog, p.RefreshSeconds, updateConfiguration) - } - } - - return nil - } - - notify := func(err error, time time.Duration) { - logger.Error().Err(err).Msgf("Provider error, retrying in %s", time) - } - err := backoff.RetryNotify(safe.OperationWithRecover(operation), backoff.WithContext(job.NewBackOff(backoff.NewExponentialBackOff()), ctxLog), notify) - if err != nil { - logger.Error().Err(err).Msg("Cannot retrieve data") - } - }) - - return nil -} - -func (p *Provider) intervalPoll(ctx context.Context, client rancher.Client, updateConfiguration func(string)) { - ticker := time.NewTicker(time.Duration(p.RefreshSeconds) * time.Second) - defer ticker.Stop() - - var version string - for { - select { - case <-ticker.C: - newVersion, err := client.GetVersion() - if err != nil { - log.Ctx(ctx).Error().Err(err).Msg("Failed to create Rancher metadata service client") - } else if version != newVersion { - version = newVersion - updateConfiguration(version) - } - case <-ctx.Done(): - return - } - } -} - -func (p *Provider) parseMetadataSourcedRancherData(ctx context.Context, stacks []rancher.Stack) (rancherDataList []rancherData) { - for _, stack := range stacks { - for _, service := range stack.Services { - logger := log.Ctx(ctx).With().Str("stack", stack.Name).Str("service", service.Name).Logger() - ctxSvc := logger.WithContext(ctx) - - servicePort := "" - if len(service.Ports) > 0 { - servicePort = service.Ports[0] - } - for _, port := range service.Ports { - logger.Debug().Msgf("Set Port %s", port) - } - - var containerIPAddresses []string - for _, container := range service.Containers { - if containerFilter(ctxSvc, container.Name, container.HealthState, container.State) { - containerIPAddresses = append(containerIPAddresses, container.PrimaryIp) - } - } - - service := rancherData{ - Name: service.Name + "_" + stack.Name, - State: service.State, - Labels: service.Labels, - Port: servicePort, - Containers: containerIPAddresses, - } - - extraConf, err := p.getConfiguration(service) - if err != nil { - logger.Error().Err(err).Msgf("Skip container %s", service.Name) - continue - } - - service.ExtraConf = extraConf - - rancherDataList = append(rancherDataList, service) - } - } - return rancherDataList -} - -func containerFilter(ctx context.Context, name, healthState, state string) bool { - logger := log.Ctx(ctx) - - if healthState != "" && healthState != healthy && healthState != updatingHealthy { - logger.Debug().Msgf("Filtering container %s with healthState of %s", name, healthState) - return false - } - - if state != "" && state != running && state != updatingRunning && state != upgraded { - logger.Debug().Msgf("Filtering container %s with state of %s", name, state) - return false - } - - return true -} diff --git a/pkg/redactor/redactor_config_test.go b/pkg/redactor/redactor_config_test.go index 300b43035..49a4a292d 100644 --- a/pkg/redactor/redactor_config_test.go +++ b/pkg/redactor/redactor_config_test.go @@ -28,8 +28,6 @@ import ( "github.com/traefik/traefik/v2/pkg/provider/kv/etcd" "github.com/traefik/traefik/v2/pkg/provider/kv/redis" "github.com/traefik/traefik/v2/pkg/provider/kv/zk" - "github.com/traefik/traefik/v2/pkg/provider/marathon" - "github.com/traefik/traefik/v2/pkg/provider/rancher" "github.com/traefik/traefik/v2/pkg/provider/rest" traefiktls "github.com/traefik/traefik/v2/pkg/tls" "github.com/traefik/traefik/v2/pkg/tracing/datadog" @@ -611,32 +609,6 @@ func TestDo_staticConfiguration(t *testing.T) { HTTPClientTimeout: 42, } - config.Providers.Marathon = &marathon.Provider{ - Constraints: `Label("foo", "bar")`, - Trace: true, - Watch: true, - Endpoint: "foobar", - DefaultRule: "PathPrefix(`/`)", - ExposedByDefault: true, - DCOSToken: "foobar", - TLS: &types.ClientTLS{ - CA: "myCa", - Cert: "mycert.pem", - Key: "mycert.key", - InsecureSkipVerify: true, - }, - DialerTimeout: 42, - ResponseHeaderTimeout: 42, - TLSHandshakeTimeout: 42, - KeepAlive: 42, - ForceTaskHostname: true, - Basic: &marathon.Basic{ - HTTPBasicAuthUser: "user", - HTTPBasicPassword: "password", - }, - RespectReadinessChecks: true, - } - config.Providers.KubernetesIngress = &ingress.Provider{ Endpoint: "MyEndpoint", Token: "MyToken", @@ -675,17 +647,6 @@ func TestDo_staticConfiguration(t *testing.T) { Insecure: true, } - config.Providers.Rancher = &rancher.Provider{ - Constraints: `Label("foo", "bar")`, - Watch: true, - DefaultRule: "PathPrefix(`/`)", - ExposedByDefault: true, - EnableServiceHealthFilter: true, - RefreshSeconds: 42, - IntervalPoll: true, - Prefix: "MyPrefix", - } - config.Providers.ConsulCatalog = &consulcatalog.ProviderBuilder{ Configuration: consulcatalog.Configuration{ Constraints: `Label("foo", "bar")`, @@ -823,17 +784,6 @@ func TestDo_staticConfiguration(t *testing.T) { AddServicesLabels: true, Prefix: "MyPrefix", }, - InfluxDB: &types.InfluxDB{ - Address: "localhost:8183", - Protocol: "http", - PushInterval: 42, - Database: "myDB", - RetentionPolicy: "12", - Username: "a", - Password: "aaaa", - AddEntryPointsLabels: true, - AddServicesLabels: true, - }, } config.Ping = &ping.Handler{ diff --git a/pkg/redactor/testdata/anonymized-static-config.json b/pkg/redactor/testdata/anonymized-static-config.json index 01883306f..14d587559 100644 --- a/pkg/redactor/testdata/anonymized-static-config.json +++ b/pkg/redactor/testdata/anonymized-static-config.json @@ -112,31 +112,6 @@ "filename": "file Filename", "debugLogGeneratedTemplate": true }, - "marathon": { - "constraints": "Label(\"foo\", \"bar\")", - "trace": true, - "watch": true, - "endpoint": "xxxx", - "defaultRule": "xxxx", - "exposedByDefault": true, - "dcosToken": "xxxx", - "tls": { - "ca": "xxxx", - "cert": "xxxx", - "key": "xxxx", - "insecureSkipVerify": true - }, - "dialerTimeout": "42ns", - "responseHeaderTimeout": "42ns", - "tlsHandshakeTimeout": "42ns", - "keepAlive": "42ns", - "forceTaskHostname": true, - "basic": { - "httpBasicAuthUser": "xxxx", - "httpBasicPassword": "xxxx" - }, - "respectReadinessChecks": true - }, "kubernetesIngress": { "endpoint": "xxxx", "token": "xxxx", @@ -180,16 +155,6 @@ "rest": { "insecure": true }, - "rancher": { - "constraints": "Label(\"foo\", \"bar\")", - "watch": true, - "defaultRule": "xxxx", - "exposedByDefault": true, - "enableServiceHealthFilter": true, - "refreshSeconds": 42, - "intervalPoll": true, - "prefix": "xxxx" - }, "consulCatalog": { "constraints": "Label(\"foo\", \"bar\")", "endpoint": { @@ -319,17 +284,6 @@ "addEntryPointsLabels": true, "addServicesLabels": true, "prefix": "MyPrefix" - }, - "influxDB": { - "address": "xxxx", - "protocol": "xxxx", - "pushInterval": "42ns", - "database": "myDB", - "retentionPolicy": "12", - "username": "xxxx", - "password": "xxxx", - "addEntryPointsLabels": true, - "addServicesLabels": true } }, "ping": { diff --git a/pkg/redactor/testdata/example.json b/pkg/redactor/testdata/example.json index 0d12d63d9..3dd94d238 100644 --- a/pkg/redactor/testdata/example.json +++ b/pkg/redactor/testdata/example.json @@ -65,7 +65,6 @@ "Docker": null, "File": null, "Web": null, - "Marathon": null, "Consul": null, "ConsulCatalog": null, "Etcd": null, @@ -73,10 +72,8 @@ "Boltdb": null, "KubernetesIngress": null, "KubernetesCRD": null, - "Mesos": null, "Eureka": null, "ECS": null, - "Rancher": null, "DynamoDB": null, "ConfigFile": "/etc/traefik/traefik.toml" } diff --git a/pkg/redactor/testdata/expected.json b/pkg/redactor/testdata/expected.json index 7319a7f1a..5849375f8 100644 --- a/pkg/redactor/testdata/expected.json +++ b/pkg/redactor/testdata/expected.json @@ -65,7 +65,6 @@ "Docker": null, "File": null, "Web": null, - "Marathon": null, "Consul": null, "ConsulCatalog": null, "Etcd": null, @@ -73,10 +72,8 @@ "Boltdb": null, "KubernetesIngress": null, "KubernetesCRD": null, - "Mesos": null, "Eureka": null, "ECS": null, - "Rancher": null, "DynamoDB": null, "ConfigFile": "/etc/traefik/traefik.toml" } diff --git a/pkg/server/server.go b/pkg/server/server.go index 421437a38..962cf6c28 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -111,7 +111,6 @@ func (s *Server) Close() { func stopMetricsClients() { metrics.StopDatadog() metrics.StopStatsd() - metrics.StopInfluxDB() metrics.StopInfluxDB2() metrics.StopOpenTelemetry() } diff --git a/pkg/types/metrics.go b/pkg/types/metrics.go index ddcf71d96..775dc7a16 100644 --- a/pkg/types/metrics.go +++ b/pkg/types/metrics.go @@ -13,7 +13,6 @@ type Metrics struct { Prometheus *Prometheus `description:"Prometheus metrics exporter type." json:"prometheus,omitempty" toml:"prometheus,omitempty" yaml:"prometheus,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Datadog *Datadog `description:"Datadog metrics exporter type." json:"datadog,omitempty" toml:"datadog,omitempty" yaml:"datadog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` StatsD *Statsd `description:"StatsD metrics exporter type." json:"statsD,omitempty" toml:"statsD,omitempty" yaml:"statsD,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` - InfluxDB *InfluxDB `description:"InfluxDB metrics exporter type." json:"influxDB,omitempty" toml:"influxDB,omitempty" yaml:"influxDB,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` InfluxDB2 *InfluxDB2 `description:"InfluxDB v2 metrics exporter type." json:"influxDB2,omitempty" toml:"influxDB2,omitempty" yaml:"influxDB2,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` OpenTelemetry *OpenTelemetry `description:"OpenTelemetry metrics exporter type." json:"openTelemetry,omitempty" toml:"openTelemetry,omitempty" yaml:"openTelemetry,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` } @@ -83,30 +82,6 @@ func (s *Statsd) SetDefaults() { s.Prefix = "traefik" } -// InfluxDB contains address, login and metrics pushing interval configuration. -type InfluxDB struct { - Address string `description:"InfluxDB address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` - Protocol string `description:"InfluxDB address protocol (udp or http)." json:"protocol,omitempty" toml:"protocol,omitempty" yaml:"protocol,omitempty"` - PushInterval types.Duration `description:"InfluxDB push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"` - Database string `description:"InfluxDB database used when protocol is http." json:"database,omitempty" toml:"database,omitempty" yaml:"database,omitempty" export:"true"` - RetentionPolicy string `description:"InfluxDB retention policy used when protocol is http." json:"retentionPolicy,omitempty" toml:"retentionPolicy,omitempty" yaml:"retentionPolicy,omitempty" export:"true"` - Username string `description:"InfluxDB username (only with http)." json:"username,omitempty" toml:"username,omitempty" yaml:"username,omitempty" loggable:"false"` - Password string `description:"InfluxDB password (only with http)." json:"password,omitempty" toml:"password,omitempty" yaml:"password,omitempty" loggable:"false"` - AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"` - AddRoutersLabels bool `description:"Enable metrics on routers." json:"addRoutersLabels,omitempty" toml:"addRoutersLabels,omitempty" yaml:"addRoutersLabels,omitempty" export:"true"` - AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"` - AdditionalLabels map[string]string `description:"Additional labels (influxdb tags) on all metrics" json:"additionalLabels,omitempty" toml:"additionalLabels,omitempty" yaml:"additionalLabels,omitempty" export:"true"` -} - -// SetDefaults sets the default values. -func (i *InfluxDB) SetDefaults() { - i.Address = "localhost:8089" - i.Protocol = "udp" - i.PushInterval = types.Duration(10 * time.Second) - i.AddEntryPointsLabels = true - i.AddServicesLabels = true -} - // InfluxDB2 contains address, token and metrics pushing interval configuration. type InfluxDB2 struct { Address string `description:"InfluxDB v2 address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"`