Skip to content

Commit

Permalink
Convert examples/teleport-usage to aws-sdk-go-v2 (#51677)
Browse files Browse the repository at this point in the history
* Convert examples/teleport-usage to aws-sdk-go-v2

* fix: apply fips to global config
  • Loading branch information
rosstimothy authored Jan 31, 2025
1 parent 88e1cd4 commit 1edb696
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 50 deletions.
18 changes: 17 additions & 1 deletion examples/teleport-usage/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
36 changes: 34 additions & 2 deletions examples/teleport-usage/go.sum
Original file line number Diff line number Diff line change
@@ -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=
Expand Down
76 changes: 29 additions & 47 deletions examples/teleport-usage/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package main

import (
"context"
"crypto/sha256"
"errors"
"fmt"
Expand All @@ -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 (
Expand All @@ -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)
}
Expand Down Expand Up @@ -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",
Expand All @@ -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
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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{
Expand Down

0 comments on commit 1edb696

Please sign in to comment.