Browse Source

Unwrapp API errors to get user-friendly error message

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 5 years ago
parent
commit
4700fed836

+ 12 - 48
ecs/cmd/commands/compose.go

@@ -8,7 +8,6 @@ import (
 	"strings"
 
 	"github.com/compose-spec/compose-go/cli"
-	"github.com/compose-spec/compose-go/types"
 	"github.com/docker/cli/cli/command"
 	amazon "github.com/docker/ecs-plugin/pkg/amazon/backend"
 	"github.com/docker/ecs-plugin/pkg/docker"
@@ -43,15 +42,11 @@ func (o upOptions) LoadBalancerArn() *string {
 	return &o.loadBalancerArn
 }
 
-func ConvertCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
+func ConvertCommand(dockerCli command.Cli, options *cli.ProjectOptions) *cobra.Command {
 	cmd := &cobra.Command{
 		Use: "convert",
-		RunE: WithProject(projectOpts, func(project *types.Project, args []string) error {
-			clusteropts, err := docker.GetAwsContext(dockerCli)
-			if err != nil {
-				return err
-			}
-			backend, err := amazon.NewBackend(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
+		RunE: docker.WithAwsContext(dockerCli, func(ctx docker.AwsContext, backend *amazon.Backend, args []string) error {
+			project, err := cli.ProjectFromOptions(options)
 			if err != nil {
 				return err
 			}
@@ -72,36 +67,24 @@ func ConvertCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cob
 	return cmd
 }
 
-func UpCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
+func UpCommand(dockerCli command.Cli, options *cli.ProjectOptions) *cobra.Command {
 	opts := upOptions{}
 	cmd := &cobra.Command{
 		Use: "up",
-		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error {
-			backend, err := amazon.NewBackend(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
-			if err != nil {
-				return err
-			}
-			return backend.Up(context.Background(), *projectOpts)
+		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error {
+			return backend.Up(context.Background(), *options)
 		}),
 	}
 	cmd.Flags().StringVar(&opts.loadBalancerArn, "load-balancer", "", "")
 	return cmd
 }
 
-func PsCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
+func PsCommand(dockerCli command.Cli, options *cli.ProjectOptions) *cobra.Command {
 	opts := upOptions{}
 	cmd := &cobra.Command{
 		Use: "ps",
-		RunE: WithProject(projectOpts, func(project *types.Project, args []string) error {
-			clusteropts, err := docker.GetAwsContext(dockerCli)
-			if err != nil {
-				return err
-			}
-			backend, err := amazon.NewBackend(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
-			if err != nil {
-				return err
-			}
-			status, err := backend.Ps(context.Background(), project)
+		RunE: docker.WithAwsContext(dockerCli, func(ctx docker.AwsContext, backend *amazon.Backend, args []string) error {
+			status, err := backend.Ps(context.Background(), *options)
 			if err != nil {
 				return err
 			}
@@ -125,11 +108,7 @@ func DownCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.
 	opts := downOptions{}
 	cmd := &cobra.Command{
 		Use: "down",
-		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error {
-			backend, err := amazon.NewBackend(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
-			if err != nil {
-				return err
-			}
+		RunE: docker.WithAwsContext(dockerCli, func(ctx docker.AwsContext, backend *amazon.Backend, args []string) error {
 			return backend.Down(context.Background(), *projectOpts)
 		}),
 	}
@@ -140,23 +119,8 @@ func DownCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.
 func LogsCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
 	cmd := &cobra.Command{
 		Use: "logs [PROJECT NAME]",
-		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error {
-			backend, err := amazon.NewBackend(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
-			if err != nil {
-				return err
-			}
-			var name string
-
-			if len(args) == 0 {
-				project, err := cli.ProjectFromOptions(projectOpts)
-				if err != nil {
-					return err
-				}
-				name = project.Name
-			} else {
-				name = args[0]
-			}
-			return backend.Logs(context.Background(), name)
+		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error {
+			return backend.Logs(context.Background(), *projectOpts)
 		}),
 	}
 	return cmd

+ 0 - 15
ecs/cmd/commands/opts.go

@@ -2,8 +2,6 @@ package commands
 
 import (
 	"github.com/compose-spec/compose-go/cli"
-	"github.com/compose-spec/compose-go/types"
-	"github.com/spf13/cobra"
 	"github.com/spf13/pflag"
 )
 
@@ -11,16 +9,3 @@ func AddFlags(o *cli.ProjectOptions, flags *pflag.FlagSet) {
 	flags.StringArrayVarP(&o.ConfigPaths, "file", "f", nil, "Specify an alternate compose file")
 	flags.StringVarP(&o.Name, "project-name", "n", "", "Specify an alternate project name (default: directory name)")
 }
-
-type ProjectFunc func(project *types.Project, args []string) error
-
-// WithProject wrap a ProjectFunc into a cobra command
-func WithProject(options *cli.ProjectOptions, f ProjectFunc) func(cmd *cobra.Command, args []string) error {
-	return func(cmd *cobra.Command, args []string) error {
-		project, err := cli.ProjectFromOptions(options)
-		if err != nil {
-			return err
-		}
-		return f(project, args)
-	}
-}

+ 4 - 20
ecs/cmd/commands/secret.go

@@ -47,11 +47,7 @@ func CreateSecret(dockerCli command.Cli) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "create NAME",
 		Short: "Creates a secret.",
-		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error {
-			backend, err := amazon.NewBackend(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
-			if err != nil {
-				return err
-			}
+		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error {
 			if len(args) == 0 {
 				return errors.New("Missing mandatory parameter: NAME")
 			}
@@ -73,11 +69,7 @@ func InspectSecret(dockerCli command.Cli) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "inspect ID",
 		Short: "Displays secret details",
-		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error {
-			backend, err := amazon.NewBackend(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
-			if err != nil {
-				return err
-			}
+		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error {
 			if len(args) == 0 {
 				return errors.New("Missing mandatory parameter: ID")
 			}
@@ -102,11 +94,7 @@ func ListSecrets(dockerCli command.Cli) *cobra.Command {
 		Use:     "list",
 		Aliases: []string{"ls"},
 		Short:   "List secrets stored for the existing account.",
-		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error {
-			backend, err := amazon.NewBackend(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
-			if err != nil {
-				return err
-			}
+		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error {
 			secrets, err := backend.ListSecrets(context.Background())
 			if err != nil {
 				return err
@@ -125,11 +113,7 @@ func DeleteSecret(dockerCli command.Cli) *cobra.Command {
 		Use:     "delete NAME",
 		Aliases: []string{"rm", "remove"},
 		Short:   "Removes a secret.",
-		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error {
-			backend, err := amazon.NewBackend(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
-			if err != nil {
-				return err
-			}
+		RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error {
 			if len(args) == 0 {
 				return errors.New("Missing mandatory parameter: [NAME]")
 			}

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

@@ -4,11 +4,16 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/compose-spec/compose-go/types"
+	"github.com/compose-spec/compose-go/cli"
 	"github.com/docker/ecs-plugin/pkg/compose"
 )
 
-func (b *Backend) Ps(ctx context.Context, project *types.Project) ([]compose.ServiceStatus, error) {
+func (b *Backend) Ps(ctx context.Context, options cli.ProjectOptions) ([]compose.ServiceStatus, error) {
+	project, err := cli.ProjectFromOptions(&options)
+	if err != nil {
+		return nil, err
+	}
+
 	cluster := b.Cluster
 	if cluster == "" {
 		cluster = project.Name

+ 13 - 2
ecs/pkg/amazon/backend/logs.go

@@ -8,11 +8,22 @@ import (
 	"strconv"
 	"strings"
 
+	"github.com/compose-spec/compose-go/cli"
+
 	"github.com/docker/ecs-plugin/pkg/console"
 )
 
-func (b *Backend) Logs(ctx context.Context, projectName string) error {
-	err := b.api.GetLogs(ctx, projectName, &logConsumer{
+func (b *Backend) Logs(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
+	}
+
+	err := b.api.GetLogs(ctx, name, &logConsumer{
 		colors: map[string]console.ColorFunc{},
 		width:  0,
 	})

+ 3 - 1
ecs/pkg/amazon/sdk/sdk.go

@@ -143,7 +143,9 @@ func (s sdk) StackExists(ctx context.Context, name string) (bool, error) {
 		StackName: aws.String(name),
 	})
 	if err != nil {
-		// FIXME doesn't work as expected
+		if strings.HasPrefix(err.Error(), fmt.Sprintf("ValidationError: Stack with id %s does not exist", name)) {
+			return false, nil
+		}
 		return false, nil
 	}
 	return len(stacks.Stacks) > 0, nil

+ 2 - 2
ecs/pkg/compose/api.go

@@ -13,8 +13,8 @@ type API interface {
 	Down(ctx context.Context, options cli.ProjectOptions) error
 
 	Convert(project *types.Project) (*cloudformation.Template, error)
-	Logs(ctx context.Context, projectName string) error
-	Ps(background context.Context, project *types.Project) ([]ServiceStatus, error)
+	Logs(ctx context.Context, projectName cli.ProjectOptions) error
+	Ps(background context.Context, options cli.ProjectOptions) ([]ServiceStatus, error)
 
 	CreateSecret(ctx context.Context, secret Secret) (string, error)
 	InspectSecret(ctx context.Context, id string) (Secret, error)

+ 12 - 2
ecs/pkg/docker/contextStore.go

@@ -3,9 +3,11 @@ package docker
 import (
 	"fmt"
 
+	"github.com/aws/aws-sdk-go/aws/awserr"
 	"github.com/docker/cli/cli/command"
 	cliconfig "github.com/docker/cli/cli/config"
 	"github.com/docker/cli/cli/context/store"
+	amazon "github.com/docker/ecs-plugin/pkg/amazon/backend"
 	"github.com/mitchellh/mapstructure"
 	"github.com/spf13/cobra"
 )
@@ -72,7 +74,7 @@ func checkAwsContextExists(contextName string) (*AwsContext, error) {
 	return &awsContext, nil
 }
 
-type ContextFunc func(ctx AwsContext, args []string) error
+type ContextFunc func(ctx AwsContext, backend *amazon.Backend, args []string) error
 
 func WithAwsContext(dockerCli command.Cli, f ContextFunc) func(cmd *cobra.Command, args []string) error {
 	return func(cmd *cobra.Command, args []string) error {
@@ -80,7 +82,15 @@ func WithAwsContext(dockerCli command.Cli, f ContextFunc) func(cmd *cobra.Comman
 		if err != nil {
 			return err
 		}
-		return f(*ctx, args)
+		backend, err := amazon.NewBackend(ctx.Profile, ctx.Cluster, ctx.Region)
+		if err != nil {
+			return err
+		}
+		err = f(*ctx, backend, args)
+		if e, ok := err.(awserr.Error); ok {
+			return fmt.Errorf(e.Message())
+		}
+		return err
 	}
 }