-
Notifications
You must be signed in to change notification settings - Fork 288
Expand file tree
/
Copy pathclean_failed_tests_aws_assets.sh
More file actions
executable file
·269 lines (240 loc) · 11.4 KB
/
clean_failed_tests_aws_assets.sh
File metadata and controls
executable file
·269 lines (240 loc) · 11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
#!/bin/bash
# clean_failed_tests_aws_assets.sh
# Cleans up orphaned AWS test resources identified by the Environment=Test tag.
#
# Usage:
# ./clean_failed_tests_aws_assets.sh # delete tagged resources
# ./clean_failed_tests_aws_assets.sh --dry-run # list without deleting
# Intentionally omitting -e: individual deletion failures are soft errors handled inline.
set -uo pipefail
DRY_RUN=false
if [[ "${1:-}" == "--dry-run" ]]; then
DRY_RUN=true
echo "[DRY RUN] No resources will be deleted"
fi
# --- Helper: delete all schedules in a given group ---
# AWS CLI v2 auto-paginates by default, so all schedules are returned across pages.
delete_schedules_in_group() {
local group_name="$1"
local schedules
schedules=$(aws scheduler list-schedules --group-name "$group_name" \
--query 'Schedules[*].Name' --output text 2>&1 || echo "")
for sched_name in $schedules; do
[[ -z "$sched_name" || "$sched_name" == "None" ]] && continue
if $DRY_RUN; then
echo " [DRY RUN] Would delete schedule: $sched_name (group: $group_name)"
else
echo " Deleting schedule: $sched_name (group: $group_name)"
aws scheduler delete-schedule --name "$sched_name" --group-name "$group_name" 2>&1 \
|| echo " WARNING: failed to delete schedule $sched_name"
fi
done
}
# --- Discover tagged resources via Resource Groups Tagging API ---
# Note: AWS CLI v2 auto-paginates by default. The --query/--output flags are applied
# after all pages are aggregated, so this handles >100 resources without manual pagination.
echo "Querying resources tagged Environment=Test ..."
RESOURCE_ARNS=$(aws resourcegroupstaggingapi get-resources \
--tag-filters Key=Environment,Values=Test \
--resource-type-filters sqs:queue sns:topic scheduler:schedule-group \
--query 'ResourceTagMappingList[*].ResourceARN' \
--output text 2>&1)
TAG_API_EXIT=$?
if [[ $TAG_API_EXIT -ne 0 ]]; then
echo "ERROR: Failed to query Resource Groups Tagging API (exit code $TAG_API_EXIT)."
echo " Ensure the caller has the resourcegroupstaggingapi:GetResources IAM permission."
echo " Response: $RESOURCE_ARNS"
exit 1
fi
if [[ -z "$RESOURCE_ARNS" || "$RESOURCE_ARNS" == "None" ]]; then
echo "No resources found with Environment=Test tag."
fi
# --- Categorise ARNs by resource type ---
# Note: SNS subscriptions cannot be tagged and will not appear in the Tagging API response.
# Subscriptions are cleaned up implicitly in the topic-deletion loop below via list-subscriptions-by-topic.
# The subscription bucket is kept for completeness in case AWS adds subscription tagging in future.
SUBSCRIPTIONS=()
TOPICS=()
QUEUES=()
SCHEDULE_GROUPS=()
if [[ -n "$RESOURCE_ARNS" && "$RESOURCE_ARNS" != "None" ]]; then
for arn in $RESOURCE_ARNS; do
# Count colons to distinguish SNS topics (5 colons) from subscriptions (6 colons)
COLON_COUNT=$(echo "$arn" | tr -cd ':' | wc -c | tr -d ' ')
case "$arn" in
*:sns:*)
if [[ "$COLON_COUNT" -ge 6 ]]; then
SUBSCRIPTIONS+=("$arn")
else
TOPICS+=("$arn")
fi
;;
*:sqs:*)
QUEUES+=("$arn")
;;
*:scheduler:*/schedule-group/*)
SCHEDULE_GROUPS+=("$arn")
;;
*)
echo " Skipping unknown resource type: $arn"
;;
esac
done
fi
echo "Found: ${#SUBSCRIPTIONS[@]} subscription(s), ${#TOPICS[@]} topic(s), ${#QUEUES[@]} queue(s), ${#SCHEDULE_GROUPS[@]} schedule group(s)"
# --- Delete in order: subscriptions, then topics, then queues, then schedule groups ---
# 1. Subscriptions
if [[ ${#SUBSCRIPTIONS[@]} -gt 0 ]]; then
for arn in "${SUBSCRIPTIONS[@]}"; do
if $DRY_RUN; then
echo " [DRY RUN] Would delete subscription: $arn"
else
echo " Deleting subscription: $arn"
aws sns unsubscribe --subscription-arn "$arn" 2>&1 || echo " WARNING: failed to delete subscription $arn"
fi
done
fi
# 2. Topics
if [[ ${#TOPICS[@]} -gt 0 ]]; then
for arn in "${TOPICS[@]}"; do
# Delete any subscriptions on this topic that weren't tagged individually
if ! $DRY_RUN; then
TOPIC_SUBS=$(aws sns list-subscriptions-by-topic --topic-arn "$arn" \
--query 'Subscriptions[*].SubscriptionArn' --output text 2>&1 || echo "")
for sub_arn in $TOPIC_SUBS; do
[[ "$sub_arn" == "PendingConfirmation" ]] && continue
echo " Deleting subscription on topic: $sub_arn"
aws sns unsubscribe --subscription-arn "$sub_arn" 2>&1 || echo " WARNING: failed to delete subscription $sub_arn"
done
fi
if $DRY_RUN; then
echo " [DRY RUN] Would delete topic: $arn"
else
echo " Deleting topic: $arn"
aws sns delete-topic --topic-arn "$arn" 2>&1 || echo " WARNING: failed to delete topic $arn"
fi
done
fi
# 3. Queues — need queue URL from ARN
if [[ ${#QUEUES[@]} -gt 0 ]]; then
for arn in "${QUEUES[@]}"; do
# Extract queue name from ARN (last segment)
QUEUE_NAME="${arn##*:}"
if $DRY_RUN; then
echo " [DRY RUN] Would delete queue: $QUEUE_NAME ($arn)"
else
QUEUE_URL=$(aws sqs get-queue-url --queue-name "$QUEUE_NAME" --query 'QueueUrl' --output text 2>&1 || echo "")
if [[ -n "$QUEUE_URL" && "$QUEUE_URL" != *"NonExistentQueue"* ]]; then
echo " Deleting queue: $QUEUE_NAME ($QUEUE_URL)"
aws sqs delete-queue --queue-url "$QUEUE_URL" 2>&1 || echo " WARNING: failed to delete queue $QUEUE_NAME"
else
echo " Queue already gone: $QUEUE_NAME"
fi
fi
done
fi
# 4. EventBridge Scheduler — delete schedules within groups, then the groups themselves
if [[ ${#SCHEDULE_GROUPS[@]} -gt 0 ]]; then
for arn in "${SCHEDULE_GROUPS[@]}"; do
# Extract group name from ARN (last segment after schedule-group/)
GROUP_NAME="${arn##*/}"
# Skip the 'default' group — it cannot be deleted, but we clean its schedules
if [[ "$GROUP_NAME" == "default" ]]; then
echo " Cleaning schedules in default group (group itself cannot be deleted)"
delete_schedules_in_group "$GROUP_NAME"
continue
fi
echo " Processing schedule group: $GROUP_NAME"
delete_schedules_in_group "$GROUP_NAME"
if $DRY_RUN; then
echo " [DRY RUN] Would delete schedule group: $GROUP_NAME"
else
echo " Deleting schedule group: $GROUP_NAME"
aws scheduler delete-schedule-group --name "$GROUP_NAME" 2>&1 \
|| echo " WARNING: failed to delete schedule group $GROUP_NAME"
fi
done
fi
# --- Also clean up Brighter-tagged schedule groups (Source=Brighter) not caught above ---
# The AwsSchedulerFactory tags groups with Source=Brighter. We require both Source=Brighter
# AND Environment=Test to avoid accidentally deleting non-test resources in shared accounts.
echo "Checking for Brighter-tagged schedule groups ..."
BRIGHTER_GROUPS=$(aws resourcegroupstaggingapi get-resources \
--tag-filters Key=Source,Values=Brighter Key=Environment,Values=Test \
--resource-type-filters scheduler:schedule-group \
--query 'ResourceTagMappingList[*].ResourceARN' \
--output text 2>&1 || echo "")
if [[ -n "$BRIGHTER_GROUPS" && "$BRIGHTER_GROUPS" != "None" ]]; then
for arn in $BRIGHTER_GROUPS; do
GROUP_NAME="${arn##*/}"
[[ "$GROUP_NAME" == "default" ]] && continue
# Skip if already processed above
if [[ ${#SCHEDULE_GROUPS[@]} -gt 0 ]] && printf '%s\n' "${SCHEDULE_GROUPS[@]}" | grep -qF "$arn"; then
continue
fi
echo " Processing Brighter schedule group: $GROUP_NAME"
delete_schedules_in_group "$GROUP_NAME"
if $DRY_RUN; then
echo " [DRY RUN] Would delete Brighter schedule group: $GROUP_NAME"
else
echo " Deleting Brighter schedule group: $GROUP_NAME"
aws scheduler delete-schedule-group --name "$GROUP_NAME" 2>&1 \
|| echo " WARNING: failed to delete schedule group $GROUP_NAME"
fi
done
else
echo " No additional Brighter schedule groups found."
fi
# --- Fallback: clean up untagged test resources by naming convention ---
# Some test fixtures (particularly FIFO tests) were not tagged with Environment=Test.
# These are identified by their naming pattern: <TestPrefix>-<GUID> (truncated to 45 chars).
# This section lists all topics/queues and deletes those matching known test prefixes.
TEST_PREFIXES="Producer-Send-Tests|Producer-Requeue-Tests|Producer-DLQ-Tests|Producer-Scheduler-Tests|Producer-Scheduler-Async-Tests|Producer-Fire-Scheduler-Tests|Producer-Fire-Scheduler-Async-Tests|Producer-Tag-Tests|Producer-FSR-Tests|Producer-FSRA-Tests|Consumer-Requeue-Tests|Consumer-DLQ-Tests|Consumer-Fallback-Tests|Consumer-Invalid-Tests|Consumer-NoChan-Tests|Buffered-Consumer-Tests|Buffered-Scheduler-Tests|Buffered-Scheduler-Async-Tests|Buffered-FSR-Tests|Redrive-Tests|Redrive-DLQ-Tests|Raw-Msg-Delivery-Tests"
echo ""
echo "Scanning for untagged test resources by naming convention ..."
# Clean untagged SNS topics
ALL_TOPICS=$(aws sns list-topics --query 'Topics[*].TopicArn' --output text 2>&1 || echo "")
UNTAGGED_TOPIC_COUNT=0
if [[ -n "$ALL_TOPICS" && "$ALL_TOPICS" != "None" ]]; then
for topic_arn in $ALL_TOPICS; do
TOPIC_NAME="${topic_arn##*:}"
if echo "$TOPIC_NAME" | grep -qE "^($TEST_PREFIXES)"; then
UNTAGGED_TOPIC_COUNT=$((UNTAGGED_TOPIC_COUNT + 1))
if $DRY_RUN; then
echo " [DRY RUN] Would delete untagged test topic: $TOPIC_NAME"
else
# Delete subscriptions first
TOPIC_SUBS=$(aws sns list-subscriptions-by-topic --topic-arn "$topic_arn" \
--query 'Subscriptions[*].SubscriptionArn' --output text 2>&1 || echo "")
for sub_arn in $TOPIC_SUBS; do
[[ "$sub_arn" == "PendingConfirmation" || -z "$sub_arn" || "$sub_arn" == "None" ]] && continue
aws sns unsubscribe --subscription-arn "$sub_arn" 2>&1 || true
done
echo " Deleting untagged test topic: $TOPIC_NAME"
aws sns delete-topic --topic-arn "$topic_arn" 2>&1 || echo " WARNING: failed to delete topic $TOPIC_NAME"
fi
fi
done
fi
echo " Found $UNTAGGED_TOPIC_COUNT untagged test topic(s)"
# Clean untagged SQS queues
ALL_QUEUES=$(aws sqs list-queues --query 'QueueUrls[*]' --output text 2>&1 || echo "")
UNTAGGED_QUEUE_COUNT=0
if [[ -n "$ALL_QUEUES" && "$ALL_QUEUES" != "None" ]]; then
for queue_url in $ALL_QUEUES; do
QUEUE_NAME="${queue_url##*/}"
if echo "$QUEUE_NAME" | grep -qE "^($TEST_PREFIXES)"; then
UNTAGGED_QUEUE_COUNT=$((UNTAGGED_QUEUE_COUNT + 1))
if $DRY_RUN; then
echo " [DRY RUN] Would delete untagged test queue: $QUEUE_NAME"
else
echo " Deleting untagged test queue: $QUEUE_NAME"
aws sqs delete-queue --queue-url "$queue_url" 2>&1 || echo " WARNING: failed to delete queue $QUEUE_NAME"
fi
fi
done
fi
echo " Found $UNTAGGED_QUEUE_COUNT untagged test queue(s)"
echo ""
echo "Cleanup complete."
exit 0