From e035ad166cd159835837515334d79a15ecbf1615 Mon Sep 17 00:00:00 2001 From: Ryan Fitzpatrick Date: Mon, 14 Jun 2021 02:20:14 -0400 Subject: [PATCH] Replace Viper with Koanf to add map case sensitivity (#3337) --- CHANGELOG.md | 4 + config/configcheck/configcheck.go | 2 +- config/configloader/config.go | 8 +- config/configloader/config_test.go | 2 +- config/configparser/parser.go | 172 +++++++++++------- config/internal/configsource/manager.go | 10 + .../config_test.go | 4 +- go.mod | 3 + go.sum | 34 +++- receiver/jaegerreceiver/config.go | 32 +--- receiver/jaegerreceiver/config_test.go | 2 +- receiver/otlpreceiver/config.go | 24 +-- receiver/otlpreceiver/config_test.go | 2 +- service/parserprovider/setflag.go | 59 ++---- 14 files changed, 202 insertions(+), 156 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3633931471..b898f82611f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 🛑 Breaking changes 🛑 + +- Provide case sensitivity in config yaml mappings by using Koanf instead of Viper (#3337) + ## v0.28.0 Beta ## 🛑 Breaking changes 🛑 diff --git a/config/configcheck/configcheck.go b/config/configcheck/configcheck.go index 0b8c16b2167..842aeed4e0b 100644 --- a/config/configcheck/configcheck.go +++ b/config/configcheck/configcheck.go @@ -96,7 +96,7 @@ func validateConfigDataType(t reflect.Type) error { } default: // The config object can carry other types but they are not used when - // reading the configuration via viper so ignore them. Basically ignore: + // reading the configuration via koanf so ignore them. Basically ignore: // reflect.Uintptr, reflect.Chan, reflect.Func, reflect.Interface, and // reflect.UnsafePointer. } diff --git a/config/configloader/config.go b/config/configloader/config.go index 7e172096c3c..c8dc9d5c27e 100644 --- a/config/configloader/config.go +++ b/config/configloader/config.go @@ -438,7 +438,7 @@ func parseIDNames(pipelineID config.ComponentID, componentType string, names []s return ret, nil } -// expandEnvConfig creates a new viper config with expanded values for all the values (simple, list or map value). +// expandEnvConfig updates a configparser.Parser with expanded values for all the values (simple, list or map value). // It does not expand the keys. func expandEnvConfig(v *configparser.Parser) { for _, k := range v.AllKeys() { @@ -458,6 +458,12 @@ func expandStringValues(value interface{}) interface{} { nslice = append(nslice, expandStringValues(vint)) } return nslice + case map[string]interface{}: + nmap := make(map[interface{}]interface{}, len(v)) + for k, vint := range v { + nmap[k] = expandStringValues(vint) + } + return nmap case map[interface{}]interface{}: nmap := make(map[interface{}]interface{}, len(v)) for k, vint := range v { diff --git a/config/configloader/config_test.go b/config/configloader/config_test.go index d1850a66ba5..857ad571a6e 100644 --- a/config/configloader/config_test.go +++ b/config/configloader/config_test.go @@ -459,7 +459,7 @@ func loadConfigFile(t *testing.T, fileName string, factories component.Factories v, err := configparser.NewParserFromFile(fileName) require.NoError(t, err) - // Load the config from viper using the given factories. + // Load the config from the configparser.Parser using the given factories. return Load(v, factories) } diff --git a/config/configparser/parser.go b/config/configparser/parser.go index 92a082a0cb9..481a61ead55 100644 --- a/config/configparser/parser.go +++ b/config/configparser/parser.go @@ -17,31 +17,33 @@ package configparser import ( "fmt" "io" + "io/ioutil" "reflect" - "strings" + "github.com/knadh/koanf" + "github.com/knadh/koanf/parsers/yaml" + "github.com/knadh/koanf/providers/confmap" + "github.com/knadh/koanf/providers/file" + "github.com/knadh/koanf/providers/rawbytes" + "github.com/mitchellh/mapstructure" "github.com/spf13/cast" - "github.com/spf13/viper" ) const ( - // KeyDelimiter is used as the default key delimiter in the default viper instance. + // KeyDelimiter is used as the default key delimiter in the default koanf instance. KeyDelimiter = "::" ) // NewParser creates a new empty Parser instance. func NewParser() *Parser { - return &Parser{ - v: viper.NewWithOptions(viper.KeyDelimiter(KeyDelimiter)), - } + return &Parser{k: koanf.New(KeyDelimiter)} } // NewParserFromFile creates a new Parser by reading the given file. func NewParserFromFile(fileName string) (*Parser, error) { // Read yaml config from file. p := NewParser() - p.v.SetConfigFile(fileName) - if err := p.v.ReadInConfig(); err != nil { + if err := p.k.Load(file.Provider(fileName), yaml.Parser()); err != nil { return nil, fmt.Errorf("unable to read the file %v: %w", fileName, err) } return p, nil @@ -49,71 +51,90 @@ func NewParserFromFile(fileName string) (*Parser, error) { // NewParserFromBuffer creates a new Parser by reading the given yaml buffer. func NewParserFromBuffer(buf io.Reader) (*Parser, error) { + content, err := ioutil.ReadAll(buf) + if err != nil { + return nil, err + } + p := NewParser() - p.v.SetConfigType("yaml") - if err := p.v.ReadConfig(buf); err != nil { + if err := p.k.Load(rawbytes.Provider(content), yaml.Parser()); err != nil { return nil, err } + return p, nil } // NewParserFromStringMap creates a parser from a map[string]interface{}. func NewParserFromStringMap(data map[string]interface{}) *Parser { p := NewParser() - // Cannot return error because the viper instance is empty. - _ = p.v.MergeConfigMap(data) + // Cannot return error because the koanf instance is empty. + _ = p.k.Load(confmap.Provider(data, KeyDelimiter), nil) return p } // Parser loads configuration. type Parser struct { - v *viper.Viper + k *koanf.Koanf } // AllKeys returns all keys holding a value, regardless of where they are set. // Nested keys are returned with a KeyDelimiter separator. func (l *Parser) AllKeys() []string { - return l.v.AllKeys() + return l.k.Keys() } // Unmarshal unmarshals the config into a struct. // Tags on the fields of the structure must be properly set. func (l *Parser) Unmarshal(rawVal interface{}) error { - return l.v.Unmarshal(rawVal) + decoder, err := mapstructure.NewDecoder(decoderConfig(rawVal)) + if err != nil { + return err + } + return decoder.Decode(l.ToStringMap()) } // UnmarshalExact unmarshals the config into a struct, erroring if a field is nonexistent. func (l *Parser) UnmarshalExact(intoCfg interface{}) error { - return l.v.UnmarshalExact(intoCfg) + dc := decoderConfig(intoCfg) + dc.ErrorUnused = true + decoder, err := mapstructure.NewDecoder(dc) + if err != nil { + return err + } + return decoder.Decode(l.ToStringMap()) } // Get can retrieve any value given the key to use. func (l *Parser) Get(key string) interface{} { - return l.v.Get(key) + return l.k.Get(key) } // Set sets the value for the key. func (l *Parser) Set(key string, value interface{}) { - l.v.Set(key, value) + // koanf doesn't offer a direct setting mechanism so merging is required. + merged := koanf.New(KeyDelimiter) + merged.Load(confmap.Provider(map[string]interface{}{key: value}, KeyDelimiter), nil) + l.k.Merge(merged) } // IsSet checks to see if the key has been set in any of the data locations. // IsSet is case-insensitive for a key. func (l *Parser) IsSet(key string) bool { - return l.v.IsSet(key) + return l.k.Exists(key) } // MergeStringMap merges the configuration from the given map with the existing config. // Note that the given map may be modified. func (l *Parser) MergeStringMap(cfg map[string]interface{}) error { - return l.v.MergeConfigMap(cfg) + toMerge := koanf.New(KeyDelimiter) + toMerge.Load(confmap.Provider(cfg, KeyDelimiter), nil) + return l.k.Merge(toMerge) } -// Sub returns new Parser instance representing a sub tree of this instance. +// Sub returns new Parser instance representing a sub-config of this instance. +// It returns an error is the sub-config is not a map (use Get()) and an empty Parser if +// none exists. func (l *Parser) Sub(key string) (*Parser, error) { - // Copied from the Viper but changed to use the same delimiter - // and return error if the sub is not a map. - // See https://github.com/spf13/viper/issues/871 data := l.Get(key) if data == nil { return NewParser(), nil @@ -122,60 +143,71 @@ func (l *Parser) Sub(key string) (*Parser, error) { if reflect.TypeOf(data).Kind() == reflect.Map { subParser := NewParser() // Cannot return error because the subv is empty. - _ = subParser.v.MergeConfigMap(cast.ToStringMap(data)) + _ = subParser.MergeStringMap(cast.ToStringMap(data)) return subParser, nil } return nil, fmt.Errorf("unexpected sub-config value kind for key:%s value:%v kind:%v)", key, data, reflect.TypeOf(data).Kind()) } -// deepSearch scans deep maps, following the key indexes listed in the -// sequence "path". -// The last value is expected to be another map, and is returned. -// -// In case intermediate keys do not exist, or map to a non-map value, -// a new map is created and inserted, and the search continues from there: -// the initial map "m" may be modified! -// This function comes from Viper code https://github.com/spf13/viper/blob/5253694/util.go#L201-L230 -// It is used here because of https://github.com/spf13/viper/issues/819 -func deepSearch(m map[string]interface{}, path []string) map[string]interface{} { - for _, k := range path { - m2, ok := m[k] - if !ok { - // Intermediate key does not exist: - // create it and continue from there. - m3 := make(map[string]interface{}) - m[k] = m3 - m = m3 - continue - } - m3, ok := m2.(map[string]interface{}) - if !ok { - // Intermediate key is a value: - // replace with a new map. - m3 = make(map[string]interface{}) - m[k] = m3 - } - // continue search from here - m = m3 +// ToStringMap creates a map[string]interface{} from a Parser. +func (l *Parser) ToStringMap() map[string]interface{} { + return l.k.Raw() +} + +// decoderConfig returns a default mapstructure.DecoderConfig capable of parsing time.Duration +// and weakly converting config field values to primitive types. It also ensures that maps +// whose values are nil pointer structs resolved to the zero value of the target struct (see +// expandNilStructPointers). A decoder created from this mapstructure.DecoderConfig will decode +// its contents to the result argument. +func decoderConfig(result interface{}) *mapstructure.DecoderConfig { + return &mapstructure.DecoderConfig{ + Result: result, + Metadata: nil, + TagName: "mapstructure", + WeaklyTypedInput: true, + DecodeHook: mapstructure.ComposeDecodeHookFunc( + expandNilStructPointers(), + mapstructure.StringToTimeDurationHookFunc(), + mapstructure.StringToSliceHookFunc(","), + ), } - return m } -// ToStringMap creates a map[string]interface{} from a Parser. -func (l *Parser) ToStringMap() map[string]interface{} { - // This is equivalent to l.v.AllSettings() but it maps nil values. - // We can't use AllSettings here because of https://github.com/spf13/viper/issues/819 - - m := map[string]interface{}{} - // Start from the list of keys, and construct the map one value at a time. - for _, k := range l.v.AllKeys() { - value := l.v.Get(k) - path := strings.Split(k, KeyDelimiter) - lastKey := strings.ToLower(path[len(path)-1]) - deepestMap := deepSearch(m, path[0:len(path)-1]) - // Set innermost value. - deepestMap[lastKey] = value +// In cases where a config has a mapping of something to a struct pointers +// we want nil values to resolve to a pointer to the zero value of the +// underlying struct just as we want nil values of a mapping of something +// to a struct to resolve to the zero value of that struct. +// +// e.g. given a config type: +// type Config struct { Thing *SomeStruct `mapstructure:"thing"` } +// +// and yaml of: +// config: +// thing: +// +// we want an unmarshalled Config to be equivalent to +// Config{Thing: &SomeStruct{}} instead of Config{Thing: nil} +func expandNilStructPointers() mapstructure.DecodeHookFunc { + return func(from reflect.Value, to reflect.Value) (interface{}, error) { + // ensure we are dealing with map to map comparison + if from.Kind() == reflect.Map && to.Kind() == reflect.Map { + toElem := to.Type().Elem() + // ensure that map values are pointers to a struct + // (that may be nil and require manual setting w/ zero value) + if toElem.Kind() == reflect.Ptr && toElem.Elem().Kind() == reflect.Struct { + fromRange := from.MapRange() + for fromRange.Next() { + fromKey := fromRange.Key() + fromValue := fromRange.Value() + // ensure that we've run into a nil pointer instance + if fromValue.IsNil() { + newFromValue := reflect.New(toElem.Elem()) + from.SetMapIndex(fromKey, newFromValue) + } + } + } + } + return from.Interface(), nil } - return m } diff --git a/config/internal/configsource/manager.go b/config/internal/configsource/manager.go index 81ab85cfd05..ddcf8bf9909 100644 --- a/config/internal/configsource/manager.go +++ b/config/internal/configsource/manager.go @@ -309,6 +309,16 @@ func (m *Manager) expandStringValues(ctx context.Context, value interface{}) (in nslice = append(nslice, value) } return nslice, nil + case map[string]interface{}: + nmap := make(map[interface{}]interface{}, len(v)) + for k, vint := range v { + value, err := m.expandStringValues(ctx, vint) + if err != nil { + return nil, err + } + nmap[k] = value + } + return nmap, nil case map[interface{}]interface{}: nmap := make(map[interface{}]interface{}, len(v)) for k, vint := range v { diff --git a/exporter/prometheusremotewriteexporter/config_test.go b/exporter/prometheusremotewriteexporter/config_test.go index 253d51eb1ec..b62eeb95d81 100644 --- a/exporter/prometheusremotewriteexporter/config_test.go +++ b/exporter/prometheusremotewriteexporter/config_test.go @@ -76,8 +76,8 @@ func Test_loadConfig(t *testing.T) { WriteBufferSize: 512 * 1024, Timeout: 5 * time.Second, Headers: map[string]string{ - "prometheus-remote-write-version": "0.1.0", - "x-scope-orgid": "234"}, + "Prometheus-Remote-Write-Version": "0.1.0", + "X-Scope-OrgID": "234"}, }, ResourceToTelemetrySettings: exporterhelper.ResourceToTelemetrySettings{Enabled: true}, }) diff --git a/go.mod b/go.mod index c9bc12360a4..142049eb341 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,10 @@ require ( github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/jaegertracing/jaeger v1.23.0 + github.com/knadh/koanf v1.0.0 github.com/leoluk/perflib_exporter v0.1.0 + github.com/magiconair/properties v1.8.1 + github.com/mitchellh/mapstructure v1.4.1 github.com/openzipkin/zipkin-go v0.2.5 github.com/pquerna/cachecontrol v0.1.0 // indirect github.com/prometheus/client_golang v1.10.0 diff --git a/go.sum b/go.sum index 5a89a73b739..965f359e5c1 100644 --- a/go.sum +++ b/go.sum @@ -241,6 +241,7 @@ github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= @@ -271,6 +272,7 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= @@ -372,6 +374,7 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-zookeeper/zk v1.0.2 h1:4mx0EYENAdX/B/rbunjlt5+4RTA/a9SMHBRuSKdGxPM= github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= @@ -534,8 +537,11 @@ github.com/hashicorp/consul/sdk v0.7.0 h1:H6R9d008jDcHPQPAqPNuydAshJ4v5/8URdFnUv github.com/hashicorp/consul/sdk v0.7.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.16.1 h1:IVQwpTGNRRIHafnTs2dQLIk4ENtneRIEEJWOVDqz99o= @@ -547,8 +553,11 @@ github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-plugin v1.4.2/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= +github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= @@ -559,6 +568,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -576,7 +586,10 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.5 h1:EBWvyu9tcRszt3Bxp3KNssBMP1KuHWyO51lz9+786iM= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= +github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20190923154419-df201c70410d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hetznercloud/hcloud-go v1.24.0 h1:/CeHDzhH3Fhm83pjxvE3xNNLbvACl0Lu1/auJ83gG5U= github.com/hetznercloud/hcloud-go v1.24.0/go.mod h1:3YmyK8yaZZ48syie6xpm3dt26rtB6s65AisBHylXYFA= @@ -617,6 +630,7 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -650,6 +664,8 @@ github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8 github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/knadh/koanf v1.0.0 h1:tGQ1L53Tp4uPx6agVGBN1U7A4f83ZpH3SwZNG+BkfqI= +github.com/knadh/koanf v1.0.0/go.mod h1:vrMMuhIH0k7EoxiMbVfFlRvJYmxcT2Eha3DH8Tx5+X4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= @@ -713,6 +729,9 @@ github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -729,6 +748,9 @@ github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mjibson/esc v0.2.0/go.mod h1:9Hw9gxxfHulMF5OJKCyhYD7PzlSdhzXyaGEBRPH1OPs= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= @@ -797,8 +819,9 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.5 h1:UwtQQx2pyPIgWYHRg+epgdx1/HnBQTgN3/oIYEJTQzU= github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -881,6 +904,7 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= +github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= github.com/rivo/tview v0.0.0-20200219210816-cd38d7432498/go.mod h1:6lkG1x+13OShEf0EaOCaTQYyB7d5nSbb181KtjlS+84= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -894,6 +918,7 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -1202,6 +1227,7 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1279,6 +1305,7 @@ golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1410,6 +1437,7 @@ google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1453,12 +1481,14 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210312152112-fc591d9ea70f h1:YRBxgxUW6GFi+AKsn8WGA9k1SZohK+gGuEqdeT5aoNQ= google.golang.org/genproto v0.0.0-20210312152112-fc591d9ea70f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -1493,6 +1523,7 @@ google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/l google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1511,6 +1542,7 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.52.0 h1:j+Lt/M1oPPejkniCg1TkWE2J3Eh1oZTsHSXzMTzUXn4= gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/receiver/jaegerreceiver/config.go b/receiver/jaegerreceiver/config.go index f08387dd262..7ed8432eeaa 100644 --- a/receiver/jaegerreceiver/config.go +++ b/receiver/jaegerreceiver/config.go @@ -17,8 +17,6 @@ package jaegerreceiver import ( "fmt" - "github.com/spf13/cast" - "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/configgrpc" "go.opentelemetry.io/collector/config/confighttp" @@ -109,33 +107,23 @@ func (cfg *Config) Unmarshal(componentParser *configparser.Parser) error { return err } - protocols := cast.ToStringMap(componentParser.Get(protocolsFieldName)) - knownProtocols := 0 - if _, ok := protocols[protoGRPC]; !ok { + protocols, err := componentParser.Sub(protocolsFieldName) + if err != nil { + return err + } + + if !protocols.IsSet(protoGRPC) { cfg.GRPC = nil - } else { - knownProtocols++ } - if _, ok := protocols[protoThriftHTTP]; !ok { + if !protocols.IsSet(protoThriftHTTP) { cfg.ThriftHTTP = nil - } else { - knownProtocols++ } - if _, ok := protocols[protoThriftBinary]; !ok { + if !protocols.IsSet(protoThriftBinary) { cfg.ThriftBinary = nil - } else { - knownProtocols++ } - if _, ok := protocols[protoThriftCompact]; !ok { + if !protocols.IsSet(protoThriftCompact) { cfg.ThriftCompact = nil - } else { - knownProtocols++ - } - // UnmarshalExact will ignore empty entries like a protocol with no values, so if a typo happened - // in the protocol that is intended to be enabled will not be enabled. So check if the protocols - // include only known protocols. - if len(protocols) != knownProtocols { - return fmt.Errorf("unknown protocols in the Jaeger receiver") } + return nil } diff --git a/receiver/jaegerreceiver/config_test.go b/receiver/jaegerreceiver/config_test.go index aac167eea1a..9dcf443f025 100644 --- a/receiver/jaegerreceiver/config_test.go +++ b/receiver/jaegerreceiver/config_test.go @@ -160,7 +160,7 @@ func TestFailedLoadConfig(t *testing.T) { factory := NewFactory() factories.Receivers[typeStr] = factory _, err = configtest.LoadConfigAndValidate(path.Join(".", "testdata", "bad_typo_default_proto_config.yaml"), factories) - assert.EqualError(t, err, "error reading receivers configuration for jaeger: unknown protocols in the Jaeger receiver") + assert.EqualError(t, err, "error reading receivers configuration for jaeger: 1 error(s) decoding:\n\n* 'protocols' has invalid keys: thrift_htttp") _, err = configtest.LoadConfigAndValidate(path.Join(".", "testdata", "bad_proto_config.yaml"), factories) assert.EqualError(t, err, "error reading receivers configuration for jaeger: 1 error(s) decoding:\n\n* 'protocols' has invalid keys: thrift_htttp") diff --git a/receiver/otlpreceiver/config.go b/receiver/otlpreceiver/config.go index e22a0169327..c431baf7f7b 100644 --- a/receiver/otlpreceiver/config.go +++ b/receiver/otlpreceiver/config.go @@ -17,8 +17,6 @@ package otlpreceiver import ( "fmt" - "github.com/spf13/cast" - "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/configgrpc" "go.opentelemetry.io/collector/config/confighttp" @@ -68,27 +66,19 @@ func (cfg *Config) Unmarshal(componentParser *configparser.Parser) error { return err } - // next manually search for protocols in viper, if a protocol is not present it means it is disable. - protocols := cast.ToStringMap(componentParser.Get(protocolsFieldName)) + // next manually search for protocols in the configparser.Parser, if a protocol is not present it means it is disable. + protocols, err := componentParser.Sub(protocolsFieldName) + if err != nil { + return err + } - // UnmarshalExact will ignore empty entries like a protocol with no values, so if a typo happened - // in the protocol that is intended to be enabled will not be enabled. So check if the protocols - // include only known protocols. - knownProtocols := 0 - if _, ok := protocols[protoGRPC]; !ok { + if !protocols.IsSet(protoGRPC) { cfg.GRPC = nil - } else { - knownProtocols++ } - if _, ok := protocols[protoHTTP]; !ok { + if !protocols.IsSet(protoHTTP) { cfg.HTTP = nil - } else { - knownProtocols++ } - if len(protocols) != knownProtocols { - return fmt.Errorf("unknown protocols in the OTLP receiver") - } return nil } diff --git a/receiver/otlpreceiver/config_test.go b/receiver/otlpreceiver/config_test.go index 425cc93dff6..1e92b1c38ea 100644 --- a/receiver/otlpreceiver/config_test.go +++ b/receiver/otlpreceiver/config_test.go @@ -199,7 +199,7 @@ func TestFailedLoadConfig(t *testing.T) { factory := NewFactory() factories.Receivers[typeStr] = factory _, err = configtest.LoadConfigAndValidate(path.Join(".", "testdata", "typo_default_proto_config.yaml"), factories) - assert.EqualError(t, err, `error reading receivers configuration for otlp: unknown protocols in the OTLP receiver`) + assert.EqualError(t, err, "error reading receivers configuration for otlp: 1 error(s) decoding:\n\n* 'protocols' has invalid keys: htttp") _, err = configtest.LoadConfigAndValidate(path.Join(".", "testdata", "bad_proto_config.yaml"), factories) assert.EqualError(t, err, "error reading receivers configuration for otlp: 1 error(s) decoding:\n\n* 'protocols' has invalid keys: thrift") diff --git a/service/parserprovider/setflag.go b/service/parserprovider/setflag.go index f7056658ff8..5a64832fcbf 100644 --- a/service/parserprovider/setflag.go +++ b/service/parserprovider/setflag.go @@ -19,13 +19,13 @@ import ( "fmt" "strings" - "github.com/spf13/viper" + "github.com/knadh/koanf" + "github.com/knadh/koanf/providers/confmap" + "github.com/magiconair/properties" "go.opentelemetry.io/collector/config/configparser" ) -const setFlagFileType = "properties" - type setFlagProvider struct { base ParserProvider } @@ -54,51 +54,32 @@ func (sfl *setFlagProvider) Get() (*configparser.Parser, error) { return nil, err } } - viperFlags := viper.NewWithOptions(viper.KeyDelimiter(configparser.KeyDelimiter)) - viperFlags.SetConfigType(setFlagFileType) - if err := viperFlags.ReadConfig(b); err != nil { - return nil, fmt.Errorf("failed to read set flag config: %v", err) - } - cp, err := sfl.base.Get() - if err != nil { + var props *properties.Properties + var err error + if props, err = properties.Load(b.Bytes(), properties.UTF8); err != nil { return nil, err } - // Viper implementation of v.MergeConfig(io.Reader) or v.MergeConfigMap(map[string]interface) - // does not work properly. This is b/c if it attempts to merge into a nil object it will fail here - // https://github.com/spf13/viper/blob/3826be313591f83193f048520482a7b3cf17d506/viper.go#L1709 - - // The workaround is to call v.Set(string, interface) on all root properties from the config file - // this will correctly preserve the original config and set them up for viper to overlay them with - // the --set params. It should also be noted that setting the root keys is important. This is - // b/c the viper .AllKeys() method does not return empty objects. - // For instance with the following yaml structure: - // a: - // b: - // c: {} - // - // viper.AllKeys() would only return a.b, but not a.c. However otel expects {} to behave - // the same as nil object in its config file. Therefore we extract and set the root keys only - // to catch both a.b and a.c. - - rootKeys := map[string]struct{}{} - for _, k := range viperFlags.AllKeys() { - keys := strings.Split(k, configparser.KeyDelimiter) - if len(keys) > 0 { - rootKeys[keys[0]] = struct{}{} - } + // Create a map manually instead of using props.Map() to allow env var expansion + // as used by original Viper-based configparser.Parser. + parsed := map[string]interface{}{} + for _, key := range props.Keys() { + value, _ := props.Get(key) + parsed[key] = value } - for k := range rootKeys { - cp.Set(k, cp.Get(k)) + propertyKoanf := koanf.New(".") + if err = propertyKoanf.Load(confmap.Provider(parsed, "."), nil); err != nil { + return nil, fmt.Errorf("failed to read set flag config: %v", err) } - // now that we've copied the config into the viper "overrides" copy the --set flags - // as well - for _, k := range viperFlags.AllKeys() { - cp.Set(k, viperFlags.Get(k)) + var cp *configparser.Parser + if cp, err = sfl.base.Get(); err != nil { + return nil, err } + cp.MergeStringMap(propertyKoanf.Raw()) + return cp, nil }