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  }