Ver Fonte

Implement `ps` without need for the original compose.yaml file

close #165

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof há 5 anos atrás
pai
commit
37b9e74308

+ 15 - 7
ecs/pkg/amazon/backend/down.go

@@ -9,13 +9,9 @@ import (
 )
 
 func (b *Backend) Down(ctx context.Context, options cli.ProjectOptions) error {
-	name := options.Name
-	if name == "" {
-		project, err := cli.ProjectFromOptions(&options)
-		if err != nil {
-			return err
-		}
-		name = project.Name
+	name, err2 := b.projectName(options)
+	if err2 != nil {
+		return err2
 	}
 
 	err := b.api.DeleteStack(ctx, name)
@@ -30,3 +26,15 @@ func (b *Backend) Down(ctx context.Context, options cli.ProjectOptions) error {
 	}
 	return nil
 }
+
+func (b *Backend) projectName(options cli.ProjectOptions) (string, error) {
+	name := options.Name
+	if name == "" {
+		project, err := cli.ProjectFromOptions(&options)
+		if err != nil {
+			return "", err
+		}
+		name = project.Name
+	}
+	return name, nil
+}

+ 20 - 15
ecs/pkg/amazon/backend/list.go

@@ -3,33 +3,34 @@ package backend
 import (
 	"context"
 	"fmt"
+	"regexp"
+	"strings"
 
 	"github.com/compose-spec/compose-go/cli"
 	"github.com/docker/ecs-plugin/pkg/compose"
 )
 
-func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose.ServiceStatus, error) {
-	project, err := cli.ProjectFromOptions(&options)
-	if err != nil {
-		return nil, err
-	}
+var targetGroupLogicalName = regexp.MustCompile("(.*)(TCP|UDP)([0-9]+)TargetGroup")
 
-	resources, err := b.api.ListStackResources(ctx, project.Name)
+func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose.ServiceStatus, error) {
+	projectName, err := b.projectName(options)
 	if err != nil {
 		return nil, err
 	}
-
-	loadBalancer, err := b.GetLoadBalancer(ctx, project)
+	parameters, err := b.api.ListStackParameters(ctx, projectName)
 	if err != nil {
 		return nil, err
 	}
+	loadBalancer := parameters[ParameterLoadBalancerARN]
+	cluster := parameters[ParameterClusterName]
 
-	cluster, err := b.GetCluster(ctx, project)
+	resources, err := b.api.ListStackResources(ctx, projectName)
 	if err != nil {
 		return nil, err
 	}
 
 	servicesARN := []string{}
+	targetGroups := []string{}
 	for _, r := range resources {
 		switch r.Type {
 		case "AWS::ECS::Service":
@@ -38,9 +39,14 @@ func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose
 			cluster = r.ARN
 		case "AWS::ElasticLoadBalancingV2::LoadBalancer":
 			loadBalancer = r.ARN
+		case "AWS::ElasticLoadBalancingV2::TargetGroup":
+			targetGroups = append(targetGroups, r.LogicalID)
 		}
 	}
 
+	if len(servicesARN) == 0 {
+		return nil, nil
+	}
 	status, err := b.api.DescribeServices(ctx, cluster, servicesARN)
 	if err != nil {
 		return nil, err
@@ -52,13 +58,12 @@ func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose
 	}
 
 	for i, state := range status {
-		s, err := project.GetService(state.Name)
-		if err != nil {
-			return nil, err
-		}
 		ports := []string{}
-		for _, p := range s.Ports {
-			ports = append(ports, fmt.Sprintf("%s:%d->%d/%s", url, p.Published, p.Target, p.Protocol))
+		for _, tg := range targetGroups {
+			groups := targetGroupLogicalName.FindStringSubmatch(tg)
+			if groups[0] == state.Name {
+				ports = append(ports, fmt.Sprintf("%s:%s->%s/%s", url, groups[2], groups[2], strings.ToLower(groups[1])))
+			}
 		}
 		state.Ports = ports
 		status[i] = state

+ 1 - 0
ecs/pkg/amazon/sdk/api.go

@@ -18,6 +18,7 @@ type API interface {
 	StackExists(ctx context.Context, name string) (bool, error)
 	CreateStack(ctx context.Context, name string, template *cloudformation.Template, parameters map[string]string) error
 	DeleteStack(ctx context.Context, name string) error
+	ListStackParameters(ctx context.Context, name string) (map[string]string, error)
 	ListStackResources(ctx context.Context, name string) ([]compose.StackResource, error)
 	GetStackID(ctx context.Context, name string) (string, error)
 	WaitStackComplete(ctx context.Context, name string, operation int) error

+ 15 - 0
ecs/pkg/amazon/sdk/sdk.go

@@ -238,6 +238,21 @@ func (s sdk) DescribeStackEvents(ctx context.Context, stackID string) ([]*cloudf
 	}
 }
 
+func (s sdk) ListStackParameters(ctx context.Context, name string) (map[string]string, error) {
+	st, err := s.CF.DescribeStacksWithContext(ctx, &cloudformation.DescribeStacksInput{
+		NextToken: nil,
+		StackName: aws.String(name),
+	})
+	if err != nil {
+		return nil, err
+	}
+	parameters := map[string]string{}
+	for _, parameter := range st.Stacks[0].Parameters {
+		parameters[*parameter.ParameterKey] = *parameter.ParameterValue
+	}
+	return parameters, nil
+}
+
 func (s sdk) ListStackResources(ctx context.Context, name string) ([]compose.StackResource, error) {
 	// FIXME handle pagination
 	res, err := s.CF.ListStackResourcesWithContext(ctx, &cloudformation.ListStackResourcesInput{