github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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 }