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

feat(ECS): enable selection of listener rules #4668

Merged
Merged
13 changes: 13 additions & 0 deletions pkg/app/piped/executor/ecs/ecs.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,19 @@ func routing(ctx context.Context, in *executor.Input, platformProviderName strin
return false
}

currListenerRuleArns, err := client.GetListenerRuleArns(ctx, currListenerArns)
if err != nil {
in.LogPersister.Errorf("Failed to get current active listener rule: %v", err)
return false
}

if len(currListenerRuleArns) > 0 {
if err := client.ModifyRules(ctx, currListenerRuleArns, routingTrafficCfg); err != nil {
in.LogPersister.Errorf("Failed to routing traffic to PRIMARY/CANARY variants: %v", err)
return false
}
khanhtc1202 marked this conversation as resolved.
Show resolved Hide resolved
}

if err := client.ModifyListeners(ctx, currListenerArns, routingTrafficCfg); err != nil {
in.LogPersister.Errorf("Failed to routing traffic to PRIMARY/CANARY variants: %v", err)
return false
Expand Down
17 changes: 16 additions & 1 deletion pkg/app/piped/executor/ecs/rollback.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,23 @@ func rollback(ctx context.Context, in *executor.Input, platformProviderName stri
return false
}

currListenerRuleArns, err := client.GetListenerRuleArns(ctx, currListenerArns)
if err != nil {
in.LogPersister.Errorf("Failed to get current active listener rule: %v", err)
return false
}

if len(currListenerRuleArns) > 0 {
if err := client.ModifyRules(ctx, currListenerRuleArns, routingTrafficCfg); err != nil {
in.LogPersister.Errorf("Failed to routing traffic to PRIMARY/CANARY variants: %v", err)
return false
}
khanhtc1202 marked this conversation as resolved.
Show resolved Hide resolved

return true
}

if err := client.ModifyListeners(ctx, currListenerArns, routingTrafficCfg); err != nil {
in.LogPersister.Errorf("Failed to routing traffic to PRIMARY variant: %v", err)
in.LogPersister.Errorf("Failed to routing traffic to PRIMARY/CANARY variants: %v", err)
return false
}
}
Expand Down
86 changes: 86 additions & 0 deletions pkg/app/piped/platformprovider/ecs/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,30 @@
return arns, nil
}

func (c *client) GetListenerRuleArns(ctx context.Context, listenerArns []string) ([]string, error) {
var ruleArns []string

// Fetch all rules by listeners
for _, listenerArn := range listenerArns {
input := &elasticloadbalancingv2.DescribeRulesInput{
ListenerArn: aws.String(listenerArn),
}
output, err := c.elbClient.DescribeRules(ctx, input)
if err != nil {
return nil, err
}
for _, rule := range output.Rules {
ruleArns = append(ruleArns, *rule.RuleArn)
}

Check warning on line 434 in pkg/app/piped/platformprovider/ecs/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/ecs/client.go#L420-L434

Added lines #L420 - L434 were not covered by tests
}

if len(ruleArns) == 0 {
return nil, platformprovider.ErrNotFound
}

Check warning on line 439 in pkg/app/piped/platformprovider/ecs/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/ecs/client.go#L437-L439

Added lines #L437 - L439 were not covered by tests

return ruleArns, nil

Check warning on line 441 in pkg/app/piped/platformprovider/ecs/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/ecs/client.go#L441

Added line #L441 was not covered by tests
}

func (c *client) getLoadBalancerArn(ctx context.Context, targetGroupArn string) (string, error) {
input := &elasticloadbalancingv2.DescribeTargetGroupsInput{
TargetGroupArns: []string{targetGroupArn},
Expand Down Expand Up @@ -470,6 +494,68 @@
return nil
}

func (c *client) ModifyRules(ctx context.Context, listenerRuleArns []string, routingTrafficCfg RoutingTrafficConfig) error {
if len(routingTrafficCfg) != 2 {
return fmt.Errorf("invalid listener configuration: requires 2 target groups")
}

Check warning on line 500 in pkg/app/piped/platformprovider/ecs/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/ecs/client.go#L497-L500

Added lines #L497 - L500 were not covered by tests

modifyListenerRule := func(ctx context.Context, listenerRuleArn string) error {
input := &elasticloadbalancingv2.ModifyRuleInput{
RuleArn: aws.String(listenerRuleArn),
Actions: []elbtypes.Action{
{
Type: elbtypes.ActionTypeEnumForward,
ForwardConfig: &elbtypes.ForwardActionConfig{
TargetGroups: []elbtypes.TargetGroupTuple{
{
TargetGroupArn: aws.String(routingTrafficCfg[0].TargetGroupArn),
Weight: aws.Int32(int32(routingTrafficCfg[0].Weight)),
},
{
TargetGroupArn: aws.String(routingTrafficCfg[1].TargetGroupArn),
Weight: aws.Int32(int32(routingTrafficCfg[1].Weight)),
},
},
},
},
},
}
_, err := c.elbClient.ModifyRule(ctx, input)
return err
}

Check warning on line 525 in pkg/app/piped/platformprovider/ecs/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/ecs/client.go#L502-L525

Added lines #L502 - L525 were not covered by tests

for _, ruleArn := range listenerRuleArns {
// Describe the rule to get current actions
describeRulesOutput, err := c.elbClient.DescribeRules(ctx, &elasticloadbalancingv2.DescribeRulesInput{
RuleArns: []string{ruleArn},
})
if err != nil {
return fmt.Errorf("error describing listener rule %v: %w", ruleArn, err)
}

Check warning on line 534 in pkg/app/piped/platformprovider/ecs/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/ecs/client.go#L527-L534

Added lines #L527 - L534 were not covered by tests

// No rules found, nothing to modify
if len(describeRulesOutput.Rules) == 0 {
return fmt.Errorf("no rules found for ARN: %s", ruleArn)
}

Check warning on line 539 in pkg/app/piped/platformprovider/ecs/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/ecs/client.go#L537-L539

Added lines #L537 - L539 were not covered by tests

// Check if the current action type is forward
for _, rule := range describeRulesOutput.Rules {
for _, action := range rule.Actions {
if action.Type == elbtypes.ActionTypeEnumForward {
// Call modifyListenerRule only if action type is forward
if err := modifyListenerRule(ctx, ruleArn); err != nil {
return err
}

Check warning on line 548 in pkg/app/piped/platformprovider/ecs/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/ecs/client.go#L542-L548

Added lines #L542 - L548 were not covered by tests
// Break the loop once the modify function is called for the rule
break

Check warning on line 550 in pkg/app/piped/platformprovider/ecs/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/ecs/client.go#L550

Added line #L550 was not covered by tests
}
}
}
}

return nil

Check warning on line 556 in pkg/app/piped/platformprovider/ecs/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/app/piped/platformprovider/ecs/client.go#L556

Added line #L556 was not covered by tests
}

func (c *client) TagResource(ctx context.Context, resourceArn string, tags []types.Tag) error {
input := &ecs.TagResourceInput{
ResourceArn: aws.String(resourceArn),
Expand Down
2 changes: 2 additions & 0 deletions pkg/app/piped/platformprovider/ecs/ecs.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ type ECS interface {

type ELB interface {
GetListenerArns(ctx context.Context, targetGroup types.LoadBalancer) ([]string, error)
GetListenerRuleArns(ctx context.Context, listenerArns []string) ([]string, error)
ModifyListeners(ctx context.Context, listenerArns []string, routingTrafficCfg RoutingTrafficConfig) error
ModifyRules(ctx context.Context, listenerRuleArns []string, routingTrafficCfg RoutingTrafficConfig) error
khanhtc1202 marked this conversation as resolved.
Show resolved Hide resolved
}

// Registry holds a pool of aws client wrappers.
Expand Down