github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/provider/joyent/config_test.go (about) 1 // Copyright 2013 Joyent Inc. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package joyent_test 5 6 import ( 7 "fmt" 8 "os" 9 10 "github.com/juju/testing" 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/environs" 16 "github.com/juju/juju/environs/config" 17 envtesting "github.com/juju/juju/environs/testing" 18 jp "github.com/juju/juju/provider/joyent" 19 coretesting "github.com/juju/juju/testing" 20 "github.com/juju/juju/utils/ssh" 21 ) 22 23 func newConfig(c *gc.C, attrs coretesting.Attrs) *config.Config { 24 attrs = coretesting.FakeConfig().Merge(attrs) 25 cfg, err := config.New(config.UseDefaults, attrs) 26 c.Assert(err, jc.ErrorIsNil) 27 return cfg 28 } 29 30 func validAttrs() coretesting.Attrs { 31 return coretesting.FakeConfig().Merge(coretesting.Attrs{ 32 "type": "joyent", 33 "sdc-user": "test", 34 "sdc-key-id": "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff", 35 "sdc-url": "test://test.api.joyentcloud.com", 36 "manta-user": "test", 37 "manta-key-id": "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff", 38 "manta-url": "test://test.manta.joyent.com", 39 "private-key-path": "~/.ssh/provider_id_rsa", 40 "algorithm": "rsa-sha256", 41 "control-dir": "juju-test", 42 }) 43 } 44 45 type ConfigSuite struct { 46 coretesting.FakeJujuHomeSuite 47 originalValues map[string]testing.Restorer 48 privateKeyData string 49 } 50 51 var _ = gc.Suite(&ConfigSuite{}) 52 53 func (s *ConfigSuite) SetUpSuite(c *gc.C) { 54 s.FakeJujuHomeSuite.SetUpSuite(c) 55 restoreSdcAccount := testing.PatchEnvironment(jp.SdcAccount, "tester") 56 s.AddSuiteCleanup(func(*gc.C) { restoreSdcAccount() }) 57 restoreSdcKeyId := testing.PatchEnvironment(jp.SdcKeyId, "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00") 58 s.AddSuiteCleanup(func(*gc.C) { restoreSdcKeyId() }) 59 restoreMantaUser := testing.PatchEnvironment(jp.MantaUser, "tester") 60 s.AddSuiteCleanup(func(*gc.C) { restoreMantaUser() }) 61 restoreMantaKeyId := testing.PatchEnvironment(jp.MantaKeyId, "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00") 62 s.AddSuiteCleanup(func(*gc.C) { restoreMantaKeyId() }) 63 s.privateKeyData = generatePrivateKey(c) 64 jp.RegisterMachinesEndpoint() 65 s.AddSuiteCleanup(func(*gc.C) { jp.UnregisterMachinesEndpoint() }) 66 } 67 68 func generatePrivateKey(c *gc.C) string { 69 oldBits := ssh.KeyBits 70 defer func() { 71 ssh.KeyBits = oldBits 72 }() 73 ssh.KeyBits = 32 74 private, _, err := ssh.GenerateKey("test-client") 75 c.Assert(err, jc.ErrorIsNil) 76 return private 77 } 78 79 func (s *ConfigSuite) SetUpTest(c *gc.C) { 80 s.FakeJujuHomeSuite.SetUpTest(c) 81 s.AddCleanup(CreateTestKey(c)) 82 for _, envVar := range jp.EnvironmentVariables { 83 s.PatchEnvironment(envVar, "") 84 } 85 } 86 87 type configtest struct { 88 info string 89 insert coretesting.Attrs 90 remove []string 91 envVars map[string]string 92 expect coretesting.Attrs 93 err string 94 } 95 96 var newConfigTests = []configtest{{ 97 info: "sdc-user is required", 98 remove: []string{"sdc-user"}, 99 err: ".* cannot get sdc-user value from environment variable .*", 100 }, { 101 info: "sdc-user cannot be empty", 102 insert: coretesting.Attrs{"sdc-user": ""}, 103 err: ".* cannot get sdc-user value from environment variable .*", 104 }, { 105 info: "can get sdc-user from env variable", 106 insert: coretesting.Attrs{"sdc-user": ""}, 107 expect: coretesting.Attrs{"sdc-user": "tester"}, 108 envVars: map[string]string{ 109 "SDC_ACCOUNT": "tester", 110 }, 111 }, { 112 info: "can get sdc-user from env variable, missing from config", 113 remove: []string{"sdc-user"}, 114 expect: coretesting.Attrs{"sdc-user": "tester"}, 115 envVars: map[string]string{ 116 "SDC_ACCOUNT": "tester", 117 }, 118 }, { 119 info: "sdc-key-id is required", 120 remove: []string{"sdc-key-id"}, 121 err: ".* cannot get sdc-key-id value from environment variable .*", 122 }, { 123 info: "sdc-key-id cannot be empty", 124 insert: coretesting.Attrs{"sdc-key-id": ""}, 125 err: ".* cannot get sdc-key-id value from environment variable .*", 126 }, { 127 info: "can get sdc-key-id from env variable", 128 insert: coretesting.Attrs{"sdc-key-id": ""}, 129 expect: coretesting.Attrs{"sdc-key-id": "key"}, 130 envVars: map[string]string{ 131 "SDC_KEY_ID": "key", 132 }, 133 }, { 134 info: "can get sdc-key-id from env variable, missing from config", 135 remove: []string{"sdc-key-id"}, 136 expect: coretesting.Attrs{"sdc-key-id": "key"}, 137 envVars: map[string]string{ 138 "SDC_KEY_ID": "key", 139 }, 140 }, { 141 info: "sdc-url is inserted if missing", 142 expect: coretesting.Attrs{"sdc-url": "test://test.api.joyentcloud.com"}, 143 }, { 144 info: "sdc-url cannot be empty", 145 insert: coretesting.Attrs{"sdc-url": ""}, 146 err: ".* cannot get sdc-url value from environment variable .*", 147 }, { 148 info: "sdc-url is untouched if present", 149 insert: coretesting.Attrs{"sdc-url": "test://test.api.joyentcloud.com"}, 150 expect: coretesting.Attrs{"sdc-url": "test://test.api.joyentcloud.com"}, 151 }, { 152 info: "manta-user is required", 153 remove: []string{"manta-user"}, 154 err: ".* cannot get manta-user value from environment variable .*", 155 }, { 156 info: "manta-user cannot be empty", 157 insert: coretesting.Attrs{"manta-user": ""}, 158 err: ".* cannot get manta-user value from environment variable .*", 159 }, { 160 info: "can get manta-user from env variable", 161 insert: coretesting.Attrs{"manta-user": ""}, 162 expect: coretesting.Attrs{"manta-user": "tester"}, 163 envVars: map[string]string{ 164 "MANTA_USER": "tester", 165 }, 166 }, { 167 info: "can get manta-user from env variable, missing from config", 168 remove: []string{"manta-user"}, 169 expect: coretesting.Attrs{"manta-user": "tester"}, 170 envVars: map[string]string{ 171 "MANTA_USER": "tester", 172 }, 173 }, { 174 info: "manta-key-id is required", 175 remove: []string{"manta-key-id"}, 176 err: ".* cannot get manta-key-id value from environment variable .*", 177 }, { 178 info: "manta-key-id cannot be empty", 179 insert: coretesting.Attrs{"manta-key-id": ""}, 180 err: ".* cannot get manta-key-id value from environment variable .*", 181 }, { 182 info: "can get manta-key-id from env variable", 183 insert: coretesting.Attrs{"manta-key-id": ""}, 184 expect: coretesting.Attrs{"manta-key-id": "key"}, 185 envVars: map[string]string{ 186 "MANTA_KEY_ID": "key", 187 }, 188 }, { 189 info: "can get manta-key-id from env variable, missing from config", 190 remove: []string{"manta-key-id"}, 191 expect: coretesting.Attrs{"manta-key-id": "key"}, 192 envVars: map[string]string{ 193 "MANTA_KEY_ID": "key", 194 }, 195 }, { 196 info: "manta-url is inserted if missing", 197 expect: coretesting.Attrs{"manta-url": "test://test.manta.joyent.com"}, 198 }, { 199 info: "manta-url cannot be empty", 200 insert: coretesting.Attrs{"manta-url": ""}, 201 err: ".* cannot get manta-url value from environment variable .*", 202 }, { 203 info: "manta-url is untouched if present", 204 insert: coretesting.Attrs{"manta-url": "test://test.manta.joyent.com"}, 205 expect: coretesting.Attrs{"manta-url": "test://test.manta.joyent.com"}, 206 }, { 207 info: "can get private-key-path from env variable", 208 insert: coretesting.Attrs{"private-key-path": ""}, 209 expect: coretesting.Attrs{"private-key-path": "some-file"}, 210 envVars: map[string]string{ 211 "MANTA_PRIVATE_KEY_FILE": "some-file", 212 }, 213 }, { 214 info: "can get private-key-path from env variable, missing from config", 215 remove: []string{"private-key-path"}, 216 expect: coretesting.Attrs{"private-key-path": "some-file"}, 217 envVars: map[string]string{ 218 "MANTA_PRIVATE_KEY_FILE": "some-file", 219 }, 220 }, { 221 info: "algorithm is inserted if missing", 222 expect: coretesting.Attrs{"algorithm": "rsa-sha256"}, 223 }, { 224 info: "algorithm cannot be empty", 225 insert: coretesting.Attrs{"algorithm": ""}, 226 err: ".* algorithm: must not be empty", 227 }, { 228 info: "unknown field is not touched", 229 insert: coretesting.Attrs{"unknown-field": 12345}, 230 expect: coretesting.Attrs{"unknown-field": 12345}, 231 }, { 232 info: "can specify just private-key", 233 remove: []string{"private-key-path"}, 234 insert: coretesting.Attrs{"private-key": "foo"}, 235 }} 236 237 func (s *ConfigSuite) TestNewEnvironConfig(c *gc.C) { 238 for i, test := range newConfigTests { 239 doTest(s, i, test, c) 240 } 241 } 242 243 func doTest(s *ConfigSuite, i int, test configtest, c *gc.C) { 244 c.Logf("test %d: %s", i, test.info) 245 for k, v := range test.envVars { 246 os.Setenv(k, v) 247 defer os.Setenv(k, "") 248 } 249 attrs := validAttrs().Merge(test.insert).Delete(test.remove...) 250 attrs["private-key"] = s.privateKeyData 251 testConfig := newConfig(c, attrs) 252 environ, err := environs.New(testConfig) 253 if test.err == "" { 254 c.Check(err, jc.ErrorIsNil) 255 if err != nil { 256 return 257 } 258 attrs := environ.Config().AllAttrs() 259 for field, value := range test.expect { 260 c.Check(attrs[field], gc.Equals, value) 261 } 262 } else { 263 c.Check(environ, gc.IsNil) 264 c.Check(err, gc.ErrorMatches, test.err) 265 } 266 } 267 268 var changeConfigTests = []struct { 269 info string 270 insert coretesting.Attrs 271 remove []string 272 expect coretesting.Attrs 273 err string 274 }{{ 275 info: "no change, no error", 276 expect: validAttrs(), 277 }, { 278 info: "can change sdc-user", 279 insert: coretesting.Attrs{"sdc-user": "joyent_user"}, 280 expect: coretesting.Attrs{"sdc-user": "joyent_user"}, 281 }, { 282 info: "can change sdc-key-id", 283 insert: coretesting.Attrs{"sdc-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"}, 284 expect: coretesting.Attrs{"sdc-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"}, 285 }, { 286 info: "can change sdc-url", 287 insert: coretesting.Attrs{"sdc-url": "test://test.api.joyentcloud.com"}, 288 expect: coretesting.Attrs{"sdc-url": "test://test.api.joyentcloud.com"}, 289 }, { 290 info: "can change manta-user", 291 insert: coretesting.Attrs{"manta-user": "manta_user"}, 292 expect: coretesting.Attrs{"manta-user": "manta_user"}, 293 }, { 294 info: "can change manta-key-id", 295 insert: coretesting.Attrs{"manta-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"}, 296 expect: coretesting.Attrs{"manta-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"}, 297 }, { 298 info: "can change manta-url", 299 insert: coretesting.Attrs{"manta-url": "test://test.manta.joyent.com"}, 300 expect: coretesting.Attrs{"manta-url": "test://test.manta.joyent.com"}, 301 }, { 302 info: "can insert unknown field", 303 insert: coretesting.Attrs{"unknown": "ignoti"}, 304 expect: coretesting.Attrs{"unknown": "ignoti"}, 305 }} 306 307 func (s *ConfigSuite) TestValidateChange(c *gc.C) { 308 attrs := validAttrs() 309 attrs["private-key"] = s.privateKeyData 310 baseConfig := newConfig(c, attrs) 311 for i, test := range changeConfigTests { 312 c.Logf("test %d: %s", i, test.info) 313 attrs := validAttrs().Merge(test.insert).Delete(test.remove...) 314 attrs["private-key"] = s.privateKeyData 315 testConfig := newConfig(c, attrs) 316 validatedConfig, err := jp.Provider.Validate(testConfig, baseConfig) 317 if test.err == "" { 318 c.Check(err, jc.ErrorIsNil) 319 if err != nil { 320 continue 321 } 322 attrs := validatedConfig.AllAttrs() 323 for field, value := range test.expect { 324 c.Check(attrs[field], gc.Equals, value) 325 } 326 } else { 327 c.Check(validatedConfig, gc.IsNil) 328 c.Check(err, gc.ErrorMatches, "invalid config change: "+test.err) 329 } 330 } 331 } 332 333 func (s *ConfigSuite) TestSetConfig(c *gc.C) { 334 baseConfig := newConfig(c, validAttrs()) 335 for i, test := range changeConfigTests { 336 c.Logf("test %d: %s", i, test.info) 337 environ, err := environs.New(baseConfig) 338 c.Assert(err, jc.ErrorIsNil) 339 attrs := validAttrs().Merge(test.insert).Delete(test.remove...) 340 testConfig := newConfig(c, attrs) 341 err = environ.SetConfig(testConfig) 342 newAttrs := environ.Config().AllAttrs() 343 if test.err == "" { 344 c.Check(err, jc.ErrorIsNil) 345 for field, value := range test.expect { 346 c.Check(newAttrs[field], gc.Equals, value) 347 } 348 } else { 349 c.Check(err, gc.ErrorMatches, test.err) 350 for field, value := range baseConfig.UnknownAttrs() { 351 c.Check(newAttrs[field], gc.Equals, value) 352 } 353 } 354 } 355 } 356 357 func validPrepareAttrs() coretesting.Attrs { 358 return validAttrs().Delete("private-key") 359 } 360 361 var prepareConfigTests = []struct { 362 info string 363 insert coretesting.Attrs 364 remove []string 365 expect coretesting.Attrs 366 err string 367 }{{ 368 info: "All value provided, nothig to do", 369 expect: validPrepareAttrs(), 370 }, { 371 info: "private key is loaded from key file", 372 insert: coretesting.Attrs{"private-key-path": fmt.Sprintf("~/.ssh/%s", testKeyFileName)}, 373 expect: coretesting.Attrs{"private-key": testPrivateKey}, 374 }, { 375 info: "bad private-key-path errors, not panics", 376 insert: coretesting.Attrs{"private-key-path": "~/.ssh/no-such-file"}, 377 err: "invalid Joyent provider config: open .*: " + utils.NoSuchFileErrRegexp, 378 }} 379 380 func (s *ConfigSuite) TestPrepareForBootstrap(c *gc.C) { 381 ctx := envtesting.BootstrapContext(c) 382 for i, test := range prepareConfigTests { 383 c.Logf("test %d: %s", i, test.info) 384 attrs := validPrepareAttrs().Merge(test.insert).Delete(test.remove...) 385 testConfig := newConfig(c, attrs) 386 preparedConfig, err := jp.Provider.PrepareForBootstrap(ctx, testConfig) 387 if test.err == "" { 388 c.Check(err, jc.ErrorIsNil) 389 attrs := preparedConfig.Config().AllAttrs() 390 for field, value := range test.expect { 391 c.Check(attrs[field], gc.Equals, value) 392 } 393 } else { 394 c.Check(preparedConfig, gc.IsNil) 395 c.Check(err, gc.ErrorMatches, test.err) 396 } 397 } 398 }