From c0f1020004894875923b46b922f683e6bd65afc9 Mon Sep 17 00:00:00 2001 From: Samuel Lang Date: Thu, 18 Nov 2021 12:32:56 +0100 Subject: [PATCH] adding config option for Healthy threshold Healthy threshold: The number of consecutive health checks successes required before considering an unhealthy target healthy This configuration is required since the default of "5" time the interval which is minimum of sum of 30s that is too long delay in our configurations Signed-off-by: Samuel Lang --- aws/adapter.go | 11 +++++++++++ aws/adapter_test.go | 8 ++++++++ aws/cf.go | 1 + aws/cf_template.go | 1 + aws/cf_template_test.go | 11 +++++++++++ controller.go | 8 ++++++++ 6 files changed, 40 insertions(+) diff --git a/aws/adapter.go b/aws/adapter.go index 80de0c18..7d784aa8 100644 --- a/aws/adapter.go +++ b/aws/adapter.go @@ -43,6 +43,7 @@ type Adapter struct { healthCheckPort uint healthCheckInterval time.Duration healthCheckTimeout time.Duration + healthyThresholdCount uint targetPort uint albHTTPTargetPort uint nlbHTTPTargetPort uint @@ -91,6 +92,7 @@ const ( DefaultTargetPort = 9999 DefaultHealthCheckInterval = 10 * time.Second DefaultHealthCheckTimeout = 5 * time.Second + DefaultHealthyThresholdCount = 5 DefaultCertificateUpdateInterval = 30 * time.Minute DefaultCreationTimeout = 5 * time.Minute DefaultIdleConnectionTimeout = 1 * time.Minute @@ -248,6 +250,13 @@ func (a *Adapter) WithHealthCheckPort(port uint) *Adapter { return a } +// WithHealthyThresholdCount returns the receiver adapter after changing the healthy threshold count that will be used by +// the resources created by the adapter +func (a *Adapter) WithHealthyThresholdCount(count uint) *Adapter { + a.healthyThresholdCount = count + return a +} + // WithTargetPort returns the receiver adapter after changing the target port that will be used by // the resources created by the adapter func (a *Adapter) WithTargetPort(port uint) *Adapter { @@ -611,6 +620,7 @@ func (a *Adapter) CreateStack(certificateARNs []string, scheme, securityGroup, o interval: a.healthCheckInterval, timeout: a.healthCheckTimeout, }, + healthyThresholdCount: a.healthyThresholdCount, targetPort: a.targetPort, targetHTTPS: a.targetHTTPS, httpDisabled: a.httpDisabled(loadBalancerType), @@ -663,6 +673,7 @@ func (a *Adapter) UpdateStack(stackName string, certificateARNs map[string]time. interval: a.healthCheckInterval, timeout: a.healthCheckTimeout, }, + healthyThresholdCount: a.healthyThresholdCount, targetPort: a.targetPort, targetHTTPS: a.targetHTTPS, httpDisabled: a.httpDisabled(loadBalancerType), diff --git a/aws/adapter_test.go b/aws/adapter_test.go index db2c47ee..27d37228 100644 --- a/aws/adapter_test.go +++ b/aws/adapter_test.go @@ -927,3 +927,11 @@ func TestWithTargetHTTPS(t *testing.T) { require.Equal(t, true, b.targetHTTPS) }) } + +func TestWithHealthyThresholdCount(t *testing.T) { + t.Run("WithHealthyThresholdCount sets the healthyThresholdCount property", func(t *testing.T) { + a := Adapter{} + b := a.WithHealthyThresholdCount(2) + require.Equal(t, uint(2), b.healthyThresholdCount) + }) +} diff --git a/aws/cf.go b/aws/cf.go index b27ce1ef..217c27e8 100644 --- a/aws/cf.go +++ b/aws/cf.go @@ -137,6 +137,7 @@ type stackSpec struct { clusterID string vpcID string healthCheck *healthCheck + healthyThresholdCount uint targetPort uint targetHTTPS bool httpDisabled bool diff --git a/aws/cf_template.go b/aws/cf_template.go index b1adbf7b..9e4a107f 100644 --- a/aws/cf_template.go +++ b/aws/cf_template.go @@ -465,6 +465,7 @@ func newTargetGroup(spec *stackSpec, targetPortParameter string) *cloudformation HealthCheckPath: cloudformation.Ref(parameterTargetGroupHealthCheckPathParameter).String(), HealthCheckPort: cloudformation.Ref(parameterTargetGroupHealthCheckPortParameter).String(), HealthCheckProtocol: cloudformation.String(healthCheckProtocol), + HealthyThresholdCount: cloudformation.Integer(int64(spec.healthyThresholdCount)), Port: cloudformation.Ref(targetPortParameter).Integer(), Protocol: cloudformation.String(protocol), VPCID: cloudformation.Ref(parameterTargetGroupVPCIDParameter).String(), diff --git a/aws/cf_template_test.go b/aws/cf_template_test.go index d0e5181c..58144900 100644 --- a/aws/cf_template_test.go +++ b/aws/cf_template_test.go @@ -585,6 +585,17 @@ func TestGenerateTemplate(t *testing.T) { validateTargetGroupOutput(t, template, "TG", "TargetGroupARN") }, }, + { + name: "Defines the HealthyThresholdCount if defined", + spec: &stackSpec{ + loadbalancerType: LoadBalancerTypeApplication, + healthyThresholdCount: 2, + }, + validate: func(t *testing.T, template *cloudformation.Template) { + tg := template.Resources["TG"].Properties.(*cloudformation.ElasticLoadBalancingV2TargetGroup) + require.Equal(t, cloudformation.Integer(2), tg.HealthyThresholdCount) + }, + }, } { t.Run(test.name, func(t *testing.T) { generated, err := generateTemplate(test.spec) diff --git a/controller.go b/controller.go index b50ddda4..4306c429 100644 --- a/controller.go +++ b/controller.go @@ -43,6 +43,7 @@ var ( healthCheckPort uint healthCheckInterval time.Duration healthCheckTimeout time.Duration + healthyThresholdCount uint targetPort uint albHTTPTargetPort uint nlbHTTPTargetPort uint @@ -221,6 +222,8 @@ func loadSettings() error { Default(aws.DefaultHealthCheckInterval.String()).DurationVar(&healthCheckInterval) kingpin.Flag("health-check-timeout", "sets the health check timeout for the created target groups. The flag accepts a value acceptable to time.ParseDuration"). Default(aws.DefaultHealthCheckTimeout.String()).DurationVar(&healthCheckTimeout) + kingpin.Flag("healthy-threshold-count", "The number of consecutive health checks successes required before considering an unhealthy target healthy"). + Default(strconv.FormatUint(aws.DefaultHealthyThresholdCount, 10)).UintVar(&healthyThresholdCount) kingpin.Flag("idle-connection-timeout", "sets the idle connection timeout of all ALBs. The flag accepts a value acceptable to time.ParseDuration and are between 1s and 4000s."). Default(aws.DefaultIdleConnectionTimeout.String()).DurationVar(&idleConnectionTimeout) kingpin.Flag("deregistration-delay-timeout", "sets the deregistration delay timeout of all target groups. The flag accepts a value acceptable to time.ParseDuration that is between 1s and 3600s."). @@ -286,6 +289,10 @@ func loadSettings() error { return fmt.Errorf("invalid health check port: %d. please use a valid TCP port", healthCheckPort) } + if healthyThresholdCount < 2 || healthyThresholdCount > 10 { + return fmt.Errorf("invalid healthy threshold: %d. must be between 2 and 10", healthyThresholdCount) + } + if targetPort == 0 || targetPort > 65535 { return fmt.Errorf("invalid target port: %d. please use a valid TCP port", targetPort) } @@ -370,6 +377,7 @@ func main() { WithHealthCheckPort(healthCheckPort). WithHealthCheckInterval(healthCheckInterval). WithHealthCheckTimeout(healthCheckTimeout). + WithHealthyThresholdCount(healthyThresholdCount). WithTargetPort(targetPort). WithALBHTTPTargetPort(albHTTPTargetPort). WithNLBHTTPTargetPort(nlbHTTPTargetPort).