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 }