From c7d3a065369b09b8aeeb53a6e83942d027bfa45d Mon Sep 17 00:00:00 2001 From: milinddethe15 Date: Thu, 27 Feb 2025 16:43:49 +0530 Subject: [PATCH] add trimmer for extra field in config Signed-off-by: milinddethe15 --- client/factory.go | 7 +++- clientutil/trimconfig.go | 28 +++++++++++++ clientutil/trimconfig_test.go | 77 +++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 clientutil/trimconfig.go create mode 100644 clientutil/trimconfig_test.go diff --git a/client/factory.go b/client/factory.go index f0a2287e..d6862164 100644 --- a/client/factory.go +++ b/client/factory.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/thanos-io/objstore" + "github.com/thanos-io/objstore/clientutil" "github.com/thanos-io/objstore/providers/azure" "github.com/thanos-io/objstore/providers/bos" "github.com/thanos-io/objstore/providers/cos" @@ -37,8 +38,12 @@ type BucketConfig struct { // NOTE: confContentYaml can contain secrets. func NewBucket(logger log.Logger, confContentYaml []byte, component string, wrapRoundtripper func(http.RoundTripper) http.RoundTripper) (objstore.Bucket, error) { level.Info(logger).Log("msg", "loading bucket configuration") + trimmedYaml, err := clientutil.TrimExtraFields(confContentYaml) + if err != nil { + return nil, errors.Wrap(err, "trimming extra fields failed") + } bucketConf := &BucketConfig{} - if err := yaml.UnmarshalStrict(confContentYaml, bucketConf); err != nil { + if err := yaml.UnmarshalStrict(trimmedYaml, bucketConf); err != nil { return nil, errors.Wrap(err, "parsing config YAML file") } diff --git a/clientutil/trimconfig.go b/clientutil/trimconfig.go new file mode 100644 index 00000000..f627f442 --- /dev/null +++ b/clientutil/trimconfig.go @@ -0,0 +1,28 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package clientutil + +import ( + "github.com/pkg/errors" + "gopkg.in/yaml.v2" +) + +func TrimExtraFields(confContentYaml []byte) ([]byte, error) { + var raw map[string]interface{} + if err := yaml.Unmarshal(confContentYaml, &raw); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal YAML") + } + allowed := map[string]bool{ + "type": true, + "config": true, + "prefix": true, + } + filtered := make(map[string]interface{}) + for key, value := range raw { + if allowed[key] { + filtered[key] = value + } + } + return yaml.Marshal(filtered) +} diff --git a/clientutil/trimconfig_test.go b/clientutil/trimconfig_test.go new file mode 100644 index 00000000..27aa1151 --- /dev/null +++ b/clientutil/trimconfig_test.go @@ -0,0 +1,77 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package clientutil + +import ( + "reflect" + "testing" + + "gopkg.in/yaml.v2" +) + +func TestTrimExtraFields(t *testing.T) { + tests := []struct { + name string + input string + expected map[string]interface{} + expectErr bool + }{ + { + name: "YAML with extra field", + input: ` +type: "s3" +config: + key1: "value1" + key2: "value2" +prefix: "/path/to/bucket" +hedging_config: + enabled: false + up_to: 3 + quantile: 0.9 +`, + expected: map[string]interface{}{ + "type": "s3", + "config": map[interface{}]interface{}{"key1": "value1", "key2": "value2"}, + "prefix": "/path/to/bucket", + }, + expectErr: false, + }, + { + name: "YAML without extra field", + input: ` +type: "s3" +config: + key: "value" +prefix: "/path/to/bucket" +`, + expected: map[string]interface{}{ + "type": "s3", + "config": map[interface{}]interface{}{"key": "value"}, + "prefix": "/path/to/bucket", + }, + expectErr: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + output, err := TrimExtraFields([]byte(tc.input)) + if (err != nil) != tc.expectErr { + t.Fatalf("TrimExtraFields() error = %v, expectErr %v", err, tc.expectErr) + } + if err != nil { + return + } + + var got map[string]interface{} + if err := yaml.Unmarshal(output, &got); err != nil { + t.Fatalf("failed to unmarshal output YAML: %v", err) + } + + if !reflect.DeepEqual(got, tc.expected) { + t.Errorf("TrimExtraFields() got = %v, expected %v", got, tc.expected) + } + }) + } +}