diff --git a/config/aws/credentials.go b/config/aws/credentials.go index 7b7591739..358080ab3 100644 --- a/config/aws/credentials.go +++ b/config/aws/credentials.go @@ -1,11 +1,12 @@ package aws import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/client" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/credentials/stscreds" - "github.com/aws/aws-sdk-go/aws/session" + "context" + awsV2 "github.com/aws/aws-sdk-go-v2/aws" + configV2 "github.com/aws/aws-sdk-go-v2/config" + credentialsV2 "github.com/aws/aws-sdk-go-v2/credentials" + stscredsV2 "github.com/aws/aws-sdk-go-v2/credentials/stscreds" + "github.com/aws/aws-sdk-go-v2/service/sts" ) type CredentialConfig struct { @@ -21,45 +22,66 @@ type CredentialConfig struct { WebIdentityTokenFile string `toml:"web_identity_token_file"` } -func (c *CredentialConfig) Credentials() (client.ConfigProvider, error) { +func (c *CredentialConfig) Credentials() (awsV2.Config, error) { if c.RoleARN != "" { return c.assumeCredentials() } - return c.rootCredentials() } -func (c *CredentialConfig) rootCredentials() (client.ConfigProvider, error) { - config := &aws.Config{ - Region: aws.String(c.Region), - } - if c.EndpointURL != "" { - config.Endpoint = &c.EndpointURL - } - if c.AccessKey != "" || c.SecretKey != "" { - config.Credentials = credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token) - } else if c.Profile != "" || c.Filename != "" { - config.Credentials = credentials.NewSharedCredentials(c.Filename, c.Profile) +func (c *CredentialConfig) rootCredentials() (awsV2.Config, error) { + options := []func(*configV2.LoadOptions) error{ + configV2.WithRegion(c.Region), } - return session.NewSession(config) + if c.EndpointURL != "" { + resolver := awsV2.EndpointResolverFunc(func(service, region string) (awsV2.Endpoint, error) { + return awsV2.Endpoint{ + URL: c.EndpointURL, + HostnameImmutable: true, + Source: awsV2.EndpointSourceCustom, + }, nil + }) + options = append(options, configV2.WithEndpointResolver(resolver)) + } + + if c.Profile != "" { + options = append(options, configV2.WithSharedConfigProfile(c.Profile)) + } + if c.Filename != "" { + options = append(options, configV2.WithSharedCredentialsFiles([]string{c.Filename})) + } + + if c.AccessKey != "" || c.SecretKey != "" { + provider := credentialsV2.NewStaticCredentialsProvider(c.AccessKey, c.SecretKey, c.Token) + options = append(options, configV2.WithCredentialsProvider(provider)) + } + + return configV2.LoadDefaultConfig(context.Background(), options...) } -func (c *CredentialConfig) assumeCredentials() (client.ConfigProvider, error) { +func (c *CredentialConfig) assumeCredentials() (awsV2.Config, error) { rootCredentials, err := c.rootCredentials() if err != nil { - return nil, err - } - config := &aws.Config{ - Region: aws.String(c.Region), - Endpoint: &c.EndpointURL, + return awsV2.Config{}, err } + var provider awsV2.CredentialsProvider + stsService := sts.NewFromConfig(rootCredentials) if c.WebIdentityTokenFile != "" { - config.Credentials = stscreds.NewWebIdentityCredentials(rootCredentials, c.RoleARN, c.RoleSessionName, c.WebIdentityTokenFile) + provider = stscredsV2.NewWebIdentityRoleProvider(stsService, c.RoleARN, stscredsV2.IdentityTokenFile(c.WebIdentityTokenFile), func(opts *stscredsV2.WebIdentityRoleOptions) { + if c.RoleSessionName != "" { + opts.RoleSessionName = c.RoleSessionName + } + }) } else { - config.Credentials = stscreds.NewCredentials(rootCredentials, c.RoleARN) + provider = stscredsV2.NewAssumeRoleProvider(stsService, c.RoleARN, func(opts *stscredsV2.AssumeRoleOptions) { + if c.RoleSessionName != "" { + opts.RoleSessionName = c.RoleSessionName + } + }) } - return session.NewSession(config) + rootCredentials.Credentials = awsV2.NewCredentialsCache(provider) + return rootCredentials, nil } diff --git a/docs/LICENSE_OF_DEPENDENCIES.md b/docs/LICENSE_OF_DEPENDENCIES.md index c52b110b2..ba1ee5147 100644 --- a/docs/LICENSE_OF_DEPENDENCIES.md +++ b/docs/LICENSE_OF_DEPENDENCIES.md @@ -36,17 +36,27 @@ following works: - github.com/aws/aws-sdk-go-v2 [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/LICENSE.txt) - github.com/aws/aws-sdk-go-v2/config [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/config/LICENSE.txt) - github.com/aws/aws-sdk-go-v2/credentials [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/credentials/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/feature/dynamodb/attributevalue/LICENSE.txt) - github.com/aws/aws-sdk-go-v2/feature/ec2/imds [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/feature/ec2/imds/LICENSE.txt) -- github.com/aws/aws-sdk-go-v2/feature/s3/manager [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/LICENSE.txt) -- github.com/aws/aws-sdk-go-v2/internal/ini [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/ec2/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/feature/s3/manager [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/feature/s3/manager/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/internal/configsources [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/internal/configsources/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/internal/ini [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/internal/ini/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/service/cloudwatch [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/cloudwatch/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/cloudwatchlogs/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/service/dynamodb [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/dynamodb/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/service/dynamodbstreams [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/dynamodbstreams/LICENSE.txt) - github.com/aws/aws-sdk-go-v2/service/ec2 [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/ec2/LICENSE.txt) - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/internal/accept-encoding/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/internal/endpoint-discovery/LICENSE.txt) - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/internal/presigned-url/LICENSE.txt) - github.com/aws/aws-sdk-go-v2/service/internal/s3shared [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/internal/s3shared/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/service/kinesis [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/kinesis/LICENSE.txt) - github.com/aws/aws-sdk-go-v2/service/s3 [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/s3/LICENSE.txt) - github.com/aws/aws-sdk-go-v2/service/sso [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/ec2/LICENSE.txt) - github.com/aws/aws-sdk-go-v2/service/sts [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/sts/LICENSE.txt) +- github.com/aws/aws-sdk-go-v2/service/timestreamwrite [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/timestreamwrite/LICENSE.txt) - github.com/aws/smithy-go [Apache License 2.0](https://github.com/aws/smithy-go/blob/main/LICENSE) +- github.com/awslabs/kinesis-aggregation/go [Apache License 2.0](https://github.com/awslabs/kinesis-aggregation/blob/master/LICENSE.txt) - github.com/benbjohnson/clock [MIT License](https://github.com/benbjohnson/clock/blob/master/LICENSE) - github.com/beorn7/perks [MIT License](https://github.com/beorn7/perks/blob/master/LICENSE) - github.com/bmatcuk/doublestar [MIT License](https://github.com/bmatcuk/doublestar/blob/master/LICENSE) diff --git a/go.mod b/go.mod index 95992243e..09cae700f 100644 --- a/go.mod +++ b/go.mod @@ -47,19 +47,26 @@ require ( github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3 // indirect github.com/aristanetworks/goarista v0.0.0-20190325233358-a123909ec740 github.com/armon/go-metrics v0.3.3 // indirect - github.com/aws/aws-sdk-go v1.38.69 github.com/aws/aws-sdk-go-v2 v1.9.1 github.com/aws/aws-sdk-go-v2/config v1.8.2 - github.com/aws/aws-sdk-go-v2/credentials v1.4.2 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.4.2 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.1 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.0.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.2.3 // indirect + github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.7.0 + github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.5.2 + github.com/aws/aws-sdk-go-v2/service/dynamodb v1.5.0 github.com/aws/aws-sdk-go-v2/service/ec2 v1.1.0 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.3.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.1.0 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.1 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.1 // indirect + github.com/aws/aws-sdk-go-v2/service/kinesis v1.6.0 github.com/aws/aws-sdk-go-v2/service/s3 v1.16.0 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.4.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.7.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.7.1 + github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.3.2 github.com/aws/smithy-go v1.8.0 github.com/benbjohnson/clock v1.1.0 github.com/beorn7/perks v1.0.1 // indirect @@ -129,8 +136,8 @@ require ( github.com/grid-x/serial v0.0.0-20191104121038-e24bc9bf6f08 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect - github.com/harlow/kinesis-consumer v0.3.1-0.20181230152818-2f58b136fee0 - github.com/hashicorp/consul/api v1.11.0 + github.com/harlow/kinesis-consumer v0.3.6-0.20210911031324-5a873d6e9fec + github.com/hashicorp/consul/api v1.9.1 github.com/hashicorp/go-cleanhttp v0.5.1 // indirect github.com/hashicorp/go-hclog v0.16.2 // indirect github.com/hashicorp/go-immutable-radix v1.2.0 // indirect @@ -264,7 +271,7 @@ require ( github.com/xdg/scram v1.0.3 github.com/xdg/stringprep v1.0.3 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect - github.com/yuin/gopher-lua v0.0.0-20180630135845-46796da1b0b4 // indirect + github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e // indirect go.etcd.io/etcd/api/v3 v3.5.0 // indirect go.mongodb.org/mongo-driver v1.5.3 go.opencensus.io v0.23.0 // indirect @@ -327,7 +334,10 @@ require ( ) require ( - github.com/aws/aws-sdk-go-v2/internal/ini v1.2.3 // indirect + github.com/aws/aws-sdk-go v1.38.3 // indirect + github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.2.0 // indirect + github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.4.0 // indirect + github.com/awslabs/kinesis-aggregation/go v0.0.0-20210630091500-54e17340d32f // indirect github.com/cenkalti/backoff/v4 v4.1.1 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index db4f0ad82..df4e48542 100644 --- a/go.sum +++ b/go.sum @@ -153,7 +153,9 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60= github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.4.4/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= @@ -238,6 +240,8 @@ github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 h1:AUNCr9CiJuwrRY github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= +github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= +github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1004 h1:YtaYjXmemIMyySUbs0VGFPqsLpsNHf4TW/L6yqpJQ9s= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1004/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= github.com/amir/raidman v0.0.0-20170415203553-1ccc43bfb9c9 h1:FXrPTd8Rdlc94dKccl7KPmdmIbVh/OjelJ8/vgMRzcQ= @@ -265,6 +269,10 @@ github.com/apache/thrift v0.14.1/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/apache/thrift v0.14.2/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.15.0 h1:aGvdaR0v1t9XLgjtBYwxcBvBOTMqClzwE26CHOgjW1Y= github.com/apache/thrift v0.15.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= +github.com/apex/log v1.6.0/go.mod h1:x7s+P9VtvFBXge9Vbn+8TrqKmuzmD35TTkeBHul8UtY= +github.com/apex/logs v1.0.0/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo= +github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= +github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3 h1:Bmjk+DjIi3tTAU0wxGaFbfjGUqlxxSXARq9A96Kgoos= github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= github.com/aristanetworks/goarista v0.0.0-20190325233358-a123909ec740 h1:FD4/ikKOFxwP8muWDypbmBWc634+YcAs3eBrYAmRdZY= @@ -287,56 +295,111 @@ github.com/ashanbrown/forbidigo v1.1.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBF github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.19.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/aws/aws-sdk-go v1.38.3 h1:QCL/le04oAz2jELMRSuJVjGT7H+4hhoQc66eMPCfU/k= github.com/aws/aws-sdk-go v1.38.3/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.38.69 h1:V489lmrdkIQSfF6OAGZZ1Cavcm7eczCm2JcGvX+yHRg= -github.com/aws/aws-sdk-go v1.38.69/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v1.1.0/go.mod h1:smfAbmpW+tcRVuNUjo3MOArSZmW72t62rkCzc2i0TWM= github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0= +github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0= +github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0= +github.com/aws/aws-sdk-go-v2 v1.8.1/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0= +github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= github.com/aws/aws-sdk-go-v2 v1.9.1 h1:ZbovGV/qo40nrOJ4q8G33AGICzaPI45FHQWJ9650pF4= github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= github.com/aws/aws-sdk-go-v2/config v1.6.0/go.mod h1:TNtBVmka80lRPk5+S9ZqVfFszOQAGJJ9KbT3EM3CHNU= +github.com/aws/aws-sdk-go-v2/config v1.6.0/go.mod h1:TNtBVmka80lRPk5+S9ZqVfFszOQAGJJ9KbT3EM3CHNU= +github.com/aws/aws-sdk-go-v2/config v1.6.1/go.mod h1:t/y3UPu0XEDy0cEw6mvygaBQaPzWiYAxfP2SzgtvclA= github.com/aws/aws-sdk-go-v2/config v1.8.2 h1:Dqy4ySXFmulRmZhfynm/5CD4Y6aXiTVhDtXLIuUe/r0= github.com/aws/aws-sdk-go-v2/config v1.8.2/go.mod h1:r0bkX9NyuCuf28qVcsEMtpAQibT7gA1Q0gzkjvgJdLU= github.com/aws/aws-sdk-go-v2/credentials v1.3.2/go.mod h1:PACKuTJdt6AlXvEq8rFI4eDmoqDFC5DpVKQbWysaDgM= +github.com/aws/aws-sdk-go-v2/credentials v1.3.2/go.mod h1:PACKuTJdt6AlXvEq8rFI4eDmoqDFC5DpVKQbWysaDgM= +github.com/aws/aws-sdk-go-v2/credentials v1.3.3/go.mod h1:oVieKMT3m9BSfqhOfuQ+E0j/yN84ZAJ7Qv8Sfume/ak= github.com/aws/aws-sdk-go-v2/credentials v1.4.2 h1:8kVE4Og6wlhVrMGiORQ3p9gRj2exjzhFRB+QzWBUa5Q= github.com/aws/aws-sdk-go-v2/credentials v1.4.2/go.mod h1:9Sp6u121/f0NnvHyhG7dgoYeUTEFC2vsvJqJ6wXpkaI= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.2.0 h1:8kvinmbIDObqsWegKP0JjeanYPiA4GUVpAtciNWE+jw= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.2.0/go.mod h1:UVFtSYSWCHj2+brBLDHUdlJXmz8LxUpZhA+Ewypc+xQ= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.4.0/go.mod h1:Mj/U8OpDbcVcoctrYwA2bak8k/HFPdcLzI/vaiXMwuM= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.4.0/go.mod h1:Mj/U8OpDbcVcoctrYwA2bak8k/HFPdcLzI/vaiXMwuM= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.4.1/go.mod h1:+GTydg3uHmVlQdkRoetz6VHKbOMEYof70m19IpMLifc= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.1 h1:Nm+BxqBtT0r+AnD6byGMCGT4Km0QwHBy8mAYptNPXY4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.1/go.mod h1:W1ldHfsgeGlKpJ4xZMKZUI6Wmp6EAstU7PxnhbXWWrI= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.4.0/go.mod h1:eHwXu2+uE/T6gpnYWwBwqoeqRf9IXyCcolyOWDRAErQ= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.3 h1:0O72494cCsazjpsGfo+LXezru6PMSp0HUB1m5UfpaRU= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.3/go.mod h1:claNkz2j/N/AZceFcAbR0NyuWnrn+jCYpI+6Ozjsc0k= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.0.2/go.mod h1:1QsSZvLUuaQ6VJsCXolYCEzV0mVBkNBp64pIJy9yRks= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.0.2/go.mod h1:1QsSZvLUuaQ6VJsCXolYCEzV0mVBkNBp64pIJy9yRks= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.0.4 h1:IM9b6hlCcVFJFydPoyphs/t7YrHfqKy7T4/7AG5Eprs= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.0.4/go.mod h1:W5gGbtNXFpF9/ssYZTaItzG/B+j0bjTnwStiCP2AtWU= github.com/aws/aws-sdk-go-v2/internal/ini v1.2.0/go.mod h1:Q5jATQc+f1MfZp3PDMhn6ry18hGvE0i8yvbXoKbnZaE= +github.com/aws/aws-sdk-go-v2/internal/ini v1.2.0/go.mod h1:Q5jATQc+f1MfZp3PDMhn6ry18hGvE0i8yvbXoKbnZaE= +github.com/aws/aws-sdk-go-v2/internal/ini v1.2.0/go.mod h1:Q5jATQc+f1MfZp3PDMhn6ry18hGvE0i8yvbXoKbnZaE= +github.com/aws/aws-sdk-go-v2/internal/ini v1.2.1/go.mod h1:Pv3WenDjI0v2Jl7UaMFIIbPOBbhn33RmmAmGgkXDoqY= github.com/aws/aws-sdk-go-v2/internal/ini v1.2.3 h1:NnXJXUz7oihrSlPKEM0yZ19b+7GQ47MX/LluLlEyE/Y= github.com/aws/aws-sdk-go-v2/internal/ini v1.2.3/go.mod h1:EES9ToeC3h063zCFDdqWGnARExNdULPaBvARm1FLwxA= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.7.0 h1:vXZPcDQg7e5z2IKz0huei6zhfAxDoZdXej2o3jUbjCI= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.7.0/go.mod h1:BlrFkwOhSgESkbdS+zJBy4+1mQ3f3Fq9Gp8nT+gaSwk= +github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.5.2 h1:B120/boLr82yRaQFEPn9u01OwWMnc+xGvz5SOHfBrHY= +github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.5.2/go.mod h1:td1djV1rAzEPcit9L8urGneIi2pYvtI7b/kfMWdpe84= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.5.0 h1:SGwKUQaJudQQZE72dDQlL2FGuHNAEK1CyqKLTjh6mqE= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.5.0/go.mod h1:XY5YhCS9SLul3JSQ08XG/nfxXxrkh6RR21XPq/J//NY= +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.4.0 h1:QbFWJr2SAyVYvyoOHvJU6sCGLnqNT94ZbWElJMEI1JY= +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.4.0/go.mod h1:bYsEP8w5YnbYyrx/Zi5hy4hTwRRQISSJS3RWrsGRijg= github.com/aws/aws-sdk-go-v2/service/ec2 v1.1.0 h1:+VnEgB1yp+7KlOsk6FXX/v/fU9uL5oSujIMkKQBBmp8= github.com/aws/aws-sdk-go-v2/service/ec2 v1.1.0/go.mod h1:/6514fU/SRcY3+ousB1zjUqiXjruSuti2qcfE70osOc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.2/go.mod h1:EASdTcM1lGhUe1/p4gkojHwlGJkeoRjjr1sRCzup3Is= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.2/go.mod h1:EASdTcM1lGhUe1/p4gkojHwlGJkeoRjjr1sRCzup3Is= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.3.0 h1:gceOysEWNNwLd6cki65IMBZ4WAM0MwgBQq2n7kejoT8= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.3.0 h1:gceOysEWNNwLd6cki65IMBZ4WAM0MwgBQq2n7kejoT8= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.3.0/go.mod h1:v8ygadNyATSm6elwJ/4gzJwcFhri9RqS8skgHKiwXPU= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.3.0/go.mod h1:v8ygadNyATSm6elwJ/4gzJwcFhri9RqS8skgHKiwXPU= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.0.2/go.mod h1:Gej5xRE+MK0r35OnxJJ07iqQ5JC1avTW/4MwGfsC2io= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.1.0 h1:QCPbsMPMcM4iGbui5SH6O4uxvZffPoBJ4CIGX7dU0l4= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.1.0/go.mod h1:enkU5tq2HoXY+ZMiQprgF3Q83T3PbO77E83yXXzRZWE= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.1/go.mod h1:PISaKWylTYAyruocNk4Lr9miOOJjOcVBd7twCPbydDk= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.2/go.mod h1:NXmNI41bdEsJMrD0v9rUvbGCB5GwdBEpKvUvIY3vTFg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.2/go.mod h1:NXmNI41bdEsJMrD0v9rUvbGCB5GwdBEpKvUvIY3vTFg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.3/go.mod h1:7gcsONBmFoCcKrAqrm95trrMd2+C/ReYKP7Vfu8yHHA= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.1 h1:APEjhKZLFlNVLATnA/TJyA+w1r/xd5r5ACWBDZ9aIvc= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.1/go.mod h1:Ve+eJOx9UWaT/lMVebnFhDhO49fSLVedHoA82+Rqme0= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.5.2/go.mod h1:QuL2Ym8BkrLmN4lUofXYq6000/i5jPjosCNK//t6gak= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.1 h1:YEz2KMyqK2zyG3uOa0l2xBc/H6NUVJir8FhwHQHF3rc= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.1/go.mod h1:yg4EN/BKoc7+DLhNOxxdvoO3+iyW2FuynvaKqLcLDUM= +github.com/aws/aws-sdk-go-v2/service/kinesis v1.6.0 h1:hb+NupVMUzINGUCfDs2+YqMkWKu47dBIQHpulM0XWh4= +github.com/aws/aws-sdk-go-v2/service/kinesis v1.6.0/go.mod h1:9O7UG2pELnP0hq35+Gd7XDjOLBkg7tmgRQ0y14ZjoJI= github.com/aws/aws-sdk-go-v2/service/s3 v1.12.0/go.mod h1:6J++A5xpo7QDsIeSqPK4UHqMSyPOCopa+zKtqAMhqVQ= github.com/aws/aws-sdk-go-v2/service/s3 v1.16.0 h1:dt1JQFj/135ozwGIWeCM3aQ8N/kB3Xu3Uu4r9zuOIyc= github.com/aws/aws-sdk-go-v2/service/s3 v1.16.0/go.mod h1:Tk23mCmfL3wb3tNIeMk/0diUZ0W4R6uZtjYKguMLW2s= github.com/aws/aws-sdk-go-v2/service/sso v1.3.2/go.mod h1:J21I6kF+d/6XHVk7kp/cx9YVD2TMD2TbLwtRGVcinXo= +github.com/aws/aws-sdk-go-v2/service/sso v1.3.2/go.mod h1:J21I6kF+d/6XHVk7kp/cx9YVD2TMD2TbLwtRGVcinXo= +github.com/aws/aws-sdk-go-v2/service/sso v1.3.3/go.mod h1:Jgw5O+SK7MZ2Yi9Yvzb4PggAPYaFSliiQuWR0hNjexk= github.com/aws/aws-sdk-go-v2/service/sso v1.4.1 h1:RfgQyv3bFT2Js6XokcrNtTjQ6wAVBRpoCgTFsypihHA= github.com/aws/aws-sdk-go-v2/service/sso v1.4.1/go.mod h1:ycPdbJZlM0BLhuBnd80WX9PucWPG88qps/2jl9HugXs= github.com/aws/aws-sdk-go-v2/service/sts v1.6.1/go.mod h1:hLZ/AnkIKHLuPGjEiyghNEdvJ2PP0MgOxcmv9EBJ4xs= +github.com/aws/aws-sdk-go-v2/service/sts v1.6.1/go.mod h1:hLZ/AnkIKHLuPGjEiyghNEdvJ2PP0MgOxcmv9EBJ4xs= +github.com/aws/aws-sdk-go-v2/service/sts v1.6.2/go.mod h1:RBhoMJB8yFToaCnbe0jNq5Dcdy0jp6LhHqg55rjClkM= github.com/aws/aws-sdk-go-v2/service/sts v1.7.1 h1:7ce9ugapSgBapwLhg7AJTqKW5U92VRX3vX65k2tsB+g= github.com/aws/aws-sdk-go-v2/service/sts v1.7.1/go.mod h1:r1i8QwKPzwByXqZb3POQfBs7jozrdnHz8PVbsvyx73w= +github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.3.2 h1:1s/RRA5Owuz4/G/eWCdCKgC+9zaz2vxFsRSwe7R3cPY= +github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.3.2 h1:1s/RRA5Owuz4/G/eWCdCKgC+9zaz2vxFsRSwe7R3cPY= +github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.3.2/go.mod h1:XoDkdZ5pBf2za2GWbFHQ8Ps0K8fRbmbwrHh7PF5xnzQ= +github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.3.2/go.mod h1:XoDkdZ5pBf2za2GWbFHQ8Ps0K8fRbmbwrHh7PF5xnzQ= +github.com/aws/smithy-go v1.0.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/aws/smithy-go v1.0.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/aws/smithy-go v1.8.0 h1:AEwwwXQZtUwP5Mz506FeXXrKBe0jA8gVM+1gEcSRooc= github.com/aws/smithy-go v1.8.0 h1:AEwwwXQZtUwP5Mz506FeXXrKBe0jA8gVM+1gEcSRooc= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/awslabs/kinesis-aggregation/go v0.0.0-20210630091500-54e17340d32f h1:Pf0BjJDga7C98f0vhw+Ip5EaiE07S3lTKpIYPNS0nMo= +github.com/awslabs/kinesis-aggregation/go v0.0.0-20210630091500-54e17340d32f/go.mod h1:SghidfnxvX7ribW6nHI7T+IBbc9puZ9kk5Tx/88h8P4= +github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= +github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -580,6 +643,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/digitalocean/godo v1.58.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU= @@ -819,6 +883,7 @@ github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3yg github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-redis/redis/v8 v8.0.0-beta.6/go.mod h1:g79Vpae8JMzg5qjk8BiwU9tK+HmU3iDVyS4UAJLFycI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -954,6 +1019,7 @@ github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZ github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/addlicense v0.0.0-20200906110928-a0294312aa76/go.mod h1:EMjYTRimagHs1FwlIqKyX3wAM0u3rA+McvlIIWmSamA= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -1070,13 +1136,13 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/harlow/kinesis-consumer v0.3.1-0.20181230152818-2f58b136fee0 h1:U0KvGD9CJIl1nbgu9yLsfWxMT6WqL8fG0IBB7RvOZZQ= -github.com/harlow/kinesis-consumer v0.3.1-0.20181230152818-2f58b136fee0/go.mod h1:dk23l2BruuUzRP8wbybQbPn3J7sZga2QHICCeaEy5rQ= +github.com/harlow/kinesis-consumer v0.3.6-0.20210911031324-5a873d6e9fec h1:ya+kv1eNnd5QhcHuaj5g5eMq5Ra3VCNaPY2ZI7Aq91o= +github.com/harlow/kinesis-consumer v0.3.6-0.20210911031324-5a873d6e9fec/go.mod h1:FIT1uhdVv2iXO0l6aACPZSVHxdth7RdmoT34jk9MEm0= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/api v1.8.1/go.mod h1:sDjTOq0yUyv5G4h+BqSea7Fn6BU+XbolEz1952UB+mk= -github.com/hashicorp/consul/api v1.11.0 h1:Hw/G8TtRvOElqxVIhBzXciiSTbapq8hZ2XKZsXk5ZCE= -github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= +github.com/hashicorp/consul/api v1.9.1 h1:SngrdG2L62qqLsUz85qcPhFZ78rPf8tcD5qjMgs6MME= +github.com/hashicorp/consul/api v1.9.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.7.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= @@ -1344,6 +1410,7 @@ github.com/leoluk/perflib_exporter v0.1.0/go.mod h1:rpV0lYj7lemdTm31t7zpCqYqPnw7 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -1415,6 +1482,7 @@ github.com/mdlayher/netlink v1.1.0 h1:mpdLgm+brq10nI9zM1BpX1kpDbh3NLl3RSnVq6ZSkf github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY= github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= github.com/mgechev/revive v1.0.3/go.mod h1:POGGZagSo/0frdr7VeAifzS5Uka0d0GPiM35MsTO8nE= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microsoft/ApplicationInsights-Go v0.4.4 h1:G4+H9WNs6ygSCe6sUyxRc2U81TI5Es90b2t/MwX5KqY= github.com/microsoft/ApplicationInsights-Go v0.4.4/go.mod h1:fKRUseBqkw6bDiXTs3ESTiU/4YTIHsQS4W3fP2ieF4U= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -1609,6 +1677,7 @@ github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKw github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5 h1:ZCnq+JUrvXcDVhX/xRolRBZifmabN1HcS1wrPSvxhrU= @@ -1767,6 +1836,7 @@ github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspo github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1846,11 +1916,14 @@ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sleepinggenius2/gosmi v0.4.3 h1:99Zwzy1Cvgsh396sw07oR2G4ab88ILGZFMxSlGWnR6o= github.com/sleepinggenius2/gosmi v0.4.3/go.mod h1:l8OniPmd3bJzw0MXP2/qh7AhP/e+bTY2CNivIhsnDT0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= +github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= github.com/snowflakedb/gosnowflake v1.6.2 h1:drZkX7Ve3qr3lLD/f0vxwesgJZfNerivknAvPRAMy88= github.com/snowflakedb/gosnowflake v1.6.2/go.mod h1:k1Wq+O8dRD/jmFBLyStEv2OrgHoMFQpqHCRSy70P0dI= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1934,6 +2007,12 @@ github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiff github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= +github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= +github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= +github.com/tj/go-buffer v1.0.1/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj52Uc= +github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0= +github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao= +github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo= github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= @@ -2020,8 +2099,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/gopher-lua v0.0.0-20180630135845-46796da1b0b4 h1:f6CCNiTjQZ0uWK4jPwhwYB8QIGGfn0ssD9kVzRUUUpk= -github.com/yuin/gopher-lua v0.0.0-20180630135845-46796da1b0b4/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= +github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e h1:oIpIX9VKxSCFrfjsKpluGbNPBGq9iNnT9crH781j9wY= +github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -2064,6 +2143,7 @@ go.opentelemetry.io/collector v0.28.0 h1:XmRwoSj3HZtC7O/12fBoQ9DInvwBwFHgHLZrwNx go.opentelemetry.io/collector v0.28.0/go.mod h1:AP/BTXwo1eedoJO7V+HQ68CSvJU1lcdqOzJCgt1VsNs= go.opentelemetry.io/collector/model v0.35.0 h1:NpKjghiqlei4ecwjOYOMhD6tj4gY8yiWHPJmbFs/ArI= go.opentelemetry.io/collector/model v0.35.0/go.mod h1:+7YCSjJG+MqiIFjauzt7oM2qkqBsaJWh5hcsO4fwsAc= +go.opentelemetry.io/otel v0.7.0/go.mod h1:aZMyHG5TqDOXEgH2tyLiXSUKly1jT3yqE9PmrzIeCdo= go.opentelemetry.io/otel v1.0.0-RC3 h1:kvwiyEkiUT/JaadXzVLI/R1wDO934A7r3Bs2wEe6wqA= go.opentelemetry.io/otel v1.0.0-RC3/go.mod h1:Ka5j3ua8tZs4Rkq4Ex3hwgBgOchyPVq5S6P2lz//nKQ= go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.23.0 h1:vKIEsT6IJU0NYd+iZccjgCmk80zsa7dTiC2Bu7U1jz0= @@ -2119,6 +2199,7 @@ golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -2164,8 +2245,9 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 h1:FR+oGxGfbQu1d+jglI3rCkjAjUnhRSZcUxr+DqlDLNo= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20200513190911-00229845015e h1:rMqLP+9XLy+LdbCXHjJHAmTfXCr93W7oruWA6Hq1Alc= +golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -2362,6 +2444,7 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2670,6 +2753,7 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= @@ -2839,6 +2923,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/plugins/inputs/cloudwatch/cloudwatch.go b/plugins/inputs/cloudwatch/cloudwatch.go index 3fb863109..17305f31c 100644 --- a/plugins/inputs/cloudwatch/cloudwatch.go +++ b/plugins/inputs/cloudwatch/cloudwatch.go @@ -1,6 +1,7 @@ package cloudwatch import ( + "context" "fmt" "net" "net/http" @@ -9,8 +10,9 @@ import ( "sync" "time" - "github.com/aws/aws-sdk-go/aws" - cwClient "github.com/aws/aws-sdk-go/service/cloudwatch" + "github.com/aws/aws-sdk-go-v2/aws" + cwClient "github.com/aws/aws-sdk-go-v2/service/cloudwatch" + "github.com/aws/aws-sdk-go-v2/service/cloudwatch/types" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/config" @@ -23,6 +25,14 @@ import ( "github.com/influxdata/telegraf/plugins/inputs" ) +const ( + StatisticAverage = "Average" + StatisticMaximum = "Maximum" + StatisticMinimum = "Minimum" + StatisticSum = "Sum" + StatisticSampleCount = "SampleCount" +) + // CloudWatch contains the configuration and cache for the cloudwatch plugin. type CloudWatch struct { StatisticExclude []string `toml:"statistic_exclude"` @@ -72,12 +82,12 @@ type metricCache struct { ttl time.Duration built time.Time metrics []filteredMetric - queries map[string][]*cwClient.MetricDataQuery + queries map[string][]types.MetricDataQuery } type cloudwatchClient interface { - ListMetrics(*cwClient.ListMetricsInput) (*cwClient.ListMetricsOutput, error) - GetMetricData(*cwClient.GetMetricDataInput) (*cwClient.GetMetricDataOutput, error) + ListMetrics(context.Context, *cwClient.ListMetricsInput, ...func(*cwClient.Options)) (*cwClient.ListMetricsOutput, error) + GetMetricData(context.Context, *cwClient.GetMetricDataInput, ...func(*cwClient.Options)) (*cwClient.GetMetricDataOutput, error) } // SampleConfig returns the default configuration of the Cloudwatch input plugin. @@ -227,12 +237,12 @@ func (c *CloudWatch) Gather(acc telegraf.Accumulator) error { wg := sync.WaitGroup{} rLock := sync.Mutex{} - results := map[string][]*cwClient.MetricDataResult{} + results := map[string][]types.MetricDataResult{} for namespace, namespacedQueries := range queries { // 500 is the maximum number of metric data queries a `GetMetricData` request can contain. batchSize := 500 - var batches [][]*cwClient.MetricDataQuery + var batches [][]types.MetricDataQuery for batchSize < len(namespacedQueries) { namespacedQueries, batches = namespacedQueries[batchSize:], append(batches, namespacedQueries[0:batchSize:batchSize]) @@ -242,7 +252,7 @@ func (c *CloudWatch) Gather(acc telegraf.Accumulator) error { for i := range batches { wg.Add(1) <-lmtr.C - go func(n string, inm []*cwClient.MetricDataQuery) { + go func(n string, inm []types.MetricDataQuery) { defer wg.Done() result, err := c.gatherMetrics(c.getDataInputs(inm)) if err != nil { @@ -268,8 +278,15 @@ func (c *CloudWatch) initializeCloudWatch() error { return err } - cfg := &aws.Config{ - HTTPClient: &http.Client{ + cfg, err := c.CredentialConfig.Credentials() + if err != nil { + return err + } + c.client = cwClient.NewFromConfig(cfg, func(options *cwClient.Options) { + // Disable logging + options.ClientLogMode = 0 + + options.HTTPClient = &http.Client{ // use values from DefaultTransport Transport: &http.Transport{ Proxy: proxy, @@ -284,15 +301,8 @@ func (c *CloudWatch) initializeCloudWatch() error { ExpectContinueTimeout: 1 * time.Second, }, Timeout: time.Duration(c.Timeout), - }, - } - - loglevel := aws.LogOff - p, err := c.CredentialConfig.Credentials() - if err != nil { - return err - } - c.client = cwClient.New(p, cfg.WithLogLevel(loglevel)) + } + }) // Initialize regex matchers for each Dimension value. for _, m := range c.Metrics { @@ -310,7 +320,7 @@ func (c *CloudWatch) initializeCloudWatch() error { } type filteredMetric struct { - metrics []*cwClient.Metric + metrics []types.Metric statFilter filter.Filter } @@ -325,18 +335,18 @@ func getFilteredMetrics(c *CloudWatch) ([]filteredMetric, error) { // check for provided metric filter if c.Metrics != nil { for _, m := range c.Metrics { - metrics := []*cwClient.Metric{} + metrics := []types.Metric{} if !hasWildcard(m.Dimensions) { - dimensions := make([]*cwClient.Dimension, len(m.Dimensions)) + dimensions := make([]types.Dimension, len(m.Dimensions)) for k, d := range m.Dimensions { - dimensions[k] = &cwClient.Dimension{ + dimensions[k] = types.Dimension{ Name: aws.String(d.Name), Value: aws.String(d.Value), } } for _, name := range m.MetricNames { for _, namespace := range c.Namespaces { - metrics = append(metrics, &cwClient.Metric{ + metrics = append(metrics, types.Metric{ Namespace: aws.String(namespace), MetricName: aws.String(name), Dimensions: dimensions, @@ -352,7 +362,7 @@ func getFilteredMetrics(c *CloudWatch) ([]filteredMetric, error) { for _, metric := range allMetrics { if isSelected(name, metric, m.Dimensions) { for _, namespace := range c.Namespaces { - metrics = append(metrics, &cwClient.Metric{ + metrics = append(metrics, types.Metric{ Namespace: aws.String(namespace), MetricName: aws.String(name), Dimensions: metric.Dimensions, @@ -401,32 +411,24 @@ func getFilteredMetrics(c *CloudWatch) ([]filteredMetric, error) { } // fetchNamespaceMetrics retrieves available metrics for a given CloudWatch namespace. -func (c *CloudWatch) fetchNamespaceMetrics() ([]*cwClient.Metric, error) { - metrics := []*cwClient.Metric{} +func (c *CloudWatch) fetchNamespaceMetrics() ([]types.Metric, error) { + metrics := []types.Metric{} var token *string - var params *cwClient.ListMetricsInput - var recentlyActive *string - switch c.RecentlyActive { - case "PT3H": - recentlyActive = &c.RecentlyActive - default: - recentlyActive = nil + params := &cwClient.ListMetricsInput{ + Dimensions: []types.DimensionFilter{}, + NextToken: token, + MetricName: nil, + } + if c.RecentlyActive == "PT3H" { + params.RecentlyActive = types.RecentlyActivePt3h } for _, namespace := range c.Namespaces { - - params = &cwClient.ListMetricsInput{ - Dimensions: []*cwClient.DimensionFilter{}, - NextToken: token, - MetricName: nil, - RecentlyActive: recentlyActive, - Namespace: aws.String(namespace), - } - + params.Namespace = aws.String(namespace) for { - resp, err := c.client.ListMetrics(params) + resp, err := c.client.ListMetrics(context.Background(), params) if err != nil { return nil, fmt.Errorf("failed to list metrics with params per namespace: %v", err) } @@ -457,75 +459,75 @@ func (c *CloudWatch) updateWindow(relativeTo time.Time) { } // getDataQueries gets all of the possible queries so we can maximize the request payload. -func (c *CloudWatch) getDataQueries(filteredMetrics []filteredMetric) map[string][]*cwClient.MetricDataQuery { +func (c *CloudWatch) getDataQueries(filteredMetrics []filteredMetric) map[string][]types.MetricDataQuery { if c.metricCache != nil && c.metricCache.queries != nil && c.metricCache.isValid() { return c.metricCache.queries } c.queryDimensions = map[string]*map[string]string{} - dataQueries := map[string][]*cwClient.MetricDataQuery{} + dataQueries := map[string][]types.MetricDataQuery{} for i, filtered := range filteredMetrics { for j, metric := range filtered.metrics { id := strconv.Itoa(j) + "_" + strconv.Itoa(i) dimension := ctod(metric.Dimensions) if filtered.statFilter.Match("average") { c.queryDimensions["average_"+id] = dimension - dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], &cwClient.MetricDataQuery{ + dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], types.MetricDataQuery{ Id: aws.String("average_" + id), Label: aws.String(snakeCase(*metric.MetricName + "_average")), - MetricStat: &cwClient.MetricStat{ - Metric: metric, - Period: aws.Int64(int64(time.Duration(c.Period).Seconds())), - Stat: aws.String(cwClient.StatisticAverage), + MetricStat: &types.MetricStat{ + Metric: &metric, + Period: aws.Int32(int32(time.Duration(c.Period).Seconds())), + Stat: aws.String(StatisticAverage), }, }) } if filtered.statFilter.Match("maximum") { c.queryDimensions["maximum_"+id] = dimension - dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], &cwClient.MetricDataQuery{ + dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], types.MetricDataQuery{ Id: aws.String("maximum_" + id), Label: aws.String(snakeCase(*metric.MetricName + "_maximum")), - MetricStat: &cwClient.MetricStat{ - Metric: metric, - Period: aws.Int64(int64(time.Duration(c.Period).Seconds())), - Stat: aws.String(cwClient.StatisticMaximum), + MetricStat: &types.MetricStat{ + Metric: &metric, + Period: aws.Int32(int32(time.Duration(c.Period).Seconds())), + Stat: aws.String(StatisticMaximum), }, }) } if filtered.statFilter.Match("minimum") { c.queryDimensions["minimum_"+id] = dimension - dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], &cwClient.MetricDataQuery{ + dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], types.MetricDataQuery{ Id: aws.String("minimum_" + id), Label: aws.String(snakeCase(*metric.MetricName + "_minimum")), - MetricStat: &cwClient.MetricStat{ - Metric: metric, - Period: aws.Int64(int64(time.Duration(c.Period).Seconds())), - Stat: aws.String(cwClient.StatisticMinimum), + MetricStat: &types.MetricStat{ + Metric: &metric, + Period: aws.Int32(int32(time.Duration(c.Period).Seconds())), + Stat: aws.String(StatisticMinimum), }, }) } if filtered.statFilter.Match("sum") { c.queryDimensions["sum_"+id] = dimension - dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], &cwClient.MetricDataQuery{ + dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], types.MetricDataQuery{ Id: aws.String("sum_" + id), Label: aws.String(snakeCase(*metric.MetricName + "_sum")), - MetricStat: &cwClient.MetricStat{ - Metric: metric, - Period: aws.Int64(int64(time.Duration(c.Period).Seconds())), - Stat: aws.String(cwClient.StatisticSum), + MetricStat: &types.MetricStat{ + Metric: &metric, + Period: aws.Int32(int32(time.Duration(c.Period).Seconds())), + Stat: aws.String(StatisticSum), }, }) } if filtered.statFilter.Match("sample_count") { c.queryDimensions["sample_count_"+id] = dimension - dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], &cwClient.MetricDataQuery{ + dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], types.MetricDataQuery{ Id: aws.String("sample_count_" + id), Label: aws.String(snakeCase(*metric.MetricName + "_sample_count")), - MetricStat: &cwClient.MetricStat{ - Metric: metric, - Period: aws.Int64(int64(time.Duration(c.Period).Seconds())), - Stat: aws.String(cwClient.StatisticSampleCount), + MetricStat: &types.MetricStat{ + Metric: &metric, + Period: aws.Int32(int32(time.Duration(c.Period).Seconds())), + Stat: aws.String(StatisticSampleCount), }, }) } @@ -553,11 +555,11 @@ func (c *CloudWatch) getDataQueries(filteredMetrics []filteredMetric) map[string // gatherMetrics gets metric data from Cloudwatch. func (c *CloudWatch) gatherMetrics( params *cwClient.GetMetricDataInput, -) ([]*cwClient.MetricDataResult, error) { - results := []*cwClient.MetricDataResult{} +) ([]types.MetricDataResult, error) { + results := []types.MetricDataResult{} for { - resp, err := c.client.GetMetricData(params) + resp, err := c.client.GetMetricData(context.Background(), params) if err != nil { return nil, fmt.Errorf("failed to get metric data: %v", err) } @@ -574,7 +576,7 @@ func (c *CloudWatch) gatherMetrics( func (c *CloudWatch) aggregateMetrics( acc telegraf.Accumulator, - metricDataResults map[string][]*cwClient.MetricDataResult, + metricDataResults map[string][]types.MetricDataResult, ) error { var ( grouper = internalMetric.NewSeriesGrouper() @@ -592,7 +594,7 @@ func (c *CloudWatch) aggregateMetrics( tags["region"] = c.Region for i := range result.Values { - if err := grouper.Add(namespace, tags, *result.Timestamps[i], *result.Label, *result.Values[i]); err != nil { + if err := grouper.Add(namespace, tags, result.Timestamps[i], *result.Label, result.Values[i]); err != nil { acc.AddError(err) } } @@ -635,7 +637,7 @@ func snakeCase(s string) string { } // ctod converts cloudwatch dimensions to regular dimensions. -func ctod(cDimensions []*cwClient.Dimension) *map[string]string { +func ctod(cDimensions []types.Dimension) *map[string]string { dimensions := map[string]string{} for i := range cDimensions { dimensions[snakeCase(*cDimensions[i].Name)] = *cDimensions[i].Value @@ -643,7 +645,7 @@ func ctod(cDimensions []*cwClient.Dimension) *map[string]string { return &dimensions } -func (c *CloudWatch) getDataInputs(dataQueries []*cwClient.MetricDataQuery) *cwClient.GetMetricDataInput { +func (c *CloudWatch) getDataInputs(dataQueries []types.MetricDataQuery) *cwClient.GetMetricDataInput { return &cwClient.GetMetricDataInput{ StartTime: aws.Time(c.windowStart), EndTime: aws.Time(c.windowEnd), @@ -665,7 +667,7 @@ func hasWildcard(dimensions []*Dimension) bool { return false } -func isSelected(name string, metric *cwClient.Metric, dimensions []*Dimension) bool { +func isSelected(name string, metric types.Metric, dimensions []*Dimension) bool { if name != *metric.MetricName { return false } diff --git a/plugins/inputs/cloudwatch/cloudwatch_test.go b/plugins/inputs/cloudwatch/cloudwatch_test.go index 3114240ec..9672ff88a 100644 --- a/plugins/inputs/cloudwatch/cloudwatch_test.go +++ b/plugins/inputs/cloudwatch/cloudwatch_test.go @@ -1,12 +1,14 @@ package cloudwatch import ( + "context" "net/http" "testing" "time" - "github.com/aws/aws-sdk-go/aws" - cwClient "github.com/aws/aws-sdk-go/service/cloudwatch" + "github.com/aws/aws-sdk-go-v2/aws" + cwClient "github.com/aws/aws-sdk-go-v2/service/cloudwatch" + "github.com/aws/aws-sdk-go-v2/service/cloudwatch/types" "github.com/stretchr/testify/require" "github.com/influxdata/telegraf/config" @@ -18,13 +20,13 @@ import ( type mockGatherCloudWatchClient struct{} -func (m *mockGatherCloudWatchClient) ListMetrics(params *cwClient.ListMetricsInput) (*cwClient.ListMetricsOutput, error) { +func (m *mockGatherCloudWatchClient) ListMetrics(_ context.Context, params *cwClient.ListMetricsInput, _ ...func(*cwClient.Options)) (*cwClient.ListMetricsOutput, error) { return &cwClient.ListMetricsOutput{ - Metrics: []*cwClient.Metric{ + Metrics: []types.Metric{ { Namespace: params.Namespace, MetricName: aws.String("Latency"), - Dimensions: []*cwClient.Dimension{ + Dimensions: []types.Dimension{ { Name: aws.String("LoadBalancerName"), Value: aws.String("p-example"), @@ -35,63 +37,53 @@ func (m *mockGatherCloudWatchClient) ListMetrics(params *cwClient.ListMetricsInp }, nil } -func (m *mockGatherCloudWatchClient) GetMetricData(params *cwClient.GetMetricDataInput) (*cwClient.GetMetricDataOutput, error) { +func (m *mockGatherCloudWatchClient) GetMetricData(_ context.Context, params *cwClient.GetMetricDataInput, _ ...func(*cwClient.Options)) (*cwClient.GetMetricDataOutput, error) { return &cwClient.GetMetricDataOutput{ - MetricDataResults: []*cwClient.MetricDataResult{ + MetricDataResults: []types.MetricDataResult{ { Id: aws.String("minimum_0_0"), Label: aws.String("latency_minimum"), - StatusCode: aws.String("completed"), - Timestamps: []*time.Time{ - params.EndTime, - }, - Values: []*float64{ - aws.Float64(0.1), + StatusCode: types.StatusCodeComplete, + Timestamps: []time.Time{ + *params.EndTime, }, + Values: []float64{0.1}, }, { Id: aws.String("maximum_0_0"), Label: aws.String("latency_maximum"), - StatusCode: aws.String("completed"), - Timestamps: []*time.Time{ - params.EndTime, - }, - Values: []*float64{ - aws.Float64(0.3), + StatusCode: types.StatusCodeComplete, + Timestamps: []time.Time{ + *params.EndTime, }, + Values: []float64{0.3}, }, { Id: aws.String("average_0_0"), Label: aws.String("latency_average"), - StatusCode: aws.String("completed"), - Timestamps: []*time.Time{ - params.EndTime, - }, - Values: []*float64{ - aws.Float64(0.2), + StatusCode: types.StatusCodeComplete, + Timestamps: []time.Time{ + *params.EndTime, }, + Values: []float64{0.2}, }, { Id: aws.String("sum_0_0"), Label: aws.String("latency_sum"), - StatusCode: aws.String("completed"), - Timestamps: []*time.Time{ - params.EndTime, - }, - Values: []*float64{ - aws.Float64(123), + StatusCode: types.StatusCodeComplete, + Timestamps: []time.Time{ + *params.EndTime, }, + Values: []float64{123}, }, { Id: aws.String("sample_count_0_0"), Label: aws.String("latency_sample_count"), - StatusCode: aws.String("completed"), - Timestamps: []*time.Time{ - params.EndTime, - }, - Values: []*float64{ - aws.Float64(100), + StatusCode: types.StatusCodeComplete, + Timestamps: []time.Time{ + *params.EndTime, }, + Values: []float64{100}, }, }, }, nil @@ -158,8 +150,8 @@ func TestGather_MultipleNamespaces(t *testing.T) { type mockSelectMetricsCloudWatchClient struct{} -func (m *mockSelectMetricsCloudWatchClient) ListMetrics(_ *cwClient.ListMetricsInput) (*cwClient.ListMetricsOutput, error) { - metrics := []*cwClient.Metric{} +func (m *mockSelectMetricsCloudWatchClient) ListMetrics(_ context.Context, params *cwClient.ListMetricsInput, _ ...func(*cwClient.Options)) (*cwClient.ListMetricsOutput, error) { + metrics := []types.Metric{} // 4 metrics are available metricNames := []string{"Latency", "RequestCount", "HealthyHostCount", "UnHealthyHostCount"} // for 3 ELBs @@ -169,10 +161,10 @@ func (m *mockSelectMetricsCloudWatchClient) ListMetrics(_ *cwClient.ListMetricsI for _, m := range metricNames { for _, lb := range loadBalancers { // For each metric/ELB pair, we get an aggregate value across all AZs. - metrics = append(metrics, &cwClient.Metric{ + metrics = append(metrics, types.Metric{ Namespace: aws.String("AWS/ELB"), MetricName: aws.String(m), - Dimensions: []*cwClient.Dimension{ + Dimensions: []types.Dimension{ { Name: aws.String("LoadBalancerName"), Value: aws.String(lb), @@ -181,10 +173,10 @@ func (m *mockSelectMetricsCloudWatchClient) ListMetrics(_ *cwClient.ListMetricsI }) for _, az := range availabilityZones { // We get a metric for each metric/ELB/AZ triplet. - metrics = append(metrics, &cwClient.Metric{ + metrics = append(metrics, types.Metric{ Namespace: aws.String("AWS/ELB"), MetricName: aws.String(m), - Dimensions: []*cwClient.Dimension{ + Dimensions: []types.Dimension{ { Name: aws.String("LoadBalancerName"), Value: aws.String(lb), @@ -205,7 +197,7 @@ func (m *mockSelectMetricsCloudWatchClient) ListMetrics(_ *cwClient.ListMetricsI return result, nil } -func (m *mockSelectMetricsCloudWatchClient) GetMetricData(_ *cwClient.GetMetricDataInput) (*cwClient.GetMetricDataOutput, error) { +func (m *mockSelectMetricsCloudWatchClient) GetMetricData(_ context.Context, params *cwClient.GetMetricDataInput, _ ...func(*cwClient.Options)) (*cwClient.GetMetricDataOutput, error) { return nil, nil } @@ -246,16 +238,16 @@ func TestSelectMetrics(t *testing.T) { } func TestGenerateStatisticsInputParams(t *testing.T) { - d := &cwClient.Dimension{ + d := types.Dimension{ Name: aws.String("LoadBalancerName"), Value: aws.String("p-example"), } namespace := "AWS/ELB" - m := &cwClient.Metric{ + m := types.Metric{ MetricName: aws.String("Latency"), - Dimensions: []*cwClient.Dimension{d}, - Namespace: &namespace, + Dimensions: []types.Dimension{d}, + Namespace: aws.String(namespace), } duration, _ := time.ParseDuration("1m") @@ -274,7 +266,7 @@ func TestGenerateStatisticsInputParams(t *testing.T) { c.updateWindow(now) statFilter, _ := filter.NewIncludeExcludeFilter(nil, nil) - queries := c.getDataQueries([]filteredMetric{{metrics: []*cwClient.Metric{m}, statFilter: statFilter}}) + queries := c.getDataQueries([]filteredMetric{{metrics: []types.Metric{m}, statFilter: statFilter}}) params := c.getDataInputs(queries[namespace]) require.EqualValues(t, *params.EndTime, now.Add(-time.Duration(c.Delay))) @@ -285,16 +277,16 @@ func TestGenerateStatisticsInputParams(t *testing.T) { } func TestGenerateStatisticsInputParamsFiltered(t *testing.T) { - d := &cwClient.Dimension{ + d := types.Dimension{ Name: aws.String("LoadBalancerName"), Value: aws.String("p-example"), } namespace := "AWS/ELB" - m := &cwClient.Metric{ + m := types.Metric{ MetricName: aws.String("Latency"), - Dimensions: []*cwClient.Dimension{d}, - Namespace: &namespace, + Dimensions: []types.Dimension{d}, + Namespace: aws.String(namespace), } duration, _ := time.ParseDuration("1m") @@ -313,7 +305,7 @@ func TestGenerateStatisticsInputParamsFiltered(t *testing.T) { c.updateWindow(now) statFilter, _ := filter.NewIncludeExcludeFilter([]string{"average", "sample_count"}, nil) - queries := c.getDataQueries([]filteredMetric{{metrics: []*cwClient.Metric{m}, statFilter: statFilter}}) + queries := c.getDataQueries([]filteredMetric{{metrics: []types.Metric{m}, statFilter: statFilter}}) params := c.getDataInputs(queries[namespace]) require.EqualValues(t, *params.EndTime, now.Add(-time.Duration(c.Delay))) diff --git a/plugins/inputs/kinesis_consumer/kinesis_consumer.go b/plugins/inputs/kinesis_consumer/kinesis_consumer.go index 88b5fef66..4ff66ed1d 100644 --- a/plugins/inputs/kinesis_consumer/kinesis_consumer.go +++ b/plugins/inputs/kinesis_consumer/kinesis_consumer.go @@ -12,10 +12,10 @@ import ( "sync" "time" - "github.com/aws/aws-sdk-go/service/dynamodb" - "github.com/aws/aws-sdk-go/service/kinesis" + "github.com/aws/aws-sdk-go-v2/service/dynamodb" + "github.com/aws/aws-sdk-go-v2/service/kinesis" consumer "github.com/harlow/kinesis-consumer" - "github.com/harlow/kinesis-consumer/checkpoint/ddb" + "github.com/harlow/kinesis-consumer/store/ddb" "github.com/influxdata/telegraf" internalaws "github.com/influxdata/telegraf/config/aws" @@ -44,7 +44,7 @@ type ( acc telegraf.TrackingAccumulator sem chan struct{} - checkpoint consumer.Checkpoint + checkpoint consumer.Store checkpoints map[string]checkpoint records map[telegraf.TrackingID]string checkpointTex sync.Mutex @@ -153,31 +153,19 @@ func (k *KinesisConsumer) SetParser(parser parsers.Parser) { } func (k *KinesisConsumer) connect(ac telegraf.Accumulator) error { - p, err := k.CredentialConfig.Credentials() + cfg, err := k.CredentialConfig.Credentials() if err != nil { return err } - client := kinesis.New(p) + client := kinesis.NewFromConfig(cfg) - k.checkpoint = &noopCheckpoint{} + k.checkpoint = &noopStore{} if k.DynamoDB != nil { - p, err := (&internalaws.CredentialConfig{ - Region: k.Region, - AccessKey: k.AccessKey, - SecretKey: k.SecretKey, - RoleARN: k.RoleARN, - Profile: k.Profile, - Filename: k.Filename, - Token: k.Token, - EndpointURL: k.EndpointURL, - }).Credentials() - if err != nil { - return err - } + var err error k.checkpoint, err = ddb.New( k.DynamoDB.AppName, k.DynamoDB.TableName, - ddb.WithDynamoClient(dynamodb.New(p)), + ddb.WithDynamoClient(dynamodb.NewFromConfig(cfg)), ddb.WithMaxInterval(time.Second*10), ) if err != nil { @@ -189,7 +177,7 @@ func (k *KinesisConsumer) connect(ac telegraf.Accumulator) error { k.StreamName, consumer.WithClient(client), consumer.WithShardIteratorType(k.ShardIteratorType), - consumer.WithCheckpoint(k), + consumer.WithStore(k), ) if err != nil { return err @@ -214,10 +202,10 @@ func (k *KinesisConsumer) connect(ac telegraf.Accumulator) error { k.wg.Add(1) go func() { defer k.wg.Done() - err := k.cons.Scan(ctx, func(r *consumer.Record) consumer.ScanStatus { + err := k.cons.Scan(ctx, func(r *consumer.Record) error { select { case <-ctx.Done(): - return consumer.ScanStatus{Error: ctx.Err()} + return ctx.Err() case k.sem <- struct{}{}: break } @@ -227,7 +215,7 @@ func (k *KinesisConsumer) connect(ac telegraf.Accumulator) error { k.Log.Errorf("Scan parser error: %s", err.Error()) } - return consumer.ScanStatus{} + return nil }) if err != nil { k.cancel() @@ -298,7 +286,7 @@ func (k *KinesisConsumer) onDelivery(ctx context.Context) { } k.lastSeqNum = strToBint(sequenceNum) - if err := k.checkpoint.Set(chk.streamName, chk.shardID, sequenceNum); err != nil { + if err := k.checkpoint.SetCheckpoint(chk.streamName, chk.shardID, sequenceNum); err != nil { k.Log.Debug("Setting checkpoint failed: %v", err) } } else { @@ -332,13 +320,13 @@ func (k *KinesisConsumer) Gather(acc telegraf.Accumulator) error { return nil } -// Get wraps the checkpoint's Get function (called by consumer library) -func (k *KinesisConsumer) Get(streamName, shardID string) (string, error) { - return k.checkpoint.Get(streamName, shardID) +// Get wraps the checkpoint's GetCheckpoint function (called by consumer library) +func (k *KinesisConsumer) GetCheckpoint(streamName, shardID string) (string, error) { + return k.checkpoint.GetCheckpoint(streamName, shardID) } -// Set wraps the checkpoint's Set function (called by consumer library) -func (k *KinesisConsumer) Set(streamName, shardID, sequenceNumber string) error { +// Set wraps the checkpoint's SetCheckpoint function (called by consumer library) +func (k *KinesisConsumer) SetCheckpoint(streamName, shardID, sequenceNumber string) error { if sequenceNumber == "" { return fmt.Errorf("sequence number should not be empty") } @@ -390,10 +378,10 @@ func (k *KinesisConsumer) Init() error { return k.configureProcessContentEncodingFunc() } -type noopCheckpoint struct{} +type noopStore struct{} -func (n noopCheckpoint) Set(string, string, string) error { return nil } -func (n noopCheckpoint) Get(string, string) (string, error) { return "", nil } +func (n noopStore) SetCheckpoint(string, string, string) error { return nil } +func (n noopStore) GetCheckpoint(string, string) (string, error) { return "", nil } func init() { negOne, _ = new(big.Int).SetString("-1", 10) diff --git a/plugins/inputs/kinesis_consumer/kinesis_consumer_test.go b/plugins/inputs/kinesis_consumer/kinesis_consumer_test.go index b8becece0..6d52f0783 100644 --- a/plugins/inputs/kinesis_consumer/kinesis_consumer_test.go +++ b/plugins/inputs/kinesis_consumer/kinesis_consumer_test.go @@ -2,7 +2,8 @@ package kinesis_consumer import ( "encoding/base64" - "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/kinesis/types" consumer "github.com/harlow/kinesis-consumer" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/parsers" @@ -53,7 +54,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) { records: make(map[telegraf.TrackingID]string), }, args: args{ - r: &consumer.Record{Data: notZippedBytes, SequenceNumber: aws.String("anything")}, + r: &consumer.Record{ + Record: types.Record{ + Data: notZippedBytes, + SequenceNumber: aws.String("anything"), + }, + }, }, wantErr: false, expected: expected{ @@ -69,7 +75,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) { records: make(map[telegraf.TrackingID]string), }, args: args{ - r: &consumer.Record{Data: notZippedBytes, SequenceNumber: aws.String("anything")}, + r: &consumer.Record{ + Record: types.Record{ + Data: notZippedBytes, + SequenceNumber: aws.String("anything"), + }, + }, }, wantErr: false, expected: expected{ @@ -85,7 +96,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) { records: make(map[telegraf.TrackingID]string), }, args: args{ - r: &consumer.Record{Data: notZippedBytes, SequenceNumber: aws.String("anything")}, + r: &consumer.Record{ + Record: types.Record{ + Data: notZippedBytes, + SequenceNumber: aws.String("anything"), + }, + }, }, wantErr: false, expected: expected{ @@ -100,7 +116,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) { records: make(map[telegraf.TrackingID]string), }, args: args{ - r: &consumer.Record{Data: notZippedBytes, SequenceNumber: aws.String("anything")}, + r: &consumer.Record{ + Record: types.Record{ + Data: notZippedBytes, + SequenceNumber: aws.String("anything"), + }, + }, }, wantErr: false, expected: expected{ @@ -116,7 +137,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) { records: make(map[telegraf.TrackingID]string), }, args: args{ - r: &consumer.Record{Data: gzippedBytes, SequenceNumber: aws.String("anything")}, + r: &consumer.Record{ + Record: types.Record{ + Data: gzippedBytes, + SequenceNumber: aws.String("anything"), + }, + }, }, wantErr: false, expected: expected{ @@ -132,7 +158,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) { records: make(map[telegraf.TrackingID]string), }, args: args{ - r: &consumer.Record{Data: zlibBytpes, SequenceNumber: aws.String("anything")}, + r: &consumer.Record{ + Record: types.Record{ + Data: zlibBytpes, + SequenceNumber: aws.String("anything"), + }, + }, }, wantErr: false, expected: expected{ diff --git a/plugins/outputs/cloudwatch/cloudwatch.go b/plugins/outputs/cloudwatch/cloudwatch.go index 85f9570b3..129f014bf 100644 --- a/plugins/outputs/cloudwatch/cloudwatch.go +++ b/plugins/outputs/cloudwatch/cloudwatch.go @@ -1,13 +1,15 @@ package cloudwatch import ( + "context" "math" "sort" "strings" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/cloudwatch" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/cloudwatch" + "github.com/aws/aws-sdk-go-v2/service/cloudwatch/types" "github.com/influxdata/telegraf" internalaws "github.com/influxdata/telegraf/config/aws" @@ -17,7 +19,7 @@ import ( type CloudWatch struct { Namespace string `toml:"namespace"` // CloudWatch Metrics Namespace HighResolutionMetrics bool `toml:"high_resolution_metrics"` - svc *cloudwatch.CloudWatch + svc *cloudwatch.Client WriteStatistics bool `toml:"write_statistics"` @@ -38,7 +40,7 @@ const ( type cloudwatchField interface { addValue(sType statisticType, value float64) - buildDatum() []*cloudwatch.MetricDatum + buildDatum() []types.MetricDatum } type statisticField struct { @@ -56,8 +58,8 @@ func (f *statisticField) addValue(sType statisticType, value float64) { } } -func (f *statisticField) buildDatum() []*cloudwatch.MetricDatum { - var datums []*cloudwatch.MetricDatum +func (f *statisticField) buildDatum() []types.MetricDatum { + var datums []types.MetricDatum if f.hasAllFields() { // If we have all required fields, we build datum with StatisticValues @@ -66,24 +68,24 @@ func (f *statisticField) buildDatum() []*cloudwatch.MetricDatum { sum := f.values[statisticTypeSum] count := f.values[statisticTypeCount] - datum := &cloudwatch.MetricDatum{ + datum := types.MetricDatum{ MetricName: aws.String(strings.Join([]string{f.metricName, f.fieldName}, "_")), Dimensions: BuildDimensions(f.tags), Timestamp: aws.Time(f.timestamp), - StatisticValues: &cloudwatch.StatisticSet{ + StatisticValues: &types.StatisticSet{ Minimum: aws.Float64(min), Maximum: aws.Float64(max), Sum: aws.Float64(sum), SampleCount: aws.Float64(count), }, - StorageResolution: aws.Int64(f.storageResolution), + StorageResolution: aws.Int32(int32(f.storageResolution)), } datums = append(datums, datum) } else { // If we don't have all required fields, we build each field as independent datum for sType, value := range f.values { - datum := &cloudwatch.MetricDatum{ + datum := types.MetricDatum{ Value: aws.Float64(value), Dimensions: BuildDimensions(f.tags), Timestamp: aws.Time(f.timestamp), @@ -134,14 +136,14 @@ func (f *valueField) addValue(sType statisticType, value float64) { } } -func (f *valueField) buildDatum() []*cloudwatch.MetricDatum { - return []*cloudwatch.MetricDatum{ +func (f *valueField) buildDatum() []types.MetricDatum { + return []types.MetricDatum{ { MetricName: aws.String(strings.Join([]string{f.metricName, f.fieldName}, "_")), Value: aws.Float64(f.value), Dimensions: BuildDimensions(f.tags), Timestamp: aws.Time(f.timestamp), - StorageResolution: aws.Int64(f.storageResolution), + StorageResolution: aws.Int32(int32(f.storageResolution)), }, } } @@ -198,11 +200,12 @@ func (c *CloudWatch) Description() string { } func (c *CloudWatch) Connect() error { - p, err := c.CredentialConfig.Credentials() + cfg, err := c.CredentialConfig.Credentials() if err != nil { return err } - c.svc = cloudwatch.New(p) + + c.svc = cloudwatch.NewFromConfig(cfg) return nil } @@ -211,7 +214,7 @@ func (c *CloudWatch) Close() error { } func (c *CloudWatch) Write(metrics []telegraf.Metric) error { - var datums []*cloudwatch.MetricDatum + var datums []types.MetricDatum for _, m := range metrics { d := BuildMetricDatum(c.WriteStatistics, c.HighResolutionMetrics, m) datums = append(datums, d...) @@ -229,13 +232,13 @@ func (c *CloudWatch) Write(metrics []telegraf.Metric) error { return nil } -func (c *CloudWatch) WriteToCloudWatch(datums []*cloudwatch.MetricDatum) error { +func (c *CloudWatch) WriteToCloudWatch(datums []types.MetricDatum) error { params := &cloudwatch.PutMetricDataInput{ MetricData: datums, Namespace: aws.String(c.Namespace), } - _, err := c.svc.PutMetricData(params) + _, err := c.svc.PutMetricData(context.Background(), params) if err != nil { c.Log.Errorf("Unable to write to CloudWatch : %+v", err.Error()) @@ -246,13 +249,13 @@ func (c *CloudWatch) WriteToCloudWatch(datums []*cloudwatch.MetricDatum) error { // Partition the MetricDatums into smaller slices of a max size so that are under the limit // for the AWS API calls. -func PartitionDatums(size int, datums []*cloudwatch.MetricDatum) [][]*cloudwatch.MetricDatum { +func PartitionDatums(size int, datums []types.MetricDatum) [][]types.MetricDatum { numberOfPartitions := len(datums) / size if len(datums)%size != 0 { numberOfPartitions++ } - partitions := make([][]*cloudwatch.MetricDatum, numberOfPartitions) + partitions := make([][]types.MetricDatum, numberOfPartitions) for i := 0; i < numberOfPartitions; i++ { start := size * i @@ -270,7 +273,7 @@ func PartitionDatums(size int, datums []*cloudwatch.MetricDatum) [][]*cloudwatch // Make a MetricDatum from telegraf.Metric. It would check if all required fields of // cloudwatch.StatisticSet are available. If so, it would build MetricDatum from statistic values. // Otherwise, fields would still been built independently. -func BuildMetricDatum(buildStatistic bool, highResolutionMetrics bool, point telegraf.Metric) []*cloudwatch.MetricDatum { +func BuildMetricDatum(buildStatistic bool, highResolutionMetrics bool, point telegraf.Metric) []types.MetricDatum { fields := make(map[string]cloudwatchField) tags := point.Tags() storageResolution := int64(60) @@ -320,7 +323,7 @@ func BuildMetricDatum(buildStatistic bool, highResolutionMetrics bool, point tel } } - var datums []*cloudwatch.MetricDatum + var datums []types.MetricDatum for _, f := range fields { d := f.buildDatum() datums = append(datums, d...) @@ -332,13 +335,13 @@ func BuildMetricDatum(buildStatistic bool, highResolutionMetrics bool, point tel // Make a list of Dimensions by using a Point's tags. CloudWatch supports up to // 10 dimensions per metric so we only keep up to the first 10 alphabetically. // This always includes the "host" tag if it exists. -func BuildDimensions(mTags map[string]string) []*cloudwatch.Dimension { +func BuildDimensions(mTags map[string]string) []types.Dimension { const MaxDimensions = 10 - dimensions := make([]*cloudwatch.Dimension, 0, MaxDimensions) + dimensions := make([]types.Dimension, 0, MaxDimensions) // This is pretty ugly but we always want to include the "host" tag if it exists. if host, ok := mTags["host"]; ok { - dimensions = append(dimensions, &cloudwatch.Dimension{ + dimensions = append(dimensions, types.Dimension{ Name: aws.String("host"), Value: aws.String(host), }) @@ -362,7 +365,7 @@ func BuildDimensions(mTags map[string]string) []*cloudwatch.Dimension { continue } - dimensions = append(dimensions, &cloudwatch.Dimension{ + dimensions = append(dimensions, types.Dimension{ Name: aws.String(k), Value: aws.String(mTags[k]), }) diff --git a/plugins/outputs/cloudwatch/cloudwatch_test.go b/plugins/outputs/cloudwatch/cloudwatch_test.go index 95987f591..df98381cf 100644 --- a/plugins/outputs/cloudwatch/cloudwatch_test.go +++ b/plugins/outputs/cloudwatch/cloudwatch_test.go @@ -2,14 +2,13 @@ package cloudwatch import ( "fmt" + "github.com/aws/aws-sdk-go-v2/service/cloudwatch/types" "math" "sort" "testing" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/cloudwatch" - + "github.com/aws/aws-sdk-go-v2/aws" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/metric" "github.com/influxdata/telegraf/testutil" @@ -117,8 +116,8 @@ func TestBuildMetricDatums(t *testing.T) { } func TestMetricDatumResolution(t *testing.T) { - const expectedStandardResolutionValue = int64(60) - const expectedHighResolutionValue = int64(1) + const expectedStandardResolutionValue = int32(60) + const expectedHighResolutionValue = int32(1) assert := assert.New(t) @@ -153,19 +152,19 @@ func TestBuildMetricDatums_SkipEmptyTags(t *testing.T) { func TestPartitionDatums(t *testing.T) { assert := assert.New(t) - testDatum := cloudwatch.MetricDatum{ + testDatum := types.MetricDatum{ MetricName: aws.String("Foo"), Value: aws.Float64(1), } - zeroDatum := []*cloudwatch.MetricDatum{} - oneDatum := []*cloudwatch.MetricDatum{&testDatum} - twoDatum := []*cloudwatch.MetricDatum{&testDatum, &testDatum} - threeDatum := []*cloudwatch.MetricDatum{&testDatum, &testDatum, &testDatum} + zeroDatum := []types.MetricDatum{} + oneDatum := []types.MetricDatum{testDatum} + twoDatum := []types.MetricDatum{testDatum, testDatum} + threeDatum := []types.MetricDatum{testDatum, testDatum, testDatum} - assert.Equal([][]*cloudwatch.MetricDatum{}, PartitionDatums(2, zeroDatum)) - assert.Equal([][]*cloudwatch.MetricDatum{oneDatum}, PartitionDatums(2, oneDatum)) - assert.Equal([][]*cloudwatch.MetricDatum{oneDatum}, PartitionDatums(2, oneDatum)) - assert.Equal([][]*cloudwatch.MetricDatum{twoDatum}, PartitionDatums(2, twoDatum)) - assert.Equal([][]*cloudwatch.MetricDatum{twoDatum, oneDatum}, PartitionDatums(2, threeDatum)) + assert.Equal([][]types.MetricDatum{}, PartitionDatums(2, zeroDatum)) + assert.Equal([][]types.MetricDatum{oneDatum}, PartitionDatums(2, oneDatum)) + assert.Equal([][]types.MetricDatum{oneDatum}, PartitionDatums(2, oneDatum)) + assert.Equal([][]types.MetricDatum{twoDatum}, PartitionDatums(2, twoDatum)) + assert.Equal([][]types.MetricDatum{twoDatum, oneDatum}, PartitionDatums(2, threeDatum)) } diff --git a/plugins/outputs/cloudwatch_logs/cloudwatch_logs.go b/plugins/outputs/cloudwatch_logs/cloudwatch_logs.go index f9ef28908..952fea4b2 100644 --- a/plugins/outputs/cloudwatch_logs/cloudwatch_logs.go +++ b/plugins/outputs/cloudwatch_logs/cloudwatch_logs.go @@ -1,19 +1,21 @@ package cloudwatch_logs import ( + "context" "fmt" "sort" "strings" "time" - "github.com/aws/aws-sdk-go/service/cloudwatchlogs" + "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs" + "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types" "github.com/influxdata/telegraf" internalaws "github.com/influxdata/telegraf/config/aws" "github.com/influxdata/telegraf/plugins/outputs" ) type messageBatch struct { - logEvents []*cloudwatchlogs.InputLogEvent + logEvents []types.InputLogEvent messageCount int } type logStreamContainer struct { @@ -25,16 +27,16 @@ type logStreamContainer struct { //Cloudwatch Logs service interface type cloudWatchLogs interface { - DescribeLogGroups(*cloudwatchlogs.DescribeLogGroupsInput) (*cloudwatchlogs.DescribeLogGroupsOutput, error) - DescribeLogStreams(*cloudwatchlogs.DescribeLogStreamsInput) (*cloudwatchlogs.DescribeLogStreamsOutput, error) - CreateLogStream(*cloudwatchlogs.CreateLogStreamInput) (*cloudwatchlogs.CreateLogStreamOutput, error) - PutLogEvents(*cloudwatchlogs.PutLogEventsInput) (*cloudwatchlogs.PutLogEventsOutput, error) + DescribeLogGroups(context.Context, *cloudwatchlogs.DescribeLogGroupsInput, ...func(options *cloudwatchlogs.Options)) (*cloudwatchlogs.DescribeLogGroupsOutput, error) + DescribeLogStreams(context.Context, *cloudwatchlogs.DescribeLogStreamsInput, ...func(options *cloudwatchlogs.Options)) (*cloudwatchlogs.DescribeLogStreamsOutput, error) + CreateLogStream(context.Context, *cloudwatchlogs.CreateLogStreamInput, ...func(options *cloudwatchlogs.Options)) (*cloudwatchlogs.CreateLogStreamOutput, error) + PutLogEvents(context.Context, *cloudwatchlogs.PutLogEventsInput, ...func(options *cloudwatchlogs.Options)) (*cloudwatchlogs.PutLogEventsOutput, error) } // CloudWatchLogs plugin object definition type CloudWatchLogs struct { - LogGroup string `toml:"log_group"` - lg *cloudwatchlogs.LogGroup //log group data + LogGroup string `toml:"log_group"` + lg *types.LogGroup //log group data LogStream string `toml:"log_stream"` lsKey string //log stream source: tag or field @@ -187,19 +189,17 @@ func (c *CloudWatchLogs) Connect() error { var logGroupsOutput = &cloudwatchlogs.DescribeLogGroupsOutput{NextToken: &dummyToken} var err error - p, err := c.CredentialConfig.Credentials() + cfg, err := c.CredentialConfig.Credentials() if err != nil { return err } - c.svc = cloudwatchlogs.New(p) - if c.svc == nil { - return fmt.Errorf("can't create cloudwatch logs service endpoint") - } + c.svc = cloudwatchlogs.NewFromConfig(cfg) //Find log group with name 'c.LogGroup' if c.lg == nil { //In case connection is not retried, first time for logGroupsOutput.NextToken != nil { logGroupsOutput, err = c.svc.DescribeLogGroups( + context.Background(), &cloudwatchlogs.DescribeLogGroupsInput{ LogGroupNamePrefix: &c.LogGroup, NextToken: queryToken}) @@ -212,7 +212,7 @@ func (c *CloudWatchLogs) Connect() error { for _, logGroup := range logGroupsOutput.LogGroups { if *(logGroup.LogGroupName) == c.LogGroup { c.Log.Debugf("Found log group %q", c.LogGroup) - c.lg = logGroup + c.lg = &logGroup //nolint:revive } } } @@ -325,7 +325,7 @@ func (c *CloudWatchLogs) Write(metrics []telegraf.Metric) error { lsContainer = val } else { lsContainer.messageBatches[0].messageCount = 0 - lsContainer.messageBatches[0].logEvents = []*cloudwatchlogs.InputLogEvent{} + lsContainer.messageBatches[0].logEvents = []types.InputLogEvent{} c.ls[logStream] = lsContainer } @@ -335,7 +335,7 @@ func (c *CloudWatchLogs) Write(metrics []telegraf.Metric) error { lsContainer.currentBatchIndex++ lsContainer.messageBatches = append(lsContainer.messageBatches, messageBatch{ - logEvents: []*cloudwatchlogs.InputLogEvent{}, + logEvents: []types.InputLogEvent{}, messageCount: 0}) lsContainer.currentBatchSizeBytes = messageSizeInBytesForAWS } else { @@ -349,7 +349,7 @@ func (c *CloudWatchLogs) Write(metrics []telegraf.Metric) error { //Adding metring to batch lsContainer.messageBatches[lsContainer.currentBatchIndex].logEvents = append(lsContainer.messageBatches[lsContainer.currentBatchIndex].logEvents, - &cloudwatchlogs.InputLogEvent{ + types.InputLogEvent{ Message: &logData, Timestamp: &metricTime}) } @@ -370,11 +370,11 @@ func (c *CloudWatchLogs) Write(metrics []telegraf.Metric) error { if elem.sequenceToken == "" { //This is the first attempt to write to log stream, //need to check log stream existence and create it if necessary - describeLogStreamOutput, err := c.svc.DescribeLogStreams(&cloudwatchlogs.DescribeLogStreamsInput{ + describeLogStreamOutput, err := c.svc.DescribeLogStreams(context.Background(), &cloudwatchlogs.DescribeLogStreamsInput{ LogGroupName: &c.LogGroup, LogStreamNamePrefix: &logStream}) if err == nil && len(describeLogStreamOutput.LogStreams) == 0 { - _, err := c.svc.CreateLogStream(&cloudwatchlogs.CreateLogStreamInput{ + _, err := c.svc.CreateLogStream(context.Background(), &cloudwatchlogs.CreateLogStreamInput{ LogGroupName: &c.LogGroup, LogStreamName: &logStream}) if err != nil { @@ -404,14 +404,14 @@ func (c *CloudWatchLogs) Write(metrics []telegraf.Metric) error { //There is a quota of 5 requests per second per log stream. Additional //requests are throttled. This quota can't be changed. - putLogEventsOutput, err := c.svc.PutLogEvents(&putLogEvents) + putLogEventsOutput, err := c.svc.PutLogEvents(context.Background(), &putLogEvents) if err != nil { c.Log.Errorf("Can't push logs batch to AWS. Reason: %v", err) continue } //Cleanup batch elem.messageBatches[index] = messageBatch{ - logEvents: []*cloudwatchlogs.InputLogEvent{}, + logEvents: []types.InputLogEvent{}, messageCount: 0} elem.sequenceToken = *putLogEventsOutput.NextSequenceToken diff --git a/plugins/outputs/cloudwatch_logs/cloudwatch_logs_test.go b/plugins/outputs/cloudwatch_logs/cloudwatch_logs_test.go index f2f9f0cac..e103eb53d 100644 --- a/plugins/outputs/cloudwatch_logs/cloudwatch_logs_test.go +++ b/plugins/outputs/cloudwatch_logs/cloudwatch_logs_test.go @@ -1,6 +1,7 @@ package cloudwatch_logs import ( + "context" "fmt" "math/rand" "net/http" @@ -8,7 +9,8 @@ import ( "testing" "time" - "github.com/aws/aws-sdk-go/service/cloudwatchlogs" + cloudwatchlogsV2 "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs" + "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types" "github.com/influxdata/telegraf" internalaws "github.com/influxdata/telegraf/config/aws" "github.com/influxdata/telegraf/testutil" @@ -17,24 +19,24 @@ import ( type mockCloudWatchLogs struct { logStreamName string - pushedLogEvents []cloudwatchlogs.InputLogEvent + pushedLogEvents []types.InputLogEvent } func (c *mockCloudWatchLogs) Init(lsName string) { c.logStreamName = lsName - c.pushedLogEvents = make([]cloudwatchlogs.InputLogEvent, 0) + c.pushedLogEvents = make([]types.InputLogEvent, 0) } -func (c *mockCloudWatchLogs) DescribeLogGroups(*cloudwatchlogs.DescribeLogGroupsInput) (*cloudwatchlogs.DescribeLogGroupsOutput, error) { +func (c *mockCloudWatchLogs) DescribeLogGroups(context.Context, *cloudwatchlogsV2.DescribeLogGroupsInput, ...func(options *cloudwatchlogsV2.Options)) (*cloudwatchlogsV2.DescribeLogGroupsOutput, error) { return nil, nil } -func (c *mockCloudWatchLogs) DescribeLogStreams(*cloudwatchlogs.DescribeLogStreamsInput) (*cloudwatchlogs.DescribeLogStreamsOutput, error) { +func (c *mockCloudWatchLogs) DescribeLogStreams(context.Context, *cloudwatchlogsV2.DescribeLogStreamsInput, ...func(options *cloudwatchlogsV2.Options)) (*cloudwatchlogsV2.DescribeLogStreamsOutput, error) { arn := "arn" creationTime := time.Now().Unix() sequenceToken := "arbitraryToken" - output := &cloudwatchlogs.DescribeLogStreamsOutput{ - LogStreams: []*cloudwatchlogs.LogStream{ + output := &cloudwatchlogsV2.DescribeLogStreamsOutput{ + LogStreams: []types.LogStream{ { Arn: &arn, CreationTime: &creationTime, @@ -48,15 +50,15 @@ func (c *mockCloudWatchLogs) DescribeLogStreams(*cloudwatchlogs.DescribeLogStrea } return output, nil } -func (c *mockCloudWatchLogs) CreateLogStream(*cloudwatchlogs.CreateLogStreamInput) (*cloudwatchlogs.CreateLogStreamOutput, error) { +func (c *mockCloudWatchLogs) CreateLogStream(context.Context, *cloudwatchlogsV2.CreateLogStreamInput, ...func(options *cloudwatchlogsV2.Options)) (*cloudwatchlogsV2.CreateLogStreamOutput, error) { return nil, nil } -func (c *mockCloudWatchLogs) PutLogEvents(input *cloudwatchlogs.PutLogEventsInput) (*cloudwatchlogs.PutLogEventsOutput, error) { +func (c *mockCloudWatchLogs) PutLogEvents(_ context.Context, input *cloudwatchlogsV2.PutLogEventsInput, _ ...func(options *cloudwatchlogsV2.Options)) (*cloudwatchlogsV2.PutLogEventsOutput, error) { sequenceToken := "arbitraryToken" - output := &cloudwatchlogs.PutLogEventsOutput{NextSequenceToken: &sequenceToken} + output := &cloudwatchlogsV2.PutLogEventsOutput{NextSequenceToken: &sequenceToken} //Saving messages for _, event := range input.LogEvents { - c.pushedLogEvents = append(c.pushedLogEvents, *event) + c.pushedLogEvents = append(c.pushedLogEvents, event) } return output, nil diff --git a/plugins/outputs/kinesis/kinesis.go b/plugins/outputs/kinesis/kinesis.go index 412e3d974..568583408 100644 --- a/plugins/outputs/kinesis/kinesis.go +++ b/plugins/outputs/kinesis/kinesis.go @@ -1,11 +1,12 @@ package kinesis import ( + "context" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/kinesis" - "github.com/aws/aws-sdk-go/service/kinesis/kinesisiface" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/kinesis" + "github.com/aws/aws-sdk-go-v2/service/kinesis/types" "github.com/gofrs/uuid" "github.com/influxdata/telegraf" internalaws "github.com/influxdata/telegraf/config/aws" @@ -26,7 +27,7 @@ type ( Log telegraf.Logger `toml:"-"` serializer serializers.Serializer - svc kinesisiface.KinesisAPI + svc kinesisClient internalaws.CredentialConfig } @@ -38,6 +39,10 @@ type ( } ) +type kinesisClient interface { + PutRecords(context.Context, *kinesis.PutRecordsInput, ...func(*kinesis.Options)) (*kinesis.PutRecordsOutput, error) +} + var sampleConfig = ` ## Amazon REGION of kinesis endpoint. region = "ap-southeast-2" @@ -126,13 +131,14 @@ func (k *KinesisOutput) Connect() error { k.Log.Infof("Establishing a connection to Kinesis in %s", k.Region) } - p, err := k.CredentialConfig.Credentials() + cfg, err := k.CredentialConfig.Credentials() if err != nil { return err } - svc := kinesis.New(p) - _, err = svc.DescribeStreamSummary(&kinesis.DescribeStreamSummaryInput{ + svc := kinesis.NewFromConfig(cfg) + + _, err = svc.DescribeStreamSummary(context.Background(), &kinesis.DescribeStreamSummaryInput{ StreamName: aws.String(k.StreamName), }) k.svc = svc @@ -147,14 +153,14 @@ func (k *KinesisOutput) SetSerializer(serializer serializers.Serializer) { k.serializer = serializer } -func (k *KinesisOutput) writeKinesis(r []*kinesis.PutRecordsRequestEntry) time.Duration { +func (k *KinesisOutput) writeKinesis(r []types.PutRecordsRequestEntry) time.Duration { start := time.Now() payload := &kinesis.PutRecordsInput{ Records: r, StreamName: aws.String(k.StreamName), } - resp, err := k.svc.PutRecords(payload) + resp, err := k.svc.PutRecords(context.Background(), payload) if err != nil { k.Log.Errorf("Unable to write to Kinesis : %s", err.Error()) return time.Since(start) @@ -214,7 +220,7 @@ func (k *KinesisOutput) Write(metrics []telegraf.Metric) error { return nil } - r := []*kinesis.PutRecordsRequestEntry{} + r := []types.PutRecordsRequestEntry{} for _, metric := range metrics { sz++ @@ -227,12 +233,12 @@ func (k *KinesisOutput) Write(metrics []telegraf.Metric) error { partitionKey := k.getPartitionKey(metric) - d := kinesis.PutRecordsRequestEntry{ + d := types.PutRecordsRequestEntry{ Data: values, PartitionKey: aws.String(partitionKey), } - r = append(r, &d) + r = append(r, d) if sz == maxRecordsPerRequest { elapsed := k.writeKinesis(r) diff --git a/plugins/outputs/kinesis/kinesis_test.go b/plugins/outputs/kinesis/kinesis_test.go index 22b8e83e4..89724ef18 100644 --- a/plugins/outputs/kinesis/kinesis_test.go +++ b/plugins/outputs/kinesis/kinesis_test.go @@ -1,13 +1,13 @@ package kinesis import ( + "context" "fmt" "testing" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/service/kinesis" - "github.com/aws/aws-sdk-go/service/kinesis/kinesisiface" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/kinesis" + "github.com/aws/aws-sdk-go-v2/service/kinesis/types" "github.com/gofrs/uuid" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/serializers" @@ -110,7 +110,7 @@ func TestPartitionKey(t *testing.T) { func TestWriteKinesis_WhenSuccess(t *testing.T) { assert := assert.New(t) - records := []*kinesis.PutRecordsRequestEntry{ + records := []types.PutRecordsRequestEntry{ { PartitionKey: aws.String(testPartitionKey), Data: []byte{0x65}, @@ -120,7 +120,7 @@ func TestWriteKinesis_WhenSuccess(t *testing.T) { svc := &mockKinesisPutRecords{} svc.SetupResponse( 0, - []*kinesis.PutRecordsResultEntry{ + []types.PutRecordsResultEntry{ { SequenceNumber: aws.String(testSequenceNumber), ShardId: aws.String(testShardID), @@ -148,7 +148,7 @@ func TestWriteKinesis_WhenSuccess(t *testing.T) { func TestWriteKinesis_WhenRecordErrors(t *testing.T) { assert := assert.New(t) - records := []*kinesis.PutRecordsRequestEntry{ + records := []types.PutRecordsRequestEntry{ { PartitionKey: aws.String(testPartitionKey), Data: []byte{0x66}, @@ -158,7 +158,7 @@ func TestWriteKinesis_WhenRecordErrors(t *testing.T) { svc := &mockKinesisPutRecords{} svc.SetupResponse( 1, - []*kinesis.PutRecordsResultEntry{ + []types.PutRecordsResultEntry{ { ErrorCode: aws.String("InternalFailure"), ErrorMessage: aws.String("Internal Service Failure"), @@ -186,7 +186,7 @@ func TestWriteKinesis_WhenRecordErrors(t *testing.T) { func TestWriteKinesis_WhenServiceError(t *testing.T) { assert := assert.New(t) - records := []*kinesis.PutRecordsRequestEntry{ + records := []types.PutRecordsRequestEntry{ { PartitionKey: aws.String(testPartitionKey), Data: []byte{}, @@ -195,7 +195,7 @@ func TestWriteKinesis_WhenServiceError(t *testing.T) { svc := &mockKinesisPutRecords{} svc.SetupErrorResponse( - awserr.New("InvalidArgumentException", "Invalid record", nil), + &types.InvalidArgumentException{Message: aws.String("Invalid record")}, ) k := KinesisOutput{ @@ -262,7 +262,7 @@ func TestWrite_SingleMetric(t *testing.T) { svc.AssertRequests(t, []*kinesis.PutRecordsInput{ { StreamName: aws.String(testStreamName), - Records: []*kinesis.PutRecordsRequestEntry{ + Records: []types.PutRecordsRequestEntry{ { PartitionKey: aws.String(testPartitionKey), Data: metricData, @@ -449,7 +449,7 @@ func TestWrite_SerializerError(t *testing.T) { svc.AssertRequests(t, []*kinesis.PutRecordsInput{ { StreamName: aws.String(testStreamName), - Records: []*kinesis.PutRecordsRequestEntry{ + Records: []types.PutRecordsRequestEntry{ { PartitionKey: aws.String(testPartitionKey), Data: metric1Data, @@ -469,20 +469,18 @@ type mockKinesisPutRecordsResponse struct { } type mockKinesisPutRecords struct { - kinesisiface.KinesisAPI - requests []*kinesis.PutRecordsInput responses []*mockKinesisPutRecordsResponse } func (m *mockKinesisPutRecords) SetupResponse( - failedRecordCount int64, - records []*kinesis.PutRecordsResultEntry, + failedRecordCount int32, + records []types.PutRecordsResultEntry, ) { m.responses = append(m.responses, &mockKinesisPutRecordsResponse{ Err: nil, Output: &kinesis.PutRecordsOutput{ - FailedRecordCount: aws.Int64(failedRecordCount), + FailedRecordCount: aws.Int32(failedRecordCount), Records: records, }, }) @@ -490,25 +488,25 @@ func (m *mockKinesisPutRecords) SetupResponse( func (m *mockKinesisPutRecords) SetupGenericResponse( successfulRecordCount uint32, - failedRecordCount uint32, + failedRecordCount int32, ) { - records := []*kinesis.PutRecordsResultEntry{} + records := []types.PutRecordsResultEntry{} for i := uint32(0); i < successfulRecordCount; i++ { - records = append(records, &kinesis.PutRecordsResultEntry{ + records = append(records, types.PutRecordsResultEntry{ SequenceNumber: aws.String(testSequenceNumber), ShardId: aws.String(testShardID), }) } - for i := uint32(0); i < failedRecordCount; i++ { - records = append(records, &kinesis.PutRecordsResultEntry{ + for i := int32(0); i < failedRecordCount; i++ { + records = append(records, types.PutRecordsResultEntry{ ErrorCode: aws.String("InternalFailure"), ErrorMessage: aws.String("Internal Service Failure"), }) } - m.SetupResponse(int64(failedRecordCount), records) + m.SetupResponse(failedRecordCount, records) } func (m *mockKinesisPutRecords) SetupErrorResponse(err error) { @@ -518,7 +516,7 @@ func (m *mockKinesisPutRecords) SetupErrorResponse(err error) { }) } -func (m *mockKinesisPutRecords) PutRecords(input *kinesis.PutRecordsInput) (*kinesis.PutRecordsOutput, error) { +func (m *mockKinesisPutRecords) PutRecords(_ context.Context, input *kinesis.PutRecordsInput, _ ...func(*kinesis.Options)) (*kinesis.PutRecordsOutput, error) { reqNum := len(m.requests) if reqNum > len(m.responses) { return nil, fmt.Errorf("Response for request %+v not setup", reqNum) @@ -612,12 +610,12 @@ func createTestMetrics( func createPutRecordsRequestEntries( metricsData [][]byte, -) []*kinesis.PutRecordsRequestEntry { +) []types.PutRecordsRequestEntry { count := len(metricsData) - records := make([]*kinesis.PutRecordsRequestEntry, count) + records := make([]types.PutRecordsRequestEntry, count) for i := 0; i < count; i++ { - records[i] = &kinesis.PutRecordsRequestEntry{ + records[i] = types.PutRecordsRequestEntry{ PartitionKey: aws.String(testPartitionKey), Data: metricsData[i], } diff --git a/plugins/outputs/timestream/timestream.go b/plugins/outputs/timestream/timestream.go index 42ea706af..6478563b6 100644 --- a/plugins/outputs/timestream/timestream.go +++ b/plugins/outputs/timestream/timestream.go @@ -1,7 +1,9 @@ package timestream import ( + "context" "encoding/binary" + "errors" "fmt" "hash/fnv" "reflect" @@ -11,9 +13,10 @@ import ( "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/outputs" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/service/timestreamwrite" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/timestreamwrite" + "github.com/aws/aws-sdk-go-v2/service/timestreamwrite/types" + "github.com/aws/smithy-go" internalaws "github.com/influxdata/telegraf/config/aws" ) @@ -38,9 +41,9 @@ type ( } WriteClient interface { - CreateTable(*timestreamwrite.CreateTableInput) (*timestreamwrite.CreateTableOutput, error) - WriteRecords(*timestreamwrite.WriteRecordsInput) (*timestreamwrite.WriteRecordsOutput, error) - DescribeDatabase(*timestreamwrite.DescribeDatabaseInput) (*timestreamwrite.DescribeDatabaseOutput, error) + CreateTable(context.Context, *timestreamwrite.CreateTableInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.CreateTableOutput, error) + WriteRecords(context.Context, *timestreamwrite.WriteRecordsInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.WriteRecordsOutput, error) + DescribeDatabase(context.Context, *timestreamwrite.DescribeDatabaseInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.DescribeDatabaseOutput, error) } ) @@ -170,11 +173,11 @@ var sampleConfig = ` // WriteFactory function provides a way to mock the client instantiation for testing purposes. var WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (WriteClient, error) { - configProvider, err := credentialConfig.Credentials() + cfg, err := credentialConfig.Credentials() if err != nil { - return nil, err + return ×treamwrite.Client{}, err } - return timestreamwrite.New(configProvider), nil + return timestreamwrite.NewFromConfig(cfg), nil } func (t *Timestream) Connect() error { @@ -235,7 +238,7 @@ func (t *Timestream) Connect() error { describeDatabaseInput := ×treamwrite.DescribeDatabaseInput{ DatabaseName: aws.String(t.DatabaseName), } - describeDatabaseOutput, err := svc.DescribeDatabase(describeDatabaseInput) + describeDatabaseOutput, err := svc.DescribeDatabase(context.Background(), describeDatabaseInput) if err != nil { t.Log.Errorf("Couldn't describe database '%s'. Check error, fix permissions, connectivity, create database.", t.DatabaseName) return err @@ -278,33 +281,45 @@ func (t *Timestream) Write(metrics []telegraf.Metric) error { func (t *Timestream) writeToTimestream(writeRecordsInput *timestreamwrite.WriteRecordsInput, resourceNotFoundRetry bool) error { t.Log.Debugf("Writing to Timestream: '%v' with ResourceNotFoundRetry: '%t'", writeRecordsInput, resourceNotFoundRetry) - _, err := t.svc.WriteRecords(writeRecordsInput) + _, err := t.svc.WriteRecords(context.Background(), writeRecordsInput) if err != nil { // Telegraf will retry ingesting the metrics if an error is returned from the plugin. // Therefore, return error only for retryable exceptions: ThrottlingException and 5xx exceptions. - if e, ok := err.(awserr.Error); ok { - switch e.Code() { - case timestreamwrite.ErrCodeResourceNotFoundException: - if resourceNotFoundRetry { - t.Log.Warnf("Failed to write to Timestream database '%s' table '%s'. Error: '%s'", - t.DatabaseName, *writeRecordsInput.TableName, e) - return t.createTableAndRetry(writeRecordsInput) - } - t.logWriteToTimestreamError(err, writeRecordsInput.TableName) - case timestreamwrite.ErrCodeThrottlingException: - return fmt.Errorf("unable to write to Timestream database '%s' table '%s'. Error: %s", - t.DatabaseName, *writeRecordsInput.TableName, err) - case timestreamwrite.ErrCodeInternalServerException: - return fmt.Errorf("unable to write to Timestream database '%s' table '%s'. Error: %s", - t.DatabaseName, *writeRecordsInput.TableName, err) - default: - t.logWriteToTimestreamError(err, writeRecordsInput.TableName) + var notFound *types.ResourceNotFoundException + if errors.As(err, ¬Found) { + if resourceNotFoundRetry { + t.Log.Warnf("Failed to write to Timestream database '%s' table '%s'. Error: '%s'", + t.DatabaseName, *writeRecordsInput.TableName, notFound) + return t.createTableAndRetry(writeRecordsInput) } - } else { + t.logWriteToTimestreamError(notFound, writeRecordsInput.TableName) + } + + var rejected *types.RejectedRecordsException + if errors.As(err, &rejected) { + t.logWriteToTimestreamError(err, writeRecordsInput.TableName) + return nil + } + + var throttling *types.ThrottlingException + if errors.As(err, &throttling) { + return fmt.Errorf("unable to write to Timestream database '%s' table '%s'. Error: %s", + t.DatabaseName, *writeRecordsInput.TableName, throttling) + } + + var internal *types.InternalServerException + if errors.As(err, &internal) { + return fmt.Errorf("unable to write to Timestream database '%s' table '%s'. Error: %s", + t.DatabaseName, *writeRecordsInput.TableName, internal) + } + + var operation *smithy.OperationError + if !errors.As(err, &operation) { // Retry other, non-aws errors. return fmt.Errorf("unable to write to Timestream database '%s' table '%s'. Error: %s", t.DatabaseName, *writeRecordsInput.TableName, err) } + t.logWriteToTimestreamError(err, writeRecordsInput.TableName) } return nil } @@ -334,27 +349,25 @@ func (t *Timestream) createTable(tableName *string) error { createTableInput := ×treamwrite.CreateTableInput{ DatabaseName: aws.String(t.DatabaseName), TableName: aws.String(*tableName), - RetentionProperties: ×treamwrite.RetentionProperties{ - MagneticStoreRetentionPeriodInDays: aws.Int64(t.CreateTableMagneticStoreRetentionPeriodInDays), - MemoryStoreRetentionPeriodInHours: aws.Int64(t.CreateTableMemoryStoreRetentionPeriodInHours), + RetentionProperties: &types.RetentionProperties{ + MagneticStoreRetentionPeriodInDays: t.CreateTableMagneticStoreRetentionPeriodInDays, + MemoryStoreRetentionPeriodInHours: t.CreateTableMemoryStoreRetentionPeriodInHours, }, } - var tags []*timestreamwrite.Tag + var tags []types.Tag for key, val := range t.CreateTableTags { - tags = append(tags, ×treamwrite.Tag{ + tags = append(tags, types.Tag{ Key: aws.String(key), Value: aws.String(val), }) } - createTableInput.SetTags(tags) + createTableInput.Tags = tags - _, err := t.svc.CreateTable(createTableInput) + _, err := t.svc.CreateTable(context.Background(), createTableInput) if err != nil { - if e, ok := err.(awserr.Error); ok { + if _, ok := err.(*types.ConflictException); ok { // if the table was created in the meantime, it's ok. - if e.Code() == timestreamwrite.ErrCodeConflictException { - return nil - } + return nil } return err } @@ -380,17 +393,17 @@ func (t *Timestream) TransformMetrics(metrics []telegraf.Metric) []*timestreamwr newWriteRecord := ×treamwrite.WriteRecordsInput{ DatabaseName: aws.String(t.DatabaseName), Records: records, - CommonAttributes: ×treamwrite.Record{ + CommonAttributes: &types.Record{ Dimensions: dimensions, Time: aws.String(timeValue), - TimeUnit: aws.String(timeUnit), + TimeUnit: timeUnit, }, } if t.MappingMode == MappingModeSingleTable { - newWriteRecord.SetTableName(t.SingleTableName) + newWriteRecord.TableName = &t.SingleTableName } if t.MappingMode == MappingModeMultiTable { - newWriteRecord.SetTableName(m.Name()) + newWriteRecord.TableName = aws.String(m.Name()) } writeRequests[id] = newWriteRecord @@ -440,17 +453,17 @@ func hashFromMetricTimeNameTagKeys(m telegraf.Metric) uint64 { return h.Sum64() } -func (t *Timestream) buildDimensions(point telegraf.Metric) []*timestreamwrite.Dimension { - var dimensions []*timestreamwrite.Dimension +func (t *Timestream) buildDimensions(point telegraf.Metric) []types.Dimension { + var dimensions []types.Dimension for tagName, tagValue := range point.Tags() { - dimension := ×treamwrite.Dimension{ + dimension := types.Dimension{ Name: aws.String(tagName), Value: aws.String(tagValue), } dimensions = append(dimensions, dimension) } if t.MappingMode == MappingModeSingleTable { - dimension := ×treamwrite.Dimension{ + dimension := types.Dimension{ Name: aws.String(t.SingleTableDimensionNameForTelegrafMeasurementName), Value: aws.String(point.Name()), } @@ -463,8 +476,8 @@ func (t *Timestream) buildDimensions(point telegraf.Metric) []*timestreamwrite.D // Tags and time are not included - common attributes are built separately. // Records with unsupported Metric Field type are skipped. // It returns an array of Timestream write records. -func (t *Timestream) buildWriteRecords(point telegraf.Metric) []*timestreamwrite.Record { - var records []*timestreamwrite.Record +func (t *Timestream) buildWriteRecords(point telegraf.Metric) []types.Record { + var records []types.Record for fieldName, fieldValue := range point.Fields() { stringFieldValue, stringFieldValueType, ok := convertValue(fieldValue) if !ok { @@ -473,9 +486,9 @@ func (t *Timestream) buildWriteRecords(point telegraf.Metric) []*timestreamwrite fieldName, reflect.TypeOf(fieldValue)) continue } - record := ×treamwrite.Record{ + record := types.Record{ MeasureName: aws.String(fieldName), - MeasureValueType: aws.String(stringFieldValueType), + MeasureValueType: stringFieldValueType, MeasureValue: aws.String(stringFieldValue), } records = append(records, record) @@ -486,13 +499,13 @@ func (t *Timestream) buildWriteRecords(point telegraf.Metric) []*timestreamwrite // partitionRecords splits the Timestream records into smaller slices of a max size // so that are under the limit for the Timestream API call. // It returns the array of array of records. -func partitionRecords(size int, records []*timestreamwrite.Record) [][]*timestreamwrite.Record { +func partitionRecords(size int, records []types.Record) [][]types.Record { numberOfPartitions := len(records) / size if len(records)%size != 0 { numberOfPartitions++ } - partitions := make([][]*timestreamwrite.Record, numberOfPartitions) + partitions := make([][]types.Record, numberOfPartitions) for i := 0; i < numberOfPartitions; i++ { start := size * i @@ -509,25 +522,19 @@ func partitionRecords(size int, records []*timestreamwrite.Record) [][]*timestre // getTimestreamTime produces Timestream TimeUnit and TimeValue with minimum possible granularity // while maintaining the same information. -func getTimestreamTime(time time.Time) (timeUnit string, timeValue string) { - const ( - TimeUnitS = "SECONDS" - TimeUnitMS = "MILLISECONDS" - TimeUnitUS = "MICROSECONDS" - TimeUnitNS = "NANOSECONDS" - ) - nanosTime := time.UnixNano() +func getTimestreamTime(t time.Time) (timeUnit types.TimeUnit, timeValue string) { + nanosTime := t.UnixNano() if nanosTime%1e9 == 0 { - timeUnit = TimeUnitS + timeUnit = types.TimeUnitSeconds timeValue = strconv.FormatInt(nanosTime/1e9, 10) } else if nanosTime%1e6 == 0 { - timeUnit = TimeUnitMS + timeUnit = types.TimeUnitMilliseconds timeValue = strconv.FormatInt(nanosTime/1e6, 10) } else if nanosTime%1e3 == 0 { - timeUnit = TimeUnitUS + timeUnit = types.TimeUnitMicroseconds timeValue = strconv.FormatInt(nanosTime/1e3, 10) } else { - timeUnit = TimeUnitNS + timeUnit = types.TimeUnitNanoseconds timeValue = strconv.FormatInt(nanosTime, 10) } return @@ -535,61 +542,55 @@ func getTimestreamTime(time time.Time) (timeUnit string, timeValue string) { // convertValue converts single Field value from Telegraf Metric and produces // value, valueType Timestream representation. -func convertValue(v interface{}) (value string, valueType string, ok bool) { - const ( - TypeBigInt = "BIGINT" - TypeDouble = "DOUBLE" - TypeBoolean = "BOOLEAN" - TypeVarchar = "VARCHAR" - ) +func convertValue(v interface{}) (value string, valueType types.MeasureValueType, ok bool) { ok = true switch t := v.(type) { case int: - valueType = TypeBigInt + valueType = types.MeasureValueTypeBigint value = strconv.FormatInt(int64(t), 10) case int8: - valueType = TypeBigInt + valueType = types.MeasureValueTypeBigint value = strconv.FormatInt(int64(t), 10) case int16: - valueType = TypeBigInt + valueType = types.MeasureValueTypeBigint value = strconv.FormatInt(int64(t), 10) case int32: - valueType = TypeBigInt + valueType = types.MeasureValueTypeBigint value = strconv.FormatInt(int64(t), 10) case int64: - valueType = TypeBigInt + valueType = types.MeasureValueTypeBigint value = strconv.FormatInt(t, 10) case uint: - valueType = TypeBigInt + valueType = types.MeasureValueTypeBigint value = strconv.FormatUint(uint64(t), 10) case uint8: - valueType = TypeBigInt + valueType = types.MeasureValueTypeBigint value = strconv.FormatUint(uint64(t), 10) case uint16: - valueType = TypeBigInt + valueType = types.MeasureValueTypeBigint value = strconv.FormatUint(uint64(t), 10) case uint32: - valueType = TypeBigInt + valueType = types.MeasureValueTypeBigint value = strconv.FormatUint(uint64(t), 10) case uint64: - valueType = TypeBigInt + valueType = types.MeasureValueTypeBigint value = strconv.FormatUint(t, 10) case float32: - valueType = TypeDouble + valueType = types.MeasureValueTypeDouble value = strconv.FormatFloat(float64(t), 'f', -1, 32) case float64: - valueType = TypeDouble + valueType = types.MeasureValueTypeDouble value = strconv.FormatFloat(t, 'f', -1, 64) case bool: - valueType = TypeBoolean + valueType = types.MeasureValueTypeBoolean if t { value = "true" } else { value = "false" } case string: - valueType = TypeVarchar + valueType = types.MeasureValueTypeVarchar value = t default: // Skip unsupported type. diff --git a/plugins/outputs/timestream/timestream_internal_test.go b/plugins/outputs/timestream/timestream_internal_test.go index 1f1194d70..d151c10d4 100644 --- a/plugins/outputs/timestream/timestream_internal_test.go +++ b/plugins/outputs/timestream/timestream_internal_test.go @@ -4,8 +4,8 @@ import ( "testing" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/timestreamwrite" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/timestreamwrite/types" "github.com/stretchr/testify/assert" ) @@ -19,57 +19,57 @@ func TestGetTimestreamTime(t *testing.T) { tOnlySeconds := time.Date(2020, time.November, 10, 23, 44, 20, 0, time.UTC) tUnitNanos, tValueNanos := getTimestreamTime(tWithNanos) - assertions.Equal("NANOSECONDS", tUnitNanos) + assertions.Equal(types.TimeUnitNanoseconds, tUnitNanos) assertions.Equal("1605051860000000123", tValueNanos) tUnitMicros, tValueMicros := getTimestreamTime(tWithMicros) - assertions.Equal("MICROSECONDS", tUnitMicros) + assertions.Equal(types.TimeUnitMicroseconds, tUnitMicros) assertions.Equal("1605051860000123", tValueMicros) tUnitMillis, tValueMillis := getTimestreamTime(tWithMillis) - assertions.Equal("MILLISECONDS", tUnitMillis) + assertions.Equal(types.TimeUnitMilliseconds, tUnitMillis) assertions.Equal("1605051860123", tValueMillis) tUnitSeconds, tValueSeconds := getTimestreamTime(tOnlySeconds) - assertions.Equal("SECONDS", tUnitSeconds) + assertions.Equal(types.TimeUnitSeconds, tUnitSeconds) assertions.Equal("1605051860", tValueSeconds) } func TestPartitionRecords(t *testing.T) { assertions := assert.New(t) - testDatum := timestreamwrite.Record{ + testDatum := types.Record{ MeasureName: aws.String("Foo"), - MeasureValueType: aws.String("DOUBLE"), + MeasureValueType: types.MeasureValueTypeDouble, MeasureValue: aws.String("123"), } - var zeroDatum []*timestreamwrite.Record - oneDatum := []*timestreamwrite.Record{&testDatum} - twoDatum := []*timestreamwrite.Record{&testDatum, &testDatum} - threeDatum := []*timestreamwrite.Record{&testDatum, &testDatum, &testDatum} + var zeroDatum []types.Record + oneDatum := []types.Record{testDatum} + twoDatum := []types.Record{testDatum, testDatum} + threeDatum := []types.Record{testDatum, testDatum, testDatum} - assertions.Equal([][]*timestreamwrite.Record{}, partitionRecords(2, zeroDatum)) - assertions.Equal([][]*timestreamwrite.Record{oneDatum}, partitionRecords(2, oneDatum)) - assertions.Equal([][]*timestreamwrite.Record{oneDatum}, partitionRecords(2, oneDatum)) - assertions.Equal([][]*timestreamwrite.Record{twoDatum}, partitionRecords(2, twoDatum)) - assertions.Equal([][]*timestreamwrite.Record{twoDatum, oneDatum}, partitionRecords(2, threeDatum)) + assertions.Equal([][]types.Record{}, partitionRecords(2, zeroDatum)) + assertions.Equal([][]types.Record{oneDatum}, partitionRecords(2, oneDatum)) + assertions.Equal([][]types.Record{oneDatum}, partitionRecords(2, oneDatum)) + assertions.Equal([][]types.Record{twoDatum}, partitionRecords(2, twoDatum)) + assertions.Equal([][]types.Record{twoDatum, oneDatum}, partitionRecords(2, threeDatum)) } func TestConvertValueSupported(t *testing.T) { intInputValues := []interface{}{-1, int8(-2), int16(-3), int32(-4), int64(-5)} intOutputValues := []string{"-1", "-2", "-3", "-4", "-5"} - intOutputValueTypes := []string{"BIGINT", "BIGINT", "BIGINT", "BIGINT", "BIGINT"} + intOutputValueTypes := []types.MeasureValueType{types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint} testConvertValueSupportedCases(t, intInputValues, intOutputValues, intOutputValueTypes) uintInputValues := []interface{}{uint(1), uint8(2), uint16(3), uint32(4), uint64(5)} uintOutputValues := []string{"1", "2", "3", "4", "5"} - uintOutputValueTypes := []string{"BIGINT", "BIGINT", "BIGINT", "BIGINT", "BIGINT"} + uintOutputValueTypes := []types.MeasureValueType{types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint} testConvertValueSupportedCases(t, uintInputValues, uintOutputValues, uintOutputValueTypes) otherInputValues := []interface{}{"foo", float32(22.123), 22.1234, true} otherOutputValues := []string{"foo", "22.123", "22.1234", "true"} - otherOutputValueTypes := []string{"VARCHAR", "DOUBLE", "DOUBLE", "BOOLEAN"} + otherOutputValueTypes := []types.MeasureValueType{types.MeasureValueTypeVarchar, types.MeasureValueTypeDouble, types.MeasureValueTypeDouble, types.MeasureValueTypeBoolean} testConvertValueSupportedCases(t, otherInputValues, otherOutputValues, otherOutputValueTypes) } @@ -80,7 +80,7 @@ func TestConvertValueUnsupported(t *testing.T) { } func testConvertValueSupportedCases(t *testing.T, - inputValues []interface{}, outputValues []string, outputValueTypes []string) { + inputValues []interface{}, outputValues []string, outputValueTypes []types.MeasureValueType) { assertions := assert.New(t) for i, inputValue := range inputValues { v, vt, ok := convertValue(inputValue) diff --git a/plugins/outputs/timestream/timestream_test.go b/plugins/outputs/timestream/timestream_test.go index 868e24d74..be61a06a1 100644 --- a/plugins/outputs/timestream/timestream_test.go +++ b/plugins/outputs/timestream/timestream_test.go @@ -1,6 +1,7 @@ -package timestream_test +package timestream import ( + "context" "fmt" "reflect" "sort" @@ -9,13 +10,11 @@ import ( "testing" "time" - "github.com/aws/aws-sdk-go/aws/awserr" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/timestreamwrite" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/timestreamwrite" + "github.com/aws/aws-sdk-go-v2/service/timestreamwrite/types" "github.com/influxdata/telegraf" internalaws "github.com/influxdata/telegraf/config/aws" - ts "github.com/influxdata/telegraf/plugins/outputs/timestream" "github.com/influxdata/telegraf/testutil" "github.com/stretchr/testify/assert" @@ -34,40 +33,37 @@ var time2 = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) const time2Epoch = "1257894000" -const timeUnit = "SECONDS" - const metricName1 = "metricName1" const metricName2 = "metricName2" -type mockTimestreamClient struct { -} +type mockTimestreamClient struct{} -func (m *mockTimestreamClient) CreateTable(*timestreamwrite.CreateTableInput) (*timestreamwrite.CreateTableOutput, error) { +func (m *mockTimestreamClient) CreateTable(context.Context, *timestreamwrite.CreateTableInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.CreateTableOutput, error) { return nil, nil } -func (m *mockTimestreamClient) WriteRecords(*timestreamwrite.WriteRecordsInput) (*timestreamwrite.WriteRecordsOutput, error) { +func (m *mockTimestreamClient) WriteRecords(context.Context, *timestreamwrite.WriteRecordsInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.WriteRecordsOutput, error) { return nil, nil } -func (m *mockTimestreamClient) DescribeDatabase(*timestreamwrite.DescribeDatabaseInput) (*timestreamwrite.DescribeDatabaseOutput, error) { +func (m *mockTimestreamClient) DescribeDatabase(context.Context, *timestreamwrite.DescribeDatabaseInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.DescribeDatabaseOutput, error) { return nil, fmt.Errorf("hello from DescribeDatabase") } func TestConnectValidatesConfigParameters(t *testing.T) { assertions := assert.New(t) - ts.WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (ts.WriteClient, error) { + WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (WriteClient, error) { return &mockTimestreamClient{}, nil } // checking base arguments - noDatabaseName := ts.Timestream{Log: testutil.Logger{}} + noDatabaseName := Timestream{Log: testutil.Logger{}} assertions.Contains(noDatabaseName.Connect().Error(), "DatabaseName") - noMappingMode := ts.Timestream{ + noMappingMode := Timestream{ DatabaseName: tsDbName, Log: testutil.Logger{}, } assertions.Contains(noMappingMode.Connect().Error(), "MappingMode") - incorrectMappingMode := ts.Timestream{ + incorrectMappingMode := Timestream{ DatabaseName: tsDbName, MappingMode: "foo", Log: testutil.Logger{}, @@ -75,24 +71,24 @@ func TestConnectValidatesConfigParameters(t *testing.T) { assertions.Contains(incorrectMappingMode.Connect().Error(), "single-table") // multi-table arguments - validMappingModeMultiTable := ts.Timestream{ + validMappingModeMultiTable := Timestream{ DatabaseName: tsDbName, - MappingMode: ts.MappingModeMultiTable, + MappingMode: MappingModeMultiTable, Log: testutil.Logger{}, } assertions.Nil(validMappingModeMultiTable.Connect()) - singleTableNameWithMultiTable := ts.Timestream{ + singleTableNameWithMultiTable := Timestream{ DatabaseName: tsDbName, - MappingMode: ts.MappingModeMultiTable, + MappingMode: MappingModeMultiTable, SingleTableName: testSingleTableName, Log: testutil.Logger{}, } assertions.Contains(singleTableNameWithMultiTable.Connect().Error(), "SingleTableName") - singleTableDimensionWithMultiTable := ts.Timestream{ + singleTableDimensionWithMultiTable := Timestream{ DatabaseName: tsDbName, - MappingMode: ts.MappingModeMultiTable, + MappingMode: MappingModeMultiTable, SingleTableDimensionNameForTelegrafMeasurementName: testSingleTableDim, Log: testutil.Logger{}, } @@ -100,25 +96,25 @@ func TestConnectValidatesConfigParameters(t *testing.T) { "SingleTableDimensionNameForTelegrafMeasurementName") // single-table arguments - noTableNameMappingModeSingleTable := ts.Timestream{ + noTableNameMappingModeSingleTable := Timestream{ DatabaseName: tsDbName, - MappingMode: ts.MappingModeSingleTable, + MappingMode: MappingModeSingleTable, Log: testutil.Logger{}, } assertions.Contains(noTableNameMappingModeSingleTable.Connect().Error(), "SingleTableName") - noDimensionNameMappingModeSingleTable := ts.Timestream{ + noDimensionNameMappingModeSingleTable := Timestream{ DatabaseName: tsDbName, - MappingMode: ts.MappingModeSingleTable, + MappingMode: MappingModeSingleTable, SingleTableName: testSingleTableName, Log: testutil.Logger{}, } assertions.Contains(noDimensionNameMappingModeSingleTable.Connect().Error(), "SingleTableDimensionNameForTelegrafMeasurementName") - validConfigurationMappingModeSingleTable := ts.Timestream{ + validConfigurationMappingModeSingleTable := Timestream{ DatabaseName: tsDbName, - MappingMode: ts.MappingModeSingleTable, + MappingMode: MappingModeSingleTable, SingleTableName: testSingleTableName, SingleTableDimensionNameForTelegrafMeasurementName: testSingleTableDim, Log: testutil.Logger{}, @@ -126,18 +122,18 @@ func TestConnectValidatesConfigParameters(t *testing.T) { assertions.Nil(validConfigurationMappingModeSingleTable.Connect()) // create table arguments - createTableNoMagneticRetention := ts.Timestream{ + createTableNoMagneticRetention := Timestream{ DatabaseName: tsDbName, - MappingMode: ts.MappingModeMultiTable, + MappingMode: MappingModeMultiTable, CreateTableIfNotExists: true, Log: testutil.Logger{}, } assertions.Contains(createTableNoMagneticRetention.Connect().Error(), "CreateTableMagneticStoreRetentionPeriodInDays") - createTableNoMemoryRetention := ts.Timestream{ + createTableNoMemoryRetention := Timestream{ DatabaseName: tsDbName, - MappingMode: ts.MappingModeMultiTable, + MappingMode: MappingModeMultiTable, CreateTableIfNotExists: true, CreateTableMagneticStoreRetentionPeriodInDays: 3, Log: testutil.Logger{}, @@ -145,9 +141,9 @@ func TestConnectValidatesConfigParameters(t *testing.T) { assertions.Contains(createTableNoMemoryRetention.Connect().Error(), "CreateTableMemoryStoreRetentionPeriodInHours") - createTableValid := ts.Timestream{ + createTableValid := Timestream{ DatabaseName: tsDbName, - MappingMode: ts.MappingModeMultiTable, + MappingMode: MappingModeMultiTable, CreateTableIfNotExists: true, CreateTableMagneticStoreRetentionPeriodInDays: 3, CreateTableMemoryStoreRetentionPeriodInHours: 3, @@ -156,9 +152,9 @@ func TestConnectValidatesConfigParameters(t *testing.T) { assertions.Nil(createTableValid.Connect()) // describe table on start arguments - describeTableInvoked := ts.Timestream{ + describeTableInvoked := Timestream{ DatabaseName: tsDbName, - MappingMode: ts.MappingModeMultiTable, + MappingMode: MappingModeMultiTable, DescribeDatabaseOnStart: true, Log: testutil.Logger{}, } @@ -169,31 +165,30 @@ type mockTimestreamErrorClient struct { ErrorToReturnOnWriteRecords error } -func (m *mockTimestreamErrorClient) CreateTable(*timestreamwrite.CreateTableInput) (*timestreamwrite.CreateTableOutput, error) { +func (m *mockTimestreamErrorClient) CreateTable(context.Context, *timestreamwrite.CreateTableInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.CreateTableOutput, error) { return nil, nil } -func (m *mockTimestreamErrorClient) WriteRecords(*timestreamwrite.WriteRecordsInput) (*timestreamwrite.WriteRecordsOutput, error) { +func (m *mockTimestreamErrorClient) WriteRecords(context.Context, *timestreamwrite.WriteRecordsInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.WriteRecordsOutput, error) { return nil, m.ErrorToReturnOnWriteRecords } -func (m *mockTimestreamErrorClient) DescribeDatabase(*timestreamwrite.DescribeDatabaseInput) (*timestreamwrite.DescribeDatabaseOutput, error) { +func (m *mockTimestreamErrorClient) DescribeDatabase(context.Context, *timestreamwrite.DescribeDatabaseInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.DescribeDatabaseOutput, error) { return nil, nil } func TestThrottlingErrorIsReturnedToTelegraf(t *testing.T) { assertions := assert.New(t) - - ts.WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (ts.WriteClient, error) { + WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (WriteClient, error) { return &mockTimestreamErrorClient{ - awserr.New(timestreamwrite.ErrCodeThrottlingException, - "Throttling Test", nil), + ErrorToReturnOnWriteRecords: &types.ThrottlingException{Message: aws.String("Throttling Test")}, }, nil } - plugin := ts.Timestream{ - MappingMode: ts.MappingModeMultiTable, + + plugin := Timestream{ + MappingMode: MappingModeMultiTable, DatabaseName: tsDbName, Log: testutil.Logger{}, } - plugin.Connect() + assertions.NoError(plugin.Connect()) input := testutil.MustMetric( metricName1, map[string]string{"tag1": "value1"}, @@ -209,19 +204,18 @@ func TestThrottlingErrorIsReturnedToTelegraf(t *testing.T) { func TestRejectedRecordsErrorResultsInMetricsBeingSkipped(t *testing.T) { assertions := assert.New(t) - - ts.WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (ts.WriteClient, error) { + WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (WriteClient, error) { return &mockTimestreamErrorClient{ - awserr.New(timestreamwrite.ErrCodeRejectedRecordsException, - "RejectedRecords Test", nil), + ErrorToReturnOnWriteRecords: &types.RejectedRecordsException{Message: aws.String("RejectedRecords Test")}, }, nil } - plugin := ts.Timestream{ - MappingMode: ts.MappingModeMultiTable, + + plugin := Timestream{ + MappingMode: MappingModeMultiTable, DatabaseName: tsDbName, Log: testutil.Logger{}, } - plugin.Connect() + assertions.NoError(plugin.Connect()) input := testutil.MustMetric( metricName1, map[string]string{"tag1": "value1"}, @@ -271,7 +265,7 @@ func TestTransformMetricsSkipEmptyMetric(t *testing.T) { dimensions: map[string]string{testSingleTableDim: metricName1}, measureValues: map[string]string{"value": "20"}, }) - comparisonTest(t, ts.MappingModeSingleTable, + comparisonTest(t, MappingModeSingleTable, []telegraf.Metric{input1, input2, input3}, []*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable}) @@ -287,7 +281,7 @@ func TestTransformMetricsSkipEmptyMetric(t *testing.T) { dimensions: map[string]string{}, measureValues: map[string]string{"value": "20"}, }) - comparisonTest(t, ts.MappingModeMultiTable, + comparisonTest(t, MappingModeMultiTable, []telegraf.Metric{input1, input2, input3}, []*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable}) } @@ -326,7 +320,7 @@ func TestTransformMetricsRequestsAboveLimitAreSplit(t *testing.T) { dimensions: map[string]string{"tag1": "value1", testSingleTableDim: metricName1}, measureValues: map[string]string{"value_supported" + strconv.Itoa(maxRecordsInWriteRecordsCall+1): "10"}, }) - comparisonTest(t, ts.MappingModeSingleTable, + comparisonTest(t, MappingModeSingleTable, inputs, []*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable}) @@ -342,7 +336,7 @@ func TestTransformMetricsRequestsAboveLimitAreSplit(t *testing.T) { dimensions: map[string]string{"tag1": "value1"}, measureValues: map[string]string{"value_supported" + strconv.Itoa(maxRecordsInWriteRecordsCall+1): "10"}, }) - comparisonTest(t, ts.MappingModeMultiTable, + comparisonTest(t, MappingModeMultiTable, inputs, []*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable}) } @@ -378,7 +372,7 @@ func TestTransformMetricsDifferentDimensionsSameTimestampsAreWrittenSeparate(t * measureValues: map[string]string{"value_supported3": "30"}, }) - comparisonTest(t, ts.MappingModeSingleTable, + comparisonTest(t, MappingModeSingleTable, []telegraf.Metric{input1, input2}, []*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable}) @@ -395,7 +389,7 @@ func TestTransformMetricsDifferentDimensionsSameTimestampsAreWrittenSeparate(t * measureValues: map[string]string{"value_supported3": "30"}, }) - comparisonTest(t, ts.MappingModeMultiTable, + comparisonTest(t, MappingModeMultiTable, []telegraf.Metric{input1, input2}, []*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable}) } @@ -431,7 +425,7 @@ func TestTransformMetricsSameDimensionsDifferentDimensionValuesAreWrittenSeparat measureValues: map[string]string{"value_supported1": "20"}, }) - comparisonTest(t, ts.MappingModeSingleTable, + comparisonTest(t, MappingModeSingleTable, []telegraf.Metric{input1, input2}, []*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable}) @@ -448,7 +442,7 @@ func TestTransformMetricsSameDimensionsDifferentDimensionValuesAreWrittenSeparat measureValues: map[string]string{"value_supported1": "20"}, }) - comparisonTest(t, ts.MappingModeMultiTable, + comparisonTest(t, MappingModeMultiTable, []telegraf.Metric{input1, input2}, []*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable}) } @@ -484,7 +478,7 @@ func TestTransformMetricsSameDimensionsDifferentTimestampsAreWrittenSeparate(t * measureValues: map[string]string{"value_supported3": "30"}, }) - comparisonTest(t, ts.MappingModeSingleTable, + comparisonTest(t, MappingModeSingleTable, []telegraf.Metric{input1, input2}, []*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable}) @@ -501,7 +495,7 @@ func TestTransformMetricsSameDimensionsDifferentTimestampsAreWrittenSeparate(t * measureValues: map[string]string{"value_supported3": "30"}, }) - comparisonTest(t, ts.MappingModeMultiTable, + comparisonTest(t, MappingModeMultiTable, []telegraf.Metric{input1, input2}, []*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable}) } @@ -531,7 +525,7 @@ func TestTransformMetricsSameDimensionsSameTimestampsAreWrittenTogether(t *testi measureValues: map[string]string{"value_supported1": "10", "value_supported2": "20", "value_supported3": "30"}, }) - comparisonTest(t, ts.MappingModeSingleTable, + comparisonTest(t, MappingModeSingleTable, []telegraf.Metric{input1, input2}, []*timestreamwrite.WriteRecordsInput{expectedResultSingleTable}) @@ -542,7 +536,7 @@ func TestTransformMetricsSameDimensionsSameTimestampsAreWrittenTogether(t *testi measureValues: map[string]string{"value_supported1": "10", "value_supported2": "20", "value_supported3": "30"}, }) - comparisonTest(t, ts.MappingModeMultiTable, + comparisonTest(t, MappingModeMultiTable, []telegraf.Metric{input1, input2}, []*timestreamwrite.WriteRecordsInput{expectedResultMultiTable}) } @@ -578,7 +572,7 @@ func TestTransformMetricsDifferentMetricsAreWrittenToDifferentTablesInMultiTable measureValues: map[string]string{"value_supported3": "30"}, }) - comparisonTest(t, ts.MappingModeSingleTable, + comparisonTest(t, MappingModeSingleTable, []telegraf.Metric{input1, input2}, []*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable}) @@ -595,7 +589,7 @@ func TestTransformMetricsDifferentMetricsAreWrittenToDifferentTablesInMultiTable measureValues: map[string]string{"value_supported3": "30"}, }) - comparisonTest(t, ts.MappingModeMultiTable, + comparisonTest(t, MappingModeMultiTable, []telegraf.Metric{input1, input2}, []*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable}) } @@ -616,7 +610,7 @@ func TestTransformMetricsUnsupportedFieldsAreSkipped(t *testing.T) { measureValues: map[string]string{"value_supported1": "10"}, }) - comparisonTest(t, ts.MappingModeSingleTable, + comparisonTest(t, MappingModeSingleTable, []telegraf.Metric{metricWithUnsupportedField}, []*timestreamwrite.WriteRecordsInput{expectedResultSingleTable}) @@ -627,7 +621,7 @@ func TestTransformMetricsUnsupportedFieldsAreSkipped(t *testing.T) { measureValues: map[string]string{"value_supported1": "10"}, }) - comparisonTest(t, ts.MappingModeMultiTable, + comparisonTest(t, MappingModeMultiTable, []telegraf.Metric{metricWithUnsupportedField}, []*timestreamwrite.WriteRecordsInput{expectedResultMultiTable}) } @@ -637,10 +631,10 @@ func comparisonTest(t *testing.T, telegrafMetrics []telegraf.Metric, timestreamRecords []*timestreamwrite.WriteRecordsInput, ) { - var plugin ts.Timestream + var plugin Timestream switch mappingMode { - case ts.MappingModeSingleTable: - plugin = ts.Timestream{ + case MappingModeSingleTable: + plugin = Timestream{ MappingMode: mappingMode, DatabaseName: tsDbName, @@ -648,8 +642,8 @@ func comparisonTest(t *testing.T, SingleTableDimensionNameForTelegrafMeasurementName: testSingleTableDim, Log: testutil.Logger{}, } - case ts.MappingModeMultiTable: - plugin = ts.Timestream{ + case MappingModeMultiTable: + plugin = Timestream{ MappingMode: mappingMode, DatabaseName: tsDbName, Log: testutil.Logger{}, @@ -710,20 +704,20 @@ type SimpleInput struct { } func buildExpectedRecords(i SimpleInput) *timestreamwrite.WriteRecordsInput { - var tsDimensions []*timestreamwrite.Dimension + var tsDimensions []types.Dimension for k, v := range i.dimensions { - tsDimensions = append(tsDimensions, ×treamwrite.Dimension{ + tsDimensions = append(tsDimensions, types.Dimension{ Name: aws.String(k), Value: aws.String(v), }) } - var tsRecords []*timestreamwrite.Record + var tsRecords []types.Record for k, v := range i.measureValues { - tsRecords = append(tsRecords, ×treamwrite.Record{ + tsRecords = append(tsRecords, types.Record{ MeasureName: aws.String(k), MeasureValue: aws.String(v), - MeasureValueType: aws.String("DOUBLE"), + MeasureValueType: types.MeasureValueTypeDouble, }) } @@ -731,10 +725,10 @@ func buildExpectedRecords(i SimpleInput) *timestreamwrite.WriteRecordsInput { DatabaseName: aws.String(tsDbName), TableName: aws.String(i.tableName), Records: tsRecords, - CommonAttributes: ×treamwrite.Record{ + CommonAttributes: &types.Record{ Dimensions: tsDimensions, Time: aws.String(i.t), - TimeUnit: aws.String(timeUnit), + TimeUnit: types.TimeUnitSeconds, }, }