From 3e785e2cb055fa226e31d8c530e6b19232bbe942 Mon Sep 17 00:00:00 2001 From: Guillaume Lours Date: Wed, 6 May 2020 12:28:33 +0200 Subject: [PATCH] Fix initialization issue of aws context with PreRun function Signed-off-by: Guillaume Lours Signed-off-by: Nicolas De Loof --- ecs/cmd/commands/compose.go | 27 +++++++++++++++++--------- ecs/cmd/commands/secret.go | 35 +++++++++++++++++----------------- ecs/cmd/main/main.go | 17 +++-------------- ecs/pkg/docker/contextStore.go | 20 ++++++++++++++++++- 4 files changed, 58 insertions(+), 41 deletions(-) diff --git a/ecs/cmd/commands/compose.go b/ecs/cmd/commands/compose.go index 459a48813..06fc80a80 100644 --- a/ecs/cmd/commands/compose.go +++ b/ecs/cmd/commands/compose.go @@ -4,13 +4,14 @@ import ( "context" "fmt" + "github.com/docker/cli/cli/command" "github.com/docker/ecs-plugin/pkg/amazon" "github.com/docker/ecs-plugin/pkg/compose" "github.com/docker/ecs-plugin/pkg/docker" "github.com/spf13/cobra" ) -func ComposeCommand(clusteropts *docker.AwsContext) *cobra.Command { +func ComposeCommand(dockerCli command.Cli) *cobra.Command { cmd := &cobra.Command{ Use: "compose", } @@ -18,9 +19,9 @@ func ComposeCommand(clusteropts *docker.AwsContext) *cobra.Command { opts.AddFlags(cmd.Flags()) cmd.AddCommand( - ConvertCommand(clusteropts, opts), - UpCommand(clusteropts, opts), - DownCommand(clusteropts, opts), + ConvertCommand(dockerCli, opts), + UpCommand(dockerCli, opts), + DownCommand(dockerCli, opts), ) return cmd } @@ -36,10 +37,14 @@ func (o upOptions) LoadBalancerArn() *string { return &o.loadBalancerArn } -func ConvertCommand(clusteropts *docker.AwsContext, projectOpts *compose.ProjectOptions) *cobra.Command { +func ConvertCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command { cmd := &cobra.Command{ Use: "convert", 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 @@ -61,11 +66,15 @@ func ConvertCommand(clusteropts *docker.AwsContext, projectOpts *compose.Project return cmd } -func UpCommand(clusteropts *docker.AwsContext, projectOpts *compose.ProjectOptions) *cobra.Command { +func UpCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command { opts := upOptions{} cmd := &cobra.Command{ Use: "up", 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 @@ -81,11 +90,11 @@ type downOptions struct { DeleteCluster bool } -func DownCommand(clusteropts *docker.AwsContext, projectOpts *compose.ProjectOptions) *cobra.Command { +func DownCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command { opts := downOptions{} cmd := &cobra.Command{ Use: "down", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error { client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region) if err != nil { return err @@ -105,7 +114,7 @@ func DownCommand(clusteropts *docker.AwsContext, projectOpts *compose.ProjectOpt } } return nil - }, + }), } cmd.Flags().BoolVar(&opts.DeleteCluster, "delete-cluster", false, "Delete cluster") return cmd diff --git a/ecs/cmd/commands/secret.go b/ecs/cmd/commands/secret.go index b46eeeb3d..8488e6cb1 100644 --- a/ecs/cmd/commands/secret.go +++ b/ecs/cmd/commands/secret.go @@ -9,6 +9,7 @@ import ( "strings" "text/tabwriter" + "github.com/docker/cli/cli/command" "github.com/docker/ecs-plugin/pkg/amazon" "github.com/docker/ecs-plugin/pkg/docker" "github.com/spf13/cobra" @@ -22,27 +23,27 @@ type deleteSecretOptions struct { recover bool } -func SecretCommand(clusteropts *docker.AwsContext) *cobra.Command { +func SecretCommand(dockerCli command.Cli) *cobra.Command { cmd := &cobra.Command{ Use: "secret", Short: "Manages secrets", } cmd.AddCommand( - CreateSecret(clusteropts), - InspectSecret(clusteropts), - ListSecrets(clusteropts), - DeleteSecret(clusteropts), + CreateSecret(dockerCli), + InspectSecret(dockerCli), + ListSecrets(dockerCli), + DeleteSecret(dockerCli), ) return cmd } -func CreateSecret(clusteropts *docker.AwsContext) *cobra.Command { +func CreateSecret(dockerCli command.Cli) *cobra.Command { //opts := createSecretOptions{} cmd := &cobra.Command{ Use: "create NAME SECRET", Short: "Creates a secret.", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error { client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region) if err != nil { return err @@ -55,16 +56,16 @@ func CreateSecret(clusteropts *docker.AwsContext) *cobra.Command { id, err := client.CreateSecret(context.Background(), name, secret) fmt.Println(id) return err - }, + }), } return cmd } -func InspectSecret(clusteropts *docker.AwsContext) *cobra.Command { +func InspectSecret(dockerCli command.Cli) *cobra.Command { cmd := &cobra.Command{ Use: "inspect ID", Short: "Displays secret details", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error { client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region) if err != nil { return err @@ -83,17 +84,17 @@ func InspectSecret(clusteropts *docker.AwsContext) *cobra.Command { } fmt.Println(out) return nil - }, + }), } return cmd } -func ListSecrets(clusteropts *docker.AwsContext) *cobra.Command { +func ListSecrets(dockerCli command.Cli) *cobra.Command { cmd := &cobra.Command{ Use: "list", Aliases: []string{"ls"}, Short: "List secrets stored for the existing account.", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error { client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region) if err != nil { return err @@ -105,18 +106,18 @@ func ListSecrets(clusteropts *docker.AwsContext) *cobra.Command { printList(os.Stdout, secrets) return nil - }, + }), } return cmd } -func DeleteSecret(clusteropts *docker.AwsContext) *cobra.Command { +func DeleteSecret(dockerCli command.Cli) *cobra.Command { opts := deleteSecretOptions{} cmd := &cobra.Command{ Use: "delete NAME", Aliases: []string{"rm", "remove"}, Short: "Removes a secret.", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error { client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region) if err != nil { return err @@ -125,7 +126,7 @@ func DeleteSecret(clusteropts *docker.AwsContext) *cobra.Command { return errors.New("Missing mandatory parameter: [NAME]") } return client.DeleteSecret(context.Background(), args[0], opts.recover) - }, + }), } cmd.Flags().BoolVar(&opts.recover, "recover", false, "Enable recovery.") return cmd diff --git a/ecs/cmd/main/main.go b/ecs/cmd/main/main.go index 812ccfeea..9af648292 100644 --- a/ecs/cmd/main/main.go +++ b/ecs/cmd/main/main.go @@ -7,7 +7,6 @@ import ( "github.com/docker/cli/cli-plugins/plugin" "github.com/docker/cli/cli/command" commands "github.com/docker/ecs-plugin/cmd/commands" - "github.com/docker/ecs-plugin/pkg/docker" "github.com/spf13/cobra" ) @@ -27,33 +26,23 @@ func main() { // NewRootCmd returns the base root command. func NewRootCmd(name string, dockerCli command.Cli) *cobra.Command { - var opts *docker.AwsContext - cmd := &cobra.Command{ Short: "Docker ECS", Long: `run multi-container applications on Amazon ECS.`, Use: name, Annotations: map[string]string{"experimentalCLI": "true"}, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - err := plugin.PersistentPreRunE(cmd, args) - if err != nil { - return err - } - contextName := dockerCli.CurrentContext() - opts, err = docker.CheckAwsContextExists(contextName) - return err - }, RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 0 { return fmt.Errorf("%q is not a docker ecs command\nSee 'docker ecs --help'", args[0]) } + cmd.Help() return nil }, } cmd.AddCommand( VersionCommand(), - commands.ComposeCommand(opts), - commands.SecretCommand(opts), + commands.ComposeCommand(dockerCli), + commands.SecretCommand(dockerCli), commands.SetupCommand(), ) return cmd diff --git a/ecs/pkg/docker/contextStore.go b/ecs/pkg/docker/contextStore.go index 31e4bc4e8..b038eb924 100644 --- a/ecs/pkg/docker/contextStore.go +++ b/ecs/pkg/docker/contextStore.go @@ -7,6 +7,7 @@ import ( cliconfig "github.com/docker/cli/cli/config" "github.com/docker/cli/cli/context/store" "github.com/mitchellh/mapstructure" + "github.com/spf13/cobra" ) const contextType = "aws" @@ -50,7 +51,7 @@ func initContextStore(contextDir string) store.Store { return store.New(contextDir, config) } -func CheckAwsContextExists(contextName string) (*AwsContext, error) { +func checkAwsContextExists(contextName string) (*AwsContext, error) { if contextName == command.DefaultContextName { return nil, fmt.Errorf("can't use \"%s\" with ECS command because it is not an AWS context", contextName) } @@ -70,3 +71,20 @@ func CheckAwsContextExists(contextName string) (*AwsContext, error) { } return &awsContext, nil } + +type ContextFunc func(ctx AwsContext, 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 { + ctx, err := GetAwsContext(dockerCli) + if err != nil { + return err + } + return f(*ctx, args) + } +} + +func GetAwsContext(dockerCli command.Cli) (*AwsContext, error) { + contextName := dockerCli.CurrentContext() + return checkAwsContextExists(contextName) +}