Add labels for traefik.frontend.entryPoints
& PassTLSCert
to Kubernetes
This commit is contained in:
parent
5d6384e101
commit
7ed4ae2f8c
4 changed files with 352 additions and 14 deletions
|
@ -57,6 +57,13 @@ See also [Kubernetes user guide](/user-guide/kubernetes).
|
||||||
# Default: false
|
# Default: false
|
||||||
#
|
#
|
||||||
# disablePassHostHeaders = true
|
# disablePassHostHeaders = true
|
||||||
|
|
||||||
|
# Enable PassTLSCert Headers.
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
# Default: false
|
||||||
|
#
|
||||||
|
# enablePassTLSCert = true
|
||||||
```
|
```
|
||||||
|
|
||||||
### `endpoint`
|
### `endpoint`
|
||||||
|
@ -90,6 +97,10 @@ Annotations can be used on containers to override default behaviour for the whol
|
||||||
Override the default frontend rule priority.
|
Override the default frontend rule priority.
|
||||||
- `traefik.frontend.redirect: https`:
|
- `traefik.frontend.redirect: https`:
|
||||||
Enables Redirect to another entryPoint for that frontend (e.g. HTTPS).
|
Enables Redirect to another entryPoint for that frontend (e.g. HTTPS).
|
||||||
|
- `traefik.frontend.entryPoints: http,https`
|
||||||
|
Override the default frontend endpoints.
|
||||||
|
- `traefik.frontend.passTLSCert: true`
|
||||||
|
Override the default frontend PassTLSCert value. Default: `false`.
|
||||||
|
|
||||||
Annotations can be used on the Kubernetes service to override default behaviour:
|
Annotations can be used on the Kubernetes service to override default behaviour:
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ type Provider struct {
|
||||||
Token string `description:"Kubernetes bearer token (not needed for in-cluster client)"`
|
Token string `description:"Kubernetes bearer token (not needed for in-cluster client)"`
|
||||||
CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)"`
|
CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)"`
|
||||||
DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers" export:"true"`
|
DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers" export:"true"`
|
||||||
|
EnablePassTLSCert bool `description:"Kubernetes enable Pass TLS Client Certs" export:"true"`
|
||||||
Namespaces Namespaces `description:"Kubernetes namespaces" export:"true"`
|
Namespaces Namespaces `description:"Kubernetes namespaces" export:"true"`
|
||||||
LabelSelector string `description:"Kubernetes api label selector to use" export:"true"`
|
LabelSelector string `description:"Kubernetes api label selector to use" export:"true"`
|
||||||
lastConfiguration safe.Safe
|
lastConfiguration safe.Safe
|
||||||
|
@ -165,25 +166,16 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PassHostHeader := p.getPassHostHeader()
|
passHostHeader := getAnnotationPassHostHeader(i, p)
|
||||||
|
passTLSCert := getAnnotationPassTLSCert(i, p)
|
||||||
passHostHeaderAnnotation, ok := i.Annotations[types.LabelFrontendPassHostHeader]
|
|
||||||
switch {
|
|
||||||
case !ok:
|
|
||||||
// No op.
|
|
||||||
case passHostHeaderAnnotation == "false":
|
|
||||||
PassHostHeader = false
|
|
||||||
case passHostHeaderAnnotation == "true":
|
|
||||||
PassHostHeader = true
|
|
||||||
default:
|
|
||||||
log.Warnf("Unknown value '%s' for %s, falling back to %s", passHostHeaderAnnotation, types.LabelFrontendPassHostHeader, PassHostHeader)
|
|
||||||
}
|
|
||||||
if realm := i.Annotations[annotationKubernetesAuthRealm]; realm != "" && realm != traefikDefaultRealm {
|
if realm := i.Annotations[annotationKubernetesAuthRealm]; realm != "" && realm != traefikDefaultRealm {
|
||||||
log.Errorf("Value for annotation %q on ingress %s/%s invalid: no realm customization supported", annotationKubernetesAuthRealm, i.ObjectMeta.Namespace, i.ObjectMeta.Name)
|
log.Errorf("Value for annotation %q on ingress %s/%s invalid: no realm customization supported", annotationKubernetesAuthRealm, i.ObjectMeta.Namespace, i.ObjectMeta.Name)
|
||||||
delete(templateObjects.Backends, r.Host+pa.Path)
|
delete(templateObjects.Backends, r.Host+pa.Path)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entryPoints := getEntrypoints(i)
|
||||||
|
|
||||||
whitelistSourceRangeAnnotation := i.Annotations[annotationKubernetesWhitelistSourceRange]
|
whitelistSourceRangeAnnotation := i.Annotations[annotationKubernetesWhitelistSourceRange]
|
||||||
whitelistSourceRange := provider.SplitAndTrimString(whitelistSourceRangeAnnotation)
|
whitelistSourceRange := provider.SplitAndTrimString(whitelistSourceRangeAnnotation)
|
||||||
|
|
||||||
|
@ -200,12 +192,14 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
|
|
||||||
templateObjects.Frontends[r.Host+pa.Path] = &types.Frontend{
|
templateObjects.Frontends[r.Host+pa.Path] = &types.Frontend{
|
||||||
Backend: r.Host + pa.Path,
|
Backend: r.Host + pa.Path,
|
||||||
PassHostHeader: PassHostHeader,
|
PassHostHeader: passHostHeader,
|
||||||
|
PassTLSCert: passTLSCert,
|
||||||
Routes: make(map[string]types.Route),
|
Routes: make(map[string]types.Route),
|
||||||
Priority: priority,
|
Priority: priority,
|
||||||
BasicAuth: basicAuthCreds,
|
BasicAuth: basicAuthCreds,
|
||||||
WhitelistSourceRange: whitelistSourceRange,
|
WhitelistSourceRange: whitelistSourceRange,
|
||||||
Redirect: entryPointRedirect,
|
Redirect: entryPointRedirect,
|
||||||
|
EntryPoints: entryPoints,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(r.Host) > 0 {
|
if len(r.Host) > 0 {
|
||||||
|
@ -318,6 +312,39 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
return &templateObjects, nil
|
return &templateObjects, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getEntrypoints(i *v1beta1.Ingress) []string {
|
||||||
|
entrypointsAnnotation, ok := i.Annotations[types.LabelFrontendEntryPoints]
|
||||||
|
if ok {
|
||||||
|
return strings.Split(entrypointsAnnotation, ",")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBoolAnnotation(meta v1.ObjectMeta, name string, defaultValue bool) bool {
|
||||||
|
annotationValue := defaultValue
|
||||||
|
annotationStringValue, ok := meta.Annotations[name]
|
||||||
|
switch {
|
||||||
|
case !ok:
|
||||||
|
// No op.
|
||||||
|
case annotationStringValue == "false":
|
||||||
|
annotationValue = false
|
||||||
|
case annotationStringValue == "true":
|
||||||
|
annotationValue = true
|
||||||
|
default:
|
||||||
|
log.Warnf("Unknown value '%s' for %s, falling back to %s", name, types.LabelFrontendPassTLSCert, defaultValue)
|
||||||
|
}
|
||||||
|
return annotationValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAnnotationPassHostHeader(i *v1beta1.Ingress, p *Provider) bool {
|
||||||
|
return getBoolAnnotation(i.ObjectMeta, types.LabelFrontendPassHostHeader, p.getPassHostHeader())
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAnnotationPassTLSCert(i *v1beta1.Ingress, p *Provider) bool {
|
||||||
|
return getBoolAnnotation(i.ObjectMeta, types.LabelFrontendPassTLSCert, p.getPassTLSCert())
|
||||||
|
}
|
||||||
|
|
||||||
func getRuleForPath(pa v1beta1.HTTPIngressPath, i *v1beta1.Ingress) string {
|
func getRuleForPath(pa v1beta1.HTTPIngressPath, i *v1beta1.Ingress) string {
|
||||||
if len(pa.Path) == 0 {
|
if len(pa.Path) == 0 {
|
||||||
return ""
|
return ""
|
||||||
|
@ -442,6 +469,10 @@ func (p *Provider) getPassHostHeader() bool {
|
||||||
return !p.DisablePassHostHeaders
|
return !p.DisablePassHostHeaders
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) getPassTLSCert() bool {
|
||||||
|
return p.EnablePassTLSCert
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provider) loadConfig(templateObjects types.Configuration) *types.Configuration {
|
func (p *Provider) loadConfig(templateObjects types.Configuration) *types.Configuration {
|
||||||
var FuncMap = template.FuncMap{}
|
var FuncMap = template.FuncMap{}
|
||||||
configuration, err := p.GetConfiguration("templates/kubernetes.tmpl", FuncMap, templateObjects)
|
configuration, err := p.GetConfiguration("templates/kubernetes.tmpl", FuncMap, templateObjects)
|
||||||
|
|
|
@ -508,6 +508,92 @@ func TestGetPassHostHeader(t *testing.T) {
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetPassTLSCert(t *testing.T) {
|
||||||
|
ingresses := []*v1beta1.Ingress{{
|
||||||
|
ObjectMeta: v1.ObjectMeta{
|
||||||
|
Namespace: "awesome",
|
||||||
|
},
|
||||||
|
Spec: v1beta1.IngressSpec{
|
||||||
|
Rules: []v1beta1.IngressRule{
|
||||||
|
{
|
||||||
|
Host: "foo",
|
||||||
|
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||||
|
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||||
|
Paths: []v1beta1.HTTPIngressPath{
|
||||||
|
{
|
||||||
|
Path: "/bar",
|
||||||
|
Backend: v1beta1.IngressBackend{
|
||||||
|
ServiceName: "service1",
|
||||||
|
ServicePort: intstr.FromInt(801),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
services := []*v1.Service{
|
||||||
|
{
|
||||||
|
ObjectMeta: v1.ObjectMeta{
|
||||||
|
Name: "service1",
|
||||||
|
Namespace: "awesome",
|
||||||
|
UID: "1",
|
||||||
|
},
|
||||||
|
Spec: v1.ServiceSpec{
|
||||||
|
ClusterIP: "10.0.0.1",
|
||||||
|
Ports: []v1.ServicePort{
|
||||||
|
{
|
||||||
|
Name: "http",
|
||||||
|
Port: 801,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
watchChan := make(chan interface{})
|
||||||
|
client := clientMock{
|
||||||
|
ingresses: ingresses,
|
||||||
|
services: services,
|
||||||
|
watchChan: watchChan,
|
||||||
|
}
|
||||||
|
provider := Provider{EnablePassTLSCert: true}
|
||||||
|
actual, err := provider.loadIngresses(client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := &types.Configuration{
|
||||||
|
Backends: map[string]*types.Backend{
|
||||||
|
"foo/bar": {
|
||||||
|
Servers: map[string]types.Server{},
|
||||||
|
CircuitBreaker: nil,
|
||||||
|
LoadBalancer: &types.LoadBalancer{
|
||||||
|
Method: "wrr",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Frontends: map[string]*types.Frontend{
|
||||||
|
"foo/bar": {
|
||||||
|
Backend: "foo/bar",
|
||||||
|
PassTLSCert: true,
|
||||||
|
PassHostHeader: true,
|
||||||
|
Routes: map[string]types.Route{
|
||||||
|
"/bar": {
|
||||||
|
Rule: "PathPrefix:/bar",
|
||||||
|
},
|
||||||
|
"foo": {
|
||||||
|
Rule: "Host:foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
func TestOnlyReferencesServicesFromOwnNamespace(t *testing.T) {
|
func TestOnlyReferencesServicesFromOwnNamespace(t *testing.T) {
|
||||||
ingresses := []*v1beta1.Ingress{
|
ingresses := []*v1beta1.Ingress{
|
||||||
{
|
{
|
||||||
|
@ -976,6 +1062,64 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ObjectMeta: v1.ObjectMeta{
|
||||||
|
Namespace: "testing",
|
||||||
|
Annotations: map[string]string{
|
||||||
|
"kubernetes.io/ingress.class": "traefik",
|
||||||
|
types.LabelFrontendPassTLSCert: "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: v1beta1.IngressSpec{
|
||||||
|
Rules: []v1beta1.IngressRule{
|
||||||
|
{
|
||||||
|
Host: "other",
|
||||||
|
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||||
|
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||||
|
Paths: []v1beta1.HTTPIngressPath{
|
||||||
|
{
|
||||||
|
Path: "/sslstuff",
|
||||||
|
Backend: v1beta1.IngressBackend{
|
||||||
|
ServiceName: "service1",
|
||||||
|
ServicePort: intstr.FromInt(80),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ObjectMeta: v1.ObjectMeta{
|
||||||
|
Namespace: "testing",
|
||||||
|
Annotations: map[string]string{
|
||||||
|
"kubernetes.io/ingress.class": "traefik",
|
||||||
|
types.LabelFrontendEntryPoints: "http,https",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: v1beta1.IngressSpec{
|
||||||
|
Rules: []v1beta1.IngressRule{
|
||||||
|
{
|
||||||
|
Host: "other",
|
||||||
|
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||||
|
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||||
|
Paths: []v1beta1.HTTPIngressPath{
|
||||||
|
{
|
||||||
|
Path: "/",
|
||||||
|
Backend: v1beta1.IngressBackend{
|
||||||
|
ServiceName: "service1",
|
||||||
|
ServicePort: intstr.FromInt(80),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: v1.ObjectMeta{
|
||||||
Namespace: "testing",
|
Namespace: "testing",
|
||||||
|
@ -1222,6 +1366,30 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
Method: "wrr",
|
Method: "wrr",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"other/": {
|
||||||
|
Servers: map[string]types.Server{
|
||||||
|
"http://example.com": {
|
||||||
|
URL: "http://example.com",
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CircuitBreaker: nil,
|
||||||
|
LoadBalancer: &types.LoadBalancer{
|
||||||
|
Method: "wrr",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"other/sslstuff": {
|
||||||
|
Servers: map[string]types.Server{
|
||||||
|
"http://example.com": {
|
||||||
|
URL: "http://example.com",
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CircuitBreaker: nil,
|
||||||
|
LoadBalancer: &types.LoadBalancer{
|
||||||
|
Method: "wrr",
|
||||||
|
},
|
||||||
|
},
|
||||||
"basic/auth": {
|
"basic/auth": {
|
||||||
Servers: map[string]types.Server{
|
Servers: map[string]types.Server{
|
||||||
"http://example.com": {
|
"http://example.com": {
|
||||||
|
@ -1299,6 +1467,32 @@ func TestIngressAnnotations(t *testing.T) {
|
||||||
},
|
},
|
||||||
Redirect: "",
|
Redirect: "",
|
||||||
},
|
},
|
||||||
|
"other/": {
|
||||||
|
Backend: "other/",
|
||||||
|
PassHostHeader: true,
|
||||||
|
EntryPoints: []string{"http", "https"},
|
||||||
|
Routes: map[string]types.Route{
|
||||||
|
"/": {
|
||||||
|
Rule: "PathPrefix:/",
|
||||||
|
},
|
||||||
|
"other": {
|
||||||
|
Rule: "Host:other",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"other/sslstuff": {
|
||||||
|
Backend: "other/sslstuff",
|
||||||
|
PassHostHeader: true,
|
||||||
|
PassTLSCert: true,
|
||||||
|
Routes: map[string]types.Route{
|
||||||
|
"/sslstuff": {
|
||||||
|
Rule: "PathPrefix:/sslstuff",
|
||||||
|
},
|
||||||
|
"other": {
|
||||||
|
Rule: "Host:other",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"basic/auth": {
|
"basic/auth": {
|
||||||
Backend: "basic/auth",
|
Backend: "basic/auth",
|
||||||
PassHostHeader: true,
|
PassHostHeader: true,
|
||||||
|
@ -1464,6 +1658,107 @@ func TestPriorityHeaderValue(t *testing.T) {
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInvalidPassTLSCertValue(t *testing.T) {
|
||||||
|
ingresses := []*v1beta1.Ingress{
|
||||||
|
{
|
||||||
|
ObjectMeta: v1.ObjectMeta{
|
||||||
|
Namespace: "testing",
|
||||||
|
Annotations: map[string]string{
|
||||||
|
types.LabelFrontendPassTLSCert: "herpderp",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: v1beta1.IngressSpec{
|
||||||
|
Rules: []v1beta1.IngressRule{
|
||||||
|
{
|
||||||
|
Host: "foo",
|
||||||
|
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||||
|
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||||
|
Paths: []v1beta1.HTTPIngressPath{
|
||||||
|
{
|
||||||
|
Path: "/bar",
|
||||||
|
Backend: v1beta1.IngressBackend{
|
||||||
|
ServiceName: "service1",
|
||||||
|
ServicePort: intstr.FromInt(80),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
services := []*v1.Service{
|
||||||
|
{
|
||||||
|
ObjectMeta: v1.ObjectMeta{
|
||||||
|
Name: "service1",
|
||||||
|
UID: "1",
|
||||||
|
Namespace: "testing",
|
||||||
|
},
|
||||||
|
Spec: v1.ServiceSpec{
|
||||||
|
ClusterIP: "10.0.0.1",
|
||||||
|
Type: "ExternalName",
|
||||||
|
ExternalName: "example.com",
|
||||||
|
Ports: []v1.ServicePort{
|
||||||
|
{
|
||||||
|
Name: "http",
|
||||||
|
Port: 80,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoints := []*v1.Endpoints{}
|
||||||
|
watchChan := make(chan interface{})
|
||||||
|
client := clientMock{
|
||||||
|
ingresses: ingresses,
|
||||||
|
services: services,
|
||||||
|
endpoints: endpoints,
|
||||||
|
watchChan: watchChan,
|
||||||
|
}
|
||||||
|
provider := Provider{}
|
||||||
|
actual, err := provider.loadIngresses(client)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := &types.Configuration{
|
||||||
|
Backends: map[string]*types.Backend{
|
||||||
|
"foo/bar": {
|
||||||
|
Servers: map[string]types.Server{
|
||||||
|
"http://example.com": {
|
||||||
|
URL: "http://example.com",
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CircuitBreaker: nil,
|
||||||
|
LoadBalancer: &types.LoadBalancer{
|
||||||
|
Method: "wrr",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Frontends: map[string]*types.Frontend{
|
||||||
|
"foo/bar": {
|
||||||
|
Backend: "foo/bar",
|
||||||
|
PassTLSCert: false,
|
||||||
|
PassHostHeader: true,
|
||||||
|
Routes: map[string]types.Route{
|
||||||
|
"/bar": {
|
||||||
|
Rule: "PathPrefix:/bar",
|
||||||
|
},
|
||||||
|
"foo": {
|
||||||
|
Rule: "Host:foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
func TestInvalidPassHostHeaderValue(t *testing.T) {
|
func TestInvalidPassHostHeaderValue(t *testing.T) {
|
||||||
ingresses := []*v1beta1.Ingress{
|
ingresses := []*v1beta1.Ingress{
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@ const (
|
||||||
LabelFrontendRequestHeader = LabelPrefix + "frontend.headers.customrequestheaders"
|
LabelFrontendRequestHeader = LabelPrefix + "frontend.headers.customrequestheaders"
|
||||||
LabelFrontendResponseHeader = LabelPrefix + "frontend.headers.customresponseheaders"
|
LabelFrontendResponseHeader = LabelPrefix + "frontend.headers.customresponseheaders"
|
||||||
LabelFrontendPassHostHeader = LabelPrefix + "frontend.passHostHeader"
|
LabelFrontendPassHostHeader = LabelPrefix + "frontend.passHostHeader"
|
||||||
|
LabelFrontendPassTLSCert = LabelPrefix + "frontend.passTLSCert"
|
||||||
LabelFrontendPriority = LabelPrefix + "frontend.priority"
|
LabelFrontendPriority = LabelPrefix + "frontend.priority"
|
||||||
LabelFrontendRule = LabelPrefix + "frontend.rule"
|
LabelFrontendRule = LabelPrefix + "frontend.rule"
|
||||||
LabelFrontendRuleType = LabelPrefix + "frontend.rule.type"
|
LabelFrontendRuleType = LabelPrefix + "frontend.rule.type"
|
||||||
|
|
Loading…
Add table
Reference in a new issue