From 1e21727a34d82f9d93e29fc0a80ebeabbbcc34b5 Mon Sep 17 00:00:00 2001 From: Jay Camp Date: Thu, 18 Mar 2021 23:37:54 -0400 Subject: [PATCH 1/4] [processor/resourcedetection] Add GKE detector This adds an gke detector for GKE. It sets cloud.provider, cloud.infrastructure_service, and k8s.cluster.name. It's intended to be used in conjunction with gce detector. The gke detector should come first so that the more specific cloud.infrastructure_service value wins (see README.md). Note that this code is taken from https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/detectors/gcp. There is a goal to prevent duplication with go-contrib in #1590 and I started down that path but it will require more time than currently available as it needs to transform from different data models, deal with any differences in metadata between existing detectors, etc. --- .../resourcedetectionprocessor/factory.go | 10 +- .../internal/gcp/gce/gce.go | 5 +- .../internal/gcp/gce/gce_test.go | 46 +------ .../internal/gcp/gke/gke.go | 70 +++++++++++ .../internal/gcp/gke/gke_test.go | 119 ++++++++++++++++++ .../internal/gcp/{gce => }/metadata.go | 29 +++-- .../internal/gcp/{gce => }/metadata_test.go | 7 +- .../internal/gcp/mockmetadata.go | 64 ++++++++++ 8 files changed, 288 insertions(+), 62 deletions(-) create mode 100644 processor/resourcedetectionprocessor/internal/gcp/gke/gke.go create mode 100644 processor/resourcedetectionprocessor/internal/gcp/gke/gke_test.go rename processor/resourcedetectionprocessor/internal/gcp/{gce => }/metadata.go (59%) rename processor/resourcedetectionprocessor/internal/gcp/{gce => }/metadata_test.go (85%) create mode 100644 processor/resourcedetectionprocessor/internal/gcp/mockmetadata.go diff --git a/processor/resourcedetectionprocessor/factory.go b/processor/resourcedetectionprocessor/factory.go index c648f8db8b7a..33924f6d7f8e 100644 --- a/processor/resourcedetectionprocessor/factory.go +++ b/processor/resourcedetectionprocessor/factory.go @@ -32,6 +32,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/azure" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/env" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/gcp/gce" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/gcp/gke" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/system" ) @@ -54,13 +55,14 @@ type factory struct { // NewFactory creates a new factory for ResourceDetection processor. func NewFactory() component.ProcessorFactory { resourceProviderFactory := internal.NewProviderFactory(map[internal.DetectorType]internal.DetectorFactory{ - env.TypeStr: env.NewDetector, - system.TypeStr: system.NewDetector, - gce.TypeStr: gce.NewDetector, + azure.TypeStr: azure.NewDetector, ec2.TypeStr: ec2.NewDetector, ecs.TypeStr: ecs.NewDetector, elasticbeanstalk.TypeStr: elasticbeanstalk.NewDetector, - azure.TypeStr: azure.NewDetector, + env.TypeStr: env.NewDetector, + gce.TypeStr: gce.NewDetector, + gke.TypeStr: gke.NewDetector, + system.TypeStr: system.NewDetector, }) f := &factory{ diff --git a/processor/resourcedetectionprocessor/internal/gcp/gce/gce.go b/processor/resourcedetectionprocessor/internal/gcp/gce/gce.go index 650702d713ba..eed47b415a95 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gce/gce.go +++ b/processor/resourcedetectionprocessor/internal/gcp/gce/gce.go @@ -25,6 +25,7 @@ import ( "go.opentelemetry.io/collector/translator/conventions" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/gcp" ) const ( @@ -34,11 +35,11 @@ const ( var _ internal.Detector = (*Detector)(nil) type Detector struct { - metadata gceMetadata + metadata gcp.Metadata } func NewDetector(component.ProcessorCreateParams, internal.DetectorConfig) (internal.Detector, error) { - return &Detector{metadata: &gceMetadataImpl{}}, nil + return &Detector{metadata: &gcp.MetadataImpl{}}, nil } func (d *Detector) Detect(context.Context) (pdata.Resource, error) { diff --git a/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go b/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go index d12cb6e9d190..72905df0f2b7 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go +++ b/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go @@ -20,53 +20,15 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/translator/conventions" "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/gcp" ) -type mockMetadata struct { - mock.Mock -} - -func (m *mockMetadata) OnGCE() bool { - return m.MethodCalled("OnGCE").Bool(0) -} - -func (m *mockMetadata) ProjectID() (string, error) { - args := m.MethodCalled("ProjectID") - return args.String(0), args.Error(1) -} - -func (m *mockMetadata) Zone() (string, error) { - args := m.MethodCalled("Zone") - return args.String(0), args.Error(1) -} - -func (m *mockMetadata) Hostname() (string, error) { - args := m.MethodCalled("Hostname") - return args.String(0), args.Error(1) -} - -func (m *mockMetadata) InstanceID() (string, error) { - args := m.MethodCalled("InstanceID") - return args.String(0), args.Error(1) -} - -func (m *mockMetadata) InstanceName() (string, error) { - args := m.MethodCalled("InstanceName") - return args.String(0), args.Error(1) -} - -func (m *mockMetadata) Get(suffix string) (string, error) { - args := m.MethodCalled("Get") - return args.String(0), args.Error(1) -} - func TestNewDetector(t *testing.T) { d, err := NewDetector(component.ProcessorCreateParams{Logger: zap.NewNop()}, nil) assert.NotNil(t, d) @@ -74,7 +36,7 @@ func TestNewDetector(t *testing.T) { } func TestDetectTrue(t *testing.T) { - md := &mockMetadata{} + md := &gcp.MockMetadata{} md.On("OnGCE").Return(true) md.On("ProjectID").Return("1", nil) md.On("Zone").Return("zone", nil) @@ -105,7 +67,7 @@ func TestDetectTrue(t *testing.T) { } func TestDetectFalse(t *testing.T) { - md := &mockMetadata{} + md := &gcp.MockMetadata{} md.On("OnGCE").Return(false) detector := &Detector{metadata: md} @@ -116,7 +78,7 @@ func TestDetectFalse(t *testing.T) { } func TestDetectError(t *testing.T) { - md := &mockMetadata{} + md := &gcp.MockMetadata{} md.On("OnGCE").Return(true) md.On("ProjectID").Return("", errors.New("err1")) md.On("Zone").Return("", errors.New("err2")) diff --git a/processor/resourcedetectionprocessor/internal/gcp/gke/gke.go b/processor/resourcedetectionprocessor/internal/gcp/gke/gke.go new file mode 100644 index 000000000000..6bbf6e854719 --- /dev/null +++ b/processor/resourcedetectionprocessor/internal/gcp/gke/gke.go @@ -0,0 +1,70 @@ +// Copyright The OpenTelemetry 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 gke + +import ( + "context" + "os" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer/pdata" + "go.opentelemetry.io/collector/translator/conventions" + "go.uber.org/zap" + + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/gcp" +) + +// TypeStr is type of detector. +const TypeStr = "gke" + +var _ internal.Detector = (*Detector)(nil) + +type Detector struct { + log *zap.Logger + metadata gcp.Metadata +} + +func NewDetector(params component.ProcessorCreateParams, _ internal.DetectorConfig) (internal.Detector, error) { + return &Detector{log: params.Logger, metadata: &gcp.MetadataImpl{}}, nil +} + +// Detect detects associated resources when running in GKE environment. +func (gke *Detector) Detect(ctx context.Context) (pdata.Resource, error) { + res := pdata.NewResource() + + // Check if on GCP. + if !gke.metadata.OnGCE() { + return res, nil + } + + attr := res.Attributes() + attr.InsertString(conventions.AttributeCloudProvider, conventions.AttributeCloudProviderGCP) + + // Check if running on k8s. + if os.Getenv("KUBERNETES_SERVICE_HOST") == "" { + return res, nil + } + + attr.InsertString(conventions.AttributeCloudInfrastructureService, conventions.AttributeCloudProviderGCPGKE) + + if clusterName, err := gke.metadata.InstanceAttributeValue("cluster-name"); err != nil { + gke.log.Warn("Unable to determine GKE cluster name", zap.Error(err)) + } else if clusterName != "" { + attr.InsertString(conventions.AttributeK8sCluster, clusterName) + } + + return res, nil +} diff --git a/processor/resourcedetectionprocessor/internal/gcp/gke/gke_test.go b/processor/resourcedetectionprocessor/internal/gcp/gke/gke_test.go new file mode 100644 index 000000000000..3757dd2e0f1a --- /dev/null +++ b/processor/resourcedetectionprocessor/internal/gcp/gke/gke_test.go @@ -0,0 +1,119 @@ +// Copyright The OpenTelemetry 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 gke + +import ( + "context" + "errors" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component" + "go.uber.org/zap" + + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/gcp" +) + +func TestNotGCE(t *testing.T) { + metadata := &gcp.MockMetadata{} + detector := &Detector{ + log: zap.NewNop(), + metadata: metadata, + } + + metadata.On("OnGCE").Return(false) + res, err := detector.Detect(context.Background()) + require.NoError(t, err) + assert.Equal(t, 0, res.Attributes().Len()) + + metadata.AssertExpectations(t) +} + +func TestDetectWithoutCluster(t *testing.T) { + metadata := &gcp.MockMetadata{} + detector := &Detector{ + log: zap.NewNop(), + metadata: metadata, + } + + metadata.On("OnGCE").Return(true) + metadata.On("InstanceAttributeValue", "cluster-name").Return("", errors.New("no cluster")) + + require.NoError(t, os.Setenv("KUBERNETES_SERVICE_HOST", "localhost")) + + res, err := detector.Detect(context.Background()) + require.NoError(t, err) + + assert.Equal(t, map[string]interface{}{ + "cloud.provider": "gcp", + "cloud.infrastructure_service": "gcp_gke", + }, internal.AttributesToMap(res.Attributes())) + + metadata.AssertExpectations(t) +} + +func TestDetectWithoutK8s(t *testing.T) { + metadata := &gcp.MockMetadata{} + detector := &Detector{ + log: zap.NewNop(), + metadata: metadata, + } + + metadata.On("OnGCE").Return(true) + + require.NoError(t, os.Unsetenv("KUBERNETES_SERVICE_HOST")) + + res, err := detector.Detect(context.Background()) + require.NoError(t, err) + + assert.Equal(t, map[string]interface{}{ + "cloud.provider": "gcp", + }, internal.AttributesToMap(res.Attributes())) + + metadata.AssertExpectations(t) +} + +func TestDetector_Detect(t *testing.T) { + metadata := &gcp.MockMetadata{} + detector := &Detector{ + log: zap.NewNop(), + metadata: metadata, + } + + metadata.On("OnGCE").Return(true) + metadata.On("InstanceAttributeValue", "cluster-name").Return("cluster-a", nil) + + require.NoError(t, os.Setenv("KUBERNETES_SERVICE_HOST", "localhost")) + + res, err := detector.Detect(context.Background()) + require.NoError(t, err) + + assert.Equal(t, map[string]interface{}{ + "cloud.provider": "gcp", + "cloud.infrastructure_service": "gcp_gke", + "k8s.cluster.name": "cluster-a", + }, internal.AttributesToMap(res.Attributes())) + + metadata.AssertExpectations(t) +} + +func TestNewDetector(t *testing.T) { + detector, err := NewDetector(component.ProcessorCreateParams{Logger: zap.NewNop()}, nil) + assert.NoError(t, err) + assert.NotNil(t, detector) +} diff --git a/processor/resourcedetectionprocessor/internal/gcp/gce/metadata.go b/processor/resourcedetectionprocessor/internal/gcp/metadata.go similarity index 59% rename from processor/resourcedetectionprocessor/internal/gcp/gce/metadata.go rename to processor/resourcedetectionprocessor/internal/gcp/metadata.go index be5198615eef..807cf4a399d5 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gce/metadata.go +++ b/processor/resourcedetectionprocessor/internal/gcp/metadata.go @@ -4,7 +4,7 @@ // 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 +// 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, @@ -12,46 +12,53 @@ // See the License for the specific language governing permissions and // limitations under the License. -package gce +package gcp import "cloud.google.com/go/compute/metadata" -type gceMetadata interface { +type Metadata interface { OnGCE() bool ProjectID() (string, error) Zone() (string, error) Hostname() (string, error) + InstanceAttributeValue(attr string) (string, error) InstanceID() (string, error) InstanceName() (string, error) Get(suffix string) (string, error) } -type gceMetadataImpl struct{} +type MetadataImpl struct{} -func (m *gceMetadataImpl) OnGCE() bool { +var _ Metadata = (*MetadataImpl)(nil) + +func (m *MetadataImpl) OnGCE() bool { return metadata.OnGCE() } -func (m *gceMetadataImpl) ProjectID() (string, error) { +func (m *MetadataImpl) ProjectID() (string, error) { return metadata.ProjectID() } -func (m *gceMetadataImpl) Zone() (string, error) { +func (m *MetadataImpl) Zone() (string, error) { return metadata.Zone() } -func (m *gceMetadataImpl) Hostname() (string, error) { +func (m *MetadataImpl) Hostname() (string, error) { return metadata.Hostname() } -func (m *gceMetadataImpl) InstanceID() (string, error) { +func (m *MetadataImpl) InstanceAttributeValue(attr string) (string, error) { + return metadata.InstanceAttributeValue(attr) +} + +func (m *MetadataImpl) InstanceID() (string, error) { return metadata.InstanceID() } -func (m *gceMetadataImpl) InstanceName() (string, error) { +func (m *MetadataImpl) InstanceName() (string, error) { return metadata.InstanceName() } -func (m *gceMetadataImpl) Get(suffix string) (string, error) { +func (m *MetadataImpl) Get(suffix string) (string, error) { return metadata.Get(suffix) } diff --git a/processor/resourcedetectionprocessor/internal/gcp/gce/metadata_test.go b/processor/resourcedetectionprocessor/internal/gcp/metadata_test.go similarity index 85% rename from processor/resourcedetectionprocessor/internal/gcp/gce/metadata_test.go rename to processor/resourcedetectionprocessor/internal/gcp/metadata_test.go index fb7660288c5f..efc02ff6da59 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gce/metadata_test.go +++ b/processor/resourcedetectionprocessor/internal/gcp/metadata_test.go @@ -4,7 +4,7 @@ // 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 +// 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, @@ -12,18 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package gce +package gcp import ( "testing" ) func TestGCEMetadata(t *testing.T) { - metadata := &gceMetadataImpl{} + metadata := &MetadataImpl{} metadata.OnGCE() metadata.ProjectID() metadata.Zone() metadata.Hostname() + metadata.InstanceAttributeValue("") metadata.InstanceID() metadata.InstanceName() metadata.Get("") diff --git a/processor/resourcedetectionprocessor/internal/gcp/mockmetadata.go b/processor/resourcedetectionprocessor/internal/gcp/mockmetadata.go new file mode 100644 index 000000000000..22ea0a715772 --- /dev/null +++ b/processor/resourcedetectionprocessor/internal/gcp/mockmetadata.go @@ -0,0 +1,64 @@ +// Copyright The OpenTelemetry 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 gcp + +import ( + "github.com/stretchr/testify/mock" +) + +var _ Metadata = (*MockMetadata)(nil) + +type MockMetadata struct { + mock.Mock +} + +func (m *MockMetadata) OnGCE() bool { + return m.MethodCalled("OnGCE").Bool(0) +} + +func (m *MockMetadata) ProjectID() (string, error) { + args := m.MethodCalled("ProjectID") + return args.String(0), args.Error(1) +} + +func (m *MockMetadata) Zone() (string, error) { + args := m.MethodCalled("Zone") + return args.String(0), args.Error(1) +} + +func (m *MockMetadata) Hostname() (string, error) { + args := m.MethodCalled("Hostname") + return args.String(0), args.Error(1) +} + +func (m *MockMetadata) InstanceAttributeValue(attr string) (string, error) { + args := m.MethodCalled("InstanceAttributeValue", attr) + return args.String(0), args.Error(1) +} + +func (m *MockMetadata) InstanceID() (string, error) { + args := m.MethodCalled("InstanceID") + return args.String(0), args.Error(1) +} + +func (m *MockMetadata) InstanceName() (string, error) { + args := m.MethodCalled("InstanceName") + return args.String(0), args.Error(1) +} + +func (m *MockMetadata) Get(suffix string) (string, error) { + args := m.MethodCalled("Get") + return args.String(0), args.Error(1) +} From b6e37307e5d780bf55c5c526bd69e3f928bd4d7e Mon Sep 17 00:00:00 2001 From: Jay Camp Date: Mon, 22 Mar 2021 16:51:56 -0400 Subject: [PATCH 2/4] add coverage for gce mock --- .../resourcedetectionprocessor/README.md | 8 +++- .../internal/gcp/gce/gce_test.go | 2 +- .../internal/gcp/mockmetadata.go | 2 +- .../internal/gcp/mockmetadata_test.go | 42 +++++++++++++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 processor/resourcedetectionprocessor/internal/gcp/mockmetadata_test.go diff --git a/processor/resourcedetectionprocessor/README.md b/processor/resourcedetectionprocessor/README.md index e03ed223bbf1..2bd0a626e501 100644 --- a/processor/resourcedetectionprocessor/README.md +++ b/processor/resourcedetectionprocessor/README.md @@ -29,6 +29,12 @@ to read resource information from the [GCE metadata server](https://cloud.google * host.image.id * host.type +* GKE: Google Kubernetes Engine + + * cloud.provider ("gcp") + * cloud.infrastructure_service ("gcp_gke") + * k8s.cluster.name (name of the GKE cluster) + * AWS EC2: Uses [AWS SDK for Go](https://docs.aws.amazon.com/sdk-for-go/api/aws/ec2metadata/) to read resource information from the [EC2 instance metadata API](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) to retrieve the following resource attributes: * cloud.provider ("aws") @@ -93,7 +99,7 @@ ec2: ## Configuration ```yaml -# a list of resource detectors to run, valid options are: "env", "system", "gce", "ec2", "ecs", "elastic_beanstalk", "azure" +# a list of resource detectors to run, valid options are: "env", "system", "gce", "gke", "ec2", "ecs", "elastic_beanstalk", "azure" detectors: [ ] # determines if existing resource attributes should be overridden or preserved, defaults to true override: diff --git a/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go b/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go index 72905df0f2b7..fcb63658b2f6 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go +++ b/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go @@ -43,7 +43,7 @@ func TestDetectTrue(t *testing.T) { md.On("Hostname").Return("hostname", nil) md.On("InstanceID").Return("2", nil) md.On("InstanceName").Return("name", nil) - md.On("Get").Return("machine-type", nil) + md.On("Get", "").Return("machine-type", nil) detector := &Detector{metadata: md} res, err := detector.Detect(context.Background()) diff --git a/processor/resourcedetectionprocessor/internal/gcp/mockmetadata.go b/processor/resourcedetectionprocessor/internal/gcp/mockmetadata.go index 22ea0a715772..a029df76c485 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/mockmetadata.go +++ b/processor/resourcedetectionprocessor/internal/gcp/mockmetadata.go @@ -59,6 +59,6 @@ func (m *MockMetadata) InstanceName() (string, error) { } func (m *MockMetadata) Get(suffix string) (string, error) { - args := m.MethodCalled("Get") + args := m.MethodCalled("Get", suffix) return args.String(0), args.Error(1) } diff --git a/processor/resourcedetectionprocessor/internal/gcp/mockmetadata_test.go b/processor/resourcedetectionprocessor/internal/gcp/mockmetadata_test.go new file mode 100644 index 000000000000..7a1fc28238a0 --- /dev/null +++ b/processor/resourcedetectionprocessor/internal/gcp/mockmetadata_test.go @@ -0,0 +1,42 @@ +// Copyright The OpenTelemetry 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 gcp + +import ( + "testing" +) + +func TestMockGCEMetadata(t *testing.T) { + metadata := &MockMetadata{} + metadata.On("OnGCE").Return(false) + metadata.On("ProjectID").Return("", nil) + metadata.On("Zone").Return("", nil) + metadata.On("Hostname").Return("", nil) + metadata.On("InstanceAttributeValue", "").Return("", nil) + metadata.On("InstanceID").Return("", nil) + metadata.On("InstanceName").Return("", nil) + metadata.On("Get", "").Return("", nil) + + metadata.OnGCE() + metadata.ProjectID() + metadata.Zone() + metadata.Hostname() + metadata.InstanceAttributeValue("") + metadata.InstanceID() + metadata.InstanceName() + metadata.Get("") + + metadata.AssertExpectations(t) +} From 85f49ba0eee0cb0698ae56d8305ccf3d3f147a47 Mon Sep 17 00:00:00 2001 From: Jay Camp Date: Tue, 23 Mar 2021 12:40:22 -0400 Subject: [PATCH 3/4] review feedback --- .../internal/gcp/gke/gke.go | 16 ++++++++++++---- .../internal/gcp/metadata.go | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/processor/resourcedetectionprocessor/internal/gcp/gke/gke.go b/processor/resourcedetectionprocessor/internal/gcp/gke/gke.go index 6bbf6e854719..09560731b06b 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gke/gke.go +++ b/processor/resourcedetectionprocessor/internal/gcp/gke/gke.go @@ -27,8 +27,16 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/gcp" ) -// TypeStr is type of detector. -const TypeStr = "gke" +const ( + // TypeStr is type of detector. + TypeStr = "gke" + + // GCE metadata attribute containing the GKE cluster name. + clusterNameAttribute = "cluster-name" + + // Environment variable that is set when running on Kubernetes. + kubernetesServiceHost = "KUBERNETES_SERVICE_HOST" +) var _ internal.Detector = (*Detector)(nil) @@ -54,13 +62,13 @@ func (gke *Detector) Detect(ctx context.Context) (pdata.Resource, error) { attr.InsertString(conventions.AttributeCloudProvider, conventions.AttributeCloudProviderGCP) // Check if running on k8s. - if os.Getenv("KUBERNETES_SERVICE_HOST") == "" { + if os.Getenv(kubernetesServiceHost) == "" { return res, nil } attr.InsertString(conventions.AttributeCloudInfrastructureService, conventions.AttributeCloudProviderGCPGKE) - if clusterName, err := gke.metadata.InstanceAttributeValue("cluster-name"); err != nil { + if clusterName, err := gke.metadata.InstanceAttributeValue(clusterNameAttribute); err != nil { gke.log.Warn("Unable to determine GKE cluster name", zap.Error(err)) } else if clusterName != "" { attr.InsertString(conventions.AttributeK8sCluster, clusterName) diff --git a/processor/resourcedetectionprocessor/internal/gcp/metadata.go b/processor/resourcedetectionprocessor/internal/gcp/metadata.go index 807cf4a399d5..167965259c24 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/metadata.go +++ b/processor/resourcedetectionprocessor/internal/gcp/metadata.go @@ -4,7 +4,7 @@ // 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 +// 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, From e2ede7b6de023b7f9fe5fe144370a6b10a3f425c Mon Sep 17 00:00:00 2001 From: Jay Camp Date: Wed, 24 Mar 2021 16:55:43 -0400 Subject: [PATCH 4/4] fix tests --- .../resourcedetectionprocessor/internal/gcp/gce/gce_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go b/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go index fcb63658b2f6..727cc4b2967d 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go +++ b/processor/resourcedetectionprocessor/internal/gcp/gce/gce_test.go @@ -43,7 +43,7 @@ func TestDetectTrue(t *testing.T) { md.On("Hostname").Return("hostname", nil) md.On("InstanceID").Return("2", nil) md.On("InstanceName").Return("name", nil) - md.On("Get", "").Return("machine-type", nil) + md.On("Get", "instance/machine-type").Return("machine-type", nil) detector := &Detector{metadata: md} res, err := detector.Detect(context.Background()) @@ -85,7 +85,7 @@ func TestDetectError(t *testing.T) { md.On("Hostname").Return("", errors.New("err3")) md.On("InstanceID").Return("", errors.New("err4")) md.On("InstanceName").Return("", errors.New("err5")) - md.On("Get").Return("", errors.New("err6")) + md.On("Get", "instance/machine-type").Return("", errors.New("err6")) detector := &Detector{metadata: md} res, err := detector.Detect(context.Background())