-
Notifications
You must be signed in to change notification settings - Fork 0
/
controller.go
137 lines (120 loc) · 3.93 KB
/
controller.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright 2016 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package state
import (
"fmt"
"github.com/juju/errors"
"github.com/juju/utils/clock"
names "gopkg.in/juju/names.v2"
mgo "gopkg.in/mgo.v2"
jujucontroller "github.com/juju/juju/controller"
"github.com/juju/juju/mongo"
)
const (
// controllerSettingsGlobalKey is the key for the controller and its settings.
controllerSettingsGlobalKey = "controllerSettings"
// controllerGlobalKey is the key for controller.
controllerGlobalKey = "c"
)
// controllerKey will return the key for a given controller using the
// controller uuid and the controllerGlobalKey.
func controllerKey(controllerUUID string) string {
return fmt.Sprintf("%s#%s", controllerGlobalKey, controllerUUID)
}
// Controller encapsulates state for the Juju controller as a whole,
// as opposed to model specific functionality.
//
// TODO(menn0) - this is currently unused, pending further refactoring
// of State.
type Controller struct {
clock clock.Clock
controllerModelTag names.ModelTag
controllerTag names.ControllerTag
mongoInfo *mongo.MongoInfo
session *mgo.Session
policy Policy
newPolicy NewPolicyFunc
runTransactionObserver RunTransactionObserverFunc
}
// Close the connection to the database.
func (ctlr *Controller) Close() error {
ctlr.session.Close()
return nil
}
// NewState returns a new State instance for the specified model. The
// connection uses the same credentials and policy as the Controller.
func (ctlr *Controller) NewState(modelTag names.ModelTag) (*State, error) {
session := ctlr.session.Copy()
st, err := newState(
modelTag,
ctlr.controllerModelTag,
session,
ctlr.mongoInfo,
ctlr.newPolicy,
ctlr.clock,
ctlr.runTransactionObserver,
)
if err != nil {
return nil, errors.Trace(err)
}
if err := st.start(ctlr.controllerTag, nil); err != nil {
return nil, errors.Trace(err)
}
return st, nil
}
// Ping probes the Controllers's database connection to ensure that it
// is still alive.
func (ctlr *Controller) Ping() error {
return ctlr.session.Ping()
}
// ControllerConfig returns the config values for the controller.
func (st *State) ControllerConfig() (jujucontroller.Config, error) {
settings, err := readSettings(st.db(), controllersC, controllerSettingsGlobalKey)
if err != nil {
return nil, errors.Trace(err)
}
return settings.Map(), nil
}
// UpdateControllerConfig allows changing some of the configuration
// for the controller. Changes passed in updateAttrs will be applied
// to the current config, and keys in removeAttrs will be unset (and
// so revert to their defaults). Only a subset of keys can be changed
// after bootstrapping.
func (st *State) UpdateControllerConfig(updateAttrs map[string]interface{}, removeAttrs []string) error {
if err := checkControllerConfigNames(updateAttrs, removeAttrs); err != nil {
return errors.Trace(err)
}
settings, err := readSettings(st.db(), controllersC, controllerSettingsGlobalKey)
if err != nil {
return errors.Trace(err)
}
for _, r := range removeAttrs {
settings.Delete(r)
}
settings.Update(updateAttrs)
// Ensure the resulting config is still valid.
newValues := settings.Map()
_, err = jujucontroller.NewConfig(
newValues[jujucontroller.ControllerUUIDKey].(string),
newValues[jujucontroller.CACertKey].(string),
newValues,
)
if err != nil {
return errors.Trace(err)
}
_, ops := settings.settingsUpdateOps()
return errors.Trace(settings.write(ops))
}
func checkControllerConfigNames(updateAttrs map[string]interface{}, removeAttrs []string) error {
for k := range updateAttrs {
if !jujucontroller.AllowedUpdateConfigAttributes.Contains(k) {
return errors.Errorf("can't change %q after bootstrap", k)
}
}
for _, r := range removeAttrs {
if !jujucontroller.AllowedUpdateConfigAttributes.Contains(r) {
return errors.Errorf("can't change %q after bootstrap", r)
}
}
return nil
}