Skip to content

Commit

Permalink
Merge pull request #494 from ekristen/fix-cloudwatchlogs
Browse files Browse the repository at this point in the history
feat: add new property to CloudWatchLogsLogGroup
  • Loading branch information
ekristen authored Jan 4, 2025
2 parents fe2a3d8 + c89b72a commit 3bc5798
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 29 deletions.
9 changes: 9 additions & 0 deletions docs/resources/cloud-watch-logs-log-group.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,17 @@ generated: true
CloudWatchLogsLogGroup
```

## Properties


- `CreatedTime`: The creation time of the log group in unix timestamp format
- `CreationTime`: The creation time of the log group in RFC3339 format
- `LastEvent`: The last event time of the log group in RFC3339 format
- `Name`: The name of the log group
- `RetentionInDays`: The number of days to retain log events in the log group
- `tag:<key>:`: This resource has tags with property `Tags`. These are key/value pairs that are
added as their own property with the prefix of `tag:` (e.g. [tag:example: "value"])

!!! note - Using Properties
Properties are what [Filters](../config-filtering.md) are written against in your configuration. You use the property
names to write filters for what you want to **keep** and omit from the nuke process.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"strings"
"time"

"github.com/gotidy/ptr"
"go.uber.org/ratelimit"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"

"github.com/ekristen/libnuke/pkg/registry"
Expand Down Expand Up @@ -46,7 +46,7 @@ func (l *CloudWatchLogsLogGroupLister) List(_ context.Context, o interface{}) ([
streamRl := ratelimit.New(15)

params := &cloudwatchlogs.DescribeLogGroupsInput{
Limit: aws.Int64(50),
Limit: ptr.Int64(50),
}

for {
Expand All @@ -72,9 +72,9 @@ func (l *CloudWatchLogsLogGroupLister) List(_ context.Context, o interface{}) ([
// get last event ingestion time
lsResp, err := svc.DescribeLogStreams(&cloudwatchlogs.DescribeLogStreamsInput{
LogGroupName: logGroup.LogGroupName,
OrderBy: aws.String("LastEventTime"),
Limit: aws.Int64(1),
Descending: aws.Bool(true),
OrderBy: ptr.String("LastEventTime"),
Limit: ptr.Int64(1),
Descending: ptr.Bool(true),
})
if err != nil {
return nil, err
Expand All @@ -87,14 +87,21 @@ func (l *CloudWatchLogsLogGroupLister) List(_ context.Context, o interface{}) ([
lastEvent = time.Unix(*logGroup.CreationTime/1000, 0)
}

var retentionInDays int64
if logGroup.RetentionInDays != nil {
retentionInDays = ptr.ToInt64(logGroup.RetentionInDays)
}

resources = append(resources, &CloudWatchLogsLogGroup{
svc: svc,
logGroup: logGroup,
lastEvent: lastEvent.Format(time.RFC3339),
tags: tagResp.Tags,
svc: svc,
Name: logGroup.LogGroupName,
CreatedTime: logGroup.CreationTime,
CreationTime: ptr.Time(time.Unix(*logGroup.CreationTime/1000, 0).UTC()),
LastEvent: ptr.Time(lastEvent), // TODO(v4): convert to UTC
RetentionInDays: retentionInDays,
Tags: tagResp.Tags,
})
}

if output.NextToken == nil {
break
}
Expand All @@ -106,32 +113,28 @@ func (l *CloudWatchLogsLogGroupLister) List(_ context.Context, o interface{}) ([
}

type CloudWatchLogsLogGroup struct {
svc *cloudwatchlogs.CloudWatchLogs
logGroup *cloudwatchlogs.LogGroup
lastEvent string
tags map[string]*string
svc *cloudwatchlogs.CloudWatchLogs
Name *string `description:"The name of the log group"`
CreatedTime *int64 `description:"The creation time of the log group in unix timestamp format"`
CreationTime *time.Time `description:"The creation time of the log group in RFC3339 format"`
LastEvent *time.Time `description:"The last event time of the log group in RFC3339 format"`
RetentionInDays int64 `description:"The number of days to retain log events in the log group"`
Tags map[string]*string
}

func (f *CloudWatchLogsLogGroup) Remove(_ context.Context) error {
_, err := f.svc.DeleteLogGroup(&cloudwatchlogs.DeleteLogGroupInput{
LogGroupName: f.logGroup.LogGroupName,
func (r *CloudWatchLogsLogGroup) Remove(_ context.Context) error {
_, err := r.svc.DeleteLogGroup(&cloudwatchlogs.DeleteLogGroupInput{
LogGroupName: r.Name,
})

return err
}

func (f *CloudWatchLogsLogGroup) String() string {
return *f.logGroup.LogGroupName
func (r *CloudWatchLogsLogGroup) String() string {
return *r.Name
}

func (f *CloudWatchLogsLogGroup) Properties() types.Properties {
properties := types.NewProperties().
Set("logGroupName", f.logGroup.LogGroupName).
Set("CreatedTime", f.logGroup.CreationTime).
Set("LastEvent", f.lastEvent)

for k, v := range f.tags {
properties.SetTag(&k, v)
}
return properties
func (r *CloudWatchLogsLogGroup) Properties() types.Properties {
return types.NewPropertiesFromStruct(r).
Set("logGroupName", r.Name) // TODO(v4): remove this property
}
34 changes: 34 additions & 0 deletions resources/cloudwatchlogs-loggroup_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package resources

import (
"strconv"
"testing"
"time"

"github.com/gotidy/ptr"
"github.com/stretchr/testify/assert"
)

func TestCloudWatchLogsLogGroupProperties(t *testing.T) {
now := time.Now().UTC()

r := &CloudWatchLogsLogGroup{
Name: ptr.String("test-log-group"),
CreatedTime: ptr.Int64(now.Unix()),
CreationTime: ptr.Time(now),
LastEvent: ptr.Time(now),
RetentionInDays: 7,
Tags: map[string]*string{
"Environment": ptr.String("production"),
},
}

properties := r.Properties()
assert.Equal(t, properties.Get("logGroupName"), "test-log-group")
assert.Equal(t, properties.Get("Name"), "test-log-group")
assert.Equal(t, properties.Get("CreatedTime"), strconv.Itoa(int(now.Unix())))
assert.Equal(t, properties.Get("CreationTime"), now.Format(time.RFC3339))
assert.Equal(t, properties.Get("LastEvent"), now.Format(time.RFC3339))
assert.Equal(t, properties.Get("RetentionInDays"), "7")
assert.Equal(t, properties.Get("tag:Environment"), "production")
}

0 comments on commit 3bc5798

Please sign in to comment.