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  }