Skip to content

Commit 416f323

Browse files
committed
feat(nrawssdk): Accept NEW_RELIC_CLOUD_AWS_ACCOUNT_ID as env var
1 parent 2a88e41 commit 416f323

File tree

5 files changed

+56
-21
lines changed

5 files changed

+56
-21
lines changed

v3/integrations/nrawssdk-v2/example/main.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,14 @@ func main() {
3838
// Start recording a New Relic transaction
3939
txn := app.StartTransaction("My sample transaction")
4040

41-
ctx := context.Background()
41+
ctx := newrelic.NewContext(context.Background(), txn)
4242

4343
awsConfig, err := config.LoadDefaultConfig(ctx, func(awsConfig *config.LoadOptions) error {
4444
// Instrument all new AWS clients with New Relic
45-
4645
return nil
4746
})
48-
creds, err := awsConfig.Credentials.Retrieve(ctx)
49-
if err != nil {
50-
log.Println("Warning couldn't get flags")
51-
}
52-
nrawssdk.AppendMiddlewares(&awsConfig.APIOptions, nil, creds)
47+
48+
nrawssdk.NRAppendMiddlewares(&awsConfig.APIOptions, ctx, awsConfig)
5349
if err != nil {
5450
log.Fatal(err)
5551
}

v3/integrations/nrawssdk-v2/nrawssdk.go

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ import (
4646
)
4747

4848
type nrMiddleware struct {
49-
txn *newrelic.Transaction
50-
creds aws.Credentials
49+
txn *newrelic.Transaction
50+
accountID string
5151
}
5252

5353
type contextKey string
@@ -77,14 +77,7 @@ func (m nrMiddleware) deserializeMiddleware(stack *smithymiddle.Stack) error {
7777
serviceName := awsmiddle.GetServiceID(ctx)
7878
operation := awsmiddle.GetOperationName(ctx)
7979
region := awsmiddle.GetRegion(ctx)
80-
81-
creds := awsmiddle.GetSigningCredentials(ctx)
82-
accountID, err := awssupport.AWSAccountIdFromAWSAccessKey(creds)
83-
if err != nil {
84-
accountID = ""
85-
fmt.Println(err.Error())
86-
}
87-
80+
accountID := m.accountID
8881
var segment endable
8982

9083
if serviceName == "dynamodb" || serviceName == "DynamoDB" {
@@ -138,7 +131,9 @@ func (m nrMiddleware) deserializeMiddleware(stack *smithymiddle.Stack) error {
138131
integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeAWSElastSearchDomainEndpoint, httpRequest.URL.String()) // this way I don't have to pull it out of context
139132
}
140133
// Set additional span attributes
134+
141135
integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeCloudAccountID, accountID) // setting account ID here, why do we only do this if it is an SQS service?
136+
142137
integrationsupport.AddAgentSpanAttribute(txn,
143138
newrelic.AttributeResponseCode, strconv.Itoa(response.StatusCode))
144139
integrationsupport.AddAgentSpanAttribute(txn,
@@ -161,7 +156,6 @@ func (m nrMiddleware) serializeMiddleware(stack *middleware.Stack) error {
161156
ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
162157
out middleware.InitializeOutput, metadata middleware.Metadata, err error) {
163158
serviceName := awsmiddle.GetServiceID(ctx)
164-
ctx = awsmiddle.SetSigningCredentials(ctx, m.creds)
165159
switch serviceName {
166160
case "dynamodb", "DynamoDB":
167161
ctx = context.WithValue(ctx, dynamodbInputKey, dynamoDBInputFromMiddlewareInput(in))
@@ -229,8 +223,31 @@ func (m nrMiddleware) serializeMiddleware(stack *middleware.Stack) error {
229223
// if err != nil {
230224
// log.Fatal(err)
231225
// }
232-
func AppendMiddlewares(apiOptions *[]func(*smithymiddle.Stack) error, txn *newrelic.Transaction, creds aws.Credentials) {
233-
m := nrMiddleware{txn: txn, creds: creds}
226+
func AppendMiddlewares(apiOptions *[]func(*smithymiddle.Stack) error, txn *newrelic.Transaction) {
227+
m := nrMiddleware{txn: txn}
228+
*apiOptions = append(*apiOptions, m.deserializeMiddleware)
229+
*apiOptions = append(*apiOptions, m.serializeMiddleware)
230+
}
231+
232+
func NRAppendMiddlewares(apiOptions *[]func(*smithymiddle.Stack) error, ctx context.Context, awsConfig aws.Config) {
233+
txn := newrelic.FromContext(ctx)
234+
235+
creds, err := awsConfig.Credentials.Retrieve(ctx)
236+
if err != nil {
237+
fmt.Println("error: Couldn't get AWS Credentials")
238+
}
239+
240+
cfg, ok := txn.Application().Config()
241+
m := nrMiddleware{txn: txn}
242+
243+
if ok {
244+
accountID, err := ResolveAWSCredentials(cfg, creds)
245+
if err != nil {
246+
fmt.Println("error: Couldn't resolve AWS credentials")
247+
}
248+
m.accountID = accountID
249+
}
250+
234251
*apiOptions = append(*apiOptions, m.deserializeMiddleware)
235252
*apiOptions = append(*apiOptions, m.serializeMiddleware)
236253
}
@@ -291,3 +308,18 @@ func dynamoDBInputFromMiddlewareInput(in middleware.InitializeInput) dynamodbInp
291308
return dynamodbInput{}
292309
}
293310
}
311+
312+
func ResolveAWSCredentials(cfg newrelic.Config, creds aws.Credentials) (string, error) {
313+
314+
accountID, err := awssupport.AWSAccountIdFromAWSAccessKey(creds)
315+
if err != nil {
316+
return "", err
317+
}
318+
319+
// if the accountID that comes back is different than what is set in the env
320+
// then we should use that accountID since it is accurate
321+
if accountID != "" && accountID != cfg.CloudAWS.AccountID {
322+
return accountID, nil
323+
}
324+
return cfg.CloudAWS.AccountID, nil
325+
}

v3/integrations/nrawssdk-v2/nrawssdk_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ var fakeCreds = func() interface{} {
6464

6565
func newConfig(ctx context.Context, txn *newrelic.Transaction) aws.Config {
6666
cfg, _ := config.LoadDefaultConfig(ctx, func(o *config.LoadOptions) error {
67-
AppendMiddlewares(&o.APIOptions, txn, aws.Credentials{})
67+
AppendMiddlewares(&o.APIOptions, txn)
6868
return nil
6969
})
7070
cfg.Credentials = fakeCreds.(aws.CredentialsProvider)

v3/newrelic/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ type Config struct {
9393
MaxSamplesStored int
9494
}
9595

96+
CloudAWS struct {
97+
AccountID string
98+
}
99+
96100
// ErrorCollector controls the capture of errors.
97101
ErrorCollector struct {
98102
// Enabled controls whether errors are captured. This setting

v3/newrelic/config_options.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,9 @@ func configFromEnvironment(getenv func(string) string) ConfigOption {
624624
// Error Collector Env Variables
625625
assignInt(&cfg.ErrorCollector.MaxSamplesStored, "NEW_RELIC_ERROR_COLLECTOR_MAX_EVENT_SAMPLES_STORED", maxErrorEvents)
626626

627+
// AWS Env Variables
628+
assignString(&cfg.CloudAWS.AccountID, "NEW_RELIC_CLOUD_AWS_ACCOUNT_ID")
629+
627630
if env := getenv("NEW_RELIC_LABELS"); env != "" {
628631
labels, err := getLabels(getenv("NEW_RELIC_LABELS"))
629632
if err != nil {

0 commit comments

Comments
 (0)