From 4b0fe9d324b266f3bf2c6382b9b5638c24d7b087 Mon Sep 17 00:00:00 2001 From: stormcat24 Date: Tue, 8 Sep 2015 11:59:00 +0900 Subject: [PATCH] handle aws.Config.MaxRetries by --retry-count option --- aws/autoscaling.go | 42 +++-------- aws/aws.go | 61 ++++++++------- aws/ecs_api.go | 165 +++++++++++++++++++++++++++++++++++++++++ aws/ecs_cluster_api.go | 82 -------------------- aws/ecs_service_api.go | 95 ------------------------ aws/ecs_task_api.go | 86 --------------------- aws/elb_api.go | 33 ++------- aws/sns_api.go | 22 ++---- bluegreen/bluegreen.go | 44 +++++------ config/config.go | 11 ++- main.go | 13 +++- service/service.go | 62 +++++++--------- task/task.go | 48 ++++++------ 13 files changed, 314 insertions(+), 450 deletions(-) create mode 100644 aws/ecs_api.go delete mode 100644 aws/ecs_cluster_api.go delete mode 100644 aws/ecs_service_api.go delete mode 100644 aws/ecs_task_api.go diff --git a/aws/autoscaling.go b/aws/autoscaling.go index 37bc6a3..4b98781 100644 --- a/aws/autoscaling.go +++ b/aws/autoscaling.go @@ -1,30 +1,23 @@ package aws + import ( - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/stormcat24/ecs-formation/util" ) - type AutoscalingApi struct { - Credentials *credentials.Credentials - Region *string + service *autoscaling.AutoScaling } func (self *AutoscalingApi) DescribeAutoScalingGroups(groups []string) (map[string]*autoscaling.Group, error) { - svc := autoscaling.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - params := &autoscaling.DescribeAutoScalingGroupsInput{ AutoScalingGroupNames: util.ConvertPointerString(groups), } asgmap := map[string]*autoscaling.Group{} - result, err := svc.DescribeAutoScalingGroups(params) + result, err := self.service.DescribeAutoScalingGroups(params) if err != nil { return asgmap, err } @@ -38,17 +31,12 @@ func (self *AutoscalingApi) DescribeAutoScalingGroups(groups []string) (map[stri func (self *AutoscalingApi) DescribeLoadBalancerState(group string) (map[string]*autoscaling.LoadBalancerState, error) { - svc := autoscaling.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - params := &autoscaling.DescribeLoadBalancersInput{ AutoScalingGroupName: aws.String(group), } lbmap := map[string]*autoscaling.LoadBalancerState{} - result, err := svc.DescribeLoadBalancers(params) + result, err := self.service.DescribeLoadBalancers(params) if err != nil { return lbmap, err } @@ -62,30 +50,20 @@ func (self *AutoscalingApi) DescribeLoadBalancerState(group string) (map[string] func (self *AutoscalingApi) AttachLoadBalancers(group string, lb []string) (*autoscaling.AttachLoadBalancersOutput, error) { - svc := autoscaling.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - params := &autoscaling.AttachLoadBalancersInput{ AutoScalingGroupName: aws.String(group), - LoadBalancerNames: util.ConvertPointerString(lb), + LoadBalancerNames: util.ConvertPointerString(lb), } - return svc.AttachLoadBalancers(params) + return self.service.AttachLoadBalancers(params) } func (self *AutoscalingApi) DetachLoadBalancers(group string, lb []string) (*autoscaling.DetachLoadBalancersOutput, error) { - svc := autoscaling.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - params := &autoscaling.DetachLoadBalancersInput{ AutoScalingGroupName: aws.String(group), - LoadBalancerNames: util.ConvertPointerString(lb), + LoadBalancerNames: util.ConvertPointerString(lb), } - return svc.DetachLoadBalancers(params) -} \ No newline at end of file + return self.service.DetachLoadBalancers(params) +} diff --git a/aws/aws.go b/aws/aws.go index e414cee..b278789 100644 --- a/aws/aws.go +++ b/aws/aws.go @@ -1,13 +1,19 @@ package aws import ( + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/service/autoscaling" + "github.com/aws/aws-sdk-go/service/ecs" + "github.com/aws/aws-sdk-go/service/elb" + "github.com/aws/aws-sdk-go/service/sns" + "github.com/stormcat24/ecs-formation/config" ) - type AwsManager struct { credentials *credentials.Credentials - region *string + region string + retryCount int } func NewAwsManager(accessKey string, secretKey string, region string) *AwsManager { @@ -16,50 +22,49 @@ func NewAwsManager(accessKey string, secretKey string, region string) *AwsManage manager := &AwsManager{ credentials: cred, - region: ®ion, + region: region, + retryCount: config.AppConfig.RetryCount, } return manager } -func (self *AwsManager) ClusterApi() *EcsClusterApi { - return &EcsClusterApi{ - Credentials: self.credentials, - Region: self.region, - } -} - -func (self *AwsManager) ServiceApi() *EcsServiceApi { - return &EcsServiceApi{ - Credentials: self.credentials, - Region: self.region, - } -} - -func (self *AwsManager) TaskApi() *EcsTaskApi { - return &EcsTaskApi{ - Credentials: self.credentials, - Region: self.region, +func (self *AwsManager) EcsApi() *EcsApi { + return &EcsApi{ + service: ecs.New(&aws.Config{ + Credentials: self.credentials, + Region: &self.region, + MaxRetries: &self.retryCount, + }), } } func (self *AwsManager) ElbApi() *ElbApi { return &ElbApi{ - Credentials: self.credentials, - Region: self.region, + service: elb.New(&aws.Config{ + Credentials: self.credentials, + Region: &self.region, + MaxRetries: &self.retryCount, + }), } } func (self *AwsManager) AutoscalingApi() *AutoscalingApi { return &AutoscalingApi{ - Credentials: self.credentials, - Region: self.region, + service: autoscaling.New(&aws.Config{ + Credentials: self.credentials, + Region: &self.region, + MaxRetries: &self.retryCount, + }), } } func (self *AwsManager) SnsApi() *SnsApi { return &SnsApi{ - Credentials: self.credentials, - Region: self.region, + service: sns.New(&aws.Config{ + Credentials: self.credentials, + Region: &self.region, + MaxRetries: &self.retryCount, + }), } -} \ No newline at end of file +} diff --git a/aws/ecs_api.go b/aws/ecs_api.go new file mode 100644 index 0000000..1baf856 --- /dev/null +++ b/aws/ecs_api.go @@ -0,0 +1,165 @@ +package aws + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ecs" +) + +type EcsApi struct { + service *ecs.ECS +} + +// Cluster API +func (self *EcsApi) CreateCluster(clusterName string) (*ecs.CreateClusterOutput, error) { + + params := &ecs.CreateClusterInput{ + ClusterName: aws.String(clusterName), + } + + return self.service.CreateCluster(params) +} + +func (self *EcsApi) DeleteCluster(clusterName string) (*ecs.DeleteClusterOutput, error) { + + params := &ecs.DeleteClusterInput{ + Cluster: aws.String(clusterName), + } + + return self.service.DeleteCluster(params) +} + +func (self *EcsApi) DescribeClusters(clusterNames []*string) (*ecs.DescribeClustersOutput, error) { + + params := &ecs.DescribeClustersInput{ + Clusters: clusterNames, + } + + return self.service.DescribeClusters(params) +} + +func (self *EcsApi) ListClusters(maxResult int64) (*ecs.ListClustersOutput, error) { + + params := &ecs.ListClustersInput{ + MaxResults: &maxResult, + } + + return self.service.ListClusters(params) +} + +func (self *EcsApi) ListContainerInstances(cluster string) (*ecs.ListContainerInstancesOutput, error) { + + params := &ecs.ListContainerInstancesInput{ + Cluster: aws.String(cluster), + } + + return self.service.ListContainerInstances(params) +} + +// Service API +func (self *EcsApi) CreateService(cluster string, service string, desiredCount int64, lb []*ecs.LoadBalancer, taskDef string, role string) (*ecs.CreateServiceOutput, error) { + + params := &ecs.CreateServiceInput{ + ServiceName: aws.String(service), + Cluster: aws.String(cluster), + DesiredCount: &desiredCount, + LoadBalancers: lb, + TaskDefinition: aws.String(taskDef), + } + + if role != "" { + params.Role = aws.String(role) + } + + return self.service.CreateService(params) +} + +func (self *EcsApi) UpdateService(cluster string, service string, desiredCount int64, taskDef string) (*ecs.UpdateServiceOutput, error) { + + params := &ecs.UpdateServiceInput{ + Cluster: aws.String(cluster), + Service: aws.String(service), + DesiredCount: &desiredCount, + TaskDefinition: aws.String(taskDef), + } + + return self.service.UpdateService(params) +} + +func (self *EcsApi) DescribeService(cluster string, services []*string) (*ecs.DescribeServicesOutput, error) { + + params := &ecs.DescribeServicesInput{ + Cluster: aws.String(cluster), + Services: services, + } + + return self.service.DescribeServices(params) +} + +func (self *EcsApi) DeleteService(cluster string, service string) (*ecs.DeleteServiceOutput, error) { + + params := &ecs.DeleteServiceInput{ + Cluster: aws.String(cluster), + Service: aws.String(service), + } + + return self.service.DeleteService(params) +} + +func (self *EcsApi) ListServices(cluster string) (*ecs.ListServicesOutput, error) { + + params := &ecs.ListServicesInput{ + Cluster: aws.String(cluster), + } + + return self.service.ListServices(params) +} + +// TASK API +func (self *EcsApi) DescribeTaskDefinition(defName string) (*ecs.DescribeTaskDefinitionOutput, error) { + + params := &ecs.DescribeTaskDefinitionInput{ + TaskDefinition: aws.String(defName), + } + + return self.service.DescribeTaskDefinition(params) +} + +func (self *EcsApi) RegisterTaskDefinition(taskName string, conDefs []*ecs.ContainerDefinition, volumes []*ecs.Volume) (*ecs.RegisterTaskDefinitionOutput, error) { + + params := &ecs.RegisterTaskDefinitionInput{ + ContainerDefinitions: conDefs, + Family: aws.String(taskName), + Volumes: volumes, + } + + return self.service.RegisterTaskDefinition(params) +} + +func (self *EcsApi) DeregisterTaskDefinition(taskName string) (*ecs.DeregisterTaskDefinitionOutput, error) { + + params := &ecs.DeregisterTaskDefinitionInput{ + TaskDefinition: aws.String(taskName), + } + + return self.service.DeregisterTaskDefinition(params) +} + +func (self *EcsApi) ListTasks(cluster string, service string) (*ecs.ListTasksOutput, error) { + + params := &ecs.ListTasksInput{ + Cluster: aws.String(cluster), + ServiceName: aws.String(service), + } + + return self.service.ListTasks(params) +} + +func (self *EcsApi) DescribeTasks(cluster string, tasks []*string) (*ecs.DescribeTasksOutput, error) { + + params := &ecs.DescribeTasksInput{ + Cluster: aws.String(cluster), + Tasks: tasks, + } + + return self.service.DescribeTasks(params) +} diff --git a/aws/ecs_cluster_api.go b/aws/ecs_cluster_api.go deleted file mode 100644 index e65a310..0000000 --- a/aws/ecs_cluster_api.go +++ /dev/null @@ -1,82 +0,0 @@ -package aws - -import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/ecs" - "github.com/aws/aws-sdk-go/aws/credentials" -) - -type EcsClusterApi struct { - Credentials *credentials.Credentials - Region *string -} - -func (self *EcsClusterApi) CreateCluster(clusterName string) (*ecs.CreateClusterOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.CreateClusterInput{ - ClusterName: aws.String(clusterName), - } - - return svc.CreateCluster(params) -} - -func (self *EcsClusterApi) DeleteCluster(clusterName string) (*ecs.DeleteClusterOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.DeleteClusterInput{ - Cluster: aws.String(clusterName), - } - - return svc.DeleteCluster(params) -} - -func (self *EcsClusterApi) DescribeClusters(clusterNames []*string) (*ecs.DescribeClustersOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.DescribeClustersInput{ - Clusters: clusterNames, - } - - return svc.DescribeClusters(params) -} - -func (self *EcsClusterApi) ListClusters(maxResult int64) (*ecs.ListClustersOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.ListClustersInput{ - MaxResults: &maxResult, - } - - return svc.ListClusters(params) -} - -func (self *EcsClusterApi) ListContainerInstances(cluster string) (*ecs.ListContainerInstancesOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.ListContainerInstancesInput{ - Cluster: aws.String(cluster), - } - - return svc.ListContainerInstances(params) -} \ No newline at end of file diff --git a/aws/ecs_service_api.go b/aws/ecs_service_api.go deleted file mode 100644 index fc7d9cd..0000000 --- a/aws/ecs_service_api.go +++ /dev/null @@ -1,95 +0,0 @@ -package aws - -import ( - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/service/ecs" - "github.com/aws/aws-sdk-go/aws" -) - -type EcsServiceApi struct { - Credentials *credentials.Credentials - Region *string -} - -func (self *EcsServiceApi) CreateService(cluster string, service string, desiredCount int64, lb []*ecs.LoadBalancer, taskDef string, role string) (*ecs.CreateServiceOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.CreateServiceInput{ - ServiceName: aws.String(service), - Cluster: aws.String(cluster), - DesiredCount: &desiredCount, - LoadBalancers: lb, - TaskDefinition: aws.String(taskDef), - } - - if role != "" { - params.Role = aws.String(role) - } - - return svc.CreateService(params) -} - -func (self *EcsServiceApi) UpdateService(cluster string, service string, desiredCount int64, taskDef string) (*ecs.UpdateServiceOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.UpdateServiceInput{ - Cluster: aws.String(cluster), - Service: aws.String(service), - DesiredCount: &desiredCount, - TaskDefinition: aws.String(taskDef), - } - - return svc.UpdateService(params) -} - -func (self *EcsServiceApi) DescribeService(cluster string, services []*string) (*ecs.DescribeServicesOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.DescribeServicesInput{ - Cluster: aws.String(cluster), - Services: services, - } - - return svc.DescribeServices(params) -} - -func (self *EcsServiceApi) DeleteService(cluster string, service string) (*ecs.DeleteServiceOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.DeleteServiceInput{ - Cluster: aws.String(cluster), - Service: aws.String(service), - } - - return svc.DeleteService(params) -} - -func (self *EcsServiceApi) ListServices(cluster string) (*ecs.ListServicesOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.ListServicesInput{ - Cluster: aws.String(cluster), - } - - return svc.ListServices(params) -} \ No newline at end of file diff --git a/aws/ecs_task_api.go b/aws/ecs_task_api.go deleted file mode 100644 index 5494e9b..0000000 --- a/aws/ecs_task_api.go +++ /dev/null @@ -1,86 +0,0 @@ -package aws - -import ( - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/ecs" -) - -type EcsTaskApi struct { - Credentials *credentials.Credentials - Region *string -} - -func (self *EcsTaskApi) DescribeTaskDefinition(defName string) (*ecs.DescribeTaskDefinitionOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.DescribeTaskDefinitionInput{ - TaskDefinition: aws.String(defName), - } - - return svc.DescribeTaskDefinition(params) -} - -func (self *EcsTaskApi) RegisterTaskDefinition(taskName string, conDefs []*ecs.ContainerDefinition, volumes []*ecs.Volume) (*ecs.RegisterTaskDefinitionOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.RegisterTaskDefinitionInput{ - ContainerDefinitions: conDefs, - Family: aws.String(taskName), - Volumes: volumes, - } - - return svc.RegisterTaskDefinition(params) -} - -func (self *EcsTaskApi) DeregisterTaskDefinition(taskName string) (*ecs.DeregisterTaskDefinitionOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.DeregisterTaskDefinitionInput{ - TaskDefinition: aws.String(taskName), - } - - return svc.DeregisterTaskDefinition(params) -} - -func (self *EcsTaskApi) ListTasks(cluster string, service string) (*ecs.ListTasksOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.ListTasksInput{ - Cluster: aws.String(cluster), - ServiceName: aws.String(service), - } - - return svc.ListTasks(params) -} - -func (self *EcsTaskApi) DescribeTasks(cluster string, tasks []*string) (*ecs.DescribeTasksOutput, error) { - - svc := ecs.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - - params := &ecs.DescribeTasksInput{ - Cluster: aws.String(cluster), - Tasks: tasks, - } - - return svc.DescribeTasks(params) -} \ No newline at end of file diff --git a/aws/elb_api.go b/aws/elb_api.go index 4aa6dd5..2b1caab 100644 --- a/aws/elb_api.go +++ b/aws/elb_api.go @@ -1,57 +1,40 @@ package aws import ( - "github.com/aws/aws-sdk-go/service/elb" - "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/elb" "github.com/stormcat24/ecs-formation/util" ) type ElbApi struct { - Credentials *credentials.Credentials - Region *string + service *elb.ELB } func (self *ElbApi) DescribeLoadBalancers(names []string) (*elb.DescribeLoadBalancersOutput, error) { - svc := elb.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - params := &elb.DescribeLoadBalancersInput{ LoadBalancerNames: util.ConvertPointerString(names), } - return svc.DescribeLoadBalancers(params) + return self.service.DescribeLoadBalancers(params) } func (self *ElbApi) RegisterInstancesWithLoadBalancer(name string, instances []*elb.Instance) (*elb.RegisterInstancesWithLoadBalancerOutput, error) { - svc := elb.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - params := &elb.RegisterInstancesWithLoadBalancerInput{ LoadBalancerName: aws.String(name), - Instances: instances, + Instances: instances, } - return svc.RegisterInstancesWithLoadBalancer(params) + return self.service.RegisterInstancesWithLoadBalancer(params) } func (self *ElbApi) DeregisterInstancesFromLoadBalancer(lb string, instances []*elb.Instance) (*elb.DeregisterInstancesFromLoadBalancerOutput, error) { - svc := elb.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - params := &elb.DeregisterInstancesFromLoadBalancerInput{ LoadBalancerName: aws.String(lb), - Instances: instances, + Instances: instances, } - return svc.DeregisterInstancesFromLoadBalancer(params) -} \ No newline at end of file + return self.service.DeregisterInstancesFromLoadBalancer(params) +} diff --git a/aws/sns_api.go b/aws/sns_api.go index dfa6930..7005b69 100644 --- a/aws/sns_api.go +++ b/aws/sns_api.go @@ -1,18 +1,15 @@ package aws import ( - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/service/sns" - "github.com/aws/aws-sdk-go/aws" "encoding/json" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/sns" ) type SnsApi struct { - Credentials *credentials.Credentials - Region *string + service *sns.SNS } - func (self *SnsApi) Publish(topicArn string, message interface{}) (*sns.PublishOutput, error) { data, err := json.Marshal(&message) @@ -20,16 +17,11 @@ func (self *SnsApi) Publish(topicArn string, message interface{}) (*sns.PublishO return &sns.PublishOutput{}, err } - svc := sns.New(&aws.Config{ - Region: self.Region, - Credentials: self.Credentials, - }) - params := &sns.PublishInput{ - TopicArn: aws.String(topicArn), - Message: aws.String(string(data)), + TopicArn: aws.String(topicArn), + Message: aws.String(string(data)), MessageStructure: aws.String("json"), } - return svc.Publish(params) -} \ No newline at end of file + return self.service.Publish(params) +} diff --git a/bluegreen/bluegreen.go b/bluegreen/bluegreen.go index 86062ae..d8a56a0 100644 --- a/bluegreen/bluegreen.go +++ b/bluegreen/bluegreen.go @@ -1,38 +1,38 @@ package bluegreen import ( - "io/ioutil" - "github.com/stormcat24/ecs-formation/aws" - "strings" - "time" - "fmt" "errors" - "github.com/stormcat24/ecs-formation/service" + "fmt" + "github.com/stormcat24/ecs-formation/aws" "github.com/stormcat24/ecs-formation/logger" + "github.com/stormcat24/ecs-formation/service" "github.com/str1ngs/ansi/color" - "regexp" "gopkg.in/yaml.v2" + "io/ioutil" + "regexp" + "strings" + "time" ) type BlueGreenController struct { - Ecs *aws.AwsManager + manager *aws.AwsManager ClusterController *service.ServiceController blueGreenMap map[string]*BlueGreen TargetResource string } -func NewBlueGreenController(ecs *aws.AwsManager, projectDir string, targetResource string) (*BlueGreenController, error) { +func NewBlueGreenController(manager *aws.AwsManager, projectDir string, targetResource string) (*BlueGreenController, error) { - ccon, errcc := service.NewServiceController(ecs, projectDir, "") + ccon, errcc := service.NewServiceController(manager, projectDir, "") if errcc != nil { return nil, errcc } con := &BlueGreenController{ - Ecs: ecs, + manager: manager, ClusterController: ccon, - TargetResource: targetResource, + TargetResource: targetResource, } defs, errs := con.searchBlueGreen(projectDir) @@ -81,7 +81,6 @@ func CreateBlueGreen(data []byte) (*BlueGreen, error) { return bg, err } - func (self *BlueGreenController) GetBlueGreenMap() map[string]*BlueGreen { return self.blueGreenMap } @@ -149,11 +148,13 @@ func (self *BlueGreenController) CreateBlueGreenPlan(bluegreen *BlueGreen, cplan }, PrimaryElb: bluegreen.PrimaryElb, StandbyElb: bluegreen.StandbyElb, - ChainElb: bluegreen.ChainElb, + ChainElb: bluegreen.ChainElb, } // describe services - bsrv, _ := self.Ecs.ServiceApi().DescribeService(blue.Cluster, []*string{ + apiecs := self.manager.EcsApi() + apias := self.manager.AutoscalingApi() + bsrv, _ := apiecs.DescribeService(blue.Cluster, []*string{ &blue.Service, }) @@ -162,7 +163,7 @@ func (self *BlueGreenController) CreateBlueGreenPlan(bluegreen *BlueGreen, cplan bgPlan.Blue.CurrentService = bsrv.Services[0] } - gsrv, _ := self.Ecs.ServiceApi().DescribeService(green.Cluster, []*string{ + gsrv, _ := apiecs.DescribeService(green.Cluster, []*string{ &green.Service, }) @@ -172,7 +173,7 @@ func (self *BlueGreenController) CreateBlueGreenPlan(bluegreen *BlueGreen, cplan } // describe autoscaling group - asgmap, err := self.Ecs.AutoscalingApi().DescribeAutoScalingGroups([]string{ + asgmap, err := apias.DescribeAutoScalingGroups([]string{ blue.AutoscalingGroup, green.AutoscalingGroup, }) @@ -192,7 +193,6 @@ func (self *BlueGreenController) CreateBlueGreenPlan(bluegreen *BlueGreen, cplan return &bgPlan, nil } - func (self *BlueGreenController) ApplyBlueGreenDeploys(plans []*BlueGreenPlan, nodeploy bool) error { for _, plan := range plans { @@ -206,7 +206,7 @@ func (self *BlueGreenController) ApplyBlueGreenDeploys(plans []*BlueGreenPlan, n func (self *BlueGreenController) ApplyBlueGreenDeploy(bgplan *BlueGreenPlan, nodeploy bool) error { - apias := self.Ecs.AutoscalingApi() + apias := self.manager.AutoscalingApi() targetGreen := bgplan.IsBlueWithPrimaryElb() @@ -289,12 +289,12 @@ func (self *BlueGreenController) ApplyBlueGreenDeploy(bgplan *BlueGreenPlan, nod func (self *BlueGreenController) waitLoadBalancer(group string, lb string) error { - api := self.Ecs.AutoscalingApi() + apias := self.manager.AutoscalingApi() for { time.Sleep(5 * time.Second) - result, err := api.DescribeLoadBalancerState(group) + result, err := apias.DescribeLoadBalancerState(group) if err != nil { return err @@ -319,4 +319,4 @@ func (self *BlueGreenController) waitLoadBalancer(group string, lb string) error return nil -} \ No newline at end of file +} diff --git a/config/config.go b/config/config.go index 5a29ab0..81f8a7e 100644 --- a/config/config.go +++ b/config/config.go @@ -2,6 +2,7 @@ package config import ( "github.com/codegangsta/cli" + "github.com/stormcat24/ecs-formation/logger" ) var ( @@ -9,14 +10,18 @@ var ( ) type ApplicationConfig struct { - SnsTopic string + SnsTopic string + RetryCount int } func PrepareGlobalOptions(c *cli.Context) error { AppConfig = &ApplicationConfig{ - SnsTopic: c.GlobalString("sns-topic"), + SnsTopic: c.GlobalString("sns-topic"), + RetryCount: c.GlobalInt("retry-count"), } + logger.Main.Infof("retry-count=%d", AppConfig.RetryCount) + return nil -} \ No newline at end of file +} diff --git a/main.go b/main.go index c3584b1..8dfb5f0 100644 --- a/main.go +++ b/main.go @@ -1,10 +1,10 @@ package main import ( - "github.com/stormcat24/ecs-formation/operation" "github.com/codegangsta/cli" - "os" "github.com/stormcat24/ecs-formation/config" + "github.com/stormcat24/ecs-formation/operation" + "os" ) func main() { @@ -18,10 +18,15 @@ func main() { app.Commands = operation.Commands app.Flags = []cli.Flag{ cli.StringFlag{ - Name: "sns-topic, s", - Usage: "AWS SNS Topic Name", + Name: "sns-topic, s", + Usage: "AWS SNS Topic Name", EnvVar: "ECSF_SNS_TOPIC", }, + cli.IntFlag{ + Name: "retry-count, r", + Usage: "AWS API Max Retry Count", + EnvVar: "ECSF_RETRY_COUNT", + }, } app.Before = config.PrepareGlobalOptions diff --git a/service/service.go b/service/service.go index db16fff..dd9077a 100644 --- a/service/service.go +++ b/service/service.go @@ -1,18 +1,18 @@ package service import ( - "io/ioutil" + "errors" "fmt" - "strings" - "regexp" - "github.com/stormcat24/ecs-formation/aws" - "os" - "github.com/str1ngs/ansi/color" "github.com/aws/aws-sdk-go/service/ecs" + "github.com/stormcat24/ecs-formation/aws" "github.com/stormcat24/ecs-formation/logger" - "time" - "errors" "github.com/stormcat24/ecs-formation/util" + "github.com/str1ngs/ansi/color" + "io/ioutil" + "os" + "regexp" + "strings" + "time" ) type TaskWatchStatus int @@ -24,15 +24,15 @@ const ( ) type ServiceController struct { - Ecs *aws.AwsManager + manager *aws.AwsManager TargetResource string clusters []Cluster } -func NewServiceController(ecs *aws.AwsManager, projectDir string, targetResource string) (*ServiceController, error) { +func NewServiceController(manager *aws.AwsManager, projectDir string, targetResource string) (*ServiceController, error) { con := &ServiceController{ - Ecs: ecs, + manager: manager, } clusters, err := con.searchServices(projectDir) @@ -71,7 +71,7 @@ func (self *ServiceController) searchServices(projectDir string) ([]Cluster, err serviceMap, _ := CreateServiceMap(content) cluster := Cluster{ - Name: clusterName, + Name: clusterName, Services: serviceMap, } @@ -106,8 +106,8 @@ func (self *ServiceController) CreateServiceUpdatePlans() ([]*ServiceUpdatePlan, func (self *ServiceController) CreateServiceUpdatePlan(cluster Cluster) (*ServiceUpdatePlan, error) { - clusterApi := self.Ecs.ClusterApi() - output, errdc := clusterApi.DescribeClusters([]*string{&cluster.Name}) + api := self.manager.EcsApi() + output, errdc := api.DescribeClusters([]*string{&cluster.Name}) if errdc != nil { return nil, errdc @@ -117,7 +117,7 @@ func (self *ServiceController) CreateServiceUpdatePlan(cluster Cluster) (*Servic return nil, errors.New(fmt.Sprintf("Cluster '%s' not found", cluster.Name)) } - rlci, errlci := clusterApi.ListContainerInstances(cluster.Name) + rlci, errlci := api.ListContainerInstances(cluster.Name) if errlci != nil { return nil, errlci } @@ -133,16 +133,14 @@ func (self *ServiceController) CreateServiceUpdatePlan(cluster Cluster) (*Servic return &ServiceUpdatePlan{}, errors.New(fmt.Sprintf("Cluster '%s' is not ACTIVE.", cluster.Name)) } - serviceApi := self.Ecs.ServiceApi() - - resListServices, errls := serviceApi.ListServices(cluster.Name) + resListServices, errls := api.ListServices(cluster.Name) if errls != nil { return &ServiceUpdatePlan{}, errls } currentServices := map[string]*ecs.Service{} if len(resListServices.ServiceArns) > 0 { - resDescribeService, errds := serviceApi.DescribeService(cluster.Name, resListServices.ServiceArns) + resDescribeService, errds := api.DescribeService(cluster.Name, resListServices.ServiceArns) if errds != nil { return &ServiceUpdatePlan{}, errds } @@ -159,10 +157,10 @@ func (self *ServiceController) CreateServiceUpdatePlan(cluster Cluster) (*Servic } return &ServiceUpdatePlan{ - Name: cluster.Name, - InstanceARNs: rlci.ContainerInstanceArns, + Name: cluster.Name, + InstanceARNs: rlci.ContainerInstanceArns, CurrentServices: currentServices, - NewServices: newServices, + NewServices: newServices, }, nil } } @@ -181,7 +179,7 @@ func (self *ServiceController) ApplyServicePlans(plans []*ServiceUpdatePlan) { func (self *ServiceController) ApplyServicePlan(plan *ServiceUpdatePlan) error { - api := self.Ecs.ServiceApi() + api := self.manager.EcsApi() for _, current := range plan.CurrentServices { @@ -197,7 +195,6 @@ func (self *ServiceController) ApplyServicePlan(plan *ServiceUpdatePlan) error { } logger.Main.Infof("Stoped '%s' service on '%s'.", *current.ServiceName, plan.Name) - // delete service result, err := api.DeleteService(plan.Name, *current.ServiceArn) if err != nil { @@ -234,18 +231,17 @@ func toLoadBalancers(values *[]LoadBalancer) []*ecs.LoadBalancer { for _, lb := range *values { loadBalancers = append(loadBalancers, &ecs.LoadBalancer{ LoadBalancerName: &lb.Name, - ContainerName: &lb.ContainerName, - ContainerPort: &lb.ContainerPort, + ContainerName: &lb.ContainerName, + ContainerPort: &lb.ContainerPort, }) } return loadBalancers } - func (self *ServiceController) waitStoppingService(cluster string, service string) error { - api := self.Ecs.ServiceApi() + api := self.manager.EcsApi() for { time.Sleep(5 * time.Second) @@ -272,8 +268,7 @@ func (self *ServiceController) waitStoppingService(cluster string, service strin func (self *ServiceController) WaitActiveService(cluster string, service string) error { - api := self.Ecs.ServiceApi() - taskApi := self.Ecs.TaskApi() + api := self.manager.EcsApi() var flag = false var taskARNs []*string @@ -298,12 +293,12 @@ func (self *ServiceController) WaitActiveService(cluster string, service string) if *target.Status == "ACTIVE" { - if len(target.Events) > 0 && strings.Contains(*target.Events[0].Message, "was unable to place a task"){ + if len(target.Events) > 0 && strings.Contains(*target.Events[0].Message, "was unable to place a task") { return errors.New(*target.Events[0].Message) } if !flag { - reslt, errlt := taskApi.ListTasks(cluster, service) + reslt, errlt := api.ListTasks(cluster, service) if errlt != nil { return errlt } @@ -316,12 +311,11 @@ func (self *ServiceController) WaitActiveService(cluster string, service string) } } - resdt, errdt := taskApi.DescribeTasks(cluster, taskARNs) + resdt, errdt := api.DescribeTasks(cluster, taskARNs) if errdt != nil { return errdt } - watchStatus := self.checkRunningTask(resdt) if watchStatus == WatchFinish { logger.Main.Info("At least one of task has started successfully.") diff --git a/task/task.go b/task/task.go index 55252b9..9cb1465 100644 --- a/task/task.go +++ b/task/task.go @@ -1,28 +1,28 @@ package task import ( - "io/ioutil" - "strings" - "regexp" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ecs" efaws "github.com/stormcat24/ecs-formation/aws" "github.com/stormcat24/ecs-formation/logger" - "github.com/aws/aws-sdk-go/service/ecs" - "time" - "github.com/aws/aws-sdk-go/aws" "github.com/stormcat24/ecs-formation/util" "github.com/str1ngs/ansi/color" + "io/ioutil" + "regexp" + "strings" + "time" ) type TaskDefinitionController struct { - Ecs *efaws.AwsManager + manager *efaws.AwsManager TargetResource string defmap map[string]*TaskDefinition } -func NewTaskDefinitionController(ecs *efaws.AwsManager, projectDir string, targetResource string) (*TaskDefinitionController, error) { +func NewTaskDefinitionController(manager *efaws.AwsManager, projectDir string, targetResource string) (*TaskDefinitionController, error) { con := &TaskDefinitionController{ - Ecs: ecs, + manager: manager, } defmap, err := con.searchTaskDefinitions(projectDir) @@ -92,7 +92,7 @@ func (self *TaskDefinitionController) CreateTaskUpdatePlan(task *TaskDefinition) } return &TaskUpdatePlan{ - Name: task.Name, + Name: task.Name, NewContainers: newContainers, } } @@ -131,7 +131,7 @@ func (self *TaskDefinitionController) ApplyTaskDefinitionPlan(task *TaskUpdatePl for _, con := range containers { var commands []*string - if (len(con.Command) > 0) { + if len(con.Command) > 0 { for _, token := range strings.Split(con.Command, " ") { commands = append(commands, aws.String(token)) } @@ -140,7 +140,7 @@ func (self *TaskDefinitionController) ApplyTaskDefinitionPlan(task *TaskUpdatePl } var entryPoints []*string - if (len(con.EntryPoint) > 0) { + if len(con.EntryPoint) > 0 { for _, token := range strings.Split(con.EntryPoint, " ") { entryPoints = append(entryPoints, aws.String(token)) } @@ -171,22 +171,22 @@ func (self *TaskDefinitionController) ApplyTaskDefinitionPlan(task *TaskUpdatePl } conDef := &ecs.ContainerDefinition{ - Cpu: &con.CpuUnits, - Command: commands, - EntryPoint: entryPoints, - Environment: toKeyValuePairs(con.Environment), - Essential: &con.Essential, - Image: aws.String(con.Image), - Links: util.ConvertPointerString(con.Links), - Memory: &con.Memory, - MountPoints: mountPoints, - Name: aws.String(con.Name), + Cpu: &con.CpuUnits, + Command: commands, + EntryPoint: entryPoints, + Environment: toKeyValuePairs(con.Environment), + Essential: &con.Essential, + Image: aws.String(con.Image), + Links: util.ConvertPointerString(con.Links), + Memory: &con.Memory, + MountPoints: mountPoints, + Name: aws.String(con.Name), PortMappings: portMappings, - VolumesFrom: volumesFrom, + VolumesFrom: volumesFrom, } conDefs = append(conDefs, conDef) } - return self.Ecs.TaskApi().RegisterTaskDefinition(task.Name, conDefs, volumes) + return self.manager.EcsApi().RegisterTaskDefinition(task.Name, conDefs, volumes) }