Skip to content

Commit fccb9b6

Browse files
committed
Separate model and controller config at backend
1 parent 27b1aaf commit fccb9b6

File tree

103 files changed

+1000
-1148
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+1000
-1148
lines changed

agent/agentbootstrap/bootstrap_test.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/juju/juju/agent/agentbootstrap"
2020
"github.com/juju/juju/apiserver/params"
2121
"github.com/juju/juju/constraints"
22+
"github.com/juju/juju/controller"
2223
"github.com/juju/juju/environs"
2324
"github.com/juju/juju/environs/config"
2425
"github.com/juju/juju/instance"
@@ -168,14 +169,34 @@ LXC_BRIDGE="ignored"`[1:])
168169
c.Assert(err, jc.ErrorIsNil)
169170
c.Assert(user.PasswordValid(testing.DefaultMongoPassword), jc.IsTrue)
170171

172+
// Check controller config
173+
controllerCfg, err := st.ControllerConfig()
174+
c.Assert(err, jc.ErrorIsNil)
175+
c.Assert(controllerCfg, jc.DeepEquals, controller.Config{
176+
"controller-uuid": testing.ModelTag.Id(),
177+
"ca-cert": testing.CACert,
178+
"ca-private-key": testing.CAKey,
179+
"state-port": 1234,
180+
// Dummy provider uses a random port, which is added to cfg used to create environment.
181+
"api-port": controller.Config(modelCfg.AllAttrs()).APIPort(),
182+
})
183+
171184
// Check that controller model configuration has been added, and
172185
// model constraints set.
173186
newModelCfg, err := st.ModelConfig()
174187
c.Assert(err, jc.ErrorIsNil)
175188
// Add in the cloud attributes.
176189
expectedAttrs := modelCfg.AllAttrs()
177190
expectedAttrs["apt-mirror"] = "http://mirror"
178-
c.Assert(newModelCfg.AllAttrs(), gc.DeepEquals, expectedAttrs)
191+
// Remove controller attributes
192+
for _, attr := range controller.ControllerOnlyConfigAttributes {
193+
if attr == controller.ControllerUUIDKey {
194+
continue
195+
}
196+
delete(expectedAttrs, attr)
197+
}
198+
c.Assert(newModelCfg.AllAttrs(), jc.DeepEquals, expectedAttrs)
199+
179200
gotModelConstraints, err := st.ModelConstraints()
180201
c.Assert(err, jc.ErrorIsNil)
181202
c.Assert(gotModelConstraints, gc.DeepEquals, expectModelConstraints)

api/common/modelwatcher.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/juju/juju/api/base"
88
apiwatcher "github.com/juju/juju/api/watcher"
99
"github.com/juju/juju/apiserver/params"
10+
"github.com/juju/juju/controller"
1011
"github.com/juju/juju/environs/config"
1112
"github.com/juju/juju/watcher"
1213
)
@@ -47,3 +48,13 @@ func (e *ModelWatcher) ModelConfig() (*config.Config, error) {
4748
}
4849
return conf, nil
4950
}
51+
52+
// ControllerConfig returns the current controller configuration.
53+
func (e *ModelWatcher) ControllerConfig() (controller.Config, error) {
54+
var result params.ControllerConfigResult
55+
err := e.facade.FacadeCall("ControllerConfig", nil, &result)
56+
if err != nil {
57+
return nil, err
58+
}
59+
return controller.Config(result.Config), nil
60+
}

api/modelmanager/modelmanager_test.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,10 @@ func (s *modelmanagerSuite) TestConfigSkeleton(c *gc.C) {
3434
modelManager := s.OpenAPI(c)
3535
result, err := modelManager.ConfigSkeleton("", "")
3636
c.Assert(err, jc.ErrorIsNil)
37-
38-
// The apiPort changes every test run as the dummy provider
39-
// looks for a random open port.
40-
apiPort := s.Environ.Config().APIPort()
41-
42-
// Numbers coming over the api are floats, not ints.
4337
c.Assert(result, jc.DeepEquals, params.ModelConfig{
4438
"type": "dummy",
4539
"controller-uuid": coretesting.ModelTag.Id(),
46-
"ca-cert": coretesting.CACert,
47-
"state-port": float64(1234),
48-
"api-port": float64(apiPort),
4940
})
50-
5141
}
5242

5343
func (s *modelmanagerSuite) TestCreateModelBadUser(c *gc.C) {

api/testing/macaroonsuite.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
"gopkg.in/macaroon-bakery.v1/httpbakery"
1717

1818
"github.com/juju/juju/api"
19-
"github.com/juju/juju/environs/config"
19+
"github.com/juju/juju/controller"
2020
jujutesting "github.com/juju/juju/juju/testing"
2121
"github.com/juju/juju/testing/factory"
2222
)
@@ -53,7 +53,7 @@ func (s *MacaroonSuite) SetUpTest(c *gc.C) {
5353
return []checkers.Caveat{checkers.DeclaredCaveat("username", username)}, nil
5454
})
5555
s.JujuConnSuite.ConfigAttrs = map[string]interface{}{
56-
config.IdentityURL: s.discharger.Location(),
56+
controller.IdentityURL: s.discharger.Location(),
5757
}
5858
s.JujuConnSuite.SetUpTest(c)
5959
}

apiserver/addresser/addresser.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/juju/juju/instance"
1414
"github.com/juju/juju/network"
1515
"github.com/juju/juju/state"
16+
"github.com/juju/juju/state/utils"
1617
"github.com/juju/juju/state/watcher"
1718
)
1819

@@ -51,11 +52,7 @@ func NewAddresserAPI(
5152
// getNetworkingEnviron checks if the environment implements NetworkingEnviron
5253
// and also if it supports IP address allocation.
5354
func (api *AddresserAPI) getNetworkingEnviron() (environs.NetworkingEnviron, bool, error) {
54-
config, err := api.st.ModelConfig()
55-
if err != nil {
56-
return nil, false, errors.Annotate(err, "getting model config")
57-
}
58-
env, err := environs.New(config)
55+
env, err := utils.GetEnviron(api.st, environs.New)
5956
if err != nil {
6057
return nil, false, errors.Annotate(err, "validating model config")
6158
}

apiserver/addresser/addresser_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func (s *AddresserSuite) TestCanDeallocateAddressesConfigGetFailure(c *gc.C) {
9191
s.st.stub.SetErrors(errors.New("ouch"))
9292

9393
result := s.api.CanDeallocateAddresses()
94-
c.Assert(result.Error, gc.ErrorMatches, "getting model config: ouch")
94+
c.Assert(result.Error, gc.ErrorMatches, "validating model config: ouch")
9595
c.Assert(result.Result, jc.IsFalse)
9696
}
9797

@@ -194,7 +194,7 @@ func (s *AddresserSuite) TestCleanupIPAddressesConfigGetFailure(c *gc.C) {
194194
// First action is getting the environment configuration,
195195
// so the injected error is returned here.
196196
apiErr := s.api.CleanupIPAddresses()
197-
c.Assert(apiErr.Error, gc.ErrorMatches, "getting model config: ouch")
197+
c.Assert(apiErr.Error, gc.ErrorMatches, "validating model config: ouch")
198198

199199
// Still has two dead addresses.
200200
dead, err = s.st.DeadIPAddresses()

apiserver/addresser/mock_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"gopkg.in/juju/names.v2"
1515

1616
"github.com/juju/juju/apiserver/addresser"
17+
"github.com/juju/juju/controller"
1718
"github.com/juju/juju/environs"
1819
"github.com/juju/juju/environs/config"
1920
"github.com/juju/juju/instance"
@@ -92,6 +93,15 @@ func (mst *mockState) ModelConfig() (*config.Config, error) {
9293
return mst.config, nil
9394
}
9495

96+
// ControllerConfig implements StateInterface.
97+
func (*mockState) ControllerConfig() (controller.Config, error) {
98+
return map[string]interface{}{
99+
controller.ControllerUUIDKey: coretesting.ModelTag.Id(),
100+
controller.CACertKey: coretesting.CACert,
101+
controller.CAPrivateKey: coretesting.CAKey,
102+
}, nil
103+
}
104+
95105
// setConfig updates the environ config stored internally. Triggers a
96106
// change event for all created config watchers.
97107
func (mst *mockState) setConfig(c *gc.C, newConfig *config.Config) {

apiserver/addresser/state.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
package addresser
55

66
import (
7-
"github.com/juju/juju/environs/config"
87
"github.com/juju/juju/instance"
98
"github.com/juju/juju/network"
109
"github.com/juju/juju/state"
10+
"github.com/juju/juju/state/utils"
1111
)
1212

1313
// StateIPAddress defines the needed methods of state.IPAddress
@@ -28,8 +28,7 @@ type StateIPAddress interface {
2828
// StateInterface defines the needed methods of state.State
2929
// for the work of the Addresser API.
3030
type StateInterface interface {
31-
// ModelConfig retrieves the model configuration.
32-
ModelConfig() (*config.Config, error)
31+
utils.ConfigGetter
3332

3433
// DeadIPAddresses retrieves all dead IP addresses.
3534
DeadIPAddresses() ([]StateIPAddress, error)

apiserver/agenttools/agenttools.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/juju/juju/environs/config"
1414
"github.com/juju/juju/environs/tools"
1515
"github.com/juju/juju/state"
16+
"github.com/juju/juju/state/utils"
1617
coretools "github.com/juju/juju/tools"
1718
)
1819

@@ -47,6 +48,7 @@ func NewAgentToolsAPI(st *state.State, resources *common.Resources, authorizer c
4748

4849
// EnvironGetter represents a struct that can provide a state.Environment.
4950
type EnvironGetter interface {
51+
utils.ConfigGetter
5052
Model() (*state.Model, error)
5153
}
5254

@@ -55,13 +57,13 @@ type envVersionUpdater func(*state.Model, version.Number) error
5557

5658
var newEnvirons = environs.New
5759

58-
func checkToolsAvailability(cfg *config.Config, finder toolsFinder) (version.Number, error) {
59-
currentVersion, ok := cfg.AgentVersion()
60+
func checkToolsAvailability(getter EnvironGetter, modelCfg *config.Config, finder toolsFinder) (version.Number, error) {
61+
currentVersion, ok := modelCfg.AgentVersion()
6062
if !ok || currentVersion == version.Zero {
6163
return version.Zero, nil
6264
}
6365

64-
env, err := newEnvirons(cfg)
66+
env, err := utils.GetEnviron(getter, newEnvirons)
6567
if err != nil {
6668
return version.Zero, errors.Annotatef(err, "cannot make model")
6769
}
@@ -71,7 +73,7 @@ func checkToolsAvailability(cfg *config.Config, finder toolsFinder) (version.Num
7173
// We'll try the released stream first, then fall back to the current configured stream
7274
// if no released tools are found.
7375
vers, err := finder(env, currentVersion.Major, currentVersion.Minor, tools.ReleasedStream, coretools.Filter{})
74-
preferredStream := tools.PreferredStream(&currentVersion, cfg.Development(), cfg.AgentStream())
76+
preferredStream := tools.PreferredStream(&currentVersion, modelCfg.Development(), modelCfg.AgentStream())
7577
if preferredStream != tools.ReleasedStream && errors.Cause(err) == coretools.ErrNoMatches {
7678
vers, err = finder(env, currentVersion.Major, currentVersion.Minor, preferredStream, coretools.Filter{})
7779
}
@@ -84,7 +86,7 @@ func checkToolsAvailability(cfg *config.Config, finder toolsFinder) (version.Num
8486
return newest, nil
8587
}
8688

87-
var envConfig = func(e *state.Model) (*config.Config, error) {
89+
var modelConfig = func(e *state.Model) (*config.Config, error) {
8890
return e.Config()
8991
}
9092

@@ -94,15 +96,15 @@ func envVersionUpdate(env *state.Model, ver version.Number) error {
9496
}
9597

9698
func updateToolsAvailability(st EnvironGetter, finder toolsFinder, update envVersionUpdater) error {
97-
env, err := st.Model()
99+
model, err := st.Model()
98100
if err != nil {
99101
return errors.Annotate(err, "cannot get model")
100102
}
101-
cfg, err := envConfig(env)
103+
cfg, err := modelConfig(model)
102104
if err != nil {
103105
return errors.Annotate(err, "cannot get config")
104106
}
105-
ver, err := checkToolsAvailability(cfg, finder)
107+
ver, err := checkToolsAvailability(st, cfg, finder)
106108
if err != nil {
107109
if errors.IsNotFound(err) {
108110
// No newer tools, so exit silently.
@@ -114,7 +116,7 @@ func updateToolsAvailability(st EnvironGetter, finder toolsFinder, update envVer
114116
logger.Debugf("tools lookup returned version Zero, this should only happen during bootstrap.")
115117
return nil
116118
}
117-
return update(env, ver)
119+
return update(model, ver)
118120
}
119121

120122
// UpdateToolsAvailable invokes a lookup and further update in environ

apiserver/agenttools/agenttools_test.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/juju/version"
1010
gc "gopkg.in/check.v1"
1111

12+
"github.com/juju/juju/controller"
1213
"github.com/juju/juju/environs"
1314
"github.com/juju/juju/environs/config"
1415
"github.com/juju/juju/state"
@@ -51,7 +52,7 @@ func (s *AgentToolsSuite) TestCheckTools(c *gc.C) {
5152
return coretools.List{&t}, nil
5253
}
5354

54-
ver, err := checkToolsAvailability(cfg, fakeToolFinder)
55+
ver, err := checkToolsAvailability(&modelGetter{cfg: cfg}, cfg, fakeToolFinder)
5556
c.Assert(err, jc.ErrorIsNil)
5657
c.Assert(ver, gc.Not(gc.Equals), version.Zero)
5758
c.Assert(ver, gc.Equals, version.Number{Major: 2, Minor: 5, Patch: 0})
@@ -86,34 +87,43 @@ func (s *AgentToolsSuite) TestCheckToolsNonReleasedStream(c *gc.C) {
8687
c.Assert(calledWithMinor, gc.Equals, 5)
8788
return coretools.List{&t}, nil
8889
}
89-
ver, err := checkToolsAvailability(cfg, fakeToolFinder)
90+
ver, err := checkToolsAvailability(&modelGetter{cfg: cfg}, cfg, fakeToolFinder)
9091
c.Assert(err, jc.ErrorIsNil)
9192
c.Assert(calledWithStreams, gc.DeepEquals, []string{"released", "proposed"})
9293
c.Assert(ver, gc.Not(gc.Equals), version.Zero)
9394
c.Assert(ver, gc.Equals, version.Number{Major: 2, Minor: 5, Patch: 0})
9495
}
9596

9697
type modelGetter struct {
98+
cfg *config.Config
9799
}
98100

99101
func (e *modelGetter) Model() (*state.Model, error) {
100102
return &state.Model{}, nil
101103
}
102104

105+
func (s *modelGetter) ModelConfig() (*config.Config, error) {
106+
return s.cfg, nil
107+
}
108+
109+
func (s *modelGetter) ControllerConfig() (controller.Config, error) {
110+
return controller.Config{}, nil
111+
}
112+
103113
func (s *AgentToolsSuite) TestUpdateToolsAvailability(c *gc.C) {
104114
fakeNewEnvirons := func(*config.Config) (environs.Environ, error) {
105115
return dummyEnviron{}, nil
106116
}
107117
s.PatchValue(&newEnvirons, fakeNewEnvirons)
108118

109-
fakeEnvConfig := func(_ *state.Model) (*config.Config, error) {
119+
fakeModelConfig := func(_ *state.Model) (*config.Config, error) {
110120
sConfig := coretesting.FakeConfig()
111121
sConfig = sConfig.Merge(coretesting.Attrs{
112122
"agent-version": "2.5.0",
113123
})
114124
return config.New(config.NoDefaults, sConfig)
115125
}
116-
s.PatchValue(&envConfig, fakeEnvConfig)
126+
s.PatchValue(&modelConfig, fakeModelConfig)
117127

118128
fakeToolFinder := func(_ environs.Environ, _ int, _ int, _ string, _ coretools.Filter) (coretools.List, error) {
119129
ver := version.Binary{Number: version.Number{Major: 2, Minor: 5, Patch: 2}}
@@ -129,7 +139,9 @@ func (s *AgentToolsSuite) TestUpdateToolsAvailability(c *gc.C) {
129139
return nil
130140
}
131141

132-
err := updateToolsAvailability(&modelGetter{}, fakeToolFinder, fakeUpdate)
142+
cfg, err := config.New(config.NoDefaults, coretesting.FakeConfig())
143+
c.Assert(err, jc.ErrorIsNil)
144+
err = updateToolsAvailability(&modelGetter{cfg: cfg}, fakeToolFinder, fakeUpdate)
133145
c.Assert(err, jc.ErrorIsNil)
134146

135147
c.Assert(ver, gc.Not(gc.Equals), version.Zero)
@@ -142,14 +154,14 @@ func (s *AgentToolsSuite) TestUpdateToolsAvailabilityNoMatches(c *gc.C) {
142154
}
143155
s.PatchValue(&newEnvirons, fakeNewEnvirons)
144156

145-
fakeEnvConfig := func(_ *state.Model) (*config.Config, error) {
157+
fakeModelConfig := func(_ *state.Model) (*config.Config, error) {
146158
sConfig := coretesting.FakeConfig()
147159
sConfig = sConfig.Merge(coretesting.Attrs{
148160
"agent-version": "2.5.0",
149161
})
150162
return config.New(config.NoDefaults, sConfig)
151163
}
152-
s.PatchValue(&envConfig, fakeEnvConfig)
164+
s.PatchValue(&modelConfig, fakeModelConfig)
153165

154166
// No new tools available.
155167
fakeToolFinder := func(_ environs.Environ, _ int, _ int, _ string, _ coretools.Filter) (coretools.List, error) {
@@ -162,6 +174,8 @@ func (s *AgentToolsSuite) TestUpdateToolsAvailabilityNoMatches(c *gc.C) {
162174
return nil
163175
}
164176

165-
err := updateToolsAvailability(&modelGetter{}, fakeToolFinder, fakeUpdate)
177+
cfg, err := config.New(config.NoDefaults, coretesting.FakeConfig())
178+
c.Assert(err, jc.ErrorIsNil)
179+
err = updateToolsAvailability(&modelGetter{cfg: cfg}, fakeToolFinder, fakeUpdate)
166180
c.Assert(err, jc.ErrorIsNil)
167181
}

apiserver/authcontext.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,17 @@ var errMacaroonAuthNotConfigured = errors.New("macaroon authentication is not co
107107
// macaroon-based logins for external users. This is just a helper function
108108
// for authCtxt.macaroonAuth.
109109
func newExternalMacaroonAuth(st *state.State) (*authentication.ExternalMacaroonAuthenticator, error) {
110-
envCfg, err := st.ModelConfig()
110+
controllerCfg, err := st.ControllerConfig()
111111
if err != nil {
112112
return nil, errors.Annotate(err, "cannot get model config")
113113
}
114-
idURL := envCfg.IdentityURL()
114+
idURL := controllerCfg.IdentityURL()
115115
if idURL == "" {
116116
return nil, errMacaroonAuthNotConfigured
117117
}
118118
// The identity server has been configured,
119119
// so configure the bakery service appropriately.
120-
idPK := envCfg.IdentityPublicKey()
120+
idPK := controllerCfg.IdentityPublicKey()
121121
if idPK == nil {
122122
// No public key supplied - retrieve it from the identity manager.
123123
idPK, err = httpbakery.PublicKeyForLocation(http.DefaultClient, idURL)

0 commit comments

Comments
 (0)