github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/modelconfig/modelconfig.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package modelconfig 5 6 import ( 7 "github.com/juju/errors" 8 9 "github.com/juju/juju/apiserver/common" 10 "github.com/juju/juju/apiserver/facade" 11 "github.com/juju/juju/apiserver/params" 12 "github.com/juju/juju/environs/config" 13 "github.com/juju/juju/permission" 14 "github.com/juju/juju/state" 15 ) 16 17 func init() { 18 common.RegisterStandardFacade("ModelConfig", 1, newFacade) 19 } 20 21 func newFacade(st *state.State, _ facade.Resources, auth facade.Authorizer) (*ModelConfigAPI, error) { 22 return NewModelConfigAPI(NewStateBackend(st), auth) 23 } 24 25 // ModelConfigAPI is the endpoint which implements the model config facade. 26 type ModelConfigAPI struct { 27 backend Backend 28 auth facade.Authorizer 29 check *common.BlockChecker 30 } 31 32 // NewModelConfigAPI creates a new instance of the ModelConfig Facade. 33 func NewModelConfigAPI(backend Backend, authorizer facade.Authorizer) (*ModelConfigAPI, error) { 34 if !authorizer.AuthClient() { 35 return nil, common.ErrPerm 36 } 37 client := &ModelConfigAPI{ 38 backend: backend, 39 auth: authorizer, 40 check: common.NewBlockChecker(backend), 41 } 42 return client, nil 43 } 44 45 func (c *ModelConfigAPI) checkCanWrite() error { 46 canWrite, err := c.auth.HasPermission(permission.WriteAccess, c.backend.ModelTag()) 47 if err != nil { 48 return errors.Trace(err) 49 } 50 if !canWrite { 51 return common.ErrPerm 52 } 53 return nil 54 } 55 56 func (c *ModelConfigAPI) isAdmin() error { 57 hasAccess, err := c.auth.HasPermission(permission.SuperuserAccess, c.backend.ControllerTag()) 58 if err != nil { 59 return errors.Trace(err) 60 } 61 if !hasAccess { 62 return common.ErrPerm 63 } 64 return nil 65 } 66 67 // ModelGet implements the server-side part of the 68 // model-config CLI command. 69 func (c *ModelConfigAPI) ModelGet() (params.ModelConfigResults, error) { 70 result := params.ModelConfigResults{} 71 if err := c.checkCanWrite(); err != nil { 72 return result, errors.Trace(err) 73 } 74 75 values, err := c.backend.ModelConfigValues() 76 if err != nil { 77 return result, errors.Trace(err) 78 } 79 80 result.Config = make(map[string]params.ConfigValue) 81 for attr, val := range values { 82 // Authorized keys are able to be listed using 83 // juju ssh-keys and including them here just 84 // clutters everything. 85 if attr == config.AuthorizedKeysKey { 86 continue 87 } 88 result.Config[attr] = params.ConfigValue{ 89 Value: val.Value, 90 Source: val.Source, 91 } 92 } 93 return result, nil 94 } 95 96 // ModelSet implements the server-side part of the 97 // set-model-config CLI command. 98 func (c *ModelConfigAPI) ModelSet(args params.ModelSet) error { 99 if err := c.checkCanWrite(); err != nil { 100 return err 101 } 102 103 if err := c.check.ChangeAllowed(); err != nil { 104 return errors.Trace(err) 105 } 106 // Make sure we don't allow changing agent-version. 107 checkAgentVersion := func(updateAttrs map[string]interface{}, removeAttrs []string, oldConfig *config.Config) error { 108 if v, found := updateAttrs["agent-version"]; found { 109 oldVersion, _ := oldConfig.AgentVersion() 110 if v != oldVersion.String() { 111 return errors.New("agent-version cannot be changed") 112 } 113 } 114 return nil 115 } 116 // Replace any deprecated attributes with their new values. 117 attrs := config.ProcessDeprecatedAttributes(args.Config) 118 return c.backend.UpdateModelConfig(attrs, nil, checkAgentVersion) 119 } 120 121 // ModelUnset implements the server-side part of the 122 // set-model-config CLI command. 123 func (c *ModelConfigAPI) ModelUnset(args params.ModelUnset) error { 124 if err := c.checkCanWrite(); err != nil { 125 return err 126 } 127 if err := c.check.ChangeAllowed(); err != nil { 128 return errors.Trace(err) 129 } 130 return c.backend.UpdateModelConfig(nil, args.Keys, nil) 131 }