refactor(k8s): new annotations style.
This commit is contained in:
parent
a4a8345a33
commit
7c80b9a692
3 changed files with 278 additions and 150 deletions
117
provider/kubernetes/annotations.go
Normal file
117
provider/kubernetes/annotations.go
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
package kubernetes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/containous/traefik/provider/label"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
annotationKubernetesIngressClass = "kubernetes.io/ingress.class"
|
||||||
|
annotationKubernetesAuthRealm = "ingress.kubernetes.io/auth-realm"
|
||||||
|
annotationKubernetesAuthType = "ingress.kubernetes.io/auth-type"
|
||||||
|
annotationKubernetesAuthSecret = "ingress.kubernetes.io/auth-secret"
|
||||||
|
annotationKubernetesRewriteTarget = "ingress.kubernetes.io/rewrite-target"
|
||||||
|
annotationKubernetesWhitelistSourceRange = "ingress.kubernetes.io/whitelist-source-range"
|
||||||
|
annotationKubernetesPreserveHost = "ingress.kubernetes.io/preserve-host"
|
||||||
|
annotationKubernetesPassTLSCert = "ingress.kubernetes.io/pass-tls-cert"
|
||||||
|
annotationKubernetesFrontendEntryPoints = "ingress.kubernetes.io/frontend-entry-points"
|
||||||
|
annotationKubernetesPriority = "ingress.kubernetes.io/priority"
|
||||||
|
annotationKubernetesCircuitBreakerExpression = "ingress.kubernetes.io/circuit-breaker-expression"
|
||||||
|
annotationKubernetesLoadBalancerMethod = "ingress.kubernetes.io/load-balancer-method"
|
||||||
|
annotationKubernetesAffinity = "ingress.kubernetes.io/affinity"
|
||||||
|
annotationKubernetesSessionCookieName = "ingress.kubernetes.io/session-cookie-name"
|
||||||
|
annotationKubernetesRuleType = "ingress.kubernetes.io/rule-type"
|
||||||
|
annotationKubernetesRedirectEntryPoint = "ingress.kubernetes.io/redirect-entry-point"
|
||||||
|
annotationKubernetesRedirectRegex = "ingress.kubernetes.io/redirect-regex"
|
||||||
|
annotationKubernetesRedirectReplacement = "ingress.kubernetes.io/redirect-replacement"
|
||||||
|
annotationKubernetesMaxConnAmount = "ingress.kubernetes.io/max-conn-amount"
|
||||||
|
annotationKubernetesMaxConnExtractorFunc = "ingress.kubernetes.io/max-conn-extractor-func"
|
||||||
|
annotationKubernetesRateLimit = "ingress.kubernetes.io/rate-limit"
|
||||||
|
annotationKubernetesErrorPages = "ingress.kubernetes.io/error-pages"
|
||||||
|
annotationKubernetesBuffering = "ingress.kubernetes.io/buffering"
|
||||||
|
|
||||||
|
annotationKubernetesSSLRedirect = "ingress.kubernetes.io/ssl-redirect"
|
||||||
|
annotationKubernetesHSTSMaxAge = "ingress.kubernetes.io/hsts-max-age"
|
||||||
|
annotationKubernetesHSTSIncludeSubdomains = "ingress.kubernetes.io/hsts-include-subdomains"
|
||||||
|
annotationKubernetesCustomRequestHeaders = "ingress.kubernetes.io/custom-request-headers"
|
||||||
|
annotationKubernetesCustomResponseHeaders = "ingress.kubernetes.io/custom-response-headers"
|
||||||
|
annotationKubernetesAllowedHosts = "ingress.kubernetes.io/allowed-hosts"
|
||||||
|
annotationKubernetesProxyHeaders = "ingress.kubernetes.io/proxy-headers"
|
||||||
|
annotationKubernetesSSLTemporaryRedirect = "ingress.kubernetes.io/ssl-temporary-redirect"
|
||||||
|
annotationKubernetesSSLHost = "ingress.kubernetes.io/ssl-host"
|
||||||
|
annotationKubernetesSSLProxyHeaders = "ingress.kubernetes.io/ssl-proxy-headers"
|
||||||
|
annotationKubernetesHSTSPreload = "ingress.kubernetes.io/hsts-preload"
|
||||||
|
annotationKubernetesForceHSTSHeader = "ingress.kubernetes.io/force-hsts"
|
||||||
|
annotationKubernetesFrameDeny = "ingress.kubernetes.io/frame-deny"
|
||||||
|
annotationKubernetesCustomFrameOptionsValue = "ingress.kubernetes.io/custom-frame-options-value"
|
||||||
|
annotationKubernetesContentTypeNosniff = "ingress.kubernetes.io/content-type-nosniff"
|
||||||
|
annotationKubernetesBrowserXSSFilter = "ingress.kubernetes.io/browser-xss-filter"
|
||||||
|
annotationKubernetesContentSecurityPolicy = "ingress.kubernetes.io/content-security-policy"
|
||||||
|
annotationKubernetesPublicKey = "ingress.kubernetes.io/public-key"
|
||||||
|
annotationKubernetesReferrerPolicy = "ingress.kubernetes.io/referrer-policy"
|
||||||
|
annotationKubernetesIsDevelopment = "ingress.kubernetes.io/is-development"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO [breaking] remove label support
|
||||||
|
var compatibilityMapping = map[string]string{
|
||||||
|
annotationKubernetesPreserveHost: "traefik.frontend.passHostHeader",
|
||||||
|
annotationKubernetesPassTLSCert: "traefik.frontend.passTLSCert",
|
||||||
|
annotationKubernetesFrontendEntryPoints: "traefik.frontend.entryPoints",
|
||||||
|
annotationKubernetesPriority: "traefik.frontend.priority",
|
||||||
|
annotationKubernetesCircuitBreakerExpression: "traefik.backend.circuitbreaker",
|
||||||
|
annotationKubernetesLoadBalancerMethod: "traefik.backend.loadbalancer.method",
|
||||||
|
annotationKubernetesAffinity: "traefik.backend.loadbalancer.stickiness",
|
||||||
|
annotationKubernetesSessionCookieName: "traefik.backend.loadbalancer.stickiness.cookieName",
|
||||||
|
annotationKubernetesRuleType: "traefik.frontend.rule.type",
|
||||||
|
annotationKubernetesRedirectEntryPoint: "traefik.frontend.redirect.entrypoint",
|
||||||
|
annotationKubernetesRedirectRegex: "traefik.frontend.redirect.regex",
|
||||||
|
annotationKubernetesRedirectReplacement: "traefik.frontend.redirect.replacement",
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAnnotationName(annotations map[string]string, name string) string {
|
||||||
|
if _, ok := annotations[name]; ok {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := annotations[label.Prefix+name]; ok {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO [breaking] remove label support
|
||||||
|
if lbl, compat := compatibilityMapping[name]; compat {
|
||||||
|
if _, ok := annotations[lbl]; ok {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStringValue(annotations map[string]string, annotation string, defaultValue string) string {
|
||||||
|
annotationName := getAnnotationName(annotations, annotation)
|
||||||
|
return label.GetStringValue(annotations, annotationName, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBoolValue(annotations map[string]string, annotation string, defaultValue bool) bool {
|
||||||
|
annotationName := getAnnotationName(annotations, annotation)
|
||||||
|
return label.GetBoolValue(annotations, annotationName, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIntValue(annotations map[string]string, annotation string, defaultValue int) int {
|
||||||
|
annotationName := getAnnotationName(annotations, annotation)
|
||||||
|
return label.GetIntValue(annotations, annotationName, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getInt64Value(annotations map[string]string, annotation string, defaultValue int64) int64 {
|
||||||
|
annotationName := getAnnotationName(annotations, annotation)
|
||||||
|
return label.GetInt64Value(annotations, annotationName, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSliceStringValue(annotations map[string]string, annotation string) []string {
|
||||||
|
annotationName := getAnnotationName(annotations, annotation)
|
||||||
|
return label.GetSliceStringValue(annotations, annotationName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMapValue(annotations map[string]string, annotation string) map[string]string {
|
||||||
|
annotationName := getAnnotationName(annotations, annotation)
|
||||||
|
return label.GetMapValue(annotations, annotationName)
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/containous/traefik/safe"
|
"github.com/containous/traefik/safe"
|
||||||
"github.com/containous/traefik/tls"
|
"github.com/containous/traefik/tls"
|
||||||
"github.com/containous/traefik/types"
|
"github.com/containous/traefik/types"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
"k8s.io/client-go/pkg/api/v1"
|
"k8s.io/client-go/pkg/api/v1"
|
||||||
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||||
"k8s.io/client-go/pkg/util/intstr"
|
"k8s.io/client-go/pkg/util/intstr"
|
||||||
|
@ -32,36 +33,9 @@ const (
|
||||||
ruleTypePathPrefix = "PathPrefix"
|
ruleTypePathPrefix = "PathPrefix"
|
||||||
ruleTypeReplacePath = "ReplacePath"
|
ruleTypeReplacePath = "ReplacePath"
|
||||||
|
|
||||||
annotationKubernetesIngressClass = "kubernetes.io/ingress.class"
|
traefikDefaultRealm = "traefik"
|
||||||
annotationKubernetesAuthRealm = "ingress.kubernetes.io/auth-realm"
|
|
||||||
annotationKubernetesAuthType = "ingress.kubernetes.io/auth-type"
|
|
||||||
annotationKubernetesAuthSecret = "ingress.kubernetes.io/auth-secret"
|
|
||||||
annotationKubernetesRewriteTarget = "ingress.kubernetes.io/rewrite-target"
|
|
||||||
annotationKubernetesWhitelistSourceRange = "ingress.kubernetes.io/whitelist-source-range"
|
|
||||||
annotationKubernetesSSLRedirect = "ingress.kubernetes.io/ssl-redirect"
|
|
||||||
annotationKubernetesHSTSMaxAge = "ingress.kubernetes.io/hsts-max-age"
|
|
||||||
annotationKubernetesHSTSIncludeSubdomains = "ingress.kubernetes.io/hsts-include-subdomains"
|
|
||||||
annotationKubernetesCustomRequestHeaders = "ingress.kubernetes.io/custom-request-headers"
|
|
||||||
annotationKubernetesCustomResponseHeaders = "ingress.kubernetes.io/custom-response-headers"
|
|
||||||
annotationKubernetesAllowedHosts = "ingress.kubernetes.io/allowed-hosts"
|
|
||||||
annotationKubernetesProxyHeaders = "ingress.kubernetes.io/proxy-headers"
|
|
||||||
annotationKubernetesSSLTemporaryRedirect = "ingress.kubernetes.io/ssl-temporary-redirect"
|
|
||||||
annotationKubernetesSSLHost = "ingress.kubernetes.io/ssl-host"
|
|
||||||
annotationKubernetesSSLProxyHeaders = "ingress.kubernetes.io/ssl-proxy-headers"
|
|
||||||
annotationKubernetesHSTSPreload = "ingress.kubernetes.io/hsts-preload"
|
|
||||||
annotationKubernetesForceHSTSHeader = "ingress.kubernetes.io/force-hsts"
|
|
||||||
annotationKubernetesFrameDeny = "ingress.kubernetes.io/frame-deny"
|
|
||||||
annotationKubernetesCustomFrameOptionsValue = "ingress.kubernetes.io/custom-frame-options-value"
|
|
||||||
annotationKubernetesContentTypeNosniff = "ingress.kubernetes.io/content-type-nosniff"
|
|
||||||
annotationKubernetesBrowserXSSFilter = "ingress.kubernetes.io/browser-xss-filter"
|
|
||||||
annotationKubernetesContentSecurityPolicy = "ingress.kubernetes.io/content-security-policy"
|
|
||||||
annotationKubernetesPublicKey = "ingress.kubernetes.io/public-key"
|
|
||||||
annotationKubernetesReferrerPolicy = "ingress.kubernetes.io/referrer-policy"
|
|
||||||
annotationKubernetesIsDevelopment = "ingress.kubernetes.io/is-development"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const traefikDefaultRealm = "traefik"
|
|
||||||
|
|
||||||
// Provider holds configurations of the provider.
|
// Provider holds configurations of the provider.
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
provider.BaseProvider `mapstructure:",squash" export:"true"`
|
provider.BaseProvider `mapstructure:",squash" export:"true"`
|
||||||
|
@ -170,7 +144,8 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, i := range ingresses {
|
for _, i := range ingresses {
|
||||||
ingressClass := i.Annotations[annotationKubernetesIngressClass]
|
annotationIngressClass := getAnnotationName(i.Annotations, annotationKubernetesIngressClass)
|
||||||
|
ingressClass := i.Annotations[annotationIngressClass]
|
||||||
|
|
||||||
if !shouldProcessIngress(ingressClass) {
|
if !shouldProcessIngress(ingressClass) {
|
||||||
continue
|
continue
|
||||||
|
@ -200,8 +175,9 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if realm := i.Annotations[annotationKubernetesAuthRealm]; realm != "" && realm != traefikDefaultRealm {
|
annotationAuthRealm := getAnnotationName(i.Annotations, annotationKubernetesAuthRealm)
|
||||||
log.Errorf("Value for annotation %q on ingress %s/%s invalid: no realm customization supported", annotationKubernetesAuthRealm, i.Namespace, i.Name)
|
if realm := i.Annotations[annotationAuthRealm]; realm != "" && realm != traefikDefaultRealm {
|
||||||
|
log.Errorf("Value for annotation %q on ingress %s/%s invalid: no realm customization supported", annotationAuthRealm, i.Namespace, i.Name)
|
||||||
delete(templateObjects.Backends, baseName)
|
delete(templateObjects.Backends, baseName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -213,12 +189,11 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
passHostHeader := label.GetBoolValue(i.Annotations, label.TraefikFrontendPassHostHeader, !p.DisablePassHostHeaders)
|
passHostHeader := getBoolValue(i.Annotations, annotationKubernetesPreserveHost, !p.DisablePassHostHeaders)
|
||||||
passTLSCert := label.GetBoolValue(i.Annotations, label.TraefikFrontendPassTLSCert, p.EnablePassTLSCert)
|
passTLSCert := getBoolValue(i.Annotations, annotationKubernetesPassTLSCert, p.EnablePassTLSCert)
|
||||||
priority := label.GetIntValue(i.Annotations, label.TraefikFrontendPriority, 0)
|
priority := getIntValue(i.Annotations, annotationKubernetesPriority, 0)
|
||||||
entryPoints := label.GetSliceStringValue(i.Annotations, label.TraefikFrontendEntryPoints)
|
entryPoints := getSliceStringValue(i.Annotations, annotationKubernetesFrontendEntryPoints)
|
||||||
whitelistSourceRange := label.GetSliceStringValue(i.Annotations, annotationKubernetesWhitelistSourceRange)
|
whitelistSourceRange := getSliceStringValue(i.Annotations, annotationKubernetesWhitelistSourceRange)
|
||||||
errorPages := label.ParseErrorPages(i.Annotations, label.Prefix+label.BaseFrontendErrorPage, label.RegexpFrontendErrorPage)
|
|
||||||
|
|
||||||
templateObjects.Frontends[baseName] = &types.Frontend{
|
templateObjects.Frontends[baseName] = &types.Frontend{
|
||||||
Backend: baseName,
|
Backend: baseName,
|
||||||
|
@ -231,7 +206,7 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
Redirect: getFrontendRedirect(i),
|
Redirect: getFrontendRedirect(i),
|
||||||
EntryPoints: entryPoints,
|
EntryPoints: entryPoints,
|
||||||
Headers: getHeader(i),
|
Headers: getHeader(i),
|
||||||
Errors: errorPages,
|
Errors: getErrorPages(i),
|
||||||
RateLimit: getRateLimit(i),
|
RateLimit: getRateLimit(i),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,19 +237,11 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if expression := service.Annotations[label.TraefikBackendCircuitBreaker]; expression != "" {
|
templateObjects.Backends[baseName].CircuitBreaker = getCircuitBreaker(service)
|
||||||
templateObjects.Backends[baseName].CircuitBreaker = &types.CircuitBreaker{
|
|
||||||
Expression: expression,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
templateObjects.Backends[baseName].LoadBalancer = getLoadBalancer(service)
|
templateObjects.Backends[baseName].LoadBalancer = getLoadBalancer(service)
|
||||||
|
templateObjects.Backends[baseName].MaxConn = getMaxConn(service)
|
||||||
templateObjects.Backends[baseName].Buffering = getBuffering(service)
|
templateObjects.Backends[baseName].Buffering = getBuffering(service)
|
||||||
|
|
||||||
if maxConn := getMaxConn(service); maxConn != nil {
|
|
||||||
templateObjects.Backends[baseName].MaxConn = maxConn
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol := label.DefaultProtocol
|
protocol := label.DefaultProtocol
|
||||||
for _, port := range service.Spec.Ports {
|
for _, port := range service.Spec.Ports {
|
||||||
if equalPorts(port, pa.Backend.ServicePort) {
|
if equalPorts(port, pa.Backend.ServicePort) {
|
||||||
|
@ -344,14 +311,10 @@ func getRuleForPath(pa v1beta1.HTTPIngressPath, i *v1beta1.Ingress) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
ruleType := i.Annotations[label.TraefikFrontendRuleType]
|
ruleType := getStringValue(i.Annotations, annotationKubernetesRuleType, ruleTypePathPrefix)
|
||||||
if ruleType == "" {
|
|
||||||
ruleType = ruleTypePathPrefix
|
|
||||||
}
|
|
||||||
|
|
||||||
rules := []string{ruleType + ":" + pa.Path}
|
rules := []string{ruleType + ":" + pa.Path}
|
||||||
|
|
||||||
if rewriteTarget := i.Annotations[annotationKubernetesRewriteTarget]; rewriteTarget != "" {
|
if rewriteTarget := getStringValue(i.Annotations, annotationKubernetesRewriteTarget, ""); rewriteTarget != "" {
|
||||||
rules = append(rules, ruleTypeReplacePath+":"+rewriteTarget)
|
rules = append(rules, ruleTypeReplacePath+":"+rewriteTarget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +329,8 @@ func getRuleForHost(host string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleBasicAuthConfig(i *v1beta1.Ingress, k8sClient Client) ([]string, error) {
|
func handleBasicAuthConfig(i *v1beta1.Ingress, k8sClient Client) ([]string, error) {
|
||||||
authType, exists := i.Annotations[annotationKubernetesAuthType]
|
annotationAuthType := getAnnotationName(i.Annotations, annotationKubernetesAuthType)
|
||||||
|
authType, exists := i.Annotations[annotationAuthType]
|
||||||
if !exists {
|
if !exists {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -375,7 +339,7 @@ func handleBasicAuthConfig(i *v1beta1.Ingress, k8sClient Client) ([]string, erro
|
||||||
return nil, fmt.Errorf("unsupported auth-type on annotation ingress.kubernetes.io/auth-type: %q", authType)
|
return nil, fmt.Errorf("unsupported auth-type on annotation ingress.kubernetes.io/auth-type: %q", authType)
|
||||||
}
|
}
|
||||||
|
|
||||||
authSecret := i.Annotations[annotationKubernetesAuthSecret]
|
authSecret := getStringValue(i.Annotations, annotationKubernetesAuthSecret, "")
|
||||||
if authSecret == "" {
|
if authSecret == "" {
|
||||||
return nil, errors.New("auth-secret annotation ingress.kubernetes.io/auth-secret must be set")
|
return nil, errors.New("auth-secret annotation ingress.kubernetes.io/auth-secret must be set")
|
||||||
}
|
}
|
||||||
|
@ -443,10 +407,11 @@ func getTLS(ingress *v1beta1.Ingress, k8sClient Client) ([]*tls.Configuration, e
|
||||||
missingEntries = append(missingEntries, "tls.key")
|
missingEntries = append(missingEntries, "tls.key")
|
||||||
}
|
}
|
||||||
if len(missingEntries) > 0 {
|
if len(missingEntries) > 0 {
|
||||||
return nil, fmt.Errorf("secret %s/%s is missing the following TLS data entries: %s", ingress.Namespace, t.SecretName, strings.Join(missingEntries, ", "))
|
return nil, fmt.Errorf("secret %s/%s is missing the following TLS data entries: %s",
|
||||||
|
ingress.Namespace, t.SecretName, strings.Join(missingEntries, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
entryPoints := label.GetSliceStringValue(ingress.Annotations, label.TraefikFrontendEntryPoints)
|
entryPoints := getSliceStringValue(ingress.Annotations, annotationKubernetesFrontendEntryPoints)
|
||||||
|
|
||||||
tlsConfig := &tls.Configuration{
|
tlsConfig := &tls.Configuration{
|
||||||
EntryPoints: entryPoints,
|
EntryPoints: entryPoints,
|
||||||
|
@ -491,36 +456,40 @@ func shouldProcessIngress(ingressClass string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFrontendRedirect(i *v1beta1.Ingress) *types.Redirect {
|
func getFrontendRedirect(i *v1beta1.Ingress) *types.Redirect {
|
||||||
frontendRedirectEntryPoint, ok := i.Annotations[label.TraefikFrontendRedirectEntryPoint]
|
redirectEntryPoint := getStringValue(i.Annotations, annotationKubernetesRedirectEntryPoint, "")
|
||||||
frep := ok && len(frontendRedirectEntryPoint) > 0
|
if len(redirectEntryPoint) > 0 {
|
||||||
|
|
||||||
frontendRedirectRegex, ok := i.Annotations[label.TraefikFrontendRedirectRegex]
|
|
||||||
frrg := ok && len(frontendRedirectRegex) > 0
|
|
||||||
|
|
||||||
frontendRedirectReplacement, ok := i.Annotations[label.TraefikFrontendRedirectReplacement]
|
|
||||||
frrp := ok && len(frontendRedirectReplacement) > 0
|
|
||||||
|
|
||||||
if frep || frrg && frrp {
|
|
||||||
return &types.Redirect{
|
return &types.Redirect{
|
||||||
EntryPoint: frontendRedirectEntryPoint,
|
EntryPoint: redirectEntryPoint,
|
||||||
Regex: frontendRedirectRegex,
|
|
||||||
Replacement: frontendRedirectReplacement,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redirectRegex := getStringValue(i.Annotations, annotationKubernetesRedirectRegex, "")
|
||||||
|
redirectReplacement := getStringValue(i.Annotations, annotationKubernetesRedirectReplacement, "")
|
||||||
|
if len(redirectRegex) > 0 && len(redirectReplacement) > 0 {
|
||||||
|
return &types.Redirect{
|
||||||
|
Regex: redirectRegex,
|
||||||
|
Replacement: redirectReplacement,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBuffering(service *v1.Service) *types.Buffering {
|
func getBuffering(service *v1.Service) *types.Buffering {
|
||||||
if label.HasPrefix(service.Annotations, label.TraefikBackendBuffering) {
|
var buffering *types.Buffering
|
||||||
return &types.Buffering{
|
|
||||||
MaxRequestBodyBytes: label.GetInt64Value(service.Annotations, label.TraefikBackendBufferingMaxRequestBodyBytes, 0),
|
bufferingRaw := getStringValue(service.Annotations, annotationKubernetesBuffering, "")
|
||||||
MemRequestBodyBytes: label.GetInt64Value(service.Annotations, label.TraefikBackendBufferingMemRequestBodyBytes, 0),
|
|
||||||
MaxResponseBodyBytes: label.GetInt64Value(service.Annotations, label.TraefikBackendBufferingMaxResponseBodyBytes, 0),
|
if len(bufferingRaw) > 0 {
|
||||||
MemResponseBodyBytes: label.GetInt64Value(service.Annotations, label.TraefikBackendBufferingMemResponseBodyBytes, 0),
|
buffering = &types.Buffering{}
|
||||||
RetryExpression: label.GetStringValue(service.Annotations, label.TraefikBackendBufferingRetryExpression, ""),
|
err := yaml.Unmarshal([]byte(bufferingRaw), buffering)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
return buffering
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLoadBalancer(service *v1.Service) *types.LoadBalancer {
|
func getLoadBalancer(service *v1.Service) *types.LoadBalancer {
|
||||||
|
@ -528,12 +497,12 @@ func getLoadBalancer(service *v1.Service) *types.LoadBalancer {
|
||||||
Method: "wrr",
|
Method: "wrr",
|
||||||
}
|
}
|
||||||
|
|
||||||
if service.Annotations[label.TraefikBackendLoadBalancerMethod] == "drr" {
|
if getStringValue(service.Annotations, annotationKubernetesLoadBalancerMethod, "") == "drr" {
|
||||||
loadBalancer.Method = "drr"
|
loadBalancer.Method = "drr"
|
||||||
}
|
}
|
||||||
|
|
||||||
if sticky := service.Annotations[label.TraefikBackendLoadBalancerSticky]; len(sticky) > 0 {
|
if sticky := service.Annotations[label.TraefikBackendLoadBalancerSticky]; len(sticky) > 0 {
|
||||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancerSticky, label.TraefikBackendLoadBalancerStickiness)
|
log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancerSticky, annotationKubernetesAffinity)
|
||||||
loadBalancer.Sticky = strings.EqualFold(strings.TrimSpace(sticky), "true")
|
loadBalancer.Sticky = strings.EqualFold(strings.TrimSpace(sticky), "true")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,9 +514,9 @@ func getLoadBalancer(service *v1.Service) *types.LoadBalancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStickiness(service *v1.Service) *types.Stickiness {
|
func getStickiness(service *v1.Service) *types.Stickiness {
|
||||||
if service.Annotations[label.TraefikBackendLoadBalancerStickiness] == "true" {
|
if getBoolValue(service.Annotations, annotationKubernetesAffinity, false) {
|
||||||
stickiness := &types.Stickiness{}
|
stickiness := &types.Stickiness{}
|
||||||
if cookieName := service.Annotations[label.TraefikBackendLoadBalancerStickinessCookieName]; len(cookieName) > 0 {
|
if cookieName := getStringValue(service.Annotations, annotationKubernetesSessionCookieName, ""); len(cookieName) > 0 {
|
||||||
stickiness.CookieName = cookieName
|
stickiness.CookieName = cookieName
|
||||||
}
|
}
|
||||||
return stickiness
|
return stickiness
|
||||||
|
@ -557,26 +526,26 @@ func getStickiness(service *v1.Service) *types.Stickiness {
|
||||||
|
|
||||||
func getHeader(i *v1beta1.Ingress) *types.Headers {
|
func getHeader(i *v1beta1.Ingress) *types.Headers {
|
||||||
headers := &types.Headers{
|
headers := &types.Headers{
|
||||||
CustomRequestHeaders: label.GetMapValue(i.Annotations, annotationKubernetesCustomRequestHeaders),
|
CustomRequestHeaders: getMapValue(i.Annotations, annotationKubernetesCustomRequestHeaders),
|
||||||
CustomResponseHeaders: label.GetMapValue(i.Annotations, annotationKubernetesCustomResponseHeaders),
|
CustomResponseHeaders: getMapValue(i.Annotations, annotationKubernetesCustomResponseHeaders),
|
||||||
AllowedHosts: label.GetSliceStringValue(i.Annotations, annotationKubernetesAllowedHosts),
|
AllowedHosts: getSliceStringValue(i.Annotations, annotationKubernetesAllowedHosts),
|
||||||
HostsProxyHeaders: label.GetSliceStringValue(i.Annotations, annotationKubernetesProxyHeaders),
|
HostsProxyHeaders: getSliceStringValue(i.Annotations, annotationKubernetesProxyHeaders),
|
||||||
SSLRedirect: label.GetBoolValue(i.Annotations, annotationKubernetesSSLRedirect, false),
|
SSLRedirect: getBoolValue(i.Annotations, annotationKubernetesSSLRedirect, false),
|
||||||
SSLTemporaryRedirect: label.GetBoolValue(i.Annotations, annotationKubernetesSSLTemporaryRedirect, false),
|
SSLTemporaryRedirect: getBoolValue(i.Annotations, annotationKubernetesSSLTemporaryRedirect, false),
|
||||||
SSLHost: label.GetStringValue(i.Annotations, annotationKubernetesSSLHost, ""),
|
SSLHost: getStringValue(i.Annotations, annotationKubernetesSSLHost, ""),
|
||||||
SSLProxyHeaders: label.GetMapValue(i.Annotations, annotationKubernetesSSLProxyHeaders),
|
SSLProxyHeaders: getMapValue(i.Annotations, annotationKubernetesSSLProxyHeaders),
|
||||||
STSSeconds: label.GetInt64Value(i.Annotations, annotationKubernetesHSTSMaxAge, 0),
|
STSSeconds: getInt64Value(i.Annotations, annotationKubernetesHSTSMaxAge, 0),
|
||||||
STSIncludeSubdomains: label.GetBoolValue(i.Annotations, annotationKubernetesHSTSIncludeSubdomains, false),
|
STSIncludeSubdomains: getBoolValue(i.Annotations, annotationKubernetesHSTSIncludeSubdomains, false),
|
||||||
STSPreload: label.GetBoolValue(i.Annotations, annotationKubernetesHSTSPreload, false),
|
STSPreload: getBoolValue(i.Annotations, annotationKubernetesHSTSPreload, false),
|
||||||
ForceSTSHeader: label.GetBoolValue(i.Annotations, annotationKubernetesForceHSTSHeader, false),
|
ForceSTSHeader: getBoolValue(i.Annotations, annotationKubernetesForceHSTSHeader, false),
|
||||||
FrameDeny: label.GetBoolValue(i.Annotations, annotationKubernetesFrameDeny, false),
|
FrameDeny: getBoolValue(i.Annotations, annotationKubernetesFrameDeny, false),
|
||||||
CustomFrameOptionsValue: label.GetStringValue(i.Annotations, annotationKubernetesCustomFrameOptionsValue, ""),
|
CustomFrameOptionsValue: getStringValue(i.Annotations, annotationKubernetesCustomFrameOptionsValue, ""),
|
||||||
ContentTypeNosniff: label.GetBoolValue(i.Annotations, annotationKubernetesContentTypeNosniff, false),
|
ContentTypeNosniff: getBoolValue(i.Annotations, annotationKubernetesContentTypeNosniff, false),
|
||||||
BrowserXSSFilter: label.GetBoolValue(i.Annotations, annotationKubernetesBrowserXSSFilter, false),
|
BrowserXSSFilter: getBoolValue(i.Annotations, annotationKubernetesBrowserXSSFilter, false),
|
||||||
ContentSecurityPolicy: label.GetStringValue(i.Annotations, annotationKubernetesContentSecurityPolicy, ""),
|
ContentSecurityPolicy: getStringValue(i.Annotations, annotationKubernetesContentSecurityPolicy, ""),
|
||||||
PublicKey: label.GetStringValue(i.Annotations, annotationKubernetesPublicKey, ""),
|
PublicKey: getStringValue(i.Annotations, annotationKubernetesPublicKey, ""),
|
||||||
ReferrerPolicy: label.GetStringValue(i.Annotations, annotationKubernetesReferrerPolicy, ""),
|
ReferrerPolicy: getStringValue(i.Annotations, annotationKubernetesReferrerPolicy, ""),
|
||||||
IsDevelopment: label.GetBoolValue(i.Annotations, annotationKubernetesIsDevelopment, false),
|
IsDevelopment: getBoolValue(i.Annotations, annotationKubernetesIsDevelopment, false),
|
||||||
}
|
}
|
||||||
|
|
||||||
if !headers.HasSecureHeadersDefined() && !headers.HasCustomHeadersDefined() {
|
if !headers.HasSecureHeadersDefined() && !headers.HasCustomHeadersDefined() {
|
||||||
|
@ -586,19 +555,9 @@ func getHeader(i *v1beta1.Ingress) *types.Headers {
|
||||||
return headers
|
return headers
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRateLimit(i *v1beta1.Ingress) *types.RateLimit {
|
|
||||||
if rlExtractFunc := i.Annotations[label.TraefikFrontendRateLimitExtractorFunc]; len(rlExtractFunc) > 0 {
|
|
||||||
return &types.RateLimit{
|
|
||||||
ExtractorFunc: rlExtractFunc,
|
|
||||||
RateSet: label.ParseRateSets(i.Annotations, label.Prefix+label.BaseFrontendRateLimit, label.RegexpFrontendRateLimit),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMaxConn(service *v1.Service) *types.MaxConn {
|
func getMaxConn(service *v1.Service) *types.MaxConn {
|
||||||
amount := label.GetInt64Value(service.Annotations, label.TraefikBackendMaxConnAmount, -1)
|
amount := getInt64Value(service.Annotations, annotationKubernetesMaxConnAmount, -1)
|
||||||
extractorFunc := service.Annotations[label.TraefikBackendMaxConnExtractorFunc]
|
extractorFunc := getStringValue(service.Annotations, annotationKubernetesMaxConnExtractorFunc, "")
|
||||||
if amount >= 0 && len(extractorFunc) > 0 {
|
if amount >= 0 && len(extractorFunc) > 0 {
|
||||||
return &types.MaxConn{
|
return &types.MaxConn{
|
||||||
ExtractorFunc: extractorFunc,
|
ExtractorFunc: extractorFunc,
|
||||||
|
@ -607,3 +566,44 @@ func getMaxConn(service *v1.Service) *types.MaxConn {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getCircuitBreaker(service *v1.Service) *types.CircuitBreaker {
|
||||||
|
if expression := getStringValue(service.Annotations, annotationKubernetesCircuitBreakerExpression, ""); expression != "" {
|
||||||
|
return &types.CircuitBreaker{
|
||||||
|
Expression: expression,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getErrorPages(i *v1beta1.Ingress) map[string]*types.ErrorPage {
|
||||||
|
var errorPages map[string]*types.ErrorPage
|
||||||
|
|
||||||
|
pagesRaw := getStringValue(i.Annotations, annotationKubernetesErrorPages, "")
|
||||||
|
if len(pagesRaw) > 0 {
|
||||||
|
errorPages = make(map[string]*types.ErrorPage)
|
||||||
|
err := yaml.Unmarshal([]byte(pagesRaw), errorPages)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errorPages
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRateLimit(i *v1beta1.Ingress) *types.RateLimit {
|
||||||
|
var rateLimit *types.RateLimit
|
||||||
|
|
||||||
|
rateRaw := getStringValue(i.Annotations, annotationKubernetesRateLimit, "")
|
||||||
|
if len(rateRaw) > 0 {
|
||||||
|
rateLimit = &types.RateLimit{}
|
||||||
|
err := yaml.Unmarshal([]byte(rateRaw), rateLimit)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rateLimit
|
||||||
|
}
|
||||||
|
|
|
@ -203,7 +203,7 @@ func TestRuleType(t *testing.T) {
|
||||||
|
|
||||||
if test.ingressRuleType != "" {
|
if test.ingressRuleType != "" {
|
||||||
ingress.Annotations = map[string]string{
|
ingress.Annotations = map[string]string{
|
||||||
label.TraefikFrontendRuleType: test.ingressRuleType,
|
annotationKubernetesRuleType: test.ingressRuleType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,8 +440,8 @@ func TestServiceAnnotations(t *testing.T) {
|
||||||
sName("service1"),
|
sName("service1"),
|
||||||
sNamespace("testing"),
|
sNamespace("testing"),
|
||||||
sUID("1"),
|
sUID("1"),
|
||||||
sAnnotation(label.TraefikBackendCircuitBreaker, "NetworkErrorRatio() > 0.5"),
|
sAnnotation(annotationKubernetesCircuitBreakerExpression, "NetworkErrorRatio() > 0.5"),
|
||||||
sAnnotation(label.TraefikBackendLoadBalancerMethod, "drr"),
|
sAnnotation(annotationKubernetesLoadBalancerMethod, "drr"),
|
||||||
sSpec(
|
sSpec(
|
||||||
clusterIP("10.0.0.1"),
|
clusterIP("10.0.0.1"),
|
||||||
sPorts(sPort(80, ""))),
|
sPorts(sPort(80, ""))),
|
||||||
|
@ -450,7 +450,7 @@ func TestServiceAnnotations(t *testing.T) {
|
||||||
sName("service2"),
|
sName("service2"),
|
||||||
sNamespace("testing"),
|
sNamespace("testing"),
|
||||||
sUID("2"),
|
sUID("2"),
|
||||||
sAnnotation(label.TraefikBackendCircuitBreaker, ""),
|
sAnnotation(annotationKubernetesCircuitBreakerExpression, ""),
|
||||||
sAnnotation(label.TraefikBackendLoadBalancerSticky, "true"),
|
sAnnotation(label.TraefikBackendLoadBalancerSticky, "true"),
|
||||||
sSpec(
|
sSpec(
|
||||||
clusterIP("10.0.0.2"),
|
clusterIP("10.0.0.2"),
|
||||||
|
@ -460,11 +460,13 @@ func TestServiceAnnotations(t *testing.T) {
|
||||||
sName("service3"),
|
sName("service3"),
|
||||||
sNamespace("testing"),
|
sNamespace("testing"),
|
||||||
sUID("3"),
|
sUID("3"),
|
||||||
sAnnotation(label.TraefikBackendBufferingMaxRequestBodyBytes, "10485760"),
|
sAnnotation(annotationKubernetesBuffering, `
|
||||||
sAnnotation(label.TraefikBackendBufferingMemRequestBodyBytes, "2097152"),
|
maxrequestbodybytes: 10485760
|
||||||
sAnnotation(label.TraefikBackendBufferingMaxResponseBodyBytes, "10485760"),
|
memrequestbodybytes: 2097153
|
||||||
sAnnotation(label.TraefikBackendBufferingMemResponseBodyBytes, "2097152"),
|
maxresponsebodybytes: 10485761
|
||||||
sAnnotation(label.TraefikBackendBufferingRetryExpression, "IsNetworkError() && Attempts() <= 2"),
|
memresponsebodybytes: 2097152
|
||||||
|
retryexpression: IsNetworkError() && Attempts() <= 2
|
||||||
|
`),
|
||||||
sSpec(
|
sSpec(
|
||||||
clusterIP("10.0.0.3"),
|
clusterIP("10.0.0.3"),
|
||||||
sPorts(sPort(803, ""))),
|
sPorts(sPort(803, ""))),
|
||||||
|
@ -473,8 +475,8 @@ func TestServiceAnnotations(t *testing.T) {
|
||||||
sName("service4"),
|
sName("service4"),
|
||||||
sNamespace("testing"),
|
sNamespace("testing"),
|
||||||
sUID("4"),
|
sUID("4"),
|
||||||
sAnnotation(label.TraefikBackendMaxConnExtractorFunc, "client.ip"),
|
sAnnotation(annotationKubernetesMaxConnExtractorFunc, "client.ip"),
|
||||||
sAnnotation(label.TraefikBackendMaxConnAmount, "6"),
|
sAnnotation(annotationKubernetesMaxConnAmount, "6"),
|
||||||
sSpec(
|
sSpec(
|
||||||
clusterIP("10.0.0.4"),
|
clusterIP("10.0.0.4"),
|
||||||
sPorts(sPort(804, ""))),
|
sPorts(sPort(804, ""))),
|
||||||
|
@ -562,8 +564,8 @@ func TestServiceAnnotations(t *testing.T) {
|
||||||
lbMethod("wrr"),
|
lbMethod("wrr"),
|
||||||
buffering(
|
buffering(
|
||||||
maxRequestBodyBytes(10485760),
|
maxRequestBodyBytes(10485760),
|
||||||
memRequestBodyBytes(2097152),
|
memRequestBodyBytes(2097153),
|
||||||
maxResponseBodyBytes(10485760),
|
maxResponseBodyBytes(10485761),
|
||||||
memResponseBodyBytes(2097152),
|
memResponseBodyBytes(2097152),
|
||||||
retrying("IsNetworkError() && Attempts() <= 2"),
|
retrying("IsNetworkError() && Attempts() <= 2"),
|
||||||
),
|
),
|
||||||
|
@ -588,7 +590,6 @@ func TestServiceAnnotations(t *testing.T) {
|
||||||
passHostHeader(),
|
passHostHeader(),
|
||||||
routes(route("bar", "Host:bar"))),
|
routes(route("bar", "Host:bar"))),
|
||||||
frontend("baz",
|
frontend("baz",
|
||||||
headers(),
|
|
||||||
passHostHeader(),
|
passHostHeader(),
|
||||||
routes(route("baz", "Host:baz"))),
|
routes(route("baz", "Host:baz"))),
|
||||||
frontend("max-conn",
|
frontend("max-conn",
|
||||||
|
@ -605,7 +606,7 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
ingresses := []*v1beta1.Ingress{
|
ingresses := []*v1beta1.Ingress{
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(label.TraefikFrontendPassHostHeader, "false"),
|
iAnnotation(annotationKubernetesPreserveHost, "false"),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(
|
iRule(
|
||||||
iHost("foo"),
|
iHost("foo"),
|
||||||
|
@ -614,7 +615,7 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
),
|
),
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(label.TraefikFrontendPassHostHeader, "true"),
|
iAnnotation(annotationKubernetesPreserveHost, "true"),
|
||||||
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(
|
iRule(
|
||||||
|
@ -624,7 +625,7 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
),
|
),
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(label.TraefikFrontendPassTLSCert, "true"),
|
iAnnotation(annotationKubernetesPassTLSCert, "true"),
|
||||||
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(
|
iRule(
|
||||||
|
@ -634,7 +635,7 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
),
|
),
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(label.TraefikFrontendEntryPoints, "http,https"),
|
iAnnotation(annotationKubernetesFrontendEntryPoints, "http,https"),
|
||||||
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(
|
iRule(
|
||||||
|
@ -692,7 +693,7 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
||||||
iAnnotation(label.TraefikFrontendRedirectEntryPoint, "https"),
|
iAnnotation(annotationKubernetesRedirectEntryPoint, "https"),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(
|
iRule(
|
||||||
iHost("redirect"),
|
iHost("redirect"),
|
||||||
|
@ -702,9 +703,14 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
||||||
iAnnotation(label.Prefix+label.BaseFrontendErrorPage+"foo."+label.SuffixErrorPageQuery, "/bar"),
|
iAnnotation(annotationKubernetesErrorPages, `
|
||||||
iAnnotation(label.Prefix+label.BaseFrontendErrorPage+"foo."+label.SuffixErrorPageStatus, "123,456"),
|
foo:
|
||||||
iAnnotation(label.Prefix+label.BaseFrontendErrorPage+"foo."+label.SuffixErrorPageBackend, "bar"),
|
status:
|
||||||
|
- "123"
|
||||||
|
- "456"
|
||||||
|
backend: bar
|
||||||
|
query: /bar
|
||||||
|
`),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(
|
iRule(
|
||||||
iHost("error-pages"),
|
iHost("error-pages"),
|
||||||
|
@ -714,13 +720,18 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
iAnnotation(annotationKubernetesIngressClass, "traefik"),
|
||||||
iAnnotation(label.TraefikFrontendRateLimitExtractorFunc, "client.ip"),
|
iAnnotation(annotationKubernetesRateLimit, `
|
||||||
iAnnotation(label.Prefix+label.BaseFrontendRateLimit+"foo."+label.SuffixRateLimitPeriod, "6"),
|
extractorfunc: client.ip
|
||||||
iAnnotation(label.Prefix+label.BaseFrontendRateLimit+"foo."+label.SuffixRateLimitAverage, "12"),
|
rateset:
|
||||||
iAnnotation(label.Prefix+label.BaseFrontendRateLimit+"foo."+label.SuffixRateLimitBurst, "18"),
|
bar:
|
||||||
iAnnotation(label.Prefix+label.BaseFrontendRateLimit+"bar."+label.SuffixRateLimitPeriod, "3"),
|
period: 3s
|
||||||
iAnnotation(label.Prefix+label.BaseFrontendRateLimit+"bar."+label.SuffixRateLimitAverage, "6"),
|
average: 6
|
||||||
iAnnotation(label.Prefix+label.BaseFrontendRateLimit+"bar."+label.SuffixRateLimitBurst, "9"),
|
burst: 9
|
||||||
|
foo:
|
||||||
|
period: 6s
|
||||||
|
average: 12
|
||||||
|
burst: 18
|
||||||
|
`),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(
|
iRule(
|
||||||
iHost("rate-limit"),
|
iHost("rate-limit"),
|
||||||
|
@ -992,7 +1003,7 @@ func TestPriorityHeaderValue(t *testing.T) {
|
||||||
ingresses := []*v1beta1.Ingress{
|
ingresses := []*v1beta1.Ingress{
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(label.TraefikFrontendPriority, "1337"),
|
iAnnotation(annotationKubernetesPriority, "1337"),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(
|
iRule(
|
||||||
iHost("foo"),
|
iHost("foo"),
|
||||||
|
@ -1052,7 +1063,7 @@ func TestInvalidPassTLSCertValue(t *testing.T) {
|
||||||
ingresses := []*v1beta1.Ingress{
|
ingresses := []*v1beta1.Ingress{
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(label.TraefikFrontendPassTLSCert, "herpderp"),
|
iAnnotation(annotationKubernetesPassTLSCert, "herpderp"),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(
|
iRule(
|
||||||
iHost("foo"),
|
iHost("foo"),
|
||||||
|
@ -1109,7 +1120,7 @@ func TestInvalidPassHostHeaderValue(t *testing.T) {
|
||||||
ingresses := []*v1beta1.Ingress{
|
ingresses := []*v1beta1.Ingress{
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(label.TraefikFrontendPassHostHeader, "herpderp"),
|
iAnnotation(annotationKubernetesPreserveHost, "herpderp"),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(
|
iRule(
|
||||||
iHost("foo"),
|
iHost("foo"),
|
||||||
|
@ -1405,7 +1416,7 @@ func TestTLSSecretLoad(t *testing.T) {
|
||||||
ingresses := []*v1beta1.Ingress{
|
ingresses := []*v1beta1.Ingress{
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(label.TraefikFrontendEntryPoints, "ep1,ep2"),
|
iAnnotation(annotationKubernetesFrontendEntryPoints, "ep1,ep2"),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(iHost("example.com"), iPaths(
|
iRule(iHost("example.com"), iPaths(
|
||||||
onePath(iBackend("example-com", intstr.FromInt(80))),
|
onePath(iBackend("example-com", intstr.FromInt(80))),
|
||||||
|
@ -1420,7 +1431,7 @@ func TestTLSSecretLoad(t *testing.T) {
|
||||||
),
|
),
|
||||||
buildIngress(
|
buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(label.TraefikFrontendEntryPoints, "ep3"),
|
iAnnotation(annotationKubernetesFrontendEntryPoints, "ep3"),
|
||||||
iRules(
|
iRules(
|
||||||
iRule(iHost("example.fail"), iPaths(
|
iRule(iHost("example.fail"), iPaths(
|
||||||
onePath(iBackend("example-fail", intstr.FromInt(80))),
|
onePath(iBackend("example-fail", intstr.FromInt(80))),
|
||||||
|
@ -1651,7 +1662,7 @@ func TestGetTLS(t *testing.T) {
|
||||||
desc: "pass the endpoints defined in the annotation to the certificate",
|
desc: "pass the endpoints defined in the annotation to the certificate",
|
||||||
ingress: buildIngress(
|
ingress: buildIngress(
|
||||||
iNamespace("testing"),
|
iNamespace("testing"),
|
||||||
iAnnotation(label.TraefikFrontendEntryPoints, "https,api-secure"),
|
iAnnotation(annotationKubernetesFrontendEntryPoints, "https,api-secure"),
|
||||||
iRules(iRule(iHost("example.com"))),
|
iRules(iRule(iHost("example.com"))),
|
||||||
iTLSes(iTLS("test-secret")),
|
iTLSes(iTLS("test-secret")),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue