feat: labels/annotations parser.
This commit is contained in:
parent
dc74f76a03
commit
ce6bbbaa33
8 changed files with 1361 additions and 14 deletions
|
@ -56,7 +56,7 @@ func runStoreConfig(kv *staert.KvSource, traefikConfiguration *TraefikConfigurat
|
|||
}
|
||||
|
||||
stdlog.Printf("Storing file configuration: %s\n", jsonConf)
|
||||
config, err := fileConfig.LoadConfig()
|
||||
config, err := fileConfig.BuildConfiguration()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -95,8 +95,8 @@ func (p *Provider) scanTable(client *dynamoClient) ([]map[string]*dynamodb.Attri
|
|||
return items, nil
|
||||
}
|
||||
|
||||
// loadDynamoConfig retrieves items from dynamodb and converts them into Backends and Frontends in a Configuration
|
||||
func (p *Provider) loadDynamoConfig(client *dynamoClient) (*types.Configuration, error) {
|
||||
// buildConfiguration retrieves items from dynamodb and converts them into Backends and Frontends in a Configuration
|
||||
func (p *Provider) buildConfiguration(client *dynamoClient) (*types.Configuration, error) {
|
||||
items, err := p.scanTable(client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -167,7 +167,7 @@ func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *s
|
|||
return handleCanceled(ctx, err)
|
||||
}
|
||||
|
||||
configuration, err := p.loadDynamoConfig(awsClient)
|
||||
configuration, err := p.buildConfiguration(awsClient)
|
||||
if err != nil {
|
||||
return handleCanceled(ctx, err)
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *s
|
|||
log.Debug("Watching Provider...")
|
||||
select {
|
||||
case <-reload.C:
|
||||
configuration, err := p.loadDynamoConfig(awsClient)
|
||||
configuration, err := p.buildConfiguration(awsClient)
|
||||
if err != nil {
|
||||
return handleCanceled(ctx, err)
|
||||
}
|
||||
|
|
|
@ -84,14 +84,14 @@ func (m *mockDynamoDBClient) ScanPages(input *dynamodb.ScanInput, fn func(*dynam
|
|||
return nil
|
||||
}
|
||||
|
||||
func TestLoadDynamoConfigSuccessful(t *testing.T) {
|
||||
func TestBuildConfigurationSuccessful(t *testing.T) {
|
||||
dbiface := &dynamoClient{
|
||||
db: &mockDynamoDBClient{
|
||||
testWithError: false,
|
||||
},
|
||||
}
|
||||
provider := Provider{}
|
||||
loadedConfig, err := provider.loadDynamoConfig(dbiface)
|
||||
loadedConfig, err := provider.buildConfiguration(dbiface)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -108,14 +108,14 @@ func TestLoadDynamoConfigSuccessful(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestLoadDynamoConfigFailure(t *testing.T) {
|
||||
func TestBuildConfigurationFailure(t *testing.T) {
|
||||
dbiface := &dynamoClient{
|
||||
db: &mockDynamoDBClient{
|
||||
testWithError: true,
|
||||
},
|
||||
}
|
||||
provider := Provider{}
|
||||
_, err := provider.loadDynamoConfig(dbiface)
|
||||
_, err := provider.buildConfiguration(dbiface)
|
||||
if err == nil {
|
||||
t.Fatal("Expected error")
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ type Provider struct {
|
|||
// Provide allows the file provider to provide configurations to traefik
|
||||
// using the given configuration channel.
|
||||
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
|
||||
configuration, err := p.LoadConfig()
|
||||
configuration, err := p.BuildConfiguration()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -52,9 +52,9 @@ func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *s
|
|||
return nil
|
||||
}
|
||||
|
||||
// LoadConfig loads configuration either from file or a directory specified by 'Filename'/'Directory'
|
||||
// BuildConfiguration loads configuration either from file or a directory specified by 'Filename'/'Directory'
|
||||
// and returns a 'Configuration' object
|
||||
func (p *Provider) LoadConfig() (*types.Configuration, error) {
|
||||
func (p *Provider) BuildConfiguration() (*types.Configuration, error) {
|
||||
if p.Directory != "" {
|
||||
return loadFileConfigFromDirectory(p.Directory, nil)
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ func (p *Provider) watcherCallback(configurationChan chan<- types.ConfigMessage,
|
|||
return
|
||||
}
|
||||
|
||||
configuration, err := p.LoadConfig()
|
||||
configuration, err := p.BuildConfiguration()
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("Error occurred during watcher callback: %s", err)
|
||||
|
|
273
provider/label/label.go
Normal file
273
provider/label/label.go
Normal file
|
@ -0,0 +1,273 @@
|
|||
package label
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containous/traefik/log"
|
||||
)
|
||||
|
||||
const (
|
||||
mapEntrySeparator = "||"
|
||||
mapValueSeparator = ":"
|
||||
)
|
||||
|
||||
// Default values
|
||||
const (
|
||||
DefaultWeight = "0"
|
||||
DefaultProtocol = "http"
|
||||
DefaultPassHostHeader = "true"
|
||||
DefaultFrontendPriority = "0"
|
||||
DefaultCircuitBreakerExpression = "NetworkErrorRatio() > 1"
|
||||
DefaultFrontendRedirect = ""
|
||||
DefaultBackendLoadBalancerMethod = "wrr"
|
||||
DefaultBackendMaxconnExtractorFunc = "request.host"
|
||||
DefaultBackendLoadbalancerStickinessCookieName = ""
|
||||
)
|
||||
|
||||
// ServicesPropertiesRegexp used to extract the name of the service and the name of the property for this service
|
||||
// All properties are under the format traefik.<servicename>.frontend.*= except the port/portIndex/weight/protocol/backend directly after traefik.<servicename>.
|
||||
var ServicesPropertiesRegexp = regexp.MustCompile(`^traefik\.(?P<service_name>.+?)\.(?P<property_name>port|portIndex|weight|protocol|backend|frontend\.(.+))$`)
|
||||
|
||||
// PortRegexp used to extract the port label of the service
|
||||
var PortRegexp = regexp.MustCompile(`^traefik\.(?P<service_name>.+?)\.port$`)
|
||||
|
||||
// ServicePropertyValues is a map of services properties
|
||||
// an example value is: weight=42
|
||||
type ServicePropertyValues map[string]string
|
||||
|
||||
// ServiceProperties is a map of service properties per service,
|
||||
// which we can get with label[serviceName][propertyName].
|
||||
// It yields a property value.
|
||||
type ServiceProperties map[string]ServicePropertyValues
|
||||
|
||||
// GetStringValue get string value associated to a label
|
||||
func GetStringValue(labels map[string]string, labelName string, defaultValue string) string {
|
||||
if value, ok := labels[labelName]; ok && len(value) > 0 {
|
||||
return value
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// GetStringValueP get string value associated to a label
|
||||
func GetStringValueP(labels *map[string]string, labelName string, defaultValue string) string {
|
||||
if labels == nil {
|
||||
return defaultValue
|
||||
}
|
||||
return GetStringValue(*labels, labelName, defaultValue)
|
||||
}
|
||||
|
||||
// GetBoolValue get bool value associated to a label
|
||||
func GetBoolValue(labels map[string]string, labelName string, defaultValue bool) bool {
|
||||
rawValue, ok := labels[labelName]
|
||||
if ok {
|
||||
v, err := strconv.ParseBool(rawValue)
|
||||
if err == nil {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// GetIntValue get int value associated to a label
|
||||
func GetIntValue(labels map[string]string, labelName string, defaultValue int) int {
|
||||
if rawValue, ok := labels[labelName]; ok {
|
||||
value, err := strconv.Atoi(rawValue)
|
||||
if err == nil {
|
||||
return value
|
||||
}
|
||||
log.Errorf("Unable to parse %q: %q, falling back to %v. %v", labelName, rawValue, defaultValue, err)
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// GetIntValueP get int value associated to a label
|
||||
func GetIntValueP(labels *map[string]string, labelName string, defaultValue int) int {
|
||||
if labels == nil {
|
||||
return defaultValue
|
||||
}
|
||||
return GetIntValue(*labels, labelName, defaultValue)
|
||||
}
|
||||
|
||||
// GetInt64Value get int64 value associated to a label
|
||||
func GetInt64Value(labels map[string]string, labelName string, defaultValue int64) int64 {
|
||||
if rawValue, ok := labels[labelName]; ok {
|
||||
value, err := strconv.ParseInt(rawValue, 10, 64)
|
||||
if err == nil {
|
||||
return value
|
||||
}
|
||||
log.Errorf("Unable to parse %q: %q, falling back to %v. %v", labelName, rawValue, defaultValue, err)
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// GetInt64ValueP get int64 value associated to a label
|
||||
func GetInt64ValueP(labels *map[string]string, labelName string, defaultValue int64) int64 {
|
||||
if labels == nil {
|
||||
return defaultValue
|
||||
}
|
||||
return GetInt64Value(*labels, labelName, defaultValue)
|
||||
}
|
||||
|
||||
// GetSliceStringValue get a slice of string associated to a label
|
||||
func GetSliceStringValue(labels map[string]string, labelName string) []string {
|
||||
var value []string
|
||||
|
||||
if values, ok := labels[labelName]; ok {
|
||||
value = SplitAndTrimString(values, ",")
|
||||
|
||||
if len(value) == 0 {
|
||||
log.Debugf("Could not load %q.", labelName)
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// GetSliceStringValueP get a slice of string value associated to a label
|
||||
func GetSliceStringValueP(labels *map[string]string, labelName string) []string {
|
||||
if labels == nil {
|
||||
return nil
|
||||
}
|
||||
return GetSliceStringValue(*labels, labelName)
|
||||
}
|
||||
|
||||
// GetMapValue get Map value associated to a label
|
||||
func GetMapValue(labels map[string]string, labelName string) map[string]string {
|
||||
if values, ok := labels[labelName]; ok {
|
||||
|
||||
if len(values) == 0 {
|
||||
log.Errorf("Missing value for %q, skipping...", labelName)
|
||||
return nil
|
||||
}
|
||||
|
||||
mapValue := make(map[string]string)
|
||||
|
||||
for _, parts := range strings.Split(values, mapEntrySeparator) {
|
||||
pair := strings.SplitN(parts, mapValueSeparator, 2)
|
||||
if len(pair) != 2 {
|
||||
log.Warnf("Could not load %q: %q, skipping...", labelName, parts)
|
||||
} else {
|
||||
mapValue[http.CanonicalHeaderKey(strings.TrimSpace(pair[0]))] = strings.TrimSpace(pair[1])
|
||||
}
|
||||
}
|
||||
|
||||
if len(mapValue) == 0 {
|
||||
log.Errorf("Could not load %q, skipping...", labelName)
|
||||
return nil
|
||||
}
|
||||
return mapValue
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetStringMultipleStrict get multiple string values associated to several labels
|
||||
// Fail if one label is missing
|
||||
func GetStringMultipleStrict(labels map[string]string, labelNames ...string) (map[string]string, error) {
|
||||
foundLabels := map[string]string{}
|
||||
for _, name := range labelNames {
|
||||
value := GetStringValue(labels, name, "")
|
||||
// Error out only if one of them is not defined.
|
||||
if len(value) == 0 {
|
||||
return nil, fmt.Errorf("label not found: %s", name)
|
||||
}
|
||||
foundLabels[name] = value
|
||||
}
|
||||
return foundLabels, nil
|
||||
}
|
||||
|
||||
// Has Check if a value is associated to a label
|
||||
func Has(labels map[string]string, labelName string) bool {
|
||||
value, ok := labels[labelName]
|
||||
return ok && len(value) > 0
|
||||
}
|
||||
|
||||
// HasP Check if a value is associated to a label
|
||||
func HasP(labels *map[string]string, labelName string) bool {
|
||||
if labels == nil {
|
||||
return false
|
||||
}
|
||||
return Has(*labels, labelName)
|
||||
}
|
||||
|
||||
// ExtractServiceProperties Extract services labels
|
||||
func ExtractServiceProperties(labels map[string]string) ServiceProperties {
|
||||
v := make(ServiceProperties)
|
||||
|
||||
for name, value := range labels {
|
||||
matches := ServicesPropertiesRegexp.FindStringSubmatch(name)
|
||||
if matches == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var serviceName string
|
||||
var propertyName string
|
||||
for i, name := range ServicesPropertiesRegexp.SubexpNames() {
|
||||
if i != 0 {
|
||||
if name == "service_name" {
|
||||
serviceName = matches[i]
|
||||
} else if name == "property_name" {
|
||||
propertyName = matches[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := v[serviceName]; !ok {
|
||||
v[serviceName] = make(ServicePropertyValues)
|
||||
}
|
||||
v[serviceName][propertyName] = value
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// ExtractServicePropertiesP Extract services labels
|
||||
func ExtractServicePropertiesP(labels *map[string]string) ServiceProperties {
|
||||
if labels == nil {
|
||||
return make(ServiceProperties)
|
||||
}
|
||||
return ExtractServiceProperties(*labels)
|
||||
}
|
||||
|
||||
// IsEnabled Check if a container is enabled in Træfik
|
||||
func IsEnabled(labels map[string]string, exposedByDefault bool) bool {
|
||||
return GetBoolValue(labels, TraefikEnable, exposedByDefault)
|
||||
}
|
||||
|
||||
// IsEnabledP Check if a container is enabled in Træfik
|
||||
func IsEnabledP(labels *map[string]string, exposedByDefault bool) bool {
|
||||
if labels == nil {
|
||||
return exposedByDefault
|
||||
}
|
||||
return IsEnabled(*labels, exposedByDefault)
|
||||
}
|
||||
|
||||
// SplitAndTrimString splits separatedString at the separator character and trims each
|
||||
// piece, filtering out empty pieces. Returns the list of pieces or nil if the input
|
||||
// did not contain a non-empty piece.
|
||||
func SplitAndTrimString(base string, sep string) []string {
|
||||
var trimmedStrings []string
|
||||
|
||||
for _, s := range strings.Split(base, sep) {
|
||||
s = strings.TrimSpace(s)
|
||||
if len(s) > 0 {
|
||||
trimmedStrings = append(trimmedStrings, s)
|
||||
}
|
||||
}
|
||||
|
||||
return trimmedStrings
|
||||
}
|
||||
|
||||
// GetServiceLabel converts a key value of Label*, given a serviceName,
|
||||
// into a pattern <LabelPrefix>.<serviceName>.<property>
|
||||
// i.e. For LabelFrontendRule and serviceName=app it will return "traefik.app.frontend.rule"
|
||||
func GetServiceLabel(labelName, serviceName string) string {
|
||||
if len(serviceName) > 0 {
|
||||
property := strings.TrimPrefix(labelName, Prefix)
|
||||
return Prefix + serviceName + "." + property
|
||||
}
|
||||
return labelName
|
||||
}
|
969
provider/label/label_test.go
Normal file
969
provider/label/label_test.go
Normal file
|
@ -0,0 +1,969 @@
|
|||
package label
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSplitAndTrimString(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
input string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
desc: "empty string",
|
||||
input: "",
|
||||
expected: nil,
|
||||
}, {
|
||||
desc: "one piece",
|
||||
input: "foo",
|
||||
expected: []string{"foo"},
|
||||
}, {
|
||||
desc: "two pieces",
|
||||
input: "foo,bar",
|
||||
expected: []string{"foo", "bar"},
|
||||
}, {
|
||||
desc: "three pieces",
|
||||
input: "foo,bar,zoo",
|
||||
expected: []string{"foo", "bar", "zoo"},
|
||||
}, {
|
||||
desc: "two pieces with whitespace",
|
||||
input: " foo , bar ",
|
||||
expected: []string{"foo", "bar"},
|
||||
}, {
|
||||
desc: "consecutive commas",
|
||||
input: " foo ,, bar ",
|
||||
expected: []string{"foo", "bar"},
|
||||
}, {
|
||||
desc: "consecutive commas with whitespace",
|
||||
input: " foo , , bar ",
|
||||
expected: []string{"foo", "bar"},
|
||||
}, {
|
||||
desc: "leading and trailing commas",
|
||||
input: ",, foo , , bar,, , ",
|
||||
expected: []string{"foo", "bar"},
|
||||
}, {
|
||||
desc: "no valid pieces",
|
||||
input: ", , , ,, ,",
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
actual := SplitAndTrimString(test.input, ",")
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetStringValue(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
labelName string
|
||||
defaultValue string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "empty labels map",
|
||||
labelName: "foo",
|
||||
defaultValue: "default",
|
||||
expected: "default",
|
||||
},
|
||||
{
|
||||
desc: "existing label",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "foo",
|
||||
defaultValue: "default",
|
||||
expected: "bar",
|
||||
},
|
||||
{
|
||||
desc: "non existing label",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "fii",
|
||||
defaultValue: "default",
|
||||
expected: "default",
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetStringValue(test.labels, test.labelName, test.defaultValue)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetStringValueP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels *map[string]string
|
||||
labelName string
|
||||
defaultValue string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "nil labels map",
|
||||
labels: nil,
|
||||
labelName: "foo",
|
||||
defaultValue: "default",
|
||||
expected: "default",
|
||||
},
|
||||
{
|
||||
desc: "existing label",
|
||||
labels: &map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "foo",
|
||||
defaultValue: "default",
|
||||
expected: "bar",
|
||||
},
|
||||
{
|
||||
desc: "non existing label",
|
||||
labels: &map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "fii",
|
||||
defaultValue: "default",
|
||||
expected: "default",
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetStringValueP(test.labels, test.labelName, test.defaultValue)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBoolValue(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
labelName string
|
||||
defaultValue bool
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
desc: "empty map",
|
||||
labelName: "foo",
|
||||
},
|
||||
{
|
||||
desc: "invalid boolean value",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "foo",
|
||||
defaultValue: true,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "valid boolean value: true",
|
||||
labels: map[string]string{
|
||||
"foo": "true",
|
||||
},
|
||||
labelName: "foo",
|
||||
defaultValue: false,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "valid boolean value: false",
|
||||
labels: map[string]string{
|
||||
"foo": "false",
|
||||
},
|
||||
labelName: "foo",
|
||||
defaultValue: true,
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetBoolValue(test.labels, test.labelName, test.defaultValue)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetIntValue(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
labelName string
|
||||
defaultValue int
|
||||
expected int
|
||||
}{
|
||||
{
|
||||
desc: "empty map",
|
||||
labelName: "foo",
|
||||
},
|
||||
{
|
||||
desc: "invalid int value",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: 666,
|
||||
},
|
||||
{
|
||||
desc: "negative int value",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": "-1",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: -1,
|
||||
},
|
||||
{
|
||||
desc: "positive int value",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": "1",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: 1,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetIntValue(test.labels, test.labelName, test.defaultValue)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetIntValueP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels *map[string]string
|
||||
labelName string
|
||||
defaultValue int
|
||||
expected int
|
||||
}{
|
||||
{
|
||||
desc: "nil map",
|
||||
labels: nil,
|
||||
labelName: "foo",
|
||||
defaultValue: 666,
|
||||
expected: 666,
|
||||
},
|
||||
{
|
||||
desc: "invalid int value",
|
||||
labelName: "foo",
|
||||
labels: &map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: 666,
|
||||
},
|
||||
{
|
||||
desc: "negative int value",
|
||||
labelName: "foo",
|
||||
labels: &map[string]string{
|
||||
"foo": "-1",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: -1,
|
||||
},
|
||||
{
|
||||
desc: "positive int value",
|
||||
labelName: "foo",
|
||||
labels: &map[string]string{
|
||||
"foo": "1",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: 1,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetIntValueP(test.labels, test.labelName, test.defaultValue)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetInt64Value(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
labelName string
|
||||
defaultValue int64
|
||||
expected int64
|
||||
}{
|
||||
{
|
||||
desc: "empty map",
|
||||
labelName: "foo",
|
||||
},
|
||||
{
|
||||
desc: "invalid int value",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: 666,
|
||||
},
|
||||
{
|
||||
desc: "negative int value",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": "-1",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: -1,
|
||||
},
|
||||
{
|
||||
desc: "positive int value",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": "1",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: 1,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetInt64Value(test.labels, test.labelName, test.defaultValue)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetInt64ValueP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels *map[string]string
|
||||
labelName string
|
||||
defaultValue int64
|
||||
expected int64
|
||||
}{
|
||||
{
|
||||
desc: "nil map",
|
||||
labels: nil,
|
||||
labelName: "foo",
|
||||
defaultValue: 666,
|
||||
expected: 666,
|
||||
},
|
||||
{
|
||||
desc: "invalid int value",
|
||||
labelName: "foo",
|
||||
labels: &map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: 666,
|
||||
},
|
||||
{
|
||||
desc: "negative int value",
|
||||
labelName: "foo",
|
||||
labels: &map[string]string{
|
||||
"foo": "-1",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: -1,
|
||||
},
|
||||
{
|
||||
desc: "positive int value",
|
||||
labelName: "foo",
|
||||
labels: &map[string]string{
|
||||
"foo": "1",
|
||||
},
|
||||
defaultValue: 666,
|
||||
expected: 1,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetInt64ValueP(test.labels, test.labelName, test.defaultValue)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSliceStringValue(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
labelName string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
desc: "empty map",
|
||||
labelName: "foo",
|
||||
},
|
||||
{
|
||||
desc: "empty value",
|
||||
labels: map[string]string{
|
||||
"foo": "",
|
||||
},
|
||||
labelName: "foo",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "one value, not split",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "foo",
|
||||
expected: []string{"bar"},
|
||||
},
|
||||
{
|
||||
desc: "several values",
|
||||
labels: map[string]string{
|
||||
"foo": "bar,bir ,bur",
|
||||
},
|
||||
labelName: "foo",
|
||||
expected: []string{"bar", "bir", "bur"},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetSliceStringValue(test.labels, test.labelName)
|
||||
assert.EqualValues(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSliceStringValueP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels *map[string]string
|
||||
labelName string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
desc: "nil map",
|
||||
labels: nil,
|
||||
labelName: "foo",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "one value, not split",
|
||||
labels: &map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "foo",
|
||||
expected: []string{"bar"},
|
||||
},
|
||||
{
|
||||
desc: "several values",
|
||||
labels: &map[string]string{
|
||||
"foo": "bar,bir ,bur",
|
||||
},
|
||||
labelName: "foo",
|
||||
expected: []string{"bar", "bir", "bur"},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetSliceStringValueP(test.labels, test.labelName)
|
||||
assert.EqualValues(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMapValue(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
labelName string
|
||||
expected map[string]string
|
||||
}{
|
||||
{
|
||||
desc: "empty map",
|
||||
labelName: "foo",
|
||||
},
|
||||
{
|
||||
desc: "existent label with empty entry",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": "",
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "existent label with invalid entry",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "existent label with empty value",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": "bar:",
|
||||
},
|
||||
expected: map[string]string{
|
||||
"Bar": "",
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "one entry",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": " Access-Control-Allow-Methods:POST,GET,OPTIONS ",
|
||||
},
|
||||
expected: map[string]string{
|
||||
"Access-Control-Allow-Methods": "POST,GET,OPTIONS",
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "several entry",
|
||||
labelName: "foo",
|
||||
labels: map[string]string{
|
||||
"foo": "Access-Control-Allow-Methods:POST,GET,OPTIONS || Content-type: application/json; charset=utf-8",
|
||||
},
|
||||
expected: map[string]string{
|
||||
"Access-Control-Allow-Methods": "POST,GET,OPTIONS",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetMapValue(test.labels, test.labelName)
|
||||
assert.EqualValues(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetStringMultipleStrict(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
labelNames []string
|
||||
expected map[string]string
|
||||
expectedErr bool
|
||||
}{
|
||||
{
|
||||
desc: "empty labels names and empty labels map",
|
||||
labels: map[string]string{},
|
||||
expected: map[string]string{},
|
||||
},
|
||||
{
|
||||
desc: "empty labels names",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
"fii": "bir",
|
||||
},
|
||||
expected: map[string]string{},
|
||||
},
|
||||
{
|
||||
desc: "one label missing",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
"fii": "bir",
|
||||
"fyy": "byr",
|
||||
},
|
||||
labelNames: []string{"foo", "fii", "fuu"},
|
||||
expected: nil,
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
desc: "all labels are present",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
"fii": "bir",
|
||||
"fyy": "byr",
|
||||
},
|
||||
labelNames: []string{"foo", "fii"},
|
||||
expected: map[string]string{
|
||||
"foo": "bar",
|
||||
"fii": "bir",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got, err := GetStringMultipleStrict(test.labels, test.labelNames...)
|
||||
if (err != nil) != test.expectedErr {
|
||||
t.Errorf("error = %v, wantErr %v", err, test.expectedErr)
|
||||
return
|
||||
}
|
||||
assert.EqualValues(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHas(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
labelName string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
desc: "nil labels map",
|
||||
labelName: "foo",
|
||||
},
|
||||
{
|
||||
desc: "nonexistent label",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "fii",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
desc: "existent label",
|
||||
labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "foo",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "existent label with empty value",
|
||||
labels: map[string]string{
|
||||
"foo": "",
|
||||
},
|
||||
labelName: "foo",
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := Has(test.labels, test.labelName)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels *map[string]string
|
||||
labelName string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
desc: "nil labels map",
|
||||
labelName: "foo",
|
||||
},
|
||||
{
|
||||
desc: "nonexistent label",
|
||||
labels: &map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "fii",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
desc: "existent label",
|
||||
labels: &map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
labelName: "foo",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "existent label with empty value",
|
||||
labels: &map[string]string{
|
||||
"foo": "",
|
||||
},
|
||||
labelName: "foo",
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := HasP(test.labels, test.labelName)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractServiceProperties(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
expected ServiceProperties
|
||||
}{
|
||||
{
|
||||
desc: "empty labels map",
|
||||
expected: ServiceProperties{},
|
||||
},
|
||||
{
|
||||
desc: "valid label names",
|
||||
labels: map[string]string{
|
||||
"traefik.foo.port": "bar",
|
||||
"traefik.foo.frontend.bar": "1bar",
|
||||
"traefik.foo.frontend.": "2bar",
|
||||
},
|
||||
expected: ServiceProperties{
|
||||
"foo": ServicePropertyValues{
|
||||
"port": "bar",
|
||||
"frontend.bar": "1bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "invalid label names",
|
||||
labels: map[string]string{
|
||||
"foo.frontend.bar": "1bar",
|
||||
"traefik.foo.frontend.": "2bar",
|
||||
"traefik.foo.port.bar": "barbar",
|
||||
"traefik.foo.frontend": "0bar",
|
||||
},
|
||||
expected: ServiceProperties{},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := ExtractServiceProperties(test.labels)
|
||||
assert.EqualValues(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractServicePropertiesP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels *map[string]string
|
||||
expected ServiceProperties
|
||||
}{
|
||||
{
|
||||
desc: "nil labels map",
|
||||
expected: ServiceProperties{},
|
||||
},
|
||||
{
|
||||
desc: "valid label names",
|
||||
labels: &map[string]string{
|
||||
"traefik.foo.port": "bar",
|
||||
"traefik.foo.frontend.bar": "1bar",
|
||||
"traefik.foo.frontend.": "2bar",
|
||||
},
|
||||
expected: ServiceProperties{
|
||||
"foo": ServicePropertyValues{
|
||||
"port": "bar",
|
||||
"frontend.bar": "1bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "invalid label names",
|
||||
labels: &map[string]string{
|
||||
"foo.frontend.bar": "1bar",
|
||||
"traefik.foo.frontend.": "2bar",
|
||||
"traefik.foo.port.bar": "barbar",
|
||||
"traefik.foo.frontend": "0bar",
|
||||
},
|
||||
expected: ServiceProperties{},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := ExtractServicePropertiesP(test.labels)
|
||||
assert.EqualValues(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsEnabled(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
exposedByDefault bool
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
desc: "empty labels map & exposedByDefault true",
|
||||
exposedByDefault: true,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "empty labels map & exposedByDefault false",
|
||||
exposedByDefault: false,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
desc: "exposedByDefault false and label enable true",
|
||||
labels: map[string]string{
|
||||
TraefikEnable: "true",
|
||||
},
|
||||
exposedByDefault: false,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "exposedByDefault false and label enable false",
|
||||
labels: map[string]string{
|
||||
TraefikEnable: "false",
|
||||
},
|
||||
exposedByDefault: false,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
desc: "exposedByDefault true and label enable false",
|
||||
labels: map[string]string{
|
||||
TraefikEnable: "false",
|
||||
},
|
||||
exposedByDefault: true,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
desc: "exposedByDefault true and label enable true",
|
||||
labels: map[string]string{
|
||||
TraefikEnable: "true",
|
||||
},
|
||||
exposedByDefault: true,
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := IsEnabled(test.labels, test.exposedByDefault)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsEnabledP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels *map[string]string
|
||||
exposedByDefault bool
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
desc: "nil labels map & exposedByDefault true",
|
||||
exposedByDefault: true,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "nil labels map & exposedByDefault false",
|
||||
exposedByDefault: false,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
desc: "exposedByDefault false and label enable true",
|
||||
labels: &map[string]string{
|
||||
TraefikEnable: "true",
|
||||
},
|
||||
exposedByDefault: false,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "exposedByDefault false and label enable false",
|
||||
labels: &map[string]string{
|
||||
TraefikEnable: "false",
|
||||
},
|
||||
exposedByDefault: false,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
desc: "exposedByDefault true and label enable false",
|
||||
labels: &map[string]string{
|
||||
TraefikEnable: "false",
|
||||
},
|
||||
exposedByDefault: true,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
desc: "exposedByDefault true and label enable true",
|
||||
labels: &map[string]string{
|
||||
TraefikEnable: "true",
|
||||
},
|
||||
exposedByDefault: true,
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := IsEnabledP(test.labels, test.exposedByDefault)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServiceLabel(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labelName string
|
||||
serviceName string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "without service name",
|
||||
labelName: TraefikPort,
|
||||
expected: TraefikPort,
|
||||
},
|
||||
{
|
||||
desc: "with service name",
|
||||
labelName: TraefikPort,
|
||||
serviceName: "bar",
|
||||
expected: "traefik.bar.port",
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetServiceLabel(test.labelName, test.serviceName)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
105
provider/label/names.go
Normal file
105
provider/label/names.go
Normal file
|
@ -0,0 +1,105 @@
|
|||
package label
|
||||
|
||||
// Traefik labels
|
||||
const (
|
||||
Prefix = "traefik."
|
||||
SuffixBackend = "backend"
|
||||
SuffixDomain = "domain"
|
||||
SuffixEnable = "enable"
|
||||
SuffixPort = "port"
|
||||
SuffixPortIndex = "portIndex"
|
||||
SuffixProtocol = "protocol"
|
||||
SuffixTags = "tags"
|
||||
SuffixWeight = "weight"
|
||||
SuffixBackendID = "backend.id"
|
||||
SuffixBackendCircuitBreaker = "backend.circuitbreaker"
|
||||
SuffixBackendCircuitBreakerExpression = "backend.circuitbreaker.expression"
|
||||
SuffixBackendHealthCheckPath = "backend.healthcheck.path"
|
||||
SuffixBackendHealthCheckInterval = "backend.healthcheck.interval"
|
||||
SuffixBackendLoadBalancerMethod = "backend.loadbalancer.method"
|
||||
SuffixBackendLoadBalancerSticky = "backend.loadbalancer.sticky"
|
||||
SuffixBackendLoadBalancerStickiness = "backend.loadbalancer.stickiness"
|
||||
SuffixBackendLoadBalancerStickinessCookieName = "backend.loadbalancer.stickiness.cookieName"
|
||||
SuffixBackendMaxConnAmount = "backend.maxconn.amount"
|
||||
SuffixBackendMaxConnExtractorFunc = "backend.maxconn.extractorfunc"
|
||||
SuffixFrontendAuthBasic = "frontend.auth.basic"
|
||||
SuffixFrontendBackend = "frontend.backend"
|
||||
SuffixFrontendEntryPoints = "frontend.entryPoints"
|
||||
SuffixFrontendRequestHeaders = "frontend.headers.customRequestHeaders"
|
||||
SuffixFrontendResponseHeaders = "frontend.headers.customResponseHeaders"
|
||||
SuffixFrontendHeadersAllowedHosts = "frontend.headers.allowedHosts"
|
||||
SuffixFrontendHeadersHostsProxyHeaders = "frontend.headers.hostsProxyHeaders"
|
||||
SuffixFrontendHeadersSSLRedirect = "frontend.headers.SSLRedirect"
|
||||
SuffixFrontendHeadersSSLTemporaryRedirect = "frontend.headers.SSLTemporaryRedirect"
|
||||
SuffixFrontendHeadersSSLHost = "frontend.headers.SSLHost"
|
||||
SuffixFrontendHeadersSSLProxyHeaders = "frontend.headers.SSLProxyHeaders"
|
||||
SuffixFrontendHeadersSTSSeconds = "frontend.headers.STSSeconds"
|
||||
SuffixFrontendHeadersSTSIncludeSubdomains = "frontend.headers.STSIncludeSubdomains"
|
||||
SuffixFrontendHeadersSTSPreload = "frontend.headers.STSPreload"
|
||||
SuffixFrontendHeadersForceSTSHeader = "frontend.headers.forceSTSHeader"
|
||||
SuffixFrontendHeadersFrameDeny = "frontend.headers.frameDeny"
|
||||
SuffixFrontendHeadersCustomFrameOptionsValue = "frontend.headers.customFrameOptionsValue"
|
||||
SuffixFrontendHeadersContentTypeNosniff = "frontend.headers.contentTypeNosniff"
|
||||
SuffixFrontendHeadersBrowserXSSFilter = "frontend.headers.browserXSSFilter"
|
||||
SuffixFrontendHeadersContentSecurityPolicy = "frontend.headers.contentSecurityPolicy"
|
||||
SuffixFrontendHeadersPublicKey = "frontend.headers.publicKey"
|
||||
SuffixFrontendHeadersReferrerPolicy = "frontend.headers.referrerPolicy"
|
||||
SuffixFrontendHeadersIsDevelopment = "frontend.headers.isDevelopment"
|
||||
SuffixFrontendPassHostHeader = "frontend.passHostHeader"
|
||||
SuffixFrontendPassTLSCert = "frontend.passTLSCert"
|
||||
SuffixFrontendPriority = "frontend.priority"
|
||||
SuffixFrontendRedirect = "frontend.redirect"
|
||||
SuffixFrontendRule = "frontend.rule"
|
||||
SuffixFrontendRuleType = "frontend.rule.type"
|
||||
SuffixFrontendWhitelistSourceRange = "frontend.whitelistSourceRange"
|
||||
SuffixFrontendValue = "frontend.value"
|
||||
TraefikDomain = Prefix + SuffixDomain
|
||||
TraefikEnable = Prefix + SuffixEnable
|
||||
TraefikPort = Prefix + SuffixPort
|
||||
TraefikPortIndex = Prefix + SuffixPortIndex
|
||||
TraefikProtocol = Prefix + SuffixProtocol
|
||||
TraefikTags = Prefix + SuffixTags
|
||||
TraefikWeight = Prefix + SuffixWeight
|
||||
TraefikBackend = Prefix + SuffixBackend
|
||||
TraefikBackendID = Prefix + SuffixBackendID
|
||||
TraefikBackendCircuitBreaker = Prefix + SuffixBackendCircuitBreaker
|
||||
TraefikBackendCircuitBreakerExpression = Prefix + SuffixBackendCircuitBreakerExpression
|
||||
TraefikBackendHealthCheckPath = Prefix + SuffixBackendHealthCheckPath
|
||||
TraefikBackendHealthCheckInterval = Prefix + SuffixBackendHealthCheckInterval
|
||||
TraefikBackendLoadBalancerMethod = Prefix + SuffixBackendLoadBalancerMethod
|
||||
TraefikBackendLoadBalancerSticky = Prefix + SuffixBackendLoadBalancerSticky
|
||||
TraefikBackendLoadBalancerStickiness = Prefix + SuffixBackendLoadBalancerStickiness
|
||||
TraefikBackendLoadBalancerStickinessCookieName = Prefix + SuffixBackendLoadBalancerStickinessCookieName
|
||||
TraefikBackendMaxConnAmount = Prefix + SuffixBackendMaxConnAmount
|
||||
TraefikBackendMaxConnExtractorFunc = Prefix + SuffixBackendMaxConnExtractorFunc
|
||||
TraefikFrontendAuthBasic = Prefix + SuffixFrontendAuthBasic
|
||||
TraefikFrontendEntryPoints = Prefix + SuffixFrontendEntryPoints
|
||||
TraefikFrontendPassHostHeader = Prefix + SuffixFrontendPassHostHeader
|
||||
TraefikFrontendPassTLSCert = Prefix + SuffixFrontendPassTLSCert
|
||||
TraefikFrontendPriority = Prefix + SuffixFrontendPriority
|
||||
TraefikFrontendRule = Prefix + SuffixFrontendRule
|
||||
TraefikFrontendRuleType = Prefix + SuffixFrontendRuleType
|
||||
TraefikFrontendRedirect = Prefix + SuffixFrontendRedirect
|
||||
TraefikFrontendValue = Prefix + SuffixFrontendValue
|
||||
TraefikFrontendWhitelistSourceRange = Prefix + SuffixFrontendWhitelistSourceRange
|
||||
TraefikFrontendRequestHeaders = Prefix + SuffixFrontendRequestHeaders
|
||||
TraefikFrontendResponseHeaders = Prefix + SuffixFrontendResponseHeaders
|
||||
TraefikFrontendAllowedHosts = Prefix + SuffixFrontendHeadersAllowedHosts
|
||||
TraefikFrontendHostsProxyHeaders = Prefix + SuffixFrontendHeadersHostsProxyHeaders
|
||||
TraefikFrontendSSLRedirect = Prefix + SuffixFrontendHeadersSSLRedirect
|
||||
TraefikFrontendSSLTemporaryRedirect = Prefix + SuffixFrontendHeadersSSLTemporaryRedirect
|
||||
TraefikFrontendSSLHost = Prefix + SuffixFrontendHeadersSSLHost
|
||||
TraefikFrontendSSLProxyHeaders = Prefix + SuffixFrontendHeadersSSLProxyHeaders
|
||||
TraefikFrontendSTSSeconds = Prefix + SuffixFrontendHeadersSTSSeconds
|
||||
TraefikFrontendSTSIncludeSubdomains = Prefix + SuffixFrontendHeadersSTSIncludeSubdomains
|
||||
TraefikFrontendSTSPreload = Prefix + SuffixFrontendHeadersSTSPreload
|
||||
TraefikFrontendForceSTSHeader = Prefix + SuffixFrontendHeadersForceSTSHeader
|
||||
TraefikFrontendFrameDeny = Prefix + SuffixFrontendHeadersFrameDeny
|
||||
TraefikFrontendCustomFrameOptionsValue = Prefix + SuffixFrontendHeadersCustomFrameOptionsValue
|
||||
TraefikFrontendContentTypeNosniff = Prefix + SuffixFrontendHeadersContentTypeNosniff
|
||||
TraefikFrontendBrowserXSSFilter = Prefix + SuffixFrontendHeadersBrowserXSSFilter
|
||||
TraefikFrontendContentSecurityPolicy = Prefix + SuffixFrontendHeadersContentSecurityPolicy
|
||||
TraefikFrontendPublicKey = Prefix + SuffixFrontendHeadersPublicKey
|
||||
TraefikFrontendReferrerPolicy = Prefix + SuffixFrontendHeadersReferrerPolicy
|
||||
TraefikFrontendIsDevelopment = Prefix + SuffixFrontendHeadersIsDevelopment
|
||||
)
|
|
@ -888,7 +888,7 @@ func (s *Server) getRoundTripper(entryPointName string, globalConfiguration conf
|
|||
return s.defaultForwardingRoundTripper, nil
|
||||
}
|
||||
|
||||
// LoadConfig returns a new gorilla.mux Route from the specified global configuration and the dynamic
|
||||
// loadConfig returns a new gorilla.mux Route from the specified global configuration and the dynamic
|
||||
// provider configurations.
|
||||
func (s *Server) loadConfig(configurations types.Configurations, globalConfiguration configuration.GlobalConfiguration) (map[string]*serverEntryPoint, error) {
|
||||
serverEntryPoints := s.buildEntryPoints(globalConfiguration)
|
||||
|
|
Loading…
Reference in a new issue