github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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/permission" 10 "github.com/juju/juju/state" 11 ) 12 13 // Facade could be anything; it will be interpreted by the apiserver 14 // machinery such that certain exported methods will be made available 15 // as facade methods to connected clients. 16 type Facade interface{} 17 18 // Factory is a callback used to create a Facade. 19 type Factory func(Context) (Facade, error) 20 21 // Context exposes useful capabilities to a Facade. 22 type Context interface { 23 24 // Abort will be closed with the client connection. Any long- 25 // running methods should pay attention to Abort, and terminate 26 // with a sensible (non-nil) error when requested. 27 Abort() <-chan struct{} 28 29 // Auth represents information about the connected client. You 30 // should always be checking individual requests against Auth: 31 // both state changes *and* data retrieval should be blocked 32 // with common.ErrPerm for any targets for which the client is 33 // not *known* to have a responsibility or requirement. 34 Auth() Authorizer 35 36 // Resources exposes per-connection capabilities. By adding a 37 // resource, you make it accessible by (returned) id to all 38 // other facades used by this connection. It's mostly used to 39 // pass watcher ids over to watcher-specific facades, but that 40 // seems to be an antipattern: it breaks the separate-facades- 41 // by-role advice, and makes it inconvenient to track a given 42 // worker's watcher activity alongside its other communications. 43 // 44 // It's also used to hold some config strings used by various 45 // consumers, because it's convenient; and the Pinger that 46 // reports client presence in state, because every Resource gets 47 // Stop()ped on conn close. Not all of these uses are 48 // necessarily a great idea. 49 Resources() Resources 50 51 // State returns, /sigh, a *State. As yet, there is no way 52 // around this; in the not-too-distant future, we hope, its 53 // capabilities will migrate towards access via Resources. 54 State() *state.State 55 56 // ID returns a string that should almost always be "", unless 57 // this is a watcher facade, in which case it exists in lieu of 58 // actual arguments in the Next() call, and is used as a key 59 // into Resources to get the watcher in play. This is not really 60 // a good idea; see Resources. 61 ID() string 62 } 63 64 // Authorizer represents the authenticated entity using the API server. 65 type Authorizer interface { 66 67 // GetAuthTag returns the entity's tag. 68 GetAuthTag() names.Tag 69 70 // AuthModelManager returns whether the authenticated entity is 71 // a machine running the environment manager job. Can't be 72 // removed from this interface without introducing a dependency 73 // on something else to look up that property: it's not inherent 74 // in the result of GetAuthTag, as the other methods all are. 75 AuthModelManager() bool 76 77 // AuthMachineAgent returns true if the entity is a machine 78 // agent. Doesn't need to be on this interface, should be a 79 // utility func if anything. 80 AuthMachineAgent() bool 81 82 // AuthUnitAgent returns true if the entity is a unit agent. 83 // Doesn't need to be on this interface, should be a utility 84 // func if anything. 85 AuthUnitAgent() bool 86 87 // AuthOwner returns true if tag == .GetAuthTag(). Doesn't need 88 // to be on this interface, should be a utility fun if anything. 89 AuthOwner(tag names.Tag) bool 90 91 // AuthClient returns true if the entity is an external user. 92 // Doesn't need to be on this interface, should be a utility 93 // func if anything. 94 AuthClient() bool 95 96 // HasPermission reports whether the given access is allowed for the given 97 // target by the authenticated entity. 98 HasPermission(operation permission.Access, target names.Tag) (bool, error) 99 100 // UserHasPermission reports whether the given access is allowed for the given 101 // target by the given user. 102 UserHasPermission(user names.UserTag, operation permission.Access, target names.Tag) (bool, error) 103 104 // ConnectedModel returns the UUID of the model to which the API 105 // connection was made. 106 ConnectedModel() string 107 } 108 109 // Resources allows you to store and retrieve Resource implementations. 110 // 111 // The lack of error returns are in deference to the existing 112 // implementation, not because they're a good idea. 113 type Resources interface { 114 Register(Resource) string 115 Get(string) Resource 116 Stop(string) error 117 } 118 119 // Resource should almost certainly be worker.Worker: the current 120 // implementation renders the apiserver vulnerable to deadlock when 121 // shutting down. (See common.Resources.StopAll -- *that* should be a 122 // Kill() and a Wait(), so that connection cleanup can kill the 123 // resources early, along with everything else, and then just wait for 124 // all those things to finish.) 125 type Resource interface { 126 Stop() error 127 }