Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor & Bug Fixes #38

Merged
merged 14 commits into from
Jan 15, 2020
Merged
Show file tree
Hide file tree
Changes from 9 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
35 changes: 29 additions & 6 deletions cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"time"

"github.com/aws/aws-sdk-go/aws/request"
"github.com/ticketmaster/aws-sdk-go-cache/cache"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
Expand Down Expand Up @@ -58,18 +59,20 @@ var serveCmd = &cobra.Command{
// argument validation
validate()
log.SetLevel(logLevel)
cacheCfg := cache.NewConfig(0 * time.Second)
eytan-avisror marked this conversation as resolved.
Show resolved Hide resolved

// prepare auth clients
auth := service.Authenticator{
ScalingGroupClient: newASGClient(region),
SQSClient: newSQSClient(region),
ELBv2Client: newELBv2Client(region),
ELBClient: newELBClient(region),
ELBv2Client: newELBv2Client(region, cacheCfg),
ELBClient: newELBClient(region, cacheCfg),
KubernetesClient: newKubernetesClient(localMode),
}

// prepare runtime context
context := service.ManagerContext{
CacheConfig: cacheCfg,
KubectlLocalPath: kubectlLocalPath,
QueueName: queueName,
DrainTimeoutSeconds: int64(drainTimeoutSeconds),
Expand Down Expand Up @@ -141,27 +144,47 @@ func newKubernetesClient(localMode string) *kubernetes.Clientset {
return kubernetes.NewForConfigOrDie(config)
}

func newELBv2Client(region string) elbv2iface.ELBV2API {
func newELBv2Client(region string, cacheCfg *cache.Config) elbv2iface.ELBV2API {
config := aws.NewConfig().WithRegion(region)
config = config.WithCredentialsChainVerboseErrors(true)
config = request.WithRetryer(config, log.NewRetryLogger(DefaultRetryer))
sess, err := session.NewSession(config)
if err != nil {
log.Fatalf("failed to create elbv2 client, %v", err)
}

cache.AddCaching(sess, cacheCfg)
cacheCfg.SetCacheTTL("elasticloadbalancing", "DescribeTargetHealth", 180*time.Second)
eytan-avisror marked this conversation as resolved.
Show resolved Hide resolved
cacheCfg.SetCacheTTL("elasticloadbalancing", "DescribeTargetGroups", 300*time.Second)
sess.Handlers.Complete.PushFront(func(r *request.Request) {
ctx := r.HTTPRequest.Context()
log.Debugf("cache hit => %v, service => %s.%s",
cache.IsCacheHit(ctx),
r.ClientInfo.ServiceName,
r.Operation.Name,
)
})
return elbv2.New(sess)
}

func newELBClient(region string) elbiface.ELBAPI {
func newELBClient(region string, cacheCfg *cache.Config) elbiface.ELBAPI {
config := aws.NewConfig().WithRegion(region)
config = config.WithCredentialsChainVerboseErrors(true)
config = request.WithRetryer(config, log.NewRetryLogger(DefaultRetryer))
sess, err := session.NewSession(config)
if err != nil {
log.Fatalf("failed to create elb client, %v", err)
}

cache.AddCaching(sess, cacheCfg)
cacheCfg.SetCacheTTL("elasticloadbalancing", "DescribeInstanceHealth", 180*time.Second)
cacheCfg.SetCacheTTL("elasticloadbalancing", "DescribeLoadBalancers", 300*time.Second)
davemasselink marked this conversation as resolved.
Show resolved Hide resolved
sess.Handlers.Complete.PushFront(func(r *request.Request) {
ctx := r.HTTPRequest.Context()
log.Debugf("cached => %v, service => %s.%s",
cache.IsCacheHit(ctx),
r.ClientInfo.ServiceName,
r.Operation.Name,
)
})
return elb.New(sess)
}

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ require (
github.com/sirupsen/logrus v1.4.2
github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.5 // indirect
github.com/ticketmaster/aws-sdk-go-cache v0.0.0-20200114200444-92e4b18a55fa
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad // indirect
golang.org/x/net v0.0.0-20190926025831-c00fd9afed17 // indirect
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
google.golang.org/appengine v1.6.4 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/karlseguin/expect.v1 v1.0.1 // indirect
k8s.io/api v0.0.0-20190927115716-5d581ce610b0
k8s.io/apimachinery v0.0.0-20190927035529-0104e33c351d
k8s.io/client-go v0.0.0-20190620085101-78d2af792bab
Expand Down
18 changes: 18 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/avast/retry-go v2.4.1+incompatible h1:WMHc0mwoz20UVmBYK89mUB/KFRlxO0p+s+sgpmJMviY=
github.com/avast/retry-go v2.4.1+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
github.com/aws/aws-sdk-go v1.16.35/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.25.0 h1:MyXUdCesJLBvSSKYcaKeeEwxNUwUpG6/uqVYeH/Zzfo=
github.com/aws/aws-sdk-go v1.25.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
Expand Down Expand Up @@ -39,6 +40,7 @@ github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
Expand All @@ -54,6 +56,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand All @@ -68,6 +72,7 @@ github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSN
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
Expand All @@ -92,6 +97,10 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karlseguin/ccache v2.0.2+incompatible h1:MpSlLlHgG3vPWTAIJsSYlyAQsHwfQ2HzgUlbJFh9Ufk=
github.com/karlseguin/ccache v2.0.2+incompatible/go.mod h1:CM9tNPzT6EdRh14+jiW8mEF9mkNZuuE51qmgGYUB93w=
github.com/karlseguin/expect v1.0.1 h1:z4wy4npwwHSWKjGWH85WNJO42VQhovxTCZDSzhjo8hY=
github.com/karlseguin/expect v1.0.1/go.mod h1:zNBxMY8P21owkeogJELCLeHIt+voOSduHYTFUbwRAV8=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -135,6 +144,7 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
Expand All @@ -143,9 +153,11 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/procfs v0.0.0-20180920065004-418d78d0b9a7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
Expand All @@ -172,7 +184,11 @@ github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRci
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/ticketmaster/aws-sdk-go-cache v0.0.0-20200114200444-92e4b18a55fa h1:1/TG5xJQOXV4PHSZ5dNr4jbuqZYblpIf9M/iURXIUBA=
github.com/ticketmaster/aws-sdk-go-cache v0.0.0-20200114200444-92e4b18a55fa/go.mod h1:tUllCtTyQfEniIDguMKypw6Y661aKvZVc0fG7SwbMEo=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
Expand Down Expand Up @@ -239,6 +255,8 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/karlseguin/expect.v1 v1.0.1 h1:9u0iUltnhFbJTHaSIH0EP+cuTU5rafIgmcsEsg2JQFw=
gopkg.in/karlseguin/expect.v1 v1.0.1/go.mod h1:uB7QIJBcclvYbwlUDkSCsGjAOMis3fP280LyhuDEf2I=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Expand Down
13 changes: 8 additions & 5 deletions pkg/service/autoscaling.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,18 @@ func sendHeartbeat(client autoscalingiface.AutoScalingAPI, event *LifecycleEvent
for {
iterationCount++
time.Sleep(time.Duration(recommendedInterval) * time.Second)
if event.eventCompleted {
return
}

if iterationCount >= maxIterations {
// hard limit in case event is not marked completed
log.Debugf("heartbeat extended over threshold, instance will be abandoned")
log.Warnf("heartbeat extended over threshold, instance will be abandoned")
event.SetEventCompleted(true)
}

if event.eventCompleted {
return
}
log.Infof("sending heartbeat for %v", instanceID)

log.Infof("sending heartbeat for %v (%v/%v)", instanceID, iterationCount, maxIterations)
err := extendLifecycleAction(client, *event)
if err != nil {
log.Errorf("failed to send heartbeat for event with instance %v: %v", instanceID, err)
Expand Down
52 changes: 35 additions & 17 deletions pkg/service/elb.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,57 @@
package service

import (
"context"
"errors"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/elb"
"github.com/aws/aws-sdk-go/service/elb/elbiface"

"github.com/keikoproj/lifecycle-manager/pkg/log"
)

func waitForDeregisterInstance(elbClient elbiface.ELBAPI, elbName, instanceID string) error {
func waitForDeregisterInstance(event *LifecycleEvent, elbClient elbiface.ELBAPI, elbName, instanceID string) error {
var (
MaxAttempts = 500
DelayIntervalSeconds int64 = 30
MaxAttempts = 500
found bool
)

waiterOpts := []request.WaiterOption{
request.WithWaiterMaxAttempts(MaxAttempts),
}
input := &elb.DescribeInstanceHealthInput{
LoadBalancerName: aws.String(elbName),
Instances: []*elb.Instance{
{
InstanceId: aws.String(instanceID),
},
},
}

err := elbClient.WaitUntilInstanceDeregisteredWithContext(context.Background(), input, waiterOpts...)
if err != nil {
return err
for i := 0; i < MaxAttempts; i++ {

if event.eventCompleted {
return errors.New("event finished execution during deregistration wait")
}

found = false
instances, err := elbClient.DescribeInstanceHealth(input)
if err != nil {
return err
}
for _, state := range instances.InstanceStates {
if aws.StringValue(state.InstanceId) == instanceID {
found = true
if aws.StringValue(state.State) == "OutOfService" {
return nil
}
break
}
}
if !found {
log.Debugf("instance %v not found in elb %v", instanceID, elbName)
return nil
}
log.Debugf("target %v is still deregistering from %v", instanceID, elbName)
eytan-avisror marked this conversation as resolved.
Show resolved Hide resolved
time.Sleep(time.Second * time.Duration(DelayIntervalSeconds))
}
return nil

err := errors.New("wait for target deregister timed out")
return err
}

func findInstanceInClassicBalancer(elbClient elbiface.ELBAPI, elbName, instanceID string) (bool, error) {
Expand Down Expand Up @@ -62,7 +81,6 @@ func deregisterInstance(elbClient elbiface.ELBAPI, elbName, instanceID string) e
},
}

log.Infof("deregistering %v from %v", instanceID, elbName)
_, err := elbClient.DeregisterInstancesFromLoadBalancer(input)
if err != nil {
return err
Expand Down
4 changes: 0 additions & 4 deletions pkg/service/elb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ type stubELB struct {
timesCalledDescribeLoadBalancers int
}

func (e *stubELB) WaitUntilInstanceDeregisteredWithContext(ctx context.Context, input *elb.DescribeInstanceHealthInput, req ...request.WaiterOption) error {
return nil
}

func (e *stubELB) DescribeInstanceHealth(input *elb.DescribeInstanceHealthInput) (*elb.DescribeInstanceHealthOutput, error) {
e.timesCalledDescribeInstanceHealth++
return &elb.DescribeInstanceHealthOutput{InstanceStates: e.instanceStates}, nil
Expand Down
56 changes: 36 additions & 20 deletions pkg/service/elbv2.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,57 @@
package service

import (
"context"
"errors"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/aws/aws-sdk-go/service/elbv2/elbv2iface"

"github.com/keikoproj/lifecycle-manager/pkg/log"
)

func waitForDeregisterTarget(elbClient elbv2iface.ELBV2API, arn, instanceID string, port int64) error {
func waitForDeregisterTarget(event *LifecycleEvent, elbClient elbv2iface.ELBV2API, arn, instanceID string, port int64) error {
var (
MaxAttempts = 500
DelayIntervalSeconds int64 = 30
MaxAttempts = 500
found bool
)

waiterOpts := []request.WaiterOption{
request.WithWaiterMaxAttempts(MaxAttempts),
}

input := &elbv2.DescribeTargetHealthInput{
TargetGroupArn: aws.String(arn),
Targets: []*elbv2.TargetDescription{
{
Id: aws.String(instanceID),
Port: aws.Int64(port),
},
},
}

err := elbClient.WaitUntilTargetDeregisteredWithContext(context.Background(), input, waiterOpts...)
if err != nil {
return err
for i := 0; i < MaxAttempts; i++ {

if event.eventCompleted {
return errors.New("event finished execution during deregistration wait")
}

found = false
targets, err := elbClient.DescribeTargetHealth(input)
if err != nil {
return err
}
for _, targetDescription := range targets.TargetHealthDescriptions {
if aws.StringValue(targetDescription.Target.Id) == instanceID && aws.Int64Value(targetDescription.Target.Port) == port {
found = true
if aws.StringValue(targetDescription.TargetHealth.State) == elbv2.TargetHealthStateEnumUnused {
return nil
}
break
}
}
if !found {
log.Debugf("target %v not found in target group %v", instanceID, arn)
return nil
}
log.Debugf("target %v is still deregistering from %v", instanceID, arn)
eytan-avisror marked this conversation as resolved.
Show resolved Hide resolved
time.Sleep(time.Second * time.Duration(DelayIntervalSeconds))
}
return nil

err := errors.New("wait for target deregister timed out")
return err
}

func findInstanceInTargetGroup(elbClient elbv2iface.ELBV2API, arn, instanceID string) (bool, int64, error) {
Expand All @@ -44,7 +61,7 @@ func findInstanceInTargetGroup(elbClient elbv2iface.ELBV2API, arn, instanceID st

target, err := elbClient.DescribeTargetHealth(input)
if err != nil {
log.Infof("failed finding instance %v in target group %v: %v", instanceID, arn, err.Error())
log.Errorf("failed finding instance %v in target group %v: %v", instanceID, arn, err.Error())
return false, 0, err
}
for _, desc := range target.TargetHealthDescriptions {
Expand All @@ -67,7 +84,6 @@ func deregisterTarget(elbClient elbv2iface.ELBV2API, arn, instanceID string, por
TargetGroupArn: aws.String(arn),
}

log.Infof("deregistering %v from %v", instanceID, arn)
_, err := elbClient.DeregisterTargets(input)
if err != nil {
return err
Expand Down
Loading