~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/state/initialize_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package state_test
 
5
 
 
6
import (
 
7
        gitjujutesting "github.com/juju/testing"
 
8
        jc "github.com/juju/testing/checkers"
 
9
        gc "gopkg.in/check.v1"
 
10
        "gopkg.in/juju/names.v2"
 
11
 
 
12
        "github.com/juju/juju/cloud"
 
13
        "github.com/juju/juju/constraints"
 
14
        "github.com/juju/juju/controller"
 
15
        "github.com/juju/juju/environs/config"
 
16
        "github.com/juju/juju/mongo/mongotest"
 
17
        "github.com/juju/juju/state"
 
18
        statetesting "github.com/juju/juju/state/testing"
 
19
        "github.com/juju/juju/storage"
 
20
        "github.com/juju/juju/testing"
 
21
)
 
22
 
 
23
type InitializeSuite struct {
 
24
        gitjujutesting.MgoSuite
 
25
        testing.BaseSuite
 
26
        State *state.State
 
27
}
 
28
 
 
29
var _ = gc.Suite(&InitializeSuite{})
 
30
 
 
31
func (s *InitializeSuite) SetUpSuite(c *gc.C) {
 
32
        s.BaseSuite.SetUpSuite(c)
 
33
        s.MgoSuite.SetUpSuite(c)
 
34
}
 
35
 
 
36
func (s *InitializeSuite) TearDownSuite(c *gc.C) {
 
37
        s.MgoSuite.TearDownSuite(c)
 
38
        s.BaseSuite.TearDownSuite(c)
 
39
}
 
40
 
 
41
func (s *InitializeSuite) SetUpTest(c *gc.C) {
 
42
        s.BaseSuite.SetUpTest(c)
 
43
        s.MgoSuite.SetUpTest(c)
 
44
}
 
45
 
 
46
func (s *InitializeSuite) openState(c *gc.C, modelTag names.ModelTag) {
 
47
        st, err := state.Open(
 
48
                modelTag,
 
49
                statetesting.NewMongoInfo(),
 
50
                mongotest.DialOpts(),
 
51
                state.NewPolicyFunc(nil),
 
52
        )
 
53
        c.Assert(err, jc.ErrorIsNil)
 
54
        s.State = st
 
55
}
 
56
 
 
57
func (s *InitializeSuite) TearDownTest(c *gc.C) {
 
58
        if s.State != nil {
 
59
                err := s.State.Close()
 
60
                c.Check(err, jc.ErrorIsNil)
 
61
        }
 
62
        s.MgoSuite.TearDownTest(c)
 
63
        s.BaseSuite.TearDownTest(c)
 
64
}
 
65
 
 
66
func (s *InitializeSuite) TestInitialize(c *gc.C) {
 
67
        cfg := testing.ModelConfig(c)
 
68
        uuid := cfg.UUID()
 
69
        owner := names.NewLocalUserTag("initialize-admin")
 
70
 
 
71
        userpassCredential := cloud.NewCredential(
 
72
                cloud.UserPassAuthType,
 
73
                map[string]string{
 
74
                        "username": "alice",
 
75
                        "password": "hunter2",
 
76
                },
 
77
        )
 
78
        userpassCredential.Label = "some-credential"
 
79
        emptyCredential := cloud.NewEmptyCredential()
 
80
        emptyCredential.Label = "empty-credential"
 
81
        cloudCredentialsIn := map[string]cloud.Credential{
 
82
                userpassCredential.Label: userpassCredential,
 
83
                emptyCredential.Label:    emptyCredential,
 
84
        }
 
85
        controllerCfg := testing.FakeControllerConfig()
 
86
        controllerCfg["controller-uuid"] = uuid
 
87
 
 
88
        st, err := state.Initialize(state.InitializeParams{
 
89
                ControllerConfig: controllerCfg,
 
90
                ControllerModelArgs: state.ModelArgs{
 
91
                        Owner:                   owner,
 
92
                        Config:                  cfg,
 
93
                        CloudName:               "dummy",
 
94
                        CloudRegion:             "some-region",
 
95
                        CloudCredential:         "some-credential",
 
96
                        StorageProviderRegistry: storage.StaticProviderRegistry{},
 
97
                },
 
98
                CloudName: "dummy",
 
99
                Cloud: cloud.Cloud{
 
100
                        Type: "dummy",
 
101
                        AuthTypes: []cloud.AuthType{
 
102
                                cloud.EmptyAuthType, cloud.UserPassAuthType,
 
103
                        },
 
104
                        Regions: []cloud.Region{{Name: "some-region"}},
 
105
                },
 
106
                CloudCredentials: cloudCredentialsIn,
 
107
                MongoInfo:        statetesting.NewMongoInfo(),
 
108
                MongoDialOpts:    mongotest.DialOpts(),
 
109
        })
 
110
        c.Assert(err, jc.ErrorIsNil)
 
111
        c.Assert(st, gc.NotNil)
 
112
        modelTag := st.ModelTag()
 
113
        c.Assert(modelTag.Id(), gc.Equals, uuid)
 
114
        err = st.Close()
 
115
        c.Assert(err, jc.ErrorIsNil)
 
116
 
 
117
        s.openState(c, modelTag)
 
118
 
 
119
        cfg, err = s.State.ModelConfig()
 
120
        c.Assert(err, jc.ErrorIsNil)
 
121
        expected := cfg.AllAttrs()
 
122
        for k, v := range config.ConfigDefaults() {
 
123
                if _, ok := expected[k]; !ok {
 
124
                        expected[k] = v
 
125
                }
 
126
        }
 
127
        c.Assert(cfg.AllAttrs(), jc.DeepEquals, expected)
 
128
        // Check that the model has been created.
 
129
        model, err := s.State.Model()
 
130
        c.Assert(err, jc.ErrorIsNil)
 
131
        c.Assert(model.Tag(), gc.Equals, modelTag)
 
132
        c.Assert(model.CloudRegion(), gc.Equals, "some-region")
 
133
        // Check that the owner has been created.
 
134
        c.Assert(model.Owner(), gc.Equals, owner)
 
135
        // Check that the owner can be retrieved by the tag.
 
136
        entity, err := s.State.FindEntity(model.Owner())
 
137
        c.Assert(err, jc.ErrorIsNil)
 
138
        c.Assert(entity.Tag(), gc.Equals, owner)
 
139
        // Check that the owner has an ModelUser created for the bootstrapped model.
 
140
        modelUser, err := s.State.UserAccess(model.Owner(), model.Tag())
 
141
        c.Assert(err, jc.ErrorIsNil)
 
142
        c.Assert(modelUser.UserTag, gc.Equals, owner)
 
143
        c.Assert(modelUser.Object, gc.Equals, model.Tag())
 
144
 
 
145
        // Check that the model can be found through the tag.
 
146
        entity, err = s.State.FindEntity(modelTag)
 
147
        c.Assert(err, jc.ErrorIsNil)
 
148
        cons, err := s.State.ModelConstraints()
 
149
        c.Assert(err, jc.ErrorIsNil)
 
150
        c.Assert(&cons, jc.Satisfies, constraints.IsEmpty)
 
151
 
 
152
        addrs, err := s.State.APIHostPorts()
 
153
        c.Assert(err, jc.ErrorIsNil)
 
154
        c.Assert(addrs, gc.HasLen, 0)
 
155
 
 
156
        info, err := s.State.ControllerInfo()
 
157
        c.Assert(err, jc.ErrorIsNil)
 
158
        c.Assert(info, jc.DeepEquals, &state.ControllerInfo{ModelTag: modelTag, CloudName: "dummy"})
 
159
 
 
160
        // Check that the model's cloud and credential names are as
 
161
        // expected, and the owner's cloud credentials are initialised.
 
162
        c.Assert(model.Cloud(), gc.Equals, "dummy")
 
163
        c.Assert(model.CloudCredential(), gc.Equals, "some-credential")
 
164
        cloudCredentials, err := s.State.CloudCredentials(model.Owner(), "dummy")
 
165
        c.Assert(err, jc.ErrorIsNil)
 
166
        c.Assert(cloudCredentials, jc.DeepEquals, cloudCredentialsIn)
 
167
}
 
168
 
 
169
func (s *InitializeSuite) TestInitializeWithInvalidCredentialType(c *gc.C) {
 
170
        owner := names.NewLocalUserTag("initialize-admin")
 
171
        modelCfg := testing.ModelConfig(c)
 
172
        controllerCfg := testing.FakeControllerConfig()
 
173
        controllerCfg["controller-uuid"] = modelCfg.UUID()
 
174
        _, err := state.Initialize(state.InitializeParams{
 
175
                ControllerConfig: controllerCfg,
 
176
                ControllerModelArgs: state.ModelArgs{
 
177
                        CloudName:               "dummy",
 
178
                        Owner:                   owner,
 
179
                        Config:                  modelCfg,
 
180
                        StorageProviderRegistry: storage.StaticProviderRegistry{},
 
181
                },
 
182
                CloudName: "dummy",
 
183
                Cloud: cloud.Cloud{
 
184
                        Type: "dummy",
 
185
                        AuthTypes: []cloud.AuthType{
 
186
                                cloud.AccessKeyAuthType, cloud.OAuth1AuthType,
 
187
                        },
 
188
                },
 
189
                CloudCredentials: map[string]cloud.Credential{
 
190
                        "borken": cloud.NewCredential(cloud.UserPassAuthType, nil),
 
191
                },
 
192
                MongoInfo:     statetesting.NewMongoInfo(),
 
193
                MongoDialOpts: mongotest.DialOpts(),
 
194
        })
 
195
        c.Assert(err, gc.ErrorMatches,
 
196
                `validating initialization args: validating cloud credentials: credential "borken" with auth-type "userpass" is not supported \(expected one of \["access-key" "oauth1"\]\)`,
 
197
        )
 
198
}
 
199
 
 
200
func (s *InitializeSuite) TestInitializeWithControllerInheritedConfig(c *gc.C) {
 
201
        cfg := testing.ModelConfig(c)
 
202
        uuid := cfg.UUID()
 
203
        initial := cfg.AllAttrs()
 
204
        controllerInheritedConfigIn := map[string]interface{}{
 
205
                "default-series": initial["default-series"],
 
206
        }
 
207
        owner := names.NewLocalUserTag("initialize-admin")
 
208
        controllerCfg := testing.FakeControllerConfig()
 
209
        controllerCfg["controller-uuid"] = uuid
 
210
 
 
211
        st, err := state.Initialize(state.InitializeParams{
 
212
                ControllerConfig: controllerCfg,
 
213
                ControllerModelArgs: state.ModelArgs{
 
214
                        CloudName:               "dummy",
 
215
                        Owner:                   owner,
 
216
                        Config:                  cfg,
 
217
                        StorageProviderRegistry: storage.StaticProviderRegistry{},
 
218
                },
 
219
                CloudName: "dummy",
 
220
                Cloud: cloud.Cloud{
 
221
                        Type:      "dummy",
 
222
                        AuthTypes: []cloud.AuthType{cloud.EmptyAuthType},
 
223
                },
 
224
                ControllerInheritedConfig: controllerInheritedConfigIn,
 
225
                MongoInfo:                 statetesting.NewMongoInfo(),
 
226
                MongoDialOpts:             mongotest.DialOpts(),
 
227
        })
 
228
        c.Assert(err, jc.ErrorIsNil)
 
229
        c.Assert(st, gc.NotNil)
 
230
        modelTag := st.ModelTag()
 
231
        c.Assert(modelTag.Id(), gc.Equals, uuid)
 
232
        err = st.Close()
 
233
        c.Assert(err, jc.ErrorIsNil)
 
234
 
 
235
        s.openState(c, modelTag)
 
236
 
 
237
        controllerInheritedConfig, err := state.ReadSettings(s.State, state.GlobalSettingsC, state.ControllerInheritedSettingsGlobalKey)
 
238
        c.Assert(err, jc.ErrorIsNil)
 
239
        c.Assert(controllerInheritedConfig.Map(), jc.DeepEquals, controllerInheritedConfigIn)
 
240
 
 
241
        expected := cfg.AllAttrs()
 
242
        for k, v := range config.ConfigDefaults() {
 
243
                if _, ok := expected[k]; !ok {
 
244
                        expected[k] = v
 
245
                }
 
246
        }
 
247
        // Config as read from state has resources tags coerced to a map.
 
248
        expected["resource-tags"] = map[string]string{}
 
249
        cfg, err = s.State.ModelConfig()
 
250
        c.Assert(err, jc.ErrorIsNil)
 
251
        c.Assert(cfg.AllAttrs(), jc.DeepEquals, expected)
 
252
}
 
253
 
 
254
func (s *InitializeSuite) TestDoubleInitializeConfig(c *gc.C) {
 
255
        cfg := testing.ModelConfig(c)
 
256
        owner := names.NewLocalUserTag("initialize-admin")
 
257
 
 
258
        mgoInfo := statetesting.NewMongoInfo()
 
259
        dialOpts := mongotest.DialOpts()
 
260
        controllerCfg := testing.FakeControllerConfig()
 
261
        controllerCfg["controller-uuid"] = cfg.UUID()
 
262
 
 
263
        args := state.InitializeParams{
 
264
                ControllerConfig: controllerCfg,
 
265
                ControllerModelArgs: state.ModelArgs{
 
266
                        CloudName:               "dummy",
 
267
                        Owner:                   owner,
 
268
                        Config:                  cfg,
 
269
                        StorageProviderRegistry: storage.StaticProviderRegistry{},
 
270
                },
 
271
                CloudName: "dummy",
 
272
                Cloud: cloud.Cloud{
 
273
                        Type:      "dummy",
 
274
                        AuthTypes: []cloud.AuthType{cloud.EmptyAuthType},
 
275
                },
 
276
                MongoInfo:     mgoInfo,
 
277
                MongoDialOpts: dialOpts,
 
278
        }
 
279
        st, err := state.Initialize(args)
 
280
        c.Assert(err, jc.ErrorIsNil)
 
281
        err = st.Close()
 
282
        c.Check(err, jc.ErrorIsNil)
 
283
 
 
284
        st, err = state.Initialize(args)
 
285
        c.Check(err, gc.ErrorMatches, "already initialized")
 
286
        if !c.Check(st, gc.IsNil) {
 
287
                err = st.Close()
 
288
                c.Check(err, jc.ErrorIsNil)
 
289
        }
 
290
}
 
291
 
 
292
func (s *InitializeSuite) TestModelConfigWithAdminSecret(c *gc.C) {
 
293
        update := map[string]interface{}{"admin-secret": "foo"}
 
294
        remove := []string{}
 
295
        s.testBadModelConfig(c, update, remove, "admin-secret should never be written to the state")
 
296
}
 
297
 
 
298
func (s *InitializeSuite) TestModelConfigWithCAPrivateKey(c *gc.C) {
 
299
        update := map[string]interface{}{"ca-private-key": "foo"}
 
300
        remove := []string{}
 
301
        s.testBadModelConfig(c, update, remove, "ca-private-key should never be written to the state")
 
302
}
 
303
 
 
304
func (s *InitializeSuite) TestModelConfigWithoutAgentVersion(c *gc.C) {
 
305
        update := map[string]interface{}{}
 
306
        remove := []string{"agent-version"}
 
307
        s.testBadModelConfig(c, update, remove, "agent-version must always be set in state")
 
308
}
 
309
 
 
310
func (s *InitializeSuite) testBadModelConfig(c *gc.C, update map[string]interface{}, remove []string, expect string) {
 
311
        good := testing.CustomModelConfig(c, testing.Attrs{"uuid": testing.ModelTag.Id()})
 
312
        bad, err := good.Apply(update)
 
313
        c.Assert(err, jc.ErrorIsNil)
 
314
        bad, err = bad.Remove(remove)
 
315
        c.Assert(err, jc.ErrorIsNil)
 
316
 
 
317
        owner := names.NewLocalUserTag("initialize-admin")
 
318
        controllerCfg := testing.FakeControllerConfig()
 
319
        controllerCfg["controller-uuid"] = good.UUID()
 
320
 
 
321
        args := state.InitializeParams{
 
322
                ControllerConfig: controllerCfg,
 
323
                ControllerModelArgs: state.ModelArgs{
 
324
                        CloudName:               "dummy",
 
325
                        Owner:                   owner,
 
326
                        Config:                  bad,
 
327
                        StorageProviderRegistry: storage.StaticProviderRegistry{},
 
328
                },
 
329
                CloudName: "dummy",
 
330
                Cloud: cloud.Cloud{
 
331
                        Type:      "dummy",
 
332
                        AuthTypes: []cloud.AuthType{cloud.EmptyAuthType},
 
333
                },
 
334
                MongoInfo:     statetesting.NewMongoInfo(),
 
335
                MongoDialOpts: mongotest.DialOpts(),
 
336
        }
 
337
        _, err = state.Initialize(args)
 
338
        c.Assert(err, gc.ErrorMatches, expect)
 
339
 
 
340
        args.ControllerModelArgs.Config = good
 
341
        st, err := state.Initialize(args)
 
342
        c.Assert(err, jc.ErrorIsNil)
 
343
        st.Close()
 
344
 
 
345
        s.openState(c, st.ModelTag())
 
346
        err = s.State.UpdateModelConfig(update, remove, nil)
 
347
        c.Assert(err, gc.ErrorMatches, expect)
 
348
 
 
349
        // ModelConfig remains inviolate.
 
350
        cfg, err := s.State.ModelConfig()
 
351
        c.Assert(err, jc.ErrorIsNil)
 
352
        goodWithDefaults, err := config.New(config.UseDefaults, good.AllAttrs())
 
353
        c.Assert(err, jc.ErrorIsNil)
 
354
        c.Assert(cfg.AllAttrs(), jc.DeepEquals, goodWithDefaults.AllAttrs())
 
355
}
 
356
 
 
357
func (s *InitializeSuite) TestCloudConfigWithForbiddenValues(c *gc.C) {
 
358
        badAttrNames := []string{
 
359
                "admin-secret",
 
360
                "ca-private-key",
 
361
                config.AgentVersionKey,
 
362
        }
 
363
        for _, attr := range controller.ControllerOnlyConfigAttributes {
 
364
                badAttrNames = append(badAttrNames, attr)
 
365
        }
 
366
 
 
367
        modelCfg := testing.ModelConfig(c)
 
368
        controllerCfg := testing.FakeControllerConfig()
 
369
        controllerCfg["controller-uuid"] = modelCfg.UUID()
 
370
        args := state.InitializeParams{
 
371
                ControllerConfig: controllerCfg,
 
372
                ControllerModelArgs: state.ModelArgs{
 
373
                        CloudName:               "dummy",
 
374
                        Owner:                   names.NewLocalUserTag("initialize-admin"),
 
375
                        Config:                  modelCfg,
 
376
                        StorageProviderRegistry: storage.StaticProviderRegistry{},
 
377
                },
 
378
                CloudName: "dummy",
 
379
                Cloud: cloud.Cloud{
 
380
                        Type:      "dummy",
 
381
                        AuthTypes: []cloud.AuthType{cloud.EmptyAuthType},
 
382
                },
 
383
                MongoInfo:     statetesting.NewMongoInfo(),
 
384
                MongoDialOpts: mongotest.DialOpts(),
 
385
        }
 
386
 
 
387
        for _, badAttrName := range badAttrNames {
 
388
                badAttrs := map[string]interface{}{badAttrName: "foo"}
 
389
                args.ControllerInheritedConfig = badAttrs
 
390
                _, err := state.Initialize(args)
 
391
                c.Assert(err, gc.ErrorMatches, "local cloud config cannot contain .*")
 
392
        }
 
393
}