github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/controller/modelmanager/createmodel_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package modelmanager_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/testing"
     9  	jc "github.com/juju/testing/checkers"
    10  	"github.com/juju/utils"
    11  	"github.com/juju/version"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/cloud"
    15  	"github.com/juju/juju/controller/modelmanager"
    16  	"github.com/juju/juju/environs"
    17  	"github.com/juju/juju/environs/config"
    18  	_ "github.com/juju/juju/provider/all"
    19  	_ "github.com/juju/juju/provider/azure"
    20  	_ "github.com/juju/juju/provider/dummy"
    21  	_ "github.com/juju/juju/provider/ec2"
    22  	_ "github.com/juju/juju/provider/joyent"
    23  	_ "github.com/juju/juju/provider/maas"
    24  	_ "github.com/juju/juju/provider/openstack"
    25  	coretesting "github.com/juju/juju/testing"
    26  	"github.com/juju/juju/tools"
    27  )
    28  
    29  type ModelConfigCreatorSuite struct {
    30  	coretesting.BaseSuite
    31  	fake       fakeProvider
    32  	creator    modelmanager.ModelConfigCreator
    33  	baseConfig *config.Config
    34  }
    35  
    36  var _ = gc.Suite(&ModelConfigCreatorSuite{})
    37  
    38  func (s *ModelConfigCreatorSuite) SetUpTest(c *gc.C) {
    39  	s.BaseSuite.SetUpTest(c)
    40  	s.fake = fakeProvider{
    41  		restrictedConfigAttributes: []string{"restricted"},
    42  	}
    43  	s.creator = modelmanager.ModelConfigCreator{
    44  		Provider: func(provider string) (environs.EnvironProvider, error) {
    45  			if provider != "fake" {
    46  				return nil, errors.Errorf("expected fake, got %s", provider)
    47  			}
    48  			return &s.fake, nil
    49  		},
    50  	}
    51  	baseConfig, err := config.New(
    52  		config.UseDefaults,
    53  		coretesting.FakeConfig().Merge(coretesting.Attrs{
    54  			"type":          "fake",
    55  			"restricted":    "area51",
    56  			"agent-version": "2.0.0",
    57  		}),
    58  	)
    59  	c.Assert(err, jc.ErrorIsNil)
    60  	s.baseConfig = baseConfig
    61  }
    62  
    63  func (s *ModelConfigCreatorSuite) newModelConfig(attrs map[string]interface{}) (*config.Config, error) {
    64  	cloudSpec := environs.CloudSpec{Type: "fake"}
    65  	return s.creator.NewModelConfig(cloudSpec, s.baseConfig, attrs)
    66  }
    67  
    68  func (s *ModelConfigCreatorSuite) TestCreateModelValidatesConfig(c *gc.C) {
    69  	newModelUUID := utils.MustNewUUID().String()
    70  	cfg, err := s.newModelConfig(coretesting.Attrs(
    71  		s.baseConfig.AllAttrs(),
    72  	).Merge(coretesting.Attrs{
    73  		"name":       "new-model",
    74  		"additional": "value",
    75  		"uuid":       newModelUUID,
    76  	}))
    77  	c.Assert(err, jc.ErrorIsNil)
    78  	expected := s.baseConfig.AllAttrs()
    79  	expected["name"] = "new-model"
    80  	expected["additional"] = "value"
    81  	expected["uuid"] = newModelUUID
    82  	c.Assert(cfg.AllAttrs(), jc.DeepEquals, expected)
    83  
    84  	s.fake.Stub.CheckCallNames(c,
    85  		"PrepareConfig",
    86  		"Validate",
    87  	)
    88  	validateCall := s.fake.Stub.Calls()[1]
    89  	c.Assert(validateCall.Args, gc.HasLen, 2)
    90  	c.Assert(validateCall.Args[0], gc.Equals, cfg)
    91  	c.Assert(validateCall.Args[1], gc.IsNil)
    92  }
    93  
    94  func (s *ModelConfigCreatorSuite) TestCreateModelBadConfig(c *gc.C) {
    95  	for i, test := range []struct {
    96  		key      string
    97  		value    interface{}
    98  		errMatch string
    99  	}{{
   100  		key:      "type",
   101  		value:    "dummy",
   102  		errMatch: `specified type "dummy" does not match controller "fake"`,
   103  	}} {
   104  		c.Logf("%d: %s", i, test.key)
   105  		_, err := s.newModelConfig(coretesting.Attrs(
   106  			s.baseConfig.AllAttrs(),
   107  		).Merge(coretesting.Attrs{
   108  			test.key: test.value,
   109  		}))
   110  		c.Check(err, gc.ErrorMatches, test.errMatch)
   111  	}
   112  }
   113  
   114  func (s *ModelConfigCreatorSuite) TestCreateModelSameAgentVersion(c *gc.C) {
   115  	cfg, err := s.newModelConfig(coretesting.Attrs(
   116  		s.baseConfig.AllAttrs(),
   117  	).Merge(coretesting.Attrs{
   118  		"name": "new-model",
   119  		"uuid": utils.MustNewUUID().String(),
   120  	}))
   121  	c.Assert(err, jc.ErrorIsNil)
   122  
   123  	baseAgentVersion, ok := s.baseConfig.AgentVersion()
   124  	c.Assert(ok, jc.IsTrue)
   125  	agentVersion, ok := cfg.AgentVersion()
   126  	c.Assert(ok, jc.IsTrue)
   127  	c.Assert(agentVersion, gc.Equals, baseAgentVersion)
   128  }
   129  
   130  func (s *ModelConfigCreatorSuite) TestCreateModelGreaterAgentVersion(c *gc.C) {
   131  	_, err := s.newModelConfig(coretesting.Attrs(
   132  		s.baseConfig.AllAttrs(),
   133  	).Merge(coretesting.Attrs{
   134  		"name":          "new-model",
   135  		"uuid":          utils.MustNewUUID().String(),
   136  		"agent-version": "2.0.1",
   137  	}))
   138  	c.Assert(err, gc.ErrorMatches,
   139  		"agent-version .* cannot be greater than the controller .*")
   140  }
   141  
   142  func (s *ModelConfigCreatorSuite) TestCreateModelLesserAgentVersionNoToolsFinder(c *gc.C) {
   143  	_, err := s.newModelConfig(coretesting.Attrs(
   144  		s.baseConfig.AllAttrs(),
   145  	).Merge(coretesting.Attrs{
   146  		"name":          "new-model",
   147  		"uuid":          utils.MustNewUUID().String(),
   148  		"agent-version": "1.9.9",
   149  	}))
   150  	c.Assert(err, gc.ErrorMatches,
   151  		"agent-version does not match base config, and no tools-finder is supplied")
   152  }
   153  
   154  func (s *ModelConfigCreatorSuite) TestCreateModelLesserAgentVersionToolsFinderFound(c *gc.C) {
   155  	s.creator.FindTools = func(version.Number) (tools.List, error) {
   156  		return tools.List{
   157  			{}, //contents don't matter, just need a non-empty list
   158  		}, nil
   159  	}
   160  	cfg, err := s.newModelConfig(coretesting.Attrs(
   161  		s.baseConfig.AllAttrs(),
   162  	).Merge(coretesting.Attrs{
   163  		"name":          "new-model",
   164  		"uuid":          utils.MustNewUUID().String(),
   165  		"agent-version": "1.9.9",
   166  	}))
   167  	c.Assert(err, jc.ErrorIsNil)
   168  	agentVersion, ok := cfg.AgentVersion()
   169  	c.Assert(ok, jc.IsTrue)
   170  	c.Assert(agentVersion, gc.Equals, version.MustParse("1.9.9"))
   171  }
   172  
   173  func (s *ModelConfigCreatorSuite) TestCreateModelLesserAgentVersionToolsFinderNotFound(c *gc.C) {
   174  	s.creator.FindTools = func(version.Number) (tools.List, error) {
   175  		return tools.List{}, nil
   176  	}
   177  	_, err := s.newModelConfig(coretesting.Attrs(
   178  		s.baseConfig.AllAttrs(),
   179  	).Merge(coretesting.Attrs{
   180  		"name":          "new-model",
   181  		"uuid":          utils.MustNewUUID().String(),
   182  		"agent-version": "1.9.9",
   183  	}))
   184  	c.Assert(err, gc.ErrorMatches, "no tools found for version .*")
   185  }
   186  
   187  type RestrictedProviderFieldsSuite struct {
   188  	coretesting.BaseSuite
   189  }
   190  
   191  var _ = gc.Suite(&RestrictedProviderFieldsSuite{})
   192  
   193  func (*RestrictedProviderFieldsSuite) TestRestrictedProviderFields(c *gc.C) {
   194  	for i, test := range []struct {
   195  		provider string
   196  		expected []string
   197  	}{{
   198  		provider: "azure",
   199  		expected: []string{"type"},
   200  	}, {
   201  		provider: "dummy",
   202  		expected: []string{"type"},
   203  	}, {
   204  		provider: "joyent",
   205  		expected: []string{"type"},
   206  	}, {
   207  		provider: "maas",
   208  		expected: []string{"type"},
   209  	}, {
   210  		provider: "openstack",
   211  		expected: []string{"type"},
   212  	}, {
   213  		provider: "ec2",
   214  		expected: []string{"type"},
   215  	}} {
   216  		c.Logf("%d: %s provider", i, test.provider)
   217  		provider, err := environs.Provider(test.provider)
   218  		c.Check(err, jc.ErrorIsNil)
   219  		fields, err := modelmanager.RestrictedProviderFields(provider)
   220  		c.Check(err, jc.ErrorIsNil)
   221  		c.Check(fields, jc.SameContents, test.expected)
   222  	}
   223  }
   224  
   225  type fakeProvider struct {
   226  	testing.Stub
   227  	environs.EnvironProvider
   228  	restrictedConfigAttributes []string
   229  }
   230  
   231  func (p *fakeProvider) Validate(cfg, old *config.Config) (*config.Config, error) {
   232  	p.MethodCall(p, "Validate", cfg, old)
   233  	return cfg, p.NextErr()
   234  }
   235  
   236  func (p *fakeProvider) PrepareConfig(args environs.PrepareConfigParams) (*config.Config, error) {
   237  	p.MethodCall(p, "PrepareConfig", args)
   238  	return args.Config, p.NextErr()
   239  }
   240  
   241  func (p *fakeProvider) CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema {
   242  	return map[cloud.AuthType]cloud.CredentialSchema{
   243  		cloud.UserPassAuthType: {
   244  			{
   245  				"username", cloud.CredentialAttr{Description: "The username"},
   246  			}, {
   247  				"password", cloud.CredentialAttr{
   248  					Description: "The password",
   249  					Hidden:      true,
   250  				},
   251  			},
   252  		},
   253  	}
   254  }
   255  
   256  func (p *fakeProvider) DetectCredentials() (*cloud.CloudCredential, error) {
   257  	return nil, errors.NotFoundf("credentials")
   258  }