github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/modelcmd/credentials_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package modelcmd_test 5 6 import ( 7 "fmt" 8 "io/ioutil" 9 "path/filepath" 10 11 "github.com/golang/mock/gomock" 12 "github.com/juju/cmd/cmdtesting" 13 "github.com/juju/errors" 14 "github.com/juju/testing" 15 jc "github.com/juju/testing/checkers" 16 gc "gopkg.in/check.v1" 17 18 "github.com/juju/juju/cloud" 19 "github.com/juju/juju/cmd/modelcmd" 20 "github.com/juju/juju/environs" 21 "github.com/juju/juju/jujuclient" 22 _ "github.com/juju/juju/provider/dummy" 23 ) 24 25 func init() { 26 dummyProvider, err := environs.Provider("dummy") 27 if err != nil { 28 panic(err) 29 } 30 // dummy does implement CloudEnvironProvider 31 asCloud := dummyProvider.(environs.CloudEnvironProvider) 32 environs.RegisterProvider("fake", mockProvider{asCloud}) 33 } 34 35 type mockProvider struct { 36 environs.CloudEnvironProvider 37 } 38 39 func (mockProvider) CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema { 40 schema := cloud.CredentialSchema{ 41 { 42 "username", cloud.CredentialAttr{}, 43 }, { 44 "password", cloud.CredentialAttr{}, 45 }, { 46 "key", cloud.CredentialAttr{FileAttr: "key-file"}, 47 }, 48 } 49 return map[cloud.AuthType]cloud.CredentialSchema{ 50 cloud.UserPassAuthType: schema, 51 "interactive": { 52 {"username", cloud.CredentialAttr{}}, 53 }, 54 } 55 } 56 57 func (mockProvider) FinalizeCredential( 58 ctx environs.FinalizeCredentialContext, 59 args environs.FinalizeCredentialParams, 60 ) (*cloud.Credential, error) { 61 if args.Credential.AuthType() == "interactive" { 62 username := args.Credential.Attributes()["username"] 63 fmt.Fprintf(ctx.GetStderr(), "generating credential for %q\n", username) 64 out := cloud.NewCredential(cloud.UserPassAuthType, map[string]string{ 65 "username": username, 66 "password": "sekret", 67 "key": "value", 68 }) 69 return &out, nil 70 } 71 return &args.Credential, nil 72 } 73 74 type credentialsSuite struct { 75 testing.IsolationSuite 76 cloud cloud.Cloud 77 store *jujuclient.MemStore 78 } 79 80 var _ = gc.Suite(&credentialsSuite{}) 81 82 func (s *credentialsSuite) SetUpTest(c *gc.C) { 83 s.IsolationSuite.SetUpTest(c) 84 s.cloud = cloud.Cloud{ 85 Name: "cloud", 86 Type: "fake", 87 Regions: []cloud.Region{ 88 {Name: "first-region"}, 89 {Name: "second-region"}, 90 }, 91 } 92 93 dir := c.MkDir() 94 keyFile := filepath.Join(dir, "keyfile") 95 err := ioutil.WriteFile(keyFile, []byte("value"), 0600) 96 c.Assert(err, jc.ErrorIsNil) 97 98 s.store = jujuclient.NewMemStore() 99 s.store.Credentials["cloud"] = cloud.CloudCredential{ 100 DefaultRegion: "second-region", 101 AuthCredentials: map[string]cloud.Credential{ 102 "interactive": cloud.NewCredential("interactive", map[string]string{ 103 "username": "user", 104 }), 105 "secrets": cloud.NewCredential(cloud.UserPassAuthType, map[string]string{ 106 "username": "user", 107 "password": "sekret", 108 "key-file": keyFile, 109 }), 110 }, 111 } 112 } 113 114 func (s *credentialsSuite) assertGetCredentials(c *gc.C, cred, region string) { 115 credential, credentialName, regionName, err := modelcmd.GetCredentials( 116 cmdtesting.Context(c), s.store, modelcmd.GetCredentialsParams{ 117 Cloud: s.cloud, 118 CloudRegion: region, 119 CredentialName: cred, 120 }, 121 ) 122 c.Assert(err, jc.ErrorIsNil) 123 expectedRegion := region 124 if expectedRegion == "" { 125 expectedRegion = s.store.Credentials["cloud"].DefaultRegion 126 } 127 c.Assert(regionName, gc.Equals, expectedRegion) 128 c.Assert(credentialName, gc.Equals, cred) 129 c.Assert(credential.Attributes(), jc.DeepEquals, map[string]string{ 130 "key": "value", 131 "username": "user", 132 "password": "sekret", 133 }) 134 } 135 136 func (s *credentialsSuite) TestGetCredentialsUserDefaultRegion(c *gc.C) { 137 s.assertGetCredentials(c, "secrets", "") 138 } 139 140 func (s *credentialsSuite) TestGetCredentialsCloudDefaultRegion(c *gc.C) { 141 creds := s.store.Credentials["cloud"] 142 creds.DefaultRegion = "" 143 s.store.Credentials["cloud"] = creds 144 s.assertGetCredentials(c, "secrets", "") 145 } 146 147 func (s *credentialsSuite) TestGetCredentialsNoRegion(c *gc.C) { 148 creds := s.store.Credentials["cloud"] 149 creds.DefaultRegion = "" 150 s.store.Credentials["cloud"] = creds 151 s.cloud.Regions = nil 152 s.assertGetCredentials(c, "secrets", "") 153 } 154 155 func (s *credentialsSuite) TestGetCredentials(c *gc.C) { 156 s.cloud.Regions = append(s.cloud.Regions, cloud.Region{Name: "third-region"}) 157 s.assertGetCredentials(c, "secrets", "third-region") 158 } 159 160 func (s *credentialsSuite) TestGetCredentialsProviderFinalizeCredential(c *gc.C) { 161 s.assertGetCredentials(c, "interactive", "") 162 } 163 164 func (s *credentialsSuite) TestRegisterCredentials(c *gc.C) { 165 ctrl := gomock.NewController(c) 166 defer ctrl.Finish() 167 168 mockProvider := modelcmd.NewMockTestCloudProvider(ctrl) 169 170 credential := map[string]*cloud.CloudCredential{ 171 "fake": { 172 AuthCredentials: map[string]cloud.Credential{ 173 "admin": cloud.NewCredential("certificate", map[string]string{ 174 "cert": "certificate", 175 }), 176 }, 177 }, 178 } 179 180 exp := mockProvider.EXPECT() 181 exp.RegisterCredentials(cloud.Cloud{ 182 Name: "fake", 183 }).Return(credential, nil) 184 185 credentials, err := modelcmd.RegisterCredentials(mockProvider, modelcmd.RegisterCredentialsParams{ 186 Cloud: cloud.Cloud{ 187 Name: "fake", 188 }, 189 }) 190 c.Assert(err, jc.ErrorIsNil) 191 c.Assert(credentials, gc.DeepEquals, credential) 192 } 193 194 func (s *credentialsSuite) TestRegisterCredentialsWithNoCredentials(c *gc.C) { 195 ctrl := gomock.NewController(c) 196 defer ctrl.Finish() 197 198 mockProvider := modelcmd.NewMockTestCloudProvider(ctrl) 199 200 credential := map[string]*cloud.CloudCredential{} 201 202 exp := mockProvider.EXPECT() 203 exp.RegisterCredentials(cloud.Cloud{ 204 Name: "fake", 205 }).Return(credential, nil) 206 207 credentials, err := modelcmd.RegisterCredentials(mockProvider, modelcmd.RegisterCredentialsParams{ 208 Cloud: cloud.Cloud{ 209 Name: "fake", 210 }, 211 }) 212 c.Assert(errors.Cause(err).Error(), gc.Matches, `credentials for provider not found`) 213 c.Assert(credentials, gc.IsNil) 214 } 215 216 func (s *credentialsSuite) TestRegisterCredentialsWithCallFailure(c *gc.C) { 217 ctrl := gomock.NewController(c) 218 defer ctrl.Finish() 219 220 mockProvider := modelcmd.NewMockTestCloudProvider(ctrl) 221 222 exp := mockProvider.EXPECT() 223 exp.RegisterCredentials(cloud.Cloud{ 224 Name: "fake", 225 }).Return(nil, errors.New("bad")) 226 227 credentials, err := modelcmd.RegisterCredentials(mockProvider, modelcmd.RegisterCredentialsParams{ 228 Cloud: cloud.Cloud{ 229 Name: "fake", 230 }, 231 }) 232 c.Assert(err.Error(), gc.Matches, `registering credentials for provider: bad`) 233 c.Assert(credentials, gc.IsNil) 234 }