launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/state/apiserver/logger/logger.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package logger
     5  
     6  import (
     7  	"github.com/loggo/loggo"
     8  	"launchpad.net/juju-core/state"
     9  	"launchpad.net/juju-core/state/api/params"
    10  	"launchpad.net/juju-core/state/apiserver/common"
    11  	"launchpad.net/juju-core/state/watcher"
    12  )
    13  
    14  var logger = loggo.GetLogger("juju.api.logger")
    15  
    16  // Logger defines the methods on the logger API end point.  Unfortunately, the
    17  // api infrastructure doesn't allow interfaces to be used as an actual
    18  // endpoint because our rpc mechanism panics.  However, I still feel that this
    19  // provides a useful documentation purpose.
    20  type Logger interface {
    21  	WatchLoggingConfig(args params.Entities) params.NotifyWatchResults
    22  	LoggingConfig(args params.Entities) params.StringResults
    23  }
    24  
    25  // LoggerAPI implements the Logger interface and is the concrete
    26  // implementation of the api end point.
    27  type LoggerAPI struct {
    28  	state      *state.State
    29  	resources  *common.Resources
    30  	authorizer common.Authorizer
    31  }
    32  
    33  var _ Logger = (*LoggerAPI)(nil)
    34  
    35  // NewLoggerAPI creates a new server-side logger API end point.
    36  func NewLoggerAPI(
    37  	st *state.State,
    38  	resources *common.Resources,
    39  	authorizer common.Authorizer,
    40  ) (*LoggerAPI, error) {
    41  	if !authorizer.AuthMachineAgent() && !authorizer.AuthUnitAgent() {
    42  		return nil, common.ErrPerm
    43  	}
    44  	return &LoggerAPI{state: st, resources: resources, authorizer: authorizer}, nil
    45  }
    46  
    47  // WatchLoggingConfig starts a watcher to track changes to the logging config
    48  // for the agents specified..  Unfortunately the current infrastruture makes
    49  // watching parts of the config non-trivial, so currently any change to the
    50  // config will cause the watcher to notify the client.
    51  func (api *LoggerAPI) WatchLoggingConfig(arg params.Entities) params.NotifyWatchResults {
    52  	result := make([]params.NotifyWatchResult, len(arg.Entities))
    53  	for i, entity := range arg.Entities {
    54  		err := common.ErrPerm
    55  		if api.authorizer.AuthOwner(entity.Tag) {
    56  			watch := api.state.WatchForEnvironConfigChanges()
    57  			// Consume the initial event. Technically, API calls to Watch
    58  			// 'transmit' the initial event in the Watch response. But
    59  			// NotifyWatchers have no state to transmit.
    60  			if _, ok := <-watch.Changes(); ok {
    61  				result[i].NotifyWatcherId = api.resources.Register(watch)
    62  				err = nil
    63  			} else {
    64  				err = watcher.MustErr(watch)
    65  			}
    66  		}
    67  		result[i].Error = common.ServerError(err)
    68  	}
    69  	return params.NotifyWatchResults{result}
    70  }
    71  
    72  // LoggingConfig reports the logging configuration for the agents specified.
    73  func (api *LoggerAPI) LoggingConfig(arg params.Entities) params.StringResults {
    74  	if len(arg.Entities) == 0 {
    75  		return params.StringResults{}
    76  	}
    77  	results := make([]params.StringResult, len(arg.Entities))
    78  	config, configErr := api.state.EnvironConfig()
    79  	for i, entity := range arg.Entities {
    80  		err := common.ErrPerm
    81  		if api.authorizer.AuthOwner(entity.Tag) {
    82  			if configErr == nil {
    83  				results[i].Result = config.LoggingConfig()
    84  				err = nil
    85  			} else {
    86  				err = configErr
    87  			}
    88  		}
    89  		results[i].Error = common.ServerError(err)
    90  	}
    91  	return params.StringResults{results}
    92  }