github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/apiserver/rsyslog/rsyslog.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package rsyslog 5 6 import ( 7 "github.com/juju/juju/apiserver/common" 8 "github.com/juju/juju/apiserver/params" 9 "github.com/juju/juju/cert" 10 "github.com/juju/juju/state" 11 "github.com/juju/juju/state/watcher" 12 ) 13 14 func init() { 15 common.RegisterStandardFacade("Rsyslog", 0, NewRsyslogAPI) 16 } 17 18 // RsyslogAPI implements the API used by the rsyslog worker. 19 type RsyslogAPI struct { 20 *common.EnvironWatcher 21 22 st *state.State 23 resources *common.Resources 24 authorizer common.Authorizer 25 StateAddresser *common.StateAddresser 26 canModify bool 27 } 28 29 // NewRsyslogAPI creates a new instance of the Rsyslog API. 30 func NewRsyslogAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*RsyslogAPI, error) { 31 if !authorizer.AuthMachineAgent() && !authorizer.AuthUnitAgent() { 32 return nil, common.ErrPerm 33 } 34 return &RsyslogAPI{ 35 EnvironWatcher: common.NewEnvironWatcher(st, resources, authorizer), 36 st: st, 37 authorizer: authorizer, 38 resources: resources, 39 canModify: authorizer.AuthEnvironManager(), 40 StateAddresser: common.NewStateAddresser(st), 41 }, nil 42 } 43 44 // SetRsyslogCert sets the rsyslog CACert. 45 func (api *RsyslogAPI) SetRsyslogCert(args params.SetRsyslogCertParams) (params.ErrorResult, error) { 46 var result params.ErrorResult 47 if !api.canModify { 48 result.Error = common.ServerError(common.ErrBadCreds) 49 return result, nil 50 } 51 if _, err := cert.ParseCert(string(args.CACert)); err != nil { 52 result.Error = common.ServerError(err) 53 return result, nil 54 } 55 attrs := map[string]interface{}{"rsyslog-ca-cert": string(args.CACert)} 56 if err := api.st.UpdateEnvironConfig(attrs, nil, nil); err != nil { 57 result.Error = common.ServerError(err) 58 } 59 return result, nil 60 } 61 62 // GetRsyslogConfig returns a RsyslogConfigResult. 63 func (api *RsyslogAPI) GetRsyslogConfig(args params.Entities) (params.RsyslogConfigResults, error) { 64 result := params.RsyslogConfigResults{ 65 Results: make([]params.RsyslogConfigResult, len(args.Entities)), 66 } 67 cfg, err := api.st.EnvironConfig() 68 if err != nil { 69 return result, err 70 } 71 for i := range args.Entities { 72 rsyslogCfg, err := newRsyslogConfig(cfg, api) 73 if err == nil { 74 result.Results[i] = params.RsyslogConfigResult{ 75 CACert: rsyslogCfg.CACert, 76 Port: rsyslogCfg.Port, 77 HostPorts: rsyslogCfg.HostPorts, 78 } 79 } else { 80 result.Results[i].Error = common.ServerError(err) 81 } 82 } 83 return result, nil 84 } 85 86 // WatchForRsyslogChanges starts a watcher to track if there are changes 87 // that require we update the rsyslog.d configurations for a machine and/or unit. 88 func (api *RsyslogAPI) WatchForRsyslogChanges(args params.Entities) (params.NotifyWatchResults, error) { 89 result := params.NotifyWatchResults{ 90 Results: make([]params.NotifyWatchResult, len(args.Entities)), 91 } 92 for i := range args.Entities { 93 err := common.ErrPerm 94 if api.authorizer.AuthMachineAgent() || api.authorizer.AuthUnitAgent() { 95 watch := api.st.WatchAPIHostPorts() 96 // Consume the initial event. Technically, API 97 // calls to Watch 'transmit' the initial event 98 // in the Watch response. But NotifyWatchers 99 // have no state to transmit. 100 if _, ok := <-watch.Changes(); ok { 101 result.Results[i].NotifyWatcherId = api.resources.Register(watch) 102 err = nil 103 } else { 104 err = watcher.EnsureErr(watch) 105 } 106 } 107 result.Results[i].Error = common.ServerError(err) 108 } 109 return result, nil 110 111 }