From 4f17693263ad903b7a89ddbb72d673ecbb6640d8 Mon Sep 17 00:00:00 2001 From: Kristin Wong Date: Fri, 17 Oct 2025 12:45:23 +0100 Subject: [PATCH 1/5] add priority labeling --- kube/config/templates/5xx-rate.tmpl | 3 +++ .../replicas-availability-deployment.tmpl | 3 +++ pkg/templates/ingress.go | 2 ++ pkg/templates/ingress_test.go | 15 ++++++++++----- pkg/templates/promrules.go | 1 + 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/kube/config/templates/5xx-rate.tmpl b/kube/config/templates/5xx-rate.tmpl index 2b0af89..839ce51 100644 --- a/kube/config/templates/5xx-rate.tmpl +++ b/kube/config/templates/5xx-rate.tmpl @@ -45,3 +45,6 @@ spec: {{if .Sensitivity}} sensitivity: {{.Sensitivity}} {{end}} + {{if .Priority}} + priority: {{.Priority}} + {{end}} diff --git a/kube/config/templates/replicas-availability-deployment.tmpl b/kube/config/templates/replicas-availability-deployment.tmpl index baff7b5..1d400c5 100644 --- a/kube/config/templates/replicas-availability-deployment.tmpl +++ b/kube/config/templates/replicas-availability-deployment.tmpl @@ -37,3 +37,6 @@ spec: {{if .Sensitivity}} sensitivity: {{.Sensitivity}} {{end}} + {{if .Priority}} + priority: {{.Priority}} + {{end}} diff --git a/pkg/templates/ingress.go b/pkg/templates/ingress.go index 0848ca7..f2b7257 100644 --- a/pkg/templates/ingress.go +++ b/pkg/templates/ingress.go @@ -29,6 +29,7 @@ type templateParameterIngress struct { Criticality string Sensitivity string BackendService string + Priority string } // CreateFromIngress @@ -46,6 +47,7 @@ func (a *PrometheusRuleTemplateManager) CreateFromIngress(ingress *networkingv1. Environment: ingress.GetAnnotations()[environmentAnnotation], Criticality: ingress.GetAnnotations()[criticalityAnnotation], Sensitivity: ingress.GetAnnotations()[sensitivityAnnotation], + Priority: ingress.GetAnnotations()[priorityAnnotation], } prometheusRules := map[string]*monitoringv1.PrometheusRule{} diff --git a/pkg/templates/ingress_test.go b/pkg/templates/ingress_test.go index 67df99f..4cd7f6d 100644 --- a/pkg/templates/ingress_test.go +++ b/pkg/templates/ingress_test.go @@ -69,11 +69,12 @@ var ( Name: "testDefaultBackend", Namespace: "testNamespace", Annotations: map[string]string{ - "com.uswitch.heimdall/5xx-rate": "0.001", - ownerAnnotation: "testIngressOwner", - environmentAnnotation: "testing", - criticalityAnnotation: "low", - sensitivityAnnotation: "public", + "com.uswitch.heimdall/5xx-rate": "0.001", + "com.uswitch.heimdall/label-priority": "p1", + ownerAnnotation: "testIngressOwner", + environmentAnnotation: "testing", + criticalityAnnotation: "low", + sensitivityAnnotation: "public", }, }, Spec: networkingv1.IngressSpec{ @@ -147,6 +148,10 @@ func TestIngressAnnotationsDefaultBackend(t *testing.T) { assert.Assert(t, is.Len(promrules, 1)) assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Expr.StrVal, expr) assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["owner"], "testIngressOwner") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["environment"], "testing") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["criticality"], "low") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["sensitivity"], "public") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["priority"], "p1") } func TestIngressAnnotationsRuleBackend(t *testing.T) { diff --git a/pkg/templates/promrules.go b/pkg/templates/promrules.go index 854b139..6e09703 100644 --- a/pkg/templates/promrules.go +++ b/pkg/templates/promrules.go @@ -21,6 +21,7 @@ const ( environmentAnnotation = "service.rvu.co.uk/environment" criticalityAnnotation = "service.rvu.co.uk/criticality" sensitivityAnnotation = "service.rvu.co.uk/sensitivity" + priorityAnnotation = "com.uswitch.heimdall/label-priority" ) // ClientSetI From 5a41bb395ef3339f472ca41adb6f29a9dea9e47e Mon Sep 17 00:00:00 2001 From: Kristin Wong Date: Fri, 17 Oct 2025 15:11:06 +0100 Subject: [PATCH 2/5] tidy up --- pkg/templates/ingress.go | 4 +++- pkg/templates/ingress_test.go | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pkg/templates/ingress.go b/pkg/templates/ingress.go index f2b7257..8f87f88 100644 --- a/pkg/templates/ingress.go +++ b/pkg/templates/ingress.go @@ -47,7 +47,6 @@ func (a *PrometheusRuleTemplateManager) CreateFromIngress(ingress *networkingv1. Environment: ingress.GetAnnotations()[environmentAnnotation], Criticality: ingress.GetAnnotations()[criticalityAnnotation], Sensitivity: ingress.GetAnnotations()[sensitivityAnnotation], - Priority: ingress.GetAnnotations()[priorityAnnotation], } prometheusRules := map[string]*monitoringv1.PrometheusRule{} @@ -58,6 +57,8 @@ func (a *PrometheusRuleTemplateManager) CreateFromIngress(ingress *networkingv1. continue } + params.Priority = ingress.GetAnnotations()[priorityAnnotation] + templateName := strings.TrimLeft(k, fmt.Sprintf("%s/", heimPrefix)) template, ok := a.templates[templateName] if !ok { @@ -124,6 +125,7 @@ func (a *PrometheusRuleTemplateManager) resolveIngressOwner(params *templatePara params.Environment = deployment.GetAnnotations()[environmentAnnotation] params.Criticality = deployment.GetAnnotations()[criticalityAnnotation] params.Sensitivity = deployment.GetAnnotations()[sensitivityAnnotation] + params.Priority = deployment.GetAnnotations()[priorityAnnotation] return params, nil } diff --git a/pkg/templates/ingress_test.go b/pkg/templates/ingress_test.go index 4cd7f6d..cebcdd3 100644 --- a/pkg/templates/ingress_test.go +++ b/pkg/templates/ingress_test.go @@ -69,12 +69,12 @@ var ( Name: "testDefaultBackend", Namespace: "testNamespace", Annotations: map[string]string{ - "com.uswitch.heimdall/5xx-rate": "0.001", - "com.uswitch.heimdall/label-priority": "p1", - ownerAnnotation: "testIngressOwner", - environmentAnnotation: "testing", - criticalityAnnotation: "low", - sensitivityAnnotation: "public", + "com.uswitch.heimdall/5xx-rate": "0.001", + ownerAnnotation: "testIngressOwner", + environmentAnnotation: "testing", + criticalityAnnotation: "low", + sensitivityAnnotation: "public", + priorityAnnotation: "p1", }, }, Spec: networkingv1.IngressSpec{ From 6df0ca036cd34eea9896937d2c43f224eea88fbf Mon Sep 17 00:00:00 2001 From: Kristin Wong Date: Fri, 17 Oct 2025 15:11:15 +0100 Subject: [PATCH 3/5] add to deployments --- pkg/templates/deployment.go | 3 +++ pkg/templates/deployment_test.go | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/pkg/templates/deployment.go b/pkg/templates/deployment.go index f045a9f..ae7c3af 100644 --- a/pkg/templates/deployment.go +++ b/pkg/templates/deployment.go @@ -31,6 +31,7 @@ type templateParameterDeployment struct { Criticality string Sensitivity string Deployment *apps.Deployment + Priority string } // CreateFromDeployment @@ -74,6 +75,8 @@ func (a *PrometheusRuleTemplateManager) CreateFromDeployment(deployment *apps.De continue } + params.Priority = deployment.GetAnnotations()[priorityAnnotation] + templateName := strings.TrimLeft(k, fmt.Sprintf("%s/", heimPrefix)) logger.Infow("template selected", "template", templateName) template, ok := a.templates[templateName] diff --git a/pkg/templates/deployment_test.go b/pkg/templates/deployment_test.go index c0bb42f..cbda200 100644 --- a/pkg/templates/deployment_test.go +++ b/pkg/templates/deployment_test.go @@ -24,6 +24,7 @@ var ( environmentAnnotation: "testing", criticalityAnnotation: "low", sensitivityAnnotation: "public", + priorityAnnotation: "p1", "com.uswitch.heimdall/replicas-availability-deployment": "1", }, OwnerReferences: []metav1.OwnerReference{}, @@ -51,4 +52,8 @@ kube_deployment_spec_replicas{namespace="testNamespace", deployment="testApp"} < assert.Assert(t, is.Len(promrules, 1)) assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Expr.StrVal, expr) assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["owner"], "testDeploymentOwner") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["environment"], "testing") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["criticality"], "low") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["sensitivity"], "public") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["priority"], "p1") } From 848c37933c068dd78ddfabfe82b53f30fd2cc866 Mon Sep 17 00:00:00 2001 From: Kristin Wong Date: Thu, 6 Nov 2025 17:22:59 +0000 Subject: [PATCH 4/5] make labels generic --- kube/config/templates/5xx-rate.tmpl | 4 +- .../replicas-availability-deployment.tmpl | 4 +- pkg/templates/deployment.go | 10 +++-- pkg/templates/deployment_test.go | 40 +++++++++++++++++ pkg/templates/ingress.go | 10 +++-- pkg/templates/ingress_test.go | 43 +++++++++++++++++++ pkg/templates/promrules.go | 19 +++++++- 7 files changed, 119 insertions(+), 11 deletions(-) diff --git a/kube/config/templates/5xx-rate.tmpl b/kube/config/templates/5xx-rate.tmpl index 839ce51..22ab929 100644 --- a/kube/config/templates/5xx-rate.tmpl +++ b/kube/config/templates/5xx-rate.tmpl @@ -45,6 +45,6 @@ spec: {{if .Sensitivity}} sensitivity: {{.Sensitivity}} {{end}} - {{if .Priority}} - priority: {{.Priority}} + {{range $key, $value := .CustomLabels}} + {{$key}}: {{$value}} {{end}} diff --git a/kube/config/templates/replicas-availability-deployment.tmpl b/kube/config/templates/replicas-availability-deployment.tmpl index 1d400c5..3b12f43 100644 --- a/kube/config/templates/replicas-availability-deployment.tmpl +++ b/kube/config/templates/replicas-availability-deployment.tmpl @@ -37,6 +37,6 @@ spec: {{if .Sensitivity}} sensitivity: {{.Sensitivity}} {{end}} - {{if .Priority}} - priority: {{.Priority}} + {{range $key, $value := .CustomLabels}} + {{$key}}: {{$value}} {{end}} diff --git a/pkg/templates/deployment.go b/pkg/templates/deployment.go index ae7c3af..de605d8 100644 --- a/pkg/templates/deployment.go +++ b/pkg/templates/deployment.go @@ -31,7 +31,7 @@ type templateParameterDeployment struct { Criticality string Sensitivity string Deployment *apps.Deployment - Priority string + CustomLabels map[string]string } // CreateFromDeployment @@ -69,13 +69,17 @@ func (a *PrometheusRuleTemplateManager) CreateFromDeployment(deployment *apps.De prometheusRules := map[string]*monitoringv1.PrometheusRule{} annotations := params.Deployment.GetAnnotations() - for k, v := range annotations { if !strings.HasPrefix(k, heimPrefix) { continue } - params.Priority = deployment.GetAnnotations()[priorityAnnotation] + // Skip label-* annotations as they are not templates + if strings.HasPrefix(k, labelPrefix) { + continue + } + + params.CustomLabels = extractCustomLabels(annotations) templateName := strings.TrimLeft(k, fmt.Sprintf("%s/", heimPrefix)) logger.Infow("template selected", "template", templateName) diff --git a/pkg/templates/deployment_test.go b/pkg/templates/deployment_test.go index cbda200..045b617 100644 --- a/pkg/templates/deployment_test.go +++ b/pkg/templates/deployment_test.go @@ -34,6 +34,31 @@ var ( Selector: &metav1.LabelSelector{}, }, } + + testDeploymentMultiLabel = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testAppMulti", + Namespace: "testNamespace", + Labels: map[string]string{ + "app": "testAppMulti", + }, + Annotations: map[string]string{ + ownerAnnotation: "testDeploymentOwner", + environmentAnnotation: "testing", + criticalityAnnotation: "low", + sensitivityAnnotation: "public", + "com.uswitch.heimdall/label-priority": "p3", + "com.uswitch.heimdall/label-channel": "testing", + "com.uswitch.heimdall/label-team": "platform", + "com.uswitch.heimdall/replicas-availability-deployment": "1", + }, + OwnerReferences: []metav1.OwnerReference{}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: new(int32), + Selector: &metav1.LabelSelector{}, + }, + } ) func TestDeploymentAnnotations(t *testing.T) { @@ -57,3 +82,18 @@ kube_deployment_spec_replicas{namespace="testNamespace", deployment="testApp"} < assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["sensitivity"], "public") assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["priority"], "p1") } + +func TestDeploymentMultipleCustomLabels(t *testing.T) { + log.Setup(log.DEBUG_LEVEL) + + client := fake.NewSimpleClientset() + + template, err := NewPrometheusRuleTemplateManager("../../kube/config/templates", client) + + promrules, err := template.CreateFromDeployment(testDeploymentMultiLabel, "testNamespace") + assert.Assert(t, is.Nil(err)) + assert.Assert(t, is.Len(promrules, 1)) + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["priority"], "p3") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["channel"], "testing") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["team"], "platform") +} diff --git a/pkg/templates/ingress.go b/pkg/templates/ingress.go index 8f87f88..03711ab 100644 --- a/pkg/templates/ingress.go +++ b/pkg/templates/ingress.go @@ -29,7 +29,7 @@ type templateParameterIngress struct { Criticality string Sensitivity string BackendService string - Priority string + CustomLabels map[string]string } // CreateFromIngress @@ -57,7 +57,12 @@ func (a *PrometheusRuleTemplateManager) CreateFromIngress(ingress *networkingv1. continue } - params.Priority = ingress.GetAnnotations()[priorityAnnotation] + // Skip label-* annotations as they are not templates + if strings.HasPrefix(k, labelPrefix) { + continue + } + + params.CustomLabels = extractCustomLabels(annotations) templateName := strings.TrimLeft(k, fmt.Sprintf("%s/", heimPrefix)) template, ok := a.templates[templateName] @@ -125,7 +130,6 @@ func (a *PrometheusRuleTemplateManager) resolveIngressOwner(params *templatePara params.Environment = deployment.GetAnnotations()[environmentAnnotation] params.Criticality = deployment.GetAnnotations()[criticalityAnnotation] params.Sensitivity = deployment.GetAnnotations()[sensitivityAnnotation] - params.Priority = deployment.GetAnnotations()[priorityAnnotation] return params, nil } diff --git a/pkg/templates/ingress_test.go b/pkg/templates/ingress_test.go index cebcdd3..ee50720 100644 --- a/pkg/templates/ingress_test.go +++ b/pkg/templates/ingress_test.go @@ -120,6 +120,33 @@ var ( }, }, } + + testIngressMultiLabel = &networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testMultiLabel", + Namespace: "testNamespace", + Annotations: map[string]string{ + "com.uswitch.heimdall/5xx-rate": "0.001", + ownerAnnotation: "testIngressOwner", + environmentAnnotation: "testing", + criticalityAnnotation: "low", + sensitivityAnnotation: "public", + "com.uswitch.heimdall/label-priority": "p2", + "com.uswitch.heimdall/label-channel": "testing", + "com.uswitch.heimdall/label-region": "eu-west-1", + }, + }, + Spec: networkingv1.IngressSpec{ + DefaultBackend: &networkingv1.IngressBackend{ + Service: &networkingv1.IngressServiceBackend{ + Name: "testService", + Port: networkingv1.ServiceBackendPort{ + Number: 80, + }, + }, + }, + }, + } ) func TestIngressAnnotationsDefaultBackend(t *testing.T) { @@ -191,3 +218,19 @@ func TestNamesMatch(t *testing.T) { service = checkNamesMatch(services) assert.Equal(t, "", service) } + +func TestIngressMultipleCustomLabels(t *testing.T) { + log.Setup(log.DEBUG_LEVEL) + + client := fake.NewSimpleClientset(testService, testDeployment, testReplicaset, testPod) + + template, err := NewPrometheusRuleTemplateManager("../../kube/config/templates", client) + + promrules, err := template.CreateFromIngress(testIngressMultiLabel) + assert.Assert(t, is.Nil(err)) + assert.Assert(t, is.Len(promrules, 1)) + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["priority"], "p2") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["channel"], "testing") + assert.Equal(t, promrules[0].Spec.Groups[0].Rules[0].Labels["region"], "eu-west-1") +} + diff --git a/pkg/templates/promrules.go b/pkg/templates/promrules.go index 6e09703..ec7f2f9 100644 --- a/pkg/templates/promrules.go +++ b/pkg/templates/promrules.go @@ -14,7 +14,10 @@ import ( corev1 "k8s.io/client-go/kubernetes/typed/core/v1" ) -var heimPrefix = "com.uswitch.heimdall" +var ( + heimPrefix = "com.uswitch.heimdall" + labelPrefix = "com.uswitch.heimdall/label-" +) const ( ownerAnnotation = "service.rvu.co.uk/owner" @@ -80,3 +83,17 @@ func collectPrometheusRules(prometheusRules map[string]*monitoringv1.PrometheusR return ret } + +// com.uswitch.heimdall/label-priority: p3 -> map["priority"] = "p3" +func extractCustomLabels(annotations map[string]string) map[string]string { + customLabels := make(map[string]string) + + for k, v := range annotations { + if strings.HasPrefix(k, labelPrefix) { + labelName := strings.TrimPrefix(k, labelPrefix) + customLabels[labelName] = v + } + } + + return customLabels +} From 45834c595a46572fe82cfac0257efa8e16b768b2 Mon Sep 17 00:00:00 2001 From: Kristin Wong Date: Fri, 14 Nov 2025 14:15:02 +0000 Subject: [PATCH 5/5] fix mistake --- pkg/templates/deployment.go | 4 ++-- pkg/templates/ingress.go | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pkg/templates/deployment.go b/pkg/templates/deployment.go index de605d8..b2331c3 100644 --- a/pkg/templates/deployment.go +++ b/pkg/templates/deployment.go @@ -69,6 +69,8 @@ func (a *PrometheusRuleTemplateManager) CreateFromDeployment(deployment *apps.De prometheusRules := map[string]*monitoringv1.PrometheusRule{} annotations := params.Deployment.GetAnnotations() + params.CustomLabels = extractCustomLabels(annotations) + for k, v := range annotations { if !strings.HasPrefix(k, heimPrefix) { continue @@ -79,8 +81,6 @@ func (a *PrometheusRuleTemplateManager) CreateFromDeployment(deployment *apps.De continue } - params.CustomLabels = extractCustomLabels(annotations) - templateName := strings.TrimLeft(k, fmt.Sprintf("%s/", heimPrefix)) logger.Infow("template selected", "template", templateName) template, ok := a.templates[templateName] diff --git a/pkg/templates/ingress.go b/pkg/templates/ingress.go index 03711ab..da8c846 100644 --- a/pkg/templates/ingress.go +++ b/pkg/templates/ingress.go @@ -51,6 +51,7 @@ func (a *PrometheusRuleTemplateManager) CreateFromIngress(ingress *networkingv1. prometheusRules := map[string]*monitoringv1.PrometheusRule{} annotations := ingress.GetAnnotations() + params.CustomLabels = extractCustomLabels(annotations) for k, v := range annotations { if !strings.HasPrefix(k, heimPrefix) { @@ -62,8 +63,6 @@ func (a *PrometheusRuleTemplateManager) CreateFromIngress(ingress *networkingv1. continue } - params.CustomLabels = extractCustomLabels(annotations) - templateName := strings.TrimLeft(k, fmt.Sprintf("%s/", heimPrefix)) template, ok := a.templates[templateName] if !ok {