Unwrapp API errors to get user-friendly error message

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2020-07-06 14:40:41 +02:00
parent f892ee1004
commit 4700fed836
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
8 changed files with 53 additions and 92 deletions

View File

@ -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

View File

@ -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)
}
}

View File

@ -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]")
}

View File

@ -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

View File

@ -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,
})

View File

@ -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

View File

@ -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)

View File

@ -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
}
}