Skip to content

Commit

Permalink
feat(ECS): enable selection of listener rules (pipe-cd#4668)
Browse files Browse the repository at this point in the history
* feat(ECS): enable selection of listener rules

Signed-off-by: moko-poi <mokopoi44@gmail.com>

* Update pkg/app/piped/platformprovider/ecs/client.go

Signed-off-by: moko-poi <mokopoi44@gmail.com>

* Make actions plan preview handle timeout option (pipe-cd#4648)

* Format and make tests pass in tool/actions-plan-preview

Signed-off-by: mi11km <mi11km.program@gmail.com>

* Use --piped-handle-timeout to make the timeout arg activate

Signed-off-by: mi11km <mi11km.program@gmail.com>

* Add tests to model/notificationevent (pipe-cd#4631)

* Add tests to model/notificationevent

Signed-off-by: Kenta Kozuka <kenta.kozuka@gmail.com>

* Add Parallel()

Signed-off-by: Kenta Kozuka <kenta.kozuka@gmail.com>

---------

Signed-off-by: Kenta Kozuka <kenta.kozuka@gmail.com>
Signed-off-by: mi11km <mi11km.program@gmail.com>

* add piped-handle-timeout(input args)

Signed-off-by: mi11km <mi11km.program@gmail.com>

---------

Signed-off-by: mi11km <mi11km.program@gmail.com>
Signed-off-by: Kenta Kozuka <kenta.kozuka@gmail.com>
Co-authored-by: Kenta Kozuka <kenta.kozuka@gmail.com>
Co-authored-by: Khanh Tran <32532742+khanhtc1202@users.noreply.github.com>
Signed-off-by: moko-poi <mokopoi44@gmail.com>

* Increase limit of stale action operations (pipe-cd#4671)

Signed-off-by: moko-poi <mokopoi44@gmail.com>

* Add docs for k8s annotations (pipe-cd#4673)

Signed-off-by: Yoshiki Fujikane <ffjlabo@gmail.com>
Signed-off-by: moko-poi <mokopoi44@gmail.com>

* feat: add modifylisner and modifyrule

Signed-off-by: moko-poi <mokopoi44@gmail.com>

* fix: ModifyRules

Signed-off-by: moko-poi <mokopoi44@gmail.com>

* fix: rollback

Signed-off-by: moko-poi <mokopoi44@gmail.com>

* fix: routing

Signed-off-by: moko-poi <mokopoi44@gmail.com>

* fix: action.Type == elbtypes.ActionTypeEnumForward

Signed-off-by: moko-poi <mokopoi44@gmail.com>

* fix: Update ModifyListeners and ModifyRules for Selective Action Modification

Signed-off-by: moko-poi <mokopoi44@gmail.com>

---------

Signed-off-by: moko-poi <mokopoi44@gmail.com>
Signed-off-by: mi11km <mi11km.program@gmail.com>
Signed-off-by: Kenta Kozuka <kenta.kozuka@gmail.com>
Signed-off-by: Yoshiki Fujikane <ffjlabo@gmail.com>
Co-authored-by: Khanh Tran <32532742+khanhtc1202@users.noreply.github.com>
Co-authored-by: Masafumi Ikeyama <54844746+mi11km@users.noreply.github.com>
Co-authored-by: Kenta Kozuka <kenta.kozuka@gmail.com>
Co-authored-by: Yoshiki Fujikane <40124947+ffjlabo@users.noreply.github.com>
Signed-off-by: 鈴木 優耀 <suzuki_masaaki@cyberagent.co.jp>
  • Loading branch information
5 people authored and 鈴木 優耀 committed Feb 12, 2024
1 parent f4b180a commit 7349d80
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 13 deletions.
15 changes: 15 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,21 @@ 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
}

return true
}

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
}

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
117 changes: 105 additions & 12 deletions pkg/app/piped/platformprovider/ecs/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"errors"
"fmt"
"strings"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
Expand Down Expand Up @@ -417,6 +418,30 @@ func (c *client) GetListenerArns(ctx context.Context, targetGroup types.LoadBala
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)
}
}

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

return ruleArns, nil
}

func (c *client) getLoadBalancerArn(ctx context.Context, targetGroupArn string) (string, error) {
input := &elasticloadbalancingv2.DescribeTargetGroupsInput{
TargetGroupArns: []string{targetGroupArn},
Expand All @@ -437,11 +462,21 @@ func (c *client) ModifyListeners(ctx context.Context, listenerArns []string, rou
return fmt.Errorf("invalid listener configuration: requires 2 target groups")
}

modifyListener := func(ctx context.Context, listenerArn string) error {
input := &elasticloadbalancingv2.ModifyListenerInput{
ListenerArn: aws.String(listenerArn),
DefaultActions: []elbtypes.Action{
{
for _, listenerArn := range listenerArns {
// Describe the listener to get the current actions
describeListenersOutput, err := c.elbClient.DescribeListeners(ctx, &elasticloadbalancingv2.DescribeListenersInput{
ListenerArns: []string{listenerArn},
})
if err != nil {
return fmt.Errorf("error describing listener %s: %w", listenerArn, err)
}

// Prepare the actions to be modified
var modifiedActions []elbtypes.Action
for _, action := range describeListenersOutput.Listeners[0].DefaultActions {
if action.Type == elbtypes.ActionTypeEnumForward {
// Modify only the forward action (new logic)
modifiedAction := elbtypes.Action{
Type: elbtypes.ActionTypeEnumForward,
ForwardConfig: &elbtypes.ForwardActionConfig{
TargetGroups: []elbtypes.TargetGroupTuple{
Expand All @@ -455,16 +490,74 @@ func (c *client) ModifyListeners(ctx context.Context, listenerArns []string, rou
},
},
},
},
},
}
modifiedActions = append(modifiedActions, modifiedAction)
} else {
// Keep other actions unchanged (new logic)
modifiedActions = append(modifiedActions, action)
}
}
_, err := c.elbClient.ModifyListener(ctx, input)
return err

// Modify the listener
_, err = c.elbClient.ModifyListener(ctx, &elasticloadbalancingv2.ModifyListenerInput{
ListenerArn: aws.String(listenerArn),
DefaultActions: modifiedActions,
})
if err != nil {
return fmt.Errorf("error modifying listener %s: %w", listenerArn, err)
}
}
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")
}

for _, listener := range listenerArns {
if err := modifyListener(ctx, listener); err != nil {
return err
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", strings.Join(listenerRuleArns, ", "), err)
}

// Prepare the actions to be modified
var modifiedActions []elbtypes.Action
for _, action := range describeRulesOutput.Rules[0].Actions {
if action.Type == elbtypes.ActionTypeEnumForward {
// Modify only the forward action (new logic)
modifiedAction := 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)),
},
},
},
}
modifiedActions = append(modifiedActions, modifiedAction)
} else {
// Keep other actions unchanged (new logic)
modifiedActions = append(modifiedActions, action)
}
}

// Modify the rule with the new actions
_, err = c.elbClient.ModifyRule(ctx, &elasticloadbalancingv2.ModifyRuleInput{
RuleArn: aws.String(ruleArn),
Actions: modifiedActions,
})
if err != nil {
return fmt.Errorf("error modifying listener rule %s: %w", ruleArn, err)
}
}
return nil
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
}

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

0 comments on commit 7349d80

Please sign in to comment.