github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/cloud/detectcredentials_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cloud_test 5 6 import ( 7 "fmt" 8 "io" 9 "regexp" 10 "strings" 11 12 "github.com/juju/cmd" 13 "github.com/juju/errors" 14 jc "github.com/juju/testing/checkers" 15 gc "gopkg.in/check.v1" 16 17 jujucloud "github.com/juju/juju/cloud" 18 "github.com/juju/juju/cmd/juju/cloud" 19 "github.com/juju/juju/environs" 20 "github.com/juju/juju/jujuclient/jujuclienttesting" 21 "github.com/juju/juju/testing" 22 ) 23 24 type detectCredentialsSuite struct { 25 store *jujuclienttesting.MemStore 26 aCredential jujucloud.CloudCredential 27 } 28 29 var _ = gc.Suite(&detectCredentialsSuite{}) 30 31 type mockProvider struct { 32 environs.EnvironProvider 33 detectedCreds *jujucloud.CloudCredential 34 credSchemas *map[jujucloud.AuthType]jujucloud.CredentialSchema 35 } 36 37 func (p *mockProvider) DetectCredentials() (*jujucloud.CloudCredential, error) { 38 if len(p.detectedCreds.AuthCredentials) == 0 { 39 return nil, errors.NotFoundf("credentials") 40 } 41 return p.detectedCreds, nil 42 } 43 44 func (p *mockProvider) CredentialSchemas() map[jujucloud.AuthType]jujucloud.CredentialSchema { 45 if p.credSchemas == nil { 46 return map[jujucloud.AuthType]jujucloud.CredentialSchema{ 47 jujucloud.AccessKeyAuthType: { 48 { 49 "access-key", jujucloud.CredentialAttr{}, 50 }, { 51 "secret-key", jujucloud.CredentialAttr{Hidden: true}, 52 }, 53 }, 54 jujucloud.UserPassAuthType: { 55 { 56 "username", jujucloud.CredentialAttr{}, 57 }, { 58 "password", jujucloud.CredentialAttr{Hidden: true}, 59 }, { 60 "application-password", jujucloud.CredentialAttr{Hidden: true}, 61 }, 62 }, 63 jujucloud.OAuth2AuthType: { 64 { 65 "client-id", jujucloud.CredentialAttr{}, 66 }, { 67 "client-email", jujucloud.CredentialAttr{}, 68 }, { 69 "private-key", jujucloud.CredentialAttr{Hidden: true}, 70 }, { 71 "project-id", jujucloud.CredentialAttr{}, 72 }, 73 }, 74 } 75 } 76 return *p.credSchemas 77 } 78 79 func (s *detectCredentialsSuite) SetUpSuite(c *gc.C) { 80 environs.RegisterProvider("mock-provider", &mockProvider{detectedCreds: &s.aCredential}) 81 } 82 83 func (s *detectCredentialsSuite) SetUpTest(c *gc.C) { 84 s.store = jujuclienttesting.NewMemStore() 85 s.aCredential = jujucloud.CloudCredential{} 86 } 87 88 func (s *detectCredentialsSuite) run(c *gc.C, stdin io.Reader, clouds map[string]jujucloud.Cloud) (*cmd.Context, error) { 89 registeredProvidersFunc := func() []string { 90 return []string{"mock-provider"} 91 } 92 allCloudsFunc := func() (map[string]jujucloud.Cloud, error) { 93 return clouds, nil 94 } 95 cloudByNameFunc := func(cloudName string) (*jujucloud.Cloud, error) { 96 if cloud, ok := clouds[cloudName]; ok { 97 return &cloud, nil 98 } 99 return nil, errors.NotFoundf("cloud %s", cloudName) 100 } 101 command := cloud.NewDetectCredentialsCommandForTest(s.store, registeredProvidersFunc, allCloudsFunc, cloudByNameFunc) 102 err := testing.InitCommand(command, nil) 103 c.Assert(err, jc.ErrorIsNil) 104 ctx := testing.Context(c) 105 ctx.Stdin = stdin 106 return ctx, command.Run(ctx) 107 } 108 109 func (s *detectCredentialsSuite) credentialWithLabel(authType jujucloud.AuthType, label string) jujucloud.Credential { 110 cred := jujucloud.NewCredential(authType, nil) 111 cred.Label = label 112 return cred 113 } 114 115 func (s *detectCredentialsSuite) assertDetectCredential(c *gc.C, cloudName, expectedRegion, errText string) { 116 s.aCredential = jujucloud.CloudCredential{ 117 DefaultRegion: "default region", 118 AuthCredentials: map[string]jujucloud.Credential{ 119 "test": s.credentialWithLabel(jujucloud.AccessKeyAuthType, "credential")}, 120 } 121 clouds := map[string]jujucloud.Cloud{ 122 "test-cloud": { 123 Type: "mock-provider", 124 }, 125 "another-cloud": { 126 Type: "another-provider", 127 }, 128 } 129 130 stdin := strings.NewReader(fmt.Sprintf("1\n%s\nQ\n", cloudName)) 131 ctx, err := s.run(c, stdin, clouds) 132 c.Assert(err, jc.ErrorIsNil) 133 if errText == "" { 134 if expectedRegion != "" { 135 s.aCredential.DefaultRegion = expectedRegion 136 } 137 c.Assert(s.store.Credentials["test-cloud"], jc.DeepEquals, s.aCredential) 138 } else { 139 output := strings.Replace(testing.Stderr(ctx), "\n", "", -1) 140 c.Assert(output, gc.Matches, ".*"+regexp.QuoteMeta(errText)+".*") 141 } 142 } 143 144 func (s *detectCredentialsSuite) TestDetectNewCredential(c *gc.C) { 145 s.assertDetectCredential(c, "test-cloud", "", "") 146 } 147 148 func (s *detectCredentialsSuite) TestDetectCredentialOverwrites(c *gc.C) { 149 s.store.Credentials = map[string]jujucloud.CloudCredential{ 150 "test-cloud": { 151 AuthCredentials: map[string]jujucloud.Credential{ 152 "test": jujucloud.NewCredential(jujucloud.AccessKeyAuthType, nil), 153 }, 154 }, 155 } 156 s.assertDetectCredential(c, "test-cloud", "", "") 157 } 158 159 func (s *detectCredentialsSuite) TestDetectCredentialKeepsExistingRegion(c *gc.C) { 160 s.store.Credentials = map[string]jujucloud.CloudCredential{ 161 "test-cloud": { 162 DefaultRegion: "west", 163 AuthCredentials: map[string]jujucloud.Credential{ 164 "test": jujucloud.NewCredential(jujucloud.AccessKeyAuthType, nil), 165 }, 166 }, 167 } 168 s.assertDetectCredential(c, "test-cloud", "west", "") 169 } 170 171 func (s *detectCredentialsSuite) TestDetectCredentialDefaultCloud(c *gc.C) { 172 s.assertDetectCredential(c, "", "", "") 173 } 174 175 func (s *detectCredentialsSuite) TestDetectCredentialUnknownCloud(c *gc.C) { 176 s.assertDetectCredential(c, "foo", "", "cloud foo not valid") 177 } 178 179 func (s *detectCredentialsSuite) TestDetectCredentialInvalidCloud(c *gc.C) { 180 s.assertDetectCredential(c, "another-cloud", "", "chosen credentials not compatible with a another-provider cloud") 181 } 182 183 func (s *detectCredentialsSuite) TestNewDetectCredentialNoneFound(c *gc.C) { 184 stdin := strings.NewReader("") 185 ctx, err := s.run(c, stdin, nil) 186 c.Assert(err, jc.ErrorIsNil) 187 output := strings.Replace(testing.Stderr(ctx), "\n", "", -1) 188 c.Assert(output, gc.Matches, ".*No cloud credentials found.*") 189 c.Assert(s.store.Credentials, gc.HasLen, 0) 190 } 191 192 func (s *detectCredentialsSuite) TestDetectCredentialInvalidChoice(c *gc.C) { 193 s.aCredential = jujucloud.CloudCredential{ 194 DefaultRegion: "detected region", 195 AuthCredentials: map[string]jujucloud.Credential{ 196 "test": s.credentialWithLabel(jujucloud.AccessKeyAuthType, "credential 1"), 197 "another": s.credentialWithLabel(jujucloud.AccessKeyAuthType, "credential 2")}, 198 } 199 200 stdin := strings.NewReader("3\nQ\n") 201 ctx, err := s.run(c, stdin, nil) 202 c.Assert(err, jc.ErrorIsNil) 203 output := strings.Replace(testing.Stderr(ctx), "\n", "", -1) 204 c.Assert(output, gc.Matches, ".*Invalid choice, enter a number between 1 and 2.*") 205 c.Assert(s.store.Credentials, gc.HasLen, 0) 206 }