Example #1
0
File: agent.go Project: OSBI/juju
func (c *configInternal) SetAPIHostPorts(servers [][]network.HostPort) {
	if c.apiDetails == nil {
		return
	}
	var addrs []string
	for _, serverHostPorts := range servers {
		// Try the preferred approach first.
		serverHP, ok := network.SelectHostPortBySpace(serverHostPorts, network.DefaultSpace)
		if ok {
			addrs = append(addrs, serverHP.NetAddr())
		} else {
			// Fallback to the legacy approach.
			hps := network.SelectInternalHostPorts(serverHostPorts, false)
			addrs = append(addrs, hps...)
		}
	}
	c.apiDetails.addresses = addrs
	logger.Infof("API server address details %q written to agent config as %q", servers, addrs)
}
Example #2
0
File: address.go Project: OSBI/juju
// SetAPIHostPorts sets the addresses of the API server instances.
// Each server is represented by one element in the top level slice.
func (st *State) SetAPIHostPorts(netHostsPorts [][]network.HostPort) error {
	// Filter any addresses not on the default space, if possible.
	// All API servers need to be accessible there.
	var hpsToSet [][]network.HostPort
	for _, hps := range netHostsPorts {
		defaultSpaceHP, ok := network.SelectHostPortBySpace(hps, network.DefaultSpace)
		if !ok {
			logger.Warningf("cannot determine API addresses in space %q to use as API endpoints; using all addresses", network.DefaultSpace)
			hpsToSet = netHostsPorts
			break
		}
		hpsToSet = append(hpsToSet, []network.HostPort{defaultSpaceHP})
	}

	doc := apiHostPortsDoc{
		APIHostPorts: fromNetworkHostsPorts(hpsToSet),
	}
	buildTxn := func(attempt int) ([]txn.Op, error) {
		existing, err := st.APIHostPorts()
		if err != nil {
			return nil, err
		}
		op := txn.Op{
			C:  controllersC,
			Id: apiHostPortsKey,
			Assert: bson.D{{
				"apihostports", fromNetworkHostsPorts(existing),
			}},
		}
		if !hostsPortsEqual(netHostsPorts, existing) {
			op.Update = bson.D{{
				"$set", bson.D{{"apihostports", doc.APIHostPorts}},
			}}
		}
		return []txn.Op{op}, nil
	}
	if err := st.run(buildTxn); err != nil {
		return errors.Annotate(err, "cannot set API addresses")
	}
	logger.Debugf("setting API hostPorts: %v", hpsToSet)
	return nil
}
Example #3
0
// Handle is part of the watcher.NotifyHandler interface.
func (c *APIAddressUpdater) Handle(_ <-chan struct{}) error {
	addresses, err := c.addresser.APIHostPorts()
	if err != nil {
		return fmt.Errorf("error getting addresses: %v", err)
	}

	// Filter out any LXC bridge addresses. See LP bug #1416928.
	hpsToSet := make([][]network.HostPort, 0, len(addresses))
	for _, hostPorts := range addresses {
		// First try to keep only addresses in the default space where all API servers are on.
		defaultSpaceHP, ok := network.SelectHostPortBySpace(hostPorts, network.DefaultSpace)
		if ok {
			hpsToSet = append(hpsToSet, []network.HostPort{defaultSpaceHP})
			continue
		} else {
			// As a fallback, use the old behavior.
			logger.Warningf("cannot determine API addresses by space %q (using all as fallback)", network.DefaultSpace)
		}

		// Strip ports, filter, then add ports again.
		filtered := network.FilterLXCAddresses(network.HostsWithoutPort(hostPorts))
		hps := make([]network.HostPort, 0, len(filtered))
		for _, hostPort := range hostPorts {
			for _, addr := range filtered {
				if addr.Value == hostPort.Address.Value {
					hps = append(hps, hostPort)
				}
			}
		}
		if len(hps) > 0 {
			hpsToSet = append(hpsToSet, hps)
		}
	}
	logger.Debugf("updating API hostPorts to %+v", hpsToSet)
	if err := c.setter.SetAPIHostPorts(hpsToSet); err != nil {
		return fmt.Errorf("error setting addresses: %v", err)
	}
	return nil
}