From efeded2670a8ae45ae8dbe0dc2fd58889f120ca8 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Thu, 16 Jul 2020 08:28:17 +0200 Subject: [PATCH] Remove Cluster from context Signed-off-by: Nicolas De Loof --- ecs/cmd/commands/compose.go | 10 ++-- ecs/cmd/commands/context.go | 31 +++++++++++ ecs/cmd/commands/secret.go | 8 +-- ecs/cmd/commands/setup.go | 52 ++++++++----------- ecs/pkg/amazon/backend/backend.go | 12 ++--- ecs/pkg/amazon/backend/cloudformation_test.go | 8 +-- ecs/pkg/amazon/backend/context.go | 22 ++++---- ecs/pkg/amazon/backend/down.go | 8 +-- ecs/pkg/amazon/backend/up.go | 2 +- ecs/pkg/docker/contextStore.go | 30 ++--------- ecs/tests/main_test.go | 2 +- 11 files changed, 90 insertions(+), 95 deletions(-) create mode 100644 ecs/cmd/commands/context.go diff --git a/ecs/cmd/commands/compose.go b/ecs/cmd/commands/compose.go index 551b5370a..bceba59b6 100644 --- a/ecs/cmd/commands/compose.go +++ b/ecs/cmd/commands/compose.go @@ -45,7 +45,7 @@ func (o upOptions) LoadBalancerArn() *string { func ConvertCommand(dockerCli command.Cli, options *cli.ProjectOptions) *cobra.Command { cmd := &cobra.Command{ Use: "convert", - RunE: docker.WithAwsContext(dockerCli, func(ctx docker.AwsContext, backend *amazon.Backend, args []string) error { + RunE: WithAwsContext(dockerCli, func(ctx docker.AwsContext, backend *amazon.Backend, args []string) error { opts := options.WithOsEnv() project, err := cli.ProjectFromOptions(&opts) if err != nil { @@ -72,7 +72,7 @@ func UpCommand(dockerCli command.Cli, options *cli.ProjectOptions) *cobra.Comman opts := upOptions{} cmd := &cobra.Command{ Use: "up", - RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error { + RunE: WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error { return backend.Up(context.Background(), *options) }), } @@ -84,7 +84,7 @@ func PsCommand(dockerCli command.Cli, options *cli.ProjectOptions) *cobra.Comman opts := upOptions{} cmd := &cobra.Command{ Use: "ps", - RunE: docker.WithAwsContext(dockerCli, func(ctx docker.AwsContext, backend *amazon.Backend, args []string) error { + RunE: WithAwsContext(dockerCli, func(ctx docker.AwsContext, backend *amazon.Backend, args []string) error { status, err := backend.Ps(context.Background(), *options) if err != nil { return err @@ -109,7 +109,7 @@ func DownCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra. opts := downOptions{} cmd := &cobra.Command{ Use: "down", - RunE: docker.WithAwsContext(dockerCli, func(ctx docker.AwsContext, backend *amazon.Backend, args []string) error { + RunE: WithAwsContext(dockerCli, func(ctx docker.AwsContext, backend *amazon.Backend, args []string) error { return backend.Down(context.Background(), *projectOpts) }), } @@ -120,7 +120,7 @@ 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, backend *amazon.Backend, args []string) error { + RunE: WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error { return backend.Logs(context.Background(), *projectOpts) }), } diff --git a/ecs/cmd/commands/context.go b/ecs/cmd/commands/context.go new file mode 100644 index 000000000..080d3b7d9 --- /dev/null +++ b/ecs/cmd/commands/context.go @@ -0,0 +1,31 @@ +package commands + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/docker/cli/cli/command" + amazon "github.com/docker/ecs-plugin/pkg/amazon/backend" + "github.com/docker/ecs-plugin/pkg/docker" + "github.com/spf13/cobra" +) + +type ContextFunc func(ctx docker.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 { + ctx, err := docker.GetAwsContext(dockerCli) + if err != nil { + return err + } + backend, err := amazon.NewBackend(ctx.Profile, 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 + } +} diff --git a/ecs/cmd/commands/secret.go b/ecs/cmd/commands/secret.go index 5bbefaa9b..3246e1237 100644 --- a/ecs/cmd/commands/secret.go +++ b/ecs/cmd/commands/secret.go @@ -47,7 +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, backend *amazon.Backend, args []string) error { + RunE: WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error { if len(args) == 0 { return errors.New("Missing mandatory parameter: NAME") } @@ -69,7 +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, backend *amazon.Backend, args []string) error { + RunE: WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error { if len(args) == 0 { return errors.New("Missing mandatory parameter: ID") } @@ -94,7 +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, backend *amazon.Backend, args []string) error { + RunE: WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error { secrets, err := backend.ListSecrets(context.Background()) if err != nil { return err @@ -113,7 +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, backend *amazon.Backend, args []string) error { + RunE: WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, backend *amazon.Backend, args []string) error { if len(args) == 0 { return errors.New("Missing mandatory parameter: [NAME]") } diff --git a/ecs/cmd/commands/setup.go b/ecs/cmd/commands/setup.go index c6ac612ce..da733f715 100644 --- a/ecs/cmd/commands/setup.go +++ b/ecs/cmd/commands/setup.go @@ -22,17 +22,18 @@ const enterLabelPrefix = "Enter " type setupOptions struct { name string - context contextStore.AwsContext + profile string + region string accessKeyID string secretAccessKey string } func (s setupOptions) unsetRequiredArgs() []string { unset := []string{} - if s.context.Profile == "" { + if s.profile == "" { unset = append(unset, "profile") } - if s.context.Region == "" { + if s.region == "" { unset = append(unset, "region") } return unset @@ -51,25 +52,28 @@ func SetupCommand() *cobra.Command { } } if opts.accessKeyID != "" && opts.secretAccessKey != "" { - if err := saveCredentials(opts.context.Profile, opts.accessKeyID, opts.secretAccessKey); err != nil { + if err := saveCredentials(opts.profile, opts.accessKeyID, opts.secretAccessKey); err != nil { return err } } - backend, err := amazon.NewBackend(opts.context.Profile, opts.context.Cluster, opts.context.Region) + backend, err := amazon.NewBackend(opts.profile, opts.region) if err != nil { return err } - _, _, err = backend.CreateContextData(context.Background(), nil) + + context, _, err := backend.CreateContextData(context.Background(), map[string]string{ + amazon.ContextParamProfile: opts.profile, + amazon.ContextParamRegion: opts.region, + }) if err != nil { return err } - return contextStore.NewContext(opts.name, &opts.context) + return contextStore.NewContext(opts.name, context) }, } cmd.Flags().StringVarP(&opts.name, "name", "n", "ecs", "Context Name") - cmd.Flags().StringVarP(&opts.context.Profile, "profile", "p", "", "AWS Profile") - cmd.Flags().StringVarP(&opts.context.Cluster, "cluster", "c", "", "ECS cluster") - cmd.Flags().StringVarP(&opts.context.Region, "region", "r", "", "AWS region") + cmd.Flags().StringVarP(&opts.profile, "profile", "p", "", "AWS Profile") + cmd.Flags().StringVarP(&opts.region, "region", "r", "", "AWS region") cmd.Flags().StringVarP(&opts.accessKeyID, "aws-key-id", "k", "", "AWS Access Key ID") cmd.Flags().StringVarP(&opts.secretAccessKey, "aws-secret-key", "s", "", "AWS Secret Access Key") @@ -88,10 +92,6 @@ func interactiveCli(opts *setupOptions) error { return err } - if err := setCluster(opts, err); err != nil { - return err - } - if err := setRegion(opts, section); err != nil { return err } @@ -156,7 +156,7 @@ func awsProfiles(filename string) (map[string]ini.Section, error) { } func setContextName(opts *setupOptions) error { - if opts.name == "aws" { + if opts.name == "ecs" { result, err := promptString(opts.name, "context name", enterLabelPrefix, 2) if err != nil { return err @@ -171,7 +171,7 @@ func setProfile(opts *setupOptions, section ini.Section) (ini.Section, error) { if err != nil { return ini.Section{}, err } - section, ok := profilesList[opts.context.Profile] + section, ok := profilesList[opts.profile] if !ok { prompt := promptui.Select{ Label: "Select AWS Profile", @@ -179,14 +179,14 @@ func setProfile(opts *setupOptions, section ini.Section) (ini.Section, error) { } _, result, err := prompt.Run() if result == "new profile" { - result, err := promptString(opts.context.Profile, "profile name", enterLabelPrefix, 2) + result, err := promptString(opts.profile, "profile name", enterLabelPrefix, 2) if err != nil { return ini.Section{}, err } - opts.context.Profile = result + opts.profile = result } else { section = profilesList[result] - opts.context.Profile = result + opts.profile = result } if err != nil { return ini.Section{}, err @@ -196,7 +196,7 @@ func setProfile(opts *setupOptions, section ini.Section) (ini.Section, error) { } func setRegion(opts *setupOptions, section ini.Section) error { - defaultRegion := opts.context.Region + defaultRegion := opts.region if defaultRegion == "" && section.Name() != "" { region, err := section.GetKey("region") if err == nil { @@ -207,17 +207,7 @@ func setRegion(opts *setupOptions, section ini.Section) error { if err != nil { return err } - opts.context.Region = result - return nil -} - -func setCluster(opts *setupOptions, err error) error { - result, err := promptString(opts.context.Cluster, "cluster name", enterLabelPrefix, 0) - if err != nil { - return err - } - - opts.context.Cluster = result + opts.region = result return nil } diff --git a/ecs/pkg/amazon/backend/backend.go b/ecs/pkg/amazon/backend/backend.go index 07764df35..f5bba4ed2 100644 --- a/ecs/pkg/amazon/backend/backend.go +++ b/ecs/pkg/amazon/backend/backend.go @@ -6,7 +6,7 @@ import ( "github.com/docker/ecs-plugin/pkg/amazon/sdk" ) -func NewBackend(profile string, cluster string, region string) (*Backend, error) { +func NewBackend(profile string, region string) (*Backend, error) { sess, err := session.NewSessionWithOptions(session.Options{ Profile: profile, Config: aws.Config{ @@ -17,14 +17,12 @@ func NewBackend(profile string, cluster string, region string) (*Backend, error) return nil, err } return &Backend{ - Cluster: cluster, - Region: region, - api: sdk.NewAPI(sess), + Region: region, + api: sdk.NewAPI(sess), }, nil } type Backend struct { - Cluster string - Region string - api sdk.API + Region string + api sdk.API } diff --git a/ecs/pkg/amazon/backend/cloudformation_test.go b/ecs/pkg/amazon/backend/cloudformation_test.go index 032b9cd58..a364bfaff 100644 --- a/ecs/pkg/amazon/backend/cloudformation_test.go +++ b/ecs/pkg/amazon/backend/cloudformation_test.go @@ -21,7 +21,7 @@ import ( func TestSimpleConvert(t *testing.T) { project := load(t, "testdata/input/simple-single-service.yaml") - result := convertResultAsString(t, project, "TestCluster") + result := convertResultAsString(t, project) expected := "simple/simple-cloudformation-conversion.golden" golden.Assert(t, result, expected) } @@ -197,10 +197,10 @@ services: } } -func convertResultAsString(t *testing.T, project *types.Project, clusterName string) string { - client, err := NewBackend("", clusterName, "") +func convertResultAsString(t *testing.T, project *types.Project) string { + backend, err := NewBackend("", "") assert.NilError(t, err) - result, err := client.Convert(project) + result, err := backend.Convert(project) assert.NilError(t, err) resultAsJSON, err := result.JSON() assert.NilError(t, err) diff --git a/ecs/pkg/amazon/backend/context.go b/ecs/pkg/amazon/backend/context.go index bc785d91a..f6f79f4e1 100644 --- a/ecs/pkg/amazon/backend/context.go +++ b/ecs/pkg/amazon/backend/context.go @@ -2,7 +2,13 @@ package backend import ( "context" - "fmt" + + "github.com/docker/ecs-plugin/pkg/docker" +) + +const ( + ContextParamRegion = "region" + ContextParamProfile = "profile" ) func (b *Backend) CreateContextData(ctx context.Context, params map[string]string) (contextData interface{}, description string, err error) { @@ -11,14 +17,8 @@ func (b *Backend) CreateContextData(ctx context.Context, params map[string]strin return "", "", err } - if b.Cluster != "" { - exists, err := b.api.ClusterExists(ctx, b.Cluster) - if err != nil { - return "", "", err - } - if !exists { - return "", "", fmt.Errorf("cluster %s does not exists", b.Cluster) - } - } - return "", "", nil + return docker.AwsContext{ + Profile: params[ContextParamProfile], + Region: params[ContextParamRegion], + }, "Amazon ECS context", nil } diff --git a/ecs/pkg/amazon/backend/down.go b/ecs/pkg/amazon/backend/down.go index 45a7f844e..31df94fca 100644 --- a/ecs/pkg/amazon/backend/down.go +++ b/ecs/pkg/amazon/backend/down.go @@ -9,12 +9,12 @@ import ( ) func (b *Backend) Down(ctx context.Context, options cli.ProjectOptions) error { - name, err2 := b.projectName(options) - if err2 != nil { - return err2 + name, err := b.projectName(options) + if err != nil { + return err } - err := b.api.DeleteStack(ctx, name) + err = b.api.DeleteStack(ctx, name) if err != nil { return err } diff --git a/ecs/pkg/amazon/backend/up.go b/ecs/pkg/amazon/backend/up.go index e91f11916..8b975dc5e 100644 --- a/ecs/pkg/amazon/backend/up.go +++ b/ecs/pkg/amazon/backend/up.go @@ -123,5 +123,5 @@ func (b Backend) GetCluster(ctx context.Context, project *types.Project) (string } return cluster, nil } - return b.Cluster, nil + return "", nil } diff --git a/ecs/pkg/docker/contextStore.go b/ecs/pkg/docker/contextStore.go index 83c055f68..30a12de21 100644 --- a/ecs/pkg/docker/contextStore.go +++ b/ecs/pkg/docker/contextStore.go @@ -3,13 +3,10 @@ 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" ) const contextType = "aws" @@ -24,16 +21,15 @@ func getter() interface{} { type AwsContext struct { Profile string - Cluster string Region string } -func NewContext(name string, awsContext *AwsContext) error { - _, err := NewContextWithStore(name, awsContext, cliconfig.ContextStoreDir()) +func NewContext(name string, awsContext interface{}) error { + _, err := NewContextWithStore(name, awsContext.(AwsContext), cliconfig.ContextStoreDir()) return err } -func NewContextWithStore(name string, awsContext *AwsContext, contextDirectory string) (store.Store, error) { +func NewContextWithStore(name string, awsContext AwsContext, contextDirectory string) (store.Store, error) { contextStore := initContextStore(contextDirectory) endpoints := map[string]interface{}{ "aws": awsContext, @@ -74,26 +70,6 @@ func checkAwsContextExists(contextName string) (*AwsContext, error) { return &awsContext, nil } -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 { - ctx, err := GetAwsContext(dockerCli) - if err != nil { - return err - } - 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 - } -} - func GetAwsContext(dockerCli command.Cli) (*AwsContext, error) { contextName := dockerCli.CurrentContext() return checkAwsContextExists(contextName) diff --git a/ecs/tests/main_test.go b/ecs/tests/main_test.go index b8a758144..5849e4060 100644 --- a/ecs/tests/main_test.go +++ b/ecs/tests/main_test.go @@ -58,7 +58,7 @@ func (d dockerCliCommand) createTestCmd(ops ...ConfigFileOperator) (icmd.Cmd, fu Profile: "sandbox.devtools.developer", Region: "eu-west-3", } - testStore, err := docker.NewContextWithStore(testContextName, &awsContext, filepath.Join(configDir, "contexts")) + testStore, err := docker.NewContextWithStore(testContextName, awsContext, filepath.Join(configDir, "contexts")) if err != nil { panic(err) }