From b8982b47c564af35964fef97609ffd6926cc2cd3 Mon Sep 17 00:00:00 2001 From: ayogun Date: Thu, 2 Jan 2025 02:56:57 +0100 Subject: [PATCH 1/6] feat(cloudwatchlogs-loggroup): add RetentionInDays properties --- resources/cloudwatchlogs-loggroups.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/resources/cloudwatchlogs-loggroups.go b/resources/cloudwatchlogs-loggroups.go index eae192be..bd325236 100644 --- a/resources/cloudwatchlogs-loggroups.go +++ b/resources/cloudwatchlogs-loggroups.go @@ -87,14 +87,14 @@ func (l *CloudWatchLogsLogGroupLister) List(_ context.Context, o interface{}) ([ lastEvent = time.Unix(*logGroup.CreationTime/1000, 0) } + resources = append(resources, &CloudWatchLogsLogGroup{ svc: svc, logGroup: logGroup, lastEvent: lastEvent.Format(time.RFC3339), tags: tagResp.Tags, }) - } - + } if output.NextToken == nil { break } @@ -128,10 +128,13 @@ func (f *CloudWatchLogsLogGroup) Properties() types.Properties { properties := types.NewProperties(). Set("logGroupName", f.logGroup.LogGroupName). Set("CreatedTime", f.logGroup.CreationTime). - Set("LastEvent", f.lastEvent) + Set("LastEvent", f.lastEvent). + Set("RetentionInDays", f.logGroup.RetentionInDays) + for k, v := range f.tags { properties.SetTag(&k, v) } return properties } + From 76177af44c20094395ca03249d80ef69310a00ba Mon Sep 17 00:00:00 2001 From: Erik Kristensen Date: Fri, 3 Jan 2025 15:32:24 -0700 Subject: [PATCH 2/6] fix(cloudwatchlogs-loggroup): property RetentionInDays should always have a value --- resources/cloudwatchlogs-loggroups.go | 29 ++++++++++++++++----------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/resources/cloudwatchlogs-loggroups.go b/resources/cloudwatchlogs-loggroups.go index bd325236..6bf96fb4 100644 --- a/resources/cloudwatchlogs-loggroups.go +++ b/resources/cloudwatchlogs-loggroups.go @@ -2,6 +2,7 @@ package resources import ( "context" + "github.com/gotidy/ptr" "strings" "time" @@ -87,14 +88,19 @@ 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, + logGroup: logGroup, + lastEvent: lastEvent.Format(time.RFC3339), + retentionInDays: retentionInDays, + tags: tagResp.Tags, }) - } + } if output.NextToken == nil { break } @@ -106,10 +112,11 @@ 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 + logGroup *cloudwatchlogs.LogGroup + lastEvent string + retentionInDays int64 + tags map[string]*string } func (f *CloudWatchLogsLogGroup) Remove(_ context.Context) error { @@ -129,12 +136,10 @@ func (f *CloudWatchLogsLogGroup) Properties() types.Properties { Set("logGroupName", f.logGroup.LogGroupName). Set("CreatedTime", f.logGroup.CreationTime). Set("LastEvent", f.lastEvent). - Set("RetentionInDays", f.logGroup.RetentionInDays) - + Set("RetentionInDays", f.retentionInDays) for k, v := range f.tags { properties.SetTag(&k, v) } return properties } - From 19ebeb32ff835379d11570abfc139fd4edb925fc Mon Sep 17 00:00:00 2001 From: Erik Kristensen Date: Fri, 3 Jan 2025 15:33:22 -0700 Subject: [PATCH 3/6] refactor(cloudwatchlogs-loggroup): standardization --- ...oggroups.go => cloudwatchlogs-loggroup.go} | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) rename resources/{cloudwatchlogs-loggroups.go => cloudwatchlogs-loggroup.go} (86%) diff --git a/resources/cloudwatchlogs-loggroups.go b/resources/cloudwatchlogs-loggroup.go similarity index 86% rename from resources/cloudwatchlogs-loggroups.go rename to resources/cloudwatchlogs-loggroup.go index 6bf96fb4..e6d1f42c 100644 --- a/resources/cloudwatchlogs-loggroups.go +++ b/resources/cloudwatchlogs-loggroup.go @@ -119,26 +119,26 @@ type CloudWatchLogsLogGroup struct { 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.logGroup.LogGroupName, }) return err } -func (f *CloudWatchLogsLogGroup) String() string { - return *f.logGroup.LogGroupName +func (r *CloudWatchLogsLogGroup) String() string { + return *r.logGroup.LogGroupName } -func (f *CloudWatchLogsLogGroup) Properties() types.Properties { +func (r *CloudWatchLogsLogGroup) Properties() types.Properties { properties := types.NewProperties(). - Set("logGroupName", f.logGroup.LogGroupName). - Set("CreatedTime", f.logGroup.CreationTime). - Set("LastEvent", f.lastEvent). - Set("RetentionInDays", f.retentionInDays) + Set("logGroupName", r.logGroup.LogGroupName). + Set("CreatedTime", r.logGroup.CreationTime). + Set("LastEvent", r.lastEvent). + Set("RetentionInDays", r.retentionInDays) - for k, v := range f.tags { + for k, v := range r.tags { properties.SetTag(&k, v) } return properties From d8ffbc5881f187d749495256ad06392b53b84982 Mon Sep 17 00:00:00 2001 From: Erik Kristensen Date: Fri, 3 Jan 2025 15:54:09 -0700 Subject: [PATCH 4/6] feat(cloudwatchlogs-loggroup): new properties, refactor properties struct --- resources/cloudwatchlogs-loggroup.go | 47 +++++++++++++--------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/resources/cloudwatchlogs-loggroup.go b/resources/cloudwatchlogs-loggroup.go index e6d1f42c..c4cfcb69 100644 --- a/resources/cloudwatchlogs-loggroup.go +++ b/resources/cloudwatchlogs-loggroup.go @@ -2,13 +2,12 @@ package resources import ( "context" - "github.com/gotidy/ptr" "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" @@ -47,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 { @@ -73,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 @@ -95,10 +94,12 @@ func (l *CloudWatchLogsLogGroupLister) List(_ context.Context, o interface{}) ([ resources = append(resources, &CloudWatchLogsLogGroup{ svc: svc, - logGroup: logGroup, - lastEvent: lastEvent.Format(time.RFC3339), - retentionInDays: retentionInDays, - tags: tagResp.Tags, + 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 { @@ -113,33 +114,27 @@ func (l *CloudWatchLogsLogGroupLister) List(_ context.Context, o interface{}) ([ type CloudWatchLogsLogGroup struct { svc *cloudwatchlogs.CloudWatchLogs - logGroup *cloudwatchlogs.LogGroup - lastEvent string - retentionInDays int64 - tags map[string]*string + 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 (r *CloudWatchLogsLogGroup) Remove(_ context.Context) error { _, err := r.svc.DeleteLogGroup(&cloudwatchlogs.DeleteLogGroupInput{ - LogGroupName: r.logGroup.LogGroupName, + LogGroupName: r.Name, }) return err } func (r *CloudWatchLogsLogGroup) String() string { - return *r.logGroup.LogGroupName + return *r.Name } func (r *CloudWatchLogsLogGroup) Properties() types.Properties { - properties := types.NewProperties(). - Set("logGroupName", r.logGroup.LogGroupName). - Set("CreatedTime", r.logGroup.CreationTime). - Set("LastEvent", r.lastEvent). - Set("RetentionInDays", r.retentionInDays) - - for k, v := range r.tags { - properties.SetTag(&k, v) - } - return properties + return types.NewPropertiesFromStruct(r). + Set("logGroupName", r.Name) // TODO(v4): remove this property } From 8f99b2145f3b2475cd6f5368af502869efc2d227 Mon Sep 17 00:00:00 2001 From: Erik Kristensen Date: Fri, 3 Jan 2025 15:55:51 -0700 Subject: [PATCH 5/6] test(cloudwatchlogs-loggroup): add property test coverage --- resources/cloudwatchlogs-loggroup_test.go | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 resources/cloudwatchlogs-loggroup_test.go diff --git a/resources/cloudwatchlogs-loggroup_test.go b/resources/cloudwatchlogs-loggroup_test.go new file mode 100644 index 00000000..e2d2e669 --- /dev/null +++ b/resources/cloudwatchlogs-loggroup_test.go @@ -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") +} From c89b72a3a3eab7502ad61d15683341c24a8e18ca Mon Sep 17 00:00:00 2001 From: Erik Kristensen Date: Fri, 3 Jan 2025 15:56:26 -0700 Subject: [PATCH 6/6] docs(resources): auto-generated --- docs/resources/cloud-watch-logs-log-group.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/resources/cloud-watch-logs-log-group.md b/docs/resources/cloud-watch-logs-log-group.md index a9d24a0d..a105b73e 100644 --- a/docs/resources/cloud-watch-logs-log-group.md +++ b/docs/resources/cloud-watch-logs-log-group.md @@ -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::`: 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.