diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fad10a..61035ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## [2.2.10] - 2026-01-06 + +### Fixed +- **LocalStack `localstack/s3/list-all` and `localstack/sqs/purge-all` syntax error**: Using `$(foreach)` in recipes with `.ONESHELL` caused bash syntax errors due to multi-line output from `mb_invoke` + - Moved iteration logic to external shell scripts for cleaner execution + +### Changed +- **`localstack/s3/list-all` improved output**: Now displays buckets and objects in a tree view with human-readable file sizes and timestamps + +### Added +- **LocalStack scripts folder**: `modules/cloud_providers/localstack/scripts/` + - `s3-list-all.sh` - Lists all S3 buckets and their contents in tree format + - `sqs-purge-all.sh` - Purges all SQS queues + ## [2.2.9] - 2026-01-04 ### Fixed diff --git a/modules/cloud_providers/localstack/localstack.mk b/modules/cloud_providers/localstack/localstack.mk index dc88cb9..f6cebcc 100644 --- a/modules/cloud_providers/localstack/localstack.mk +++ b/modules/cloud_providers/localstack/localstack.mk @@ -167,38 +167,13 @@ localstack/s3/ls: ## List S3 buckets or bucket contents (optional: bucket=my-buc $(call localstack_cmd,s3 ls $(if $(value bucket),s3://$(bucket),)) localstack/s3/list-all: ## List all S3 buckets with details - $(call localstack_cmd,s3 ls) - echo "" - $(call mb_printf_info,Listing contents of all buckets:) - $(let mb_invoke_run_in_shell,$(mb_on),\ - $(call localstack_cmd,s3api list-buckets --query "Buckets[].Name" --output text)\ - ) - $(eval _buckets := $(mb_invoke_shell_output)) - $(if $(strip $(_buckets)),\ - $(foreach b,$(strip $(_buckets)),\ - echo "";\ - $(call mb_printf_info,Bucket: $(b));\ - $(call localstack_cmd,s3 ls s3://$(b) --recursive) || echo " (empty)";\ - ),\ - $(call mb_printf_warn,No buckets found)\ - ) + $(call mb_invoke,$(mb_modules_path)/cloud_providers/localstack/scripts/s3-list-all.sh $(localstack_endpoint_url) $(localstack_region)) localstack/sqs/ls: ## List all SQS queues $(call localstack_cmd,sqs list-queues) localstack/sqs/purge-all: ## Purge all SQS queues (use with caution!) - $(call mb_printf_warn,Purging all SQS queues...) - $(let mb_invoke_run_in_shell,$(mb_on),\ - $(call localstack_cmd,sqs list-queues --query "QueueUrls[]" --output text)\ - ) - $(eval _queue_urls := $(mb_invoke_shell_output)) - $(if $(strip $(_queue_urls)),\ - $(foreach url,$(strip $(_queue_urls)),\ - $(call mb_printf_info,Purging: $(url));\ - $(call localstack_cmd,sqs purge-queue --queue-url $(url)) || true;\ - ),\ - $(call mb_printf_warn,No queues found)\ - ) + $(call mb_invoke,$(mb_modules_path)/cloud_providers/localstack/scripts/sqs-purge-all.sh $(localstack_endpoint_url) $(localstack_region)) ##################################################################################### # AWS Module Integration - The Magic Redirect diff --git a/modules/cloud_providers/localstack/scripts/s3-list-all.sh b/modules/cloud_providers/localstack/scripts/s3-list-all.sh new file mode 100755 index 0000000..efb1b9f --- /dev/null +++ b/modules/cloud_providers/localstack/scripts/s3-list-all.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +##################################################################################### +# s3-list-all.sh +# List all S3 buckets and their contents from LocalStack (tree view) +# +# Usage: s3-list-all.sh +# +# Arguments: +# endpoint_url - LocalStack endpoint (e.g., http://localhost:4566) +# region - AWS region (e.g., eu-west-1) +# +# Prerequisites: +# - aws CLI installed and on PATH +# - LocalStack running and accessible +##################################################################################### + +set -euo pipefail + +readonly ENDPOINT_URL="${1:?Usage: $0 }" +readonly REGION="${2:?Usage: $0 }" + +aws_cmd() { + aws --endpoint-url "$ENDPOINT_URL" --region "$REGION" "$@" +} + +human_size() { + local bytes=$1 + if [[ $bytes -ge 1073741824 ]]; then + printf "%.1f GB" "$(echo "scale=1; $bytes / 1073741824" | bc)" + elif [[ $bytes -ge 1048576 ]]; then + printf "%.1f MB" "$(echo "scale=1; $bytes / 1048576" | bc)" + elif [[ $bytes -ge 1024 ]]; then + printf "%.1f KB" "$(echo "scale=1; $bytes / 1024" | bc)" + else + printf "%d B" "$bytes" + fi +} + +echo "S3 Buckets:" +echo "" + +buckets=$(aws_cmd s3api list-buckets --query "Buckets[].Name" --output text 2>/dev/null || echo "") + +if [[ -z "$buckets" ]]; then + echo " (no buckets found)" + exit 0 +fi + +bucket_array=($buckets) +total_buckets=${#bucket_array[@]} +bucket_index=0 + +for bucket in "${bucket_array[@]}"; do + bucket_index=$((bucket_index + 1)) + is_last_bucket=$([[ $bucket_index -eq $total_buckets ]] && echo 1 || echo 0) + + if [[ $is_last_bucket -eq 1 ]]; then + echo "└── $bucket/" + prefix=" " + else + echo "├── $bucket/" + prefix="│ " + fi + + # Get objects in bucket (LastModified, Size, Key) + objects=$(aws_cmd s3api list-objects-v2 --bucket "$bucket" --query "Contents[].[LastModified,Size,Key]" --output text 2>/dev/null || echo "") + + if [[ -z "$objects" || "$objects" == "None" ]]; then + echo "${prefix}└── (empty)" + else + # Count objects for proper tree formatting + object_count=$(echo "$objects" | wc -l) + object_index=0 + + while IFS=$'\t' read -r timestamp size key; do + object_index=$((object_index + 1)) + is_last_object=$([[ $object_index -eq $object_count ]] && echo 1 || echo 0) + + size_human=$(human_size "$size") + # Format timestamp: 2026-01-06T11:14:41+00:00 -> 2026-01-06 11:14:41 + timestamp_formatted=$(echo "$timestamp" | sed 's/T/ /; s/+.*//') + + if [[ $is_last_object -eq 1 ]]; then + echo "${prefix}└── $timestamp_formatted $key ($size_human)" + else + echo "${prefix}├── $timestamp_formatted $key ($size_human)" + fi + done <<< "$objects" + fi +done diff --git a/modules/cloud_providers/localstack/scripts/sqs-purge-all.sh b/modules/cloud_providers/localstack/scripts/sqs-purge-all.sh new file mode 100755 index 0000000..484f184 --- /dev/null +++ b/modules/cloud_providers/localstack/scripts/sqs-purge-all.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +##################################################################################### +# sqs-purge-all.sh +# Purge all SQS queues in LocalStack +# +# Usage: sqs-purge-all.sh +# +# Arguments: +# endpoint_url - LocalStack endpoint (e.g., http://localhost:4566) +# region - AWS region (e.g., eu-west-1) +# +# Prerequisites: +# - aws CLI installed and on PATH +# - LocalStack running and accessible +# +# WARNING: This will delete all messages from all queues! +##################################################################################### + +set -euo pipefail + +readonly ENDPOINT_URL="${1:?Usage: $0 }" +readonly REGION="${2:?Usage: $0 }" + +aws_cmd() { + aws --endpoint-url "$ENDPOINT_URL" --region "$REGION" "$@" +} + +echo "WARNING: Purging all SQS queues..." + +queue_urls=$(aws_cmd sqs list-queues --query "QueueUrls[]" --output text 2>/dev/null || echo "") + +if [[ -z "$queue_urls" ]]; then + echo "No queues found" + exit 0 +fi + +for url in $queue_urls; do + echo " Purging: $url" + aws_cmd sqs purge-queue --queue-url "$url" 2>/dev/null || true +done + +echo "Done"