Skip to content

Commit

Permalink
handle empty tags, add tests and close underlying body
Browse files Browse the repository at this point in the history
Signed-off-by: Kavindu Dodanduwa <[email protected]>
  • Loading branch information
Kavindu-Dodan committed Oct 30, 2024
1 parent 7f2db42 commit 9adedf4
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 15 deletions.
46 changes: 31 additions & 15 deletions libbeat/processors/add_cloud_metadata/provider_aws_ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func getTags(ctx context.Context, imdsClient IMDSClient, ec2Client EC2Client, in
logger.Info("Tag extraction from IMDS failed, fallback to DescribeTags API to obtain EKS cluster name.")
clusterName, err := clusterNameFromDescribeTag(ctx, ec2Client, instanceId)
if err != nil {
logger.Warnf("error obtaining cluster name: %s.", err)
logger.Warnf("error obtaining cluster name: %v.", err)
return tags
}

Expand All @@ -169,36 +169,52 @@ func getTags(ctx context.Context, imdsClient IMDSClient, ec2Client EC2Client, in
func getTagsFromIMDS(ctx context.Context, client IMDSClient, logger *logp.Logger) (tags map[string]string, ok bool) {
tags = make(map[string]string)

metadata, err := client.GetMetadata(ctx, &imds.GetMetadataInput{Path: tagsCategory})
b, err := getMetadataHelper(ctx, client, tagsCategory, logger)
if err != nil {
logger.Warnf("error from IMDS tags category request: %s", err)
logger.Warnf("error obtaining tags category: %v", err)
return tags, false
}

b, err := io.ReadAll(metadata.Content)
if err != nil {
logger.Warnf("error extracting tags category payload: %s", err)
return tags, false
tagInput := string(b)
if tagInput == "" {
logger.Info("No tags present in the EC2 instance")
return tags, true
}

for _, tag := range strings.Split(string(b), "\n") {
for _, tag := range strings.Split(tagInput, "\n") {
tagPath := fmt.Sprintf("%s/%s", tagsCategory, tag)
metadata, err := client.GetMetadata(ctx, &imds.GetMetadataInput{Path: tagPath})
b, err := getMetadataHelper(ctx, client, tagPath, logger)
if err != nil {
logger.Warnf("error from IMDS tag request: %s", err)
logger.Warnf("error extracting tag value of %s: %v", tag, err)
return tags, false
}

b, err := io.ReadAll(metadata.Content)
tags[tag] = string(b)
}

return tags, true
}

// getMetadataHelper performs the IMDS call for the given path and returns the response content after closing the underlying content reader.
func getMetadataHelper(ctx context.Context, client IMDSClient, path string, logger *logp.Logger) (content []byte, err error) {
metadata, err := client.GetMetadata(ctx, &imds.GetMetadataInput{Path: path})
if err != nil {
return nil, fmt.Errorf("error from IMDS metadata request: %w", err)
}

defer func(Content io.ReadCloser) {
err := Content.Close()
if err != nil {
logger.Warnf("error extracting tag value payload: %s", err)
return tags, false
logger.Warnf("error closing IMDS metadata response body: %v", err)
}
}(metadata.Content)

tags[tag] = string(b)
content, err = io.ReadAll(metadata.Content)
if err != nil {
return nil, fmt.Errorf("error extracting metadata from the IMDS response: %w", err)
}

return tags, true
return content, nil
}

// clusterNameFromDescribeTag is a helper to extract EKS cluster name using DescribeTag.
Expand Down
13 changes: 13 additions & 0 deletions libbeat/processors/add_cloud_metadata/provider_aws_ec2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,19 @@ func Test_getTags(t *testing.T) {
}},
want: map[string]string{},
},
{
name: "Empty tags results in empty tag extraction",
imdsClient: &MockIMDSClient{
GetMetadataFunc: func(ctx context.Context, input *imds.GetMetadataInput, f ...func(*imds.Options)) (*imds.GetMetadataOutput, error) {
return &imds.GetMetadataOutput{Content: io.NopCloser(strings.NewReader(""))}, nil
},
},
ec2Client: &MockEC2Client{
DescribeTagsFunc: func(ctx context.Context, params *ec2.DescribeTagsInput, optFns ...func(*ec2.Options)) (*ec2.DescribeTagsOutput, error) {
return nil, errors.New("some error from DescribeTag")
}},
want: map[string]string{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit 9adedf4

Please sign in to comment.