From da299f59e2a941dc7e2c903111fc114407eb01b8 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Wed, 27 May 2020 14:38:50 +0200 Subject: [PATCH] introduce 'ps' command Signed-off-by: Nicolas De Loof --- ecs/cmd/commands/compose.go | 21 ++++++++++++++ ecs/pkg/amazon/api.go | 8 ++---- ecs/pkg/amazon/list.go | 55 +++++++++++++++++++++++++++++++++++++ ecs/pkg/amazon/sdk.go | 4 ++- ecs/pkg/compose/api.go | 1 + 5 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 ecs/pkg/amazon/list.go diff --git a/ecs/cmd/commands/compose.go b/ecs/cmd/commands/compose.go index f7a07226d..0b1e70e65 100644 --- a/ecs/cmd/commands/compose.go +++ b/ecs/cmd/commands/compose.go @@ -23,6 +23,7 @@ func ComposeCommand(dockerCli command.Cli) *cobra.Command { UpCommand(dockerCli, opts), DownCommand(dockerCli, opts), LogsCommand(dockerCli, opts), + PsCommand(dockerCli, opts), ) return cmd } @@ -87,6 +88,26 @@ func UpCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobr return cmd } +func PsCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command { + opts := upOptions{} + cmd := &cobra.Command{ + Use: "ps", + RunE: compose.WithProject(projectOpts, func(project *compose.Project, args []string) error { + clusteropts, err := docker.GetAwsContext(dockerCli) + if err != nil { + return err + } + client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region) + if err != nil { + return err + } + return client.ComposePs(context.Background(), project) + }), + } + cmd.Flags().StringVar(&opts.loadBalancerArn, "load-balancer", "", "") + return cmd +} + type downOptions struct { DeleteCluster bool } diff --git a/ecs/pkg/amazon/api.go b/ecs/pkg/amazon/api.go index fecc5d80b..9fd599a1b 100644 --- a/ecs/pkg/amazon/api.go +++ b/ecs/pkg/amazon/api.go @@ -1,15 +1,11 @@ package amazon -import "context" - -//go:generate mockgen -destination=./api_mock.go -self_package "github.com/docker/ecs-plugin/pkg/amazon" -package=amazon . API +//go:generate mockgen -destination=./mock/api.go -package=mock . API type API interface { downAPI upAPI logsAPI secretsAPI - GetTasks(ctx context.Context, cluster string, name string) ([]string, error) - GetNetworkInterfaces(ctx context.Context, cluster string, arns ...string) ([]string, error) - GetPublicIPs(ctx context.Context, interfaces ...string) ([]string, error) + psAPI } diff --git a/ecs/pkg/amazon/list.go b/ecs/pkg/amazon/list.go new file mode 100644 index 000000000..d401e0d69 --- /dev/null +++ b/ecs/pkg/amazon/list.go @@ -0,0 +1,55 @@ +package amazon + +import ( + "context" + "fmt" + "os" + "strings" + "text/tabwriter" + + "github.com/docker/ecs-plugin/pkg/compose" +) + +func (c *client) ComposePs(ctx context.Context, project *compose.Project) error { + cluster := c.Cluster + if cluster == "" { + cluster = project.Name + } + w := tabwriter.NewWriter(os.Stdout, 20, 2, 3, ' ', 0) + fmt.Fprintf(w, "Name\tState\tPorts\n") + for _, s := range project.Services { + tasks, err := c.api.GetTasks(ctx, cluster, s.Name) + if err != nil { + return err + } + if len(tasks) == 0 { + continue + } + // TODO get more data from DescribeTask, including tasks status + networkInterfaces, err := c.api.GetNetworkInterfaces(ctx, cluster, tasks...) + if err != nil { + return err + } + if len(networkInterfaces) == 0 { + fmt.Fprintf(w, "%s\t%s\t\n", s.Name, "Provisioning") + continue + } + publicIps, err := c.api.GetPublicIPs(ctx, networkInterfaces...) + if err != nil { + return err + } + ports := []string{} + for _, p := range s.Ports { + ports = append(ports, fmt.Sprintf("%s:%d->%d/%s", strings.Join(publicIps, ","), p.Published, p.Target, p.Protocol)) + } + fmt.Fprintf(w, "%s\t%s\t%s\n", s.Name, "Up", strings.Join(ports, ", ")) + } + w.Flush() + return nil +} + +type psAPI interface { + GetTasks(ctx context.Context, cluster string, name string) ([]string, error) + GetNetworkInterfaces(ctx context.Context, cluster string, arns ...string) ([]string, error) + GetPublicIPs(ctx context.Context, interfaces ...string) ([]string, error) +} diff --git a/ecs/pkg/amazon/sdk.go b/ecs/pkg/amazon/sdk.go index 42b00c8e8..3f9b9e6b6 100644 --- a/ecs/pkg/amazon/sdk.go +++ b/ecs/pkg/amazon/sdk.go @@ -388,7 +388,9 @@ func (s sdk) GetPublicIPs(ctx context.Context, interfaces ...string) ([]string, } publicIPs := []string{} for _, interf := range desc.NetworkInterfaces { - publicIPs = append(publicIPs, *interf.Association.PublicIp) + if interf.Association != nil { + publicIPs = append(publicIPs, *interf.Association.PublicIp) + } } return publicIPs, nil } diff --git a/ecs/pkg/compose/api.go b/ecs/pkg/compose/api.go index b39afe02d..1049a993c 100644 --- a/ecs/pkg/compose/api.go +++ b/ecs/pkg/compose/api.go @@ -17,4 +17,5 @@ type API interface { InspectSecret(ctx context.Context, id string) (docker.Secret, error) ListSecrets(ctx context.Context) ([]docker.Secret, error) DeleteSecret(ctx context.Context, id string, recover bool) error + ComposePs(background context.Context, project *Project) error }