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 }