github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/certupdater/manifold.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package certupdater
     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/apiserver/params"
    13  	"github.com/juju/juju/state"
    14  	"github.com/juju/juju/worker/common"
    15  	workerstate "github.com/juju/juju/worker/state"
    16  )
    17  
    18  // ManifoldConfig holds the information necessary to run a certupdater
    19  // in a dependency.Engine.
    20  type ManifoldConfig struct {
    21  	AgentName                string
    22  	StateName                string
    23  	NewWorker                func(Config) worker.Worker
    24  	NewMachineAddressWatcher func(st *state.State, machineId string) (AddressWatcher, error)
    25  }
    26  
    27  // Validate validates the manifold configuration.
    28  func (config ManifoldConfig) Validate() error {
    29  	if config.AgentName == "" {
    30  		return errors.NotValidf("empty AgentName")
    31  	}
    32  	if config.StateName == "" {
    33  		return errors.NotValidf("empty StateName")
    34  	}
    35  	if config.NewWorker == nil {
    36  		return errors.NotValidf("nil NewWorker")
    37  	}
    38  	if config.NewMachineAddressWatcher == nil {
    39  		return errors.NotValidf("nil NewMachineAddressWatcher")
    40  	}
    41  	return nil
    42  }
    43  
    44  // Manifold returns a dependency.Manifold that will run a certupdater.
    45  func Manifold(config ManifoldConfig) dependency.Manifold {
    46  	return dependency.Manifold{
    47  		Inputs: []string{
    48  			config.AgentName,
    49  			config.StateName,
    50  		},
    51  		Start: config.start,
    52  	}
    53  }
    54  
    55  // start is a method on ManifoldConfig because it's more readable than a closure.
    56  func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) {
    57  	if err := config.Validate(); err != nil {
    58  		return nil, errors.Trace(err)
    59  	}
    60  
    61  	var agent jujuagent.Agent
    62  	if err := context.Get(config.AgentName, &agent); err != nil {
    63  		return nil, errors.Trace(err)
    64  	}
    65  
    66  	var stTracker workerstate.StateTracker
    67  	if err := context.Get(config.StateName, &stTracker); err != nil {
    68  		return nil, errors.Trace(err)
    69  	}
    70  	statePool, err := stTracker.Use()
    71  	if err != nil {
    72  		return nil, errors.Trace(err)
    73  	}
    74  
    75  	agentConfig := agent.CurrentConfig()
    76  	setStateServingInfo := func(info params.StateServingInfo) error {
    77  		return agent.ChangeConfig(func(config jujuagent.ConfigSetter) error {
    78  			config.SetStateServingInfo(info)
    79  			return nil
    80  		})
    81  	}
    82  
    83  	st := statePool.SystemState()
    84  	addressWatcher, err := config.NewMachineAddressWatcher(st, agentConfig.Tag().Id())
    85  	if err != nil {
    86  		return nil, errors.Trace(err)
    87  	}
    88  
    89  	w := config.NewWorker(Config{
    90  		AddressWatcher:         addressWatcher,
    91  		StateServingInfoGetter: agentConfig,
    92  		StateServingInfoSetter: setStateServingInfo,
    93  		ControllerConfigGetter: st,
    94  		APIHostPortsGetter:     st,
    95  	})
    96  	return common.NewCleanupWorker(w, func() { stTracker.Done() }), nil
    97  }
    98  
    99  // NewMachineAddressWatcher is the function that non-test code should
   100  // pass into ManifoldConfig.NewMachineAddressWatcher.
   101  func NewMachineAddressWatcher(st *state.State, machineId string) (AddressWatcher, error) {
   102  	return st.Machine(machineId)
   103  }