forked from open-telemetry/opentelemetry-collector-contrib
-
Notifications
You must be signed in to change notification settings - Fork 16
/
ec2metadata.go
123 lines (103 loc) · 3.44 KB
/
ec2metadata.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// 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:https://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 host // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscontainerinsightreceiver/internal/host"
import (
"context"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
awsec2metadata "github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"go.uber.org/zap"
)
type metadataClient interface {
GetInstanceIdentityDocumentWithContext(ctx context.Context) (awsec2metadata.EC2InstanceIdentityDocument, error)
}
type ec2MetadataProvider interface {
getInstanceID() string
getInstanceType() string
getRegion() string
getInstanceIP() string
}
type ec2Metadata struct {
logger *zap.Logger
client metadataClient
refreshInterval time.Duration
instanceID string
instanceType string
instanceIP string
region string
instanceIDReadyC chan bool
instanceIPReadyC chan bool
localMode bool
}
type ec2MetadataOption func(*ec2Metadata)
func newEC2Metadata(ctx context.Context, session *session.Session, refreshInterval time.Duration,
instanceIDReadyC chan bool, instanceIPReadyC chan bool, localMode bool, logger *zap.Logger, options ...ec2MetadataOption) ec2MetadataProvider {
emd := &ec2Metadata{
client: awsec2metadata.New(session, &aws.Config{
Retryer: client.DefaultRetryer{NumMaxRetries: 5},
}),
refreshInterval: refreshInterval,
instanceIDReadyC: instanceIDReadyC,
instanceIPReadyC: instanceIPReadyC,
localMode: localMode,
logger: logger,
}
for _, opt := range options {
opt(emd)
}
shouldRefresh := func() bool {
// stop the refresh once we get instance ID and type successfully
return emd.instanceID == "" || emd.instanceType == "" || emd.instanceIP == ""
}
go RefreshUntil(ctx, emd.refresh, emd.refreshInterval, shouldRefresh, 0)
return emd
}
func (emd *ec2Metadata) refresh(ctx context.Context) {
if emd.localMode {
emd.logger.Debug("Running EC2MetadataProvider in local mode. Skipping EC2 metadata fetch")
return
}
emd.logger.Info("Fetch instance id and type from ec2 metadata")
doc, err := emd.client.GetInstanceIdentityDocumentWithContext(ctx)
if err != nil {
emd.logger.Error("Failed to get ec2 metadata", zap.Error(err))
return
}
emd.instanceID = doc.InstanceID
emd.instanceType = doc.InstanceType
emd.region = doc.Region
emd.instanceIP = doc.PrivateIP
// notify ec2tags and ebsvolume that the instance id is ready
if emd.instanceID != "" {
close(emd.instanceIDReadyC)
}
// notify ecsinfo that the instance id is ready
if emd.instanceIP != "" {
close(emd.instanceIPReadyC)
}
}
func (emd *ec2Metadata) getInstanceID() string {
return emd.instanceID
}
func (emd *ec2Metadata) getInstanceType() string {
return emd.instanceType
}
func (emd *ec2Metadata) getRegion() string {
return emd.region
}
func (emd *ec2Metadata) getInstanceIP() string {
return emd.instanceIP
}