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