From 1edb69677b2e601e321df1fbafc23743ff94625f Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Fri, 31 Jan 2025 06:34:17 -0500 Subject: [PATCH] Convert examples/teleport-usage to aws-sdk-go-v2 (#51677) * Convert examples/teleport-usage to aws-sdk-go-v2 * fix: apply fips to global config --- examples/teleport-usage/go.mod | 18 +++++++- examples/teleport-usage/go.sum | 36 +++++++++++++++- examples/teleport-usage/main.go | 76 +++++++++++++-------------------- 3 files changed, 80 insertions(+), 50 deletions(-) diff --git a/examples/teleport-usage/go.mod b/examples/teleport-usage/go.mod index 9c009bebf497a..cdf1098b60673 100644 --- a/examples/teleport-usage/go.mod +++ b/examples/teleport-usage/go.mod @@ -3,11 +3,27 @@ module usage-script go 1.22 require ( - github.com/aws/aws-sdk-go v1.47.4 + github.com/aws/aws-sdk-go-v2 v1.35.0 + github.com/aws/aws-sdk-go-v2/config v1.29.3 + github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.17.0 + github.com/aws/aws-sdk-go-v2/service/dynamodb v1.39.7 github.com/stretchr/testify v1.8.3 ) require ( + github.com/aws/aws-sdk-go-v2/credentials v1.17.56 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.26 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.30 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.30 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect + github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.17 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.11 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.11 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.13 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.12 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.33.11 // indirect + github.com/aws/smithy-go v1.22.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/examples/teleport-usage/go.sum b/examples/teleport-usage/go.sum index ba1d2e24403b0..3a30d379e0bf3 100644 --- a/examples/teleport-usage/go.sum +++ b/examples/teleport-usage/go.sum @@ -1,5 +1,37 @@ -github.com/aws/aws-sdk-go v1.47.4 h1:IyhNbmPt+5ldi5HNzv7ZnXiqSglDMaJiZlzj4Yq3qnk= -github.com/aws/aws-sdk-go v1.47.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go-v2 v1.35.0 h1:jTPxEJyzjSuuz0wB+302hr8Eu9KUI+Zv8zlujMGJpVI= +github.com/aws/aws-sdk-go-v2 v1.35.0/go.mod h1:JgstGg0JjWU1KpVJjD5H0y0yyAIpSdKEq556EI6yOOM= +github.com/aws/aws-sdk-go-v2/config v1.29.3 h1:a5Ucjxe6iV+LHEBmYA9w40rT5aGxWybx/4l/O/fvJlE= +github.com/aws/aws-sdk-go-v2/config v1.29.3/go.mod h1:pt9z1x12zDiDb4iFLrxoeAKLVCU/Gp9DL/5BnwlY77o= +github.com/aws/aws-sdk-go-v2/credentials v1.17.56 h1:JKMBreKudV+ozx6rZJLvEtiexv48aEdhdC7mXUw9MLs= +github.com/aws/aws-sdk-go-v2/credentials v1.17.56/go.mod h1:S3xRjIHD8HHFgMTz4L56q/7IldfNtGL9JjH/vP3U6DA= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.17.0 h1:OljitD0YIY2qkKpHChC+CMjKywEsqDLhUlHOI2AseXQ= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.17.0/go.mod h1:bcffXfieyW3VfH02hxx6MBuCU9UOBRguc4iS7mV7V9E= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.26 h1:XMBqBEuZLf8yxtH+mU/uUDyQbN4iD/xv9h6he2+lzhw= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.26/go.mod h1:d0+wQ/3CYGPuHEfBTPpQdfUX7gjk0/Lxs5Q6KzdEGY8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.30 h1:+7AzSGNhHoY53di13lvztf9Dyd/9ofzoYGBllkWp3a0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.30/go.mod h1:Jxd/FrCny99yURiQiMywgXvBhd7tmgdv6KdlUTNzMSo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.30 h1:Ex06eY6I5rO7IX0HalGfa5nGjpBoOsS1Qm3xfjkuszs= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.30/go.mod h1:AvyEMA9QcX59kFhVizBpIBpEMThUTXssuJe+emBdcGM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.39.7 h1:JFLdDS6ZGKoZii7O+9IBsuvCnvW2vSbseNBji8OKEo8= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.39.7/go.mod h1:8blEsG2cwaS8BK1YiWSEWFwmVav7i7EJk5swid5Vhcw= +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.17 h1:jPqYzzklr/WkOk5imqvgpm4MkGLoXs6daKsoQSQiSrg= +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.17/go.mod h1:DRtG2Ux6Ba26Q+bt/ef7gHa10ilrfqobnAAnmBIPnuk= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 h1:D4oz8/CzT9bAEYtVhSBmFj2dNOtaHOtMKc2vHBwYizA= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2/go.mod h1:Za3IHqTQ+yNcRHxu1OFucBh0ACZT4j4VQFF0BqpZcLY= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.11 h1:f36sb0FYLZui8mzV6o8DxkUyvOdZfkemyCPTGDJdWhE= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.11/go.mod h1:MaBbVwqDmlH9ytOOcERyVQ+Z6nvWkEdRy0k44m3MYkE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.11 h1:5JKQ2J3BBW4ovy6A/5Lwx9SpA6IzgH8jB3bquGZ1NUw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.11/go.mod h1:VShCk7rfCzK/b9U1aSkzLwcOoaDlYna16482QqEavis= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.13 h1:q4pOAKxypbFoUJzOpgo939bF50qb4DgYshiDfcsdN0M= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.13/go.mod h1:G/0PTg7+vQT42ictQGjJhixzTcVZtHFvrN/OeTXrRfQ= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.12 h1:4sGSGshSSfO1vrcXruPick3ioSf8nhhD6nuB2ni37P4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.12/go.mod h1:NHpu/pLOelViA4qxkAFH10VLqh+XeLhZfXDaFyMVgSs= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.11 h1:RIXOjp7Dp4siCYJRwBHUcBdVgOWflSJGlq4ZhMI5Ta0= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.11/go.mod h1:ZR17k9bPKPR8u0IkyA6xVsjr56doNQ4ZB1fs7abYBfE= +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/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= diff --git a/examples/teleport-usage/main.go b/examples/teleport-usage/main.go index 0e9a12a5720d3..45a97b733539a 100644 --- a/examples/teleport-usage/main.go +++ b/examples/teleport-usage/main.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "context" "crypto/sha256" "errors" "fmt" @@ -29,13 +30,11 @@ import ( "strings" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/endpoints" - awsrequest "github.com/aws/aws-sdk-go/aws/request" - awssession "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/dynamodb" - "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue" + "github.com/aws/aws-sdk-go-v2/service/dynamodb" + "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" ) const ( @@ -60,39 +59,33 @@ func main() { fmt.Println("Gathering data, this may take a moment") - // Assume a base read capacity of 25 units per second to start off. - // If this is too high and we encounter throttling that could impede Teleport, it will be adjusted automatically. - limiter := newAdaptiveRateLimiter(25) + ctx := context.Background() + + configOpts := []func(*config.LoadOptions) error{config.WithRegion(params.awsRegion)} // Check the package name for one of the boring primitives. If the package // path is from BoringCrypto, we know this binary was compiled using // `GOEXPERIMENT=boringcrypto`. hash := sha256.New() - useFIPSEndpoint := endpoints.FIPSEndpointStateUnset if reflect.TypeOf(hash).Elem().PkgPath() == "crypto/internal/boring" { - useFIPSEndpoint = endpoints.FIPSEndpointStateEnabled + configOpts = append(configOpts, config.WithUseFIPSEndpoint(aws.FIPSEndpointStateEnabled)) } - // create an AWS session using default SDK behavior, i.e. it will interpret - // the environment and ~/.aws directory just like an AWS CLI tool would: - session, err := awssession.NewSessionWithOptions(awssession.Options{ - SharedConfigState: awssession.SharedConfigEnable, - Config: aws.Config{ - Retryer: limiter, - Region: aws.String(params.awsRegion), - CredentialsChainVerboseErrors: aws.Bool(true), - UseFIPSEndpoint: useFIPSEndpoint, - }, - }) + awsConfig, err := config.LoadDefaultConfig(ctx, configOpts...) if err != nil { log.Fatal(err) } - // Reduce internal retry count so throttling errors bubble up to our rate limiter with less delay. - svc := dynamodb.New(session) + // Assume a base read capacity of 25 units per second to start off. + // If this is too high and we encounter throttling that could impede Teleport, it will be adjusted automatically. + limiter := newAdaptiveRateLimiter(25) + + svc := dynamodb.NewFromConfig(awsConfig, func(o *dynamodb.Options) { + o.Retryer = aws.NopRetryer{} + }) for _, date := range daysBetween(params.startDate, params.startDate.Add(scanDuration)) { - err := scanDay(svc, limiter, params.tableName, date, state) + err := scanDay(ctx, svc, limiter, params.tableName, date, state) if err != nil { log.Fatal(err) } @@ -123,7 +116,7 @@ func displayProductResults(name string, users map[string]struct{}, showUsers boo } // scanDay scans a single day of events from the audit log table. -func scanDay(svc *dynamodb.DynamoDB, limiter *adaptiveRateLimiter, tableName string, date string, state *trackedState) error { +func scanDay(ctx context.Context, svc dynamodb.QueryAPIClient, limiter *adaptiveRateLimiter, tableName string, date string, state *trackedState) error { attributes := map[string]interface{}{ ":date": date, ":e1": "session.start", @@ -133,31 +126,32 @@ func scanDay(svc *dynamodb.DynamoDB, limiter *adaptiveRateLimiter, tableName str ":e5": "kube.request", } - attributeValues, err := dynamodbattribute.MarshalMap(attributes) + attributeValues, err := attributevalue.MarshalMap(attributes) if err != nil { return err } - var paginationKey map[string]*dynamodb.AttributeValue + var paginationKey map[string]types.AttributeValue pageCount := 1 outer: for { fmt.Printf(" scanning date %v page %v...\n", date, pageCount) - scanOut, err := svc.Query(&dynamodb.QueryInput{ + scanOut, err := svc.Query(ctx, &dynamodb.QueryInput{ TableName: aws.String(tableName), IndexName: aws.String(indexName), KeyConditionExpression: aws.String("CreatedAtDate = :date"), ExpressionAttributeValues: attributeValues, FilterExpression: aws.String("EventType IN (:e1, :e2, :e3, :e4, :e5)"), ExclusiveStartKey: paginationKey, - ReturnConsumedCapacity: aws.String(dynamodb.ReturnConsumedCapacityTotal), + ReturnConsumedCapacity: types.ReturnConsumedCapacityTotal, // We limit the number of items returned to the current capacity to minimize any usage spikes // that could affect Teleport as RCUs may be consumed for multiple seconds if the response is large, slowing down Teleport significantly. - Limit: aws.Int64(int64(limiter.currentCapacity())), + Limit: aws.Int32(int32(limiter.currentCapacity())), }) if err != nil { - if aerr, ok := err.(awserr.Error); ok && aerr.Code() == dynamodb.ErrCodeProvisionedThroughputExceededException { + var throughputExceededError *types.ProvisionedThroughputExceededException + if errors.As(err, &throughputExceededError) { fmt.Println(" throttled by DynamoDB, adjusting request rate...") limiter.reportThrottleError() continue outer @@ -191,10 +185,10 @@ type event struct { } // applies a set of scanned raw events onto the tracked state. -func reduceEvents(rawEvents []map[string]*dynamodb.AttributeValue, state *trackedState) error { +func reduceEvents(rawEvents []map[string]types.AttributeValue, state *trackedState) error { for _, rawEvent := range rawEvents { var event event - err := dynamodbattribute.UnmarshalMap(rawEvent, &event) + err := attributevalue.UnmarshalMap(rawEvent, &event) if err != nil { log.Fatal(err) } @@ -354,18 +348,6 @@ func (a *adaptiveRateLimiter) currentCapacity() float64 { return a.permitCapacity } -func (a *adaptiveRateLimiter) RetryRules(r *awsrequest.Request) time.Duration { - return 0 -} - -func (a *adaptiveRateLimiter) ShouldRetry(*awsrequest.Request) bool { - return false -} - -func (a *adaptiveRateLimiter) MaxRetries() int { - return 0 -} - func newAdaptiveRateLimiter(permitsPerSecond float64) *adaptiveRateLimiter { fmt.Printf(" setting initial read rate to %v RCUs\n", int(permitsPerSecond)) return &adaptiveRateLimiter{