diff --git a/discovery/kubernetes/ingress.go b/discovery/kubernetes/ingress.go index a6ef746e47..b638421f3b 100644 --- a/discovery/kubernetes/ingress.go +++ b/discovery/kubernetes/ingress.go @@ -147,6 +147,7 @@ const ( ingressSchemeLabel = metaLabelPrefix + "ingress_scheme" ingressHostLabel = metaLabelPrefix + "ingress_host" ingressPathLabel = metaLabelPrefix + "ingress_path" + ingressClassLabel = metaLabelPrefix + "ingress_class" ) func ingressLabels(ingress *v1beta1.Ingress) model.LabelSet { @@ -154,6 +155,11 @@ func ingressLabels(ingress *v1beta1.Ingress) model.LabelSet { ls := make(model.LabelSet, 2*(len(ingress.Labels)+len(ingress.Annotations))+2) ls[ingressNameLabel] = lv(ingress.Name) ls[namespaceLabel] = lv(ingress.Namespace) + if ingress.Spec.IngressClassName == nil { + ls[ingressClassLabel] = lv("") + } else { + ls[ingressClassLabel] = lv(*ingress.Spec.IngressClassName) + } for k, v := range ingress.Labels { ln := strutil.SanitizeLabelName(k) diff --git a/discovery/kubernetes/ingress_test.go b/discovery/kubernetes/ingress_test.go index 27c0cf92b8..ff0cd46e84 100644 --- a/discovery/kubernetes/ingress_test.go +++ b/discovery/kubernetes/ingress_test.go @@ -33,7 +33,7 @@ const ( TLSMixed ) -func makeIngress(tls TLSMode) *v1beta1.Ingress { +func makeIngress(tls TLSMode, excludeClass bool) *v1beta1.Ingress { ret := &v1beta1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "testingress", @@ -42,7 +42,8 @@ func makeIngress(tls TLSMode) *v1beta1.Ingress { Annotations: map[string]string{"test/annotation": "testannotationvalue"}, }, Spec: v1beta1.IngressSpec{ - TLS: nil, + IngressClassName: classString("testclass"), + TLS: nil, Rules: []v1beta1.IngressRule{ { Host: "example.com", @@ -81,13 +82,23 @@ func makeIngress(tls TLSMode) *v1beta1.Ingress { ret.Spec.TLS = []v1beta1.IngressTLS{{Hosts: []string{"example.com"}}} } + if excludeClass { + ret.Spec.IngressClassName = nil + } + return ret } -func expectedTargetGroups(ns string, tls TLSMode) map[string]*targetgroup.Group { +func classString(v string) *string { + return &v +} + +func expectedTargetGroups(ns string, tls TLSMode, excludeClass bool) map[string]*targetgroup.Group { scheme1 := "http" scheme2 := "http" + ingressClassName := "testclass" + switch tls { case TLSYes: scheme1 = "https" @@ -96,6 +107,10 @@ func expectedTargetGroups(ns string, tls TLSMode) map[string]*targetgroup.Group scheme1 = "https" } + if excludeClass { + ingressClassName = "" + } + key := fmt.Sprintf("ingress/%s/testingress", ns) return map[string]*targetgroup.Group{ key: { @@ -126,6 +141,7 @@ func expectedTargetGroups(ns string, tls TLSMode) map[string]*targetgroup.Group "__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": lv(ingressClassName), }, Source: key, }, @@ -138,11 +154,11 @@ func TestIngressDiscoveryAdd(t *testing.T) { k8sDiscoveryTest{ discovery: n, afterStart: func() { - obj := makeIngress(TLSNo) + obj := makeIngress(TLSNo, false) c.NetworkingV1beta1().Ingresses("default").Create(context.Background(), obj, metav1.CreateOptions{}) }, expectedMaxItems: 1, - expectedRes: expectedTargetGroups("default", TLSNo), + expectedRes: expectedTargetGroups("default", TLSNo, false), }.Run(t) } @@ -152,11 +168,11 @@ func TestIngressDiscoveryAddTLS(t *testing.T) { k8sDiscoveryTest{ discovery: n, afterStart: func() { - obj := makeIngress(TLSYes) + obj := makeIngress(TLSYes, false) c.NetworkingV1beta1().Ingresses("default").Create(context.Background(), obj, metav1.CreateOptions{}) }, expectedMaxItems: 1, - expectedRes: expectedTargetGroups("default", TLSYes), + expectedRes: expectedTargetGroups("default", TLSYes, false), }.Run(t) } @@ -166,26 +182,40 @@ func TestIngressDiscoveryAddMixed(t *testing.T) { k8sDiscoveryTest{ discovery: n, afterStart: func() { - obj := makeIngress(TLSMixed) + obj := makeIngress(TLSMixed, false) c.NetworkingV1beta1().Ingresses("default").Create(context.Background(), obj, metav1.CreateOptions{}) }, expectedMaxItems: 1, - expectedRes: expectedTargetGroups("default", TLSMixed), + expectedRes: expectedTargetGroups("default", TLSMixed, false), + }.Run(t) +} + +func TestIngressDiscoveryAddNoClass(t *testing.T) { + n, c := makeDiscovery(RoleIngress, NamespaceDiscovery{Names: []string{"default"}}) + + k8sDiscoveryTest{ + discovery: n, + afterStart: func() { + obj := makeIngress(TLSMixed, true) + c.NetworkingV1beta1().Ingresses("default").Create(context.Background(), obj, metav1.CreateOptions{}) + }, + expectedMaxItems: 1, + expectedRes: expectedTargetGroups("default", TLSMixed, true), }.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 := expectedTargetGroups("ns1", TLSNo, false) + for k, v := range expectedTargetGroups("ns2", TLSNo, false) { expected[k] = v } k8sDiscoveryTest{ discovery: n, afterStart: func() { for _, ns := range []string{"ns1", "ns2"} { - obj := makeIngress(TLSNo) + obj := makeIngress(TLSNo, false) obj.Namespace = ns c.NetworkingV1beta1().Ingresses(obj.Namespace).Create(context.Background(), obj, metav1.CreateOptions{}) } diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index af94de42a4..542e90a95e 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -1342,6 +1342,7 @@ Available meta labels: * `__meta_kubernetes_ingress_labelpresent_`: `true` for each label from the ingress object. * `__meta_kubernetes_ingress_annotation_`: Each annotation from the ingress object. * `__meta_kubernetes_ingress_annotationpresent_`: `true` for each annotation from the ingress object. +* `__meta_kubernetes_ingress_class`: Class from the ingress spec, if present. Default to `""`. * `__meta_kubernetes_ingress_scheme`: Protocol scheme of ingress, `https` if TLS config is set. Defaults to `http`. * `__meta_kubernetes_ingress_path`: Path from ingress spec. Defaults to `/`.