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