diff --git a/.github/workflows/clean-aws-resources.yml b/.github/workflows/clean-aws-resources.yml index 69afd07e6f3..1140bed3371 100644 --- a/.github/workflows/clean-aws-resources.yml +++ b/.github/workflows/clean-aws-resources.yml @@ -309,3 +309,25 @@ jobs: set -e go run ./clean_security_group/clean_security_group.go || { echo "Failed to clean security groups"; exit 1; } + clean-ssm-documents: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ vars.TERRAFORM_AWS_ASSUME_ROLE }} + aws-region: us-west-2 + + - name: Clean Old Test SSM Documents and Parameters + working-directory: tool/clean + run: | + set -e + echo "Cleaning test SSM documents and parameters in us-west-2" + go run ./clean_ssm_documents/clean_ssm_documents.go --dry-run=false || { echo "Failed to clean SSM documents in us-west-2"; exit 1; } + diff --git a/tool/clean/clean_ssm_documents/README.md b/tool/clean/clean_ssm_documents/README.md new file mode 100644 index 00000000000..81eb57e85ec --- /dev/null +++ b/tool/clean/clean_ssm_documents/README.md @@ -0,0 +1,43 @@ +# SSM Documents and Parameters Cleanup Tool + +This tool cleans up test SSM documents and parameters that may be left behind from CloudWatch Agent testing. + +## What it cleans + +### SSM Documents +- Documents with prefixes: + - `Test-AmazonCloudWatch-ManageAgent-` (used by ssm_document tests) + +### SSM Parameters +- Parameters with exact names: + - `agentConfig1` (used by ssm_document tests) + - `agentConfig2` (used by ssm_document tests) + +**Note**: These patterns have been verified to only match test resources and will not affect production SSM documents or parameters. + +## Usage + +```bash +# Dry run (default) - shows what would be deleted without actually deleting +go run ./clean_ssm_documents.go + +# Actually delete resources +go run ./clean_ssm_documents.go --dry-run=false + +# Enable verbose logging to see all API calls +go run ./clean_ssm_documents.go --verbose + +# Combine flags +go run ./clean_ssm_documents.go --dry-run=false --verbose +``` + +## Configuration + +The tool is configured to: +- Clean resources older than 1 day +- Use 10 concurrent workers for processing +- Run in dry-run mode by default for safety + +## Integration + +This tool is integrated into the GitHub Actions workflow `clean-aws-resources.yml` and runs daily across multiple AWS regions to clean up test resources automatically. \ No newline at end of file diff --git a/tool/clean/clean_ssm_documents/clean_ssm_documents.go b/tool/clean/clean_ssm_documents/clean_ssm_documents.go new file mode 100644 index 00000000000..c44128a1b21 --- /dev/null +++ b/tool/clean/clean_ssm_documents/clean_ssm_documents.go @@ -0,0 +1,422 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: MIT + +package main + +import ( + "context" + "flag" + "fmt" + "log" + "strings" + "sync" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/aws/aws-sdk-go-v2/service/ssm/types" + + "github.com/aws/amazon-cloudwatch-agent/tool/clean" +) + +type ssmClient interface { + ListDocuments(ctx context.Context, params *ssm.ListDocumentsInput, optFns ...func(*ssm.Options)) (*ssm.ListDocumentsOutput, error) + DeleteDocument(ctx context.Context, params *ssm.DeleteDocumentInput, optFns ...func(*ssm.Options)) (*ssm.DeleteDocumentOutput, error) + DescribeParameters(ctx context.Context, params *ssm.DescribeParametersInput, optFns ...func(*ssm.Options)) (*ssm.DescribeParametersOutput, error) + DeleteParameter(ctx context.Context, params *ssm.DeleteParameterInput, optFns ...func(*ssm.Options)) (*ssm.DeleteParameterOutput, error) +} + +const ( + SSMProcessChanSize = 100 +) + +// Config holds the application configuration +type Config struct { + creationThreshold time.Duration + numWorkers int + dryRun bool + verbose bool + testDocumentPrefixes []string + testParameterPrefixes []string +} + +// Global configuration +var ( + cfg Config +) + +func init() { + // Set default configuration + cfg = Config{ + creationThreshold: 1 * clean.KeepDurationOneDay, // Clean documents older than 1 day + numWorkers: 10, + dryRun: true, + verbose: false, + testDocumentPrefixes: []string{ + "Test-AmazonCloudWatch-ManageAgent-", // Used by ssm_document tests + }, + testParameterPrefixes: []string{ + // Used by ssm_document tests + "agentConfig1", + "agentConfig2", + }, + } +} + +func main() { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute) + defer cancel() + + // Parse command line flags + flag.BoolVar(&cfg.dryRun, "dry-run", true, "Enable dry-run mode (no actual deletion)") + flag.BoolVar(&cfg.verbose, "verbose", false, "Enable verbose logging") + flag.Parse() + + // Load AWS configuration + awsCfg, err := loadAWSConfig(ctx) + if err != nil { + log.Fatalf("Error loading AWS config: %v", err) + } + + // Create SSM client + client := ssm.NewFromConfig(awsCfg) + + // Compute cutoff time (resources older than this will be cleaned) + cutoffTime := time.Now().Add(cfg.creationThreshold) // creationThreshold is negative, so this gives us a past time + + log.Printf("🔍 Searching for test SSM documents and parameters older than %v (cutoff: %v) in %s region\n", + -cfg.creationThreshold, cutoffTime.Format("2006-01-02 15:04:05 UTC"), awsCfg.Region) + + // Clean old test documents + deletedDocs := cleanOldTestDocuments(ctx, client, cutoffTime) + log.Printf("📄 Total test documents processed: %d", len(deletedDocs)) + + // Clean old test parameters + deletedParams := cleanOldTestParameters(ctx, client, cutoffTime) + log.Printf("⚙️ Total test parameters processed: %d", len(deletedParams)) + + // Summary + if len(deletedDocs) > 0 || len(deletedParams) > 0 { + log.Printf("✅ Cleanup completed: %d documents, %d parameters", len(deletedDocs), len(deletedParams)) + } else { + log.Printf("✅ No test resources found to clean up") + } +} + +func loadAWSConfig(ctx context.Context) (aws.Config, error) { + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + return aws.Config{}, fmt.Errorf("loading AWS config: %w", err) + } + cfg.RetryMode = aws.RetryModeAdaptive + return cfg, nil +} + +func cleanOldTestDocuments(ctx context.Context, client ssmClient, cutoffTime time.Time) []string { + var ( + wg sync.WaitGroup + deletedDocuments []string + foundDocumentChan = make(chan *types.DocumentIdentifier, SSMProcessChanSize) + deletedDocumentChan = make(chan string, SSMProcessChanSize) + handlerWg sync.WaitGroup + ) + + // Start worker pool + log.Printf("👷 Creating %d workers for document cleanup\n", cfg.numWorkers) + for i := 0; i < cfg.numWorkers; i++ { + wg.Add(1) + w := documentWorker{ + id: i, + wg: &wg, + incomingDocumentChan: foundDocumentChan, + deletedDocumentChan: deletedDocumentChan, + cutoffTime: cutoffTime, + } + go w.processDocument(ctx, client) + } + + // Start handler + handlerWg.Add(1) + go func() { + handleDeletedDocuments(&deletedDocuments, deletedDocumentChan) + handlerWg.Done() + }() + + // Fetch and process documents + if err := fetchAndProcessDocuments(ctx, client, foundDocumentChan); err != nil { + log.Printf("Error processing documents: %v", err) + } + + close(foundDocumentChan) + wg.Wait() + close(deletedDocumentChan) + handlerWg.Wait() + + return deletedDocuments +} + +func cleanOldTestParameters(ctx context.Context, client ssmClient, cutoffTime time.Time) []string { + var ( + wg sync.WaitGroup + deletedParameters []string + foundParameterChan = make(chan *types.ParameterMetadata, SSMProcessChanSize) + deletedParameterChan = make(chan string, SSMProcessChanSize) + handlerWg sync.WaitGroup + ) + + // Start worker pool + log.Printf("👷 Creating %d workers for parameter cleanup\n", cfg.numWorkers) + for i := 0; i < cfg.numWorkers; i++ { + wg.Add(1) + w := parameterWorker{ + id: i, + wg: &wg, + incomingParameterChan: foundParameterChan, + deletedParameterChan: deletedParameterChan, + cutoffTime: cutoffTime, + } + go w.processParameter(ctx, client) + } + + // Start handler + handlerWg.Add(1) + go func() { + handleDeletedParameters(&deletedParameters, deletedParameterChan) + handlerWg.Done() + }() + + // Fetch and process parameters + if err := fetchAndProcessParameters(ctx, client, foundParameterChan); err != nil { + log.Printf("Error processing parameters: %v", err) + } + + close(foundParameterChan) + wg.Wait() + close(deletedParameterChan) + handlerWg.Wait() + + return deletedParameters +} + +type documentWorker struct { + id int + wg *sync.WaitGroup + incomingDocumentChan <-chan *types.DocumentIdentifier + deletedDocumentChan chan<- string + cutoffTime time.Time +} + +func (w *documentWorker) processDocument(ctx context.Context, client ssmClient) { + defer w.wg.Done() + + for document := range w.incomingDocumentChan { + if err := w.handleDocument(ctx, client, document); err != nil { + log.Printf("Worker %d: Error processing document: %v", w.id, err) + } + } +} + +func (w *documentWorker) handleDocument(ctx context.Context, client ssmClient, document *types.DocumentIdentifier) error { + if document.CreatedDate == nil || document.Name == nil { + return fmt.Errorf("document has missing required fields: %v", document) + } + + documentName := *document.Name + createdDate := *document.CreatedDate + + // Check if document is old enough and matches test patterns + if createdDate.After(w.cutoffTime) { + // Document is too new, skip it + return nil + } + + if !isTestDocument(documentName) { + return nil + } + + log.Printf("🚨 Worker: %d| Old Test Document: %s (Created: %v)\n", + w.id, documentName, createdDate) + + w.deletedDocumentChan <- documentName + + if cfg.dryRun { + log.Printf("🛑 Dry-Run: Would delete document: %s", documentName) + return nil + } + + return deleteDocument(ctx, client, documentName) +} + +type parameterWorker struct { + id int + wg *sync.WaitGroup + incomingParameterChan <-chan *types.ParameterMetadata + deletedParameterChan chan<- string + cutoffTime time.Time +} + +func (w *parameterWorker) processParameter(ctx context.Context, client ssmClient) { + defer w.wg.Done() + + for parameter := range w.incomingParameterChan { + if err := w.handleParameter(ctx, client, parameter); err != nil { + log.Printf("Worker %d: Error processing parameter: %v", w.id, err) + } + } +} + +func (w *parameterWorker) handleParameter(ctx context.Context, client ssmClient, parameter *types.ParameterMetadata) error { + if parameter.LastModifiedDate == nil || parameter.Name == nil { + return fmt.Errorf("parameter has missing required fields: %v", parameter) + } + + parameterName := *parameter.Name + lastModified := *parameter.LastModifiedDate + + // Check if parameter is old enough and matches test patterns + if lastModified.After(w.cutoffTime) { + // Parameter is too new, skip it + return nil + } + + if !isTestParameter(parameterName) { + return nil + } + + log.Printf("🚨 Worker: %d| Old Test Parameter: %s (Last Modified: %v)\n", + w.id, parameterName, lastModified) + + w.deletedParameterChan <- parameterName + + if cfg.dryRun { + log.Printf("🛑 Dry-Run: Would delete parameter: %s", parameterName) + return nil + } + + return deleteParameter(ctx, client, parameterName) +} + +func handleDeletedDocuments(deletedDocuments *[]string, deletedDocumentChan chan string) { + for documentName := range deletedDocumentChan { + *deletedDocuments = append(*deletedDocuments, documentName) + // Only log every 10 processed items to reduce noise, or if verbose mode is enabled + if cfg.verbose || len(*deletedDocuments)%10 == 0 { + log.Printf("🔍 Processed %d documents so far\n", len(*deletedDocuments)) + } + } +} + +func handleDeletedParameters(deletedParameters *[]string, deletedParameterChan chan string) { + for parameterName := range deletedParameterChan { + *deletedParameters = append(*deletedParameters, parameterName) + // Log each parameter since there should be fewer of them + log.Printf("🔍 Processed %d parameters so far\n", len(*deletedParameters)) + } +} + +func deleteDocument(ctx context.Context, client ssmClient, documentName string) error { + _, err := client.DeleteDocument(ctx, &ssm.DeleteDocumentInput{ + Name: aws.String(documentName), + }) + if err != nil { + return fmt.Errorf("deleting document %s: %w", documentName, err) + } + log.Printf("✅ Deleted document: %s", documentName) + return nil +} + +func deleteParameter(ctx context.Context, client ssmClient, parameterName string) error { + _, err := client.DeleteParameter(ctx, &ssm.DeleteParameterInput{ + Name: aws.String(parameterName), + }) + if err != nil { + return fmt.Errorf("deleting parameter %s: %w", parameterName, err) + } + log.Printf("✅ Deleted parameter: %s", parameterName) + return nil +} + +func fetchAndProcessDocuments(ctx context.Context, client ssmClient, documentChan chan<- *types.DocumentIdentifier) error { + var nextToken *string + describeCount := 0 + + for { + output, err := client.ListDocuments(ctx, &ssm.ListDocumentsInput{ + NextToken: nextToken, + MaxResults: aws.Int32(50), // Process in batches + }) + if err != nil { + return fmt.Errorf("listing documents: %w", err) + } + + // Only log every 10th batch to reduce noise, or if verbose mode is enabled + if cfg.verbose || describeCount%10 == 0 || output.NextToken == nil { + log.Printf("🔍 Scanned %d batches | Found %d documents in current batch\n", describeCount+1, len(output.DocumentIdentifiers)) + } + + for _, document := range output.DocumentIdentifiers { + documentChan <- &document + } + + if output.NextToken == nil { + break + } + + nextToken = output.NextToken + describeCount++ + } + + return nil +} + +func fetchAndProcessParameters(ctx context.Context, client ssmClient, parameterChan chan<- *types.ParameterMetadata) error { + var nextToken *string + describeCount := 0 + + for { + output, err := client.DescribeParameters(ctx, &ssm.DescribeParametersInput{ + NextToken: nextToken, + MaxResults: aws.Int32(50), // Process in batches + }) + if err != nil { + return fmt.Errorf("describing parameters: %w", err) + } + + // Only log every 10th batch to reduce noise, or if verbose mode is enabled + if cfg.verbose || describeCount%10 == 0 || output.NextToken == nil { + log.Printf("🔍 Scanned %d batches | Found %d parameters in current batch\n", describeCount+1, len(output.Parameters)) + } + + for _, parameter := range output.Parameters { + parameterChan <- ¶meter + } + + if output.NextToken == nil { + break + } + + nextToken = output.NextToken + describeCount++ + } + + return nil +} + +func isTestDocument(documentName string) bool { + for _, prefix := range cfg.testDocumentPrefixes { + if strings.HasPrefix(documentName, prefix) { + return true + } + } + return false +} + +func isTestParameter(parameterName string) bool { + for _, exactName := range cfg.testParameterPrefixes { + if parameterName == exactName { + return true + } + } + return false +} diff --git a/tool/clean/clean_ssm_documents/clean_ssm_documents_test.go b/tool/clean/clean_ssm_documents/clean_ssm_documents_test.go new file mode 100644 index 00000000000..4ebd35a75f0 --- /dev/null +++ b/tool/clean/clean_ssm_documents/clean_ssm_documents_test.go @@ -0,0 +1,94 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: MIT + +package main + +import ( + "testing" +) + +func TestIsTestDocument(t *testing.T) { + testCases := []struct { + name string + docName string + expected bool + }{ + { + name: "Test document with correct prefix", + docName: "Test-AmazonCloudWatch-ManageAgent-abc123", + expected: true, + }, + { + name: "Production AmazonCloudWatch-ManageAgent document", + docName: "AmazonCloudWatch-ManageAgent", + expected: false, + }, + { + name: "Regular document", + docName: "MyCustomDocument", + expected: false, + }, + { + name: "Empty document name", + docName: "", + expected: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := isTestDocument(tc.docName) + if result != tc.expected { + t.Errorf("isTestDocument(%q) = %v, expected %v", tc.docName, result, tc.expected) + } + }) + } +} + +func TestIsTestParameter(t *testing.T) { + testCases := []struct { + name string + paramName string + expected bool + }{ + { + name: "Test parameter agentConfig1", + paramName: "agentConfig1", + expected: true, + }, + { + name: "Test parameter agentConfig2", + paramName: "agentConfig2", + expected: true, + }, + { + name: "Test parameter MetricRenameSSM", + paramName: "MetricRenameSSM", + expected: true, + }, + { + name: "Regular parameter", + paramName: "regular-parameter", + expected: false, + }, + { + name: "Parameter with agentConfig in name but not exact match", + paramName: "myagentConfig1setting", + expected: false, + }, + { + name: "Empty parameter name", + paramName: "", + expected: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := isTestParameter(tc.paramName) + if result != tc.expected { + t.Errorf("isTestParameter(%q) = %v, expected %v", tc.paramName, result, tc.expected) + } + }) + } +} diff --git a/tool/clean/go.mod b/tool/clean/go.mod index e2209f00715..3a861cc067b 100644 --- a/tool/clean/go.mod +++ b/tool/clean/go.mod @@ -1,12 +1,12 @@ module github.com/aws/amazon-cloudwatch-agent/tool/clean -go 1.22 +go 1.23 -toolchain go1.23.6 +toolchain go1.24.2 require ( github.com/aws/aws-sdk-go v1.48.14 - github.com/aws/aws-sdk-go-v2 v1.36.2 + github.com/aws/aws-sdk-go-v2 v1.41.0 github.com/aws/aws-sdk-go-v2/config v1.25.12 github.com/aws/aws-sdk-go-v2/service/autoscaling v1.36.3 github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.45.14 @@ -15,7 +15,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/efs v1.26.3 github.com/aws/aws-sdk-go-v2/service/eks v1.35.3 github.com/aws/aws-sdk-go-v2/service/iam v1.28.3 - github.com/aws/smithy-go v1.22.2 + github.com/aws/smithy-go v1.24.0 github.com/stretchr/testify v1.8.4 ) @@ -23,11 +23,12 @@ require ( github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.16.10 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.33 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.33 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8 // indirect + github.com/aws/aws-sdk-go-v2/service/ssm v1.67.7 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.3 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.3 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.26.3 // indirect diff --git a/tool/clean/go.sum b/tool/clean/go.sum index ec10d06adbf..3db22ed12a7 100644 --- a/tool/clean/go.sum +++ b/tool/clean/go.sum @@ -2,6 +2,8 @@ github.com/aws/aws-sdk-go v1.48.14 h1:nVLrp+F84SG+xGiFMfe1TE6ZV6smF+42tuuNgYGV30 github.com/aws/aws-sdk-go v1.48.14/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.36.2 h1:Ub6I4lq/71+tPb/atswvToaLGVMxKZvjYDVOWEExOcU= github.com/aws/aws-sdk-go-v2 v1.36.2/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= +github.com/aws/aws-sdk-go-v2 v1.41.0 h1:tNvqh1s+v0vFYdA1xq0aOJH+Y5cRyZ5upu6roPgPKd4= +github.com/aws/aws-sdk-go-v2 v1.41.0/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14= github.com/aws/aws-sdk-go-v2/config v1.25.12 h1:mF4cMuNh/2G+d19nWnm1vJ/ak0qK6SbqF0KtSX9pxu0= @@ -12,8 +14,12 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9 h1:FZVFahMyZle6WcogZCOxo6D github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9/go.mod h1:kjq7REMIkxdtcEC9/4BVXjOsNY5isz6jQbEgk6osRTU= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.33 h1:knLyPMw3r3JsU8MFHWctE4/e2qWbPaxDYLlohPvnY8c= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.33/go.mod h1:EBp2HQ3f+XCB+5J+IoEbGhoV7CpJbnrsd4asNXmTL0A= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 h1:rgGwPzb82iBYSvHMHXc8h9mRoOUBZIGFgKb9qniaZZc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16/go.mod h1:L/UxsGeKpGoIj6DxfhOWHWQ/kGKcd4I1VncE4++IyKA= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.33 h1:K0+Ne08zqti8J9jwENxZ5NoUyBnaFDTu3apwQJWrwwA= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.33/go.mod h1:K97stwwzaWzmqxO8yLGHhClbVW1tC6VT1pDLk1pGrq4= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 h1:1jtGzuV7c82xnqOVfx2F0xmJcOw5374L7N6juGW6x6U= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16/go.mod h1:M2E5OQf+XLe+SZGmmpaI2yy+J326aFf6/+54PoxSANc= github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw= github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= github.com/aws/aws-sdk-go-v2/service/autoscaling v1.36.3 h1:16TRfDZhx5aX90VsvG0yJ5XNlDNHMVDj2DBpVMwDxzc= @@ -34,6 +40,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3 h1:e3PCNeE github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3/go.mod h1:gIeeNyaL8tIEqZrzAnTeyhHcE0yysCtcaP+N9kxLZ+E= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8 h1:EamsKe+ZjkOQjDdHd86/JCEucjFKQ9T0atWKO4s2Lgs= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8/go.mod h1:Q0vV3/csTpbkfKLI5Sb56cJQTCTtJ0ixdb7P+Wedqiw= +github.com/aws/aws-sdk-go-v2/service/ssm v1.67.7 h1:0q42w8/mywPCzQD1IoWIBUCYfBJc5+fLwtZNpHffBSM= +github.com/aws/aws-sdk-go-v2/service/ssm v1.67.7/go.mod h1:urlU9nfKJEfi0+8T9luB3f3Y0UnomH/yxI7tTrfH9es= github.com/aws/aws-sdk-go-v2/service/sso v1.18.3 h1:wKspi1zc2ZVcgZEu3k2Mt4zGKQSoZTftsoUTLsYPcVo= github.com/aws/aws-sdk-go-v2/service/sso v1.18.3/go.mod h1:zxk6y1X2KXThESWMS5CrKRvISD8mbIMab6nZrCGxDG0= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.3 h1:CxAHBS0BWSUqI7qzXHc2ZpTeHaM9JNnWJ9BN6Kmo2CY= @@ -42,6 +50,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.26.3 h1:KfREzajmHCSYjCaMRtdLr9boUMA7 github.com/aws/aws-sdk-go-v2/service/sts v1.26.3/go.mod h1:7Ld9eTqocTvJqqJ5K/orbSDwmGcpRdlDiLjz2DO+SL8= github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk= +github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=