Beispiel #1
0
func (s *APIEndpointForEnvSuite) TestAPIEndpointNotMachineLocal(c *gc.C) {
	store := newConfigStore("env-name", dummyStoreInfo)
	called := 0
	hostPorts := [][]instance.HostPort{
		instance.AddressesWithPort([]instance.Address{
			instance.NewAddress("1.0.0.1", instance.NetworkPublic),
			instance.NewAddress("192.0.0.1", instance.NetworkCloudLocal),
			instance.NewAddress("127.0.0.1", instance.NetworkMachineLocal),
			instance.NewAddress("localhost", instance.NetworkMachineLocal),
		}, 1234),
		instance.AddressesWithPort([]instance.Address{
			instance.NewAddress("1.0.0.2", instance.NetworkUnknown),
			instance.NewAddress("2002:0:0:0:0:0:100:2", instance.NetworkUnknown),
			instance.NewAddress("::1", instance.NetworkMachineLocal),
			instance.NewAddress("127.0.0.1", instance.NetworkMachineLocal),
			instance.NewAddress("localhost", instance.NetworkMachineLocal),
		}, 1235),
	}

	expectState := &mockAPIState{apiHostPorts: hostPorts}
	apiOpen := func(_ *api.Info, _ api.DialOpts) (juju.APIState, error) {
		called++
		return expectState, nil
	}
	endpoint, err := juju.APIEndpointInStore("env-name", true, store, apiOpen)
	c.Assert(err, gc.IsNil)
	c.Check(called, gc.Equals, 1)
	c.Check(endpoint.Addresses, gc.DeepEquals, []string{
		"1.0.0.1:1234",
		"192.0.0.1:1234",
		"1.0.0.2:1235",
	})
}
Beispiel #2
0
func (s *MachineSuite) TestMachineAgentRunsAPIAddressUpdaterWorker(c *gc.C) {
	// Start the machine agent.
	m, _, _ := s.primeAgent(c, version.Current, state.JobHostUnits)
	a := s.newAgent(c, m)
	go func() { c.Check(a.Run(nil), gc.IsNil) }()
	defer func() { c.Check(a.Stop(), gc.IsNil) }()

	// Update the API addresses.
	updatedServers := [][]instance.HostPort{instance.AddressesWithPort(
		instance.NewAddresses("localhost"), 1234,
	)}
	err := s.BackingState.SetAPIHostPorts(updatedServers)
	c.Assert(err, gc.IsNil)

	// Wait for config to be updated.
	s.BackingState.StartSync()
	for attempt := coretesting.LongAttempt.Start(); attempt.Next(); {
		addrs, err := a.CurrentConfig().APIAddresses()
		c.Assert(err, gc.IsNil)
		if reflect.DeepEqual(addrs, []string{"localhost:1234"}) {
			return
		}
	}
	c.Fatalf("timeout while waiting for agent config to change")
}
Beispiel #3
0
func (s *APIAddressUpdaterSuite) TestAddressChange(c *gc.C) {
	setter := &apiAddressSetter{servers: make(chan [][]instance.HostPort, 1)}
	st, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits)
	worker := apiaddressupdater.NewAPIAddressUpdater(st.Machiner(), setter)
	defer func() { c.Assert(worker.Wait(), gc.IsNil) }()
	defer worker.Kill()
	s.BackingState.StartSync()
	updatedServers := [][]instance.HostPort{instance.AddressesWithPort(
		instance.NewAddresses("localhost", "127.0.0.1"),
		1234,
	)}
	// SetAPIHostPorts should be called with the initial value (empty),
	// and then the updated value.
	select {
	case <-time.After(coretesting.LongWait):
		c.Fatalf("timed out waiting for SetAPIHostPorts to be called first")
	case servers := <-setter.servers:
		c.Assert(servers, gc.HasLen, 0)
	}
	err := s.State.SetAPIHostPorts(updatedServers)
	c.Assert(err, gc.IsNil)
	s.BackingState.StartSync()
	select {
	case <-time.After(coretesting.LongWait):
		c.Fatalf("timed out waiting for SetAPIHostPorts to be called second")
	case servers := <-setter.servers:
		c.Assert(servers, gc.DeepEquals, updatedServers)
	}
}
Beispiel #4
0
func (s *APIEndpointForEnvSuite) TestAPIEndpointRefresh(c *gc.C) {
	store := newConfigStore("env-name", dummyStoreInfo)
	called := 0
	expectState := &mockAPIState{
		apiHostPorts: [][]instance.HostPort{
			instance.AddressesWithPort([]instance.Address{instance.NewAddress("0.1.2.3", instance.NetworkUnknown)}, 1234),
		},
	}
	apiOpen := func(apiInfo *api.Info, opts api.DialOpts) (juju.APIState, error) {
		c.Check(apiInfo.Tag, gc.Equals, "user-foo")
		c.Check(string(apiInfo.CACert), gc.Equals, "certificated")
		c.Check(apiInfo.Password, gc.Equals, "foopass")
		c.Check(opts, gc.DeepEquals, api.DefaultDialOpts())
		called++
		return expectState, nil
	}
	endpoint, err := juju.APIEndpointInStore("env-name", false, store, apiOpen)
	c.Assert(err, gc.IsNil)
	c.Assert(called, gc.Equals, 0)
	c.Check(endpoint.Addresses, gc.DeepEquals, []string{"foo.invalid"})
	// However, if we ask to refresh them, we'll connect to the API and get
	// the freshest set
	endpoint, err = juju.APIEndpointInStore("env-name", true, store, apiOpen)
	c.Assert(err, gc.IsNil)
	c.Check(called, gc.Equals, 1)
	// This refresh now gives us the values return by APIHostPorts
	c.Check(endpoint.Addresses, gc.DeepEquals, []string{"0.1.2.3:1234"})
}
Beispiel #5
0
// testNamespace starts a worker and ensures that
// the rsyslog config file has the expected filename,
// and the appropriate log dir is used.
func (s *RsyslogSuite) testNamespace(c *gc.C, st *api.State, tag, namespace, expectedFilename, expectedLogDir string) {
	restarted := make(chan struct{}, 2) // once for create, once for teardown
	s.PatchValue(rsyslog.RestartRsyslog, func() error {
		restarted <- struct{}{}
		return nil
	})

	err := os.MkdirAll(expectedLogDir, 0755)
	c.Assert(err, gc.IsNil)
	worker, err := rsyslog.NewRsyslogConfigWorker(st.Rsyslog(), rsyslog.RsyslogModeForwarding, tag, namespace, []string{"0.1.2.3"})
	c.Assert(err, gc.IsNil)
	defer func() { c.Assert(worker.Wait(), gc.IsNil) }()
	defer worker.Kill()

	// change the API HostPorts to trigger an rsyslog restart
	newHostPorts := instance.AddressesWithPort(instance.NewAddresses("127.0.0.1"), 6541)
	err = s.State.SetAPIHostPorts([][]instance.HostPort{newHostPorts})
	c.Assert(err, gc.IsNil)

	// Wait for rsyslog to be restarted, so we can check to see
	// what the name of the config file is.
	waitForRestart(c, restarted)

	// Ensure that ca-cert.pem gets written to the expected log dir.
	waitForFile(c, filepath.Join(expectedLogDir, "ca-cert.pem"))

	dir, err := os.Open(*rsyslog.RsyslogConfDir)
	c.Assert(err, gc.IsNil)
	names, err := dir.Readdirnames(-1)
	dir.Close()
	c.Assert(err, gc.IsNil)
	c.Assert(names, gc.HasLen, 1)
	c.Assert(names[0], gc.Equals, expectedFilename)
}
Beispiel #6
0
func parseHostPort(s string) (instance.HostPort, error) {
	addr, port, err := net.SplitHostPort(s)
	if err != nil {
		return instance.HostPort{}, err
	}
	portNum, err := strconv.Atoi(port)
	if err != nil {
		return instance.HostPort{}, fmt.Errorf("bad port number %q", port)
	}
	addrs := instance.NewAddresses(addr)
	hostPorts := instance.AddressesWithPort(addrs, portNum)
	return hostPorts[0], nil
}
Beispiel #7
0
func (m *fakeMachine) setStateHostPort(hostPort string) {
	var mongoHostPorts []instance.HostPort
	if hostPort != "" {
		host, portStr, err := net.SplitHostPort(hostPort)
		if err != nil {
			panic(err)
		}
		port, err := strconv.Atoi(portStr)
		if err != nil {
			panic(err)
		}
		mongoHostPorts = instance.AddressesWithPort(instance.NewAddresses(host), port)
		mongoHostPorts[0].NetworkScope = instance.NetworkCloudLocal
	}

	m.mutate(func(doc *machineDoc) {
		doc.mongoHostPorts = mongoHostPorts
	})
}
Beispiel #8
0
func (s *APIEndpointForEnvSuite) TestAPIEndpointNotCached(c *gc.C) {
	coretesting.WriteEnvironments(c, coretesting.MultipleEnvConfig)
	store, err := configstore.Default()
	c.Assert(err, gc.IsNil)
	ctx := coretesting.Context(c)
	env, err := environs.PrepareFromName("erewhemos", ctx, store)
	c.Assert(err, gc.IsNil)
	defer dummy.Reset()
	envtesting.UploadFakeTools(c, env.Storage())
	err = bootstrap.Bootstrap(ctx, env, environs.BootstrapParams{})
	c.Assert(err, gc.IsNil)

	// Note: if we get Bootstrap to start caching the API endpoint
	// immediately, we'll still want to have this test for compatibility.
	// We can just write blank info instead of reading and checking it is empty.
	savedInfo, err := store.ReadInfo("erewhemos")
	c.Assert(err, gc.IsNil)
	// Ensure that the data isn't cached
	c.Check(savedInfo.APIEndpoint().Addresses, gc.HasLen, 0)

	called := 0
	expectState := &mockAPIState{
		apiHostPorts: [][]instance.HostPort{
			instance.AddressesWithPort([]instance.Address{instance.NewAddress("0.1.2.3", instance.NetworkUnknown)}, 1234),
		},
	}
	apiOpen := func(apiInfo *api.Info, opts api.DialOpts) (juju.APIState, error) {
		c.Check(apiInfo.Tag, gc.Equals, "user-admin")
		c.Check(string(apiInfo.CACert), gc.Equals, coretesting.CACert)
		c.Check(apiInfo.Password, gc.Equals, coretesting.DefaultMongoPassword)
		c.Check(opts, gc.DeepEquals, api.DefaultDialOpts())
		called++
		return expectState, nil
	}
	endpoint, err := juju.APIEndpointInStore("erewhemos", false, store, apiOpen)
	c.Assert(err, gc.IsNil)
	c.Assert(called, gc.Equals, 1)
	c.Check(endpoint.Addresses, gc.DeepEquals, []string{"0.1.2.3:1234"})
}
Beispiel #9
0
func (s *NewAPIClientSuite) TestWithInfoOnly(c *gc.C) {
	store := newConfigStore("noconfig", dummyStoreInfo)

	called := 0
	expectState := &mockAPIState{
		apiHostPorts: [][]instance.HostPort{
			instance.AddressesWithPort([]instance.Address{instance.NewAddress("0.1.2.3", instance.NetworkUnknown)}, 1234),
		},
	}
	apiOpen := func(apiInfo *api.Info, opts api.DialOpts) (juju.APIState, error) {
		c.Check(apiInfo.Tag, gc.Equals, "user-foo")
		c.Check(string(apiInfo.CACert), gc.Equals, "certificated")
		c.Check(apiInfo.Password, gc.Equals, "foopass")
		c.Check(opts, gc.DeepEquals, api.DefaultDialOpts())
		called++
		return expectState, nil
	}

	// Give NewAPIFromStore a store interface that can report when the
	// config was written to, to check if the cache is updated.
	mockStore := &storageWithWriteNotify{store: store}
	st, err := juju.NewAPIFromStore("noconfig", mockStore, apiOpen)
	c.Assert(err, gc.IsNil)
	c.Assert(st, gc.Equals, expectState)
	c.Assert(called, gc.Equals, 1)
	c.Assert(mockStore.written, jc.IsTrue)
	info, err := store.ReadInfo("noconfig")
	c.Assert(err, gc.IsNil)
	c.Assert(info.APIEndpoint().Addresses, gc.DeepEquals, []string{"0.1.2.3:1234"})
	mockStore.written = false

	// If APIHostPorts haven't changed, then the store won't be updated.
	st, err = juju.NewAPIFromStore("noconfig", mockStore, apiOpen)
	c.Assert(err, gc.IsNil)
	c.Assert(st, gc.Equals, expectState)
	c.Assert(called, gc.Equals, 2)
	c.Assert(mockStore.written, jc.IsFalse)
}
Beispiel #10
0
// newRsyslogConfig creates a new instance of the RsyslogConfig.
func newRsyslogConfig(envCfg *config.Config, api *RsyslogAPI) (*apirsyslog.RsyslogConfig, error) {
	stateAddrsResult, err := api.StateAddresser.StateAddresses()
	if err != nil {
		return nil, err
	}
	port := envCfg.SyslogPort()

	var bareAddrs []string
	for _, addr := range stateAddrsResult.Result {
		hostOnly, _, err := net.SplitHostPort(addr)
		if err != nil {
			return nil, err
		}
		bareAddrs = append(bareAddrs, hostOnly)
	}
	apiAddresses := instance.NewAddresses(bareAddrs...)

	return &apirsyslog.RsyslogConfig{
		CACert:    envCfg.RsyslogCACert(),
		Port:      port,
		HostPorts: instance.AddressesWithPort(apiAddresses, port),
	}, nil
}
Beispiel #11
0
// initAPIHostPorts sets the initial API host/port addresses in state.
func initAPIHostPorts(c ConfigSetter, st *state.State, addrs []instance.Address, apiPort int) error {
	hostPorts := instance.AddressesWithPort(addrs, apiPort)
	return st.SetAPIHostPorts([][]instance.HostPort{hostPorts})
}
Beispiel #12
0
func addressesWithPort(port int, addrs ...string) []instance.HostPort {
	return instance.AddressesWithPort(instance.NewAddresses(addrs...), port)
}
Beispiel #13
0
func (m *machineShim) MongoHostPorts() []instance.HostPort {
	return instance.AddressesWithPort(m.Addresses(), m.mongoPort)
}
Beispiel #14
0
func (m *machineShim) APIHostPorts() []instance.HostPort {
	return instance.AddressesWithPort(m.Addresses(), m.apiPort)
}