From 31703ac661b95fe467bff6cf32a9cddbb5bffb9d Mon Sep 17 00:00:00 2001 From: aiordache Date: Tue, 21 Jul 2020 17:45:16 +0200 Subject: [PATCH] generic URL/port/protocol retrieval for compose ps Signed-off-by: aiordache --- cmd/commands/compose.go | 2 +- pkg/amazon/backend/list.go | 24 ++++--------- pkg/amazon/sdk/sdk.go | 70 +++++++++++++++++++++++++++++++++++--- pkg/compose/types.go | 23 ++++++++++--- 4 files changed, 91 insertions(+), 28 deletions(-) diff --git a/cmd/commands/compose.go b/cmd/commands/compose.go index bceba59..75a9555 100644 --- a/cmd/commands/compose.go +++ b/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) { 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") return nil diff --git a/pkg/amazon/backend/list.go b/pkg/amazon/backend/list.go index ff3c4b2..165241d 100644 --- a/pkg/amazon/backend/list.go +++ b/pkg/amazon/backend/list.go @@ -21,7 +21,6 @@ func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose if err != nil { return nil, err } - loadBalancer := parameters[ParameterLoadBalancerARN] cluster := parameters[ParameterClusterName] resources, err := b.api.ListStackResources(ctx, projectName) @@ -30,20 +29,14 @@ func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose } servicesARN := []string{} - targetGroups := []string{} for _, r := range resources { switch r.Type { case "AWS::ECS::Service": servicesARN = append(servicesARN, r.ARN) case "AWS::ECS::Cluster": 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 } @@ -52,18 +45,15 @@ func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose return nil, err } - url, err := b.api.GetLoadBalancerURL(ctx, loadBalancer) - if err != nil { - return nil, err - } - for i, state := range status { 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 status[i] = state diff --git a/pkg/amazon/sdk/sdk.go b/pkg/amazon/sdk/sdk.go index b2d0cb1..7447ecc 100644 --- a/pkg/amazon/sdk/sdk.go +++ b/pkg/amazon/sdk/sdk.go @@ -449,6 +449,7 @@ func (s sdk) DescribeServices(ctx context.Context, cluster string, arns []string if err != nil { return nil, err } + status := []compose.ServiceStatus{} for _, service := range services.Services { var name string @@ -460,17 +461,76 @@ func (s sdk) DescribeServices(ctx context.Context, cluster string, arns []string if name == "" { 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{ - 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 } +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) { tasks, err := s.ECS.ListTasksWithContext(ctx, &ecs.ListTasksInput{ Cluster: aws.String(cluster), diff --git a/pkg/compose/types.go b/pkg/compose/types.go index ec59578..1426d1b 100644 --- a/pkg/compose/types.go +++ b/pkg/compose/types.go @@ -9,12 +9,25 @@ type StackResource struct { Status string } +type PortMapping struct { + Source int + Target int +} + +type LoadBalancer struct { + URL string + TargetPort int + PublishedPort int + Protocol string +} + 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 (