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", }) }
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") }
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) } }
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"}) }
// 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) }
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 }
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 }) }
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"}) }
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) }
// 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 }
// 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}) }
func addressesWithPort(port int, addrs ...string) []instance.HostPort { return instance.AddressesWithPort(instance.NewAddresses(addrs...), port) }
func (m *machineShim) MongoHostPorts() []instance.HostPort { return instance.AddressesWithPort(m.Addresses(), m.mongoPort) }
func (m *machineShim) APIHostPorts() []instance.HostPort { return instance.AddressesWithPort(m.Addresses(), m.apiPort) }