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

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package caasbroker
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/loggo"
     9  	"gopkg.in/juju/worker.v1/catacomb"
    10  
    11  	"github.com/juju/juju/caas"
    12  	"github.com/juju/juju/environs"
    13  	"github.com/juju/juju/environs/config"
    14  )
    15  
    16  var logger = loggo.GetLogger("juju.worker.caas")
    17  
    18  // ConfigAPI exposes a model configuration and a watch constructor
    19  // that allows clients to be informed of changes to the configuration.
    20  type ConfigAPI interface {
    21  	CloudSpec() (environs.CloudSpec, error)
    22  	ModelConfig() (*config.Config, error)
    23  }
    24  
    25  // Config describes the dependencies of a Tracker.
    26  //
    27  // It's arguable that it should be called TrackerConfig, because of the heavy
    28  // use of model config in this package.
    29  type Config struct {
    30  	ConfigAPI              ConfigAPI
    31  	NewContainerBrokerFunc caas.NewContainerBrokerFunc
    32  }
    33  
    34  // Validate returns an error if the config cannot be used to start a Tracker.
    35  func (config Config) Validate() error {
    36  	if config.ConfigAPI == nil {
    37  		return errors.NotValidf("nil ConfigAPI")
    38  	}
    39  	if config.NewContainerBrokerFunc == nil {
    40  		return errors.NotValidf("nil NewContainerBrokerFunc")
    41  	}
    42  	return nil
    43  }
    44  
    45  // Tracker loads a caas broker, makes it available to clients, and updates
    46  // the broker in response to config changes until it is killed.
    47  type Tracker struct {
    48  	config   Config
    49  	catacomb catacomb.Catacomb
    50  	broker   caas.Broker
    51  }
    52  
    53  // NewTracker returns a new Tracker, or an error if anything goes wrong.
    54  // If a tracker is returned, its Broker() method is immediately usable.
    55  //
    56  // The caller is responsible for Kill()ing the returned Tracker and Wait()ing
    57  // for any errors it might return.
    58  func NewTracker(config Config) (*Tracker, error) {
    59  	if err := config.Validate(); err != nil {
    60  		return nil, errors.Trace(err)
    61  	}
    62  	cloudSpec, err := config.ConfigAPI.CloudSpec()
    63  	if err != nil {
    64  		return nil, errors.Annotate(err, "cannot get cloud information")
    65  	}
    66  	cfg, err := config.ConfigAPI.ModelConfig()
    67  	if err != nil {
    68  		return nil, errors.Trace(err)
    69  	}
    70  	broker, err := config.NewContainerBrokerFunc(environs.OpenParams{
    71  		Cloud:  cloudSpec,
    72  		Config: cfg,
    73  	})
    74  	if err != nil {
    75  		return nil, errors.Annotate(err, "cannot create caas broker")
    76  	}
    77  
    78  	t := &Tracker{
    79  		config: config,
    80  		broker: broker,
    81  	}
    82  	err = catacomb.Invoke(catacomb.Plan{
    83  		Site: &t.catacomb,
    84  		Work: t.loop,
    85  	})
    86  	if err != nil {
    87  		return nil, errors.Trace(err)
    88  	}
    89  	return t, nil
    90  }
    91  
    92  // Broker returns the encapsulated Broker. It will continue to be updated in
    93  // the background for as long as the Tracker continues to run.
    94  func (t *Tracker) Broker() caas.Broker {
    95  	return t.broker
    96  }
    97  
    98  func (t *Tracker) loop() error {
    99  	// TODO(caas) - watch for config and credential changes
   100  	for {
   101  		logger.Debugf("waiting for config and credential notifications")
   102  		select {
   103  		case <-t.catacomb.Dying():
   104  			return t.catacomb.ErrDying()
   105  		}
   106  	}
   107  }
   108  
   109  // Kill is part of the worker.Worker interface.
   110  func (t *Tracker) Kill() {
   111  	t.catacomb.Kill(nil)
   112  }
   113  
   114  // Wait is part of the worker.Worker interface.
   115  func (t *Tracker) Wait() error {
   116  	return t.catacomb.Wait()
   117  }