From 932918cd3fe003d0f4fd0fe153b610a068fe9fea Mon Sep 17 00:00:00 2001 From: Arve Knudsen Date: Thu, 18 Jul 2024 10:40:47 +0200 Subject: [PATCH] OTLPConfig.UnmarshalYAML: Return error on invalid input Signed-off-by: Arve Knudsen --- config/config.go | 22 ++++++++++--------- config/config_test.go | 22 +++++++++++++------ .../otlp_sanitize_resource_attributes.bad.yml | 2 ++ ...otlp_sanitize_resource_attributes.good.yml | 2 +- 4 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 config/testdata/otlp_sanitize_resource_attributes.bad.yml diff --git a/config/config.go b/config/config.go index fd2e6e06c..913983881 100644 --- a/config/config.go +++ b/config/config.go @@ -19,7 +19,6 @@ import ( "net/url" "os" "path/filepath" - "slices" "sort" "strconv" "strings" @@ -1324,17 +1323,20 @@ func (c *OTLPConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { } seen := map[string]struct{}{} - i := 0 - for i < len(c.PromoteResourceAttributes) { - s := strings.TrimSpace(c.PromoteResourceAttributes[i]) - if _, exists := seen[s]; exists { - c.PromoteResourceAttributes = slices.Delete(c.PromoteResourceAttributes, i, i+1) + var err error + for i, attr := range c.PromoteResourceAttributes { + attr = strings.TrimSpace(attr) + if attr == "" { + err = errors.Join(err, fmt.Errorf("empty promoted OTel resource attribute")) + continue + } + if _, exists := seen[attr]; exists { + err = errors.Join(err, fmt.Errorf("duplicated promoted OTel resource attribute %q", attr)) continue } - seen[s] = struct{}{} - c.PromoteResourceAttributes[i] = s - i++ + seen[attr] = struct{}{} + c.PromoteResourceAttributes[i] = attr } - return nil + return err } diff --git a/config/config_test.go b/config/config_test.go index 5822d2ceb..b684fdb50 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1478,15 +1478,23 @@ func TestRemoteWriteRetryOnRateLimit(t *testing.T) { } func TestOTLPSanitizeResourceAttributes(t *testing.T) { - want, err := LoadFile(filepath.Join("testdata", "otlp_sanitize_resource_attributes.good.yml"), false, false, log.NewNopLogger()) - require.NoError(t, err) + t.Run("good config", func(t *testing.T) { + want, err := LoadFile(filepath.Join("testdata", "otlp_sanitize_resource_attributes.good.yml"), false, false, log.NewNopLogger()) + require.NoError(t, err) - out, err := yaml.Marshal(want) - require.NoError(t, err) - var got Config - require.NoError(t, yaml.UnmarshalStrict(out, &got)) + out, err := yaml.Marshal(want) + require.NoError(t, err) + var got Config + require.NoError(t, yaml.UnmarshalStrict(out, &got)) - require.Equal(t, []string{"k8s.cluster.name", "k8s.job.name", "k8s.namespace.name"}, got.OTLPConfig.PromoteResourceAttributes) + require.Equal(t, []string{"k8s.cluster.name", "k8s.job.name", "k8s.namespace.name"}, got.OTLPConfig.PromoteResourceAttributes) + }) + + t.Run("bad config", func(t *testing.T) { + _, err := LoadFile(filepath.Join("testdata", "otlp_sanitize_resource_attributes.bad.yml"), false, false, log.NewNopLogger()) + require.ErrorContains(t, err, `duplicated promoted OTel resource attribute "k8s.job.name"`) + require.ErrorContains(t, err, `empty promoted OTel resource attribute`) + }) } func TestLoadConfig(t *testing.T) { diff --git a/config/testdata/otlp_sanitize_resource_attributes.bad.yml b/config/testdata/otlp_sanitize_resource_attributes.bad.yml new file mode 100644 index 000000000..37ec5d120 --- /dev/null +++ b/config/testdata/otlp_sanitize_resource_attributes.bad.yml @@ -0,0 +1,2 @@ +otlp: + promote_resource_attributes: ["k8s.cluster.name", " k8s.job.name ", "k8s.namespace.name", "k8s.job.name", ""] diff --git a/config/testdata/otlp_sanitize_resource_attributes.good.yml b/config/testdata/otlp_sanitize_resource_attributes.good.yml index ce91302fe..67247e774 100644 --- a/config/testdata/otlp_sanitize_resource_attributes.good.yml +++ b/config/testdata/otlp_sanitize_resource_attributes.good.yml @@ -1,2 +1,2 @@ otlp: - promote_resource_attributes: ["k8s.cluster.name", "k8s.job.name", "k8s.namespace.name", " k8s.job.name "] + promote_resource_attributes: ["k8s.cluster.name", " k8s.job.name ", "k8s.namespace.name"]