github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/environs/open_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package environs_test 5 6 import ( 7 "github.com/juju/errors" 8 jc "github.com/juju/testing/checkers" 9 gc "gopkg.in/check.v1" 10 11 "github.com/juju/juju/cert" 12 "github.com/juju/juju/environs" 13 "github.com/juju/juju/environs/bootstrap" 14 "github.com/juju/juju/environs/config" 15 "github.com/juju/juju/environs/configstore" 16 "github.com/juju/juju/environs/filestorage" 17 envtesting "github.com/juju/juju/environs/testing" 18 envtools "github.com/juju/juju/environs/tools" 19 "github.com/juju/juju/provider/dummy" 20 "github.com/juju/juju/testing" 21 "github.com/juju/juju/version" 22 ) 23 24 type OpenSuite struct { 25 testing.FakeJujuHomeSuite 26 envtesting.ToolsFixture 27 } 28 29 var _ = gc.Suite(&OpenSuite{}) 30 31 func (s *OpenSuite) SetUpTest(c *gc.C) { 32 s.FakeJujuHomeSuite.SetUpTest(c) 33 testing.WriteEnvironments(c, testing.MultipleEnvConfigNoDefault) 34 } 35 36 func (s *OpenSuite) TearDownTest(c *gc.C) { 37 dummy.Reset() 38 s.FakeJujuHomeSuite.TearDownTest(c) 39 } 40 41 func (s *OpenSuite) TestNewDummyEnviron(c *gc.C) { 42 s.PatchValue(&version.Current.Number, testing.FakeVersionNumber) 43 // matches *Settings.Map() 44 cfg, err := config.New(config.NoDefaults, dummySampleConfig()) 45 c.Assert(err, jc.ErrorIsNil) 46 ctx := envtesting.BootstrapContext(c) 47 env, err := environs.Prepare(cfg, ctx, configstore.NewMem()) 48 c.Assert(err, jc.ErrorIsNil) 49 50 storageDir := c.MkDir() 51 s.PatchValue(&envtools.DefaultBaseURL, storageDir) 52 stor, err := filestorage.NewFileStorageWriter(storageDir) 53 c.Assert(err, jc.ErrorIsNil) 54 envtesting.UploadFakeTools(c, stor, cfg.AgentStream(), cfg.AgentStream()) 55 err = bootstrap.Bootstrap(ctx, env, bootstrap.BootstrapParams{}) 56 c.Assert(err, jc.ErrorIsNil) 57 } 58 59 func (s *OpenSuite) TestUpdateEnvInfo(c *gc.C) { 60 store := configstore.NewMem() 61 ctx := envtesting.BootstrapContext(c) 62 _, err := environs.PrepareFromName("erewhemos", ctx, store) 63 c.Assert(err, jc.ErrorIsNil) 64 65 info, err := store.ReadInfo("erewhemos") 66 c.Assert(err, jc.ErrorIsNil) 67 c.Assert(info, gc.NotNil) 68 c.Assert(info.APIEndpoint().CACert, gc.Not(gc.Equals), "") 69 c.Assert(info.APIEndpoint().EnvironUUID, gc.Not(gc.Equals), "") 70 c.Assert(info.APICredentials().Password, gc.Not(gc.Equals), "") 71 c.Assert(info.APICredentials().User, gc.Equals, "admin") 72 } 73 74 func (*OpenSuite) TestNewUnknownEnviron(c *gc.C) { 75 attrs := dummySampleConfig().Merge(testing.Attrs{ 76 "type": "wondercloud", 77 }) 78 env, err := environs.NewFromAttrs(attrs) 79 c.Assert(err, gc.ErrorMatches, "no registered provider for.*") 80 c.Assert(env, gc.IsNil) 81 } 82 83 func (*OpenSuite) TestNewFromName(c *gc.C) { 84 store := configstore.NewMem() 85 ctx := envtesting.BootstrapContext(c) 86 e, err := environs.PrepareFromName("erewhemos", ctx, store) 87 c.Assert(err, jc.ErrorIsNil) 88 89 e, err = environs.NewFromName("erewhemos", store) 90 c.Assert(err, jc.ErrorIsNil) 91 c.Assert(e.Config().Name(), gc.Equals, "erewhemos") 92 } 93 94 func (*OpenSuite) TestNewFromNameWithInvalidInfo(c *gc.C) { 95 store := configstore.NewMem() 96 cfg, _, err := environs.ConfigForName("erewhemos", store) 97 c.Assert(err, jc.ErrorIsNil) 98 info := store.CreateInfo("erewhemos") 99 100 // The configuration from environments.yaml is invalid 101 // because it doesn't contain the state-id attribute which 102 // the dummy environment adds at Prepare time. 103 info.SetBootstrapConfig(cfg.AllAttrs()) 104 err = info.Write() 105 c.Assert(err, jc.ErrorIsNil) 106 107 e, err := environs.NewFromName("erewhemos", store) 108 c.Assert(err, gc.ErrorMatches, "environment is not prepared") 109 c.Assert(e, gc.IsNil) 110 } 111 112 func (*OpenSuite) TestNewFromNameWithInvalidEnvironConfig(c *gc.C) { 113 store := configstore.NewMem() 114 115 e, err := environs.NewFromName("erewhemos", store) 116 c.Assert(err, gc.Equals, environs.ErrNotBootstrapped) 117 c.Assert(e, gc.IsNil) 118 } 119 120 func (*OpenSuite) TestPrepareFromName(c *gc.C) { 121 ctx := envtesting.BootstrapContext(c) 122 e, err := environs.PrepareFromName("erewhemos", ctx, configstore.NewMem()) 123 c.Assert(err, jc.ErrorIsNil) 124 c.Assert(e.Config().Name(), gc.Equals, "erewhemos") 125 } 126 127 func (*OpenSuite) TestConfigForName(c *gc.C) { 128 cfg, source, err := environs.ConfigForName("erewhemos", configstore.NewMem()) 129 c.Assert(err, jc.ErrorIsNil) 130 c.Assert(source, gc.Equals, environs.ConfigFromEnvirons) 131 c.Assert(cfg.Name(), gc.Equals, "erewhemos") 132 } 133 134 func (*OpenSuite) TestConfigForNameNoDefault(c *gc.C) { 135 cfg, source, err := environs.ConfigForName("", configstore.NewMem()) 136 c.Assert(err, gc.ErrorMatches, "no default environment found") 137 c.Assert(cfg, gc.IsNil) 138 c.Assert(source, gc.Equals, environs.ConfigFromEnvirons) 139 } 140 141 func (*OpenSuite) TestConfigForNameDefault(c *gc.C) { 142 testing.WriteEnvironments(c, testing.SingleEnvConfig) 143 cfg, source, err := environs.ConfigForName("", configstore.NewMem()) 144 c.Assert(err, jc.ErrorIsNil) 145 c.Assert(cfg.Name(), gc.Equals, "erewhemos") 146 c.Assert(source, gc.Equals, environs.ConfigFromEnvirons) 147 } 148 149 func (*OpenSuite) TestConfigForNameFromInfo(c *gc.C) { 150 testing.WriteEnvironments(c, testing.SingleEnvConfig) 151 store := configstore.NewMem() 152 cfg, source, err := environs.ConfigForName("", store) 153 c.Assert(err, jc.ErrorIsNil) 154 c.Assert(source, gc.Equals, environs.ConfigFromEnvirons) 155 156 info := store.CreateInfo("test-config") 157 var attrs testing.Attrs = cfg.AllAttrs() 158 attrs = attrs.Merge(testing.Attrs{ 159 "name": "test-config", 160 }) 161 info.SetBootstrapConfig(attrs) 162 err = info.Write() 163 c.Assert(err, jc.ErrorIsNil) 164 165 cfg, source, err = environs.ConfigForName("test-config", store) 166 c.Assert(err, jc.ErrorIsNil) 167 c.Assert(source, gc.Equals, environs.ConfigFromInfo) 168 c.Assert(testing.Attrs(cfg.AllAttrs()), gc.DeepEquals, attrs) 169 } 170 171 func (*OpenSuite) TestNew(c *gc.C) { 172 cfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Merge( 173 testing.Attrs{ 174 "state-server": false, 175 "name": "erewhemos", 176 }, 177 )) 178 c.Assert(err, jc.ErrorIsNil) 179 e, err := environs.New(cfg) 180 c.Assert(err, gc.ErrorMatches, "environment is not prepared") 181 c.Assert(e, gc.IsNil) 182 } 183 184 func (*OpenSuite) TestPrepare(c *gc.C) { 185 baselineAttrs := dummy.SampleConfig().Merge(testing.Attrs{ 186 "state-server": false, 187 "name": "erewhemos", 188 }).Delete( 189 "ca-cert", 190 "ca-private-key", 191 "admin-secret", 192 "uuid", 193 ) 194 cfg, err := config.New(config.NoDefaults, baselineAttrs) 195 c.Assert(err, jc.ErrorIsNil) 196 store := configstore.NewMem() 197 ctx := envtesting.BootstrapContext(c) 198 env, err := environs.Prepare(cfg, ctx, store) 199 c.Assert(err, jc.ErrorIsNil) 200 201 // Check that the environment info file was correctly created. 202 info, err := store.ReadInfo("erewhemos") 203 c.Assert(err, jc.ErrorIsNil) 204 c.Assert(info.Initialized(), jc.IsTrue) 205 c.Assert(info.BootstrapConfig(), gc.DeepEquals, env.Config().AllAttrs()) 206 c.Logf("bootstrap config: %#v", info.BootstrapConfig()) 207 208 // Check that an admin-secret was chosen. 209 adminSecret := env.Config().AdminSecret() 210 c.Assert(adminSecret, gc.HasLen, 32) 211 c.Assert(adminSecret, gc.Matches, "^[0-9a-f]*$") 212 213 // Check that the CA cert was generated. 214 cfgCertPEM, cfgCertOK := env.Config().CACert() 215 cfgKeyPEM, cfgKeyOK := env.Config().CAPrivateKey() 216 c.Assert(cfgCertOK, jc.IsTrue) 217 c.Assert(cfgKeyOK, jc.IsTrue) 218 219 // Check the common name of the generated cert 220 caCert, _, err := cert.ParseCertAndKey(cfgCertPEM, cfgKeyPEM) 221 c.Assert(err, jc.ErrorIsNil) 222 c.Assert(caCert.Subject.CommonName, gc.Equals, `juju-generated CA for environment "`+testing.SampleEnvName+`"`) 223 224 // Check that a uuid was chosen. 225 uuid, exists := env.Config().UUID() 226 c.Assert(exists, jc.IsTrue) 227 c.Assert(uuid, gc.Matches, `[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}`) 228 229 // Check we can call Prepare again. 230 env, err = environs.Prepare(cfg, ctx, store) 231 c.Assert(err, jc.ErrorIsNil) 232 c.Assert(env.Config().AllAttrs(), gc.DeepEquals, info.BootstrapConfig()) 233 } 234 235 func (*OpenSuite) TestPrepareGeneratesDifferentAdminSecrets(c *gc.C) { 236 baselineAttrs := dummy.SampleConfig().Merge(testing.Attrs{ 237 "state-server": false, 238 "name": "erewhemos", 239 }).Delete( 240 "admin-secret", 241 ) 242 cfg, err := config.New(config.NoDefaults, baselineAttrs) 243 c.Assert(err, jc.ErrorIsNil) 244 245 ctx := envtesting.BootstrapContext(c) 246 env0, err := environs.Prepare(cfg, ctx, configstore.NewMem()) 247 c.Assert(err, jc.ErrorIsNil) 248 adminSecret0 := env0.Config().AdminSecret() 249 c.Assert(adminSecret0, gc.HasLen, 32) 250 c.Assert(adminSecret0, gc.Matches, "^[0-9a-f]*$") 251 252 env1, err := environs.Prepare(cfg, ctx, configstore.NewMem()) 253 c.Assert(err, jc.ErrorIsNil) 254 adminSecret1 := env1.Config().AdminSecret() 255 c.Assert(adminSecret1, gc.HasLen, 32) 256 c.Assert(adminSecret1, gc.Matches, "^[0-9a-f]*$") 257 258 c.Assert(adminSecret1, gc.Not(gc.Equals), adminSecret0) 259 } 260 261 func (*OpenSuite) TestPrepareWithMissingKey(c *gc.C) { 262 cfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Delete("ca-cert", "ca-private-key").Merge( 263 testing.Attrs{ 264 "state-server": false, 265 "name": "erewhemos", 266 "ca-cert": string(testing.CACert), 267 }, 268 )) 269 c.Assert(err, jc.ErrorIsNil) 270 store := configstore.NewMem() 271 env, err := environs.Prepare(cfg, envtesting.BootstrapContext(c), store) 272 c.Assert(err, gc.ErrorMatches, "cannot ensure CA certificate: environment configuration with a certificate but no CA private key") 273 c.Assert(env, gc.IsNil) 274 // Ensure that the config storage info is cleaned up. 275 _, err = store.ReadInfo(cfg.Name()) 276 c.Assert(err, jc.Satisfies, errors.IsNotFound) 277 } 278 279 func (*OpenSuite) TestPrepareWithExistingKeyPair(c *gc.C) { 280 cfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Merge( 281 testing.Attrs{ 282 "state-server": false, 283 "name": "erewhemos", 284 "ca-cert": string(testing.CACert), 285 "ca-private-key": string(testing.CAKey), 286 }, 287 )) 288 c.Assert(err, jc.ErrorIsNil) 289 ctx := envtesting.BootstrapContext(c) 290 env, err := environs.Prepare(cfg, ctx, configstore.NewMem()) 291 c.Assert(err, jc.ErrorIsNil) 292 cfgCertPEM, cfgCertOK := env.Config().CACert() 293 cfgKeyPEM, cfgKeyOK := env.Config().CAPrivateKey() 294 c.Assert(cfgCertOK, jc.IsTrue) 295 c.Assert(cfgKeyOK, jc.IsTrue) 296 c.Assert(string(cfgCertPEM), gc.DeepEquals, testing.CACert) 297 c.Assert(string(cfgKeyPEM), gc.DeepEquals, testing.CAKey) 298 } 299 300 func (*OpenSuite) TestDestroy(c *gc.C) { 301 cfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Merge( 302 testing.Attrs{ 303 "state-server": false, 304 "name": "erewhemos", 305 }, 306 )) 307 c.Assert(err, jc.ErrorIsNil) 308 309 store := configstore.NewMem() 310 // Prepare the environment and sanity-check that 311 // the config storage info has been made. 312 ctx := envtesting.BootstrapContext(c) 313 e, err := environs.Prepare(cfg, ctx, store) 314 c.Assert(err, jc.ErrorIsNil) 315 _, err = store.ReadInfo(e.Config().Name()) 316 c.Assert(err, jc.ErrorIsNil) 317 318 err = environs.Destroy(e, store) 319 c.Assert(err, jc.ErrorIsNil) 320 321 // Check that the environment has actually been destroyed 322 // and that the config info has been destroyed too. 323 _, err = e.StateServerInstances() 324 c.Assert(err, gc.ErrorMatches, "environment has been destroyed") 325 _, err = store.ReadInfo(e.Config().Name()) 326 c.Assert(err, jc.Satisfies, errors.IsNotFound) 327 } 328 329 func (*OpenSuite) TestNewFromAttrs(c *gc.C) { 330 e, err := environs.NewFromAttrs(dummy.SampleConfig().Merge( 331 testing.Attrs{ 332 "state-server": false, 333 "name": "erewhemos", 334 }, 335 )) 336 c.Assert(err, gc.ErrorMatches, "environment is not prepared") 337 c.Assert(e, gc.IsNil) 338 }