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