github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/provider/ec2/config_test.go (about) 1 // Copyright 2011, 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package ec2 5 6 // TODO: Clean this up so it matches environs/openstack/config_test.go. 7 8 import ( 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "strings" 13 14 jc "github.com/juju/testing/checkers" 15 "github.com/juju/utils" 16 "gopkg.in/amz.v3/aws" 17 gc "gopkg.in/check.v1" 18 19 "github.com/juju/juju/environs" 20 "github.com/juju/juju/environs/config" 21 envtesting "github.com/juju/juju/environs/testing" 22 "github.com/juju/juju/testing" 23 ) 24 25 // Use local suite since this file lives in the ec2 package 26 // for testing internals. 27 type ConfigSuite struct { 28 testing.BaseSuite 29 savedHome, savedAccessKey, savedSecretKey string 30 } 31 32 var _ = gc.Suite(&ConfigSuite{}) 33 34 var configTestRegion = aws.Region{ 35 Name: "configtest", 36 EC2Endpoint: "testregion.nowhere:1234", 37 } 38 39 var testAuth = aws.Auth{"gopher", "long teeth"} 40 41 // configTest specifies a config parsing test, checking that env when 42 // parsed as the ec2 section of a config file matches baseConfigResult 43 // when mutated by the mutate function, or that the parse matches the 44 // given error. 45 type configTest struct { 46 config map[string]interface{} 47 change map[string]interface{} 48 expect map[string]interface{} 49 region string 50 cbucket string 51 pbucket string 52 pbucketRegion string 53 accessKey string 54 secretKey string 55 firewallMode string 56 blockStorageSource string 57 err string 58 } 59 60 type attrs map[string]interface{} 61 62 func (t configTest) check(c *gc.C) { 63 attrs := testing.FakeConfig().Merge(testing.Attrs{ 64 "type": "ec2", 65 "control-bucket": "x", 66 }).Merge(t.config) 67 cfg, err := config.New(config.NoDefaults, attrs) 68 c.Assert(err, jc.ErrorIsNil) 69 e, err := environs.New(cfg) 70 if t.change != nil { 71 c.Assert(err, jc.ErrorIsNil) 72 73 // Testing a change in configuration. 74 var old, changed, valid *config.Config 75 ec2env := e.(*environ) 76 old = ec2env.ecfg().Config 77 changed, err = old.Apply(t.change) 78 c.Assert(err, jc.ErrorIsNil) 79 80 // Keep err for validation below. 81 valid, err = providerInstance.Validate(changed, old) 82 if err == nil { 83 err = ec2env.SetConfig(valid) 84 } 85 } 86 if t.err != "" { 87 c.Check(err, gc.ErrorMatches, t.err) 88 return 89 } 90 c.Assert(err, jc.ErrorIsNil) 91 92 ecfg := e.(*environ).ecfg() 93 c.Assert(ecfg.Name(), gc.Equals, "testenv") 94 c.Assert(ecfg.controlBucket(), gc.Equals, "x") 95 if t.region != "" { 96 c.Assert(ecfg.region(), gc.Equals, t.region) 97 } 98 if t.accessKey != "" { 99 c.Assert(ecfg.accessKey(), gc.Equals, t.accessKey) 100 c.Assert(ecfg.secretKey(), gc.Equals, t.secretKey) 101 expected := map[string]string{ 102 "access-key": t.accessKey, 103 "secret-key": t.secretKey, 104 } 105 c.Assert(err, jc.ErrorIsNil) 106 actual, err := e.Provider().SecretAttrs(ecfg.Config) 107 c.Assert(err, jc.ErrorIsNil) 108 c.Assert(expected, gc.DeepEquals, actual) 109 } else { 110 c.Assert(ecfg.accessKey(), gc.DeepEquals, testAuth.AccessKey) 111 c.Assert(ecfg.secretKey(), gc.DeepEquals, testAuth.SecretKey) 112 } 113 if t.firewallMode != "" { 114 c.Assert(ecfg.FirewallMode(), gc.Equals, t.firewallMode) 115 } 116 for name, expect := range t.expect { 117 actual, found := ecfg.UnknownAttrs()[name] 118 c.Check(found, jc.IsTrue) 119 c.Check(actual, gc.Equals, expect) 120 } 121 122 // check storage bucket is configured correctly 123 env := e.(*environ) 124 c.Assert(env.Storage().(*ec2storage).bucket.Region.Name, gc.Equals, ecfg.region()) 125 126 expectedStorage := "ebs" 127 if t.blockStorageSource != "" { 128 expectedStorage = t.blockStorageSource 129 } 130 storage, ok := ecfg.StorageDefaultBlockSource() 131 c.Assert(ok, jc.IsTrue) 132 c.Assert(storage, gc.Equals, expectedStorage) 133 } 134 135 var configTests = []configTest{ 136 { 137 config: attrs{}, 138 }, { 139 // check that region defaults to us-east-1 140 config: attrs{}, 141 region: "us-east-1", 142 }, { 143 config: attrs{ 144 "region": "eu-west-1", 145 }, 146 region: "eu-west-1", 147 }, { 148 config: attrs{ 149 "region": "unknown", 150 }, 151 err: ".*invalid region name.*", 152 }, { 153 config: attrs{ 154 "region": "configtest", 155 }, 156 region: "configtest", 157 }, { 158 config: attrs{ 159 "region": "configtest", 160 }, 161 change: attrs{ 162 "region": "us-east-1", 163 }, 164 err: `.*cannot change region from "configtest" to "us-east-1"`, 165 }, { 166 config: attrs{ 167 "region": 666, 168 }, 169 err: `.*expected string, got int\(666\)`, 170 }, { 171 config: attrs{ 172 "access-key": 666, 173 }, 174 err: `.*expected string, got int\(666\)`, 175 }, { 176 config: attrs{ 177 "secret-key": 666, 178 }, 179 err: `.*expected string, got int\(666\)`, 180 }, { 181 config: attrs{ 182 "control-bucket": 666, 183 }, 184 err: `.*expected string, got int\(666\)`, 185 }, { 186 change: attrs{ 187 "control-bucket": "new-x", 188 }, 189 err: `.*cannot change control-bucket from "x" to "new-x"`, 190 }, { 191 config: attrs{ 192 "access-key": "jujuer", 193 "secret-key": "open sesame", 194 }, 195 accessKey: "jujuer", 196 secretKey: "open sesame", 197 }, { 198 config: attrs{ 199 "access-key": "jujuer", 200 }, 201 err: ".*environment has no access-key or secret-key", 202 }, { 203 config: attrs{ 204 "secret-key": "badness", 205 }, 206 err: ".*environment has no access-key or secret-key", 207 }, { 208 config: attrs{ 209 "admin-secret": "Futumpsh", 210 }, 211 }, { 212 config: attrs{}, 213 firewallMode: config.FwInstance, 214 }, { 215 config: attrs{}, 216 blockStorageSource: "ebs", 217 }, { 218 config: attrs{ 219 "storage-default-block-source": "ebs-fast", 220 }, 221 blockStorageSource: "ebs-fast", 222 }, { 223 config: attrs{ 224 "firewall-mode": "instance", 225 }, 226 firewallMode: config.FwInstance, 227 }, { 228 config: attrs{ 229 "firewall-mode": "global", 230 }, 231 firewallMode: config.FwGlobal, 232 }, { 233 config: attrs{ 234 "firewall-mode": "none", 235 }, 236 firewallMode: config.FwNone, 237 }, { 238 config: attrs{ 239 "ssl-hostname-verification": false, 240 }, 241 err: ".*disabling ssh-hostname-verification is not supported", 242 }, { 243 config: attrs{ 244 "future": "hammerstein", 245 }, 246 expect: attrs{ 247 "future": "hammerstein", 248 }, 249 }, { 250 change: attrs{ 251 "future": "hammerstein", 252 }, 253 expect: attrs{ 254 "future": "hammerstein", 255 }, 256 }, 257 } 258 259 func indent(s string, with string) string { 260 var r string 261 lines := strings.Split(s, "\n") 262 for _, l := range lines { 263 r += with + l + "\n" 264 } 265 return r 266 } 267 268 func (s *ConfigSuite) SetUpTest(c *gc.C) { 269 s.BaseSuite.SetUpTest(c) 270 s.savedHome = utils.Home() 271 s.savedAccessKey = os.Getenv("AWS_ACCESS_KEY_ID") 272 s.savedSecretKey = os.Getenv("AWS_SECRET_ACCESS_KEY") 273 274 home := c.MkDir() 275 sshDir := filepath.Join(home, ".ssh") 276 err := os.Mkdir(sshDir, 0777) 277 c.Assert(err, jc.ErrorIsNil) 278 err = ioutil.WriteFile(filepath.Join(sshDir, "id_rsa.pub"), []byte("sshkey\n"), 0666) 279 c.Assert(err, jc.ErrorIsNil) 280 281 utils.SetHome(home) 282 os.Setenv("AWS_ACCESS_KEY_ID", testAuth.AccessKey) 283 os.Setenv("AWS_SECRET_ACCESS_KEY", testAuth.SecretKey) 284 aws.Regions["configtest"] = configTestRegion 285 } 286 287 func (s *ConfigSuite) TearDownTest(c *gc.C) { 288 utils.SetHome(s.savedHome) 289 os.Setenv("AWS_ACCESS_KEY_ID", s.savedAccessKey) 290 os.Setenv("AWS_SECRET_ACCESS_KEY", s.savedSecretKey) 291 delete(aws.Regions, "configtest") 292 s.BaseSuite.TearDownTest(c) 293 } 294 295 func (s *ConfigSuite) TestConfig(c *gc.C) { 296 for i, t := range configTests { 297 c.Logf("test %d: %v", i, t.config) 298 t.check(c) 299 } 300 } 301 302 func (s *ConfigSuite) TestMissingAuth(c *gc.C) { 303 os.Setenv("AWS_ACCESS_KEY_ID", "") 304 os.Setenv("AWS_SECRET_ACCESS_KEY", "") 305 306 // Since PR #52 amz.v3 uses these AWS_ vars as fallbacks, if set. 307 os.Setenv("AWS_ACCESS_KEY", "") 308 os.Setenv("AWS_SECRET_KEY", "") 309 310 // Since LP r37 goamz uses also these EC2_ as fallbacks, so unset them too. 311 os.Setenv("EC2_ACCESS_KEY", "") 312 os.Setenv("EC2_SECRET_KEY", "") 313 test := configTests[0] 314 test.err = ".*environment has no access-key or secret-key" 315 test.check(c) 316 } 317 318 func (s *ConfigSuite) TestPrepareForCreateInsertsUniqueControlBucket(c *gc.C) { 319 s.PatchValue(&verifyCredentials, func(*environ) error { return nil }) 320 attrs := testing.FakeConfig().Merge(testing.Attrs{ 321 "type": "ec2", 322 }) 323 cfg, err := config.New(config.NoDefaults, attrs) 324 c.Assert(err, jc.ErrorIsNil) 325 326 cfg1, err := providerInstance.PrepareForCreateEnvironment(cfg) 327 c.Assert(err, jc.ErrorIsNil) 328 329 bucket1 := cfg1.UnknownAttrs()["control-bucket"] 330 c.Assert(bucket1, gc.Matches, "[a-f0-9]{32}") 331 332 cfg2, err := providerInstance.PrepareForCreateEnvironment(cfg) 333 c.Assert(err, jc.ErrorIsNil) 334 bucket2 := cfg2.UnknownAttrs()["control-bucket"] 335 c.Assert(bucket2, gc.Matches, "[a-f0-9]{32}") 336 337 c.Assert(bucket1, gc.Not(gc.Equals), bucket2) 338 } 339 340 func (s *ConfigSuite) TestPrepareInsertsUniqueControlBucket(c *gc.C) { 341 s.PatchValue(&verifyCredentials, func(*environ) error { return nil }) 342 attrs := testing.FakeConfig().Merge(testing.Attrs{ 343 "type": "ec2", 344 }) 345 cfg, err := config.New(config.NoDefaults, attrs) 346 c.Assert(err, jc.ErrorIsNil) 347 348 ctx := envtesting.BootstrapContext(c) 349 env0, err := providerInstance.PrepareForBootstrap(ctx, cfg) 350 c.Assert(err, jc.ErrorIsNil) 351 bucket0 := env0.(*environ).ecfg().controlBucket() 352 c.Assert(bucket0, gc.Matches, "[a-f0-9]{32}") 353 354 env1, err := providerInstance.PrepareForBootstrap(ctx, cfg) 355 c.Assert(err, jc.ErrorIsNil) 356 bucket1 := env1.(*environ).ecfg().controlBucket() 357 c.Assert(bucket1, gc.Matches, "[a-f0-9]{32}") 358 359 c.Assert(bucket1, gc.Not(gc.Equals), bucket0) 360 } 361 362 func (s *ConfigSuite) TestPrepareDoesNotTouchExistingControlBucket(c *gc.C) { 363 s.PatchValue(&verifyCredentials, func(*environ) error { return nil }) 364 attrs := testing.FakeConfig().Merge(testing.Attrs{ 365 "type": "ec2", 366 "control-bucket": "burblefoo", 367 }) 368 cfg, err := config.New(config.NoDefaults, attrs) 369 c.Assert(err, jc.ErrorIsNil) 370 371 env, err := providerInstance.PrepareForBootstrap(envtesting.BootstrapContext(c), cfg) 372 c.Assert(err, jc.ErrorIsNil) 373 bucket := env.(*environ).ecfg().controlBucket() 374 c.Assert(bucket, gc.Equals, "burblefoo") 375 } 376 377 func (s *ConfigSuite) TestPrepareSetsDefaultBlockSource(c *gc.C) { 378 s.PatchValue(&verifyCredentials, func(*environ) error { return nil }) 379 attrs := testing.FakeConfig().Merge(testing.Attrs{ 380 "type": "ec2", 381 }) 382 cfg, err := config.New(config.NoDefaults, attrs) 383 c.Assert(err, jc.ErrorIsNil) 384 385 env, err := providerInstance.PrepareForBootstrap(envtesting.BootstrapContext(c), cfg) 386 c.Assert(err, jc.ErrorIsNil) 387 source, ok := env.(*environ).ecfg().StorageDefaultBlockSource() 388 c.Assert(ok, jc.IsTrue) 389 c.Assert(source, gc.Equals, "ebs") 390 } 391 392 func (*ConfigSuite) TestSchema(c *gc.C) { 393 fields := providerInstance.Schema() 394 // Check that all the fields defined in environs/config 395 // are in the returned schema. 396 globalFields, err := config.Schema(nil) 397 c.Assert(err, gc.IsNil) 398 for name, field := range globalFields { 399 c.Check(fields[name], jc.DeepEquals, field) 400 } 401 }