Merge current v2.8 into v2.9
This commit is contained in:
commit
30ec5c58fe
4 changed files with 40 additions and 17 deletions
|
@ -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).
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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(","),
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue