diff --git a/dataclients/kubernetes/hosts.go b/dataclients/kubernetes/hosts.go index 60dfd4a37a..c6cbb04af7 100644 --- a/dataclients/kubernetes/hosts.go +++ b/dataclients/kubernetes/hosts.go @@ -15,6 +15,9 @@ func createHostRx(hosts ...string) string { hrx := make([]string, len(hosts)) for i, host := range hosts { + if strings.HasPrefix(host, "*.") { + host = strings.Replace(host, "*", "[a-z0-9]+((-[a-z0-9]+)?)*", 1) + } // trailing dots and port are not allowed in kube // ingress spec, so we can append optional setting // without check diff --git a/dataclients/kubernetes/hosts_test.go b/dataclients/kubernetes/hosts_test.go new file mode 100644 index 0000000000..3e2f668ae0 --- /dev/null +++ b/dataclients/kubernetes/hosts_test.go @@ -0,0 +1,31 @@ +package kubernetes + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestHostsToRegex(t *testing.T) { + for _, ti := range []struct { + msg string + host string + regex string + }{ + { + msg: "simple", + host: "simple.example.org", + regex: "^(simple[.]example[.]org[.]?(:[0-9]+)?)$", + }, + { + msg: "wildcard", + host: "*.example.org", + regex: "^([a-z0-9]+((-[a-z0-9]+)?)*[.]example[.]org[.]?(:[0-9]+)?)$", + }, + } { + t.Run(ti.msg, func(t *testing.T) { + regex := createHostRx(ti.host) + require.Equal(t, ti.regex, regex) + }) + } +} diff --git a/dataclients/kubernetes/testdata/ingressV1/ingress-data/wildcard-ing-prefix.eskip b/dataclients/kubernetes/testdata/ingressV1/ingress-data/wildcard-ing-prefix.eskip new file mode 100644 index 0000000000..99c886544e --- /dev/null +++ b/dataclients/kubernetes/testdata/ingressV1/ingress-data/wildcard-ing-prefix.eskip @@ -0,0 +1,3 @@ +kube_foo__qux____example_org_____qux: + Host("^([a-z0-9]+((-[a-z0-9]+)?)*[.]example[.]org[.]?(:[0-9]+)?)$") && PathSubtree("/") + -> ; diff --git a/dataclients/kubernetes/testdata/ingressV1/ingress-data/wildcard-ing-prefix.yaml b/dataclients/kubernetes/testdata/ingressV1/ingress-data/wildcard-ing-prefix.yaml new file mode 100644 index 0000000000..9c3c914786 --- /dev/null +++ b/dataclients/kubernetes/testdata/ingressV1/ingress-data/wildcard-ing-prefix.yaml @@ -0,0 +1,49 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: qux + namespace: foo +spec: + rules: + - host: "*.example.org" + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: qux + port: + name: baz +--- +apiVersion: v1 +kind: Service +metadata: + name: qux + namespace: foo +spec: + clusterIP: 10.3.190.97 + ports: + - name: baz + port: 8181 + protocol: TCP + targetPort: 8080 + selector: + application: myapp + type: ClusterIP +--- +apiVersion: v1 +kind: Endpoints +metadata: + labels: + application: myapp + name: qux + namespace: foo +subsets: +- addresses: + - ip: 10.2.9.103 + - ip: 10.2.9.104 + ports: + - name: baz + port: 8080 + protocol: TCP diff --git a/predicates/forwarded/forwarded_test.go b/predicates/forwarded/forwarded_test.go index a8dc3a7313..7b05341af6 100644 --- a/predicates/forwarded/forwarded_test.go +++ b/predicates/forwarded/forwarded_test.go @@ -162,6 +162,50 @@ func TestForwardedHost(t *testing.T) { }, matches: true, isError: false, + }, { + msg: "wildcard host should match", + host: "^([a-z0-9]+((-[a-z0-9]+)?)*[.]example[.]org[.]?(:[0-9]+)?)$", // *.example.org + r: request{ + url: "https://test.example.org/index.html", + headers: http.Header{ + "Forwarded": []string{`host="test.example.org"`}, + }, + }, + matches: true, + isError: false, + }, { + msg: "wildcard 2 host should match", + host: "^([a-z0-9]+((-[a-z0-9]+)?)*[.]example[.]org[.]?(:[0-9]+)?)$", // *.example.org + r: request{ + url: "https://test-v2.example.org/index.html", + headers: http.Header{ + "Forwarded": []string{`host="test-v2.example.org"`}, + }, + }, + matches: true, + isError: false, + }, { + msg: "wildcard 3 host should match", + host: "^([a-z0-9]+((-[a-z0-9]+)?)*[.]example[.]org[.]?(:[0-9]+)?)$", // *.example.org + r: request{ + url: "https://test-v2-v3.example.org/index.html", + headers: http.Header{ + "Forwarded": []string{`host="test-v2-v3.example.org"`}, + }, + }, + matches: true, + isError: false, + }, { + msg: "wildcard 4 host shouldn't match", + host: "^([a-z0-9]+((-[a-z0-9]+)?)*[.]example[.]org[.]?(:[0-9]+)?)$", // *.example.org + r: request{ + url: "https://test-.example.org/index.html", + headers: http.Header{ + "Forwarded": []string{`host="test-.example.org"`}, + }, + }, + matches: false, + isError: false, }} for _, tc := range testCases { @@ -173,7 +217,7 @@ func TestForwardedHost(t *testing.T) { hasError := err != nil if hasError || tc.isError { if !tc.isError { - t.Fatal("Predicate creation failed") + t.Fatalf("Predicate creation failed, %s", err) } if !hasError {