Skip to content

Commit

Permalink
Merge pull request #1241 from mergenci/external-api-call-counter
Browse files Browse the repository at this point in the history
Count external API calls
  • Loading branch information
mergenci authored Mar 28, 2024
2 parents f87412a + 28c4ff2 commit aaad019
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 20 deletions.
13 changes: 7 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ go 1.21

require (
dario.cat/mergo v1.0.0
github.com/aws/aws-sdk-go-v2 v1.24.0
github.com/aws/aws-sdk-go v1.49.2
github.com/aws/aws-sdk-go-v2 v1.24.1
github.com/aws/aws-sdk-go-v2/config v1.26.1
github.com/aws/aws-sdk-go-v2/credentials v1.16.12
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10
Expand All @@ -17,7 +18,7 @@ require (
github.com/aws/smithy-go v1.19.0
github.com/crossplane/crossplane-runtime v1.16.0-rc.1.0.20240213134610-7fcb8c5cad6f
github.com/crossplane/crossplane-tools v0.0.0-20230925130601-628280f8bf79
github.com/crossplane/upjet v1.3.0-rc.0.0.20240314162745-2ef7077f6d16
github.com/crossplane/upjet v1.3.0-rc.0.0.20240328123350-4c67d8ebd380
github.com/go-ini/ini v1.46.0
github.com/google/go-cmp v0.6.0
github.com/hashicorp/terraform-json v0.18.0
Expand All @@ -44,11 +45,10 @@ require (
github.com/antchfx/htmlquery v1.2.4 // indirect
github.com/antchfx/xpath v1.2.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/aws/aws-sdk-go v1.49.2 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.7 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9 // indirect
github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.26.5 // indirect
Expand Down Expand Up @@ -140,6 +140,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.23.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect
github.com/aws/aws-sdk-go-v2/service/support v1.19.6 // indirect
github.com/aws/aws-sdk-go-v2/service/swf v1.20.5 // indirect
github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.23.6 // indirect
github.com/aws/aws-sdk-go-v2/service/transcribe v1.34.5 // indirect
Expand Down Expand Up @@ -277,6 +278,6 @@ require (

replace golang.org/x/exp => golang.org/x/exp v0.0.0-20231006140011-7918f672742d

replace github.com/hashicorp/terraform-provider-aws => github.com/upbound/terraform-provider-aws v0.0.0-20240129145938-c69f68a59916
replace github.com/hashicorp/terraform-provider-aws => github.com/upbound/terraform-provider-aws v0.0.0-20240328111213-f2f0fdd63866

replace github.com/hashicorp/terraform-plugin-log => github.com/gdavison/terraform-plugin-log v0.0.0-20230928191232-6c653d8ef8fb
22 changes: 12 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/aws/aws-sdk-go v1.49.2 h1:+4BEcm1nPCoDbVd+gg8cdxpa1qJfrvnddy12vpEVWjw=
github.com/aws/aws-sdk-go v1.49.2/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7AwGuk=
github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU=
github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo=
github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o=
Expand All @@ -40,10 +40,10 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6Jk
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.7 h1:FnLf60PtjXp8ZOzQfhJVsqF0OtYKQZWQfqOLshh8YXg=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.7/go.mod h1:tDVvl8hyU6E9B8TrnNrZQEVkQlB8hjJwcgpPhgtlnNg=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9/go.mod h1:Xjqy+Nyj7VDLBtCMkQYOw1QYfAEZCVLrfI0ezve8wd4=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 h1:N94sVhRACtXyVcjXxrwK1SKFIJrA9pOJ5yu2eSHnmls=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9/go.mod h1:hqamLz7g1/4EJP+GH5NBhcUMLjW+gKLQabgyz6/7WAU=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9 h1:ugD6qzjYtB7zM5PN/ZIeaAIyefPaD82G8+SJopgvUpw=
Expand Down Expand Up @@ -230,6 +230,8 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsY
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38=
github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg=
github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU=
github.com/aws/aws-sdk-go-v2/service/support v1.19.6 h1:ZD8OSo915ouOvw9JIjT0pccHwubdLoHmQYjAXIxFA0I=
github.com/aws/aws-sdk-go-v2/service/support v1.19.6/go.mod h1:Mzty8X8zv84IXyvPJ0nI1gZhurnKgrD46J6MRgJsGGk=
github.com/aws/aws-sdk-go-v2/service/swf v1.20.5 h1:9CU3kwRGpUReKubOsmxgG9LfaVpZ1PW/ON+5ZTKu5Gs=
github.com/aws/aws-sdk-go-v2/service/swf v1.20.5/go.mod h1:i01QTdCHqrntRqtNeYmxUSDCcmXERzFCePIcHDjASHE=
github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.23.6 h1:+7xZRneTlcraXL4+oN2kUlQX9ULh4aIxmcpUoR/faGA=
Expand Down Expand Up @@ -266,8 +268,8 @@ github.com/crossplane/crossplane-runtime v1.16.0-rc.1.0.20240213134610-7fcb8c5ca
github.com/crossplane/crossplane-runtime v1.16.0-rc.1.0.20240213134610-7fcb8c5cad6f/go.mod h1:kRcJjJQmBFrR2n/KhwL8wYS7xNfq3D8eK4JliEScOHI=
github.com/crossplane/crossplane-tools v0.0.0-20230925130601-628280f8bf79 h1:HigXs5tEQxWz0fcj8hzbU2UAZgEM7wPe0XRFOsrtF8Y=
github.com/crossplane/crossplane-tools v0.0.0-20230925130601-628280f8bf79/go.mod h1:+e4OaFlOcmr0JvINHl/yvEYBrZawzTgj6pQumOH1SS0=
github.com/crossplane/upjet v1.3.0-rc.0.0.20240314162745-2ef7077f6d16 h1:rga2kPfuFXAeodP2+Ni8svo38BrfsdaaCv6yejn/+2M=
github.com/crossplane/upjet v1.3.0-rc.0.0.20240314162745-2ef7077f6d16/go.mod h1:0bHLtnejZ9bDeyXuBb9MSOQLvKo3+aoTeUBO8N0dGSA=
github.com/crossplane/upjet v1.3.0-rc.0.0.20240328123350-4c67d8ebd380 h1:qNtHCHpg9+gVEOSvR+lbE/eVejQ7ERF7CXe6/jH+feI=
github.com/crossplane/upjet v1.3.0-rc.0.0.20240328123350-4c67d8ebd380/go.mod h1:0bHLtnejZ9bDeyXuBb9MSOQLvKo3+aoTeUBO8N0dGSA=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/dave/jennifer v1.4.1 h1:XyqG6cn5RQsTj3qlWQTKlRGAyrTcsk1kUmWdZBzRjDw=
Expand Down Expand Up @@ -552,8 +554,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tmccombs/hcl2json v0.3.3 h1:+DLNYqpWE0CsOQiEZu+OZm5ZBImake3wtITYxQ8uLFQ=
github.com/tmccombs/hcl2json v0.3.3/go.mod h1:Y2chtz2x9bAeRTvSibVRVgbLJhLJXKlUeIvjeVdnm4w=
github.com/upbound/terraform-provider-aws v0.0.0-20240129145938-c69f68a59916 h1:W3WAB6utkebXviDpnym5bWaQtqASXeudJ7bu7v9CJA4=
github.com/upbound/terraform-provider-aws v0.0.0-20240129145938-c69f68a59916/go.mod h1:Kb86v3lyFUggXmDTi53PPHLENdWUdD8t3IfjS7rFd+0=
github.com/upbound/terraform-provider-aws v0.0.0-20240328111213-f2f0fdd63866 h1:pBLZE97vtQmP21UGdr+CCWuNilZZYDidbGdBauve6tM=
github.com/upbound/terraform-provider-aws v0.0.0-20240328111213-f2f0fdd63866/go.mod h1:iJUX0JshS3o+xF8KZs+dcnR93xkK5dHr/FHh9jskl4Y=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
Expand Down
70 changes: 66 additions & 4 deletions internal/clients/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ package clients

import (
"context"
"reflect"
"unsafe"

"github.com/aws/aws-sdk-go-v2/aws"
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
awsrequest "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/smithy-go/middleware"
"github.com/crossplane/crossplane-runtime/pkg/resource"
"github.com/crossplane/upjet/pkg/metrics"
"github.com/crossplane/upjet/pkg/terraform"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/xpprovider"
Expand Down Expand Up @@ -111,6 +113,48 @@ func (m *metaOnlyPrimary) Meta() any {
return m.meta
}

// withExternalAPICallCounter configures an AWS SDK v2 stack (client)
// with an API call counter. AWS SDK v2 offers configuring
// "middlewares" to customize a request. Middlewares can be plugged
// into different steps of the stack. Middlewares can save and access
// metadata in the stack, such as ServiceID (EC2, IAM, etc.) and
// OperationName (DescribeVPCs, etc.). For documentation, see:
// https://aws.github.io/aws-sdk-go-v2/docs/middleware/
func withExternalAPICallCounter(stack *middleware.Stack) error {
externalAPICallCounterMiddleware := middleware.DeserializeMiddlewareFunc("externalAPICallCounter",
func(ctx context.Context, input middleware.DeserializeInput, next middleware.DeserializeHandler) (middleware.DeserializeOutput, middleware.Metadata, error) {
serviceID := awsmiddleware.GetServiceID(ctx)
operationName := awsmiddleware.GetOperationName(ctx)

// next.HandleDeserialize() calls the next middleware function
// in the stack, which in turn calls the next. Finally, the
// request is performed. Each middleware function receives the
// output from the middleware function it invoked, processes it,
// and returns its result to the middleware function that
// invoked itself.
output, metadata, err := next.HandleDeserialize(ctx, input)
if err == nil {
metrics.ExternalAPICalls.WithLabelValues(serviceID, operationName).Inc()
}
return output, metadata, err
},
)

// We register the call counter to the end of the deserialization
// step, so that we're right next to Transport handler
// (http.RoundTripper) in the stack (see
// https://aws.github.io/aws-sdk-go-v2/docs/middleware/). In this
// case, it's easy to distinguish API errors from connection
// errors, because only connection errors cause a non-nil error
// returned by next.HandleDeserialize() (see middleware
// implementation above). If we were to register the call counter
// to any other position (such as earlier stack steps (finalize,
// build, etc.) or even the beginning of deserialization step), we
// would have to implement a logic to distinguish between API
// errors and connection errors.
return stack.Deserialize.Add(externalAPICallCounterMiddleware, middleware.After)
}

// configureNoForkAWSClient populates the supplied *terraform.Setup with
// Terraform Plugin SDK style AWS client (Meta) and Terraform Plugin Framework
// style FrameworkProvider
Expand Down Expand Up @@ -146,8 +190,7 @@ func configureNoForkAWSClient(ctx context.Context, ps *terraform.Setup, config *
// only used for retrieving the ServicePackages from the singleton provider instance
p := config.TerraformProvider.Meta()
tfAwsConnsClient, diags := tfAwsConnsCfg.GetClient(ctx, &xpprovider.AWSClient{
// #nosec G103
ServicePackages: (*xpprovider.AWSClient)(unsafe.Pointer(reflect.ValueOf(p).Pointer())).ServicePackages,
ServicePackages: p.(*xpprovider.AWSClient).ServicePackages,
})
if diags.HasError() {
return errors.Errorf("cannot construct TF AWS Client from TF AWS Config, %v", diags)
Expand All @@ -162,5 +205,24 @@ func configureNoForkAWSClient(ctx context.Context, ps *terraform.Setup, config *
ps.Meta = tfAwsConnsClient
fwProvider := xpprovider.GetFrameworkProviderWithMeta(&metaOnlyPrimary{meta: tfAwsConnsClient})
ps.FrameworkProvider = fwProvider

// Register AWS SDK v1 call counter. Unlike AWS SDK v2, v1 doesn't
// store service ID (EC2, IAM, etc.) and operation name
// (DescribeVPCs, etc.) in request context. Therefore, it's not
// possible to implement this session handler's functionality with
// an http.RoundTripper. To learn how SDK v1 session handler phases
// map to SDK v2 middleware stack steps, see:
// https://aws.github.io/aws-sdk-go-v2/docs/migrating/#handler-phases
tfAwsConnsClient.Session.Handlers.Send.PushBack(func(r *awsrequest.Request) {
// In case of API errors (or no errors), r.Error is nil.
// In case of connection errors, r.Error is non-nil.
if r.Error == nil {
metrics.ExternalAPICalls.WithLabelValues(r.ClientInfo.ServiceID, r.Operation.Name).Inc()
}
})

// Register AWS SDK v2 call counter
tfAwsConnsClient.AppendAPIOptions(withExternalAPICallCounter)

return nil
}
1 change: 1 addition & 0 deletions internal/clients/provider_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const (
var userAgentV2 = config.WithAPIOptions([]func(*middleware.Stack) error{
awsmiddleware.AddUserAgentKeyValue("upbound-provider-aws", version.Version),
awsmiddleware.AddUserAgentKeyValue("crossplane-provider-aws", version.Version),
withExternalAPICallCounter,
})

func getRegion(obj runtime.Object) (string, error) {
Expand Down

0 comments on commit aaad019

Please sign in to comment.