Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry-pick #21101 to 7.x: Fix index out of range error when getting AWS account name #21143

Merged
merged 3 commits into from
Sep 17, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ field. You can revert this change by configuring tags for the module and omittin
- Update fields.yml in the azure module, missing metrics field. {pull}20918[20918]
- The `elasticsearch/index` metricset only requests wildcard expansion for hidden indices if the monitored Elasticsearch cluster supports it. {pull}20938[20938]
- Disable Kafka metricsets based on Jolokia by default. They require a different configuration. {pull}20989[20989]
- Fix panic index out of range error when getting AWS account name. {pull}21101[21101] {issue}21095[21095]

*Packetbeat*

Expand Down
49 changes: 30 additions & 19 deletions x-pack/metricbeat/module/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ec2/ec2iface"
"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/aws-sdk-go-v2/service/iam/iamiface"
"github.com/aws/aws-sdk-go-v2/service/rds"
"github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi"
"github.com/aws/aws-sdk-go-v2/service/sts"
Expand Down Expand Up @@ -105,25 +106,6 @@ func NewMetricSet(base mb.BaseMetricSet) (*MetricSet, error) {
awsConfig.Region = "us-east-1"
}

svcIam := iam.New(awscommon.EnrichAWSConfigWithEndpoint(
config.AWSConfig.Endpoint, "iam", "", awsConfig))
req := svcIam.ListAccountAliasesRequest(&iam.ListAccountAliasesInput{})
output, err := req.Send(context.TODO())
if err != nil {
base.Logger().Warn("failed to list account aliases, please check permission setting: ", err)
metricSet.AccountName = metricSet.AccountID
} else {
// When there is no account alias, account ID will be used as cloud.account.name
if len(output.AccountAliases) == 0 {
metricSet.AccountName = metricSet.AccountID
}

// There can be more than one aliases for each account, for now we are only
// collecting the first one.
metricSet.AccountName = output.AccountAliases[0]
base.Logger().Debug("AWS Credentials belong to account name: ", metricSet.AccountName)
}

// Get IAM account id
svcSts := sts.New(awscommon.EnrichAWSConfigWithEndpoint(
config.AWSConfig.Endpoint, "sts", "", awsConfig))
Expand All @@ -136,6 +118,11 @@ func NewMetricSet(base mb.BaseMetricSet) (*MetricSet, error) {
base.Logger().Debug("AWS Credentials belong to account ID: ", metricSet.AccountID)
}

// Get account name/alias
svcIam := iam.New(awscommon.EnrichAWSConfigWithEndpoint(
config.AWSConfig.Endpoint, "iam", "", awsConfig))
metricSet.AccountName = getAccountName(svcIam, base, metricSet)

// Construct MetricSet with a full regions list
if config.Regions == nil {
svcEC2 := ec2.New(awscommon.EnrichAWSConfigWithEndpoint(
Expand Down Expand Up @@ -170,6 +157,30 @@ func getRegions(svc ec2iface.ClientAPI) (completeRegionsList []string, err error
return
}

func getAccountName(svc iamiface.ClientAPI, base mb.BaseMetricSet, metricSet MetricSet) string {
req := svc.ListAccountAliasesRequest(&iam.ListAccountAliasesInput{})
output, err := req.Send(context.TODO())

accountName := metricSet.AccountID
if err != nil {
base.Logger().Warn("failed to list account aliases, please check permission setting: ", err)
return accountName
}

// When there is no account alias, account ID will be used as cloud.account.name
if len(output.AccountAliases) == 0 {
accountName = metricSet.AccountID
base.Logger().Debug("AWS Credentials belong to account ID: ", metricSet.AccountID)
return accountName
}

// There can be more than one aliases for each account, for now we are only
// collecting the first one.
accountName = output.AccountAliases[0]
base.Logger().Debug("AWS Credentials belong to account name: ", metricSet.AccountName)
return accountName
}

// StringInSlice checks if a string is already exists in list and its location
func StringInSlice(str string, list []string) (bool, int) {
for idx, v := range list {
Expand Down