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 }