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