Fix initialization issue of aws context with PreRun function

Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Guillaume Lours 2020-05-06 12:28:33 +02:00 committed by Nicolas De Loof
parent 1889d04d83
commit 3e785e2cb0
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
4 changed files with 58 additions and 41 deletions

View File

@ -4,13 +4,14 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/docker/cli/cli/command"
"github.com/docker/ecs-plugin/pkg/amazon" "github.com/docker/ecs-plugin/pkg/amazon"
"github.com/docker/ecs-plugin/pkg/compose" "github.com/docker/ecs-plugin/pkg/compose"
"github.com/docker/ecs-plugin/pkg/docker" "github.com/docker/ecs-plugin/pkg/docker"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func ComposeCommand(clusteropts *docker.AwsContext) *cobra.Command { func ComposeCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "compose", Use: "compose",
} }
@ -18,9 +19,9 @@ func ComposeCommand(clusteropts *docker.AwsContext) *cobra.Command {
opts.AddFlags(cmd.Flags()) opts.AddFlags(cmd.Flags())
cmd.AddCommand( cmd.AddCommand(
ConvertCommand(clusteropts, opts), ConvertCommand(dockerCli, opts),
UpCommand(clusteropts, opts), UpCommand(dockerCli, opts),
DownCommand(clusteropts, opts), DownCommand(dockerCli, opts),
) )
return cmd return cmd
} }
@ -36,10 +37,14 @@ func (o upOptions) LoadBalancerArn() *string {
return &o.loadBalancerArn 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{ cmd := &cobra.Command{
Use: "convert", Use: "convert",
RunE: compose.WithProject(projectOpts, func(project *compose.Project, args []string) error { 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) client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
if err != nil { if err != nil {
return err return err
@ -61,11 +66,15 @@ func ConvertCommand(clusteropts *docker.AwsContext, projectOpts *compose.Project
return cmd return cmd
} }
func UpCommand(clusteropts *docker.AwsContext, projectOpts *compose.ProjectOptions) *cobra.Command { func UpCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
opts := upOptions{} opts := upOptions{}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "up", Use: "up",
RunE: compose.WithProject(projectOpts, func(project *compose.Project, args []string) error { 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) client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
if err != nil { if err != nil {
return err return err
@ -81,11 +90,11 @@ type downOptions struct {
DeleteCluster bool DeleteCluster bool
} }
func DownCommand(clusteropts *docker.AwsContext, projectOpts *compose.ProjectOptions) *cobra.Command { func DownCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
opts := downOptions{} opts := downOptions{}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "down", 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) client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
if err != nil { if err != nil {
return err return err
@ -105,7 +114,7 @@ func DownCommand(clusteropts *docker.AwsContext, projectOpts *compose.ProjectOpt
} }
} }
return nil return nil
}, }),
} }
cmd.Flags().BoolVar(&opts.DeleteCluster, "delete-cluster", false, "Delete cluster") cmd.Flags().BoolVar(&opts.DeleteCluster, "delete-cluster", false, "Delete cluster")
return cmd return cmd

View File

@ -9,6 +9,7 @@ import (
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"github.com/docker/cli/cli/command"
"github.com/docker/ecs-plugin/pkg/amazon" "github.com/docker/ecs-plugin/pkg/amazon"
"github.com/docker/ecs-plugin/pkg/docker" "github.com/docker/ecs-plugin/pkg/docker"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -22,27 +23,27 @@ type deleteSecretOptions struct {
recover bool recover bool
} }
func SecretCommand(clusteropts *docker.AwsContext) *cobra.Command { func SecretCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "secret", Use: "secret",
Short: "Manages secrets", Short: "Manages secrets",
} }
cmd.AddCommand( cmd.AddCommand(
CreateSecret(clusteropts), CreateSecret(dockerCli),
InspectSecret(clusteropts), InspectSecret(dockerCli),
ListSecrets(clusteropts), ListSecrets(dockerCli),
DeleteSecret(clusteropts), DeleteSecret(dockerCli),
) )
return cmd return cmd
} }
func CreateSecret(clusteropts *docker.AwsContext) *cobra.Command { func CreateSecret(dockerCli command.Cli) *cobra.Command {
//opts := createSecretOptions{} //opts := createSecretOptions{}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "create NAME SECRET", Use: "create NAME SECRET",
Short: "Creates a 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) client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
if err != nil { if err != nil {
return err return err
@ -55,16 +56,16 @@ func CreateSecret(clusteropts *docker.AwsContext) *cobra.Command {
id, err := client.CreateSecret(context.Background(), name, secret) id, err := client.CreateSecret(context.Background(), name, secret)
fmt.Println(id) fmt.Println(id)
return err return err
}, }),
} }
return cmd return cmd
} }
func InspectSecret(clusteropts *docker.AwsContext) *cobra.Command { func InspectSecret(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "inspect ID", Use: "inspect ID",
Short: "Displays secret details", 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) client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
if err != nil { if err != nil {
return err return err
@ -83,17 +84,17 @@ func InspectSecret(clusteropts *docker.AwsContext) *cobra.Command {
} }
fmt.Println(out) fmt.Println(out)
return nil return nil
}, }),
} }
return cmd return cmd
} }
func ListSecrets(clusteropts *docker.AwsContext) *cobra.Command { func ListSecrets(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "list", Use: "list",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Short: "List secrets stored for the existing account.", 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) client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
if err != nil { if err != nil {
return err return err
@ -105,18 +106,18 @@ func ListSecrets(clusteropts *docker.AwsContext) *cobra.Command {
printList(os.Stdout, secrets) printList(os.Stdout, secrets)
return nil return nil
}, }),
} }
return cmd return cmd
} }
func DeleteSecret(clusteropts *docker.AwsContext) *cobra.Command { func DeleteSecret(dockerCli command.Cli) *cobra.Command {
opts := deleteSecretOptions{} opts := deleteSecretOptions{}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "delete NAME", Use: "delete NAME",
Aliases: []string{"rm", "remove"}, Aliases: []string{"rm", "remove"},
Short: "Removes a secret.", 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) client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region)
if err != nil { if err != nil {
return err return err
@ -125,7 +126,7 @@ func DeleteSecret(clusteropts *docker.AwsContext) *cobra.Command {
return errors.New("Missing mandatory parameter: [NAME]") return errors.New("Missing mandatory parameter: [NAME]")
} }
return client.DeleteSecret(context.Background(), args[0], opts.recover) return client.DeleteSecret(context.Background(), args[0], opts.recover)
}, }),
} }
cmd.Flags().BoolVar(&opts.recover, "recover", false, "Enable recovery.") cmd.Flags().BoolVar(&opts.recover, "recover", false, "Enable recovery.")
return cmd return cmd

View File

@ -7,7 +7,6 @@ import (
"github.com/docker/cli/cli-plugins/plugin" "github.com/docker/cli/cli-plugins/plugin"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
commands "github.com/docker/ecs-plugin/cmd/commands" commands "github.com/docker/ecs-plugin/cmd/commands"
"github.com/docker/ecs-plugin/pkg/docker"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -27,33 +26,23 @@ func main() {
// NewRootCmd returns the base root command. // NewRootCmd returns the base root command.
func NewRootCmd(name string, dockerCli command.Cli) *cobra.Command { func NewRootCmd(name string, dockerCli command.Cli) *cobra.Command {
var opts *docker.AwsContext
cmd := &cobra.Command{ cmd := &cobra.Command{
Short: "Docker ECS", Short: "Docker ECS",
Long: `run multi-container applications on Amazon ECS.`, Long: `run multi-container applications on Amazon ECS.`,
Use: name, Use: name,
Annotations: map[string]string{"experimentalCLI": "true"}, 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 { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 0 { if len(args) != 0 {
return fmt.Errorf("%q is not a docker ecs command\nSee 'docker ecs --help'", args[0]) return fmt.Errorf("%q is not a docker ecs command\nSee 'docker ecs --help'", args[0])
} }
cmd.Help()
return nil return nil
}, },
} }
cmd.AddCommand( cmd.AddCommand(
VersionCommand(), VersionCommand(),
commands.ComposeCommand(opts), commands.ComposeCommand(dockerCli),
commands.SecretCommand(opts), commands.SecretCommand(dockerCli),
commands.SetupCommand(), commands.SetupCommand(),
) )
return cmd return cmd

View File

@ -7,6 +7,7 @@ import (
cliconfig "github.com/docker/cli/cli/config" cliconfig "github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/context/store" "github.com/docker/cli/cli/context/store"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
"github.com/spf13/cobra"
) )
const contextType = "aws" const contextType = "aws"
@ -50,7 +51,7 @@ func initContextStore(contextDir string) store.Store {
return store.New(contextDir, config) return store.New(contextDir, config)
} }
func CheckAwsContextExists(contextName string) (*AwsContext, error) { func checkAwsContextExists(contextName string) (*AwsContext, error) {
if contextName == command.DefaultContextName { if contextName == command.DefaultContextName {
return nil, fmt.Errorf("can't use \"%s\" with ECS command because it is not an AWS context", contextName) 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 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)
}