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

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package controllerport
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/pubsub"
     9  	"gopkg.in/juju/worker.v1"
    10  	"gopkg.in/juju/worker.v1/dependency"
    11  
    12  	"github.com/juju/juju/agent"
    13  	"github.com/juju/juju/controller"
    14  	"github.com/juju/juju/state"
    15  	workerstate "github.com/juju/juju/worker/state"
    16  )
    17  
    18  // Logger defines the methods needed for the worker to log messages.
    19  type Logger interface {
    20  	Debugf(string, ...interface{})
    21  	Infof(string, ...interface{})
    22  	Errorf(string, ...interface{})
    23  }
    24  
    25  // ManifoldConfig holds the information necessary to determine the controller
    26  // api port and keep it up to date.
    27  type ManifoldConfig struct {
    28  	AgentName string
    29  	HubName   string
    30  	StateName string
    31  
    32  	Logger                  Logger
    33  	UpdateControllerAPIPort func(int) error
    34  
    35  	GetControllerConfig func(*state.State) (controller.Config, error)
    36  	NewWorker           func(Config) (worker.Worker, error)
    37  }
    38  
    39  // Validate validates the manifold configuration.
    40  func (config ManifoldConfig) Validate() error {
    41  	if config.AgentName == "" {
    42  		return errors.NotValidf("empty AgentName")
    43  	}
    44  	if config.HubName == "" {
    45  		return errors.NotValidf("empty HubName")
    46  	}
    47  	if config.StateName == "" {
    48  		return errors.NotValidf("empty StateName")
    49  	}
    50  	if config.Logger == nil {
    51  		return errors.NotValidf("nil Logger")
    52  	}
    53  	if config.UpdateControllerAPIPort == nil {
    54  		return errors.NotValidf("nil UpdateControllerAPIPort")
    55  	}
    56  	if config.GetControllerConfig == nil {
    57  		return errors.NotValidf("nil GetControllerConfig")
    58  	}
    59  	if config.NewWorker == nil {
    60  		return errors.NotValidf("nil NewWorker")
    61  	}
    62  	return nil
    63  }
    64  
    65  // Manifold returns a dependency.Manifold that will run an HTTP server
    66  // worker. The manifold outputs an *apiserverhttp.Mux, for other workers
    67  // to register handlers against.
    68  func Manifold(config ManifoldConfig) dependency.Manifold {
    69  	return dependency.Manifold{
    70  		Inputs: []string{
    71  			config.AgentName,
    72  			config.HubName,
    73  			config.StateName,
    74  		},
    75  		Start: config.start,
    76  	}
    77  }
    78  
    79  // start is a method on ManifoldConfig because it's more readable than a closure.
    80  func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) {
    81  	if err := config.Validate(); err != nil {
    82  		return nil, errors.Trace(err)
    83  	}
    84  
    85  	var agent agent.Agent
    86  	if err := context.Get(config.AgentName, &agent); err != nil {
    87  		return nil, errors.Trace(err)
    88  	}
    89  
    90  	var hub *pubsub.StructuredHub
    91  	if err := context.Get(config.HubName, &hub); err != nil {
    92  		return nil, errors.Trace(err)
    93  	}
    94  
    95  	var stTracker workerstate.StateTracker
    96  	if err := context.Get(config.StateName, &stTracker); err != nil {
    97  		return nil, errors.Trace(err)
    98  	}
    99  	statePool, err := stTracker.Use()
   100  	if err != nil {
   101  		return nil, errors.Trace(err)
   102  	}
   103  	defer stTracker.Done()
   104  
   105  	systemState := statePool.SystemState()
   106  	controllerConfig, err := config.GetControllerConfig(systemState)
   107  	if err != nil {
   108  		return nil, errors.Annotate(err, "unable to get controller config")
   109  	}
   110  	controllerAPIPort := controllerConfig.ControllerAPIPort()
   111  
   112  	w, err := config.NewWorker(Config{
   113  		AgentConfig:             agent.CurrentConfig(),
   114  		Hub:                     hub,
   115  		Logger:                  config.Logger,
   116  		ControllerAPIPort:       controllerAPIPort,
   117  		UpdateControllerAPIPort: config.UpdateControllerAPIPort,
   118  	})
   119  	if err != nil {
   120  		return nil, errors.Trace(err)
   121  	}
   122  	return w, nil
   123  }
   124  
   125  // GetControllerConfig gets the controller config from the given state
   126  // - it's a shim so we can test the manifold without a state suite.
   127  func GetControllerConfig(st *state.State) (controller.Config, error) {
   128  	return st.ControllerConfig()
   129  }