discovery:kube: Support wildcard matching for ingress rules

This change sets the scheme to https when a rule specified by Ingress
matches a wildcard DNS entry in the ingress TLS hosts

Signed-off-by: Philip Gough <philip.p.gough@gmail.com>
pull/9118/head
Philip Gough 3 years ago
parent 8a5d8c15e3
commit 0af7250c52

@ -15,6 +15,7 @@ package kubernetes
import (
"context"
"strings"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
@ -193,18 +194,16 @@ func (i *Ingress) buildIngress(ingress ingressAdaptor) *targetgroup.Group {
}
tg.Labels = ingressLabels(ingress)
tlsHosts := make(map[string]struct{})
for _, host := range ingress.tlsHosts() {
tlsHosts[host] = struct{}{}
}
for _, rule := range ingress.rules() {
scheme := "http"
paths := pathsFromIngressPaths(rule.paths())
scheme := "http"
_, isTLS := tlsHosts[rule.host()]
if isTLS {
scheme = "https"
out:
for _, pattern := range ingress.tlsHosts() {
if matchesHostnamePattern(pattern, rule.host()) {
scheme = "https"
break out
}
}
for _, path := range paths {
@ -219,3 +218,34 @@ func (i *Ingress) buildIngress(ingress ingressAdaptor) *targetgroup.Group {
return tg
}
// matchesHostnamePattern returns true if the host matches a wildcard DNS
// pattern or pattern and host are equal
func matchesHostnamePattern(pattern, host string) bool {
// check for exact match
if pattern == host {
return true
}
patternParts := strings.Split(pattern, ".")
hostParts := strings.Split(host, ".")
// if they are not equal, we cna check if we need to match
// on a wildcard or else give up
if len(patternParts) == 0 || patternParts[0] != "*" {
return false
}
// to get a valid wildcard match the parts will need to be the same length
if len(patternParts) != len(hostParts) {
return false
}
for i := 1; i < len(patternParts); i++ {
if patternParts[i] != hostParts[i] {
return false
}
}
return true
}

@ -19,11 +19,11 @@ import (
"testing"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/discovery/targetgroup"
v1 "k8s.io/api/networking/v1"
"k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/prometheus/prometheus/discovery/targetgroup"
)
type TLSMode int
@ -32,6 +32,7 @@ const (
TLSNo TLSMode = iota
TLSYes
TLSMixed
TLSWildcard
)
func makeIngress(tls TLSMode) *v1.Ingress {
@ -81,6 +82,8 @@ func makeIngress(tls TLSMode) *v1.Ingress {
ret.Spec.TLS = []v1.IngressTLS{{Hosts: []string{"example.com", "test.example.com"}}}
case TLSMixed:
ret.Spec.TLS = []v1.IngressTLS{{Hosts: []string{"example.com"}}}
case TLSWildcard:
ret.Spec.TLS = []v1.IngressTLS{{Hosts: []string{"*.example.com"}}}
}
return ret
@ -133,6 +136,8 @@ func makeIngressV1beta1(tls TLSMode) *v1beta1.Ingress {
ret.Spec.TLS = []v1beta1.IngressTLS{{Hosts: []string{"example.com", "test.example.com"}}}
case TLSMixed:
ret.Spec.TLS = []v1beta1.IngressTLS{{Hosts: []string{"example.com"}}}
case TLSWildcard:
ret.Spec.TLS = []v1beta1.IngressTLS{{Hosts: []string{"*.example.com"}}}
}
return ret
@ -152,6 +157,8 @@ func expectedTargetGroups(ns string, tls TLSMode) map[string]*targetgroup.Group
scheme2 = "https"
case TLSMixed:
scheme1 = "https"
case TLSWildcard:
scheme2 = "https"
}
key := fmt.Sprintf("ingress/%s/testingress", ns)

Loading…
Cancel
Save