diff --git a/.goreleaser.yml b/.goreleaser.yml index b46259a56..27bc16cd2 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -40,6 +40,8 @@ builds: goarch: arm64 - goos: freebsd goarch: arm64 + - goos: windows + goarch: arm changelog: skip: true diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 128b5656e..f43ec07d7 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -64,7 +64,7 @@ blocks: - name: GH_VERSION value: 1.12.1 - name: CODENAME - value: "beaufort" + value: "banon" - name: IN_DOCKER value: "" prologue: diff --git a/CHANGELOG.md b/CHANGELOG.md index a7e083b1b..39e862247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ -## [v2.9.0-rc1](https://github.com/traefik/traefik/tree/v2.9.0-rc1) (2022-09-14) -[All Commits](https://github.com/traefik/traefik/compare/v2.8.0-rc1...v2.9.0-rc1) +## [v2.9.0-rc3](https://github.com/traefik/traefik/tree/v2.9.0-rc3) (2022-09-16) +[All Commits](https://github.com/traefik/traefik/compare/v2.9.0-rc2...v2.9.0-rc3) + +**Misc:** +- Merge current v2.8 into v2.9 ([#9343](https://github.com/traefik/traefik/pull/9343) by [kevinpollet](https://github.com/kevinpollet)) + +## [v2.9.0-rc1](https://github.com/traefik/traefik/tree/v2.9.0-rc2) (2022-09-14) +[All Commits](https://github.com/traefik/traefik/compare/v2.8.0-rc1...v2.9.0-rc2) **Enhancements:** - **[acme,tls]** ACME Default Certificate ([#9189](https://github.com/traefik/traefik/pull/9189) by [rtribotte](https://github.com/rtribotte)) @@ -30,6 +36,11 @@ - Merge current v2.8 into master ([#9146](https://github.com/traefik/traefik/pull/9146) by [kevinpollet](https://github.com/kevinpollet)) - Merge current v2.8 into master ([#9135](https://github.com/traefik/traefik/pull/9135) by [kevinpollet](https://github.com/kevinpollet)) +## [v2.9.0-rc1](https://github.com/traefik/traefik/tree/v2.9.0-rc1) (2022-09-14) +[All Commits](https://github.com/traefik/traefik/compare/v2.8.0-rc1...v2.9.0-rc1) + +Release canceled. + ## [v2.8.5](https://github.com/traefik/traefik/tree/v2.8.5) (2022-09-13) [All Commits](https://github.com/traefik/traefik/compare/v2.8.4...v2.8.5) diff --git a/docs/content/getting-started/faq.md b/docs/content/getting-started/faq.md index 087504452..01b33f639 100644 --- a/docs/content/getting-started/faq.md +++ b/docs/content/getting-started/faq.md @@ -157,3 +157,27 @@ By default, the following headers are automatically added when proxying requests For more details, please check out the [forwarded header](../routing/entrypoints.md#forwarded-headers) documentation. + +## What does the "field not found" error mean? + +```shell +error: field not found, node: -badField- +``` + +The "field not found" error occurs, when an unknown property is encountered in the dynamic or static configuration. + +One easy way to check whether a configuration file is well-formed, is to validate it with: + +- [JSON Schema of the static configuration](https://json.schemastore.org/traefik-v2.json) +- [JSON Schema of the dynamic configuration](https://json.schemastore.org/traefik-v2-file-provider.json) + +## Why are some resources (routers, middlewares, services...) not created/applied? + +As a common tip, if a resource is dropped/not created by Traefik after the dynamic configuration was evaluated, +one should look for an error in the logs. + +If found, the error obviously confirms that something went wrong while creating the resource, +and the message should help in figuring out the mistake(s) in the configuration, and how to fix it. + +When using the file provider, +one easy way to check if the dynamic configuration is well-formed is to validate it with the [JSON Schema of the dynamic configuration](https://json.schemastore.org/traefik-v2-file-provider.json). diff --git a/docs/content/migration/v2.md b/docs/content/migration/v2.md index 1fe8c9f13..00827cb28 100644 --- a/docs/content/migration/v2.md +++ b/docs/content/migration/v2.md @@ -445,7 +445,7 @@ To enable HTTP/3 on an EntryPoint, please check out the [HTTP/3 configuration](. ### Kubernetes Gateway API Provider In `v2.6`, the [Kubernetes Gateway API provider](../providers/kubernetes-gateway.md) now only supports the version [v1alpha2](https://gateway-api.sigs.k8s.io/v1alpha2/guides/getting-started/) of the specification and -[route namespaces](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.RouteNamespaces) selectors, which requires Traefik to fetch and watch the cluster namespaces. +[route namespaces](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.RouteNamespaces) selectors, which requires Traefik to fetch and watch the cluster namespaces. Therefore, the [RBAC](../reference/dynamic-configuration/kubernetes-gateway.md#rbac) and [CRD](../reference/dynamic-configuration/kubernetes-gateway.md#definitions) definitions must be updated. ## v2.6.0 to v2.6.1 diff --git a/docs/content/routing/routers/index.md b/docs/content/routing/routers/index.md index d5ef084a6..3a5045a27 100644 --- a/docs/content/routing/routers/index.md +++ b/docs/content/routing/routers/index.md @@ -233,18 +233,18 @@ If the rule is verified, the router becomes active, calls middlewares, and then The table below lists all the available matchers: -| Rule | Description | -|------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| -| ```Headers(`key`, `value`)``` | Check if there is a key `key`defined in the headers, with the value `value` | -| ```HeadersRegexp(`key`, `regexp`)``` | Check if there is a key `key`defined in the headers, with a value that matches the regular expression `regexp` | -| ```Host(`example.com`, ...)``` | Check if the request domain (host header value) targets one of the given `domains`. | -| ```HostHeader(`example.com`, ...)``` | Same as `Host`, only exists for historical reasons. | -| ```HostRegexp(`example.com`, `{subdomain:[a-z]+}.example.com`, ...)``` | Match the request domain. See "Regexp Syntax" below. | -| ```Method(`GET`, ...)``` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`) | -| ```Path(`/path`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`, ...)``` | Match exact request path. See "Regexp Syntax" below. | -| ```PathPrefix(`/products/`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`)``` | Match request prefix path. See "Regexp Syntax" below. | -| ```Query(`foo=bar`, `bar=baz`)``` | Match Query String parameters. It accepts a sequence of key=value pairs. | -| ```ClientIP(`10.0.0.0/16`, `::1`)``` | Match if the request client IP is one of the given IP/CIDR. It accepts IPv4, IPv6 and CIDR formats. | +| Rule | Description | +|--------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| +| ```Headers(`key`, `value`)``` | Check if there is a key `key`defined in the headers, with the value `value` | +| ```HeadersRegexp(`key`, `regexp`)``` | Check if there is a key `key`defined in the headers, with a value that matches the regular expression `regexp` | +| ```Host(`example.com`, ...)``` | Check if the request domain (host header value) targets one of the given `domains`. | +| ```HostHeader(`example.com`, ...)``` | Same as `Host`, only exists for historical reasons. | +| ```HostRegexp(`example.com`, `{subdomain:[a-z]+}.example.com`, ...)``` | Match the request domain. See "Regexp Syntax" below. | +| ```Method(`GET`, ...)``` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`) | +| ```Path(`/path`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`, ...)``` | Match exact request path. See "Regexp Syntax" below. | +| ```PathPrefix(`/products/`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`)``` | Match request prefix path. See "Regexp Syntax" below. | +| ```Query(`foo=bar`, `bar=baz`)``` | Match Query String parameters. It accepts a sequence of key=value pairs. | +| ```ClientIP(`10.0.0.0/16`, `::1`)``` | Match if the request client IP is one of the given IP/CIDR. It accepts IPv4, IPv6 and CIDR formats. | !!! important "Non-ASCII Domain Names" @@ -259,6 +259,7 @@ The table below lists all the available matchers: The regexp name (`name` in the above example) is an arbitrary value, that exists only for historical reasons. Any `regexp` supported by [Go's regexp package](https://golang.org/pkg/regexp/) may be used. + For example, here is a case insensitive path matcher syntax: ```Path(`/{path:(?i:Products)}`)```. !!! info "Combining Matchers Using Operators and Parenthesis" diff --git a/pkg/plugins/middlewares.go b/pkg/plugins/middlewares.go index 09edbc954..e46dbae34 100644 --- a/pkg/plugins/middlewares.go +++ b/pkg/plugins/middlewares.go @@ -84,6 +84,9 @@ func (p middlewareBuilder) createConfig(config map[string]interface{}) (reflect. } vConfig := results[0] + if len(config) == 0 { + return vConfig, nil + } cfg := &mapstructure.DecoderConfig{ DecodeHook: mapstructure.StringToSliceHookFunc(","), diff --git a/pkg/server/middleware/plugins.go b/pkg/server/middleware/plugins.go index a40179151..3a092f140 100644 --- a/pkg/server/middleware/plugins.go +++ b/pkg/server/middleware/plugins.go @@ -2,7 +2,6 @@ package middleware import ( "errors" - "fmt" "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/plugins" @@ -30,9 +29,5 @@ func findPluginConfig(rawConfig map[string]dynamic.PluginConf) (string, map[stri return "", nil, errors.New("missing plugin type") } - if len(rawPluginConfig) == 0 { - return "", nil, fmt.Errorf("missing plugin configuration: %s", pluginType) - } - return pluginType, rawPluginConfig, nil } diff --git a/script/gcg/traefik-rc-new.toml b/script/gcg/traefik-rc-new.toml index 9e01d10e0..2e8ec3d34 100644 --- a/script/gcg/traefik-rc-new.toml +++ b/script/gcg/traefik-rc-new.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example RC2 of v2.8.0 -CurrentRef = "v2.8" -PreviousRef = "v2.8.0-rc1" -BaseBranch = "v2.8" -FutureCurrentRefName = "v2.8.0-rc2" +# example RC3 of v2.9.0 +CurrentRef = "v2.9" +PreviousRef = "v2.9.0-rc2" +BaseBranch = "v2.9" +FutureCurrentRefName = "v2.9.0-rc3" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10