github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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  	"github.com/juju/utils"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/cert"
    13  	"github.com/juju/juju/environs"
    14  	"github.com/juju/juju/environs/bootstrap"
    15  	"github.com/juju/juju/environs/config"
    16  	"github.com/juju/juju/environs/filestorage"
    17  	sstesting "github.com/juju/juju/environs/simplestreams/testing"
    18  	envtesting "github.com/juju/juju/environs/testing"
    19  	envtools "github.com/juju/juju/environs/tools"
    20  	"github.com/juju/juju/juju"
    21  	"github.com/juju/juju/jujuclient"
    22  	"github.com/juju/juju/jujuclient/jujuclienttesting"
    23  	"github.com/juju/juju/provider/dummy"
    24  	"github.com/juju/juju/testing"
    25  	jujuversion "github.com/juju/juju/version"
    26  )
    27  
    28  type OpenSuite struct {
    29  	testing.FakeJujuXDGDataHomeSuite
    30  	envtesting.ToolsFixture
    31  }
    32  
    33  var _ = gc.Suite(&OpenSuite{})
    34  
    35  func (s *OpenSuite) SetUpTest(c *gc.C) {
    36  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    37  	s.ToolsFixture.SetUpTest(c)
    38  	s.PatchValue(&juju.JujuPublicKey, sstesting.SignedMetadataPublicKey)
    39  }
    40  
    41  func (s *OpenSuite) TearDownTest(c *gc.C) {
    42  	dummy.Reset(c)
    43  	s.ToolsFixture.TearDownTest(c)
    44  	s.FakeJujuXDGDataHomeSuite.TearDownTest(c)
    45  }
    46  
    47  func (s *OpenSuite) TestNewDummyEnviron(c *gc.C) {
    48  	s.PatchValue(&jujuversion.Current, testing.FakeVersionNumber)
    49  	// matches *Settings.Map()
    50  	cfg, err := config.New(config.NoDefaults, dummySampleConfig())
    51  	c.Assert(err, jc.ErrorIsNil)
    52  	ctx := envtesting.BootstrapContext(c)
    53  	cache := jujuclienttesting.NewMemStore()
    54  	env, err := environs.Prepare(ctx, cache, environs.PrepareParams{
    55  		ControllerName: cfg.Name(),
    56  		BaseConfig:     cfg.AllAttrs(),
    57  		CloudName:      "dummy",
    58  	})
    59  	c.Assert(err, jc.ErrorIsNil)
    60  
    61  	storageDir := c.MkDir()
    62  	s.PatchValue(&envtools.DefaultBaseURL, storageDir)
    63  	stor, err := filestorage.NewFileStorageWriter(storageDir)
    64  	c.Assert(err, jc.ErrorIsNil)
    65  	envtesting.UploadFakeTools(c, stor, cfg.AgentStream(), cfg.AgentStream())
    66  	err = bootstrap.Bootstrap(ctx, env, bootstrap.BootstrapParams{})
    67  	c.Assert(err, jc.ErrorIsNil)
    68  
    69  	// New controller should have been added to collection.
    70  	foundController, err := cache.ControllerByName(cfg.Name())
    71  	c.Assert(err, jc.ErrorIsNil)
    72  	c.Assert(foundController.ControllerUUID, gc.DeepEquals, cfg.UUID())
    73  }
    74  
    75  func (s *OpenSuite) TestUpdateEnvInfo(c *gc.C) {
    76  	store := jujuclienttesting.NewMemStore()
    77  	ctx := envtesting.BootstrapContext(c)
    78  	cfg, err := config.New(config.UseDefaults, map[string]interface{}{
    79  		"type":            "dummy",
    80  		"name":            "admin-model",
    81  		"controller-uuid": utils.MustNewUUID().String(),
    82  		"uuid":            utils.MustNewUUID().String(),
    83  	})
    84  	c.Assert(err, jc.ErrorIsNil)
    85  	_, err = environs.Prepare(ctx, store, environs.PrepareParams{
    86  		ControllerName: "controller-name",
    87  		BaseConfig:     cfg.AllAttrs(),
    88  		CloudName:      "dummy",
    89  	})
    90  	c.Assert(err, jc.ErrorIsNil)
    91  
    92  	foundController, err := store.ControllerByName("controller-name")
    93  	c.Assert(err, jc.ErrorIsNil)
    94  	c.Assert(foundController.ControllerUUID, gc.Equals, cfg.ControllerUUID())
    95  	c.Assert(foundController.CACert, gc.Not(gc.Equals), "")
    96  	foundModel, err := store.ModelByName("controller-name", "admin@local", "admin-model")
    97  	c.Assert(err, jc.ErrorIsNil)
    98  	c.Assert(foundModel, jc.DeepEquals, &jujuclient.ModelDetails{
    99  		ModelUUID: cfg.UUID(),
   100  	})
   101  }
   102  
   103  func (*OpenSuite) TestNewUnknownEnviron(c *gc.C) {
   104  	cfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Merge(
   105  		testing.Attrs{
   106  			"type": "wondercloud",
   107  		},
   108  	))
   109  	c.Assert(err, jc.ErrorIsNil)
   110  	env, err := environs.New(cfg)
   111  	c.Assert(err, gc.ErrorMatches, "no registered provider for.*")
   112  	c.Assert(env, gc.IsNil)
   113  }
   114  
   115  func (*OpenSuite) TestNew(c *gc.C) {
   116  	cfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Merge(
   117  		testing.Attrs{
   118  			"controller": false,
   119  			"name":       "erewhemos",
   120  		},
   121  	))
   122  	c.Assert(err, jc.ErrorIsNil)
   123  	e, err := environs.New(cfg)
   124  	c.Assert(err, gc.ErrorMatches, "model is not prepared")
   125  	c.Assert(e, gc.IsNil)
   126  }
   127  
   128  func (*OpenSuite) TestPrepare(c *gc.C) {
   129  	baselineAttrs := dummy.SampleConfig().Merge(testing.Attrs{
   130  		"controller": false,
   131  		"name":       "erewhemos",
   132  	}).Delete(
   133  		"ca-cert",
   134  		"ca-private-key",
   135  		"admin-secret",
   136  	)
   137  	cfg, err := config.New(config.NoDefaults, baselineAttrs)
   138  	c.Assert(err, jc.ErrorIsNil)
   139  	controllerStore := jujuclienttesting.NewMemStore()
   140  	ctx := envtesting.BootstrapContext(c)
   141  	env, err := environs.Prepare(ctx, controllerStore, environs.PrepareParams{
   142  		ControllerName: cfg.Name(),
   143  		BaseConfig:     cfg.AllAttrs(),
   144  		CloudName:      "dummy",
   145  	})
   146  	c.Assert(err, jc.ErrorIsNil)
   147  
   148  	// Check that an admin-secret was chosen.
   149  	adminSecret := env.Config().AdminSecret()
   150  	c.Assert(adminSecret, gc.HasLen, 32)
   151  	c.Assert(adminSecret, gc.Matches, "^[0-9a-f]*$")
   152  
   153  	// Check that the CA cert was generated.
   154  	cfgCertPEM, cfgCertOK := env.Config().CACert()
   155  	cfgKeyPEM, cfgKeyOK := env.Config().CAPrivateKey()
   156  	c.Assert(cfgCertOK, jc.IsTrue)
   157  	c.Assert(cfgKeyOK, jc.IsTrue)
   158  
   159  	// Check the common name of the generated cert
   160  	caCert, _, err := cert.ParseCertAndKey(cfgCertPEM, cfgKeyPEM)
   161  	c.Assert(err, jc.ErrorIsNil)
   162  	c.Assert(caCert.Subject.CommonName, gc.Equals, `juju-generated CA for model "`+testing.SampleModelName+`"`)
   163  
   164  	// Check that controller was cached
   165  	foundController, err := controllerStore.ControllerByName(cfg.Name())
   166  	c.Assert(err, jc.ErrorIsNil)
   167  	c.Assert(foundController.ControllerUUID, gc.DeepEquals, cfg.UUID())
   168  
   169  	// Check we cannot call Prepare again.
   170  	env, err = environs.Prepare(ctx, controllerStore, environs.PrepareParams{
   171  		ControllerName: cfg.Name(),
   172  		BaseConfig:     cfg.AllAttrs(),
   173  		CloudName:      "dummy",
   174  	})
   175  	c.Assert(err, jc.Satisfies, errors.IsAlreadyExists)
   176  	c.Assert(err, gc.ErrorMatches, `controller "erewhemos" already exists`)
   177  }
   178  
   179  func (*OpenSuite) TestPrepareGeneratesDifferentAdminSecrets(c *gc.C) {
   180  	baselineAttrs := dummy.SampleConfig().Merge(testing.Attrs{
   181  		"controller": false,
   182  		"name":       "erewhemos",
   183  	}).Delete(
   184  		"admin-secret",
   185  	)
   186  
   187  	ctx := envtesting.BootstrapContext(c)
   188  	env0, err := environs.Prepare(ctx, jujuclienttesting.NewMemStore(), environs.PrepareParams{
   189  		ControllerName: "erewhemos",
   190  		BaseConfig:     baselineAttrs,
   191  		CloudName:      "dummy",
   192  	})
   193  	c.Assert(err, jc.ErrorIsNil)
   194  	adminSecret0 := env0.Config().AdminSecret()
   195  	c.Assert(adminSecret0, gc.HasLen, 32)
   196  	c.Assert(adminSecret0, gc.Matches, "^[0-9a-f]*$")
   197  
   198  	// Allocate a new UUID, or we'll end up with the same config.
   199  	newUUID := utils.MustNewUUID()
   200  	baselineAttrs[config.UUIDKey] = newUUID.String()
   201  	baselineAttrs[config.ControllerUUIDKey] = newUUID.String()
   202  
   203  	env1, err := environs.Prepare(ctx, jujuclienttesting.NewMemStore(), environs.PrepareParams{
   204  		ControllerName: "erewhemos",
   205  		BaseConfig:     baselineAttrs,
   206  		CloudName:      "dummy",
   207  	})
   208  	c.Assert(err, jc.ErrorIsNil)
   209  	adminSecret1 := env1.Config().AdminSecret()
   210  	c.Assert(adminSecret1, gc.HasLen, 32)
   211  	c.Assert(adminSecret1, gc.Matches, "^[0-9a-f]*$")
   212  
   213  	c.Assert(adminSecret1, gc.Not(gc.Equals), adminSecret0)
   214  }
   215  
   216  func (*OpenSuite) TestPrepareWithMissingKey(c *gc.C) {
   217  	cfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Delete("ca-cert", "ca-private-key").Merge(
   218  		testing.Attrs{
   219  			"controller": false,
   220  			"name":       "erewhemos",
   221  			"ca-cert":    string(testing.CACert),
   222  		},
   223  	))
   224  	c.Assert(err, jc.ErrorIsNil)
   225  	controllerStore := jujuclienttesting.NewMemStore()
   226  	env, err := environs.Prepare(envtesting.BootstrapContext(c), controllerStore, environs.PrepareParams{
   227  		ControllerName: cfg.Name(),
   228  		BaseConfig:     cfg.AllAttrs(),
   229  		CloudName:      "dummy",
   230  	})
   231  	c.Assert(err, gc.ErrorMatches, "cannot ensure CA certificate: controller configuration with a certificate but no CA private key")
   232  	c.Assert(env, gc.IsNil)
   233  }
   234  
   235  func (*OpenSuite) TestPrepareWithExistingKeyPair(c *gc.C) {
   236  	cfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Merge(
   237  		testing.Attrs{
   238  			"controller":     false,
   239  			"name":           "erewhemos",
   240  			"ca-cert":        string(testing.CACert),
   241  			"ca-private-key": string(testing.CAKey),
   242  		},
   243  	))
   244  	c.Assert(err, jc.ErrorIsNil)
   245  	ctx := envtesting.BootstrapContext(c)
   246  	env, err := environs.Prepare(ctx, jujuclienttesting.NewMemStore(), environs.PrepareParams{
   247  		ControllerName: cfg.Name(),
   248  		BaseConfig:     cfg.AllAttrs(),
   249  		CloudName:      "dummy",
   250  	})
   251  	c.Assert(err, jc.ErrorIsNil)
   252  	cfgCertPEM, cfgCertOK := env.Config().CACert()
   253  	cfgKeyPEM, cfgKeyOK := env.Config().CAPrivateKey()
   254  	c.Assert(cfgCertOK, jc.IsTrue)
   255  	c.Assert(cfgKeyOK, jc.IsTrue)
   256  	c.Assert(string(cfgCertPEM), gc.DeepEquals, testing.CACert)
   257  	c.Assert(string(cfgKeyPEM), gc.DeepEquals, testing.CAKey)
   258  }
   259  
   260  func (*OpenSuite) TestDestroy(c *gc.C) {
   261  	cfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Merge(
   262  		testing.Attrs{
   263  			"name": "erewhemos",
   264  		},
   265  	))
   266  	c.Assert(err, jc.ErrorIsNil)
   267  
   268  	store := jujuclienttesting.NewMemStore()
   269  	// Prepare the environment and sanity-check that
   270  	// the config storage info has been made.
   271  	ctx := envtesting.BootstrapContext(c)
   272  	e, err := environs.Prepare(ctx, store, environs.PrepareParams{
   273  		ControllerName: "controller-name",
   274  		BaseConfig:     cfg.AllAttrs(),
   275  		CloudName:      "dummy",
   276  	})
   277  	c.Assert(err, jc.ErrorIsNil)
   278  	_, err = store.ControllerByName("controller-name")
   279  	c.Assert(err, jc.ErrorIsNil)
   280  
   281  	err = environs.Destroy("controller-name", e, store)
   282  	c.Assert(err, jc.ErrorIsNil)
   283  
   284  	// Check that the environment has actually been destroyed
   285  	// and that the controller details been removed too.
   286  	_, err = e.ControllerInstances()
   287  	c.Assert(err, gc.ErrorMatches, "model is not prepared")
   288  	_, err = store.ControllerByName("controller-name")
   289  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   290  }