github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/worker/apiaddressupdater/apiaddressupdater.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package apiaddressupdater
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/loggo"
    10  
    11  	"github.com/juju/juju/api/watcher"
    12  	"github.com/juju/juju/network"
    13  	"github.com/juju/juju/worker"
    14  )
    15  
    16  var logger = loggo.GetLogger("juju.worker.apiaddressupdater")
    17  
    18  // APIAddressUpdater is responsible for propagating API addresses.
    19  //
    20  // In practice, APIAddressUpdater is used by a machine agent to watch
    21  // API addresses in state and write the changes to the agent's config file.
    22  type APIAddressUpdater struct {
    23  	addresser APIAddresser
    24  	setter    APIAddressSetter
    25  }
    26  
    27  // APIAddresser is an interface that is provided to NewAPIAddressUpdater
    28  // which can be used to watch for API address changes.
    29  type APIAddresser interface {
    30  	APIHostPorts() ([][]network.HostPort, error)
    31  	WatchAPIHostPorts() (watcher.NotifyWatcher, error)
    32  }
    33  
    34  // APIAddressSetter is an interface that is provided to NewAPIAddressUpdater
    35  // whose SetAPIHostPorts method will be invoked whenever address changes occur.
    36  type APIAddressSetter interface {
    37  	SetAPIHostPorts(servers [][]network.HostPort) error
    38  }
    39  
    40  // NewAPIAddressUpdater returns a worker.Worker that watches for changes to
    41  // API addresses and then sets them on the APIAddressSetter.
    42  func NewAPIAddressUpdater(addresser APIAddresser, setter APIAddressSetter) worker.Worker {
    43  	return worker.NewNotifyWorker(&APIAddressUpdater{
    44  		addresser: addresser,
    45  		setter:    setter,
    46  	})
    47  }
    48  
    49  func (c *APIAddressUpdater) SetUp() (watcher.NotifyWatcher, error) {
    50  	return c.addresser.WatchAPIHostPorts()
    51  }
    52  
    53  func (c *APIAddressUpdater) Handle(_ <-chan struct{}) error {
    54  	addresses, err := c.addresser.APIHostPorts()
    55  	if err != nil {
    56  		return fmt.Errorf("error getting addresses: %v", err)
    57  	}
    58  	// Filter out any LXC bridge addresses. See LP bug #1416928.
    59  	hpsToSet := make([][]network.HostPort, 0, len(addresses))
    60  	for _, hostPorts := range addresses {
    61  		// Strip ports, filter, then add ports again.
    62  		filtered := network.FilterLXCAddresses(network.HostsWithoutPort(hostPorts))
    63  		hps := make([]network.HostPort, 0, len(filtered))
    64  		for _, hostPort := range hostPorts {
    65  			for _, addr := range filtered {
    66  				if addr.Value == hostPort.Address.Value {
    67  					hps = append(hps, hostPort)
    68  				}
    69  			}
    70  		}
    71  		if len(hps) > 0 {
    72  			hpsToSet = append(hpsToSet, hps)
    73  		}
    74  	}
    75  	if err := c.setter.SetAPIHostPorts(hpsToSet); err != nil {
    76  		return fmt.Errorf("error setting addresses: %v", err)
    77  	}
    78  	logger.Infof("API addresses updated to %q", hpsToSet)
    79  	return nil
    80  }
    81  
    82  func (c *APIAddressUpdater) TearDown() error {
    83  	return nil
    84  }