From 78c6963feabe64cd03389b1dea2a061781dcbaeb Mon Sep 17 00:00:00 2001 From: Tetiana Yeremenko Date: Wed, 10 Dec 2025 20:27:07 +0000 Subject: [PATCH] Add support for entity type and name in custom monitored resource --- prometheus-to-sd/config/common_config.go | 25 +++- prometheus-to-sd/config/dynamic_source.go | 4 +- .../config/dynamic_source_test.go | 27 ++++- prometheus-to-sd/config/pod_config_test.go | 111 +++++++++++++++++- prometheus-to-sd/config/source_config.go | 4 +- prometheus-to-sd/config/source_config_test.go | 68 +++++++++-- prometheus-to-sd/translator/translator.go | 26 ++-- .../translator/translator_test.go | 104 ++++++++++++++-- 8 files changed, 325 insertions(+), 44 deletions(-) diff --git a/prometheus-to-sd/config/common_config.go b/prometheus-to-sd/config/common_config.go index 620645ae5..13f39514a 100644 --- a/prometheus-to-sd/config/common_config.go +++ b/prometheus-to-sd/config/common_config.go @@ -30,12 +30,12 @@ type PodConfig interface { IsMetricLabel(labelName string) bool // GetPodInfo returns the information required to identify the pod. - GetPodInfo(labels []*dto.LabelPair) (containerName, podId, namespaceId, tenantUID string) + GetPodInfo(labels []*dto.LabelPair) (containerName, podId, namespaceId, tenantUID, entityType, entityName string) } // NewPodConfig returns a PodConfig which uses for the provided pod, namespace and container label values, // if found, and falls back to the podId and namespaceId. -func NewPodConfig(podId, namespaceId, podIdLabel, namespaceIdLabel, containerNameLabel, tenantUIDLabel string) PodConfig { +func NewPodConfig(podId, namespaceId, podIdLabel, namespaceIdLabel, containerNameLabel, tenantUIDLabel, entityTypeLabel, entityNameLabel string) PodConfig { return &podConfigImpl{ podId: podId, namespaceId: namespaceId, @@ -43,6 +43,8 @@ func NewPodConfig(podId, namespaceId, podIdLabel, namespaceIdLabel, containerNam namespaceIdLabel: namespaceIdLabel, containerNameLabel: containerNameLabel, tenantUIDLabel: tenantUIDLabel, + entityTypeLabel: entityTypeLabel, + entityNameLabel: entityNameLabel, } } @@ -53,14 +55,21 @@ type podConfigImpl struct { namespaceIdLabel string containerNameLabel string tenantUIDLabel string + entityTypeLabel string + entityNameLabel string } func (p *podConfigImpl) IsMetricLabel(labelName string) bool { - return labelName != p.podIdLabel && labelName != p.containerNameLabel && labelName != p.namespaceIdLabel && labelName != p.tenantUIDLabel + return labelName != p.podIdLabel && + labelName != p.containerNameLabel && + labelName != p.namespaceIdLabel && + labelName != p.tenantUIDLabel && + labelName != p.entityTypeLabel && + labelName != p.entityNameLabel } -func (p *podConfigImpl) GetPodInfo(labels []*dto.LabelPair) (containerName, podId, namespaceId, tenantUID string) { - containerName, podId, namespaceId, tenantUID = "", p.podId, p.namespaceId, "" +func (p *podConfigImpl) GetPodInfo(labels []*dto.LabelPair) (containerName, podId, namespaceId, tenantUID, entityType, entityName string) { + containerName, podId, namespaceId, tenantUID, entityType, entityName = "", p.podId, p.namespaceId, "", "", "" for _, label := range labels { if label.GetName() == p.containerNameLabel && label.GetValue() != "" { containerName = label.GetValue() @@ -70,9 +79,13 @@ func (p *podConfigImpl) GetPodInfo(labels []*dto.LabelPair) (containerName, podI namespaceId = label.GetValue() } else if label.GetName() == p.tenantUIDLabel && label.GetValue() != "" { tenantUID = label.GetValue() + } else if label.GetName() == p.entityTypeLabel && label.GetValue() != "" { + entityType = label.GetValue() + } else if label.GetName() == p.entityNameLabel && label.GetValue() != "" { + entityName = label.GetValue() } } - return containerName, podId, namespaceId, tenantUID + return containerName, podId, namespaceId, tenantUID, entityType, entityName } // CommonConfig contains all required information about environment in which diff --git a/prometheus-to-sd/config/dynamic_source.go b/prometheus-to-sd/config/dynamic_source.go index 085a921e4..eff82485a 100644 --- a/prometheus-to-sd/config/dynamic_source.go +++ b/prometheus-to-sd/config/dynamic_source.go @@ -108,6 +108,8 @@ func mapToSourceConfig(componentName string, url url.URL, ip string, podId, name namespaceIdLabel := values.Get("namespaceIdLabel") containerNamelabel := values.Get("containerNamelabel") tenantUIDLabel := values.Get("tenantUIDLabel") + entityTypeLabel := values.Get("entityTypeLabel") + entityNameLabel := values.Get("entityNameLabel") metricsPrefix := values.Get("metricsPrefix") customResource := values.Get("customResourceType") customLabels := getMap(values, "customLabels") @@ -115,7 +117,7 @@ func mapToSourceConfig(componentName string, url url.URL, ip string, podId, name if err != nil { return nil, err } - podConfig := NewPodConfig(podId, namespaceId, podIdLabel, namespaceIdLabel, containerNamelabel, tenantUIDLabel) + podConfig := NewPodConfig(podId, namespaceId, podIdLabel, namespaceIdLabel, containerNamelabel, tenantUIDLabel, entityTypeLabel, entityNameLabel) whitelistedLabelsMap, err := parseWhitelistedLabels(url.Query().Get("whitelistedLabels")) if err != nil { return nil, err diff --git a/prometheus-to-sd/config/dynamic_source_test.go b/prometheus-to-sd/config/dynamic_source_test.go index c6d07391c..1d4cd13c7 100644 --- a/prometheus-to-sd/config/dynamic_source_test.go +++ b/prometheus-to-sd/config/dynamic_source_test.go @@ -38,7 +38,7 @@ func TestMapToSourceConfig(t *testing.T) { Port: uint(8080), Path: defaultMetricsPath, AuthConfig: emptyAuthConfig, - PodConfig: NewPodConfig(podName, podNamespace, "", "", "", ""), + PodConfig: NewPodConfig(podName, podNamespace, "", "", "", "", "", ""), WhitelistedLabelsMap: emptyWhitelistedLabelsMap, CustomLabels: map[string]string{}, }, @@ -57,7 +57,7 @@ func TestMapToSourceConfig(t *testing.T) { Path: defaultMetricsPath, AuthConfig: tokenAuthConfig, Whitelisted: []string{"metric1", "metric2"}, - PodConfig: NewPodConfig(podName, podNamespace, "", "", "", ""), + PodConfig: NewPodConfig(podName, podNamespace, "", "", "", "", "", ""), WhitelistedLabelsMap: emptyWhitelistedLabelsMap, CustomLabels: map[string]string{}, }, @@ -76,7 +76,7 @@ func TestMapToSourceConfig(t *testing.T) { Path: defaultMetricsPath, AuthConfig: userAuthConfig, Whitelisted: []string{"metric1", "metric2"}, - PodConfig: NewPodConfig(podName, podNamespace, "pod-id", "namespace-id", "container-name", ""), + PodConfig: NewPodConfig(podName, podNamespace, "pod-id", "namespace-id", "container-name", "", "", ""), WhitelistedLabelsMap: emptyWhitelistedLabelsMap, CustomLabels: map[string]string{}, }, @@ -94,7 +94,7 @@ func TestMapToSourceConfig(t *testing.T) { Port: uint(8080), Path: defaultMetricsPath, Whitelisted: []string{"metric1", "metric2"}, - PodConfig: NewPodConfig(podName, podNamespace, "pod-id", "namespace-id", "id", ""), + PodConfig: NewPodConfig(podName, podNamespace, "pod-id", "namespace-id", "id", "", "", ""), WhitelistedLabelsMap: map[string]map[string]bool{ "containerNameLabel": {"/system.slice/node-problem-detector.service": true}, }, @@ -113,7 +113,24 @@ func TestMapToSourceConfig(t *testing.T) { Host: "very_important_ip", Port: uint(8080), Path: defaultMetricsPath, - PodConfig: NewPodConfig(podName, podNamespace, "pod-id", "namespace-id", "id", "tenant-uid"), + PodConfig: NewPodConfig(podName, podNamespace, "pod-id", "namespace-id", "id", "tenant-uid", "", ""), + WhitelistedLabelsMap: emptyWhitelistedLabelsMap, + CustomLabels: map[string]string{}, + }, + }, + { + componentName: "custom-entity", + url: url.URL{Host: ":8080", RawQuery: "podIdLabel=pod-id&entityTypeLabel=custom-type-label&entityNameLabel=custom-name-label"}, + ip: "very_important_ip", + podName: podName, + podNamespace: podNamespace, + want: SourceConfig{ + Component: "custom-entity", + Protocol: "http", + Host: "very_important_ip", + Port: uint(8080), + Path: defaultMetricsPath, + PodConfig: NewPodConfig(podName, podNamespace, "pod-id", "", "", "", "custom-type-label", "custom-name-label"), WhitelistedLabelsMap: emptyWhitelistedLabelsMap, CustomLabels: map[string]string{}, }, diff --git a/prometheus-to-sd/config/pod_config_test.go b/prometheus-to-sd/config/pod_config_test.go index 87451a3e7..4d96ec6f7 100644 --- a/prometheus-to-sd/config/pod_config_test.go +++ b/prometheus-to-sd/config/pod_config_test.go @@ -76,6 +76,31 @@ func TestIsMetricLabel(t *testing.T) { label: "def", want: false, }, + { + desc: "entityTypeLabel matches", + config: &podConfigImpl{ + containerNameLabel: "foo", + podIdLabel: "bar", + namespaceIdLabel: "abc", + tenantUIDLabel: "def", + entityTypeLabel: "ghi", + }, + label: "ghi", + want: false, + }, + { + desc: "entityNameLabel matches", + config: &podConfigImpl{ + containerNameLabel: "foo", + podIdLabel: "bar", + namespaceIdLabel: "abc", + tenantUIDLabel: "def", + entityTypeLabel: "ghi", + entityNameLabel: "jkl", + }, + label: "jkl", + want: false, + }, { desc: "none match", config: &podConfigImpl{ @@ -102,6 +127,8 @@ func TestGetPodInfo(t *testing.T) { pod, podLabel := "pod", "pLabel" namespace, namespaceLabel := "namespace", "nLabel" tenantUID, tenantUIDLabel := "tenantUID", "tLabel" + entityType, entityTypeLabel := "entityType", "eTLabel" + entityName, entityNameLabel := "entityName", "eNLabel" other, otherLabel := "other", "olabel" labels := []*dto.LabelPair{ { @@ -124,6 +151,14 @@ func TestGetPodInfo(t *testing.T) { Name: &tenantUIDLabel, Value: &tenantUID, }, + { + Name: &entityTypeLabel, + Value: &entityType, + }, + { + Name: &entityNameLabel, + Value: &entityName, + }, } for _, tc := range []struct { desc string @@ -132,6 +167,8 @@ func TestGetPodInfo(t *testing.T) { wantPodId string wantNamespaceId string wantTenantUID string + wantEntityType string + wantEntityName string }{ { desc: "empty", @@ -139,6 +176,9 @@ func TestGetPodInfo(t *testing.T) { wantContainerName: "", wantPodId: "", wantNamespaceId: "", + wantTenantUID: "", + wantEntityType: "", + wantEntityName: "", }, { desc: "not matching labels", @@ -150,6 +190,9 @@ func TestGetPodInfo(t *testing.T) { wantContainerName: "", wantPodId: "", wantNamespaceId: "", + wantTenantUID: "", + wantEntityType: "", + wantEntityName: "", }, { desc: "matching labels", @@ -161,6 +204,9 @@ func TestGetPodInfo(t *testing.T) { wantContainerName: container, wantPodId: pod, wantNamespaceId: namespace, + wantTenantUID: "", + wantEntityType: "", + wantEntityName: "", }, { desc: "matching labels w/ podId and namespaceId specified", @@ -174,6 +220,9 @@ func TestGetPodInfo(t *testing.T) { wantContainerName: container, wantPodId: pod, wantNamespaceId: namespace, + wantTenantUID: "", + wantEntityType: "", + wantEntityName: "", }, { desc: "not matching labels w/ podId and namespaceId specified", @@ -187,6 +236,9 @@ func TestGetPodInfo(t *testing.T) { wantContainerName: "", wantPodId: "podid", wantNamespaceId: "namespaceid", + wantTenantUID: "", + wantEntityType: "", + wantEntityName: "", }, { desc: "some matching labels w/ podId and namespaceId specified", @@ -200,6 +252,9 @@ func TestGetPodInfo(t *testing.T) { wantContainerName: container, wantPodId: "podid", wantNamespaceId: "namespaceid", + wantTenantUID: "", + wantEntityType: "", + wantEntityName: "", }, { desc: "podId and namespaceId specified", @@ -210,17 +265,63 @@ func TestGetPodInfo(t *testing.T) { wantContainerName: "", wantPodId: "podid", wantNamespaceId: "namespaceid", + wantTenantUID: "", + wantEntityType: "", + wantEntityName: "", }, { desc: "tenant UID specified", config: &podConfigImpl{ tenantUIDLabel: tenantUIDLabel, }, - wantTenantUID: tenantUID, + wantContainerName: "", + wantPodId: "", + wantNamespaceId: "", + wantTenantUID: tenantUID, + wantEntityType: "", + wantEntityName: "", + }, + { + desc: "entity type specified", + config: &podConfigImpl{ + entityTypeLabel: entityTypeLabel, + }, + wantContainerName: "", + wantPodId: "", + wantNamespaceId: "", + wantTenantUID: "", + wantEntityType: entityType, + wantEntityName: "", + }, + { + desc: "entity name specified", + config: &podConfigImpl{ + entityNameLabel: entityNameLabel, + }, + wantContainerName: "", + wantPodId: "", + wantNamespaceId: "", + wantTenantUID: "", + wantEntityType: "", + wantEntityName: entityName, + }, + { + desc: "all custom labels specified", + config: &podConfigImpl{ + tenantUIDLabel: tenantUIDLabel, + entityTypeLabel: entityTypeLabel, + entityNameLabel: entityNameLabel, + }, + wantContainerName: "", + wantPodId: "", + wantNamespaceId: "", + wantTenantUID: tenantUID, + wantEntityType: entityType, + wantEntityName: entityName, }, } { t.Run(tc.desc, func(t *testing.T) { - container, pod, namespace, tenantUID := tc.config.GetPodInfo(labels) + container, pod, namespace, tenantUID, entityType, entityName := tc.config.GetPodInfo(labels) if container != tc.wantContainerName { t.Errorf("Unexpected containerName; got %q, want %q", container, tc.wantContainerName) } @@ -233,6 +334,12 @@ func TestGetPodInfo(t *testing.T) { if tenantUID != tc.wantTenantUID { t.Errorf("Unexpected tenantUID; got %q, want %q", tenantUID, tc.wantTenantUID) } + if entityType != tc.wantEntityType { + t.Errorf("Unexpected entityType; got %q, want %q", entityType, tc.wantEntityType) + } + if entityName != tc.wantEntityName { + t.Errorf("Unexpected entityName; got %q, want %q", entityName, tc.wantEntityName) + } }) } } diff --git a/prometheus-to-sd/config/source_config.go b/prometheus-to-sd/config/source_config.go index 1603a9276..6a63664b9 100644 --- a/prometheus-to-sd/config/source_config.go +++ b/prometheus-to-sd/config/source_config.go @@ -107,6 +107,8 @@ func parseSourceConfig(uri flags.Uri, podId, namespaceId string) (*SourceConfig, namespaceIdLabel := values.Get("namespaceIdLabel") containerNameLabel := values.Get("containerNameLabel") tenantUIDLabel := values.Get("tenantUIDLabel") + entityTypeLabel := values.Get("entityTypeLabel") + entityNameLabel := values.Get("entityNameLabel") metricsPrefix := values.Get("metricsPrefix") customResource := values.Get("customResourceType") customLabels := getMap(values, "customLabels") @@ -114,7 +116,7 @@ func parseSourceConfig(uri flags.Uri, podId, namespaceId string) (*SourceConfig, if err != nil { return nil, err } - podConfig := NewPodConfig(podId, namespaceId, podIdLabel, namespaceIdLabel, containerNameLabel, tenantUIDLabel) + podConfig := NewPodConfig(podId, namespaceId, podIdLabel, namespaceIdLabel, containerNameLabel, tenantUIDLabel, entityTypeLabel, entityNameLabel) whitelistedLabelsMap, err := parseWhitelistedLabels(values.Get("whitelistedLabels")) if err != nil { diff --git a/prometheus-to-sd/config/source_config_test.go b/prometheus-to-sd/config/source_config_test.go index 7e6579a6c..cb0f4b224 100644 --- a/prometheus-to-sd/config/source_config_test.go +++ b/prometheus-to-sd/config/source_config_test.go @@ -30,8 +30,8 @@ var ( ) func TestNewSourceConfig(t *testing.T) { - podConfig := NewPodConfig("podId", "namespaceId", "", "", "", "") - emptyPodConfig := NewPodConfig("", "", "", "", "", "") + podConfig := NewPodConfig("podId", "namespaceId", "", "", "", "", "", "") + emptyPodConfig := NewPodConfig("", "", "", "", "", "", "", "") authConfig := AuthConfig{Token: "token"} correct := [...]struct { component string @@ -156,7 +156,7 @@ func TestParseSourceConfig(t *testing.T) { Path: defaultMetricsPath, AuthConfig: tokenAuthConfig, Whitelisted: []string{"a", "b", "c", "d"}, - PodConfig: NewPodConfig(podId, namespaceId, "", "", "", ""), + PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "", "", ""), WhitelistedLabelsMap: emptyWhitelistedLabelsMap, CustomLabels: map[string]string{}, }, @@ -179,7 +179,7 @@ func TestParseSourceConfig(t *testing.T) { Path: "/status/prometheus", AuthConfig: userAuthConfig, Whitelisted: []string{"a", "b", "c", "d"}, - PodConfig: NewPodConfig(podId, namespaceId, "", "", "", ""), + PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "", "", ""), WhitelistedLabelsMap: emptyWhitelistedLabelsMap, CustomLabels: map[string]string{}, }, @@ -201,7 +201,7 @@ func TestParseSourceConfig(t *testing.T) { Port: 8080, Path: defaultMetricsPath, MetricsPrefix: "container.googleapis.com/newPrefix", - PodConfig: NewPodConfig(podId, namespaceId, "", "", "", ""), + PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "", "", ""), WhitelistedLabelsMap: emptyWhitelistedLabelsMap, CustomLabels: map[string]string{}, }, @@ -226,7 +226,7 @@ func TestParseSourceConfig(t *testing.T) { "containerNameLabel": {"testContainer": true}, "podIdLabel": {"pod1": true}, }, - PodConfig: NewPodConfig(podId, namespaceId, "", "", "", ""), + PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "", "", ""), CustomLabels: map[string]string{}, }, }, @@ -249,7 +249,7 @@ func TestParseSourceConfig(t *testing.T) { WhitelistedLabelsMap: map[string]map[string]bool{ "containerNameLabel": {"testContainer1": true, "testContainer2": true}, }, - PodConfig: NewPodConfig(podId, namespaceId, "", "", "", ""), + PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "", "", ""), CustomLabels: map[string]string{}, }, }, @@ -270,7 +270,7 @@ func TestParseSourceConfig(t *testing.T) { Port: 1234, Path: defaultMetricsPath, WhitelistedLabelsMap: emptyWhitelistedLabelsMap, - PodConfig: NewPodConfig(podId, namespaceId, "", "", "", ""), + PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "", "", ""), CustomResourceType: "quux", CustomLabels: map[string]string{ "foo": "bar", @@ -295,7 +295,7 @@ func TestParseSourceConfig(t *testing.T) { Port: 1234, Path: defaultMetricsPath, WhitelistedLabelsMap: emptyWhitelistedLabelsMap, - PodConfig: NewPodConfig(podId, namespaceId, "", "", "", ""), + PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "", "", ""), CustomResourceType: "quux", CustomLabels: map[string]string{ "foo": "", @@ -320,13 +320,61 @@ func TestParseSourceConfig(t *testing.T) { Port: 1234, Path: defaultMetricsPath, WhitelistedLabelsMap: emptyWhitelistedLabelsMap, - PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "some_uid"), + PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "some_uid", "", ""), CustomResourceType: "quux", CustomLabels: map[string]string{ "some_uid": "", }, }, }, + { + flags.Uri{ + Key: "testComponent", + Val: url.URL{ + Scheme: "http", + Host: "hostname:1234", + Path: defaultMetricsPath, + RawQuery: "customResourceType=quux&customLabels[type]=&&entityTypeLabel=type", + }, + }, + SourceConfig{ + Component: "testComponent", + Protocol: "http", + Host: "hostname", + Port: 1234, + Path: defaultMetricsPath, + WhitelistedLabelsMap: emptyWhitelistedLabelsMap, + PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "", "type", ""), + CustomResourceType: "quux", + CustomLabels: map[string]string{ + "type": "", + }, + }, + }, + { + flags.Uri{ + Key: "testComponent", + Val: url.URL{ + Scheme: "http", + Host: "hostname:1234", + Path: defaultMetricsPath, + RawQuery: "customResourceType=quux&customLabels[name]=&&entityNameLabel=name", + }, + }, + SourceConfig{ + Component: "testComponent", + Protocol: "http", + Host: "hostname", + Port: 1234, + Path: defaultMetricsPath, + WhitelistedLabelsMap: emptyWhitelistedLabelsMap, + PodConfig: NewPodConfig(podId, namespaceId, "", "", "", "", "", "name"), + CustomResourceType: "quux", + CustomLabels: map[string]string{ + "name": "", + }, + }, + }, } for _, c := range correct { diff --git a/prometheus-to-sd/translator/translator.go b/prometheus-to-sd/translator/translator.go index db921cab1..fc1bd940b 100644 --- a/prometheus-to-sd/translator/translator.go +++ b/prometheus-to-sd/translator/translator.go @@ -481,10 +481,10 @@ func createProjectName(config *config.GceConfig) string { } func getMonitoredResourceFromLabels(config *config.CommonConfig, labels []*dto.LabelPair) *monitoredres.MonitoredResource { - container, pod, namespace, tenantUID := config.SourceConfig.PodConfig.GetPodInfo(labels) + container, pod, namespace, tenantUID, entityType, entityName := config.SourceConfig.PodConfig.GetPodInfo(labels) if config.SourceConfig.CustomResourceType != "" { - return getCustomMonitoredResource(config, tenantUID) + return getCustomMonitoredResource(config, tenantUID, entityType, entityName) } prefix := config.MonitoredResourceTypePrefix @@ -554,19 +554,29 @@ func getMonitoredResourceFromLabels(config *config.CommonConfig, labels []*dto.L } } -func getCustomMonitoredResource(config *config.CommonConfig, tenantUID string) *monitoredres.MonitoredResource { +func getCustomMonitoredResource(config *config.CommonConfig, tenantUID, entityType, entityName string) *monitoredres.MonitoredResource { resourceLabels := config.SourceConfig.CustomLabels applyDefaultIfEmpty(resourceLabels, "instance_id", config.GceConfig.InstanceId) applyDefaultIfEmpty(resourceLabels, "project_id", config.GceConfig.Project) applyDefaultIfEmpty(resourceLabels, "cluster_name", config.GceConfig.Cluster) applyDefaultIfEmpty(resourceLabels, "location", config.GceConfig.ClusterLocation) applyDefaultIfEmpty(resourceLabels, "node_name", config.GceConfig.Instance) + finalLabels := maps.Clone(resourceLabels) + dynamicLabels := map[string]string{ + "tenant_uid": tenantUID, + "entity_type": entityType, + "entity_name": entityName, + } + + for key, value := range dynamicLabels { + // Only apply the dynamic value if the key was pre-configured in CustomLabels + if _, found := finalLabels[key]; found { + finalLabels[key] = value + } + } return &monitoredres.MonitoredResource{ - Type: config.SourceConfig.CustomResourceType, - // Need to clone the map because timeseries created using this label can - // have its label value overwritten by a newer value of tenant_uid before - // it was even exported since map would have pointed to the same address. - Labels: cloneAndApplyDefaultIfFound(resourceLabels, "tenant_uid", tenantUID), + Type: config.SourceConfig.CustomResourceType, + Labels: finalLabels, } } diff --git a/prometheus-to-sd/translator/translator_test.go b/prometheus-to-sd/translator/translator_test.go index b0dd8d065..a3c0a0273 100644 --- a/prometheus-to-sd/translator/translator_test.go +++ b/prometheus-to-sd/translator/translator_test.go @@ -60,7 +60,7 @@ var commonConfig = &config.CommonConfig{ Instance: "kubernetes-master.c.test-proj.internal", }, SourceConfig: &config.SourceConfig{ - PodConfig: config.NewPodConfig("machine", "", "", "", "", ""), + PodConfig: config.NewPodConfig("machine", "", "", "", "", "", "", ""), Component: "testcomponent", MetricsPrefix: "container.googleapis.com/master", }, @@ -323,7 +323,7 @@ func TestGetMonitoredResourceFromLabels(t *testing.T) { InstanceId: "123", }, SourceConfig: &config.SourceConfig{ - PodConfig: config.NewPodConfig("", "", "", "", "", ""), + PodConfig: config.NewPodConfig("", "", "", "", "", "", "", ""), }, MonitoredResourceLabels: map[string]string{}, }, @@ -345,7 +345,7 @@ func TestGetMonitoredResourceFromLabels(t *testing.T) { &config.CommonConfig{ GceConfig: &config.GceConfig{}, SourceConfig: &config.SourceConfig{ - PodConfig: config.NewPodConfig("machine", "", "", "", "", ""), + PodConfig: config.NewPodConfig("machine", "", "", "", "", "", "", ""), }, MonitoredResourceTypePrefix: "k8s_", MonitoredResourceLabels: map[string]string{ @@ -376,7 +376,7 @@ func TestGetMonitoredResourceFromLabels(t *testing.T) { InstanceId: "123", }, SourceConfig: &config.SourceConfig{ - PodConfig: config.NewPodConfig("machine", "", "", "", "", ""), + PodConfig: config.NewPodConfig("machine", "", "", "", "", "", "", ""), }, MonitoredResourceTypePrefix: "k8s_", MonitoredResourceLabels: map[string]string{}, @@ -401,7 +401,7 @@ func TestGetMonitoredResourceFromLabels(t *testing.T) { InstanceId: "123", }, SourceConfig: &config.SourceConfig{ - PodConfig: config.NewPodConfig("test-pod", "test-namespace", "", "", "", ""), + PodConfig: config.NewPodConfig("test-pod", "test-namespace", "", "", "", "", "", ""), }, MonitoredResourceTypePrefix: "k8s_", MonitoredResourceLabels: map[string]string{ @@ -425,7 +425,7 @@ func TestGetMonitoredResourceFromLabels(t *testing.T) { &config.CommonConfig{ GceConfig: &config.GceConfig{}, SourceConfig: &config.SourceConfig{ - PodConfig: config.NewPodConfig("test-pod", "test-namespace", "", "", "containerNameLabel", ""), + PodConfig: config.NewPodConfig("test-pod", "test-namespace", "", "", "containerNameLabel", "", "", ""), }, MonitoredResourceTypePrefix: "k8s_", MonitoredResourceLabels: map[string]string{ @@ -461,7 +461,7 @@ func TestGetMonitoredResourceFromLabels(t *testing.T) { InstanceId: "123", }, SourceConfig: &config.SourceConfig{ - PodConfig: config.NewPodConfig("machine", "", "", "", "", ""), + PodConfig: config.NewPodConfig("machine", "", "", "", "", "", "", ""), }, MonitoredResourceTypePrefix: "other_prefix_", MonitoredResourceLabels: map[string]string{ @@ -496,7 +496,7 @@ func TestGetMonitoredResourceFromLabels(t *testing.T) { CustomLabels: map[string]string{ "foo": "bar", }, - PodConfig: config.NewPodConfig("", "", "", "", "", ""), + PodConfig: config.NewPodConfig("", "", "", "", "", "", "", ""), }, }, nil, @@ -528,7 +528,7 @@ func TestGetMonitoredResourceFromLabels(t *testing.T) { "instance_id": "", "node_name": "", }, - PodConfig: config.NewPodConfig("", "", "", "", "", ""), + PodConfig: config.NewPodConfig("", "", "", "", "", "", "", ""), }, }, nil, @@ -565,7 +565,7 @@ func TestGetMonitoredResourceFromLabels(t *testing.T) { "node_name": "", "tenant_uid": "old-tenant-uid", }, - PodConfig: config.NewPodConfig("", "", "", "", "", "tenantUIDLabel"), + PodConfig: config.NewPodConfig("", "", "", "", "", "tenantUIDLabel", "", ""), }, }, []*dto.LabelPair{ @@ -584,6 +584,88 @@ func TestGetMonitoredResourceFromLabels(t *testing.T) { "tenant_uid": "tenant_uid", }, }, + { + "Add entity type label to custom monitored resource", + &config.CommonConfig{ + MonitoredResourceLabels: map[string]string{}, + GceConfig: &config.GceConfig{ + Project: "default-project", + Zone: "us-east1-a", + Cluster: "test-cluster", + ClusterLocation: "test-location", + Instance: "default-instance", + InstanceId: "123", + }, + SourceConfig: &config.SourceConfig{ + CustomResourceType: "resource_foo", + CustomLabels: map[string]string{ + "project_id": "", + "cluster_name": "", + "location": "", + "instance_id": "", + "node_name": "", + "entity_type": "test", + }, + PodConfig: config.NewPodConfig("", "", "", "", "", "", "entityTypeLabel", ""), + }, + }, + []*dto.LabelPair{ + { + Name: stringPtr("entityTypeLabel"), + Value: stringPtr("test"), + }, + }, + "resource_foo", + map[string]string{ + "project_id": "default-project", + "cluster_name": "test-cluster", + "location": "test-location", + "instance_id": "123", + "node_name": "default-instance", + "entity_type": "test", + }, + }, + { + "Add entity name label to custom monitored resource", + &config.CommonConfig{ + MonitoredResourceLabels: map[string]string{}, + GceConfig: &config.GceConfig{ + Project: "default-project", + Zone: "us-east1-a", + Cluster: "test-cluster", + ClusterLocation: "test-location", + Instance: "default-instance", + InstanceId: "123", + }, + SourceConfig: &config.SourceConfig{ + CustomResourceType: "resource_foo", + CustomLabels: map[string]string{ + "project_id": "", + "cluster_name": "", + "location": "", + "instance_id": "", + "node_name": "", + "entity_name": "test", + }, + PodConfig: config.NewPodConfig("", "", "", "", "", "", "", "entityNameLabel"), + }, + }, + []*dto.LabelPair{ + { + Name: stringPtr("entityNameLabel"), + Value: stringPtr("entity_name"), + }, + }, + "resource_foo", + map[string]string{ + "project_id": "default-project", + "cluster_name": "test-cluster", + "location": "test-location", + "instance_id": "123", + "node_name": "default-instance", + "entity_name": "entity_name", + }, + }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { @@ -713,7 +795,7 @@ func TestTranslatePrometheusToStackdriverWithLabelFiltering(t *testing.T) { Instance: "kubernetes-master.c.test-proj.internal", }, SourceConfig: &config.SourceConfig{ - PodConfig: config.NewPodConfig("machine", "", "", "", "", ""), + PodConfig: config.NewPodConfig("machine", "", "", "", "", "", "", ""), Component: "testcomponent", MetricsPrefix: "container.googleapis.com/master", Whitelisted: []string{testMetricName, testMetricHistogram, booleanMetricName, floatMetricName},