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  }