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