github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/auditconfigupdater/manifold.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package auditconfigupdater 5 6 import ( 7 "github.com/juju/errors" 8 "gopkg.in/juju/worker.v1" 9 "gopkg.in/juju/worker.v1/dependency" 10 11 jujuagent "github.com/juju/juju/agent" 12 "github.com/juju/juju/core/auditlog" 13 "github.com/juju/juju/worker/common" 14 workerstate "github.com/juju/juju/worker/state" 15 ) 16 17 // ManifoldConfig holds the information needed to run an 18 // auditconfigupdater in a dependency.Engine. 19 type ManifoldConfig struct { 20 AgentName string 21 StateName string 22 NewWorker func(ConfigSource, auditlog.Config, AuditLogFactory) (worker.Worker, error) 23 } 24 25 // Validate validates the manifold configuration. 26 func (config ManifoldConfig) Validate() error { 27 if config.AgentName == "" { 28 return errors.NotValidf("empty AgentName") 29 } 30 if config.StateName == "" { 31 return errors.NotValidf("empty StateName") 32 } 33 if config.NewWorker == nil { 34 return errors.NotValidf("nil NewWorker") 35 } 36 return nil 37 } 38 39 // Manifold returns a dependency.Manifold to run an 40 // auditconfigupdater. 41 func Manifold(config ManifoldConfig) dependency.Manifold { 42 return dependency.Manifold{ 43 Inputs: []string{ 44 config.AgentName, 45 config.StateName, 46 }, 47 Start: config.start, 48 Output: output, 49 } 50 } 51 52 func (config ManifoldConfig) start(context dependency.Context) (_ worker.Worker, err error) { 53 if err := config.Validate(); err != nil { 54 return nil, errors.Trace(err) 55 } 56 57 var agent jujuagent.Agent 58 if err := context.Get(config.AgentName, &agent); err != nil { 59 return nil, errors.Trace(err) 60 } 61 62 var stTracker workerstate.StateTracker 63 if err := context.Get(config.StateName, &stTracker); err != nil { 64 return nil, errors.Trace(err) 65 } 66 statePool, err := stTracker.Use() 67 if err != nil { 68 return nil, errors.Trace(err) 69 } 70 defer func() { 71 if err != nil { 72 stTracker.Done() 73 } 74 }() 75 76 logDir := agent.CurrentConfig().LogDir() 77 78 st := statePool.SystemState() 79 80 logFactory := func(cfg auditlog.Config) auditlog.AuditLog { 81 return auditlog.NewLogFile(logDir, cfg.MaxSizeMB, cfg.MaxBackups) 82 } 83 auditConfig, err := initialConfig(st) 84 if err != nil { 85 return nil, errors.Trace(err) 86 } 87 if auditConfig.Enabled { 88 auditConfig.Target = logFactory(auditConfig) 89 } 90 91 w, err := config.NewWorker(st, auditConfig, logFactory) 92 if err != nil { 93 return nil, errors.Trace(err) 94 } 95 return common.NewCleanupWorker(w, func() { stTracker.Done() }), nil 96 } 97 98 type withCurrentConfig interface { 99 CurrentConfig() auditlog.Config 100 } 101 102 func output(in worker.Worker, out interface{}) error { 103 if w, ok := in.(*common.CleanupWorker); ok { 104 in = w.Worker 105 } 106 w, ok := in.(withCurrentConfig) 107 if !ok { 108 return errors.Errorf("expected worker implementing CurrentConfig(), got %T", in) 109 } 110 target, ok := out.(*func() auditlog.Config) 111 if !ok { 112 return errors.Errorf("out should be *func() auditlog.Config; got %T", out) 113 } 114 *target = w.CurrentConfig 115 return nil 116 } 117 118 func initialConfig(source ConfigSource) (auditlog.Config, error) { 119 cfg, err := source.ControllerConfig() 120 if err != nil { 121 return auditlog.Config{}, errors.Trace(err) 122 } 123 result := auditlog.Config{ 124 Enabled: cfg.AuditingEnabled(), 125 CaptureAPIArgs: cfg.AuditLogCaptureArgs(), 126 MaxSizeMB: cfg.AuditLogMaxSizeMB(), 127 MaxBackups: cfg.AuditLogMaxBackups(), 128 ExcludeMethods: cfg.AuditLogExcludeMethods(), 129 } 130 return result, nil 131 }