diff --git a/controllers/providers/aws/autoscaling.go b/controllers/providers/aws/autoscaling.go index 71c74c4e..5af50401 100644 --- a/controllers/providers/aws/autoscaling.go +++ b/controllers/providers/aws/autoscaling.go @@ -23,32 +23,17 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface" - "github.com/keikoproj/aws-sdk-go-cache/cache" "github.com/keikoproj/instance-manager/controllers/common" ) // GetAwsAsgClient returns an ASG client -func GetAwsAsgClient(region string, cacheCfg *cache.Config, maxRetries int, collector *common.MetricsCollector) autoscalingiface.AutoScalingAPI { +func GetAwsAsgClient(region string, maxRetries int, collector *common.MetricsCollector) autoscalingiface.AutoScalingAPI { config := aws.NewConfig().WithRegion(region).WithCredentialsChainVerboseErrors(true) config = request.WithRetryer(config, NewRetryLogger(maxRetries, collector)) sess, err := session.NewSession(config) if err != nil { panic(err) } - - cache.AddCaching(sess, cacheCfg) - cacheCfg.SetCacheTTL("autoscaling", "DescribeAutoScalingGroups", DescribeAutoScalingGroupsTTL) - cacheCfg.SetCacheTTL("autoscaling", "DescribeWarmPool", DescribeWarmPoolTTL) - cacheCfg.SetCacheTTL("autoscaling", "DescribeLaunchConfigurations", DescribeLaunchConfigurationsTTL) - cacheCfg.SetCacheTTL("autoscaling", "DescribeLifecycleHooks", DescribeLifecycleHooksTTL) - sess.Handlers.Complete.PushFront(func(r *request.Request) { - ctx := r.HTTPRequest.Context() - log.V(1).Info("AWS API call", - "cacheHit", cache.IsCacheHit(ctx), - "service", r.ClientInfo.ServiceName, - "operation", r.Operation.Name, - ) - }) return autoscaling.New(sess) } diff --git a/controllers/providers/aws/aws.go b/controllers/providers/aws/aws.go index 7b305c83..06e72506 100644 --- a/controllers/providers/aws/aws.go +++ b/controllers/providers/aws/aws.go @@ -40,28 +40,6 @@ var ( ) const ( - CacheDefaultTTL time.Duration = 0 * time.Second - DescribeWarmPoolTTL time.Duration = 60 * time.Second - DescribeAutoScalingGroupsTTL time.Duration = 60 * time.Second - DescribeLaunchConfigurationsTTL time.Duration = 60 * time.Second - ListAttachedRolePoliciesTTL time.Duration = 60 * time.Second - GetRoleTTL time.Duration = 60 * time.Second - GetInstanceProfileTTL time.Duration = 60 * time.Second - DescribeNodegroupTTL time.Duration = 60 * time.Second - DescribeLifecycleHooksTTL time.Duration = 180 * time.Second - DescribeClusterTTL time.Duration = 180 * time.Second - DescribeSecurityGroupsTTL time.Duration = 180 * time.Second - DescribeSubnetsTTL time.Duration = 180 * time.Second - DescribeLaunchTemplatesTTL time.Duration = 60 * time.Second - DescribeLaunchTemplateVersionsTTL time.Duration = 60 * time.Second - DescribeInstanceTypesTTL time.Duration = 24 * time.Hour - DescribeInstanceTypeOfferingTTL time.Duration = 1 * time.Hour - GetParameterTTL time.Duration = 1 * time.Hour - - CacheBackgroundPruningInterval time.Duration = 1 * time.Hour - CacheMaxItems int64 = 250 - CacheItemsToPrune uint32 = 25 - LaunchTemplateStrategyCapacityOptimized = "capacity-optimized" LaunchTemplateStrategyLowestPrice = "lowest-price" LaunchTemplateAllocationStrategy = "prioritized" diff --git a/controllers/providers/aws/ec2.go b/controllers/providers/aws/ec2.go index 1de09537..d258ef82 100644 --- a/controllers/providers/aws/ec2.go +++ b/controllers/providers/aws/ec2.go @@ -24,36 +24,17 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2/ec2iface" - "github.com/keikoproj/aws-sdk-go-cache/cache" "github.com/keikoproj/instance-manager/controllers/common" ) // GetAwsEc2Client returns an EC2 client -func GetAwsEc2Client(region string, cacheCfg *cache.Config, maxRetries int, collector *common.MetricsCollector) ec2iface.EC2API { +func GetAwsEc2Client(region string, maxRetries int, collector *common.MetricsCollector) ec2iface.EC2API { config := aws.NewConfig().WithRegion(region).WithCredentialsChainVerboseErrors(true) config = request.WithRetryer(config, NewRetryLogger(maxRetries, collector)) sess, err := session.NewSession(config) if err != nil { panic(err) } - - cache.AddCaching(sess, cacheCfg) - cacheCfg.SetCacheTTL("ec2", "DescribeSecurityGroups", DescribeSecurityGroupsTTL) - cacheCfg.SetCacheTTL("ec2", "DescribeSubnets", DescribeSubnetsTTL) - cacheCfg.SetCacheTTL("ec2", "DescribeInstanceTypes", DescribeInstanceTypesTTL) - cacheCfg.SetExcludeFlushing("ec2", "DescribeInstanceTypes", true) - cacheCfg.SetCacheTTL("ec2", "DescribeInstanceTypeOfferings", DescribeInstanceTypeOfferingTTL) - cacheCfg.SetExcludeFlushing("ec2", "DescribeInstanceTypeOfferings", true) - cacheCfg.SetCacheTTL("ec2", "DescribeLaunchTemplates", DescribeLaunchTemplatesTTL) - cacheCfg.SetCacheTTL("ec2", "DescribeLaunchTemplateVersions", DescribeLaunchTemplateVersionsTTL) - sess.Handlers.Complete.PushFront(func(r *request.Request) { - ctx := r.HTTPRequest.Context() - log.V(1).Info("AWS API call", - "cacheHit", cache.IsCacheHit(ctx), - "service", r.ClientInfo.ServiceName, - "operation", r.Operation.Name, - ) - }) return ec2.New(sess) } diff --git a/controllers/providers/aws/eks.go b/controllers/providers/aws/eks.go index 47ae87e2..8b6de6a0 100644 --- a/controllers/providers/aws/eks.go +++ b/controllers/providers/aws/eks.go @@ -24,29 +24,17 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/eks" "github.com/aws/aws-sdk-go/service/eks/eksiface" - "github.com/keikoproj/aws-sdk-go-cache/cache" "github.com/keikoproj/instance-manager/controllers/common" ) // GetAwsEksClient returns an EKS client -func GetAwsEksClient(region string, cacheCfg *cache.Config, maxRetries int, collector *common.MetricsCollector) eksiface.EKSAPI { +func GetAwsEksClient(region string, maxRetries int, collector *common.MetricsCollector) eksiface.EKSAPI { config := aws.NewConfig().WithRegion(region).WithCredentialsChainVerboseErrors(true) config = request.WithRetryer(config, NewRetryLogger(maxRetries, collector)) sess, err := session.NewSession(config) if err != nil { panic(err) } - cache.AddCaching(sess, cacheCfg) - cacheCfg.SetCacheTTL("eks", "DescribeCluster", DescribeClusterTTL) - cacheCfg.SetCacheTTL("eks", "DescribeNodegroup", DescribeNodegroupTTL) - sess.Handlers.Complete.PushFront(func(r *request.Request) { - ctx := r.HTTPRequest.Context() - log.V(1).Info("AWS API call", - "cacheHit", cache.IsCacheHit(ctx), - "service", r.ClientInfo.ServiceName, - "operation", r.Operation.Name, - ) - }) return eks.New(sess, config) } diff --git a/controllers/providers/aws/iam.go b/controllers/providers/aws/iam.go index c55f75b8..e310cacf 100644 --- a/controllers/providers/aws/iam.go +++ b/controllers/providers/aws/iam.go @@ -24,31 +24,18 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/iam" "github.com/aws/aws-sdk-go/service/iam/iamiface" - "github.com/keikoproj/aws-sdk-go-cache/cache" "github.com/keikoproj/instance-manager/controllers/common" "github.com/pkg/errors" ) -// GetAwsIAMClient returns an IAM client -func GetAwsIamClient(region string, cacheCfg *cache.Config, maxRetries int, collector *common.MetricsCollector) iamiface.IAMAPI { +// GetAwsIamClient returns an IAM client +func GetAwsIamClient(region string, maxRetries int, collector *common.MetricsCollector) iamiface.IAMAPI { config := aws.NewConfig().WithRegion(region).WithCredentialsChainVerboseErrors(true) config = request.WithRetryer(config, NewRetryLogger(maxRetries, collector)) sess, err := session.NewSession(config) if err != nil { panic(err) } - cache.AddCaching(sess, cacheCfg) - cacheCfg.SetCacheTTL("iam", "GetInstanceProfile", GetInstanceProfileTTL) - cacheCfg.SetCacheTTL("iam", "GetRole", GetRoleTTL) - cacheCfg.SetCacheTTL("iam", "ListAttachedRolePolicies", ListAttachedRolePoliciesTTL) - sess.Handlers.Complete.PushFront(func(r *request.Request) { - ctx := r.HTTPRequest.Context() - log.V(1).Info("AWS API call", - "cacheHit", cache.IsCacheHit(ctx), - "service", r.ClientInfo.ServiceName, - "operation", r.Operation.Name, - ) - }) return iam.New(sess, config) } diff --git a/controllers/providers/aws/retry_test.go b/controllers/providers/aws/retry_test.go new file mode 100644 index 00000000..4fa27a24 --- /dev/null +++ b/controllers/providers/aws/retry_test.go @@ -0,0 +1,72 @@ +package aws + +import ( + "fmt" + "net/http" + "testing" + + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/keikoproj/instance-manager/controllers/common" + "github.com/onsi/gomega" +) + +func TestNewRetryLogger(t *testing.T) { + g := gomega.NewGomegaWithT(t) + + collector := common.NewMetricsCollector() + logger := NewRetryLogger(5, collector) + + g.Expect(logger).ToNot(gomega.BeNil()) + g.Expect(logger.NumMaxRetries).To(gomega.Equal(5)) + g.Expect(logger.metricsCollector).To(gomega.Equal(collector)) +} + +func TestRetryLoggerDefaultRetries(t *testing.T) { + g := gomega.NewGomegaWithT(t) + + collector := common.NewMetricsCollector() + logger := NewRetryLogger(12, collector) + + g.Expect(logger.NumMaxRetries).To(gomega.Equal(12)) +} + +func TestRetryRulesThrottleIncrementsMetric(t *testing.T) { + g := gomega.NewGomegaWithT(t) + + collector := common.NewMetricsCollector() + logger := NewRetryLogger(3, collector) + + // Build a minimal request that looks throttled (HTTP 429) + req := &request.Request{ + ClientInfo: metadata.ClientInfo{ServiceName: "ec2"}, + Operation: &request.Operation{Name: "DescribeInstances"}, + HTTPResponse: &http.Response{ + StatusCode: 429, + Status: fmt.Sprintf("%d %s", 429, "Too Many Requests"), + }, + } + + // RetryRules should not panic and should return a duration + duration := logger.RetryRules(req) + g.Expect(duration).To(gomega.BeNumerically(">=", 0)) +} + +func TestRetryRulesNoOperationNoPanic(t *testing.T) { + g := gomega.NewGomegaWithT(t) + + collector := common.NewMetricsCollector() + logger := NewRetryLogger(3, collector) + + // Request with no Operation set — should not panic + req := &request.Request{ + ClientInfo: metadata.ClientInfo{ServiceName: "autoscaling"}, + HTTPResponse: &http.Response{ + StatusCode: 500, + Status: "500 Internal Server Error", + }, + } + + duration := logger.RetryRules(req) + g.Expect(duration).To(gomega.BeNumerically(">=", 0)) +} diff --git a/controllers/providers/aws/ssm.go b/controllers/providers/aws/ssm.go index 42f44fbf..0397a7f6 100644 --- a/controllers/providers/aws/ssm.go +++ b/controllers/providers/aws/ssm.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ssm" "github.com/aws/aws-sdk-go/service/ssm/ssmiface" - "github.com/keikoproj/aws-sdk-go-cache/cache" "github.com/keikoproj/instance-manager/controllers/common" ) @@ -44,23 +43,13 @@ var ( } ) -func GetAwsSsmClient(region string, cacheCfg *cache.Config, maxRetries int, collector *common.MetricsCollector) ssmiface.SSMAPI { +func GetAwsSsmClient(region string, maxRetries int, collector *common.MetricsCollector) ssmiface.SSMAPI { config := aws.NewConfig().WithRegion(region).WithCredentialsChainVerboseErrors(true) config = request.WithRetryer(config, NewRetryLogger(maxRetries, collector)) sess, err := session.NewSession(config) if err != nil { panic(err) } - cache.AddCaching(sess, cacheCfg) - cacheCfg.SetCacheTTL("ssm", "GetParameter", GetParameterTTL) - sess.Handlers.Complete.PushFront(func(r *request.Request) { - ctx := r.HTTPRequest.Context() - log.V(1).Info("AWS API call", - "cacheHit", cache.IsCacheHit(ctx), - "service", r.ClientInfo.ServiceName, - "operation", r.Operation.Name, - ) - }) return ssm.New(sess) } diff --git a/go.mod b/go.mod index e23996fc..de062638 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,6 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/go-logr/logr v1.4.3 github.com/keikoproj/aws-auth v0.7.0 - github.com/keikoproj/aws-sdk-go-cache v0.1.1 github.com/onsi/gomega v1.39.1 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.23.2 @@ -43,7 +42,6 @@ require ( github.com/go-openapi/swag v0.23.1 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.2.5 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.6.9 // indirect github.com/google/go-cmp v0.7.0 // indirect @@ -55,7 +53,6 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/karlseguin/ccache/v2 v2.0.8 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect diff --git a/go.sum b/go.sum index efa3fae6..02bcc701 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,6 @@ github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1 github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= -github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= @@ -90,14 +88,8 @@ github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2E github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/karlseguin/ccache/v2 v2.0.8 h1:lT38cE//uyf6KcFok0rlgXtGFBWxkI6h/qg4tbFyDnA= -github.com/karlseguin/ccache/v2 v2.0.8/go.mod h1:2BDThcfQMf/c0jnZowt16eW405XIqZPavt+HoYEtcxQ= -github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003 h1:vJ0Snvo+SLMY72r5J4sEfkuE7AFbixEP2qRbEcum/wA= -github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003/go.mod h1:zNBxMY8P21owkeogJELCLeHIt+voOSduHYTFUbwRAV8= github.com/keikoproj/aws-auth v0.7.0 h1:0ezPUJcgCjh1lJtThPaiA5/1VXDSlKvPSbGwiGgTwxM= github.com/keikoproj/aws-auth v0.7.0/go.mod h1:oh0871jM5nHwYH6pkPQje46yt1mA5hHpUC0Yr/4bfdk= -github.com/keikoproj/aws-sdk-go-cache v0.1.1 h1:APgoX+e9j7krDqc4MFUIsvLKD12v4gr6r3ypRHiwHN0= -github.com/keikoproj/aws-sdk-go-cache v0.1.1/go.mod h1:Yso98U+nATeJdnAr2H4Ji9gNqOpvW2NsPQ1TjjkIIYo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= @@ -159,8 +151,6 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ= -github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/main.go b/main.go index 7fe6cf15..52280045 100644 --- a/main.go +++ b/main.go @@ -22,7 +22,6 @@ import ( stdruntime "runtime" "sync" - "github.com/keikoproj/aws-sdk-go-cache/cache" instancemgrv1alpha1 "github.com/keikoproj/instance-manager/api/instancemgr/v1alpha1" "github.com/keikoproj/instance-manager/controllers" "github.com/keikoproj/instance-manager/controllers/common" @@ -125,24 +124,16 @@ func main() { os.Exit(1) } - cacheCfg := cache.NewConfig(aws.CacheDefaultTTL, aws.CacheBackgroundPruningInterval, aws.CacheMaxItems, aws.CacheItemsToPrune) - cacheCollector := cacheCfg.NewCacheCollector("instance_manager") controllerCollector := common.NewMetricsCollector() awsWorker := aws.AwsWorker{ - Ec2Client: aws.GetAwsEc2Client(awsRegion, cacheCfg, maxAPIRetries, controllerCollector), - IamClient: aws.GetAwsIamClient(awsRegion, cacheCfg, maxAPIRetries, controllerCollector), - AsgClient: aws.GetAwsAsgClient(awsRegion, cacheCfg, maxAPIRetries, controllerCollector), - EksClient: aws.GetAwsEksClient(awsRegion, cacheCfg, maxAPIRetries, controllerCollector), - SsmClient: aws.GetAwsSsmClient(awsRegion, cacheCfg, maxAPIRetries, controllerCollector), + Ec2Client: aws.GetAwsEc2Client(awsRegion, maxAPIRetries, controllerCollector), + IamClient: aws.GetAwsIamClient(awsRegion, maxAPIRetries, controllerCollector), + AsgClient: aws.GetAwsAsgClient(awsRegion, maxAPIRetries, controllerCollector), + EksClient: aws.GetAwsEksClient(awsRegion, maxAPIRetries, controllerCollector), + SsmClient: aws.GetAwsSsmClient(awsRegion, maxAPIRetries, controllerCollector), Ec2Metadata: metadata, } - if err := prometheus.Register(cacheCollector); err != nil { - if _, ok := err.(prometheus.AlreadyRegisteredError); !ok { - setupLog.Error(err, "failed to register cache metrics collector") - os.Exit(1) - } - } if err := prometheus.Register(controllerCollector); err != nil { if _, ok := err.(prometheus.AlreadyRegisteredError); !ok { setupLog.Error(err, "failed to register controller metrics collector")