diff --git a/config/config_test.go b/config/config_test.go index 9b0d0480..969091b2 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -21,7 +21,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "go.yaml.in/yaml/v2" + "go.yaml.in/yaml/v3" ) func TestJSONMarshalSecret(t *testing.T) { @@ -158,11 +158,11 @@ func TestHeaderYamlMarshal(t *testing.T) { }, "simple": { input: ProxyHeader{"single": []Secret{"a"}}, - expected: []byte("single:\n- \n"), + expected: []byte("single:\n - \n"), }, "multi": { input: ProxyHeader{"multi": []Secret{"a", "b"}}, - expected: []byte("multi:\n- \n- \n"), + expected: []byte("multi:\n - \n - \n"), }, "empty": { input: ProxyHeader{"empty": nil}, @@ -173,8 +173,8 @@ func TestHeaderYamlMarshal(t *testing.T) { for name, tc := range testcases { t.Run(name, func(t *testing.T) { actual, err := yaml.Marshal(tc.input) - require.NoErrorf(t, err, "error unmarshaling %#v: %s", tc.input, err) - require.Truef(t, bytes.Equal(actual, tc.expected), "expecting: %q, actual: %q", tc.expected, actual) + require.NoErrorf(t, err, "error marshaling %#v: %s", tc.input, err) + require.Equal(t, tc.expected, actual) }) } } diff --git a/config/http_config.go b/config/http_config.go index d633479c..4bee10d4 100644 --- a/config/http_config.go +++ b/config/http_config.go @@ -22,6 +22,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "maps" "net" "net/http" @@ -35,7 +36,7 @@ import ( "github.com/golang-jwt/jwt/v5" "github.com/mwitkow/go-conntrack" - "go.yaml.in/yaml/v2" + "go.yaml.in/yaml/v3" "golang.org/x/net/http/httpproxy" "golang.org/x/net/http2" "golang.org/x/oauth2" @@ -308,8 +309,9 @@ func (o *OAuth2) SetDirectory(dir string) { // LoadHTTPConfig parses the YAML input s into a HTTPClientConfig. func LoadHTTPConfig(s string) (*HTTPClientConfig, error) { cfg := &HTTPClientConfig{} - err := yaml.UnmarshalStrict([]byte(s), cfg) - if err != nil { + decoder := yaml.NewDecoder(strings.NewReader(s)) + decoder.KnownFields(true) + if err := decoder.Decode(cfg); err != nil && !errors.Is(err, io.EOF) { return nil, err } return cfg, nil diff --git a/config/http_config_test.go b/config/http_config_test.go index 4d61ae12..9eb75c9b 100644 --- a/config/http_config_test.go +++ b/config/http_config_test.go @@ -37,7 +37,7 @@ import ( "time" "github.com/stretchr/testify/require" - "go.yaml.in/yaml/v2" + "go.yaml.in/yaml/v3" ) const ( diff --git a/config/tls_config_test.go b/config/tls_config_test.go index cffe1320..4304220a 100644 --- a/config/tls_config_test.go +++ b/config/tls_config_test.go @@ -19,6 +19,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "os" "path/filepath" "reflect" @@ -26,7 +27,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "go.yaml.in/yaml/v2" + "go.yaml.in/yaml/v3" ) // LoadTLSConfig parses the given file into a tls.Config. @@ -38,7 +39,9 @@ func LoadTLSConfig(filename string) (*tls.Config, error) { cfg := TLSConfig{} switch filepath.Ext(filename) { case ".yml": - if err = yaml.UnmarshalStrict(content, &cfg); err != nil { + decoder := yaml.NewDecoder(bytes.NewReader(content)) + decoder.KnownFields(true) + if err := decoder.Decode(&cfg); err != nil && !errors.Is(err, io.EOF) { return nil, err } case ".json": @@ -101,11 +104,13 @@ var expectedTLSConfigs = []struct { func TestValidTLSConfig(t *testing.T) { for _, cfg := range expectedTLSConfigs { - got, err := LoadTLSConfig("testdata/" + cfg.filename) - require.NoErrorf(t, err, "Error parsing %s: %s", cfg.filename, err) - // non-nil functions are never equal. - got.GetClientCertificate = nil - require.Truef(t, reflect.DeepEqual(got, cfg.config), "%v: unexpected config result: \n\n%v\n expected\n\n%v", cfg.filename, got, cfg.config) + t.Run(cfg.filename, func(t *testing.T) { + got, err := LoadTLSConfig("testdata/" + cfg.filename) + require.NoErrorf(t, err, "Error parsing %s: %s", cfg.filename, err) + // non-nil functions are never equal. + got.GetClientCertificate = nil + require.Truef(t, reflect.DeepEqual(got, cfg.config), "%v: unexpected config result: \n\n%v\n expected\n\n%v", cfg.filename, got, cfg.config) + }) } } diff --git a/go.mod b/go.mod index e3a5d87f..75ee9fe3 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f github.com/prometheus/client_model v0.6.2 github.com/stretchr/testify v1.12.1 - go.yaml.in/yaml/v2 v2.4.4 + go.yaml.in/yaml/v3 v3.0.5 golang.org/x/net v0.58.0 golang.org/x/oauth2 v0.36.0 google.golang.org/protobuf v1.36.12 @@ -26,7 +26,6 @@ require ( github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/procfs v0.21.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect - go.yaml.in/yaml/v3 v3.0.5 // indirect golang.org/x/sys v0.47.0 // indirect golang.org/x/text v0.41.0 // indirect ) diff --git a/go.sum b/go.sum index 367d5efc..3999a189 100644 --- a/go.sum +++ b/go.sum @@ -43,8 +43,6 @@ github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8 github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= -go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= diff --git a/model/metric_test.go b/model/metric_test.go index 90f9f9bf..3e510894 100644 --- a/model/metric_test.go +++ b/model/metric_test.go @@ -24,13 +24,23 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" dto "github.com/prometheus/client_model/go" "github.com/stretchr/testify/require" - "go.yaml.in/yaml/v2" + "go.yaml.in/yaml/v3" "google.golang.org/protobuf/proto" ) +// obsoleteUnmarshaler matches yaml.v3's unexported compatibility interface +// for the callback-based UnmarshalYAML method used by yaml.v2. Keeping this +// method preserves compatibility with both yaml.v2 and yaml.v3. +// +// See https://github.com/yaml/go-yaml/blob/v3.0.5/yaml.go#L39-L41 +// And https://github.com/yaml/go-yaml/blob/v3.0.5/decode.go#L422-L429 +type obsoleteUnmarshaler interface { + UnmarshalYAML(unmarshal func(any) error) error +} + var _ interface { yaml.Marshaler - yaml.Unmarshaler + obsoleteUnmarshaler json.Marshaler json.Unmarshaler fmt.Stringer diff --git a/promslog/slog_test.go b/promslog/slog_test.go index dd5f6b24..e4dd0f07 100644 --- a/promslog/slog_test.go +++ b/promslog/slog_test.go @@ -24,7 +24,7 @@ import ( "time" "github.com/stretchr/testify/require" - "go.yaml.in/yaml/v2" + "go.yaml.in/yaml/v3" ) var (