diff --git a/.chloggen/dockerstats-tls-config.yaml b/.chloggen/dockerstats-tls-config.yaml new file mode 100644 index 0000000000000..7263425c22b3d --- /dev/null +++ b/.chloggen/dockerstats-tls-config.yaml @@ -0,0 +1,35 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog) +component: receiver/docker_stats + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add TLS configuration support for connecting to the Docker daemon over HTTPS with client and server certificates. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [33557] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: | + A new optional `tls` configuration block is available in `docker_stats` receiver config (and the + shared `internal/docker` package). When omitted the connection remains insecure (plain HTTP or + Unix socket), preserving existing behavior. When provided it supports the standard + `configtls.ClientConfig` fields: `ca_file`, `cert_file`, `key_file`, `insecure_skip_verify`, + `min_version`, and `max_version`. + A warning is now emitted when a plain `tcp://` or `http://` endpoint is used without TLS, + reflecting Docker's deprecation of unauthenticated TCP connections since Docker v26.0 + (see https://docs.docker.com/engine/deprecated/#unauthenticated-tcp-connections). + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user, api] diff --git a/extension/observer/dockerobserver/go.mod b/extension/observer/dockerobserver/go.mod index 4d27e8c468971..6c564465a696c 100644 --- a/extension/observer/dockerobserver/go.mod +++ b/extension/observer/dockerobserver/go.mod @@ -38,11 +38,14 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/ebitengine/purego v0.10.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -75,6 +78,9 @@ require ( github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/config/configopaque v1.54.1-0.20260320051400-372cc483b303 // indirect + go.opentelemetry.io/collector/config/configoptional v1.54.1-0.20260320051400-372cc483b303 // indirect + go.opentelemetry.io/collector/config/configtls v1.54.1-0.20260320051400-372cc483b303 // indirect go.opentelemetry.io/collector/featuregate v1.54.1-0.20260320051400-372cc483b303 // indirect go.opentelemetry.io/collector/internal/componentalias v0.148.1-0.20260320051400-372cc483b303 // indirect go.opentelemetry.io/collector/pdata v1.54.1-0.20260320051400-372cc483b303 // indirect diff --git a/extension/observer/dockerobserver/go.sum b/extension/observer/dockerobserver/go.sum index a2a3f262a684a..6f3d6005cb75d 100644 --- a/extension/observer/dockerobserver/go.sum +++ b/extension/observer/dockerobserver/go.sum @@ -39,6 +39,12 @@ github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= +github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= +github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -53,6 +59,10 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -143,6 +153,12 @@ go.opentelemetry.io/collector/component v1.54.1-0.20260320051400-372cc483b303 h1 go.opentelemetry.io/collector/component v1.54.1-0.20260320051400-372cc483b303/go.mod h1:yUMBYsySY/sDcXm8kOzEoZxt+JLdala6hxzSW0npOxY= go.opentelemetry.io/collector/component/componenttest v0.148.1-0.20260320051400-372cc483b303 h1:0fmi1mQ+24e1JBdF2EGpD/S55X+Mq4cAdWs76PkaUOk= go.opentelemetry.io/collector/component/componenttest v0.148.1-0.20260320051400-372cc483b303/go.mod h1:1c1+6mZOmI0raoya5vA/X0F+fawEjNS6tCEs5xLATtA= +go.opentelemetry.io/collector/config/configopaque v1.54.1-0.20260320051400-372cc483b303 h1:Jum5sgJ8VWhEbOibhJLVoOpv4G945HZW6ohS0scd5/I= +go.opentelemetry.io/collector/config/configopaque v1.54.1-0.20260320051400-372cc483b303/go.mod h1:beDuR48blgodzbJkUgMFu9vg0qxjU04tcBtb/rVEP/A= +go.opentelemetry.io/collector/config/configoptional v1.54.1-0.20260320051400-372cc483b303 h1:htD9PCoL2aHwR95R30AlLS0i777Vi6OGI/8UQdm2Cx0= +go.opentelemetry.io/collector/config/configoptional v1.54.1-0.20260320051400-372cc483b303/go.mod h1:c8cFSCUN/A6U00janThFC64ZpyKV1viq/chPOoaqe3I= +go.opentelemetry.io/collector/config/configtls v1.54.1-0.20260320051400-372cc483b303 h1:kpDljGOhHVpFyh5JM15HWeQyTpqBZ9pwwg/ui7SG1p0= +go.opentelemetry.io/collector/config/configtls v1.54.1-0.20260320051400-372cc483b303/go.mod h1:ikruZqHoIlR+MaqUgDKotQiuN64uAdlH6zxsTjSKjSM= go.opentelemetry.io/collector/confmap v1.54.1-0.20260320051400-372cc483b303 h1:fm5gRSiwqmNsNX4a3DpgaOShiFI8PdZK9F6NOcFXPnQ= go.opentelemetry.io/collector/confmap v1.54.1-0.20260320051400-372cc483b303/go.mod h1:mQxG8bk0IWIt9gbWMvzE+cRkOuCuzbzkNGBq2YJ4wNM= go.opentelemetry.io/collector/confmap/xconfmap v0.148.1-0.20260320051400-372cc483b303 h1:d3Jpn2EMZJfQnu6QSIrZEWkLuRpwgKlMidLnaaKU2gw= diff --git a/internal/docker/config.go b/internal/docker/config.go index 1389ed6aa32a3..ceba7e9f3b244 100644 --- a/internal/docker/config.go +++ b/internal/docker/config.go @@ -4,6 +4,7 @@ package docker // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/docker" import ( + "context" "errors" "fmt" "strconv" @@ -12,6 +13,8 @@ import ( "github.com/docker/docker/api/types/versions" "github.com/docker/docker/client" + "go.opentelemetry.io/collector/config/configoptional" + "go.opentelemetry.io/collector/config/configtls" "go.opentelemetry.io/collector/confmap" ) @@ -29,6 +32,11 @@ type Config struct { // Docker client API version. If empty, the client will auto-negotiate // the API version with the Docker daemon using version negotiation. DockerAPIVersion string `mapstructure:"api_version"` + + // TLS holds optional TLS client configuration for connecting to the Docker daemon + // over HTTPS. When nil (the default), the connection uses no custom TLS — suitable + // for Unix sockets and plain HTTP endpoints. + TLS configoptional.Optional[configtls.ClientConfig] `mapstructure:"tls,omitempty"` } func (config *Config) Unmarshal(conf *confmap.Conf) error { @@ -51,6 +59,11 @@ func (config Config) Validate() error { if config.Endpoint == "" { return errors.New("endpoint must be specified") } + if config.TLS.HasValue() { + if _, err := config.TLS.Get().LoadTLSConfig(context.Background()); err != nil { + return fmt.Errorf("invalid tls configuration: %w", err) + } + } return nil } diff --git a/internal/docker/config.schema.yaml b/internal/docker/config.schema.yaml index c5aff83d0ce89..257ff9ebb69f1 100644 --- a/internal/docker/config.schema.yaml +++ b/internal/docker/config.schema.yaml @@ -17,3 +17,7 @@ $defs: description: The maximum amount of time to wait for docker API responses. Default is 5s type: string format: duration + tls: + description: TLS holds optional TLS client configuration for connecting to the Docker daemon over HTTPS. When nil (the default), the connection uses no custom TLS — suitable for Unix sockets and plain HTTP endpoints. + x-optional: true + $ref: go.opentelemetry.io/collector/config/configtls.client_config diff --git a/internal/docker/config_test.go b/internal/docker/config_test.go index 9175eed537438..f4458851d1d61 100644 --- a/internal/docker/config_test.go +++ b/internal/docker/config_test.go @@ -8,6 +8,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/config/configoptional" + "go.opentelemetry.io/collector/config/configtls" + "go.opentelemetry.io/collector/confmap" ) func TestAPIVersion(t *testing.T) { @@ -78,3 +81,49 @@ func TestAPIVersion(t *testing.T) { }) } } + +func TestDefaultConfigHasNoTLS(t *testing.T) { + cfg := NewDefaultConfig() + assert.False(t, cfg.TLS.HasValue(), "default config should have nil TLS for backward compatibility") +} + +func TestNewConfigHasNoTLS(t *testing.T) { + cfg := NewConfig("unix:///var/run/docker.sock", 0, nil, "") + assert.False(t, cfg.TLS.HasValue(), "NewConfig should have nil TLS by default") +} + +func TestUnmarshalNoTLSKeepsNil(t *testing.T) { + conf := confmap.NewFromStringMap(map[string]any{ + "endpoint": "unix:///var/run/docker.sock", + }) + cfg := &Config{} + require.NoError(t, cfg.Unmarshal(conf)) + assert.False(t, cfg.TLS.HasValue(), "omitting tls block should leave TLS nil") +} + +func TestUnmarshalWithTLSBlock(t *testing.T) { + conf := confmap.NewFromStringMap(map[string]any{ + "endpoint": "https://example.com/", + "tls": map[string]any{ + "insecure_skip_verify": true, + }, + }) + cfg := &Config{} + require.NoError(t, cfg.Unmarshal(conf)) + assert.True(t, cfg.TLS.HasValue()) + assert.True(t, cfg.TLS.Get().InsecureSkipVerify) +} + +func TestValidateInvalidTLSCertPath(t *testing.T) { + cfg := &Config{ + Endpoint: "https://example.com/", + TLS: configoptional.Some(configtls.ClientConfig{ + Config: configtls.Config{ + CAFile: "/nonexistent/ca.pem", + }, + }), + } + err := cfg.Validate() + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid tls configuration") +} diff --git a/internal/docker/docker.go b/internal/docker/docker.go index 037afc7be600b..a92924a112815 100644 --- a/internal/docker/docker.go +++ b/internal/docker/docker.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "io" + "net/http" "strings" "sync" "time" @@ -62,6 +63,25 @@ func NewDockerClient(config *Config, logger *zap.Logger, opts ...docker.Opt) (*C logger.Debug("Docker API version not specified, using automatic version negotiation") } + // Configure TLS transport when a TLS config is provided. + if config.TLS.HasValue() && !config.TLS.Get().Insecure { + tlsCfg, err := config.TLS.Get().LoadTLSConfig(context.Background()) + if err != nil { + return nil, fmt.Errorf("could not load docker client TLS config: %w", err) + } + transport := &http.Transport{TLSClientConfig: tlsCfg} + clientOpts = append(clientOpts, docker.WithHTTPClient(&http.Client{Transport: transport})) + } else if isTCPEndpoint(config.Endpoint) { + // Unauthenticated TCP connections to the Docker daemon were deprecated in Docker v26.0 + // and enforcement began in v27.0. Configure the 'tls' block to secure this connection. + // See: https://docs.docker.com/engine/deprecated/#unauthenticated-tcp-connections + logger.Warn( + "Unauthenticated TCP connection to Docker daemon is deprecated since Docker v26.0. "+ + "Configure the 'tls' option to use a secure connection.", + zap.String("endpoint", config.Endpoint), + ) + } + // Append any additional opts passed by caller clientOpts = append(clientOpts, opts...) @@ -342,6 +362,13 @@ func (dc *Client) shouldBeExcluded(image string) bool { return dc.excludedImageMatcher != nil && dc.excludedImageMatcher.matches(image) } +// isTCPEndpoint reports whether the endpoint uses a plain TCP or HTTP scheme, +// meaning the connection is not secured by a Unix socket, named pipe, or TLS. +func isTCPEndpoint(endpoint string) bool { + lower := strings.ToLower(endpoint) + return strings.HasPrefix(lower, "tcp://") || strings.HasPrefix(lower, "http://") +} + func ContainerEnvToMap(env []string) map[string]string { out := make(map[string]string, len(env)) for _, v := range env { diff --git a/internal/docker/docker_test.go b/internal/docker/docker_test.go index 5d3a7a7b043fb..7da53fca00305 100644 --- a/internal/docker/docker_test.go +++ b/internal/docker/docker_test.go @@ -19,6 +19,8 @@ import ( ctypes "github.com/docker/docker/api/types/container" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/config/configoptional" + "go.opentelemetry.io/collector/config/configtls" "go.uber.org/zap" "go.uber.org/zap/zapcore" "go.uber.org/zap/zaptest/observer" @@ -222,11 +224,15 @@ func TestEventLoopHandlesError(t *testing.T) { defer cancel() assert.EventuallyWithT(t, func(tt *assert.CollectT) { + var eventErrLogs []observer.LoggedEntry for _, l := range logs.All() { - assert.Contains(tt, l.Message, "Error watching docker container events") - assert.Contains(tt, l.ContextMap()["error"], "EOF") + if strings.Contains(l.Message, "Error watching docker container events") { + eventErrLogs = append(eventErrLogs, l) + } + } + if assert.NotEmpty(tt, eventErrLogs) { + assert.Contains(tt, eventErrLogs[0].ContextMap()["error"], "EOF") } - assert.NotEmpty(tt, logs.All()) }, 1*time.Second, 1*time.Millisecond, "failed to find desired error logs.") finished := make(chan struct{}) @@ -292,3 +298,69 @@ func TestDefaultConfigUsesNegotiation(t *testing.T) { config := NewDefaultConfig() assert.Empty(t, config.DockerAPIVersion, "Default config should have empty DockerAPIVersion for auto-negotiation") } + +func TestTLSClientConfig(t *testing.T) { + // Start a TLS test server + srv := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + })) + defer srv.Close() + + config := &Config{ + Endpoint: srv.URL, + Timeout: 5 * time.Second, + TLS: configoptional.Some(configtls.ClientConfig{ + InsecureSkipVerify: true, + }), + } + + cli, err := NewDockerClient(config, zap.NewNop()) + require.NoError(t, err) + assert.NotNil(t, cli) +} + +func TestUnauthenticatedTCPWarning(t *testing.T) { + for _, endpoint := range []string{ + "tcp://192.168.1.1:2375", + "http://192.168.1.1:2375", + "TCP://192.168.1.1:2375", + "HTTP://192.168.1.1:2375", + } { + t.Run(endpoint, func(t *testing.T) { + observed, logs := observer.New(zapcore.WarnLevel) + _, _ = NewDockerClient(&Config{Endpoint: endpoint}, zap.New(observed)) + assert.NotEmpty(t, logs.All(), "expected a deprecation warning for unauthenticated TCP endpoint") + assert.Contains(t, logs.All()[0].Message, "deprecated") + }) + } +} + +func TestNoWarningForSecureEndpoints(t *testing.T) { + for _, endpoint := range []string{ + "unix:///var/run/docker.sock", + "npipe:////./pipe/docker_engine", + } { + t.Run(endpoint, func(t *testing.T) { + observed, logs := observer.New(zapcore.WarnLevel) + _, _ = NewDockerClient(&Config{Endpoint: endpoint}, zap.New(observed)) + assert.Empty(t, logs.All(), "expected no deprecation warning for non-TCP endpoint") + }) + } +} + +func TestTLSClientConfigInvalidCert(t *testing.T) { + config := &Config{ + Endpoint: "https://example.com/", + Timeout: 5 * time.Second, + TLS: configoptional.Some(configtls.ClientConfig{ + Config: configtls.Config{ + CAFile: "/nonexistent/ca.pem", + }, + }), + } + + cli, err := NewDockerClient(config, zap.NewNop()) + assert.Nil(t, cli) + require.Error(t, err) + assert.Contains(t, err.Error(), "could not load docker client TLS config") +} diff --git a/internal/docker/go.mod b/internal/docker/go.mod index b6350a4b6eeb2..fb4fabc1625d5 100644 --- a/internal/docker/go.mod +++ b/internal/docker/go.mod @@ -8,6 +8,8 @@ require ( github.com/docker/docker v28.5.2+incompatible github.com/gobwas/glob v0.2.3 github.com/stretchr/testify v1.11.1 + go.opentelemetry.io/collector/config/configoptional v1.54.1-0.20260320051400-372cc483b303 + go.opentelemetry.io/collector/config/configtls v1.54.1-0.20260320051400-372cc483b303 go.opentelemetry.io/collector/confmap v1.54.1-0.20260320051400-372cc483b303 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 @@ -22,9 +24,12 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/hashicorp/go-version v1.8.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect @@ -40,6 +45,8 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/config/configopaque v1.54.1-0.20260320051400-372cc483b303 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.148.1-0.20260320051400-372cc483b303 // indirect go.opentelemetry.io/collector/featuregate v1.54.1-0.20260320051400-372cc483b303 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect @@ -49,6 +56,7 @@ require ( go.opentelemetry.io/otel/trace v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.48.0 // indirect golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/time v0.4.0 // indirect diff --git a/internal/docker/go.sum b/internal/docker/go.sum index bcb7f27484735..58effa8165b08 100644 --- a/internal/docker/go.sum +++ b/internal/docker/go.sum @@ -25,6 +25,12 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= +github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= +github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -38,6 +44,10 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= @@ -86,10 +96,20 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/config/configopaque v1.54.1-0.20260320051400-372cc483b303 h1:Jum5sgJ8VWhEbOibhJLVoOpv4G945HZW6ohS0scd5/I= +go.opentelemetry.io/collector/config/configopaque v1.54.1-0.20260320051400-372cc483b303/go.mod h1:beDuR48blgodzbJkUgMFu9vg0qxjU04tcBtb/rVEP/A= +go.opentelemetry.io/collector/config/configoptional v1.54.1-0.20260320051400-372cc483b303 h1:htD9PCoL2aHwR95R30AlLS0i777Vi6OGI/8UQdm2Cx0= +go.opentelemetry.io/collector/config/configoptional v1.54.1-0.20260320051400-372cc483b303/go.mod h1:c8cFSCUN/A6U00janThFC64ZpyKV1viq/chPOoaqe3I= +go.opentelemetry.io/collector/config/configtls v1.54.1-0.20260320051400-372cc483b303 h1:kpDljGOhHVpFyh5JM15HWeQyTpqBZ9pwwg/ui7SG1p0= +go.opentelemetry.io/collector/config/configtls v1.54.1-0.20260320051400-372cc483b303/go.mod h1:ikruZqHoIlR+MaqUgDKotQiuN64uAdlH6zxsTjSKjSM= go.opentelemetry.io/collector/confmap v1.54.1-0.20260320051400-372cc483b303 h1:fm5gRSiwqmNsNX4a3DpgaOShiFI8PdZK9F6NOcFXPnQ= go.opentelemetry.io/collector/confmap v1.54.1-0.20260320051400-372cc483b303/go.mod h1:mQxG8bk0IWIt9gbWMvzE+cRkOuCuzbzkNGBq2YJ4wNM= +go.opentelemetry.io/collector/confmap/xconfmap v0.148.1-0.20260320051400-372cc483b303 h1:d3Jpn2EMZJfQnu6QSIrZEWkLuRpwgKlMidLnaaKU2gw= +go.opentelemetry.io/collector/confmap/xconfmap v0.148.1-0.20260320051400-372cc483b303/go.mod h1:4qTMr3V0uSXXac9wVs/UD5fIqRKw5yIl58+Vjsc6RHM= go.opentelemetry.io/collector/featuregate v1.54.1-0.20260320051400-372cc483b303 h1:ryTtKxevytMTQ7b4vEtvuM4s9AisQZlvikfWvIpo0R4= go.opentelemetry.io/collector/featuregate v1.54.1-0.20260320051400-372cc483b303/go.mod h1:PS7zY/zaCb28EqciePVwRHVhc3oKortTFXsi3I6ee4g= +go.opentelemetry.io/collector/internal/testutil v0.148.0 h1:3Z9hperte3vSmbBTYeNndoEUICICrNz8hzx+v0FYXBQ= +go.opentelemetry.io/collector/internal/testutil v0.148.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= @@ -115,6 +135,8 @@ go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= diff --git a/receiver/dockerstatsreceiver/config_test.go b/receiver/dockerstatsreceiver/config_test.go index 35edea5836e2e..279020f2738a1 100644 --- a/receiver/dockerstatsreceiver/config_test.go +++ b/receiver/dockerstatsreceiver/config_test.go @@ -9,9 +9,12 @@ import ( "time" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configoptional" + "go.opentelemetry.io/collector/config/configtls" "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/confmap/confmaptest" "go.opentelemetry.io/collector/confmap/xconfmap" @@ -40,6 +43,25 @@ func TestLoadConfig(t *testing.T) { id: component.NewIDWithName(metadata.Type, ""), expected: createDefaultConfig(), }, + { + id: component.NewIDWithName(metadata.Type, "tls"), + expected: &Config{ + ControllerConfig: scraperhelper.ControllerConfig{ + CollectionInterval: 10 * time.Second, + InitialDelay: time.Second, + Timeout: 5 * time.Second, + }, + Config: docker.Config{ + Endpoint: "https://example.com/", + DockerAPIVersion: "1.44", + Timeout: 5 * time.Second, + TLS: configoptional.Some(configtls.ClientConfig{ + InsecureSkipVerify: true, + }), + }, + MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), + }, + }, { id: component.NewIDWithName(metadata.Type, "allsettings"), expected: &Config{ @@ -88,7 +110,7 @@ func TestLoadConfig(t *testing.T) { assert.NoError(t, xconfmap.Validate(cfg)) if diff := cmp.Diff(tt.expected, cfg, cmp.FilterPath(func(p cmp.Path) bool { return p.Last().String() == ".enabledSetByUser" - }, cmp.Ignore())); diff != "" { + }, cmp.Ignore()), cmpopts.IgnoreUnexported(configoptional.Optional[configtls.ClientConfig]{})); diff != "" { t.Errorf("Config mismatch (-expected +actual):\n%s", diff) } }) diff --git a/receiver/dockerstatsreceiver/go.mod b/receiver/dockerstatsreceiver/go.mod index eebe1cbc890ee..7aa87e12a22ad 100644 --- a/receiver/dockerstatsreceiver/go.mod +++ b/receiver/dockerstatsreceiver/go.mod @@ -14,6 +14,8 @@ require ( go.opentelemetry.io/collector/component v1.54.1-0.20260320051400-372cc483b303 go.opentelemetry.io/collector/component/componentstatus v0.148.1-0.20260320051400-372cc483b303 go.opentelemetry.io/collector/component/componenttest v0.148.1-0.20260320051400-372cc483b303 + go.opentelemetry.io/collector/config/configoptional v1.54.1-0.20260320051400-372cc483b303 + go.opentelemetry.io/collector/config/configtls v1.54.1-0.20260320051400-372cc483b303 go.opentelemetry.io/collector/confmap v1.54.1-0.20260320051400-372cc483b303 go.opentelemetry.io/collector/confmap/xconfmap v0.148.1-0.20260320051400-372cc483b303 go.opentelemetry.io/collector/consumer v1.54.1-0.20260320051400-372cc483b303 @@ -48,11 +50,14 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/ebitengine/purego v0.10.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -86,6 +91,7 @@ require ( github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/config/configopaque v1.54.1-0.20260320051400-372cc483b303 // indirect go.opentelemetry.io/collector/consumer/consumererror v0.148.1-0.20260320051400-372cc483b303 // indirect go.opentelemetry.io/collector/consumer/xconsumer v0.148.1-0.20260320051400-372cc483b303 // indirect go.opentelemetry.io/collector/featuregate v1.54.1-0.20260320051400-372cc483b303 // indirect diff --git a/receiver/dockerstatsreceiver/go.sum b/receiver/dockerstatsreceiver/go.sum index 6e2c24432e833..ea13e6d96473a 100644 --- a/receiver/dockerstatsreceiver/go.sum +++ b/receiver/dockerstatsreceiver/go.sum @@ -39,6 +39,12 @@ github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d h1:EdO/NMMuCZfxhdzTZLuKAciQSnI2DV+Ppg8+vAYrnqA= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80= +github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4= +github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -55,6 +61,10 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -147,6 +157,12 @@ go.opentelemetry.io/collector/component/componentstatus v0.148.1-0.2026032005140 go.opentelemetry.io/collector/component/componentstatus v0.148.1-0.20260320051400-372cc483b303/go.mod h1:yqg3SpGQc22W3wGICdnb+2kZVW9daBr3+LrGUCHkKfc= go.opentelemetry.io/collector/component/componenttest v0.148.1-0.20260320051400-372cc483b303 h1:0fmi1mQ+24e1JBdF2EGpD/S55X+Mq4cAdWs76PkaUOk= go.opentelemetry.io/collector/component/componenttest v0.148.1-0.20260320051400-372cc483b303/go.mod h1:1c1+6mZOmI0raoya5vA/X0F+fawEjNS6tCEs5xLATtA= +go.opentelemetry.io/collector/config/configopaque v1.54.1-0.20260320051400-372cc483b303 h1:Jum5sgJ8VWhEbOibhJLVoOpv4G945HZW6ohS0scd5/I= +go.opentelemetry.io/collector/config/configopaque v1.54.1-0.20260320051400-372cc483b303/go.mod h1:beDuR48blgodzbJkUgMFu9vg0qxjU04tcBtb/rVEP/A= +go.opentelemetry.io/collector/config/configoptional v1.54.1-0.20260320051400-372cc483b303 h1:htD9PCoL2aHwR95R30AlLS0i777Vi6OGI/8UQdm2Cx0= +go.opentelemetry.io/collector/config/configoptional v1.54.1-0.20260320051400-372cc483b303/go.mod h1:c8cFSCUN/A6U00janThFC64ZpyKV1viq/chPOoaqe3I= +go.opentelemetry.io/collector/config/configtls v1.54.1-0.20260320051400-372cc483b303 h1:kpDljGOhHVpFyh5JM15HWeQyTpqBZ9pwwg/ui7SG1p0= +go.opentelemetry.io/collector/config/configtls v1.54.1-0.20260320051400-372cc483b303/go.mod h1:ikruZqHoIlR+MaqUgDKotQiuN64uAdlH6zxsTjSKjSM= go.opentelemetry.io/collector/confmap v1.54.1-0.20260320051400-372cc483b303 h1:fm5gRSiwqmNsNX4a3DpgaOShiFI8PdZK9F6NOcFXPnQ= go.opentelemetry.io/collector/confmap v1.54.1-0.20260320051400-372cc483b303/go.mod h1:mQxG8bk0IWIt9gbWMvzE+cRkOuCuzbzkNGBq2YJ4wNM= go.opentelemetry.io/collector/confmap/xconfmap v0.148.1-0.20260320051400-372cc483b303 h1:d3Jpn2EMZJfQnu6QSIrZEWkLuRpwgKlMidLnaaKU2gw= diff --git a/receiver/dockerstatsreceiver/testdata/config.yaml b/receiver/dockerstatsreceiver/testdata/config.yaml index de3ffce662a7b..0024599a7fb7d 100644 --- a/receiver/dockerstatsreceiver/testdata/config.yaml +++ b/receiver/dockerstatsreceiver/testdata/config.yaml @@ -1,4 +1,8 @@ docker_stats: +docker_stats/tls: + endpoint: https://example.com/ + tls: + insecure_skip_verify: true docker_stats/allsettings: endpoint: http://example.com/ collection_interval: 2s