diff --git a/.circleci/config.yml b/.circleci/config.yml index 8e5fff950..8f035514d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,7 +25,6 @@ jobs: - go/load-cache: key: v1-go<< parameters.go_version >> - run: make test - - run: make -C sigv4 test - when: condition: << parameters.use_gomod_cache >> steps: @@ -74,7 +73,6 @@ jobs: - go/load-cache: key: v1-go<< parameters.go_version >> - run: make style - - run: make -C sigv4 style - run: make -C assets style - run: make check-go-mod-version - when: diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9b7d29d83..a8d849c7c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,7 +8,3 @@ updates: directory: "/assets" schedule: interval: monthly - - package-ecosystem: "gomod" - directory: "/sigv4" - schedule: - interval: monthly diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index e645ba30a..0c00c410a 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -26,7 +26,7 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install Go - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: 1.23.x - name: Install snmp_exporter/generator dependencies @@ -36,4 +36,4 @@ jobs: uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 with: args: --verbose - version: v1.62.0 + version: v1.63.4 diff --git a/Makefile.common b/Makefile.common index fc47bdbb2..d1576bb31 100644 --- a/Makefile.common +++ b/Makefile.common @@ -61,7 +61,7 @@ PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_ SKIP_GOLANGCI_LINT := GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v1.62.0 +GOLANGCI_LINT_VERSION ?= v1.63.4 # golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64. # windows isn't included here because of the path separator being different. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) diff --git a/README.md b/README.md index 43ff7e75f..954cc91b4 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ any stability guarantees for external usage. * **config**: Common configuration structures * **expfmt**: Decoding and encoding for the exposition format * **model**: Shared data structures -* **promlog**: A logging wrapper around [go-kit/log](https://github.com/go-kit/kit/tree/master/log) * **promslog**: A logging wrapper around [log/slog](https://pkg.go.dev/log/slog) * **route**: A routing wrapper around [httprouter](https://github.com/julienschmidt/httprouter) using `context.Context` * **server**: Common servers diff --git a/config/http_config.go b/config/http_config.go index 57ec252ad..63809083a 100644 --- a/config/http_config.go +++ b/config/http_config.go @@ -52,7 +52,8 @@ var ( http2Enabled: true, // 5 minutes is typically above the maximum sane scrape interval. So we can // use keepalive for all configurations. - idleConnTimeout: 5 * time.Minute, + idleConnTimeout: 5 * time.Minute, + newTLSConfigFunc: NewTLSConfigWithContext, } ) @@ -452,8 +453,12 @@ func (a *BasicAuth) UnmarshalYAML(unmarshal func(interface{}) error) error { // by net.Dialer. type DialContextFunc func(context.Context, string, string) (net.Conn, error) +// NewTLSConfigFunc returns tls.Config. +type NewTLSConfigFunc func(context.Context, *TLSConfig, ...TLSConfigOption) (*tls.Config, error) + type httpClientOptions struct { dialContextFunc DialContextFunc + newTLSConfigFunc NewTLSConfigFunc keepAlivesEnabled bool http2Enabled bool idleConnTimeout time.Duration @@ -473,13 +478,23 @@ func (f httpClientOptionFunc) applyToHTTPClientOptions(options *httpClientOption f(options) } -// WithDialContextFunc allows you to override func gets used for the actual dialing. The default is `net.Dialer.DialContext`. +// WithDialContextFunc allows you to override the func gets used for the dialing. +// The default is `net.Dialer.DialContext`. func WithDialContextFunc(fn DialContextFunc) HTTPClientOption { return httpClientOptionFunc(func(opts *httpClientOptions) { opts.dialContextFunc = fn }) } +// WithNewTLSConfigFunc allows you to override the func that creates the TLS config +// from the prometheus http config. +// The default is `NewTLSConfigWithContext`. +func WithNewTLSConfigFunc(newTLSConfigFunc NewTLSConfigFunc) HTTPClientOption { + return httpClientOptionFunc(func(opts *httpClientOptions) { + opts.newTLSConfigFunc = newTLSConfigFunc + }) +} + // WithKeepAlivesDisabled allows to disable HTTP keepalive. func WithKeepAlivesDisabled() HTTPClientOption { return httpClientOptionFunc(func(opts *httpClientOptions) { @@ -670,7 +685,7 @@ func NewRoundTripperFromConfigWithContext(ctx context.Context, cfg HTTPClientCon return rt, nil } - tlsConfig, err := NewTLSConfig(&cfg.TLSConfig, WithSecretManager(opts.secretManager)) + tlsConfig, err := opts.newTLSConfigFunc(ctx, &cfg.TLSConfig, WithSecretManager(opts.secretManager)) if err != nil { return nil, err } @@ -679,6 +694,7 @@ func NewRoundTripperFromConfigWithContext(ctx context.Context, cfg HTTPClientCon if err != nil { return nil, err } + if tlsSettings.immutable() { // No need for a RoundTripper that reloads the files automatically. return newRT(tlsConfig) diff --git a/expfmt/openmetrics_create.go b/expfmt/openmetrics_create.go index f1c495dd6..a21ed4ec1 100644 --- a/expfmt/openmetrics_create.go +++ b/expfmt/openmetrics_create.go @@ -38,7 +38,7 @@ type EncoderOption func(*encoderOption) // WithCreatedLines is an EncoderOption that configures the OpenMetrics encoder // to include _created lines (See -// https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#counter-1). +// https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#counter-1). // Created timestamps can improve the accuracy of series reset detection, but // come with a bandwidth cost. // @@ -102,7 +102,7 @@ func WithUnit() EncoderOption { // // - According to the OM specs, the `# UNIT` line is optional, but if populated, // the unit has to be present in the metric name as its suffix: -// (see https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#unit). +// (see https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#unit). // However, in order to accommodate any potential scenario where such a change in the // metric name is not desirable, the users are here given the choice of either explicitly // opt in, in case they wish for the unit to be included in the output AND in the metric name diff --git a/go.mod b/go.mod index 87b897618..4d62719bb 100644 --- a/go.mod +++ b/go.mod @@ -4,16 +4,15 @@ go 1.21 require ( github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/go-kit/log v0.2.1 github.com/google/go-cmp v0.6.0 github.com/julienschmidt/httprouter v1.3.0 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f github.com/prometheus/client_model v0.6.1 github.com/stretchr/testify v1.10.0 - golang.org/x/net v0.32.0 + golang.org/x/net v0.33.0 golang.org/x/oauth2 v0.24.0 - google.golang.org/protobuf v1.35.2 + google.golang.org/protobuf v1.36.1 gopkg.in/yaml.v2 v2.4.0 ) @@ -22,7 +21,6 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.20.4 // indirect diff --git a/go.sum b/go.sum index 2bb9e8254..b5955f01f 100644 --- a/go.sum +++ b/go.sum @@ -9,10 +9,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= @@ -47,16 +43,16 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= +google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/model/alert_test.go b/model/alert_test.go index 2a8d7bba1..fc3eaf108 100644 --- a/model/alert_test.go +++ b/model/alert_test.go @@ -22,6 +22,11 @@ import ( ) func TestAlertValidate(t *testing.T) { + oldScheme := NameValidationScheme + NameValidationScheme = LegacyValidation + defer func() { + NameValidationScheme = oldScheme + }() ts := time.Now() cases := []struct { diff --git a/model/metric.go b/model/metric.go index 0daca836a..5766107cf 100644 --- a/model/metric.go +++ b/model/metric.go @@ -28,13 +28,13 @@ import ( var ( // NameValidationScheme determines the method of name validation to be used by - // all calls to IsValidMetricName() and LabelName IsValid(). Setting UTF-8 mode - // in isolation from other components that don't support UTF-8 may result in - // bugs or other undefined behavior. This value is intended to be set by - // UTF-8-aware binaries as part of their startup. To avoid need for locking, - // this value should be set once, ideally in an init(), before multiple - // goroutines are started. - NameValidationScheme = LegacyValidation + // all calls to IsValidMetricName() and LabelName IsValid(). Setting UTF-8 + // mode in isolation from other components that don't support UTF-8 may result + // in bugs or other undefined behavior. This value can be set to + // LegacyValidation during startup if a binary is not UTF-8-aware binaries. To + // avoid need for locking, this value should be set once, ideally in an + // init(), before multiple goroutines are started. + NameValidationScheme = UTF8Validation // NameEscapingScheme defines the default way that names will be escaped when // presented to systems that do not support UTF-8 names. If the Content-Type diff --git a/promlog/flag/flag.go b/promlog/flag/flag.go deleted file mode 100644 index 16352a0fe..000000000 --- a/promlog/flag/flag.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2017 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Deprecated: This package has been deprecated in favor of migrating to -// `github.com/prometheus/common/promslog` which uses the Go standard library -// `log/slog` package. -package flag - -import ( - "strings" - - kingpin "github.com/alecthomas/kingpin/v2" - - "github.com/prometheus/common/promlog" //nolint:staticcheck -) - -// LevelFlagName is the canonical flag name to configure the allowed log level -// within Prometheus projects. -const LevelFlagName = "log.level" - -// LevelFlagHelp is the help description for the log.level flag. -var LevelFlagHelp = "Only log messages with the given severity or above. One of: [" + strings.Join(promlog.LevelFlagOptions, ", ") + "]" - -// FormatFlagName is the canonical flag name to configure the log format -// within Prometheus projects. -const FormatFlagName = "log.format" - -// FormatFlagHelp is the help description for the log.format flag. -var FormatFlagHelp = "Output format of log messages. One of: [" + strings.Join(promlog.FormatFlagOptions, ", ") + "]" - -// AddFlags adds the flags used by this package to the Kingpin application. -// To use the default Kingpin application, call AddFlags(kingpin.CommandLine) -func AddFlags(a *kingpin.Application, config *promlog.Config) { - config.Level = &promlog.AllowedLevel{} - a.Flag(LevelFlagName, LevelFlagHelp). - Default("info").HintOptions(promlog.LevelFlagOptions...). - SetValue(config.Level) - - config.Format = &promlog.AllowedFormat{} - a.Flag(FormatFlagName, FormatFlagHelp). - Default("logfmt").HintOptions(promlog.FormatFlagOptions...). - SetValue(config.Format) -} diff --git a/promlog/log.go b/promlog/log.go deleted file mode 100644 index 24a11622b..000000000 --- a/promlog/log.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2017 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package promlog defines standardised ways to initialize Go kit loggers -// across Prometheus components. -// It should typically only ever be imported by main packages. -// -// Deprecated: This package has been deprecated in favor of migrating to -// `github.com/prometheus/common/promslog` which uses the Go standard library -// `log/slog` package. -package promlog - -import ( - "fmt" - "os" - "sync" - "time" - - "github.com/go-kit/log" - "github.com/go-kit/log/level" -) - -var ( - // This timestamp format differs from RFC3339Nano by using .000 instead - // of .999999999 which changes the timestamp from 9 variable to 3 fixed - // decimals (.130 instead of .130987456). - timestampFormat = log.TimestampFormat( - func() time.Time { return time.Now().UTC() }, - "2006-01-02T15:04:05.000Z07:00", - ) - - LevelFlagOptions = []string{"debug", "info", "warn", "error"} - FormatFlagOptions = []string{"logfmt", "json"} -) - -// AllowedLevel is a settable identifier for the minimum level a log entry -// must be have. -type AllowedLevel struct { - s string - o level.Option -} - -func (l *AllowedLevel) UnmarshalYAML(unmarshal func(interface{}) error) error { - var s string - type plain string - if err := unmarshal((*plain)(&s)); err != nil { - return err - } - if s == "" { - return nil - } - lo := &AllowedLevel{} - if err := lo.Set(s); err != nil { - return err - } - *l = *lo - return nil -} - -func (l *AllowedLevel) String() string { - return l.s -} - -// Set updates the value of the allowed level. -func (l *AllowedLevel) Set(s string) error { - switch s { - case "debug": - l.o = level.AllowDebug() - case "info": - l.o = level.AllowInfo() - case "warn": - l.o = level.AllowWarn() - case "error": - l.o = level.AllowError() - default: - return fmt.Errorf("unrecognized log level %q", s) - } - l.s = s - return nil -} - -// AllowedFormat is a settable identifier for the output format that the logger can have. -type AllowedFormat struct { - s string -} - -func (f *AllowedFormat) String() string { - return f.s -} - -// Set updates the value of the allowed format. -func (f *AllowedFormat) Set(s string) error { - switch s { - case "logfmt", "json": - f.s = s - default: - return fmt.Errorf("unrecognized log format %q", s) - } - return nil -} - -// Config is a struct containing configurable settings for the logger -type Config struct { - Level *AllowedLevel - Format *AllowedFormat -} - -// New returns a new leveled oklog logger. Each logged line will be annotated -// with a timestamp. The output always goes to stderr. -func New(config *Config) log.Logger { - if config.Format != nil && config.Format.s == "json" { - return NewWithLogger(log.NewJSONLogger(log.NewSyncWriter(os.Stderr)), config) - } - - return NewWithLogger(log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)), config) -} - -// NewWithLogger returns a new leveled oklog logger with a custom log.Logger. -// Each logged line will be annotated with a timestamp. -func NewWithLogger(l log.Logger, config *Config) log.Logger { - if config.Level != nil { - l = log.With(l, "ts", timestampFormat, "caller", log.Caller(5)) - l = level.NewFilter(l, config.Level.o) - } else { - l = log.With(l, "ts", timestampFormat, "caller", log.DefaultCaller) - } - return l -} - -// NewDynamic returns a new leveled logger. Each logged line will be annotated -// with a timestamp. The output always goes to stderr. Some properties can be -// changed, like the level. -func NewDynamic(config *Config) *logger { - if config.Format != nil && config.Format.s == "json" { - return NewDynamicWithLogger(log.NewJSONLogger(log.NewSyncWriter(os.Stderr)), config) - } - - return NewDynamicWithLogger(log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)), config) -} - -// NewDynamicWithLogger returns a new leveled logger with a custom io.Writer. -// Each logged line will be annotated with a timestamp. -// Some properties can be changed, like the level. -func NewDynamicWithLogger(l log.Logger, config *Config) *logger { - lo := &logger{ - base: l, - leveled: l, - } - - if config.Level != nil { - lo.SetLevel(config.Level) - } - - return lo -} - -type logger struct { - base log.Logger - leveled log.Logger - currentLevel *AllowedLevel - mtx sync.Mutex -} - -// Log implements logger.Log. -func (l *logger) Log(keyvals ...interface{}) error { - l.mtx.Lock() - defer l.mtx.Unlock() - return l.leveled.Log(keyvals...) -} - -// SetLevel changes the log level. -func (l *logger) SetLevel(lvl *AllowedLevel) { - l.mtx.Lock() - defer l.mtx.Unlock() - if lvl == nil { - l.leveled = log.With(l.base, "ts", timestampFormat, "caller", log.DefaultCaller) - l.currentLevel = nil - return - } - - if l.currentLevel != nil && l.currentLevel.s != lvl.s { - _ = l.base.Log("msg", "Log level changed", "prev", l.currentLevel, "current", lvl) - } - l.currentLevel = lvl - l.leveled = level.NewFilter(log.With(l.base, "ts", timestampFormat, "caller", log.Caller(5)), lvl.o) -} diff --git a/promlog/log_test.go b/promlog/log_test.go deleted file mode 100644 index 395e05164..000000000 --- a/promlog/log_test.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2020 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package promlog - -import ( - "fmt" - "testing" - - "github.com/go-kit/log/level" - "github.com/stretchr/testify/require" - "gopkg.in/yaml.v2" -) - -// Make sure creating and using a logger with an empty configuration doesn't -// result in a panic. -func TestDefaultConfig(t *testing.T) { - logger := New(&Config{}) - - err := logger.Log("hello", "world") - require.NoError(t, err) -} - -func TestUnmarshallLevel(t *testing.T) { - l := &AllowedLevel{} - err := yaml.Unmarshal([]byte(`debug`), l) - if err != nil { - t.Error(err) - } - if l.s != "debug" { - t.Errorf("expected %s, got %s", "debug", l.s) - } -} - -func TestUnmarshallEmptyLevel(t *testing.T) { - l := &AllowedLevel{} - err := yaml.Unmarshal([]byte(``), l) - if err != nil { - t.Error(err) - } - if l.s != "" { - t.Errorf("expected empty level, got %s", l.s) - } -} - -func TestUnmarshallBadLevel(t *testing.T) { - l := &AllowedLevel{} - err := yaml.Unmarshal([]byte(`debugg`), l) - if err == nil { - t.Error("expected error") - } - expErr := `unrecognized log level "debugg"` - if err.Error() != expErr { - t.Errorf("expected error %s, got %s", expErr, err.Error()) - } - if l.s != "" { - t.Errorf("expected empty level, got %s", l.s) - } -} - -type recordKeyvalLogger struct { - count int -} - -func (r *recordKeyvalLogger) Log(keyvals ...interface{}) error { - for _, v := range keyvals { - if fmt.Sprintf("%v", v) == "Log level changed" { - return nil - } - } - r.count++ - return nil -} - -func TestDynamic(t *testing.T) { - logger := NewDynamic(&Config{}) - - debugLevel := &AllowedLevel{} - err := debugLevel.Set("debug") - require.NoError(t, err) - infoLevel := &AllowedLevel{} - err = infoLevel.Set("info") - require.NoError(t, err) - - recorder := &recordKeyvalLogger{} - logger.base = recorder - logger.SetLevel(debugLevel) - err = level.Debug(logger).Log("hello", "world") - require.NoError(t, err) - require.Equalf(t, 1, recorder.count, "log not found") - - recorder.count = 0 - logger.SetLevel(infoLevel) - err = level.Debug(logger).Log("hello", "world") - require.NoError(t, err) - require.Equalf(t, 0, recorder.count, "log found") - err = level.Info(logger).Log("hello", "world") - require.NoError(t, err) - require.Equalf(t, 1, recorder.count, "log not found") - err = level.Debug(logger).Log("hello", "world") - require.NoError(t, err) - require.Equalf(t, 1, recorder.count, "extra log found") -} diff --git a/sigv4/.yamllint b/sigv4/.yamllint deleted file mode 100644 index 281c94646..000000000 --- a/sigv4/.yamllint +++ /dev/null @@ -1,27 +0,0 @@ ---- -extends: default - -rules: - braces: - max-spaces-inside: 1 - level: error - brackets: - max-spaces-inside: 1 - level: error - commas: disable - comments: disable - comments-indentation: disable - document-start: disable - indentation: - spaces: consistent - key-duplicates: - ignore: | - config/testdata/section_key_dup.bad.yml - line-length: disable - truthy: - ignore: | - .github/workflows/codeql-analysis.yml - .github/workflows/funcbench.yml - .github/workflows/fuzzing.yml - .github/workflows/prombench.yml - .github/workflows/golangci-lint.yml diff --git a/sigv4/Makefile b/sigv4/Makefile deleted file mode 100644 index 0b62dd325..000000000 --- a/sigv4/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2018 The Prometheus Authors -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -include ../Makefile.common - -.PHONY: test -test:: deps check_license unused common-test lint diff --git a/sigv4/README.md b/sigv4/README.md deleted file mode 100644 index 661680e64..000000000 --- a/sigv4/README.md +++ /dev/null @@ -1,12 +0,0 @@ -github.com/prometheus/common/sigv4 module -========================================= - -sigv4 provides a http.RoundTripper that will sign requests using -Amazon's Signature Verification V4 signing procedure, using credentials -from the default AWS credential chain. - -This is a separate module from github.com/prometheus/common to prevent -it from having and propagating a dependency on the AWS SDK. - -This module is considered internal to Prometheus, without any stability -guarantees for external usage. diff --git a/sigv4/go.mod b/sigv4/go.mod deleted file mode 100644 index a751b7f15..000000000 --- a/sigv4/go.mod +++ /dev/null @@ -1,33 +0,0 @@ -module github.com/prometheus/common/sigv4 - -go 1.21 - -replace github.com/prometheus/common => ../ - -require ( - github.com/aws/aws-sdk-go v1.55.5 - github.com/prometheus/common v0.59.1 - github.com/stretchr/testify v1.10.0 - gopkg.in/yaml.v2 v2.4.0 -) - -require ( - github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/jpillora/backoff v1.0.0 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.20.4 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/procfs v0.15.1 // indirect - golang.org/x/net v0.32.0 // indirect - golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect - google.golang.org/protobuf v1.35.2 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/sigv4/go.sum b/sigv4/go.sum deleted file mode 100644 index 957af981d..000000000 --- a/sigv4/go.sum +++ /dev/null @@ -1,59 +0,0 @@ -github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= -github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -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/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= -github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sigv4/sigv4.go b/sigv4/sigv4.go deleted file mode 100644 index 17cc9139a..000000000 --- a/sigv4/sigv4.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Deprecated: This package has been migrated to github.com/prometheus/sigv4. -package sigv4 - -import ( - "bytes" - "errors" - "fmt" - "io" - "net/http" - "net/textproto" - "path" - "sync" - "time" - - "github.com/aws/aws-sdk-go/aws/endpoints" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/credentials/stscreds" - "github.com/aws/aws-sdk-go/aws/session" - signer "github.com/aws/aws-sdk-go/aws/signer/v4" -) - -var sigv4HeaderDenylist = []string{ - "uber-trace-id", -} - -type sigV4RoundTripper struct { - region string - next http.RoundTripper - pool sync.Pool - - signer *signer.Signer -} - -// NewSigV4RoundTripper returns a new http.RoundTripper that will sign requests -// using Amazon's Signature Verification V4 signing procedure. The request will -// then be handed off to the next RoundTripper provided by next. If next is nil, -// http.DefaultTransport will be used. -// -// Credentials for signing are retrieved using the the default AWS credential -// chain. If credentials cannot be found, an error will be returned. -func NewSigV4RoundTripper(cfg *SigV4Config, next http.RoundTripper) (http.RoundTripper, error) { - if next == nil { - next = http.DefaultTransport - } - - creds := credentials.NewStaticCredentials(cfg.AccessKey, string(cfg.SecretKey), "") - if cfg.AccessKey == "" && cfg.SecretKey == "" { - creds = nil - } - - useFIPSSTSEndpoint := endpoints.FIPSEndpointStateDisabled - if cfg.UseFIPSSTSEndpoint { - useFIPSSTSEndpoint = endpoints.FIPSEndpointStateEnabled - } - - sess, err := session.NewSessionWithOptions(session.Options{ - Config: aws.Config{ - Region: aws.String(cfg.Region), - Credentials: creds, - UseFIPSEndpoint: useFIPSSTSEndpoint, - }, - Profile: cfg.Profile, - }) - if err != nil { - return nil, fmt.Errorf("could not create new AWS session: %w", err) - } - if _, err := sess.Config.Credentials.Get(); err != nil { - return nil, fmt.Errorf("could not get SigV4 credentials: %w", err) - } - if aws.StringValue(sess.Config.Region) == "" { - return nil, errors.New("region not configured in sigv4 or in default credentials chain") - } - - signerCreds := sess.Config.Credentials - if cfg.RoleARN != "" { - signerCreds = stscreds.NewCredentials(sess, cfg.RoleARN) - } - - rt := &sigV4RoundTripper{ - region: cfg.Region, - next: next, - signer: signer.NewSigner(signerCreds), - } - rt.pool.New = rt.newBuf - return rt, nil -} - -func (rt *sigV4RoundTripper) newBuf() interface{} { - return bytes.NewBuffer(make([]byte, 0, 1024)) -} - -func (rt *sigV4RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - // rt.signer.Sign needs a seekable body, so we replace the body with a - // buffered reader filled with the contents of original body. - buf := rt.pool.Get().(*bytes.Buffer) - defer func() { - buf.Reset() - rt.pool.Put(buf) - }() - - if req.Body != nil { - if _, err := io.Copy(buf, req.Body); err != nil { - return nil, err - } - // Close the original body since we don't need it anymore. - _ = req.Body.Close() - } - - // Ensure our seeker is back at the start of the buffer once we return. - var seeker io.ReadSeeker = bytes.NewReader(buf.Bytes()) - defer func() { - _, _ = seeker.Seek(0, io.SeekStart) - }() - req.Body = io.NopCloser(seeker) - - // Clean path like documented in AWS documentation. - // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html - req.URL.Path = path.Clean(req.URL.Path) - - // Clone the request and trim out headers that we don't want to sign. - signReq := req.Clone(req.Context()) - for _, header := range sigv4HeaderDenylist { - signReq.Header.Del(header) - } - - headers, err := rt.signer.Sign(signReq, seeker, "aps", rt.region, time.Now().UTC()) - if err != nil { - return nil, fmt.Errorf("failed to sign request: %w", err) - } - - // Copy over signed headers. Authorization header is not returned by - // rt.signer.Sign and needs to be copied separately. - for k, v := range headers { - req.Header[textproto.CanonicalMIMEHeaderKey(k)] = v - } - req.Header.Set("Authorization", signReq.Header.Get("Authorization")) - - return rt.next.RoundTrip(req) -} diff --git a/sigv4/sigv4_config.go b/sigv4/sigv4_config.go deleted file mode 100644 index 2f5e7572a..000000000 --- a/sigv4/sigv4_config.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package sigv4 - -import ( - "errors" - - "github.com/prometheus/common/config" -) - -// SigV4Config is the configuration for signing remote write requests with -// AWS's SigV4 verification process. Empty values will be retrieved using the -// AWS default credentials chain. -type SigV4Config struct { - Region string `yaml:"region,omitempty"` - AccessKey string `yaml:"access_key,omitempty"` - SecretKey config.Secret `yaml:"secret_key,omitempty"` - Profile string `yaml:"profile,omitempty"` - RoleARN string `yaml:"role_arn,omitempty"` - UseFIPSSTSEndpoint bool `yaml:"use_fips_sts_endpoint,omitempty"` -} - -func (c *SigV4Config) Validate() error { - if (c.AccessKey == "") != (c.SecretKey == "") { - return errors.New("must provide a AWS SigV4 Access key and Secret Key if credentials are specified in the SigV4 config") - } - return nil -} - -func (c *SigV4Config) UnmarshalYAML(unmarshal func(interface{}) error) error { - type plain SigV4Config - *c = SigV4Config{} - if err := unmarshal((*plain)(c)); err != nil { - return err - } - return c.Validate() -} diff --git a/sigv4/sigv4_config_test.go b/sigv4/sigv4_config_test.go deleted file mode 100644 index 6c8058f64..000000000 --- a/sigv4/sigv4_config_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package sigv4 - -import ( - "os" - "testing" - - "github.com/stretchr/testify/require" - "gopkg.in/yaml.v2" -) - -func loadSigv4Config(filename string) (*SigV4Config, error) { - content, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - cfg := SigV4Config{} - if err = yaml.UnmarshalStrict(content, &cfg); err != nil { - return nil, err - } - return &cfg, nil -} - -func testGoodConfig(t *testing.T, filename string) { - _, err := loadSigv4Config(filename) - require.NoErrorf(t, err, "Unexpected error parsing %s: %s", filename, err) -} - -func TestGoodSigV4Configs(t *testing.T) { - filesToTest := []string{"testdata/sigv4_good.yaml", "testdata/sigv4_good.yaml"} - for _, filename := range filesToTest { - testGoodConfig(t, filename) - } -} - -func TestBadSigV4Config(t *testing.T) { - filename := "testdata/sigv4_bad.yaml" - _, err := loadSigv4Config(filename) - require.Errorf(t, err, "Did not receive expected error unmarshaling bad sigv4 config") - require.ErrorContainsf(t, err, "must provide a AWS SigV4 Access key and Secret Key", "Received unexpected error from unmarshal of %s: %s", filename, err.Error()) -} diff --git a/sigv4/sigv4_test.go b/sigv4/sigv4_test.go deleted file mode 100644 index b470672c2..000000000 --- a/sigv4/sigv4_test.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package sigv4 - -import ( - "net/http" - "os" - "strings" - "testing" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/session" - signer "github.com/aws/aws-sdk-go/aws/signer/v4" - "github.com/stretchr/testify/require" -) - -type RoundTripperFunc func(req *http.Request) (*http.Response, error) - -// RoundTrip implements the RoundTripper interface. -func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) { - return rt(r) -} - -func TestSigV4_Inferred_Region(t *testing.T) { - os.Setenv("AWS_ACCESS_KEY_ID", "secret") - os.Setenv("AWS_SECRET_ACCESS_KEY", "token") - os.Setenv("AWS_REGION", "us-west-2") - - sess, err := session.NewSession(&aws.Config{ - // Setting to an empty string to demostrate the default value from the yaml - // won't override the environment's region. - Region: aws.String(""), - }) - require.NoError(t, err) - _, err = sess.Config.Credentials.Get() - require.NoError(t, err) - - require.NotNil(t, sess.Config.Region) - require.Equal(t, "us-west-2", *sess.Config.Region) -} - -func TestSigV4RoundTripper(t *testing.T) { - var gotReq *http.Request - - rt := &sigV4RoundTripper{ - region: "us-east-2", - next: RoundTripperFunc(func(req *http.Request) (*http.Response, error) { - gotReq = req - return &http.Response{StatusCode: http.StatusOK}, nil - }), - signer: signer.NewSigner(credentials.NewStaticCredentials( - "test-id", - "secret", - "token", - )), - } - rt.pool.New = rt.newBuf - - cli := &http.Client{Transport: rt} - - req, err := http.NewRequest(http.MethodPost, "https://example.com", strings.NewReader("Hello, world!")) - require.NoError(t, err) - - _, err = cli.Do(req) - require.NoError(t, err) - require.NotNil(t, gotReq) - - origReq := gotReq - require.NotEmpty(t, origReq.Header.Get("Authorization")) - require.NotEmpty(t, origReq.Header.Get("X-Amz-Date")) - - // Perform the same request but with a header that shouldn't included in the - // signature; validate that the Authorization signature matches. - t.Run("Ignored Headers", func(t *testing.T) { - req, err := http.NewRequest(http.MethodPost, "https://example.com", strings.NewReader("Hello, world!")) - require.NoError(t, err) - - req.Header.Add("Uber-Trace-Id", "some-trace-id") - - _, err = cli.Do(req) - require.NoError(t, err) - require.NotNil(t, gotReq) - - require.Equal(t, origReq.Header.Get("Authorization"), gotReq.Header.Get("Authorization")) - }) - - t.Run("Escape URL", func(t *testing.T) { - req, err := http.NewRequest(http.MethodPost, "https://example.com/test//test", strings.NewReader("Hello, world!")) - require.NoError(t, err) - require.Equal(t, "/test//test", req.URL.Path) - - _, err = cli.Do(req) - require.NoError(t, err) - require.NotNil(t, gotReq) - - require.Equal(t, "/test/test", gotReq.URL.Path) - }) - - t.Run("No body", func(t *testing.T) { - req, err := http.NewRequest(http.MethodGet, "https://example.com/test/test", nil) - require.NoError(t, err) - _, err = cli.Do(req) - require.NoError(t, err) - }) -} diff --git a/sigv4/testdata/sigv4_bad.yaml b/sigv4/testdata/sigv4_bad.yaml deleted file mode 100644 index 7086f636b..000000000 --- a/sigv4/testdata/sigv4_bad.yaml +++ /dev/null @@ -1,4 +0,0 @@ -region: us-east-2 -access_key: AccessKey -profile: profile -role_arn: blah:role/arn diff --git a/sigv4/testdata/sigv4_good.yaml b/sigv4/testdata/sigv4_good.yaml deleted file mode 100644 index 629669458..000000000 --- a/sigv4/testdata/sigv4_good.yaml +++ /dev/null @@ -1,6 +0,0 @@ -region: us-east-2 -access_key: AccessKey -secret_key: SecretKey -profile: profile -role_arn: blah:role/arn -use_fips_sts_endpoint: true diff --git a/sigv4/testdata/sigv4_good_empty_keys.yaml b/sigv4/testdata/sigv4_good_empty_keys.yaml deleted file mode 100644 index de10c0ff3..000000000 --- a/sigv4/testdata/sigv4_good_empty_keys.yaml +++ /dev/null @@ -1,3 +0,0 @@ -region: us-east-2 -profile: profile -role_arn: blah:role/arn