launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/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 "launchpad.net/goamz/aws" 15 gc "launchpad.net/gocheck" 16 17 "launchpad.net/juju-core/environs" 18 "launchpad.net/juju-core/environs/config" 19 "launchpad.net/juju-core/juju/osenv" 20 "launchpad.net/juju-core/testing" 21 "launchpad.net/juju-core/testing/testbase" 22 ) 23 24 // Use local suite since this file lives in the ec2 package 25 // for testing internals. 26 type ConfigSuite struct { 27 testbase.LoggingSuite 28 savedHome, savedAccessKey, savedSecretKey string 29 } 30 31 var _ = gc.Suite(&ConfigSuite{}) 32 33 var configTestRegion = aws.Region{ 34 Name: "configtest", 35 EC2Endpoint: "testregion.nowhere:1234", 36 } 37 38 var testAuth = aws.Auth{"gopher", "long teeth"} 39 40 // configTest specifies a config parsing test, checking that env when 41 // parsed as the ec2 section of a config file matches baseConfigResult 42 // when mutated by the mutate function, or that the parse matches the 43 // given error. 44 type configTest struct { 45 config map[string]interface{} 46 change map[string]interface{} 47 expect map[string]interface{} 48 region string 49 cbucket string 50 pbucket string 51 pbucketRegion string 52 accessKey string 53 secretKey string 54 firewallMode string 55 err string 56 } 57 58 type attrs map[string]interface{} 59 60 func (t configTest) check(c *gc.C) { 61 attrs := testing.FakeConfig().Merge(testing.Attrs{ 62 "type": "ec2", 63 "control-bucket": "x", 64 }).Merge(t.config) 65 cfg, err := config.New(config.NoDefaults, attrs) 66 c.Assert(err, gc.IsNil) 67 e, err := environs.New(cfg) 68 if t.change != nil { 69 c.Assert(err, gc.IsNil) 70 71 // Testing a change in configuration. 72 var old, changed, valid *config.Config 73 ec2env := e.(*environ) 74 old = ec2env.ecfg().Config 75 changed, err = old.Apply(t.change) 76 c.Assert(err, gc.IsNil) 77 78 // Keep err for validation below. 79 valid, err = providerInstance.Validate(changed, old) 80 if err == nil { 81 err = ec2env.SetConfig(valid) 82 } 83 } 84 if t.err != "" { 85 c.Check(err, gc.ErrorMatches, t.err) 86 return 87 } 88 c.Assert(err, gc.IsNil) 89 90 ecfg := e.(*environ).ecfg() 91 c.Assert(ecfg.Name(), gc.Equals, "testenv") 92 c.Assert(ecfg.controlBucket(), gc.Equals, "x") 93 if t.region != "" { 94 c.Assert(ecfg.region(), gc.Equals, t.region) 95 } 96 if t.accessKey != "" { 97 c.Assert(ecfg.accessKey(), gc.Equals, t.accessKey) 98 c.Assert(ecfg.secretKey(), gc.Equals, t.secretKey) 99 expected := map[string]string{ 100 "access-key": t.accessKey, 101 "secret-key": t.secretKey, 102 } 103 c.Assert(err, gc.IsNil) 104 actual, err := e.Provider().SecretAttrs(ecfg.Config) 105 c.Assert(err, gc.IsNil) 106 c.Assert(expected, gc.DeepEquals, actual) 107 } else { 108 c.Assert(ecfg.accessKey(), gc.DeepEquals, testAuth.AccessKey) 109 c.Assert(ecfg.secretKey(), gc.DeepEquals, testAuth.SecretKey) 110 } 111 if t.firewallMode != "" { 112 c.Assert(ecfg.FirewallMode(), gc.Equals, t.firewallMode) 113 } 114 for name, expect := range t.expect { 115 actual, found := ecfg.UnknownAttrs()[name] 116 c.Check(found, gc.Equals, true) 117 c.Check(actual, gc.Equals, expect) 118 } 119 120 // check storage bucket is configured correctly 121 env := e.(*environ) 122 c.Assert(env.Storage().(*ec2storage).bucket.Region.Name, gc.Equals, ecfg.region()) 123 } 124 125 var configTests = []configTest{ 126 { 127 config: attrs{}, 128 }, { 129 // check that region defaults to us-east-1 130 config: attrs{}, 131 region: "us-east-1", 132 }, { 133 config: attrs{ 134 "region": "eu-west-1", 135 }, 136 region: "eu-west-1", 137 }, { 138 config: attrs{ 139 "region": "unknown", 140 }, 141 err: ".*invalid region name.*", 142 }, { 143 config: attrs{ 144 "region": "configtest", 145 }, 146 region: "configtest", 147 }, { 148 config: attrs{ 149 "region": "configtest", 150 }, 151 change: attrs{ 152 "region": "us-east-1", 153 }, 154 err: `cannot change region from "configtest" to "us-east-1"`, 155 }, { 156 config: attrs{ 157 "region": 666, 158 }, 159 err: `.*expected string, got int\(666\)`, 160 }, { 161 config: attrs{ 162 "access-key": 666, 163 }, 164 err: `.*expected string, got int\(666\)`, 165 }, { 166 config: attrs{ 167 "secret-key": 666, 168 }, 169 err: `.*expected string, got int\(666\)`, 170 }, { 171 config: attrs{ 172 "control-bucket": 666, 173 }, 174 err: `.*expected string, got int\(666\)`, 175 }, { 176 change: attrs{ 177 "control-bucket": "new-x", 178 }, 179 err: `cannot change control-bucket from "x" to "new-x"`, 180 }, { 181 config: attrs{ 182 "access-key": "jujuer", 183 "secret-key": "open sesame", 184 }, 185 accessKey: "jujuer", 186 secretKey: "open sesame", 187 }, { 188 config: attrs{ 189 "access-key": "jujuer", 190 }, 191 err: ".*environment has no access-key or secret-key", 192 }, { 193 config: attrs{ 194 "secret-key": "badness", 195 }, 196 err: ".*environment has no access-key or secret-key", 197 }, { 198 config: attrs{ 199 "admin-secret": "Futumpsh", 200 }, 201 }, { 202 config: attrs{}, 203 firewallMode: config.FwInstance, 204 }, { 205 config: attrs{ 206 "firewall-mode": "instance", 207 }, 208 firewallMode: config.FwInstance, 209 }, { 210 config: attrs{ 211 "firewall-mode": "global", 212 }, 213 firewallMode: config.FwGlobal, 214 }, { 215 config: attrs{ 216 "ssl-hostname-verification": false, 217 }, 218 err: "disabling ssh-hostname-verification is not supported", 219 }, { 220 config: attrs{ 221 "future": "hammerstein", 222 }, 223 expect: attrs{ 224 "future": "hammerstein", 225 }, 226 }, { 227 change: attrs{ 228 "future": "hammerstein", 229 }, 230 expect: attrs{ 231 "future": "hammerstein", 232 }, 233 }, 234 } 235 236 func indent(s string, with string) string { 237 var r string 238 lines := strings.Split(s, "\n") 239 for _, l := range lines { 240 r += with + l + "\n" 241 } 242 return r 243 } 244 245 func (s *ConfigSuite) SetUpTest(c *gc.C) { 246 s.LoggingSuite.SetUpTest(c) 247 s.savedHome = osenv.Home() 248 s.savedAccessKey = os.Getenv("AWS_ACCESS_KEY_ID") 249 s.savedSecretKey = os.Getenv("AWS_SECRET_ACCESS_KEY") 250 251 home := c.MkDir() 252 sshDir := filepath.Join(home, ".ssh") 253 err := os.Mkdir(sshDir, 0777) 254 c.Assert(err, gc.IsNil) 255 err = ioutil.WriteFile(filepath.Join(sshDir, "id_rsa.pub"), []byte("sshkey\n"), 0666) 256 c.Assert(err, gc.IsNil) 257 258 osenv.SetHome(home) 259 os.Setenv("AWS_ACCESS_KEY_ID", testAuth.AccessKey) 260 os.Setenv("AWS_SECRET_ACCESS_KEY", testAuth.SecretKey) 261 aws.Regions["configtest"] = configTestRegion 262 } 263 264 func (s *ConfigSuite) TearDownTest(c *gc.C) { 265 osenv.SetHome(s.savedHome) 266 os.Setenv("AWS_ACCESS_KEY_ID", s.savedAccessKey) 267 os.Setenv("AWS_SECRET_ACCESS_KEY", s.savedSecretKey) 268 delete(aws.Regions, "configtest") 269 s.LoggingSuite.TearDownTest(c) 270 } 271 272 func (s *ConfigSuite) TestConfig(c *gc.C) { 273 for i, t := range configTests { 274 c.Logf("test %d: %v", i, t.config) 275 t.check(c) 276 } 277 } 278 279 func (s *ConfigSuite) TestMissingAuth(c *gc.C) { 280 os.Setenv("AWS_ACCESS_KEY_ID", "") 281 os.Setenv("AWS_SECRET_ACCESS_KEY", "") 282 // Since r37 goamz uses these as fallbacks, so unset them too. 283 os.Setenv("EC2_ACCESS_KEY", "") 284 os.Setenv("EC2_SECRET_KEY", "") 285 test := configTests[0] 286 test.err = "environment has no access-key or secret-key" 287 test.check(c) 288 } 289 290 func (s *ConfigSuite) TestPrepareInsertsUniqueControlBucket(c *gc.C) { 291 attrs := testing.FakeConfig().Merge(testing.Attrs{ 292 "type": "ec2", 293 }) 294 cfg, err := config.New(config.NoDefaults, attrs) 295 c.Assert(err, gc.IsNil) 296 297 env0, err := providerInstance.Prepare(cfg) 298 c.Assert(err, gc.IsNil) 299 bucket0 := env0.(*environ).ecfg().controlBucket() 300 c.Assert(bucket0, gc.Matches, "[a-f0-9]{32}") 301 302 env1, err := providerInstance.Prepare(cfg) 303 c.Assert(err, gc.IsNil) 304 bucket1 := env1.(*environ).ecfg().controlBucket() 305 c.Assert(bucket1, gc.Matches, "[a-f0-9]{32}") 306 307 c.Assert(bucket1, gc.Not(gc.Equals), bucket0) 308 } 309 310 func (s *ConfigSuite) TestPrepareDoesNotTouchExistingControlBucket(c *gc.C) { 311 attrs := testing.FakeConfig().Merge(testing.Attrs{ 312 "type": "ec2", 313 "control-bucket": "burblefoo", 314 }) 315 cfg, err := config.New(config.NoDefaults, attrs) 316 c.Assert(err, gc.IsNil) 317 318 env, err := providerInstance.Prepare(cfg) 319 c.Assert(err, gc.IsNil) 320 bucket := env.(*environ).ecfg().controlBucket() 321 c.Assert(bucket, gc.Equals, "burblefoo") 322 }