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