Skip to content

Commit

Permalink
Merge pull request #121 from openfresh/feature/task_placement_policy
Browse files Browse the repository at this point in the history
support task placement policy
  • Loading branch information
stormcat24 authored Apr 24, 2017
2 parents 530ccfd + 057e773 commit 1f77ad2
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 62 deletions.
34 changes: 17 additions & 17 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions cmd/service/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,24 @@ func createClusterPlans(srv service.ClusterService) ([]*types.ServiceUpdatePlan,
util.PrintlnYellow(" RoleARN = %s", *asg.RoleARN)
}

if len(cs.PlacementStrategy) > 0 {
util.PrintlnYellow(" PlacementStrategy:")
}
for _, ps := range cs.PlacementStrategy {
util.PrintlnYellow(" -")
util.PrintlnYellow(" Type = %s", *ps.Type)
util.PrintlnYellow(" Field = %s", *ps.Field)
}

if len(cs.PlacementConstraints) > 0 {
util.PrintlnYellow(" PlacementConstraints:")
}
for _, pc := range cs.PlacementConstraints {
util.PrintlnYellow(" -")
util.PrintlnYellow(" Type = %s", *pc.Type)
util.PrintlnYellow(" Field = %s", *pc.Expression)
}

util.Println()
}

Expand Down Expand Up @@ -182,13 +200,32 @@ func createClusterPlans(srv service.ClusterService) ([]*types.ServiceUpdatePlan,
util.PrintlnYellow(" ContainerName:%v", lb.ContainerName)
util.PrintlnYellow(" ContainerPort:%v", lb.ContainerPort)
}

if add.AutoScaling != nil && add.AutoScaling.Target != nil {
asg := add.AutoScaling.Target
util.PrintlnYellow(" AutoScaling:")
util.PrintlnYellow(" MinCapacity = %v", asg.MinCapacity)
util.PrintlnYellow(" MaxCapacity = %v", asg.MaxCapacity)
util.PrintlnYellow(" RoleARN = %s", asg.Role)
}

if len(add.PlacementStrategy) > 0 {
for _, ps := range add.PlacementStrategy {
util.PrintlnYellow(" PlacementStrategy:")
util.PrintlnYellow(" -")
util.PrintlnYellow(" Type = %v", ps.Type)
util.PrintlnYellow(" Field = %v", ps.Field)
}
}

if len(add.PlacementConstraints) > 0 {
for _, pc := range add.PlacementConstraints {
util.PrintlnYellow(" PlacementConstraints:")
util.PrintlnYellow(" -")
util.PrintlnYellow(" Type = %v", pc.Type)
util.PrintlnYellow(" Expression = %v", pc.Expression)
}
}
util.Println()
}

Expand Down
76 changes: 39 additions & 37 deletions service/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,56 +147,57 @@ func (s ConcreteClusterService) createServiceUpdatePlan(cluster types.Cluster) (
if len(lciResult.ContainerInstanceArns) == 0 {
logger.Main.Warnf("ECS instances not found in cluster '%s' not found", cluster.Name)
return nil, nil
} else {
target := output.Clusters[0]
}

if *target.Status != "ACTIVE" {
return nil, fmt.Errorf("Cluster '%s' is not ACTIVE.", cluster.Name)
}
target := output.Clusters[0]

if *target.Status != "ACTIVE" {
return nil, fmt.Errorf("Cluster '%s' is not ACTIVE.", cluster.Name)
}

lsResult, err := s.ecsCli.ListServices(cluster.Name)
if err != nil {
return nil, err
}

currentStacks := map[string]*types.ServiceStack{}
if len(lsResult.ServiceArns) > 0 {

lsResult, err := s.ecsCli.ListServices(cluster.Name)
resDescribeService, err := s.ecsCli.DescribeService(cluster.Name, lsResult.ServiceArns)
if err != nil {
return nil, err
}

currentStacks := map[string]*types.ServiceStack{}
if len(lsResult.ServiceArns) > 0 {
for _, service := range resDescribeService.Services {
if s.targetService == "" || (s.targetService != "" && s.targetService == *service.ServiceName) {

resDescribeService, errds := s.ecsCli.DescribeService(cluster.Name, lsResult.ServiceArns)
if errds != nil {
return nil, errds
}

for _, service := range resDescribeService.Services {
if s.targetService == "" || (s.targetService != "" && s.targetService == *service.ServiceName) {
autoScaling, err := s.appAutoscalingCli.DescribeScalableTarget(cluster.Name, *service.ServiceName)
if err != nil {
return nil, err
}
autoScaling, err := s.appAutoscalingCli.DescribeScalableTarget(cluster.Name, *service.ServiceName)
if err != nil {
return nil, err
}

currentStacks[*service.ServiceName] = &types.ServiceStack{
Service: service,
AutoScaling: autoScaling,
}
currentStacks[*service.ServiceName] = &types.ServiceStack{
Service: service,
AutoScaling: autoScaling,
}
}
}
}

newServices := map[string]*types.Service{}
for name, newService := range cluster.Services {
if s.targetService == "" || (s.targetService != "" && s.targetService == newService.Name) {
s := newService
newServices[name] = &s
}
newServices := map[string]*types.Service{}
for name, newService := range cluster.Services {
if s.targetService == "" || (s.targetService != "" && s.targetService == newService.Name) {
s := newService
newServices[name] = &s
}

return &types.ServiceUpdatePlan{
Name: cluster.Name,
InstanceARNs: lciResult.ContainerInstanceArns,
CurrentServices: currentStacks,
NewServices: newServices,
}, nil
}

return &types.ServiceUpdatePlan{
Name: cluster.Name,
InstanceARNs: lciResult.ContainerInstanceArns,
CurrentServices: currentStacks,
NewServices: newServices,
}, nil
}

func (s ConcreteClusterService) ApplyServicePlans(plans []*types.ServiceUpdatePlan) error {
Expand Down Expand Up @@ -274,6 +275,8 @@ func (s ConcreteClusterService) ApplyServicePlan(plan *types.ServiceUpdatePlan)
MaximumPercent: aws.Int64(add.MaximumPercent.Int64),
}
}
p.PlacementConstraints = types.ToPlacementConstraints(add.PlacementConstraints)
p.PlacementStrategy = types.ToPlacementStrategy(add.PlacementStrategy)

csrv, err := s.ecsCli.CreateService(&p)
if err != nil {
Expand Down Expand Up @@ -540,7 +543,6 @@ func toLoadBalancersNew(values []types.LoadBalancer) []*awsecs.LoadBalancer {

loadBalancers = append(loadBalancers, &addElb)
}
fmt.Println(loadBalancers)

return loadBalancers
}
28 changes: 20 additions & 8 deletions service/types/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ type Cluster struct {

type Service struct {
Name string
TaskDefinition string `yaml:"task_definition"`
DesiredCount int64 `yaml:"desired_count"`
KeepDesiredCount bool `yaml:"keep_desired_count"`
LoadBalancers []LoadBalancer `yaml:"load_balancers"`
MinimumHealthyPercent null.Int `yaml:"minimum_healthy_percent"`
MaximumPercent null.Int `yaml:"maximum_percent"`
Role string `yaml:"role"`
AutoScaling *AutoScaling `yaml:"autoscaling"`
TaskDefinition string `yaml:"task_definition"`
DesiredCount int64 `yaml:"desired_count"`
KeepDesiredCount bool `yaml:"keep_desired_count"`
LoadBalancers []LoadBalancer `yaml:"load_balancers"`
MinimumHealthyPercent null.Int `yaml:"minimum_healthy_percent"`
MaximumPercent null.Int `yaml:"maximum_percent"`
Role string `yaml:"role"`
AutoScaling *AutoScaling `yaml:"autoscaling"`
PlacementConstraints []PlacementConstraint `yaml:"placement_constraints"`
PlacementStrategy []PlacementStrategy `yaml:"placement_strategy"`
}

type LoadBalancer struct {
Expand Down Expand Up @@ -59,3 +61,13 @@ type ServiceScalableTarget struct {
MaxCapacity uint `yaml:"max_capacity"`
Role string `yaml:"role"`
}

type PlacementConstraint struct {
Expression string `yaml:"expression"`
Type string `yaml:"type"`
}

type PlacementStrategy struct {
Field string `yaml:"field"`
Type string `yaml:"type"`
}
30 changes: 30 additions & 0 deletions service/types/placement.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package types

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ecs"
)

func ToPlacementConstraints(placementConstraints []PlacementConstraint) []*ecs.PlacementConstraint {

slice := make([]*ecs.PlacementConstraint, len(placementConstraints))
for i, pc := range placementConstraints {
slice[i] = &ecs.PlacementConstraint{
Expression: aws.String(pc.Expression),
Type: aws.String(pc.Type),
}
}
return slice
}

func ToPlacementStrategy(placementStrategy []PlacementStrategy) []*ecs.PlacementStrategy {

slice := make([]*ecs.PlacementStrategy, len(placementStrategy))
for i, pc := range placementStrategy {
slice[i] = &ecs.PlacementStrategy{
Field: aws.String(pc.Field),
Type: aws.String(pc.Type),
}
}
return slice
}

0 comments on commit 1f77ad2

Please sign in to comment.