diff --git a/athenalib/discard.go b/athenalib/discard.go new file mode 100644 index 0000000..3e7cc1e --- /dev/null +++ b/athenalib/discard.go @@ -0,0 +1,13 @@ +package athenalib + +import "io" + +// discardWithClose uses io.Discard to discard writes, but also has a no-op Close method +type discardWithClose struct{} + +func (d discardWithClose) Write(p []byte) (int, error) { + return io.Discard.Write(p) +} +func (d discardWithClose) Close() error { + return nil +} diff --git a/athenalib/query.go b/athenalib/query.go new file mode 100644 index 0000000..2dfdd4e --- /dev/null +++ b/athenalib/query.go @@ -0,0 +1,99 @@ +package athenalib + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/athena" + "github.com/aws/aws-sdk-go-v2/service/athena/types" +) + +func waitForQuery(ctx context.Context, ath *athena.Client, execID *string, logDetails bool) error { + for { + out, err := ath.GetQueryExecution(ctx, &athena.GetQueryExecutionInput{ + QueryExecutionId: execID, + }) + if err != nil { + return fmt.Errorf("Getting query status failed: %s", err) + } + status := string(out.QueryExecution.Status.State) + switch status { + case "SUCCEEDED": + return nil + case "QUEUED": + if logDetails { + log.Printf("Query is queued") + } + case "RUNNING": + if logDetails { + log.Printf("Query is running") + } + case "FAILED": + return fmt.Errorf("Query return status %q: %s", status, aws.ToString(out.QueryExecution.Status.StateChangeReason)) + case "CANCELLED": + return fmt.Errorf("Query return status %q", status) + default: + return fmt.Errorf("Unknown query status %q", status) + } + time.Sleep(time.Second) + } +} + +func QueryAthena(ctx context.Context, ath *athena.Client, database, query, outputLocation string, maxRows int64, logDetails bool) ([]types.Row, error) { + execIn := &athena.StartQueryExecutionInput{ + QueryString: aws.String(query), + ResultConfiguration: &types.ResultConfiguration{ + OutputLocation: &outputLocation, + }, + } + if database != "" { + execIn.QueryExecutionContext = &types.QueryExecutionContext{ + Database: &database, + } + } + execOut, err := ath.StartQueryExecution(ctx, execIn) + if err != nil { + return nil, fmt.Errorf("Querying failed: %s", err) + } + + err = waitForQuery(ctx, ath, execOut.QueryExecutionId, logDetails) + if err != nil { + return nil, fmt.Errorf("Waiting for query results failed: %s", err) + } + + var rowsPerQuery int64 = 1000 + if maxRows > 0 && maxRows < rowsPerQuery { + rowsPerQuery = maxRows + } + + var rows []types.Row + var nextToken *string = nil + + for { + var numRows int64 = 1000 + if maxRows > 0 && int64(len(rows))+numRows > maxRows { + numRows = maxRows - int64(len(rows)) + } + out, err := ath.GetQueryResults(ctx, &athena.GetQueryResultsInput{ + QueryExecutionId: execOut.QueryExecutionId, + MaxResults: aws.Int32(int32(numRows)), + NextToken: nextToken, + }) + if err != nil { + return nil, fmt.Errorf("Getting results failed: %s", err) + } + + rows = append(rows, out.ResultSet.Rows...) + if maxRows > 0 && maxRows <= int64(len(rows)) { + break + } + nextToken = out.NextToken + if nextToken == nil { + break + } + } + return rows, nil +} diff --git a/athenalib/write.go b/athenalib/write.go new file mode 100644 index 0000000..11a92c9 --- /dev/null +++ b/athenalib/write.go @@ -0,0 +1,146 @@ +package athenalib + +import ( + "context" + "encoding/json" + "fmt" + "io" + "log" + "sync" + "time" + + awsconfig "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/feature/s3/manager" + "github.com/aws/aws-sdk-go-v2/service/s3" +) + +var discard = discardWithClose{} + +type WriteRowsOption func(*writeRowsConfig) + +type writeRowsConfig struct { + overwrite bool + keyName string + dryRun bool +} + +// WithOverwrite sets whether to overwrite existing rows. It defaults to use +// "data" as the key name unless one is provided +func WithOverwrite(overwrite bool, keyName string) WriteRowsOption { + if keyName == "" { + keyName = "data" + } + return func(c *writeRowsConfig) { + c.overwrite = overwrite + c.keyName = keyName + } +} + +// WithDryRun sets whether this is a dry run +func WithDryRun(dryRun bool) WriteRowsOption { + return func(c *writeRowsConfig) { + c.dryRun = dryRun + } +} + +// WriteRows writes the given rows to S3, serialized as JSON objects, one per line. +// It provides the following options: +// - WithDryRun: sets whether this is a dry run (default false) +// - WithOverwrite: sets whether to overwrite existing rows (default false) +// +// If a partition key is specified, then the value for that key must be a string +// in each row. The destination file for each row will be: +// - s3://// +// if there is no partition key specified (partitionKey is "") +// - s3:////=/ +// if there is a partition key specified +func WriteRows(ctx context.Context, bucket, keyPrefix string, rows []map[string]interface{}, partitionKey string, opts ...WriteRowsOption) error { + config := &writeRowsConfig{ + dryRun: false, + overwrite: false, + } + + for _, opt := range opts { + opt(config) + } + + var uploader *manager.Uploader + if !config.dryRun { + cfg, err := awsconfig.LoadDefaultConfig(ctx) + if err != nil { + return fmt.Errorf("error loading config: %s", err) + } + s3client := s3.NewFromConfig(cfg) + uploader = manager.NewUploader(s3client) + } + + var keyName string + if config.overwrite { + keyName = config.keyName + } else { + keyName = time.Now().UTC().Format(time.RFC3339Nano) + } + + // In this loop we iterate through the rows, serializing them and dispatching + // them to S3 uploaders that buffer the data in the background. + writers := map[string]io.WriteCloser{} // partitionKey -> writer + uploaderWait := new(sync.WaitGroup) + var uploaderError error // if there are uploader errors, this will hold an arbitrary one of them + uploaderErrorMu := new(sync.Mutex) + for idx, row := range rows { + key := keyPrefix + if partitionKey != "" { + datum, ok := row[partitionKey].(string) + if !ok { + return fmt.Errorf("Row %d: does not have %q field or it is not a string", idx, partitionKey) + } + key = fmt.Sprintf("%s/%s=%s", key, partitionKey, datum) + } + key = fmt.Sprintf("%s/%s.jsonrows", key, keyName) + writer := writers[key] + if writer == nil { + if config.dryRun { + log.Printf("Will upload to s3://%s/%s", bucket, key) + writer = discard + writers[key] = writer + } else { + r, w := io.Pipe() + writers[key] = w + writer = w + uploaderWait.Add(1) + go func(bucket, key string, reader io.Reader) { + log.Printf("Starting upload of s3://%s/%s", bucket, key) + _, err := uploader.Upload(ctx, &s3.PutObjectInput{ + Bucket: &bucket, + Key: &key, + Body: reader, + }) + if err != nil { + // There are two possibilities now: + // 1. This was the last write to this pipe. Set uploaderError so that + // the function will eventually return an error. + // 2. There will be more writes to this pipe. Close the pipe with an + // error so that the writes fail and report the error. + uploaderErrorMu.Lock() + uploaderError = err + uploaderErrorMu.Unlock() + r.CloseWithError(fmt.Errorf("Uploader error: %s", err)) + } else { + log.Printf("Finished upload of s3://%s/%s", bucket, key) + } + uploaderWait.Done() + + }(bucket, key, r) + } + } + err := json.NewEncoder(writer).Encode(row) + if err != nil { + return fmt.Errorf("Row %d: error writing JSON: %s", idx, err) + } + } + for _, w := range writers { + w.Close() + } + uploaderWait.Wait() + return uploaderError +} diff --git a/go.mod b/go.mod index 13ebb21..2d0bb4e 100644 --- a/go.mod +++ b/go.mod @@ -3,15 +3,18 @@ module github.com/corbaltcode/go-libraries go 1.24 require ( - github.com/aws/aws-sdk-go-v2 v1.41.4 - github.com/aws/aws-sdk-go-v2/config v1.31.0 - github.com/aws/aws-sdk-go-v2/credentials v1.19.5 + github.com/aws/aws-sdk-go-v2 v1.43.3 + github.com/aws/aws-sdk-go-v2/config v1.32.34 + github.com/aws/aws-sdk-go-v2/credentials v1.19.33 github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.6.16 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.39 + github.com/aws/aws-sdk-go-v2/service/athena v1.60.3 github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.55.2 github.com/aws/aws-sdk-go-v2/service/rds v1.113.1 + github.com/aws/aws-sdk-go-v2/service/s3 v1.106.4 github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.0 github.com/aws/aws-sdk-go-v2/service/ssm v1.63.0 - github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 + github.com/aws/aws-sdk-go-v2/service/sts v1.45.3 github.com/coreos/go-oidc/v3 v3.6.0 github.com/google/go-cmp v0.5.9 github.com/jmoiron/sqlx v1.3.5 @@ -20,15 +23,19 @@ require ( ) require ( - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.30.7 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 // indirect - github.com/aws/smithy-go v1.24.2 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.16 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.34 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.34 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.34 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.35 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.15 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.27 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.34 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.35 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.5.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.33.3 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.38.3 // indirect + github.com/aws/smithy-go v1.27.6 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/go-jose/go-jose/v3 v3.0.0 // indirect github.com/golang/protobuf v1.5.2 // indirect diff --git a/go.sum b/go.sum index e8e981c..e354a4b 100644 --- a/go.sum +++ b/go.sum @@ -1,39 +1,53 @@ -github.com/aws/aws-sdk-go-v2 v1.41.4 h1:10f50G7WyU02T56ox1wWXq+zTX9I1zxG46HYuG1hH/k= -github.com/aws/aws-sdk-go-v2 v1.41.4/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= -github.com/aws/aws-sdk-go-v2/config v1.31.0 h1:9yH0xiY5fUnVNLRWO0AtayqwU1ndriZdN78LlhruJR4= -github.com/aws/aws-sdk-go-v2/config v1.31.0/go.mod h1:VeV3K72nXnhbe4EuxxhzsDc/ByrCSlZwUnWH52Nde/I= -github.com/aws/aws-sdk-go-v2/credentials v1.19.5 h1:xMo63RlqP3ZZydpJDMBsH9uJ10hgHYfQFIk1cHDXrR4= -github.com/aws/aws-sdk-go-v2/credentials v1.19.5/go.mod h1:hhbH6oRcou+LpXfA/0vPElh/e0M3aFeOblE1sssAAEk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 h1:80+uETIWS1BqjnN9uJ0dBUaETh+P1XwFy5vwHwK5r9k= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16/go.mod h1:wOOsYuxYuB/7FlnVtzeBYRcjSRtQpAW0hCP7tIULMwo= +github.com/aws/aws-sdk-go-v2 v1.43.3 h1:XJIcfv8uDs2ukdQsoAC8/Ebu1ejxwzlayl2ZsiFns2A= +github.com/aws/aws-sdk-go-v2 v1.43.3/go.mod h1:70vwSy16txshwG+g55WkpgPKDIByzHI8ccBsOteo3bQ= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.16 h1:aiuaKlDweRC5qExJondpWjOgyzMHpofpwspGXUtwn4c= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.16/go.mod h1:nG/LOlmox9BDe9HvQnXWzgcK8uKbgBMZ/Hp5pVt/21I= +github.com/aws/aws-sdk-go-v2/config v1.32.34 h1:o+YAizrX562nEZXaB38uYTK8RvIsvW0uuRP+e5e0Pfk= +github.com/aws/aws-sdk-go-v2/config v1.32.34/go.mod h1:wc0zYRChOniiufvdWiRVf3jgXSgbkvaD683IHHHc2ZQ= +github.com/aws/aws-sdk-go-v2/credentials v1.19.33 h1:/e5V3EWfeDiW6cuRxHsC8gbwko4/vvVYPJR2afBKFFY= +github.com/aws/aws-sdk-go-v2/credentials v1.19.33/go.mod h1:ZxAmkcyOM9beY/WO9oxp2oVPXiP3rq5N1/p4NbenJdE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.34 h1:1EsGke6rTD2CG3j2MMVB77n6Q+FlbQWYI/dFdLWBNtM= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.34/go.mod h1:5B1Z/QbaWzqoWRzYxZfmCbDDRcvUHcfAIQw/S+KfDmc= github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.6.16 h1:LFB4eCU2S9wpFAkEnSqtP8CgdOk0cjMIzuXas1+rbWM= github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.6.16/go.mod h1:Q7hjCcQzFZ9QgZ+xeJhO4X1rv7uKAl4aoBEjab6MS8k= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 h1:CNXO7mvgThFGqOFgbNAP2nol2qAWBOGfqR/7tQlvLmc= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20/go.mod h1:oydPDJKcfMhgfcgBUZaG+toBbwy8yPWubJXBVERtI4o= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 h1:tN6W/hg+pkM+tf9XDkWUbDEjGLb+raoBMFsTodcoYKw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20/go.mod h1:YJ898MhD067hSHA6xYCx5ts/jEd8BSOLtQDL3iZsvbc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.39 h1:ryMx7XNg1mYxQ8FQZgjKzmsy6sQcCdOW1JS6km5T2K0= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.39/go.mod h1:pZIHX61l/gDP1X9LffJU+Kid5sDiItcYajCXXV65jR8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.34 h1:vuIfjzoeqhQMGJyOBU3t0ZEjn2jrN8Bbg1N4CgjzM5Q= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.34/go.mod h1:hP28cN4CPJLZHirdQPrZR50JcLN4ApRJP2tzG8cRlhY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.34 h1:9faHsnqxJ1vDvB4wMZy/ajIDyz5QhllQjjc72RJpXAw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.34/go.mod h1:Yp6nIyejpa23nzlB/LhT63KTla9Jdi06nv/HH/OkAH8= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.35 h1:Oe8gMKJLO5awqpa5EhAGKVnBv1s+brdWVuxM2mDa7zA= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.35/go.mod h1:FZevcG9cOST/FWAAUhHIchjR9fXFXFRCWodOhx+PDLA= +github.com/aws/aws-sdk-go-v2/service/athena v1.60.3 h1:9YpQ1D/TtKRX8ljjhFToHnLMhyPLnzkVOltL6kA2WNc= +github.com/aws/aws-sdk-go-v2/service/athena v1.60.3/go.mod h1:+xcEqCwLfrzwggAuY4CbvBvaML6Uv0ngwZiybJgjcxI= github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.55.2 h1:mleWBVIxwceEzyItUVoqMFiv6TmOP6ECPoN6WB/VWXc= github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.55.2/go.mod h1:cMApt548kNgu87UsBTNWVv+fpzjbUTFRSFjD1688SBs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 h1:oHjJHeUy0ImIV0bsrX0X91GkV5nJAyv1l1CC9lnO0TI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16/go.mod h1:iRSNGgOYmiYwSCXxXaKb9HfOEj40+oTKn8pTxMlYkRM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.15 h1:JJLBQxwY+AFwuPAi5ivGc1ChnTdUt4cXMv7e76m2c/Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.15/go.mod h1:lQknBIe78MVL0cQOQDlag8KGflMbMEVFx9mB6O8ENvk= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.27 h1:zwB6ltUc0UiyOsRQaMQ8jNLjKECbjhadCyl4hqV0y/c= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.27/go.mod h1:ce9y+Y+hGLUyPKJZZJGoFLuFJNfCNuWZTujUJAsckQA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.34 h1:sYg4qHWLqsjp15PzX7XCOHSOgKEGoZ5vQY43VvZ1pas= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.34/go.mod h1:N58SSz3roKf1HzW5qRaOiyk6MbDLTKgLPvlTfJ90iyI= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.35 h1:ohfdSAm4TA6nryIY7mLqe4mnSIAnAreoAPBM81ZVoIM= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.35/go.mod h1:uUjphnxMb3HH3vIiOHl4dH0fGNKL+csjqRQEabbfw5k= github.com/aws/aws-sdk-go-v2/service/rds v1.113.1 h1:/vV0g/Su8rCTqT57UUYiFU/aRrPXz//fGDn1dkXblG4= github.com/aws/aws-sdk-go-v2/service/rds v1.113.1/go.mod h1:q02df+DL73LN+jDXzj86tMsI6kKf1kfv61nB684H+o8= +github.com/aws/aws-sdk-go-v2/service/s3 v1.106.4 h1:nN+nb2rhWmPOMwFA+e6xDJZJ0h/VAI39XVBzn52Fn8A= +github.com/aws/aws-sdk-go-v2/service/s3 v1.106.4/go.mod h1:lWk6L5Q3YkaC7so1bQUJkvF7hj2KUFzdZ4w15wc2GHY= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.0 h1:vL6rQXcGtFv9q/9eRPdI+lL+dvTm7xKGZYSHEvmrpDk= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.0/go.mod h1:QwEDLD+7EukuEUnbWtiNE8LhgvvmhjZoi4XAppYPtyc= +github.com/aws/aws-sdk-go-v2/service/signin v1.5.3 h1:togAtAmgV5IGMnQDuBDJeM8z5Y5RN6G7xeOgphWz+Yc= +github.com/aws/aws-sdk-go-v2/service/signin v1.5.3/go.mod h1:T7xKUUUvN7W3RW8UmMvKnD12xqh+Ux2gCPHPhnt64Dg= github.com/aws/aws-sdk-go-v2/service/ssm v1.63.0 h1:1T8wFNEtOP4lgLC7v8Fzgbb4kFrMmnscG7kOqkbA26c= github.com/aws/aws-sdk-go-v2/service/ssm v1.63.0/go.mod h1:CDVmu8K5JKdgdJakdZ9gC3K6OJ/+izv/kUncFeGRIj4= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.7 h1:eYnlt6QxnFINKzwxP5/Ucs1vkG7VT3Iezmvfgc2waUw= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.7/go.mod h1:+fWt2UHSb4kS7Pu8y+BMBvJF0EWx+4H0hzNwtDNRTrg= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 h1:AHDr0DaHIAo8c9t1emrzAlVDFp+iMMKnPdYy6XO4MCE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12/go.mod h1:GQ73XawFFiWxyWXMHWfhiomvP3tXtdNar/fi8z18sx0= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 h1:SciGFVNZ4mHdm7gpD1dgZYnCuVdX1s+lFTg4+4DOy70= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfmkdMZqsovezbAeO+Ubiv2pk= -github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= -github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/aws/aws-sdk-go-v2/service/sso v1.33.3 h1:YjH64OUytnWZBHUtM9GMyi4ZWBiSQdEJkZuPykOIe44= +github.com/aws/aws-sdk-go-v2/service/sso v1.33.3/go.mod h1:5qoHcDZDTSJotoKk1bvVRPv1MXaL/NhfY9ng8D1g/ig= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.38.3 h1:A4o1di/XGaqtw6r3toSBrFX2U7mVSLqg7jo9wL4I+cU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.38.3/go.mod h1:sKuKz2kHtrGVtFu34vbM3LWSA9CKD9YZUmm6e5PPqRA= +github.com/aws/aws-sdk-go-v2/service/sts v1.45.3 h1:Fi7+DiKN1+QphlajvE6FqeZ8GRbnnRul7zTdUiRpbGc= +github.com/aws/aws-sdk-go-v2/service/sts v1.45.3/go.mod h1:KCc3e27fHZUGtzpek7wZcp6dyCpGkJJo/+3PBujh/yU= +github.com/aws/smithy-go v1.27.6 h1:0zjT8jgK3jbrTT7JJ3EE6JsMhX8JTrZ+f1sEndYDXrA= +github.com/aws/smithy-go v1.27.6/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o= github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=