github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facade/interface.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package facade 5 6 import ( 7 "gopkg.in/juju/names.v2" 8 9 "github.com/juju/juju/core/cache" 10 "github.com/juju/juju/core/leadership" 11 "github.com/juju/juju/core/lease" 12 "github.com/juju/juju/core/presence" 13 "github.com/juju/juju/permission" 14 "github.com/juju/juju/state" 15 ) 16 17 // Facade could be anything; it will be interpreted by the apiserver 18 // machinery such that certain exported methods will be made available 19 // as facade methods to connected clients. 20 type Facade interface{} 21 22 // Factory is a callback used to create a Facade. 23 type Factory func(Context) (Facade, error) 24 25 // Context exposes useful capabilities to a Facade. 26 type Context interface { 27 28 // Auth represents information about the connected client. You 29 // should always be checking individual requests against Auth: 30 // both state changes *and* data retrieval should be blocked 31 // with common.ErrPerm for any targets for which the client is 32 // not *known* to have a responsibility or requirement. 33 Auth() Authorizer 34 35 // Dispose disposes the context and any resources related to 36 // the API server facade object. Normally the context will not 37 // be disposed until the API connection is closed. This is OK 38 // except when contexts are dynamically generated, such as in 39 // the case of watchers. When a facade context is no longer 40 // needed, e.g. when a watcher is closed, then the context may 41 // be disposed by calling this method. 42 Dispose() 43 44 // Resources exposes per-connection capabilities. By adding a 45 // resource, you make it accessible by (returned) id to all 46 // other facades used by this connection. It's mostly used to 47 // pass watcher ids over to watcher-specific facades, but that 48 // seems to be an antipattern: it breaks the separate-facades- 49 // by-role advice, and makes it inconvenient to track a given 50 // worker's watcher activity alongside its other communications. 51 // 52 // It's also used to hold some config strings used by various 53 // consumers, because it's convenient; and the Pinger that 54 // reports client presence in state, because every Resource gets 55 // Stop()ped on conn close. Not all of these uses are 56 // necessarily a great idea. 57 Resources() Resources 58 59 // State returns, /sigh, a *State. As yet, there is no way 60 // around this; in the not-too-distant future, we hope, its 61 // capabilities will migrate towards access via Resources. 62 State() *state.State 63 64 // StatePool returns the state pool used by the apiserver to minimise the 65 // creation of the expensive *State instances. 66 StatePool() *state.StatePool 67 68 // Controller returns the in-memory representation of the models 69 // in the database. 70 Controller() *cache.Controller 71 72 // Presence returns an instance that is able to be asked for 73 // the current model presence. 74 Presence() Presence 75 76 // Hub returns the central hub that the API server holds. 77 // At least at this stage, facades only need to publish events. 78 Hub() Hub 79 80 // ID returns a string that should almost always be "", unless 81 // this is a watcher facade, in which case it exists in lieu of 82 // actual arguments in the Next() call, and is used as a key 83 // into Resources to get the watcher in play. This is not really 84 // a good idea; see Resources. 85 ID() string 86 87 // LeadershipClaimer returns a leadership.Claimer tied to a 88 // specific model. 89 LeadershipClaimer(modelUUID string) (leadership.Claimer, error) 90 91 // LeadershipChecker returns a leadership.Checker for this 92 // context's model. 93 LeadershipChecker() (leadership.Checker, error) 94 95 // LeadershipPinner returns a leadership.Pinner for this 96 // context's model. 97 LeadershipPinner(modelUUID string) (leadership.Pinner, error) 98 99 // SingularClaimer returns a lease.Claimer for singular leases for 100 // this context's model. 101 SingularClaimer() (lease.Claimer, error) 102 } 103 104 //go:generate mockgen -package mocks -destination mocks/facade_mock.go github.com/juju/juju/apiserver/facade Resources,Authorizer 105 106 // Authorizer represents the authenticated entity using the API server. 107 type Authorizer interface { 108 109 // GetAuthTag returns the entity's tag. 110 GetAuthTag() names.Tag 111 112 // AuthController returns whether the authenticated entity is 113 // a machine acting as a controller. Can't be removed from this 114 // interface without introducing a dependency on something else 115 // to look up that property: it's not inherent in the result of 116 // GetAuthTag, as the other methods all are. 117 AuthController() bool 118 119 // TODO(wallyworld - bug 1733759) - the following auth methods should not be on this interface 120 // eg introduce a utility func or something. 121 122 // AuthMachineAgent returns true if the entity is a machine agent. 123 AuthMachineAgent() bool 124 125 // AuthApplicationAgent returns true if the entity is an application operator. 126 AuthApplicationAgent() bool 127 128 // AuthUnitAgent returns true if the entity is a unit agent. 129 AuthUnitAgent() bool 130 131 // AuthOwner returns true if tag == .GetAuthTag(). 132 AuthOwner(tag names.Tag) bool 133 134 // AuthClient returns true if the entity is an external user. 135 AuthClient() bool 136 137 // HasPermission reports whether the given access is allowed for the given 138 // target by the authenticated entity. 139 HasPermission(operation permission.Access, target names.Tag) (bool, error) 140 141 // UserHasPermission reports whether the given access is allowed for the given 142 // target by the given user. 143 UserHasPermission(user names.UserTag, operation permission.Access, target names.Tag) (bool, error) 144 145 // ConnectedModel returns the UUID of the model to which the API 146 // connection was made. 147 ConnectedModel() string 148 } 149 150 // Resources allows you to store and retrieve Resource implementations. 151 // 152 // The lack of error returns are in deference to the existing 153 // implementation, not because they're a good idea. 154 type Resources interface { 155 Register(Resource) string 156 Get(string) Resource 157 Stop(string) error 158 } 159 160 // Resource should almost certainly be worker.Worker: the current 161 // implementation renders the apiserver vulnerable to deadlock when 162 // shutting down. (See common.Resources.StopAll -- *that* should be a 163 // Kill() and a Wait(), so that connection cleanup can kill the 164 // resources early, along with everything else, and then just wait for 165 // all those things to finish.) 166 type Resource interface { 167 Stop() error 168 } 169 170 // Presence represents the current known state of API connections from agents 171 // to any of the API servers. 172 type Presence interface { 173 ModelPresence(modelUUID string) ModelPresence 174 } 175 176 // ModelPresence represents the API server connections for a model. 177 type ModelPresence interface { 178 // For a given non controller agent, return the Status for that agent. 179 AgentStatus(agent string) (presence.Status, error) 180 } 181 182 // Hub represents the central hub that the API server has. 183 type Hub interface { 184 Publish(topic string, data interface{}) (<-chan struct{}, error) 185 }