Przeglądaj źródła

generic URL/port/protocol retrieval for compose ps

Signed-off-by: aiordache <[email protected]>
Signed-off-by: Nicolas De Loof <[email protected]>
aiordache 5 lat temu
rodzic
commit
12215130b5

+ 1 - 1
ecs/cmd/commands/compose.go

@@ -91,7 +91,7 @@ func PsCommand(dockerCli command.Cli, options *cli.ProjectOptions) *cobra.Comman
 			}
 			}
 			printSection(os.Stdout, len(status), func(w io.Writer) {
 			printSection(os.Stdout, len(status), func(w io.Writer) {
 				for _, service := range status {
 				for _, service := range status {
-					fmt.Fprintf(w, "%s\t%s\t%d/%d\t%s\n", service.ID, service.Name, service.Replicas, service.Desired, strings.Join(service.Ports, " "))
+					fmt.Fprintf(w, "%s\t%s\t%d/%d\t%s\n", service.ID, service.Name, service.Replicas, service.Desired, strings.Join(service.Ports, ", "))
 				}
 				}
 			}, "ID", "NAME", "REPLICAS", "PORTS")
 			}, "ID", "NAME", "REPLICAS", "PORTS")
 			return nil
 			return nil

+ 7 - 17
ecs/pkg/amazon/backend/list.go

@@ -21,7 +21,6 @@ func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	loadBalancer := parameters[ParameterLoadBalancerARN]
 	cluster := parameters[ParameterClusterName]
 	cluster := parameters[ParameterClusterName]
 
 
 	resources, err := b.api.ListStackResources(ctx, projectName)
 	resources, err := b.api.ListStackResources(ctx, projectName)
@@ -30,20 +29,14 @@ func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose
 	}
 	}
 
 
 	servicesARN := []string{}
 	servicesARN := []string{}
-	targetGroups := []string{}
 	for _, r := range resources {
 	for _, r := range resources {
 		switch r.Type {
 		switch r.Type {
 		case "AWS::ECS::Service":
 		case "AWS::ECS::Service":
 			servicesARN = append(servicesARN, r.ARN)
 			servicesARN = append(servicesARN, r.ARN)
 		case "AWS::ECS::Cluster":
 		case "AWS::ECS::Cluster":
 			cluster = r.ARN
 			cluster = r.ARN
-		case "AWS::ElasticLoadBalancingV2::LoadBalancer":
-			loadBalancer = r.ARN
-		case "AWS::ElasticLoadBalancingV2::TargetGroup":
-			targetGroups = append(targetGroups, r.LogicalID)
 		}
 		}
 	}
 	}
-
 	if len(servicesARN) == 0 {
 	if len(servicesARN) == 0 {
 		return nil, nil
 		return nil, nil
 	}
 	}
@@ -52,18 +45,15 @@ func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	url, err := b.api.GetLoadBalancerURL(ctx, loadBalancer)
-	if err != nil {
-		return nil, err
-	}
-
 	for i, state := range status {
 	for i, state := range status {
 		ports := []string{}
 		ports := []string{}
-		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])))
-			}
+		for _, lb := range state.LoadBalancers {
+			ports = append(ports, fmt.Sprintf(
+				"%s:%d->%d/%s",
+				lb.URL,
+				lb.PublishedPort,
+				lb.TargetPort,
+				strings.ToLower(lb.Protocol)))
 		}
 		}
 		state.Ports = ports
 		state.Ports = ports
 		status[i] = state
 		status[i] = state

+ 65 - 5
ecs/pkg/amazon/sdk/sdk.go

@@ -449,6 +449,7 @@ func (s sdk) DescribeServices(ctx context.Context, cluster string, arns []string
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
+
 	status := []compose.ServiceStatus{}
 	status := []compose.ServiceStatus{}
 	for _, service := range services.Services {
 	for _, service := range services.Services {
 		var name string
 		var name string
@@ -460,17 +461,76 @@ func (s sdk) DescribeServices(ctx context.Context, cluster string, arns []string
 		if name == "" {
 		if name == "" {
 			return nil, fmt.Errorf("service %s doesn't have a %s tag", *service.ServiceArn, compose.ServiceTag)
 			return nil, fmt.Errorf("service %s doesn't have a %s tag", *service.ServiceArn, compose.ServiceTag)
 		}
 		}
+		targetGroupArns := []string{}
+		for _, lb := range service.LoadBalancers {
+			targetGroupArns = append(targetGroupArns, *lb.TargetGroupArn)
+		}
+		// getURLwithPortMapping makes 2 queries
+		// one to get the target groups and another for load balancers
+		loadBalancers, err := s.getURLWithPortMapping(ctx, targetGroupArns)
+		if err != nil {
+			return nil, err
+		}
 		status = append(status, compose.ServiceStatus{
 		status = append(status, compose.ServiceStatus{
-			ID:       *service.ServiceName,
-			Name:     name,
-			Replicas: int(*service.RunningCount),
-			Desired:  int(*service.DesiredCount),
+			ID:            *service.ServiceName,
+			Name:          name,
+			Replicas:      int(*service.RunningCount),
+			Desired:       int(*service.DesiredCount),
+			LoadBalancers: loadBalancers,
 		})
 		})
 	}
 	}
-
 	return status, nil
 	return status, nil
 }
 }
 
 
+func (s sdk) getURLWithPortMapping(ctx context.Context, targetGroupArns []string) ([]compose.LoadBalancer, error) {
+	if len(targetGroupArns) == 0 {
+		return nil, nil
+	}
+	groups, err := s.ELB.DescribeTargetGroups(&elbv2.DescribeTargetGroupsInput{
+		TargetGroupArns: aws.StringSlice(targetGroupArns),
+	})
+	if err != nil {
+		return nil, err
+	}
+	lbarns := []*string{}
+	for _, tg := range groups.TargetGroups {
+		lbarns = append(lbarns, tg.LoadBalancerArns...)
+	}
+
+	lbs, err := s.ELB.DescribeLoadBalancersWithContext(ctx, &elbv2.DescribeLoadBalancersInput{
+		LoadBalancerArns: lbarns,
+	})
+
+	if err != nil {
+		return nil, err
+	}
+	filterLB := func(arn *string, lbs []*elbv2.LoadBalancer) *elbv2.LoadBalancer {
+		for _, lb := range lbs {
+			if *lb.LoadBalancerArn == *arn {
+				return lb
+			}
+		}
+		return nil
+	}
+	loadBalancers := []compose.LoadBalancer{}
+	for _, tg := range groups.TargetGroups {
+		for _, lbarn := range tg.LoadBalancerArns {
+			lb := filterLB(lbarn, lbs.LoadBalancers)
+			if lb == nil {
+				continue
+			}
+			loadBalancers = append(loadBalancers, compose.LoadBalancer{
+				URL:           *lb.DNSName,
+				TargetPort:    int(*tg.Port),
+				PublishedPort: int(*tg.Port),
+				Protocol:      *tg.Protocol,
+			})
+
+		}
+	}
+	return loadBalancers, nil
+}
+
 func (s sdk) ListTasks(ctx context.Context, cluster string, family string) ([]string, error) {
 func (s sdk) ListTasks(ctx context.Context, cluster string, family string) ([]string, error) {
 	tasks, err := s.ECS.ListTasksWithContext(ctx, &ecs.ListTasksInput{
 	tasks, err := s.ECS.ListTasksWithContext(ctx, &ecs.ListTasksInput{
 		Cluster: aws.String(cluster),
 		Cluster: aws.String(cluster),

+ 18 - 5
ecs/pkg/compose/types.go

@@ -9,12 +9,25 @@ type StackResource struct {
 	Status    string
 	Status    string
 }
 }
 
 
+type PortMapping struct {
+	Source int
+	Target int
+}
+
+type LoadBalancer struct {
+	URL           string
+	TargetPort    int
+	PublishedPort int
+	Protocol      string
+}
+
 type ServiceStatus struct {
 type ServiceStatus struct {
-	ID       string
-	Name     string
-	Replicas int
-	Desired  int
-	Ports    []string
+	ID            string
+	Name          string
+	Replicas      int
+	Desired       int
+	Ports         []string
+	LoadBalancers []LoadBalancer
 }
 }
 
 
 const (
 const (