From 65d115cc7c33f03c874a9902236866d9f548026e Mon Sep 17 00:00:00 2001 From: Efe Karakus Date: Mon, 10 Aug 2020 13:51:11 -0700 Subject: [PATCH] fix(cli)!: use default creds when deploying "test" env with "copilot init" (#1242) Removes the --profile flag from the "init" command as it's most likely not used + this change is the expected behavior from customers. Fixes #1068 #1104 By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. --- internal/pkg/aws/sessions/sessions.go | 17 +++++++++++++---- internal/pkg/aws/sessions/sessions_test.go | 12 ++++++------ internal/pkg/cli/env_init.go | 14 ++++++++++++-- internal/pkg/cli/init.go | 11 ++++------- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/internal/pkg/aws/sessions/sessions.go b/internal/pkg/aws/sessions/sessions.go index 9816410c689..1791f992bcb 100644 --- a/internal/pkg/aws/sessions/sessions.go +++ b/internal/pkg/aws/sessions/sessions.go @@ -12,6 +12,7 @@ import ( "sync" "time" + "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/copilot-cli/internal/pkg/version" "github.com/aws/aws-sdk-go/aws" @@ -23,7 +24,7 @@ import ( const ( userAgentHeader = "User-Agent" - credsTimeout = 10 * time.Second + credsTimeout = 10 * time.Second clientTimeout = 30 * time.Second ) @@ -65,7 +66,7 @@ func (p *Provider) Default() (*session.Session, error) { // DefaultWithRegion returns a session configured against the "default" AWS profile and the input region. func (p *Provider) DefaultWithRegion(region string) (*session.Session, error) { sess, err := session.NewSessionWithOptions(session.Options{ - Config: *newConfig().WithRegion(region), + Config: *newConfig().WithRegion(region), SharedConfigState: session.SharedConfigEnable, }) if err != nil { @@ -112,14 +113,22 @@ func (p *Provider) FromRole(roleARN string, region string) (*session.Session, er // AreCredsFromEnvVars returns true if the session's credentials provider is environment variables, false otherwise. // An error is returned if the credentials are invalid or the request times out. func AreCredsFromEnvVars(sess *session.Session) (bool, error) { + v, err := creds(sess) + if err != nil { + return false, err + } + return v.ProviderName == session.EnvProviderName, nil +} + +func creds(sess *session.Session) (credentials.Value, error) { ctx, cancel := context.WithTimeout(context.Background(), credsTimeout) defer cancel() v, err := sess.Config.Credentials.GetWithContext(ctx) if err != nil { - return false, fmt.Errorf("get credentials of session: %w", err) + return credentials.Value{}, fmt.Errorf("get credentials of session: %w", err) } - return v.ProviderName == session.EnvProviderName, nil + return v, nil } // newConfig returns a config with an end-to-end request timeout and verbose credentials errors. diff --git a/internal/pkg/aws/sessions/sessions_test.go b/internal/pkg/aws/sessions/sessions_test.go index e988d6343c9..7d17d7f900c 100644 --- a/internal/pkg/aws/sessions/sessions_test.go +++ b/internal/pkg/aws/sessions/sessions_test.go @@ -16,7 +16,7 @@ import ( // mockProvider implements the AWS SDK's credentials.Provider interface. type mockProvider struct { value credentials.Value - err error + err error } func (m mockProvider) Retrieve() (credentials.Value, error) { @@ -34,9 +34,9 @@ func TestAreCredsFromEnvVars(t *testing.T) { testCases := map[string]struct { inSess *session.Session - wantedOk bool + wantedOk bool wantedErr error - } { + }{ "returns true if the credentials come from environment variables": { inSess: &session.Session{ Config: &aws.Config{ @@ -44,7 +44,7 @@ func TestAreCredsFromEnvVars(t *testing.T) { value: credentials.Value{ ProviderName: session.EnvProviderName, }, - err: nil, + err: nil, }), }, }, @@ -57,7 +57,7 @@ func TestAreCredsFromEnvVars(t *testing.T) { value: credentials.Value{ ProviderName: credentials.SharedCredsProviderName, }, - err: nil, + err: nil, }), }, }, @@ -81,7 +81,7 @@ func TestAreCredsFromEnvVars(t *testing.T) { ok, err := AreCredsFromEnvVars(tc.inSess) if tc.wantedErr != nil { - require.EqualError(t, tc.wantedErr, err.Error()) + require.EqualError(t, err, tc.wantedErr.Error()) } else { require.Equal(t, tc.wantedOk, ok) } diff --git a/internal/pkg/cli/env_init.go b/internal/pkg/cli/env_init.go index 3cb4f5e577d..0a39ad24001 100644 --- a/internal/pkg/cli/env_init.go +++ b/internal/pkg/cli/env_init.go @@ -124,7 +124,7 @@ type initEnvOpts struct { configureRuntimeClients func(*initEnvOpts) error } -func configureInitEnvClients(o *initEnvOpts) error { +func configureInitEnvFromFlags(o *initEnvOpts) error { var sess *session.Session if o.Profile != "" { profileSess, err := sessions.NewProvider().FromProfile(o.Profile) @@ -150,6 +150,16 @@ func configureInitEnvClients(o *initEnvOpts) error { return nil } +func configureInitEnvFromDefaultSess(o *initEnvOpts) error { + sess, err := sessions.NewProvider().Default() + if err != nil { + return fmt.Errorf("create default session: %w", err) + } + o.envIdentity = identity.New(sess) + o.envDeployer = deploycfn.New(sess) + return nil +} + func newInitEnvOpts(vars initEnvVars) (*initEnvOpts, error) { store, err := config.NewStore() if err != nil { @@ -171,7 +181,7 @@ func newInitEnvOpts(vars initEnvVars) (*initEnvOpts, error) { identity: identity.New(defaultSession), profileConfig: cfg, prog: termprogress.NewSpinner(), - configureRuntimeClients: configureInitEnvClients, + configureRuntimeClients: configureInitEnvFromFlags, }, nil } diff --git a/internal/pkg/cli/init.go b/internal/pkg/cli/init.go index 94e616bfbf3..3c762d53638 100644 --- a/internal/pkg/cli/init.go +++ b/internal/pkg/cli/init.go @@ -44,7 +44,6 @@ type initVars struct { svcType string svcName string dockerfilePath string - profile string imageTag string port uint16 } @@ -81,14 +80,14 @@ func newInitOpts(vars initVars) (*initOpts, error) { return nil, err } sessProvider := sessions.NewProvider() - sess, err := sessProvider.Default() + defaultSess, err := sessProvider.Default() if err != nil { return nil, err } prompt := prompt.New() spin := termprogress.NewSpinner() - id := identity.New(sess) - deployer := cloudformation.New(sess) + id := identity.New(defaultSess) + deployer := cloudformation.New(defaultSess) cfg, err := profile.NewConfig() if err != nil { return nil, err @@ -126,7 +125,6 @@ func newInitOpts(vars initVars) (*initOpts, error) { initEnvVars: initEnvVars{ GlobalOpts: NewGlobalOpts(), Name: defaultEnvironmentName, - Profile: vars.profile, IsProduction: false, }, store: ssm, @@ -135,7 +133,7 @@ func newInitOpts(vars initVars) (*initOpts, error) { prog: spin, identity: id, - configureRuntimeClients: configureInitEnvClients, + configureRuntimeClients: configureInitEnvFromDefaultSess, } deploySvcCmd := &deploySvcOpts{ @@ -293,7 +291,6 @@ func BuildInitCmd() *cobra.Command { return nil }), } - cmd.Flags().StringVar(&vars.profile, profileFlag, defaultEnvironmentProfile, profileFlagDescription) cmd.Flags().StringVarP(&vars.appName, appFlag, appFlagShort, "", appFlagDescription) cmd.Flags().StringVarP(&vars.svcName, svcFlag, svcFlagShort, "", svcFlagDescription) cmd.Flags().StringVarP(&vars.svcType, svcTypeFlag, svcTypeFlagShort, "", svcTypeFlagDescription)