Skip to content

Commit

Permalink
don't clone original taskdef if no changes are detected (#9)
Browse files Browse the repository at this point in the history
* don't clone original taskdef if no changes are required
* update go version
  • Loading branch information
andresvia authored Nov 6, 2019
1 parent 87bef2b commit c1598cd
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 66 deletions.
2 changes: 1 addition & 1 deletion asg.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ecs"
"github.com/cenkalti/backoff"
"github.com/cenkalti/backoff/v3"
"log"
"strings"
"sync"
Expand Down
46 changes: 23 additions & 23 deletions asg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,38 @@ type mockAutoScalingClient struct {
}

func (m *mockAutoScalingClient) DescribeAutoScalingGroups(input *autoscaling.DescribeAutoScalingGroupsInput) (*autoscaling.DescribeAutoScalingGroupsOutput, error) {
name := ""
name := ""
return &autoscaling.DescribeAutoScalingGroupsOutput{
AutoScalingGroups: []*autoscaling.Group{
&autoscaling.Group{
Instances: []*autoscaling.Instance{
// TODO
},
LaunchConfigurationName: &name,
},
},
}, nil
AutoScalingGroups: []*autoscaling.Group{
&autoscaling.Group{
Instances: []*autoscaling.Instance{
// TODO
},
LaunchConfigurationName: &name,
},
},
}, nil
}

func TestListASGInstaces(t *testing.T) {
instances, name, err := listASGInstaces(&mockAutoScalingClient{}, "")
if len(instances) != 0 {
t.Errorf("unexpected")
}
if *name != "" {
t.Errorf("unexpected")
}
if err != nil {
t.Errorf("unexpected")
}
if len(instances) != 0 {
t.Errorf("unexpected")
}
if *name != "" {
t.Errorf("unexpected")
}
if err != nil {
t.Errorf("unexpected")
}
}

func TestNeedReplacement(t *testing.T) {
name := ""
name := ""
replace := needReplacement("", autoscaling.Instance{LaunchConfigurationName: &name})
if replace {
t.Errorf("unexpected")
}
if replace {
t.Errorf("unexpected")
}
}

func TestFilterInstancesToReplace(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion cmd/enforce-aws-ecs-asg-launchconfig/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ecs"
"github.com/cenkalti/backoff"
"github.com/cenkalti/backoff/v3"
"log"
)

Expand Down
2 changes: 1 addition & 1 deletion cmd/update-aws-ecs-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ecs"
"github.com/cenkalti/backoff"
"github.com/cenkalti/backoff/v3"
"log"
"os"
"strings"
Expand Down
5 changes: 3 additions & 2 deletions ecs-alter-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package awsecs

import (
"errors"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ecs"
"github.com/cenkalti/backoff"
"github.com/cenkalti/backoff/v3"
"log"
)

Expand All @@ -26,7 +27,7 @@ func alterServiceOrValidatedRollBack(api ecs.ECS, cluster, service string, image
return ErrPermanentNothingToRollback
}
log.Printf("attempt rollback %v", alterSvcErr)
rollback, err := api.UpdateService(&ecs.UpdateServiceInput{Cluster: oldsvc.ClusterArn, Service: oldsvc.ServiceName, TaskDefinition: oldsvc.TaskDefinition, DesiredCount: oldsvc.DesiredCount})
rollback, err := api.UpdateService(&ecs.UpdateServiceInput{Cluster: oldsvc.ClusterArn, Service: oldsvc.ServiceName, TaskDefinition: oldsvc.TaskDefinition, DesiredCount: oldsvc.DesiredCount, ForceNewDeployment: aws.Bool(true)})
if err != nil {
return err
}
Expand Down
118 changes: 87 additions & 31 deletions ecs.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package awsecs

import (
"encoding/json"
"errors"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ecs"
"github.com/cenkalti/backoff"
"github.com/cenkalti/backoff/v3"
"log"
"reflect"
)

var (
Expand All @@ -27,56 +29,95 @@ var (
errNoPrimaryDeployment = backoff.Permanent(errors.New("no PRIMARY deployment"))
)

func copy(input ecs.TaskDefinition) ecs.RegisterTaskDefinitionInput {
func copyTd(input ecs.TaskDefinition, tags []*ecs.Tag) ecs.RegisterTaskDefinitionInput {
obj, err := json.Marshal(input)
if err != nil {
panic(err)
}
inputClone := ecs.TaskDefinition{}
err = json.Unmarshal(obj, &inputClone)
if err != nil {
panic(err)
}
output := ecs.RegisterTaskDefinitionInput{}
output.ContainerDefinitions = input.ContainerDefinitions
output.Cpu = input.Cpu
output.ExecutionRoleArn = input.ExecutionRoleArn
output.Family = input.Family
output.IpcMode = input.IpcMode
output.Memory = input.Memory
output.NetworkMode = input.NetworkMode
output.PidMode = input.PidMode
output.PlacementConstraints = input.PlacementConstraints
output.RequiresCompatibilities = input.RequiresCompatibilities
output.TaskRoleArn = input.TaskRoleArn
output.Volumes = input.Volumes
output.ContainerDefinitions = inputClone.ContainerDefinitions
output.Cpu = inputClone.Cpu
output.ExecutionRoleArn = inputClone.ExecutionRoleArn
output.Family = inputClone.Family
// output.InferenceAccelerators // not supported by the current version of the SDK
output.IpcMode = inputClone.IpcMode
output.Memory = inputClone.Memory
output.NetworkMode = inputClone.NetworkMode
output.PidMode = inputClone.PidMode
output.PlacementConstraints = inputClone.PlacementConstraints
output.ProxyConfiguration = inputClone.ProxyConfiguration
output.RequiresCompatibilities = inputClone.RequiresCompatibilities
output.Tags = tags
output.TaskRoleArn = inputClone.TaskRoleArn
output.Volumes = inputClone.Volumes
return output
}

func alterImages(copy ecs.RegisterTaskDefinitionInput, imageMap map[string]string) ecs.RegisterTaskDefinitionInput {
obj, err := json.Marshal(copy)
if err != nil {
panic(err)
}
copyClone := ecs.RegisterTaskDefinitionInput{}
err = json.Unmarshal(obj, &copyClone)
if err != nil {
panic(err)
}
for name, image := range imageMap {
for _, containerDefinition := range copy.ContainerDefinitions {
for _, containerDefinition := range copyClone.ContainerDefinitions {
if *containerDefinition.Name == name {
containerDefinition.Image = aws.String(image)
}
}
}
return copy
return copyClone
}

func alterEnvironments(copy ecs.RegisterTaskDefinitionInput, envMaps map[string]map[string]string) ecs.RegisterTaskDefinitionInput {
obj, err := json.Marshal(copy)
if err != nil {
panic(err)
}
copyClone := ecs.RegisterTaskDefinitionInput{}
err = json.Unmarshal(obj, &copyClone)
if err != nil {
panic(err)
}
for name, envMap := range envMaps {
for i, containerDefinition := range copy.ContainerDefinitions {
for i, containerDefinition := range copyClone.ContainerDefinitions {
if *containerDefinition.Name == name {
new := alterEnvironment(*containerDefinition, envMap)
copy.ContainerDefinitions[i] = &new
altered := alterEnvironment(*containerDefinition, envMap)
copyClone.ContainerDefinitions[i] = &altered
}
}
}
return copy
return copyClone
}

func alterSecrets(copy ecs.RegisterTaskDefinitionInput, secretMaps map[string]map[string]string) ecs.RegisterTaskDefinitionInput {
obj, err := json.Marshal(copy)
if err != nil {
panic(err)
}
copyClone := ecs.RegisterTaskDefinitionInput{}
err = json.Unmarshal(obj, &copyClone)
if err != nil {
panic(err)
}
for name, secretMap := range secretMaps {
for i, containerDefinition := range copy.ContainerDefinitions {
for i, containerDefinition := range copyClone.ContainerDefinitions {
if *containerDefinition.Name == name {
new := alterSecret(*containerDefinition, secretMap)
copy.ContainerDefinitions[i] = &new
altered := alterSecret(*containerDefinition, secretMap)
copyClone.ContainerDefinitions[i] = &altered
}
}
}
return copy
return copyClone
}

func alterEnvironment(copy ecs.ContainerDefinition, envMap map[string]string) ecs.ContainerDefinition {
Expand Down Expand Up @@ -130,13 +171,28 @@ func copyTaskDef(api ecs.ECS, taskdef string, imageMap map[string]string, envMap
if err != nil {
return "", err
}
copy := alterSecrets(alterEnvironments(alterImages(copy(*output.TaskDefinition), imageMap), envMaps), secretMaps)
new, err := api.RegisterTaskDefinition(&copy)
if err != nil {
return "", err

asRegisterTaskDefinitionInput := copyTd(*output.TaskDefinition, output.Tags)
tdCopy := alterSecrets(alterEnvironments(alterImages(asRegisterTaskDefinitionInput, imageMap), envMaps), secretMaps)

// if os.Getenv("DEBUG") == "YES" {
// out, _ := json.Marshal(asRegisterTaskDefinitionInput)
// fmt.Println(string(out))
// out, _ = json.Marshal(tdCopy)
// fmt.Println(string(out))
// panic("something")
// }

if reflect.DeepEqual(asRegisterTaskDefinitionInput, tdCopy) {
return *output.TaskDefinition.TaskDefinitionArn, nil
} else {
tdNew, err := api.RegisterTaskDefinition(&tdCopy)
if err != nil {
return "", err
}
arn := tdNew.TaskDefinition.TaskDefinitionArn
return *arn, nil
}
arn := new.TaskDefinition.TaskDefinitionArn
return *arn, nil
}

func alterService(api ecs.ECS, cluster, service string, imageMap map[string]string, envMaps map[string]map[string]string, secretMaps map[string]map[string]string, desiredCount *int64, taskdef string) (ecs.Service, ecs.Service, error) {
Expand All @@ -156,7 +212,7 @@ func alterService(api ecs.ECS, cluster, service string, imageMap map[string]stri
if desiredCount == nil {
desiredCount = svc.DesiredCount
}
updated, err := api.UpdateService(&ecs.UpdateServiceInput{Cluster: aws.String(cluster), Service: aws.String(service), TaskDefinition: aws.String(newTd), DesiredCount: desiredCount})
updated, err := api.UpdateService(&ecs.UpdateServiceInput{Cluster: aws.String(cluster), Service: aws.String(service), TaskDefinition: aws.String(newTd), DesiredCount: desiredCount, ForceNewDeployment: aws.Bool(true)})
if err != nil {
return *svc, ecs.Service{}, err
}
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module github.com/Autodesk/go-awsecs

go 1.12
go 1.13

require (
github.com/aws/aws-sdk-go v1.19.24
github.com/cenkalti/backoff v0.0.0-20190506075156-2146c9339422
github.com/aws/aws-sdk-go v1.19.49
github.com/cenkalti/backoff/v3 v3.0.0
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
github.com/aws/aws-sdk-go v1.19.24 h1:qOIYaFxcFg07Vdn799ERpGiuUUIEi5MQ2vYib3CNMp4=
github.com/aws/aws-sdk-go v1.19.24/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/cenkalti/backoff v0.0.0-20190506075156-2146c9339422 h1:+FKjzBIdfBHYDvxCv+djmDJdes/AoDtg8gpcxowBlF8=
github.com/cenkalti/backoff v0.0.0-20190506075156-2146c9339422/go.mod h1:b6Nc7NRH5C4aCISLry0tLnTjcuTEvoiqcWDdsU0sOGM=
github.com/aws/aws-sdk-go v1.19.49 h1:GUlenK625g5iKrIiRcqRS/CvPMLc8kZRtMxXuXBhFx4=
github.com/aws/aws-sdk-go v1.19.49/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c=
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=

0 comments on commit c1598cd

Please sign in to comment.