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 }