mirror of https://github.com/prometheus/prometheus
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
343 lines
9.7 KiB
343 lines
9.7 KiB
// Copyright 2016 The Prometheus Authors |
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
|
// you may not use this file except in compliance with the License. |
|
// You may obtain a copy of the License at |
|
// |
|
// http://www.apache.org/licenses/LICENSE-2.0 |
|
// |
|
// Unless required by applicable law or agreed to in writing, software |
|
// distributed under the License is distributed on an "AS IS" BASIS, |
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
// See the License for the specific language governing permissions and |
|
// limitations under the License. |
|
|
|
package kubernetes |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"testing" |
|
|
|
"github.com/prometheus/common/model" |
|
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 |
|
|
|
const ( |
|
TLSNo TLSMode = iota |
|
TLSYes |
|
TLSMixed |
|
TLSWildcard |
|
) |
|
|
|
func makeIngress(tls TLSMode) *v1.Ingress { |
|
ret := &v1.Ingress{ |
|
ObjectMeta: metav1.ObjectMeta{ |
|
Name: "testingress", |
|
Namespace: "default", |
|
Labels: map[string]string{"test/label": "testvalue"}, |
|
Annotations: map[string]string{"test/annotation": "testannotationvalue"}, |
|
}, |
|
Spec: v1.IngressSpec{ |
|
IngressClassName: classString("testclass"), |
|
TLS: nil, |
|
Rules: []v1.IngressRule{ |
|
{ |
|
Host: "example.com", |
|
IngressRuleValue: v1.IngressRuleValue{ |
|
HTTP: &v1.HTTPIngressRuleValue{ |
|
Paths: []v1.HTTPIngressPath{ |
|
{Path: "/"}, |
|
{Path: "/foo"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
// No backend config, ignored |
|
Host: "nobackend.example.com", |
|
IngressRuleValue: v1.IngressRuleValue{ |
|
HTTP: &v1.HTTPIngressRuleValue{}, |
|
}, |
|
}, |
|
{ |
|
Host: "test.example.com", |
|
IngressRuleValue: v1.IngressRuleValue{ |
|
HTTP: &v1.HTTPIngressRuleValue{ |
|
Paths: []v1.HTTPIngressPath{{}}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
} |
|
|
|
switch tls { |
|
case TLSYes: |
|
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 |
|
} |
|
|
|
func makeIngressV1beta1(tls TLSMode) *v1beta1.Ingress { |
|
ret := &v1beta1.Ingress{ |
|
ObjectMeta: metav1.ObjectMeta{ |
|
Name: "testingress", |
|
Namespace: "default", |
|
Labels: map[string]string{"test/label": "testvalue"}, |
|
Annotations: map[string]string{"test/annotation": "testannotationvalue"}, |
|
}, |
|
Spec: v1beta1.IngressSpec{ |
|
IngressClassName: classString("testclass"), |
|
TLS: nil, |
|
Rules: []v1beta1.IngressRule{ |
|
{ |
|
Host: "example.com", |
|
IngressRuleValue: v1beta1.IngressRuleValue{ |
|
HTTP: &v1beta1.HTTPIngressRuleValue{ |
|
Paths: []v1beta1.HTTPIngressPath{ |
|
{Path: "/"}, |
|
{Path: "/foo"}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
// No backend config, ignored |
|
Host: "nobackend.example.com", |
|
IngressRuleValue: v1beta1.IngressRuleValue{ |
|
HTTP: &v1beta1.HTTPIngressRuleValue{}, |
|
}, |
|
}, |
|
{ |
|
Host: "test.example.com", |
|
IngressRuleValue: v1beta1.IngressRuleValue{ |
|
HTTP: &v1beta1.HTTPIngressRuleValue{ |
|
Paths: []v1beta1.HTTPIngressPath{{}}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
} |
|
|
|
switch tls { |
|
case TLSYes: |
|
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 |
|
} |
|
|
|
func classString(v string) *string { |
|
return &v |
|
} |
|
|
|
func expectedTargetGroups(ns string, tls TLSMode) map[string]*targetgroup.Group { |
|
scheme1 := "http" |
|
scheme2 := "http" |
|
|
|
switch tls { |
|
case TLSYes: |
|
scheme1 = "https" |
|
scheme2 = "https" |
|
case TLSMixed: |
|
scheme1 = "https" |
|
case TLSWildcard: |
|
scheme2 = "https" |
|
} |
|
|
|
key := fmt.Sprintf("ingress/%s/testingress", ns) |
|
return map[string]*targetgroup.Group{ |
|
key: { |
|
Targets: []model.LabelSet{ |
|
{ |
|
"__meta_kubernetes_ingress_scheme": lv(scheme1), |
|
"__meta_kubernetes_ingress_host": "example.com", |
|
"__meta_kubernetes_ingress_path": "/", |
|
"__address__": "example.com", |
|
}, |
|
{ |
|
"__meta_kubernetes_ingress_scheme": lv(scheme1), |
|
"__meta_kubernetes_ingress_host": "example.com", |
|
"__meta_kubernetes_ingress_path": "/foo", |
|
"__address__": "example.com", |
|
}, |
|
{ |
|
"__meta_kubernetes_ingress_scheme": lv(scheme2), |
|
"__meta_kubernetes_ingress_host": "test.example.com", |
|
"__address__": "test.example.com", |
|
"__meta_kubernetes_ingress_path": "/", |
|
}, |
|
}, |
|
Labels: model.LabelSet{ |
|
"__meta_kubernetes_ingress_name": "testingress", |
|
"__meta_kubernetes_namespace": lv(ns), |
|
"__meta_kubernetes_ingress_label_test_label": "testvalue", |
|
"__meta_kubernetes_ingress_labelpresent_test_label": "true", |
|
"__meta_kubernetes_ingress_annotation_test_annotation": "testannotationvalue", |
|
"__meta_kubernetes_ingress_annotationpresent_test_annotation": "true", |
|
"__meta_kubernetes_ingress_class_name": "testclass", |
|
}, |
|
Source: key, |
|
}, |
|
} |
|
} |
|
|
|
func TestIngressDiscoveryAdd(t *testing.T) { |
|
n, c := makeDiscovery(RoleIngress, NamespaceDiscovery{Names: []string{"default"}}) |
|
|
|
k8sDiscoveryTest{ |
|
discovery: n, |
|
afterStart: func() { |
|
obj := makeIngress(TLSNo) |
|
c.NetworkingV1().Ingresses("default").Create(context.Background(), obj, metav1.CreateOptions{}) |
|
}, |
|
expectedMaxItems: 1, |
|
expectedRes: expectedTargetGroups("default", TLSNo), |
|
}.Run(t) |
|
} |
|
|
|
func TestIngressDiscoveryAddV1beta1(t *testing.T) { |
|
n, c := makeDiscoveryWithVersion(RoleIngress, NamespaceDiscovery{Names: []string{"default"}}, "v1.18.0") |
|
|
|
k8sDiscoveryTest{ |
|
discovery: n, |
|
afterStart: func() { |
|
obj := makeIngressV1beta1(TLSNo) |
|
c.NetworkingV1beta1().Ingresses("default").Create(context.Background(), obj, metav1.CreateOptions{}) |
|
}, |
|
expectedMaxItems: 1, |
|
expectedRes: expectedTargetGroups("default", TLSNo), |
|
}.Run(t) |
|
} |
|
|
|
func TestIngressDiscoveryAddTLS(t *testing.T) { |
|
n, c := makeDiscovery(RoleIngress, NamespaceDiscovery{Names: []string{"default"}}) |
|
|
|
k8sDiscoveryTest{ |
|
discovery: n, |
|
afterStart: func() { |
|
obj := makeIngress(TLSYes) |
|
c.NetworkingV1().Ingresses("default").Create(context.Background(), obj, metav1.CreateOptions{}) |
|
}, |
|
expectedMaxItems: 1, |
|
expectedRes: expectedTargetGroups("default", TLSYes), |
|
}.Run(t) |
|
} |
|
|
|
func TestIngressDiscoveryAddTLSV1beta1(t *testing.T) { |
|
n, c := makeDiscoveryWithVersion(RoleIngress, NamespaceDiscovery{Names: []string{"default"}}, "v1.18.0") |
|
|
|
k8sDiscoveryTest{ |
|
discovery: n, |
|
afterStart: func() { |
|
obj := makeIngressV1beta1(TLSYes) |
|
c.NetworkingV1beta1().Ingresses("default").Create(context.Background(), obj, metav1.CreateOptions{}) |
|
}, |
|
expectedMaxItems: 1, |
|
expectedRes: expectedTargetGroups("default", TLSYes), |
|
}.Run(t) |
|
} |
|
|
|
func TestIngressDiscoveryAddMixed(t *testing.T) { |
|
n, c := makeDiscovery(RoleIngress, NamespaceDiscovery{Names: []string{"default"}}) |
|
|
|
k8sDiscoveryTest{ |
|
discovery: n, |
|
afterStart: func() { |
|
obj := makeIngress(TLSMixed) |
|
c.NetworkingV1().Ingresses("default").Create(context.Background(), obj, metav1.CreateOptions{}) |
|
}, |
|
expectedMaxItems: 1, |
|
expectedRes: expectedTargetGroups("default", TLSMixed), |
|
}.Run(t) |
|
} |
|
|
|
func TestIngressDiscoveryAddMixedV1beta1(t *testing.T) { |
|
n, c := makeDiscoveryWithVersion(RoleIngress, NamespaceDiscovery{Names: []string{"default"}}, "v1.18.0") |
|
|
|
k8sDiscoveryTest{ |
|
discovery: n, |
|
afterStart: func() { |
|
obj := makeIngressV1beta1(TLSMixed) |
|
c.NetworkingV1beta1().Ingresses("default").Create(context.Background(), obj, metav1.CreateOptions{}) |
|
}, |
|
expectedMaxItems: 1, |
|
expectedRes: expectedTargetGroups("default", TLSMixed), |
|
}.Run(t) |
|
} |
|
|
|
func TestIngressDiscoveryNamespaces(t *testing.T) { |
|
n, c := makeDiscovery(RoleIngress, NamespaceDiscovery{Names: []string{"ns1", "ns2"}}) |
|
|
|
expected := expectedTargetGroups("ns1", TLSNo) |
|
for k, v := range expectedTargetGroups("ns2", TLSNo) { |
|
expected[k] = v |
|
} |
|
k8sDiscoveryTest{ |
|
discovery: n, |
|
afterStart: func() { |
|
for _, ns := range []string{"ns1", "ns2"} { |
|
obj := makeIngress(TLSNo) |
|
obj.Namespace = ns |
|
c.NetworkingV1().Ingresses(obj.Namespace).Create(context.Background(), obj, metav1.CreateOptions{}) |
|
} |
|
}, |
|
expectedMaxItems: 2, |
|
expectedRes: expected, |
|
}.Run(t) |
|
} |
|
|
|
func TestIngressDiscoveryNamespacesV1beta1(t *testing.T) { |
|
n, c := makeDiscoveryWithVersion(RoleIngress, NamespaceDiscovery{Names: []string{"ns1", "ns2"}}, "v1.18.0") |
|
|
|
expected := expectedTargetGroups("ns1", TLSNo) |
|
for k, v := range expectedTargetGroups("ns2", TLSNo) { |
|
expected[k] = v |
|
} |
|
k8sDiscoveryTest{ |
|
discovery: n, |
|
afterStart: func() { |
|
for _, ns := range []string{"ns1", "ns2"} { |
|
obj := makeIngressV1beta1(TLSNo) |
|
obj.Namespace = ns |
|
c.NetworkingV1beta1().Ingresses(obj.Namespace).Create(context.Background(), obj, metav1.CreateOptions{}) |
|
} |
|
}, |
|
expectedMaxItems: 2, |
|
expectedRes: expected, |
|
}.Run(t) |
|
} |
|
|
|
func TestIngressDiscoveryOwnNamespace(t *testing.T) { |
|
n, c := makeDiscovery(RoleIngress, NamespaceDiscovery{IncludeOwnNamespace: true}) |
|
|
|
expected := expectedTargetGroups("own-ns", TLSNo) |
|
k8sDiscoveryTest{ |
|
discovery: n, |
|
afterStart: func() { |
|
for _, ns := range []string{"own-ns", "non-own-ns"} { |
|
obj := makeIngress(TLSNo) |
|
obj.Namespace = ns |
|
c.NetworkingV1().Ingresses(obj.Namespace).Create(context.Background(), obj, metav1.CreateOptions{}) |
|
} |
|
}, |
|
expectedMaxItems: 1, |
|
expectedRes: expected, |
|
}.Run(t) |
|
}
|
|
|