github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/state/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/cert" 8 "github.com/juju/juju/state" 9 "github.com/juju/juju/state/api/params" 10 "github.com/juju/juju/state/apiserver/common" 11 "github.com/juju/juju/state/watcher" 12 ) 13 14 // RsyslogAPI implements the API used by the rsyslog worker. 15 type RsyslogAPI struct { 16 *common.EnvironWatcher 17 18 st *state.State 19 resources *common.Resources 20 authorizer common.Authorizer 21 StateAddresser *common.StateAddresser 22 canModify bool 23 } 24 25 // NewRsyslogAPI creates a new instance of the Rsyslog API. 26 func NewRsyslogAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*RsyslogAPI, error) { 27 if !authorizer.AuthMachineAgent() && !authorizer.AuthUnitAgent() { 28 return nil, common.ErrPerm 29 } 30 // Can always watch for environ changes. 31 getCanWatch := common.AuthAlways(true) 32 // Does not get the secrets. 33 getCanReadSecrets := common.AuthAlways(false) 34 return &RsyslogAPI{ 35 EnvironWatcher: common.NewEnvironWatcher(st, resources, getCanWatch, getCanReadSecrets), 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.MustErr(watch) 105 } 106 } 107 result.Results[i].Error = common.ServerError(err) 108 } 109 return result, nil 110 111 }