Skip to content

Commit

Permalink
refactor cloudwatch resource types (#512)
Browse files Browse the repository at this point in the history
  • Loading branch information
james03160927 authored Jul 24, 2023
1 parent db4cada commit 65bd31b
Show file tree
Hide file tree
Showing 10 changed files with 304 additions and 566 deletions.
6 changes: 3 additions & 3 deletions aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -1137,7 +1137,7 @@ func GetAllResources(targetRegions []string, excludeAfter time.Time, resourceTyp
}
if IsNukeable(cloudwatchDashboards.ResourceName(), resourceTypes) {
start := time.Now()
cwdbNames, err := getAllCloudWatchDashboards(cloudNukeSession, excludeAfter, configObj)
cwdbNames, err := cloudwatchDashboards.getAll(configObj)
if err != nil {
ge := report.GeneralError{
Error: err,
Expand Down Expand Up @@ -1168,7 +1168,7 @@ func GetAllResources(targetRegions []string, excludeAfter time.Time, resourceTyp
}
if IsNukeable(cloudwatchLogGroups.ResourceName(), resourceTypes) {
start := time.Now()
lgNames, err := getAllCloudWatchLogGroups(cloudNukeSession, excludeAfter, configObj)
lgNames, err := cloudwatchLogGroups.getAll(configObj)
if err != nil {
ge := report.GeneralError{
Error: err,
Expand Down Expand Up @@ -1863,7 +1863,7 @@ func GetAllResources(targetRegions []string, excludeAfter time.Time, resourceTyp
}
if IsNukeable(cloudwatchAlarms.ResourceName(), resourceTypes) {
start := time.Now()
cwalNames, err := getAllCloudWatchAlarms(cloudNukeSession, excludeAfter, configObj)
cwalNames, err := cloudwatchAlarms.getAll(configObj)
if err != nil {
ge := report.GeneralError{
Error: err,
Expand Down
80 changes: 23 additions & 57 deletions aws/cloudwatch_alarm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,37 @@ package aws

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/gruntwork-io/cloud-nuke/config"
"github.com/gruntwork-io/cloud-nuke/logging"
"github.com/gruntwork-io/cloud-nuke/report"
"github.com/gruntwork-io/cloud-nuke/telemetry"
"github.com/gruntwork-io/go-commons/errors"
commonTelemetry "github.com/gruntwork-io/go-commons/telemetry"
"time"

"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/gruntwork-io/cloud-nuke/config"
)

func getAllCloudWatchAlarms(session *session.Session, excludeAfter time.Time, configObj config.Config) ([]*string, error) {
svc := cloudwatch.New(session)

func (cw CloudWatchAlarms) getAll(configObj config.Config) ([]*string, error) {
allAlarms := []*string{}
input := &cloudwatch.DescribeAlarmsInput{
AlarmTypes: aws.StringSlice([]string{cloudwatch.AlarmTypeMetricAlarm, cloudwatch.AlarmTypeCompositeAlarm}),
}
err := svc.DescribeAlarmsPages(
err := cw.Client.DescribeAlarmsPages(
input,
func(page *cloudwatch.DescribeAlarmsOutput, lastPage bool) bool {
for _, alarm := range page.MetricAlarms {
if shouldIncludeCloudWatchMetricAlarm(alarm, excludeAfter, configObj) {
if configObj.CloudWatchAlarm.ShouldInclude(config.ResourceValue{
Name: alarm.AlarmName,
Time: alarm.AlarmConfigurationUpdatedTimestamp,
}) {
allAlarms = append(allAlarms, alarm.AlarmName)
}
}

for _, alarm := range page.CompositeAlarms {
if shouldIncludeCloudWatchCompositeAlarm(alarm, excludeAfter, configObj) {
if configObj.CloudWatchAlarm.ShouldInclude(config.ResourceValue{
Name: alarm.AlarmName,
Time: alarm.AlarmConfigurationUpdatedTimestamp,
}) {
allAlarms = append(allAlarms, alarm.AlarmName)
}
}
Expand All @@ -40,45 +42,9 @@ func getAllCloudWatchAlarms(session *session.Session, excludeAfter time.Time, co
return allAlarms, errors.WithStackTrace(err)
}

func shouldIncludeCloudWatchCompositeAlarm(alarm *cloudwatch.CompositeAlarm, excludeAfter time.Time, configObj config.Config) bool {
if alarm == nil {
return false
}

if alarm.AlarmConfigurationUpdatedTimestamp != nil && excludeAfter.Before(*alarm.AlarmConfigurationUpdatedTimestamp) {
return false
}

return config.ShouldInclude(
aws.StringValue(alarm.AlarmName),
configObj.CloudWatchAlarm.IncludeRule.NamesRegExp,
configObj.CloudWatchAlarm.ExcludeRule.NamesRegExp,
)
}

func shouldIncludeCloudWatchMetricAlarm(alarm *cloudwatch.MetricAlarm, excludeAfter time.Time, configObj config.Config) bool {
if alarm == nil {
return false
}

if alarm.AlarmConfigurationUpdatedTimestamp != nil && excludeAfter.Before(*alarm.AlarmConfigurationUpdatedTimestamp) {
return false
}

return config.ShouldInclude(
aws.StringValue(alarm.AlarmName),
configObj.CloudWatchAlarm.IncludeRule.NamesRegExp,
configObj.CloudWatchAlarm.ExcludeRule.NamesRegExp,
)
}

func nukeAllCloudWatchAlarms(session *session.Session, identifiers []*string) error {
region := aws.StringValue(session.Config.Region)

svc := cloudwatch.New(session)

func (cw CloudWatchAlarms) nukeAll(identifiers []*string) error {
if len(identifiers) == 0 {
logging.Logger.Debugf("No CloudWatch Alarms to nuke in region %s", region)
logging.Logger.Debugf("No CloudWatch Alarms to nuke in region %s", cw.Region)
return nil
}

Expand All @@ -91,10 +57,10 @@ func nukeAllCloudWatchAlarms(session *session.Session, identifiers []*string) er
return TooManyCloudWatchAlarmsErr{}
}

logging.Logger.Debugf("Deleting CloudWatch Alarms in region %s", region)
logging.Logger.Debugf("Deleting CloudWatch Alarms in region %s", cw.Region)

// If the alarm's type is composite alarm, remove the dependency by removing the rule.
alarms, err := svc.DescribeAlarms(&cloudwatch.DescribeAlarmsInput{
alarms, err := cw.Client.DescribeAlarms(&cloudwatch.DescribeAlarmsInput{
AlarmTypes: aws.StringSlice([]string{cloudwatch.AlarmTypeMetricAlarm, cloudwatch.AlarmTypeCompositeAlarm}),
AlarmNames: identifiers,
})
Expand All @@ -103,12 +69,12 @@ func nukeAllCloudWatchAlarms(session *session.Session, identifiers []*string) er
telemetry.TrackEvent(commonTelemetry.EventContext{
EventName: "Error Nuking Cloudwatch Alarm Dependency",
}, map[string]interface{}{
"region": *session.Config.Region,
"region": cw.Region,
})
}

for _, compositeAlarm := range alarms.CompositeAlarms {
_, err := svc.PutCompositeAlarm(&cloudwatch.PutCompositeAlarmInput{
_, err := cw.Client.PutCompositeAlarm(&cloudwatch.PutCompositeAlarmInput{
AlarmName: compositeAlarm.AlarmName,
AlarmRule: aws.String("FALSE"),
})
Expand All @@ -117,13 +83,13 @@ func nukeAllCloudWatchAlarms(session *session.Session, identifiers []*string) er
telemetry.TrackEvent(commonTelemetry.EventContext{
EventName: "Error Nuking Cloudwatch Composite Alarm",
}, map[string]interface{}{
"region": *session.Config.Region,
"region": cw.Region,
})
}
}

input := cloudwatch.DeleteAlarmsInput{AlarmNames: identifiers}
_, err = svc.DeleteAlarms(&input)
_, err = cw.Client.DeleteAlarms(&input)

// Record status of this resource
e := report.BatchEntry{
Expand All @@ -138,13 +104,13 @@ func nukeAllCloudWatchAlarms(session *session.Session, identifiers []*string) er
telemetry.TrackEvent(commonTelemetry.EventContext{
EventName: "Error Nuking Cloudwatch Alarm",
}, map[string]interface{}{
"region": *session.Config.Region,
"region": cw.Region,
})
return errors.WithStackTrace(err)
}

for _, alarmName := range identifiers {
logging.Logger.Debugf("[OK] CloudWatch Alarm %s was deleted in %s", aws.StringValue(alarmName), region)
logging.Logger.Debugf("[OK] CloudWatch Alarm %s was deleted in %s", aws.StringValue(alarmName), cw.Region)
}
return nil
}
Expand Down
Loading

0 comments on commit 65bd31b

Please sign in to comment.