Example #1
0
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 {
		// 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)
		}
	}
	if err := c.setter.SetAPIHostPorts(hpsToSet); err != nil {
		return fmt.Errorf("error setting addresses: %v", err)
	}
	return nil
}
Example #2
0
// setMachineAddresses sets the addresses for this machine to all of the
// host's non-loopback interface IP addresses.
func setMachineAddresses(tag names.MachineTag, m Machine) error {
	addrs, err := interfaceAddrs()
	if err != nil {
		return err
	}
	var hostAddresses []network.Address
	for _, addr := range addrs {
		var ip net.IP
		switch addr := addr.(type) {
		case *net.IPAddr:
			ip = addr.IP
		case *net.IPNet:
			ip = addr.IP
		default:
			continue
		}
		address := network.NewAddress(ip.String())
		// Filter out link-local addresses as we cannot reliably use them.
		if address.Scope == network.ScopeLinkLocal {
			continue
		}
		hostAddresses = append(hostAddresses, address)
	}
	if len(hostAddresses) == 0 {
		return nil
	}
	// Filter out any LXC bridge addresses.
	hostAddresses = network.FilterLXCAddresses(hostAddresses)
	logger.Infof("setting addresses for %v to %q", tag, hostAddresses)
	return m.SetMachineAddresses(hostAddresses)
}
Example #3
0
// InitializeState should be called on the bootstrap machine's agent
// configuration. It uses that information to create the state server, dial the
// state server, and initialize it. It also generates a new password for the
// bootstrap machine and calls Write to save the the configuration.
//
// The envCfg values will be stored in the state's EnvironConfig; the
// machineCfg values will be used to configure the bootstrap Machine,
// and its constraints will be also be used for the environment-level
// constraints. The connection to the state server will respect the
// given timeout parameter.
//
// InitializeState returns the newly initialized state and bootstrap
// machine. If it fails, the state may well be irredeemably compromised.
func InitializeState(adminUser names.UserTag, c ConfigSetter, envCfg *config.Config, machineCfg BootstrapMachineConfig, dialOpts mongo.DialOpts, policy state.Policy) (_ *state.State, _ *state.Machine, resultErr error) {
	if c.Tag() != names.NewMachineTag(BootstrapMachineId) {
		return nil, nil, errors.Errorf("InitializeState not called with bootstrap machine's configuration")
	}
	servingInfo, ok := c.StateServingInfo()
	if !ok {
		return nil, nil, errors.Errorf("state serving information not available")
	}
	// N.B. no users are set up when we're initializing the state,
	// so don't use any tag or password when opening it.
	info, ok := c.MongoInfo()
	if !ok {
		return nil, nil, errors.Errorf("stateinfo not available")
	}
	info.Tag = nil
	info.Password = c.OldPassword()

	if err := initMongoAdminUser(info.Info, dialOpts, info.Password); err != nil {
		return nil, nil, errors.Annotate(err, "failed to initialize mongo admin user")
	}

	logger.Debugf("initializing address %v", info.Addrs)
	st, err := state.Initialize(adminUser, info, envCfg, dialOpts, policy)
	if err != nil {
		return nil, nil, errors.Errorf("failed to initialize state: %v", err)
	}
	logger.Debugf("connected to initial state")
	defer func() {
		if resultErr != nil {
			st.Close()
		}
	}()
	servingInfo.SharedSecret = machineCfg.SharedSecret
	c.SetStateServingInfo(servingInfo)

	// Filter out any LXC bridge addresses from the machine addresses,
	// except for local environments. See LP bug #1416928.
	if !isLocalEnv(envCfg) {
		machineCfg.Addresses = network.FilterLXCAddresses(machineCfg.Addresses)
	} else {
		logger.Debugf("local environment - not filtering addresses from %v", machineCfg.Addresses)
	}

	if err = initAPIHostPorts(c, st, machineCfg.Addresses, servingInfo.APIPort); err != nil {
		return nil, nil, err
	}
	ssi := paramsStateServingInfoToStateStateServingInfo(servingInfo)
	if err := st.SetStateServingInfo(ssi); err != nil {
		return nil, nil, errors.Errorf("cannot set state serving info: %v", err)
	}
	m, err := initConstraintsAndBootstrapMachine(c, st, machineCfg)
	if err != nil {
		return nil, nil, err
	}
	return st, m, nil
}
Example #4
0
func (s *NetworkSuite) TestFilterLXCAddresses(c *gc.C) {
	lxcFakeNetConfig := filepath.Join(c.MkDir(), "lxc-net")
	netConf := []byte(`
  # comments ignored
LXC_BR= ignored
LXC_ADDR = "fooo"
 LXC_BRIDGE = " foobar " # detected, spaces stripped
anything else ignored
LXC_BRIDGE="ignored"`[1:])
	err := ioutil.WriteFile(lxcFakeNetConfig, netConf, 0644)
	c.Assert(err, jc.ErrorIsNil)
	s.PatchValue(&network.InterfaceByNameAddrs, func(name string) ([]net.Addr, error) {
		c.Assert(name, gc.Equals, "foobar")
		return []net.Addr{
			&net.IPAddr{IP: net.IPv4(10, 0, 3, 1)},
			&net.IPAddr{IP: net.IPv4(10, 0, 3, 4)},
			// Try a CIDR 10.0.3.5/24 as well.
			&net.IPNet{IP: net.IPv4(10, 0, 3, 5), Mask: net.IPv4Mask(255, 255, 255, 0)},
		}, nil
	})
	s.PatchValue(&network.LXCNetDefaultConfig, lxcFakeNetConfig)

	inputAddresses := network.NewAddresses(
		"127.0.0.1",
		"2001:db8::1",
		"10.0.0.1",
		"10.0.3.1", // filtered (directly as IP)
		"10.0.3.3", // filtered (by the 10.0.3.5/24 CIDR)
		"10.0.3.5", // filtered (directly)
		"10.0.3.4", // filtered (directly)
		"192.168.123.42",
	)
	filteredAddresses := network.NewAddresses(
		"127.0.0.1",
		"2001:db8::1",
		"10.0.0.1",
		"192.168.123.42",
	)
	c.Assert(network.FilterLXCAddresses(inputAddresses), jc.DeepEquals, filteredAddresses)
}
Example #5
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
}
Example #6
0
// InitializeState should be called on the bootstrap machine's agent
// configuration. It uses that information to create the controller, dial the
// controller, and initialize it. It also generates a new password for the
// bootstrap machine and calls Write to save the the configuration.
//
// The cfg values will be stored in the state's ModelConfig; the
// machineCfg values will be used to configure the bootstrap Machine,
// and its constraints will be also be used for the model-level
// constraints. The connection to the controller will respect the
// given timeout parameter.
//
// InitializeState returns the newly initialized state and bootstrap
// machine. If it fails, the state may well be irredeemably compromised.
func InitializeState(
	adminUser names.UserTag,
	c agent.ConfigSetter,
	cfg *config.Config,
	hostedModelConfigAttrs map[string]interface{},
	machineCfg BootstrapMachineConfig,
	dialOpts mongo.DialOpts,
	policy state.Policy,
) (_ *state.State, _ *state.Machine, resultErr error) {
	if c.Tag() != names.NewMachineTag(agent.BootstrapMachineId) {
		return nil, nil, errors.Errorf("InitializeState not called with bootstrap machine's configuration")
	}
	servingInfo, ok := c.StateServingInfo()
	if !ok {
		return nil, nil, errors.Errorf("state serving information not available")
	}
	// N.B. no users are set up when we're initializing the state,
	// so don't use any tag or password when opening it.
	info, ok := c.MongoInfo()
	if !ok {
		return nil, nil, errors.Errorf("stateinfo not available")
	}
	info.Tag = nil
	info.Password = c.OldPassword()

	if err := initMongoAdminUser(info.Info, dialOpts, info.Password); err != nil {
		return nil, nil, errors.Annotate(err, "failed to initialize mongo admin user")
	}

	logger.Debugf("initializing address %v", info.Addrs)
	st, err := state.Initialize(adminUser, info, cfg, dialOpts, policy)
	if err != nil {
		return nil, nil, errors.Errorf("failed to initialize state: %v", err)
	}
	logger.Debugf("connected to initial state")
	defer func() {
		if resultErr != nil {
			st.Close()
		}
	}()
	servingInfo.SharedSecret = machineCfg.SharedSecret
	c.SetStateServingInfo(servingInfo)

	// Filter out any LXC bridge addresses from the machine addresses.
	machineCfg.Addresses = network.FilterLXCAddresses(machineCfg.Addresses)

	if err = initAPIHostPorts(c, st, machineCfg.Addresses, servingInfo.APIPort); err != nil {
		return nil, nil, err
	}
	ssi := paramsStateServingInfoToStateStateServingInfo(servingInfo)
	if err := st.SetStateServingInfo(ssi); err != nil {
		return nil, nil, errors.Errorf("cannot set state serving info: %v", err)
	}
	m, err := initConstraintsAndBootstrapMachine(c, st, machineCfg)
	if err != nil {
		return nil, nil, err
	}

	// Create the initial hosted model, with the model config passed to
	// bootstrap, which contains the UUID, name for the hosted model,
	// and any user supplied config.
	attrs := make(map[string]interface{})
	for k, v := range hostedModelConfigAttrs {
		attrs[k] = v
	}
	hostedModelConfig, err := modelmanager.ModelConfigCreator{}.NewModelConfig(modelmanager.IsAdmin, cfg, attrs)
	if err != nil {
		return nil, nil, errors.Annotate(err, "creating hosted model config")
	}
	_, hostedModelState, err := st.NewModel(hostedModelConfig, adminUser)
	if err != nil {
		return nil, nil, errors.Annotate(err, "creating hosted model")
	}
	if err := hostedModelState.SetModelConstraints(machineCfg.ModelConstraints); err != nil {
		return nil, nil, errors.Annotate(err, "cannot set initial hosted model constraints")
	}
	hostedModelState.Close()

	return st, m, nil
}