Files
Zakhar BessarabandGitHub 66e955134d deps: unpin AWS dependencies and add workaround for S3 compatibility (#9844)
Updates:
- unpin AWS dependencies and run `make vendor-update`
- add config options to enable checksums only if required by storage in
order to preserve backwards compatibility

Related issues:
- https://github.com/VictoriaMetrics/VictoriaMetrics/issues/9748
- https://github.com/VictoriaMetrics/VictoriaMetrics/issues/8622

Tested with: AWS S3, self-hosted MinIO, Linode object storage as it was
failing previously with multi-part uploads (reported here -
https://github.com/VictoriaMetrics/VictoriaMetrics/pull/8630#issuecomment-2772185033).
An updated library allows (PR with the
fix - https://github.com/aws/aws-sdk-go-v2/pull/3151) overriding
multi-part upload configurations so that compatibility can be preserved.

Signed-off-by: Zakhar Bessarab <[email protected]>
2025-10-10 18:35:37 +04:00

62 lines
1.9 KiB
Go

// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package internal // import "go.opentelemetry.io/collector/confmap/internal"
import (
"reflect"
"github.com/go-viper/mapstructure/v2"
encoder "go.opentelemetry.io/collector/confmap/internal/mapstructure"
)
// EncoderConfig returns a default encoder.EncoderConfig that includes
// an EncodeHook that handles both TextMarshaler and Marshaler
// interfaces.
func EncoderConfig(rawVal any, _ MarshalOptions) *encoder.EncoderConfig {
return &encoder.EncoderConfig{
EncodeHook: mapstructure.ComposeDecodeHookFunc(
encoder.YamlMarshalerHookFunc(),
encoder.TextMarshalerHookFunc(),
marshalerHookFunc(rawVal),
),
}
}
// marshalerHookFunc returns a DecodeHookFuncValue that checks structs that aren't
// the original to see if they implement the Marshaler interface.
func marshalerHookFunc(orig any) mapstructure.DecodeHookFuncValue {
origType := reflect.TypeOf(orig)
return safeWrapDecodeHookFunc(func(from, _ reflect.Value) (any, error) {
if from.Kind() != reflect.Struct {
return from.Interface(), nil
}
// ignore original to avoid infinite loop.
if from.Type() == origType && reflect.DeepEqual(from.Interface(), orig) {
return from.Interface(), nil
}
marshaler, ok := from.Interface().(Marshaler)
if !ok {
return from.Interface(), nil
}
conf := NewFromStringMap(nil)
if err := marshaler.Marshal(conf); err != nil {
return nil, err
}
stringMap := conf.ToStringMap()
if stringMap == nil {
// If conf is still nil after marshaling, we want to encode it as an untyped nil
// instead of a map-typed nil. This ensures the value is a proper null value
// in the final marshaled output instead of an empty map. We hit this case
// when marshaling wrapper structs that have no direct representation
// in the marshaled output that aren't tagged with "squash" on the fields
// they're used on.
return nil, nil
}
return stringMap, nil
})
}