From 9a486f36599a20e0b8fe2ee75d84b7e8c08dfec0 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 2 Jul 2020 10:34:04 +0800 Subject: [PATCH] [MetricBeat] set tags correctly if the dimension value is ARN (#19433) * fix setting tags when dimension value is arn format in aws cloudwatch module --- CHANGELOG.next.asciidoc | 1 + .../module/aws/cloudwatch/cloudwatch.go | 7 +++++++ .../module/aws/cloudwatch/cloudwatch_test.go | 16 ++++++++++++++++ x-pack/metricbeat/module/aws/utils.go | 6 +++--- x-pack/metricbeat/module/aws/utils_test.go | 2 +- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 9d8db101f4e..331f348f992 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -260,6 +260,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix incorrect usage of hints builder when exposed port is a substring of the hint {pull}19052[19052] - Remove dedot for tag values in aws module. {issue}19112[19112] {pull}19221[19221] - Stop counterCache only when already started {pull}19103[19103] +- Set tags correctly if the dimension value is ARN {issue}19111[19111] {pull}19433[19433] - Fix bug incorrect parsing of float numbers as integers in Couchbase module {issue}18949[18949] {pull}19055[19055] *Packetbeat* diff --git a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go index 2cc447723be..aac756190f2 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch.go @@ -615,6 +615,13 @@ func insertTags(events map[string]mb.Event, identifier string, resourceTagMap ma subIdentifiers := strings.Split(identifier, dimensionSeparator) for _, v := range subIdentifiers { tags := resourceTagMap[v] + // some metric dimension values are arn format, eg: AWS/DDOS namespace metric + if len(tags) == 0 && strings.HasPrefix(v, "arn:") { + resourceID, err := aws.FindIdentifierFromARN(v) + if err == nil { + tags = resourceTagMap[resourceID] + } + } if len(tags) != 0 { // By default, replace dot "." using underscore "_" for tag keys. // Note: tag values are not dedotted. diff --git a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch_test.go b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch_test.go index e6b5cdebe5a..93a0c42492c 100644 --- a/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch_test.go +++ b/x-pack/metricbeat/module/aws/cloudwatch/cloudwatch_test.go @@ -1407,10 +1407,14 @@ func TestInsertTags(t *testing.T) { tagValue1 := "engineering" tagKey2 := "owner" tagValue2 := "foo" + identifierContainsArn := "arn:aws:ec2:ap-northeast-1:111111111111:eip-allocation/eipalloc-0123456789abcdef,SYNFlood" + tagKey3 := "env" + tagValue3 := "dev" events := map[string]mb.Event{} events[identifier1] = aws.InitEvent(regionName, accountName, accountID) events[identifier2] = aws.InitEvent(regionName, accountName, accountID) + events[identifierContainsArn] = aws.InitEvent(regionName, accountName, accountID) resourceTagMap := map[string][]resourcegroupstaggingapi.Tag{} resourceTagMap["test-s3-1"] = []resourcegroupstaggingapi.Tag{ @@ -1425,6 +1429,12 @@ func TestInsertTags(t *testing.T) { Value: awssdk.String(tagValue2), }, } + resourceTagMap["eipalloc-0123456789abcdef"] = []resourcegroupstaggingapi.Tag{ + { + Key: awssdk.String(tagKey3), + Value: awssdk.String(tagValue3), + }, + } cases := []struct { title string @@ -1444,6 +1454,12 @@ func TestInsertTags(t *testing.T) { "aws.tags.owner", tagValue2, }, + { + "test identifier with arn value", + identifierContainsArn, + "aws.tags.env", + tagValue3, + }, } for _, c := range cases { diff --git a/x-pack/metricbeat/module/aws/utils.go b/x-pack/metricbeat/module/aws/utils.go index f9e0f58b16c..4c92cb140c6 100644 --- a/x-pack/metricbeat/module/aws/utils.go +++ b/x-pack/metricbeat/module/aws/utils.go @@ -188,9 +188,9 @@ func GetResourcesTags(svc resourcegroupstaggingapiiface.ClientAPI, resourceTypeF } for _, resourceTag := range output.ResourceTagMappingList { - identifier, err := findIdentifierFromARN(*resourceTag.ResourceARN) + identifier, err := FindIdentifierFromARN(*resourceTag.ResourceARN) if err != nil { - err = errors.Wrap(err, "error findIdentifierFromARN") + err = errors.Wrap(err, "error FindIdentifierFromARN") return nil, err } resourceTagMap[identifier] = resourceTag.Tags @@ -199,7 +199,7 @@ func GetResourcesTags(svc resourcegroupstaggingapiiface.ClientAPI, resourceTypeF return resourceTagMap, nil } -func findIdentifierFromARN(resourceARN string) (string, error) { +func FindIdentifierFromARN(resourceARN string) (string, error) { arnParsed, err := arn.Parse(resourceARN) if err != nil { err = errors.Wrap(err, "error Parse arn") diff --git a/x-pack/metricbeat/module/aws/utils_test.go b/x-pack/metricbeat/module/aws/utils_test.go index c33d61c641f..4270d52b6ef 100644 --- a/x-pack/metricbeat/module/aws/utils_test.go +++ b/x-pack/metricbeat/module/aws/utils_test.go @@ -377,7 +377,7 @@ func TestFindIdentifierFromARN(t *testing.T) { } for _, c := range cases { - identifier, err := findIdentifierFromARN(c.resourceARN) + identifier, err := FindIdentifierFromARN(c.resourceARN) assert.NoError(t, err) assert.Equal(t, c.expectedIdentifier, identifier) }