github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/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 "github.com/juju/worker/v3" 9 "github.com/juju/worker/v3/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, err := statePool.SystemState() 79 if err != nil { 80 return nil, errors.Trace(err) 81 } 82 83 logFactory := func(cfg auditlog.Config) auditlog.AuditLog { 84 return auditlog.NewLogFile(logDir, cfg.MaxSizeMB, cfg.MaxBackups) 85 } 86 auditConfig, err := initialConfig(st) 87 if err != nil { 88 return nil, errors.Trace(err) 89 } 90 if auditConfig.Enabled { 91 auditConfig.Target = logFactory(auditConfig) 92 } 93 94 w, err := config.NewWorker(st, auditConfig, logFactory) 95 if err != nil { 96 return nil, errors.Trace(err) 97 } 98 return common.NewCleanupWorker(w, func() { _ = stTracker.Done() }), nil 99 } 100 101 type withCurrentConfig interface { 102 CurrentConfig() auditlog.Config 103 } 104 105 func output(in worker.Worker, out interface{}) error { 106 if w, ok := in.(*common.CleanupWorker); ok { 107 in = w.Worker 108 } 109 w, ok := in.(withCurrentConfig) 110 if !ok { 111 return errors.Errorf("expected worker implementing CurrentConfig(), got %T", in) 112 } 113 target, ok := out.(*func() auditlog.Config) 114 if !ok { 115 return errors.Errorf("out should be *func() auditlog.Config; got %T", out) 116 } 117 *target = w.CurrentConfig 118 return nil 119 } 120 121 func initialConfig(source ConfigSource) (auditlog.Config, error) { 122 cfg, err := source.ControllerConfig() 123 if err != nil { 124 return auditlog.Config{}, errors.Trace(err) 125 } 126 result := auditlog.Config{ 127 Enabled: cfg.AuditingEnabled(), 128 CaptureAPIArgs: cfg.AuditLogCaptureArgs(), 129 MaxSizeMB: cfg.AuditLogMaxSizeMB(), 130 MaxBackups: cfg.AuditLogMaxBackups(), 131 ExcludeMethods: cfg.AuditLogExcludeMethods(), 132 } 133 return result, nil 134 }