diff --git a/internal/metadataproviders/aws/ec2/metadata.go b/internal/metadataproviders/aws/ec2/metadata.go index 6011b1d658bb..509069a68d86 100644 --- a/internal/metadataproviders/aws/ec2/metadata.go +++ b/internal/metadataproviders/aws/ec2/metadata.go @@ -6,6 +6,8 @@ package ec2 // import "github.com/open-telemetry/opentelemetry-collector-contrib import ( "context" + "github.com/aws/aws-sdk-go/aws/request" + override "github.com/amazon-contributing/opentelemetry-collector-contrib/override/aws" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/ec2metadata" @@ -14,6 +16,7 @@ import ( type Provider interface { Get(ctx context.Context) (ec2metadata.EC2InstanceIdentityDocument, error) + GetHandlers() *request.Handlers Hostname(ctx context.Context) (string, error) InstanceID(ctx context.Context) (string, error) } @@ -58,3 +61,7 @@ func (c *metadataClient) Get(_ context.Context) (ec2metadata.EC2InstanceIdentity } return c.metadataFallbackEnable.GetInstanceIdentityDocument() } + +func (c *metadataClient) GetHandlers() *request.Handlers { + return &c.metadata.Handlers +} diff --git a/processor/resourcedetectionprocessor/config.go b/processor/resourcedetectionprocessor/config.go index 8dd1c1f10c8b..c519dc222f81 100644 --- a/processor/resourcedetectionprocessor/config.go +++ b/processor/resourcedetectionprocessor/config.go @@ -4,6 +4,7 @@ package resourcedetectionprocessor // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor" import ( + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/confighttp" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal" @@ -41,6 +42,10 @@ type Config struct { // If a supplied attribute is not a valid attribute of a supplied detector it will be ignored. // Deprecated: Please use detector's resource_attributes config instead Attributes []string `mapstructure:"attributes"` + + // MiddlewareID is an ID for an extension that can be used to configure the + // AWS client. + MiddlewareID *component.ID `mapstructure:"middleware,omitempty"` } // DetectorConfig contains user-specified configurations unique to all individual detectors diff --git a/processor/resourcedetectionprocessor/go.mod b/processor/resourcedetectionprocessor/go.mod index f5c84df0d63c..a151435823d5 100644 --- a/processor/resourcedetectionprocessor/go.mod +++ b/processor/resourcedetectionprocessor/go.mod @@ -5,6 +5,7 @@ go 1.22.5 require ( cloud.google.com/go/compute/metadata v0.3.0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.23.0 + github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware v0.0.0-20240419190856-2f880467f335 github.com/aws/aws-sdk-go v1.53.11 github.com/google/go-cmp v0.6.0 github.com/hashicorp/consul/api v1.29.1 @@ -38,6 +39,8 @@ require ( github.com/Showmax/go-fqdn v1.0.0 // indirect github.com/amazon-contributing/opentelemetry-collector-contrib/override/aws v0.0.0-20240415183253-230331014d2c // indirect github.com/armon/go-metrics v0.4.1 // indirect + github.com/aws/aws-sdk-go-v2 v1.22.2 // indirect + github.com/aws/smithy-go v1.16.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -168,3 +171,5 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sco replace github.com/openshift/api v3.9.0+incompatible => github.com/openshift/api v0.0.0-20180801171038-322a19404e37 replace github.com/amazon-contributing/opentelemetry-collector-contrib/override/aws => ../../override/aws + +replace github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware => ../../extension/awsmiddleware \ No newline at end of file diff --git a/processor/resourcedetectionprocessor/go.sum b/processor/resourcedetectionprocessor/go.sum index 55f884576027..b5ae315416c4 100644 --- a/processor/resourcedetectionprocessor/go.sum +++ b/processor/resourcedetectionprocessor/go.sum @@ -48,6 +48,9 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware v0.0.0-20240419190856-2f880467f335/go.mod h1:5JOe6ISApVHBIsZuLb8ppaY06ujDcHCxYJE5wCymNoI= +github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware v0.0.0-20241204155332-be45e31638de h1:GC8FheDVk0E2TYsJt9U/Qid68rWQ4bbRBcJxa/cQ5sM= +github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware v0.0.0-20241204155332-be45e31638de/go.mod h1:/RaNSxxO06niapGT00snMdgFfjjjW/kV3TZGX8kHuwM= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= @@ -57,6 +60,28 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.53.11 h1:KcmduYvX15rRqt4ZU/7jKkmDxU/G87LJ9MUI0yQJh00= github.com/aws/aws-sdk-go v1.53.11/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go-v2 v1.22.2 h1:lV0U8fnhAnPz8YcdmZVV60+tr6CakHzqA6P8T46ExJI= +github.com/aws/aws-sdk-go-v2 v1.22.2/go.mod h1:Kd0OJtkW3Q0M0lUWGszapWjEvrXDzRW+D21JNsroB+c= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 h1:OPLEkmhXf6xFPiz0bLeDArZIDx1NNS4oJyG4nv3Gct0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 h1:6lJvvkQ9HmbHZ4h/IEwclwv2mrTW8Uq1SOB/kXy0mfw= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4/go.mod h1:1PrKYwxTM+zjpw9Y41KFtoJCQrJ34Z47Y4VgVbfndjo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 h1:m0QTSI6pZYJTk5WSKx3fm5cNW/DCicVzULBgU/6IyD0= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14/go.mod h1:dDilntgHy9WnHXsh7dDtUPgHKEfTJIBUTHM8OWm0f/0= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 h1:eev2yZX7esGRjqRbnVk1UxMLw4CyVZDpZXRCcy75oQk= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36/go.mod h1:lGnOkH9NJATw0XEPcAknFBj3zzNTEGRHtSw+CwC1YTg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKitgIiLV1+MHobfR5Xg25iYnyzWZhyQuSlDI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 h1:v0jkRigbSD6uOdwcaUQmgEwG1BkPfAPDqaeNt/29ghg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4/go.mod h1:LhTyt8J04LL+9cIt7pYJ5lbS/U98ZmXovLOR/4LUsk8= +github.com/aws/aws-sdk-go-v2/service/s3 v1.40.0 h1:wl5dxN1NONhTDQD9uaEvNsDRX29cBmGED/nl0jkWlt4= +github.com/aws/aws-sdk-go-v2/service/s3 v1.40.0/go.mod h1:rDGMZA7f4pbmTtPOk5v5UM2lmX6UAbRnMDJeDvnH7AM= +github.com/aws/smithy-go v1.16.0 h1:gJZEH/Fqh+RsvlJ1Zt4tVAtV6bKkp3cC+R6FCZMNzik= +github.com/aws/smithy-go v1.16.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= diff --git a/processor/resourcedetectionprocessor/internal/aws/ec2/ec2.go b/processor/resourcedetectionprocessor/internal/aws/ec2/ec2.go index 21a2f6f02ded..696cdaee32cf 100644 --- a/processor/resourcedetectionprocessor/internal/aws/ec2/ec2.go +++ b/processor/resourcedetectionprocessor/internal/aws/ec2/ec2.go @@ -9,6 +9,8 @@ import ( "net/http" "regexp" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" @@ -122,6 +124,10 @@ func (d *Detector) Detect(ctx context.Context) (resource pcommon.Resource, schem return res, conventions.SchemaURL, nil } +func (d *Detector) ExposeHandlers() (handlers *request.Handlers) { + return d.metadataProvider.GetHandlers() +} + func getClientConfig(ctx context.Context, logger *zap.Logger) *http.Client { client, err := internal.ClientFromContext(ctx) if err != nil { diff --git a/processor/resourcedetectionprocessor/internal/resourcedetection.go b/processor/resourcedetectionprocessor/internal/resourcedetection.go index 21b5c7cfb392..4d3500026651 100644 --- a/processor/resourcedetectionprocessor/internal/resourcedetection.go +++ b/processor/resourcedetectionprocessor/internal/resourcedetection.go @@ -12,6 +12,10 @@ import ( "sync" "time" + "github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware" + "github.com/aws/aws-sdk-go/aws/request" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/processor" "go.uber.org/zap" @@ -23,6 +27,9 @@ type Detector interface { Detect(ctx context.Context) (resource pcommon.Resource, schemaURL string, err error) } +type HandlerProvider interface { + ExposeHandlers() *request.Handlers +} type DetectorConfig any type ResourceDetectorConfig interface { @@ -116,6 +123,14 @@ func (p *ResourceProvider) Get(ctx context.Context, client *http.Client) (resour return p.detectedResource.resource, p.detectedResource.schemaURL, p.detectedResource.err } +func (p *ResourceProvider) ConfigureHandlers(ctx context.Context, host component.Host, middlewareId component.ID) { + for _, detector := range p.detectors { + if handlerDetector, ok := detector.(HandlerProvider); ok { + awsmiddleware.TryConfigure(p.logger, host, middlewareId, awsmiddleware.SDKv1(handlerDetector.ExposeHandlers())) + } + } +} + func (p *ResourceProvider) detectResource(ctx context.Context) { p.detectedResource = &resourceResult{} diff --git a/processor/resourcedetectionprocessor/internal/resourcedetection_test.go b/processor/resourcedetectionprocessor/internal/resourcedetection_test.go index 9e17934f0eba..57907c97de27 100644 --- a/processor/resourcedetectionprocessor/internal/resourcedetection_test.go +++ b/processor/resourcedetectionprocessor/internal/resourcedetection_test.go @@ -7,6 +7,8 @@ import ( "context" "errors" "fmt" + "github.com/aws/aws-sdk-go/aws/request" + "go.opentelemetry.io/collector/component" "net/http" "sync" "testing" @@ -317,3 +319,100 @@ func TestFilterAttributes_NoAttributes(t *testing.T) { assert.Equal(t, len(droppedAttributes), 0) } + +// mockDetectorWithHandler is a mock detector that implements HandlerProvider +type mockDetectorWithHandler struct { + handlersCalled bool +} + +func (m *mockDetectorWithHandler) Detect(ctx context.Context) (resource pcommon.Resource, schemaURL string, err error) { + return pcommon.NewResource(), "", nil +} + +func (m *mockDetectorWithHandler) ExposeHandlers() *request.Handlers { + m.handlersCalled = true + return &request.Handlers{} +} + +// mockExtension implements component.Component +type mockExtension struct { + configured bool +} + +func (m *mockExtension) Start(context.Context, component.Host) error { + return nil +} + +func (m *mockExtension) Shutdown(context.Context) error { + return nil +} + +// mockHost implements component.Host +type mockHost struct { + extensions map[component.ID]component.Component +} + +// mockDetector is a basic detector that doesn't implement HandlerProvider +type mockDetector struct{} + +func (m *mockDetector) Detect(ctx context.Context) (resource pcommon.Resource, schemaURL string, err error) { + return pcommon.NewResource(), "", nil +} + +func newMockHost() component.Host { + return &mockHost{ + extensions: make(map[component.ID]component.Component), + } +} + +func (m *mockHost) GetExtension(id component.ID) (component.Component, error) { + if ext, ok := m.extensions[id]; ok { + return ext, nil + } + return nil, nil +} + +func (m *mockHost) ReportFatalError(err error) {} + +func (m *mockHost) GetFactory(kind component.Kind, componentType component.Type) component.Factory { + return nil +} + +func (m *mockHost) GetExtensions() map[component.ID]component.Component { + return m.extensions +} + +func (m *mockHost) GetExporters() map[component.DataType]map[component.ID]component.Component { + return nil +} + +func TestConfigureHandlers(t *testing.T) { + testType, _ := component.NewType("awsmiddleware") + mockDetector := &mockDetectorWithHandler{} + logger := zap.NewNop() + provider := NewResourceProvider(logger, 0, nil, mockDetector) + mockExt := &mockExtension{} + host := newMockHost() + host.(*mockHost).extensions[component.NewID(testType)] = mockExt + + middlewareID := component.NewID(testType) + ctx := context.Background() + provider.ConfigureHandlers(ctx, host, middlewareID) + + assert.True(t, mockDetector.handlersCalled, "ExposeHandlers should have been called") +} + +func TestConfigureHandlersWithNonHandlerDetector(t *testing.T) { + testType, _ := component.NewType("awsmiddleware") + basicDetector := &mockDetector{} + logger := zap.NewNop() + provider := NewResourceProvider(logger, 0, nil, basicDetector) + + mockExt := &mockExtension{} + host := newMockHost() + host.(*mockHost).extensions[component.NewID(testType)] = mockExt + middlewareID := component.NewID(testType) + + ctx := context.Background() + provider.ConfigureHandlers(ctx, host, middlewareID) +} diff --git a/processor/resourcedetectionprocessor/resourcedetection_processor.go b/processor/resourcedetectionprocessor/resourcedetection_processor.go index 44f3331e6473..03f7aa26c83c 100644 --- a/processor/resourcedetectionprocessor/resourcedetection_processor.go +++ b/processor/resourcedetectionprocessor/resourcedetection_processor.go @@ -17,6 +17,7 @@ import ( ) type resourceDetectionProcessor struct { + middlewareID *component.ID provider *internal.ResourceProvider resource pcommon.Resource schemaURL string @@ -30,6 +31,9 @@ func (rdp *resourceDetectionProcessor) Start(ctx context.Context, host component client, _ := rdp.httpClientSettings.ToClient(ctx, host, rdp.telemetrySettings) ctx = internal.ContextWithClient(ctx, client) var err error + if host != nil && rdp.middlewareID != nil{ + rdp.provider.ConfigureHandlers(ctx, host, *rdp.middlewareID) //configuring middleware in all clients of detectors + } rdp.resource, rdp.schemaURL, err = rdp.provider.Get(ctx, client) return err } diff --git a/receiver/awscontainerinsightreceiver/config.go b/receiver/awscontainerinsightreceiver/config.go index 45a3b5bb9baa..92ae143e6e56 100644 --- a/receiver/awscontainerinsightreceiver/config.go +++ b/receiver/awscontainerinsightreceiver/config.go @@ -6,6 +6,8 @@ package awscontainerinsightreceiver // import "github.com/open-telemetry/opentel import ( "time" + "go.opentelemetry.io/collector/component" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/awsutil" ) @@ -72,4 +74,8 @@ type Config struct { // RunOnSystemd is an optional attribute to run the receiver in an EC2 environment RunOnSystemd bool `mapstructure:"run_on_systemd,omitempty"` + + // MiddlewareID is an ID for an extension that can be used to configure the + // AWS client. + MiddlewareID *component.ID `mapstructure:"middleware,omitempty"` } diff --git a/receiver/awscontainerinsightreceiver/go.mod b/receiver/awscontainerinsightreceiver/go.mod index e1b08ef592e0..92bbe044aab7 100644 --- a/receiver/awscontainerinsightreceiver/go.mod +++ b/receiver/awscontainerinsightreceiver/go.mod @@ -4,6 +4,7 @@ go 1.22.5 require ( github.com/Microsoft/hcsshim v0.12.0-rc.3 + github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware v0.0.0-20240419190856-2f880467f335 github.com/amazon-contributing/opentelemetry-collector-contrib/override/aws v0.0.0-00010101000000-000000000000 github.com/aws/aws-sdk-go v1.53.11 github.com/go-kit/log v0.2.1 @@ -53,6 +54,8 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect github.com/armon/go-metrics v0.4.1 // indirect + github.com/aws/aws-sdk-go-v2 v1.22.2 // indirect + github.com/aws/smithy-go v1.16.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -272,3 +275,4 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/corei replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest => ../../pkg/pdatatest replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden => ../../pkg/golden +replace github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware => ../../extension/awsmiddleware \ No newline at end of file diff --git a/receiver/awscontainerinsightreceiver/go.sum b/receiver/awscontainerinsightreceiver/go.sum index df99a82adcd6..898a564d9cc4 100644 --- a/receiver/awscontainerinsightreceiver/go.sum +++ b/receiver/awscontainerinsightreceiver/go.sum @@ -77,6 +77,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware v0.0.0-20241204155332-be45e31638de h1:GC8FheDVk0E2TYsJt9U/Qid68rWQ4bbRBcJxa/cQ5sM= +github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware v0.0.0-20241204155332-be45e31638de/go.mod h1:/RaNSxxO06niapGT00snMdgFfjjjW/kV3TZGX8kHuwM= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= @@ -87,6 +89,28 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.53.11 h1:KcmduYvX15rRqt4ZU/7jKkmDxU/G87LJ9MUI0yQJh00= github.com/aws/aws-sdk-go v1.53.11/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go-v2 v1.22.2 h1:lV0U8fnhAnPz8YcdmZVV60+tr6CakHzqA6P8T46ExJI= +github.com/aws/aws-sdk-go-v2 v1.22.2/go.mod h1:Kd0OJtkW3Q0M0lUWGszapWjEvrXDzRW+D21JNsroB+c= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 h1:OPLEkmhXf6xFPiz0bLeDArZIDx1NNS4oJyG4nv3Gct0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 h1:6lJvvkQ9HmbHZ4h/IEwclwv2mrTW8Uq1SOB/kXy0mfw= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4/go.mod h1:1PrKYwxTM+zjpw9Y41KFtoJCQrJ34Z47Y4VgVbfndjo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 h1:m0QTSI6pZYJTk5WSKx3fm5cNW/DCicVzULBgU/6IyD0= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14/go.mod h1:dDilntgHy9WnHXsh7dDtUPgHKEfTJIBUTHM8OWm0f/0= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 h1:eev2yZX7esGRjqRbnVk1UxMLw4CyVZDpZXRCcy75oQk= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36/go.mod h1:lGnOkH9NJATw0XEPcAknFBj3zzNTEGRHtSw+CwC1YTg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKitgIiLV1+MHobfR5Xg25iYnyzWZhyQuSlDI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 h1:v0jkRigbSD6uOdwcaUQmgEwG1BkPfAPDqaeNt/29ghg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4/go.mod h1:LhTyt8J04LL+9cIt7pYJ5lbS/U98ZmXovLOR/4LUsk8= +github.com/aws/aws-sdk-go-v2/service/s3 v1.40.0 h1:wl5dxN1NONhTDQD9uaEvNsDRX29cBmGED/nl0jkWlt4= +github.com/aws/aws-sdk-go-v2/service/s3 v1.40.0/go.mod h1:rDGMZA7f4pbmTtPOk5v5UM2lmX6UAbRnMDJeDvnH7AM= +github.com/aws/smithy-go v1.16.0 h1:gJZEH/Fqh+RsvlJ1Zt4tVAtV6bKkp3cC+R6FCZMNzik= +github.com/aws/smithy-go v1.16.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3/go.mod h1:CIWtjkly68+yqLPbvwwR/fjNJA/idrtULjZWh2v1ys0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= diff --git a/receiver/awscontainerinsightreceiver/internal/host/ebsvolume.go b/receiver/awscontainerinsightreceiver/internal/host/ebsvolume.go index a40f14be95a0..23db89cb6af1 100644 --- a/receiver/awscontainerinsightreceiver/internal/host/ebsvolume.go +++ b/receiver/awscontainerinsightreceiver/internal/host/ebsvolume.go @@ -7,6 +7,7 @@ import ( "bufio" "context" "fmt" + "log" "os" "path/filepath" "regexp" @@ -15,6 +16,8 @@ import ( "sync" "time" + "github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/session" @@ -56,7 +59,7 @@ type ebsVolume struct { type ebsVolumeOption func(*ebsVolume) func newEBSVolume(ctx context.Context, session *session.Session, instanceID string, region string, - refreshInterval time.Duration, logger *zap.Logger, options ...ebsVolumeOption) ebsVolumeProvider { + refreshInterval time.Duration, logger *zap.Logger, configurer *awsmiddleware.Configurer, options ...ebsVolumeOption) ebsVolumeProvider { e := &ebsVolume{ dev2Vol: make(map[string]string), instanceID: instanceID, @@ -69,7 +72,12 @@ func newEBSVolume(ctx context.Context, session *session.Session, instanceID stri osLstat: os.Lstat, evalSymLinks: filepath.EvalSymlinks, } - + if configurer != nil { + err := configurer.Configure(awsmiddleware.SDKv1(&e.client.(*ec2.EC2).Handlers)) + if err != nil { + log.Println("There was a problem configuring middleware on ec2 client") + } + } for _, opt := range options { opt(e) } diff --git a/receiver/awscontainerinsightreceiver/internal/host/ebsvolume_test.go b/receiver/awscontainerinsightreceiver/internal/host/ebsvolume_test.go index 9b304c9ac3d5..78820e47a4a6 100644 --- a/receiver/awscontainerinsightreceiver/internal/host/ebsvolume_test.go +++ b/receiver/awscontainerinsightreceiver/internal/host/ebsvolume_test.go @@ -164,7 +164,7 @@ func TestEBSVolume(t *testing.T) { } } - e := newEBSVolume(ctx, sess, "instanceId", "us-west-2", time.Millisecond, zap.NewNop(), + e := newEBSVolume(ctx, sess, "instanceId", "us-west-2", time.Millisecond, zap.NewNop(), nil, clientOption, maxJitterOption, hostMountsOption, LstatOption, evalSymLinksOption) <-mockVolumeClient.success @@ -180,7 +180,7 @@ func TestEBSVolume(t *testing.T) { hostMountsOption = func(e *ebsVolume) { e.hostMounts = "/an-invalid-path" } - e = newEBSVolume(ctx, sess, "instanceId", "us-west-2", time.Millisecond, zap.NewNop(), + e = newEBSVolume(ctx, sess, "instanceId", "us-west-2", time.Millisecond, zap.NewNop(), nil, clientOption, maxJitterOption, hostMountsOption, LstatOption, evalSymLinksOption) ebsIDs = e.extractEbsIDsUsedByKubernetes() assert.Equal(t, 0, len(ebsIDs)) diff --git a/receiver/awscontainerinsightreceiver/internal/host/ec2metadata.go b/receiver/awscontainerinsightreceiver/internal/host/ec2metadata.go index 50548916bdad..7598ff707a15 100644 --- a/receiver/awscontainerinsightreceiver/internal/host/ec2metadata.go +++ b/receiver/awscontainerinsightreceiver/internal/host/ec2metadata.go @@ -5,8 +5,11 @@ package host // import "github.com/open-telemetry/opentelemetry-collector-contri import ( "context" + "log" "time" + "github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware" + override "github.com/amazon-contributing/opentelemetry-collector-contrib/override/aws" "github.com/aws/aws-sdk-go/aws" awsec2metadata "github.com/aws/aws-sdk-go/aws/ec2metadata" @@ -42,7 +45,7 @@ type ec2Metadata struct { type ec2MetadataOption func(*ec2Metadata) func newEC2Metadata(ctx context.Context, session *session.Session, refreshInterval time.Duration, - instanceIDReadyC chan bool, instanceIPReadyC chan bool, localMode bool, imdsRetries int, logger *zap.Logger, options ...ec2MetadataOption) ec2MetadataProvider { + instanceIDReadyC chan bool, instanceIPReadyC chan bool, localMode bool, imdsRetries int, logger *zap.Logger, configurer *awsmiddleware.Configurer, options ...ec2MetadataOption) ec2MetadataProvider { emd := &ec2Metadata{ client: awsec2metadata.New(session, &aws.Config{ Retryer: override.NewIMDSRetryer(imdsRetries), @@ -55,6 +58,12 @@ func newEC2Metadata(ctx context.Context, session *session.Session, refreshInterv localMode: localMode, logger: logger, } + if configurer != nil { + err := configurer.Configure(awsmiddleware.SDKv1(&emd.client.(*awsec2metadata.EC2Metadata).Handlers)) + if err != nil { + log.Println("There was a problem configuring middleware on ec2 client") + } + } for _, opt := range options { opt(emd) diff --git a/receiver/awscontainerinsightreceiver/internal/host/ec2metadata_test.go b/receiver/awscontainerinsightreceiver/internal/host/ec2metadata_test.go index 927c333b0676..f7d73f912f4c 100644 --- a/receiver/awscontainerinsightreceiver/internal/host/ec2metadata_test.go +++ b/receiver/awscontainerinsightreceiver/internal/host/ec2metadata_test.go @@ -42,7 +42,7 @@ func TestEC2Metadata(t *testing.T) { e.client = &mockMetadataClient{} e.clientFallbackEnable = &mockMetadataClient{} } - e := newEC2Metadata(ctx, sess, 3*time.Millisecond, instanceIDReadyC, instanceIPReadyP, false, 0, zap.NewNop(), clientOption) + e := newEC2Metadata(ctx, sess, 3*time.Millisecond, instanceIDReadyC, instanceIPReadyP, false, 0, zap.NewNop(), nil, clientOption) assert.NotNil(t, e) <-instanceIDReadyC diff --git a/receiver/awscontainerinsightreceiver/internal/host/ec2tags.go b/receiver/awscontainerinsightreceiver/internal/host/ec2tags.go index 8e95fc763760..dc1306f15780 100644 --- a/receiver/awscontainerinsightreceiver/internal/host/ec2tags.go +++ b/receiver/awscontainerinsightreceiver/internal/host/ec2tags.go @@ -5,9 +5,12 @@ package host // import "github.com/open-telemetry/opentelemetry-collector-contri import ( "context" + "log" "strings" "time" + "github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/session" @@ -48,7 +51,7 @@ type ec2Tags struct { type ec2TagsOption func(*ec2Tags) func newEC2Tags(ctx context.Context, session *session.Session, instanceID string, region string, containerOrchestrator string, - refreshInterval time.Duration, logger *zap.Logger, options ...ec2TagsOption) ec2TagsProvider { + refreshInterval time.Duration, logger *zap.Logger, configurer *awsmiddleware.Configurer, options ...ec2TagsOption) ec2TagsProvider { et := &ec2Tags{ instanceID: instanceID, client: ec2.New(session, aws.NewConfig().WithRegion(region)), @@ -57,6 +60,12 @@ func newEC2Tags(ctx context.Context, session *session.Session, instanceID string logger: logger, containerOrchestrator: containerOrchestrator, } + if configurer != nil { + err := configurer.Configure(awsmiddleware.SDKv1(&et.client.(*ec2.EC2).Handlers)) + if err != nil { + log.Println("There was a problem configuring middleware on ec2 client") + } + } for _, opt := range options { opt(et) diff --git a/receiver/awscontainerinsightreceiver/internal/host/ec2tags_test.go b/receiver/awscontainerinsightreceiver/internal/host/ec2tags_test.go index 3dc65e766f62..25b67444b1d1 100644 --- a/receiver/awscontainerinsightreceiver/internal/host/ec2tags_test.go +++ b/receiver/awscontainerinsightreceiver/internal/host/ec2tags_test.go @@ -76,7 +76,7 @@ func TestEC2TagsForEKS(t *testing.T) { isSucessOption := func(e *ec2Tags) { e.isSucess = make(chan bool) } - et := newEC2Tags(ctx, sess, "instanceId", "us-west-2", ci.EKS, time.Millisecond, zap.NewNop(), clientOption, + et := newEC2Tags(ctx, sess, "instanceId", "us-west-2", ci.EKS, time.Millisecond, zap.NewNop(), nil, clientOption, maxJitterOption, isSucessOption) // wait for ec2 tags are fetched @@ -105,7 +105,7 @@ func TestEC2TagsForECS(t *testing.T) { isSucessOption := func(e *ec2Tags) { e.isSucess = make(chan bool) } - et := newEC2Tags(ctx, sess, "instanceId", "us-west-2", ci.ECS, time.Millisecond, zap.NewNop(), clientOption, + et := newEC2Tags(ctx, sess, "instanceId", "us-west-2", ci.ECS, time.Millisecond, zap.NewNop(), nil, clientOption, maxJitterOption, isSucessOption) // wait for ec2 tags are fetched diff --git a/receiver/awscontainerinsightreceiver/internal/host/hostinfo.go b/receiver/awscontainerinsightreceiver/internal/host/hostinfo.go index 51c9e1668f65..dd8f94823ca8 100644 --- a/receiver/awscontainerinsightreceiver/internal/host/hostinfo.go +++ b/receiver/awscontainerinsightreceiver/internal/host/hostinfo.go @@ -8,6 +8,7 @@ import ( "fmt" "time" + "github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "go.uber.org/zap" @@ -63,8 +64,12 @@ func WithSystemdEnabled(enabled bool) Option { } } +func withConfigurer[T any](configurer *awsmiddleware.Configurer, creator func(configurer *awsmiddleware.Configurer) T) T { + return creator(configurer) +} + // NewInfo creates a new Info struct -func NewInfo(awsSessionSettings awsutil.AWSSessionSettings, containerOrchestrator string, refreshInterval time.Duration, logger *zap.Logger, options ...Option) (*Info, error) { +func NewInfo(awsSessionSettings awsutil.AWSSessionSettings, containerOrchestrator string, refreshInterval time.Duration, logger *zap.Logger, configurer *awsmiddleware.Configurer, options ...Option) (*Info, error) { ctx, cancel := context.WithCancel(context.Background()) mInfo := &Info{ cancel: cancel, @@ -76,13 +81,11 @@ func NewInfo(awsSessionSettings awsutil.AWSSessionSettings, containerOrchestrato containerOrchestrator: containerOrchestrator, awsSessionCreator: awsutil.GetAWSConfigSession, nodeCapacityCreator: newNodeCapacity, - ec2MetadataCreator: newEC2Metadata, - ebsVolumeCreator: newEBSVolume, - ec2TagsCreator: newEC2Tags, - - // used in test only - ebsVolumeReadyC: make(chan bool), - ec2TagsReadyC: make(chan bool), + ec2MetadataCreator: createEC2MetadataCreator(configurer), + ebsVolumeCreator: createEBSVolumeCreator(configurer), + ec2TagsCreator: createEC2TagsCreator(configurer), + ebsVolumeReadyC: make(chan bool), + ec2TagsReadyC: make(chan bool), } for _, opt := range options { @@ -108,6 +111,69 @@ func NewInfo(awsSessionSettings awsutil.AWSSessionSettings, containerOrchestrato return mInfo, nil } +// createEC2MetadataCreator returns a function that creates an EC2 metadata provider. +// It uses the provided configurer to set up AWS middleware for the EC2 metadata client. +// +// The returned function is a factory that, when called, creates an EC2 metadata provider +// with the following capabilities: +// - Fetches EC2 instance metadata +// - Refreshes metadata at specified intervals +// - Notifies when instance ID and IP are ready via channels +// - Supports local mode and IMDS retries +// - Configures logging +// - Applies additional options for customization +// +// This layered approach allows for flexible configuration and dependency injection, +// making it easier to customize behavior and improve testability. +func createEC2MetadataCreator(configurer *awsmiddleware.Configurer) func(context.Context, *session.Session, time.Duration, chan bool, chan bool, bool, int, *zap.Logger, ...ec2MetadataOption) ec2MetadataProvider { + return withConfigurer(configurer, func(c *awsmiddleware.Configurer) func(context.Context, *session.Session, time.Duration, chan bool, chan bool, bool, int, *zap.Logger, ...ec2MetadataOption) ec2MetadataProvider { + return func(ctx context.Context, session *session.Session, refreshInterval time.Duration, instanceIDReadyC, instanceIPReadyC chan bool, localMode bool, imdsRetries int, logger *zap.Logger, options ...ec2MetadataOption) ec2MetadataProvider { + return newEC2Metadata(ctx, session, refreshInterval, instanceIDReadyC, instanceIPReadyC, localMode, imdsRetries, logger, c, options...) + } + }) +} + +// createEBSVolumeCreator returns a function that creates an EBS volume provider. +// It uses the provided configurer to set up AWS middleware for the EBS volume client. +// +// The returned function is a factory that, when called, creates an EBS volume provider +// with the following capabilities: +// - Fetches EBS volume information for a specific EC2 instance +// - Refreshes volume information at specified intervals +// - Configures logging +// - Applies additional options for customization +// +// This approach allows for flexible configuration of the EBS volume provider, +// enabling easier testing and customization of behavior. +func createEBSVolumeCreator(configurer *awsmiddleware.Configurer) func(context.Context, *session.Session, string, string, time.Duration, *zap.Logger, ...ebsVolumeOption) ebsVolumeProvider { + return withConfigurer(configurer, func(c *awsmiddleware.Configurer) func(context.Context, *session.Session, string, string, time.Duration, *zap.Logger, ...ebsVolumeOption) ebsVolumeProvider { + return func(ctx context.Context, session *session.Session, instanceID, region string, refreshInterval time.Duration, logger *zap.Logger, options ...ebsVolumeOption) ebsVolumeProvider { + return newEBSVolume(ctx, session, instanceID, region, refreshInterval, logger, c, options...) + } + }) +} + +// createEC2TagsCreator returns a function that creates an EC2 tags provider. +// It uses the provided configurer to set up AWS middleware for the EC2 tags client. +// +// The returned function is a factory that, when called, creates an EC2 tags provider +// with the following capabilities: +// - Fetches EC2 instance tags +// - Refreshes tag information at specified intervals +// - Supports container orchestrator-specific tag handling +// - Configures logging +// - Applies additional options for customization +// +// This design allows for flexible configuration of the EC2 tags provider, +// facilitating easier testing and customization of tag retrieval and processing. +func createEC2TagsCreator(configurer *awsmiddleware.Configurer) func(context.Context, *session.Session, string, string, string, time.Duration, *zap.Logger, ...ec2TagsOption) ec2TagsProvider { + return withConfigurer(configurer, func(c *awsmiddleware.Configurer) func(context.Context, *session.Session, string, string, string, time.Duration, *zap.Logger, ...ec2TagsOption) ec2TagsProvider { + return func(ctx context.Context, session *session.Session, instanceID, region, containerOrchestrator string, refreshInterval time.Duration, logger *zap.Logger, options ...ec2TagsOption) ec2TagsProvider { + return newEC2Tags(ctx, session, instanceID, region, containerOrchestrator, refreshInterval, logger, c, options...) + } + }) +} + func (m *Info) lazyInitEBSVolume(ctx context.Context) { // wait until the instance id is ready <-m.instanceIDReadyC diff --git a/receiver/awscontainerinsightreceiver/internal/host/hostinfo_test.go b/receiver/awscontainerinsightreceiver/internal/host/hostinfo_test.go index b37f1bdc98d1..cfe3d1a3766d 100644 --- a/receiver/awscontainerinsightreceiver/internal/host/hostinfo_test.go +++ b/receiver/awscontainerinsightreceiver/internal/host/hostinfo_test.go @@ -77,7 +77,7 @@ func TestInfo(t *testing.T) { return nil, errors.New("error") } } - m, err := NewInfo(awsutil.CreateDefaultSessionConfig(), ci.EKS, time.Minute, zap.NewNop(), nodeCapacityCreatorOpt) + m, err := NewInfo(awsutil.CreateDefaultSessionConfig(), ci.EKS, time.Minute, zap.NewNop(), nil, nodeCapacityCreatorOpt) assert.Nil(t, m) assert.Error(t, err) @@ -92,7 +92,7 @@ func TestInfo(t *testing.T) { return nil, nil, errors.New("error") } } - m, err = NewInfo(awsutil.CreateDefaultSessionConfig(), ci.EKS, time.Minute, zap.NewNop(), nodeCapacityCreatorOpt, awsSessionCreatorOpt) + m, err = NewInfo(awsutil.CreateDefaultSessionConfig(), ci.EKS, time.Minute, zap.NewNop(), nil, nodeCapacityCreatorOpt, awsSessionCreatorOpt) assert.Nil(t, m) assert.Error(t, err) @@ -120,7 +120,7 @@ func TestInfo(t *testing.T) { return &mockEC2Tags{} } } - m, err = NewInfo(awsutil.CreateDefaultSessionConfig(), ci.EKS, time.Minute, zap.NewNop(), awsSessionCreatorOpt, + m, err = NewInfo(awsutil.CreateDefaultSessionConfig(), ci.EKS, time.Minute, zap.NewNop(), nil, awsSessionCreatorOpt, nodeCapacityCreatorOpt, ec2MetadataCreatorOpt, ebsVolumeCreatorOpt, ec2TagsCreatorOpt) assert.NoError(t, err) assert.NotNil(t, m) @@ -144,7 +144,7 @@ func TestInfo(t *testing.T) { assert.Equal(t, "asg", m.GetAutoScalingGroupName()) // Test with cluster name override - m, err = NewInfo(awsutil.CreateDefaultSessionConfig(), ci.EKS, time.Minute, zap.NewNop(), awsSessionCreatorOpt, + m, err = NewInfo(awsutil.CreateDefaultSessionConfig(), ci.EKS, time.Minute, zap.NewNop(), nil, awsSessionCreatorOpt, nodeCapacityCreatorOpt, ec2MetadataCreatorOpt, ebsVolumeCreatorOpt, ec2TagsCreatorOpt, WithClusterName("override-cluster")) assert.NoError(t, err) assert.NotNil(t, m) @@ -159,7 +159,7 @@ func TestInfoForECS(t *testing.T) { return nil, errors.New("error") } } - m, err := NewInfo(awsutil.CreateDefaultSessionConfig(), ci.ECS, time.Minute, zap.NewNop(), nodeCapacityCreatorOpt) + m, err := NewInfo(awsutil.CreateDefaultSessionConfig(), ci.ECS, time.Minute, zap.NewNop(), nil, nodeCapacityCreatorOpt) assert.Nil(t, m) assert.Error(t, err) @@ -174,7 +174,7 @@ func TestInfoForECS(t *testing.T) { return nil, nil, errors.New("error") } } - m, err = NewInfo(awsutil.CreateDefaultSessionConfig(), ci.ECS, time.Minute, zap.NewNop(), nodeCapacityCreatorOpt, awsSessionCreatorOpt) + m, err = NewInfo(awsutil.CreateDefaultSessionConfig(), ci.ECS, time.Minute, zap.NewNop(), nil, nodeCapacityCreatorOpt, awsSessionCreatorOpt) assert.Nil(t, m) assert.Error(t, err) @@ -202,7 +202,7 @@ func TestInfoForECS(t *testing.T) { return &mockEC2Tags{} } } - m, err = NewInfo(awsutil.CreateDefaultSessionConfig(), ci.ECS, time.Minute, zap.NewNop(), awsSessionCreatorOpt, + m, err = NewInfo(awsutil.CreateDefaultSessionConfig(), ci.ECS, time.Minute, zap.NewNop(), nil, awsSessionCreatorOpt, nodeCapacityCreatorOpt, ec2MetadataCreatorOpt, ebsVolumeCreatorOpt, ec2TagsCreatorOpt) assert.NoError(t, err) assert.NotNil(t, m) diff --git a/receiver/awscontainerinsightreceiver/receiver.go b/receiver/awscontainerinsightreceiver/receiver.go index d9ba52430d8d..e7702282f847 100644 --- a/receiver/awscontainerinsightreceiver/receiver.go +++ b/receiver/awscontainerinsightreceiver/receiver.go @@ -11,6 +11,8 @@ import ( "runtime" "time" + "github.com/amazon-contributing/opentelemetry-collector-contrib/extension/awsmiddleware" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/pdata/pmetric" @@ -78,8 +80,13 @@ func newAWSContainerInsightReceiver( // Start collecting metrics from cadvisor and k8s api server (if it is an elected leader) func (acir *awsContainerInsightReceiver) Start(ctx context.Context, host component.Host) error { ctx, acir.cancel = context.WithCancel(ctx) + var configurer *awsmiddleware.Configurer + if acir.config != nil && acir.config.MiddlewareID != nil { + configurer, _ = awsmiddleware.GetConfigurer(host.GetExtensions(), *acir.config.MiddlewareID) + } + hostInfo, hostInfoErr := hostinfo.NewInfo(acir.config.AWSSessionSettings, acir.config.ContainerOrchestrator, - acir.config.CollectionInterval, acir.settings.Logger, hostinfo.WithClusterName(acir.config.ClusterName), + acir.config.CollectionInterval, acir.settings.Logger, configurer, hostinfo.WithClusterName(acir.config.ClusterName), hostinfo.WithSystemdEnabled(acir.config.RunOnSystemd)) if hostInfoErr != nil { return hostInfoErr diff --git a/receiver/awscontainerinsightreceiver/receiver_test.go b/receiver/awscontainerinsightreceiver/receiver_test.go index 8eed8d7b625a..c58f480b805a 100644 --- a/receiver/awscontainerinsightreceiver/receiver_test.go +++ b/receiver/awscontainerinsightreceiver/receiver_test.go @@ -6,6 +6,9 @@ package awscontainerinsightreceiver import ( "context" "errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "go.opentelemetry.io/collector/component" "testing" "github.com/stretchr/testify/require" @@ -158,3 +161,60 @@ func TestCollectDataWithSystemd(t *testing.T) { err = r.collectData(ctx) require.Nil(t, err) } + +// MockHost is a mock implementation of component.Host +type MockHost struct { + mock.Mock +} + +func (m *MockHost) GetExtensions() map[component.ID]component.Component { + args := m.Called() + return args.Get(0).(map[component.ID]component.Component) +} + +// MockConfigurer is a mock implementation of awsmiddleware.Configurer +type MockConfigurer struct { + mock.Mock +} + +func (m *MockConfigurer) Start(context.Context, component.Host) error { + return nil +} + +func (m *MockConfigurer) Shutdown(context.Context) error { + return nil +} + +func (m *MockHost) GetFactory(kind component.Kind, componentType component.Type) component.Factory { + return nil +} + +func TestAWSContainerInsightReceiverStart(t *testing.T) { + // Create a mock host + mockHost := new(MockHost) + testType, _ := component.NewType("awsmiddleware") + + // Create a mock configurer + mockConfigurer := new(MockConfigurer) + agenthealth, _ := component.NewType("agenthealth") + // Set up the mock host to return a map with the mock configurer + mockHost.On("GetExtensions").Return(map[component.ID]component.Component{ + component.NewID(testType): mockConfigurer, + }) + + statusCodeID := component.NewIDWithName(agenthealth, "statuscode") + + // Create a receiver instance + config := &Config{ + CollectionInterval: 60, + ContainerOrchestrator: "eks", + MiddlewareID: &statusCodeID, + } + consumer := consumertest.NewNop() + receiver, err := newAWSContainerInsightReceiver(component.TelemetrySettings{}, config, consumer) + assert.NoError(t, err) + err = receiver.Start(context.Background(), mockHost) + assert.Error(t, err) + + mockHost.AssertCalled(t, "GetExtensions") +}