Merge pull request #9118 from PhilipGough/fixes-8902

discovery:kube: Support wildcard matching for ingress rules
This commit is contained in:
Frederic Branczyk 2021-08-26 16:48:25 +02:00 committed by GitHub
commit 1276aaaa9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 11 deletions

View File

@ -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 {
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
}

View File

@ -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)