Skip to content

Commit b50e830

Browse files
committed
all: store cloud/credentials in state
When bootstrapping, we now store the cloud definition in the state database. We also store the cloud credential used to bootstrap against the admin user, and the name of the credential against the controller and default models.
1 parent ac22cf7 commit b50e830

29 files changed

+817
-298
lines changed

agent/agentbootstrap/bootstrap.go

Lines changed: 49 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ import (
1212

1313
"github.com/juju/juju/agent"
1414
"github.com/juju/juju/apiserver/params"
15-
"github.com/juju/juju/constraints"
15+
"github.com/juju/juju/cloudconfig/instancecfg"
1616
"github.com/juju/juju/controller/modelmanager"
17-
"github.com/juju/juju/environs/config"
1817
"github.com/juju/juju/instance"
1918
"github.com/juju/juju/mongo"
2019
"github.com/juju/juju/network"
@@ -24,27 +23,17 @@ import (
2423

2524
var logger = loggo.GetLogger("juju.agent.agentbootstrap")
2625

27-
// BootstrapMachineConfig holds configuration information
28-
// to attach to the bootstrap machine.
29-
type BootstrapMachineConfig struct {
30-
// Addresses holds the bootstrap machine's addresses.
31-
Addresses []network.Address
26+
// InitializeStateParams holds parameters used for initializing the state
27+
// database.
28+
type InitializeStateParams struct {
29+
instancecfg.StateInitializationParams
3230

33-
// BootstrapConstraints holds the bootstrap machine's constraints.
34-
BootstrapConstraints constraints.Value
31+
// BootstrapMachineAddresses holds the bootstrap machine's addresses.
32+
BootstrapMachineAddresses []network.Address
3533

36-
// ModelConstraints holds the model-level constraints.
37-
ModelConstraints constraints.Value
38-
39-
// Jobs holds the jobs that the machine agent will run.
40-
Jobs []multiwatcher.MachineJob
41-
42-
// InstanceId holds the instance id of the bootstrap machine.
43-
InstanceId instance.Id
44-
45-
// Characteristics holds hardware information on the
46-
// bootstrap machine.
47-
Characteristics instance.HardwareCharacteristics
34+
// BootstrapMachineJobs holds the jobs that the bootstrap machine
35+
// agent will run.
36+
BootstrapMachineJobs []multiwatcher.MachineJob
4837

4938
// SharedSecret is the Mongo replica set shared secret (keyfile).
5039
SharedSecret string
@@ -66,12 +55,7 @@ type BootstrapMachineConfig struct {
6655
func InitializeState(
6756
adminUser names.UserTag,
6857
c agent.ConfigSetter,
69-
cfg *config.Config,
70-
cloudName string,
71-
cloudRegion string,
72-
cloudConfigAttrs map[string]interface{},
73-
hostedModelConfigAttrs map[string]interface{},
74-
machineCfg BootstrapMachineConfig,
58+
args InitializeStateParams,
7559
dialOpts mongo.DialOpts,
7660
policy state.Policy,
7761
) (_ *state.State, _ *state.Machine, resultErr error) {
@@ -96,7 +80,20 @@ func InitializeState(
9680
}
9781

9882
logger.Debugf("initializing address %v", info.Addrs)
99-
st, err := state.Initialize(adminUser, info, cloudName, cloudRegion, cloudConfigAttrs, cfg, dialOpts, policy)
83+
st, err := state.Initialize(state.InitializeParams{
84+
ControllerModelArgs: state.ModelArgs{
85+
Owner: adminUser,
86+
Config: args.ControllerModelConfig,
87+
CloudRegion: args.ControllerCloudRegion,
88+
Constraints: args.ModelConstraints,
89+
},
90+
CloudName: args.ControllerCloudName,
91+
Cloud: args.ControllerCloud,
92+
ModelConfigDefaults: args.ModelConfigDefaults,
93+
MongoInfo: info,
94+
MongoDialOpts: dialOpts,
95+
Policy: policy,
96+
})
10097
if err != nil {
10198
return nil, nil, errors.Errorf("failed to initialize state: %v", err)
10299
}
@@ -106,46 +103,46 @@ func InitializeState(
106103
st.Close()
107104
}
108105
}()
109-
servingInfo.SharedSecret = machineCfg.SharedSecret
106+
servingInfo.SharedSecret = args.SharedSecret
110107
c.SetStateServingInfo(servingInfo)
111108

112109
// Filter out any LXC bridge addresses from the machine addresses.
113-
machineCfg.Addresses = network.FilterLXCAddresses(machineCfg.Addresses)
110+
args.BootstrapMachineAddresses = network.FilterLXCAddresses(args.BootstrapMachineAddresses)
114111

115-
if err = initAPIHostPorts(c, st, machineCfg.Addresses, servingInfo.APIPort); err != nil {
112+
if err = initAPIHostPorts(c, st, args.BootstrapMachineAddresses, servingInfo.APIPort); err != nil {
116113
return nil, nil, err
117114
}
118115
ssi := paramsStateServingInfoToStateStateServingInfo(servingInfo)
119116
if err := st.SetStateServingInfo(ssi); err != nil {
120117
return nil, nil, errors.Errorf("cannot set state serving info: %v", err)
121118
}
122-
m, err := initConstraintsAndBootstrapMachine(c, st, machineCfg)
119+
m, err := initBootstrapMachine(c, st, args)
123120
if err != nil {
124-
return nil, nil, err
121+
return nil, nil, errors.Annotate(err, "cannot initialize bootstrap machine")
125122
}
126123

127124
// Create the initial hosted model, with the model config passed to
128125
// bootstrap, which contains the UUID, name for the hosted model,
129126
// and any user supplied config.
130127
attrs := make(map[string]interface{})
131-
for k, v := range hostedModelConfigAttrs {
128+
for k, v := range args.HostedModelConfig {
132129
attrs[k] = v
133130
}
134-
hostedModelConfig, err := modelmanager.ModelConfigCreator{}.NewModelConfig(modelmanager.IsAdmin, cfg, attrs)
131+
hostedModelConfig, err := modelmanager.ModelConfigCreator{}.NewModelConfig(
132+
modelmanager.IsAdmin, args.ControllerModelConfig, attrs,
133+
)
135134
if err != nil {
136135
return nil, nil, errors.Annotate(err, "creating hosted model config")
137136
}
138137
_, hostedModelState, err := st.NewModel(state.ModelArgs{
139-
CloudRegion: cloudRegion,
140-
Config: hostedModelConfig,
141138
Owner: adminUser,
139+
Config: hostedModelConfig,
140+
CloudRegion: args.ControllerCloudRegion,
141+
Constraints: args.ModelConstraints,
142142
})
143143
if err != nil {
144144
return nil, nil, errors.Annotate(err, "creating hosted model")
145145
}
146-
if err := hostedModelState.SetModelConstraints(machineCfg.ModelConstraints); err != nil {
147-
return nil, nil, errors.Annotate(err, "cannot set initial hosted model constraints")
148-
}
149146
hostedModelState.Close()
150147

151148
return st, m, nil
@@ -163,17 +160,6 @@ func paramsStateServingInfoToStateStateServingInfo(i params.StateServingInfo) st
163160
}
164161
}
165162

166-
func initConstraintsAndBootstrapMachine(c agent.ConfigSetter, st *state.State, cfg BootstrapMachineConfig) (*state.Machine, error) {
167-
if err := st.SetModelConstraints(cfg.ModelConstraints); err != nil {
168-
return nil, errors.Annotate(err, "cannot set initial model constraints")
169-
}
170-
m, err := initBootstrapMachine(c, st, cfg)
171-
if err != nil {
172-
return nil, errors.Annotate(err, "cannot initialize bootstrap machine")
173-
}
174-
return m, nil
175-
}
176-
177163
// initMongoAdminUser adds the admin user with the specified
178164
// password to the admin database in Mongo.
179165
func initMongoAdminUser(info mongo.Info, dialOpts mongo.DialOpts, password string) error {
@@ -186,24 +172,28 @@ func initMongoAdminUser(info mongo.Info, dialOpts mongo.DialOpts, password strin
186172
}
187173

188174
// initBootstrapMachine initializes the initial bootstrap machine in state.
189-
func initBootstrapMachine(c agent.ConfigSetter, st *state.State, cfg BootstrapMachineConfig) (*state.Machine, error) {
190-
logger.Infof("initialising bootstrap machine with config: %+v", cfg)
175+
func initBootstrapMachine(c agent.ConfigSetter, st *state.State, args InitializeStateParams) (*state.Machine, error) {
176+
logger.Infof("initialising bootstrap machine with config: %+v", args)
191177

192-
jobs := make([]state.MachineJob, len(cfg.Jobs))
193-
for i, job := range cfg.Jobs {
178+
jobs := make([]state.MachineJob, len(args.BootstrapMachineJobs))
179+
for i, job := range args.BootstrapMachineJobs {
194180
machineJob, err := machineJobFromParams(job)
195181
if err != nil {
196182
return nil, errors.Errorf("invalid bootstrap machine job %q: %v", job, err)
197183
}
198184
jobs[i] = machineJob
199185
}
186+
var hardware instance.HardwareCharacteristics
187+
if args.BootstrapMachineHardwareCharacteristics != nil {
188+
hardware = *args.BootstrapMachineHardwareCharacteristics
189+
}
200190
m, err := st.AddOneMachine(state.MachineTemplate{
201-
Addresses: cfg.Addresses,
191+
Addresses: args.BootstrapMachineAddresses,
202192
Series: series.HostSeries(),
203193
Nonce: agent.BootstrapNonce,
204-
Constraints: cfg.BootstrapConstraints,
205-
InstanceId: cfg.InstanceId,
206-
HardwareCharacteristics: cfg.Characteristics,
194+
Constraints: args.BootstrapMachineConstraints,
195+
InstanceId: args.BootstrapMachineInstanceId,
196+
HardwareCharacteristics: hardware,
207197
Jobs: jobs,
208198
})
209199
if err != nil {

agent/agentbootstrap/bootstrap_test.go

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818
"github.com/juju/juju/agent"
1919
"github.com/juju/juju/agent/agentbootstrap"
2020
"github.com/juju/juju/apiserver/params"
21+
"github.com/juju/juju/cloud"
22+
"github.com/juju/juju/cloudconfig/instancecfg"
2123
"github.com/juju/juju/constraints"
2224
"github.com/juju/juju/controller"
2325
"github.com/juju/juju/environs"
@@ -109,15 +111,6 @@ LXC_BRIDGE="ignored"`[1:])
109111
"10.0.3.4", // lxc bridge address filtered (-"-).
110112
"10.0.3.3", // not a lxc bridge address
111113
)
112-
mcfg := agentbootstrap.BootstrapMachineConfig{
113-
Addresses: initialAddrs,
114-
BootstrapConstraints: expectBootstrapConstraints,
115-
ModelConstraints: expectModelConstraints,
116-
Jobs: []multiwatcher.MachineJob{multiwatcher.JobManageModel},
117-
InstanceId: "i-bootstrap",
118-
Characteristics: expectHW,
119-
SharedSecret: "abc123",
120-
}
121114
filteredAddrs := network.NewAddresses(
122115
"zeroonetwothree",
123116
"0.1.2.3",
@@ -142,14 +135,31 @@ LXC_BRIDGE="ignored"`[1:])
142135
"name": "hosted",
143136
"uuid": hostedModelUUID,
144137
}
145-
cloudConfigAttrs := map[string]interface{}{
138+
modelConfigDefaults := map[string]interface{}{
146139
"apt-mirror": "http://mirror",
147140
}
148141

142+
args := agentbootstrap.InitializeStateParams{
143+
StateInitializationParams: instancecfg.StateInitializationParams{
144+
BootstrapMachineConstraints: expectBootstrapConstraints,
145+
BootstrapMachineInstanceId: "i-bootstrap",
146+
BootstrapMachineHardwareCharacteristics: &expectHW,
147+
ControllerCloud: cloud.Cloud{Type: "dummy"},
148+
ControllerCloudName: "dummy",
149+
ControllerCloudRegion: "some-region",
150+
ControllerModelConfig: modelCfg,
151+
ModelConstraints: expectModelConstraints,
152+
ModelConfigDefaults: modelConfigDefaults,
153+
HostedModelConfig: hostedModelConfigAttrs,
154+
},
155+
BootstrapMachineAddresses: initialAddrs,
156+
BootstrapMachineJobs: []multiwatcher.MachineJob{multiwatcher.JobManageModel},
157+
SharedSecret: "abc123",
158+
}
159+
149160
adminUser := names.NewLocalUserTag("agent-admin")
150161
st, m, err := agentbootstrap.InitializeState(
151-
adminUser, cfg, modelCfg, "dummy", "some-region", cloudConfigAttrs, hostedModelConfigAttrs, mcfg,
152-
mongotest.DialOpts(), environs.NewStatePolicy(),
162+
adminUser, cfg, args, mongotest.DialOpts(), environs.NewStatePolicy(),
153163
)
154164
c.Assert(err, jc.ErrorIsNil)
155165
defer st.Close()
@@ -276,9 +286,10 @@ func (s *bootstrapSuite) TestInitializeStateWithStateServingInfoNotAvailable(c *
276286
_, available := cfg.StateServingInfo()
277287
c.Assert(available, jc.IsFalse)
278288

289+
args := agentbootstrap.InitializeStateParams{}
290+
279291
adminUser := names.NewLocalUserTag("agent-admin")
280-
_, _, err = agentbootstrap.InitializeState(adminUser, cfg,
281-
nil, "dummy", "some-region", nil, nil, agentbootstrap.BootstrapMachineConfig{}, mongotest.DialOpts(), environs.NewStatePolicy())
292+
_, _, err = agentbootstrap.InitializeState(adminUser, cfg, args, mongotest.DialOpts(), environs.NewStatePolicy())
282293
// InitializeState will fail attempting to get the api port information
283294
c.Assert(err, gc.ErrorMatches, "state serving information not available")
284295
}
@@ -305,13 +316,6 @@ func (s *bootstrapSuite) TestInitializeStateFailsSecondTime(c *gc.C) {
305316
SharedSecret: "baz",
306317
SystemIdentity: "qux",
307318
})
308-
expectHW := instance.MustParseHardware("mem=2048M")
309-
mcfg := agentbootstrap.BootstrapMachineConfig{
310-
BootstrapConstraints: constraints.MustParse("mem=1024M"),
311-
Jobs: []multiwatcher.MachineJob{multiwatcher.JobManageModel},
312-
InstanceId: "i-bootstrap",
313-
Characteristics: expectHW,
314-
}
315319
modelAttrs := dummy.SampleConfig().Delete("admin-secret").Merge(testing.Attrs{
316320
"agent-version": jujuversion.Current.String(),
317321
})
@@ -323,16 +327,29 @@ func (s *bootstrapSuite) TestInitializeStateFailsSecondTime(c *gc.C) {
323327
"uuid": utils.MustNewUUID().String(),
324328
}
325329

330+
args := agentbootstrap.InitializeStateParams{
331+
StateInitializationParams: instancecfg.StateInitializationParams{
332+
BootstrapMachineInstanceId: "i-bootstrap",
333+
ControllerCloud: cloud.Cloud{Type: "dummy"},
334+
ControllerCloudName: "dummy",
335+
ControllerCloudRegion: "some-region",
336+
ControllerModelConfig: modelCfg,
337+
HostedModelConfig: hostedModelConfigAttrs,
338+
},
339+
BootstrapMachineJobs: []multiwatcher.MachineJob{multiwatcher.JobManageModel},
340+
SharedSecret: "abc123",
341+
}
342+
326343
adminUser := names.NewLocalUserTag("agent-admin")
327344
st, _, err := agentbootstrap.InitializeState(
328-
adminUser, cfg, modelCfg, "dummy", "some-region", nil, hostedModelConfigAttrs, mcfg,
329-
mongotest.DialOpts(), state.Policy(nil),
345+
adminUser, cfg, args, mongotest.DialOpts(), state.Policy(nil),
330346
)
331347
c.Assert(err, jc.ErrorIsNil)
332348
st.Close()
333349

334-
st, _, err = agentbootstrap.InitializeState(adminUser, cfg, modelCfg,
335-
"dummy", "some-region", nil, nil, mcfg, mongotest.DialOpts(), environs.NewStatePolicy())
350+
st, _, err = agentbootstrap.InitializeState(
351+
adminUser, cfg, args, mongotest.DialOpts(), state.Policy(nil),
352+
)
336353
if err == nil {
337354
st.Close()
338355
}

0 commit comments

Comments
 (0)