Merge current v2.8 into v2.9

This commit is contained in:
kevinpollet 2022-09-16 14:57:07 +02:00
commit 30ec5c58fe
No known key found for this signature in database
GPG key ID: 0C9A5DDD1B292453
4 changed files with 40 additions and 17 deletions

View file

@ -157,3 +157,27 @@ By default, the following headers are automatically added when proxying requests
For more details, For more details,
please check out the [forwarded header](../routing/entrypoints.md#forwarded-headers) documentation. 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).

View file

@ -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: The table below lists all the available matchers:
| Rule | Description | | Rule | Description |
|------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| |--------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|
| ```Headers(`key`, `value`)``` | Check if there is a key `key`defined in the headers, with the value `value` | | ```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` | | ```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`. | | ```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. | | ```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. | | ```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`) | | ```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. | | ```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. | | ```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. | | ```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. | | ```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" !!! 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. 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. 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" !!! info "Combining Matchers Using Operators and Parenthesis"

View file

@ -84,6 +84,9 @@ func (p middlewareBuilder) createConfig(config map[string]interface{}) (reflect.
} }
vConfig := results[0] vConfig := results[0]
if len(config) == 0 {
return vConfig, nil
}
cfg := &mapstructure.DecoderConfig{ cfg := &mapstructure.DecoderConfig{
DecodeHook: mapstructure.StringToSliceHookFunc(","), DecodeHook: mapstructure.StringToSliceHookFunc(","),

View file

@ -2,7 +2,6 @@ package middleware
import ( import (
"errors" "errors"
"fmt"
"github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/plugins" "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") return "", nil, errors.New("missing plugin type")
} }
if len(rawPluginConfig) == 0 {
return "", nil, fmt.Errorf("missing plugin configuration: %s", pluginType)
}
return pluginType, rawPluginConfig, nil return pluginType, rawPluginConfig, nil
} }