Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions controllers/providers/aws/autoscaling.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
22 changes: 0 additions & 22 deletions controllers/providers/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
21 changes: 1 addition & 20 deletions controllers/providers/aws/ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
14 changes: 1 addition & 13 deletions controllers/providers/aws/eks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
17 changes: 2 additions & 15 deletions controllers/providers/aws/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
72 changes: 72 additions & 0 deletions controllers/providers/aws/retry_test.go
Original file line number Diff line number Diff line change
@@ -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))
}
13 changes: 1 addition & 12 deletions controllers/providers/aws/ssm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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)
}

Expand Down
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
10 changes: 0 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down Expand Up @@ -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=
Expand Down Expand Up @@ -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=
Expand Down
19 changes: 5 additions & 14 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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")
Expand Down
Loading