func (s *publishSuite) TestPublisherSetsAPIHostPortsOnce(c *gc.C) { var mock mockAPIHostPortsSetter statePublish := newPublisher(&mock) hostPorts1 := network.AddressesWithPort(network.NewAddresses("testing1.invalid", "127.0.0.1"), 1234) hostPorts2 := network.AddressesWithPort(network.NewAddresses("testing2.invalid", "127.0.0.2"), 1234) // statePublish.publishAPIServers should not update state a second time. apiServers := [][]network.HostPort{hostPorts1} for i := 0; i < 2; i++ { err := statePublish.publishAPIServers(apiServers, nil) c.Assert(err, gc.IsNil) } c.Assert(mock.calls, gc.Equals, 1) c.Assert(mock.apiHostPorts, gc.DeepEquals, apiServers) apiServers = append(apiServers, hostPorts2) for i := 0; i < 2; i++ { err := statePublish.publishAPIServers(apiServers, nil) c.Assert(err, gc.IsNil) } c.Assert(mock.calls, gc.Equals, 2) c.Assert(mock.apiHostPorts, gc.DeepEquals, apiServers) }
func (s *clientSuite) TestAPIHostPorts(c *gc.C) { server1Addresses := []network.Address{{ Value: "server-1", Type: network.HostName, Scope: network.ScopePublic, }, { Value: "10.0.0.1", Type: network.IPv4Address, Scope: network.ScopeCloudLocal, }} server2Addresses := []network.Address{{ Value: "::1", Type: network.IPv6Address, Scope: network.ScopeMachineLocal, }} stateAPIHostPorts := [][]network.HostPort{ network.AddressesWithPort(server1Addresses, 123), network.AddressesWithPort(server2Addresses, 456), } err := s.State.SetAPIHostPorts(stateAPIHostPorts) c.Assert(err, jc.ErrorIsNil) apiHostPorts, err := s.APIState.Client().APIHostPorts() c.Assert(err, jc.ErrorIsNil) c.Assert(apiHostPorts, gc.DeepEquals, stateAPIHostPorts) }
func (*suite) TestSetAPIHostPorts(c *gc.C) { conf, err := agent.NewAgentConfig(attributeParams) c.Assert(err, jc.ErrorIsNil) addrs, err := conf.APIAddresses() c.Assert(err, jc.ErrorIsNil) c.Assert(addrs, gc.DeepEquals, attributeParams.APIAddresses) // The first cloud-local address for each server is used, // else if there are none then the first public- or unknown- // scope address. // // If a server has only machine-local addresses, or none // at all, then it will be excluded. server1 := network.NewAddresses("0.1.2.3", "0.1.2.4", "zeroonetwothree") server1[0].Scope = network.ScopeCloudLocal server1[1].Scope = network.ScopeCloudLocal server1[2].Scope = network.ScopePublic server2 := network.NewAddresses("127.0.0.1") server2[0].Scope = network.ScopeMachineLocal server3 := network.NewAddresses("0.1.2.5", "zeroonetwofive") server3[0].Scope = network.ScopeUnknown server3[1].Scope = network.ScopeUnknown conf.SetAPIHostPorts([][]network.HostPort{ network.AddressesWithPort(server1, 123), network.AddressesWithPort(server2, 124), network.AddressesWithPort(server3, 125), }) addrs, err = conf.APIAddresses() c.Assert(err, jc.ErrorIsNil) c.Assert(addrs, gc.DeepEquals, []string{"0.1.2.3:123", "0.1.2.5:125"}) }
func (s *APIEndpointForEnvSuite) TestAPIEndpointNotMachineLocal(c *gc.C) { store := newConfigStore("env-name", dummyStoreInfo) called := 0 hostPorts := [][]network.HostPort{ network.AddressesWithPort([]network.Address{ network.NewAddress("1.0.0.1", network.ScopePublic), network.NewAddress("192.0.0.1", network.ScopeCloudLocal), network.NewAddress("127.0.0.1", network.ScopeMachineLocal), network.NewAddress("localhost", network.ScopeMachineLocal), }, 1234), network.AddressesWithPort([]network.Address{ network.NewAddress("1.0.0.2", network.ScopeUnknown), network.NewAddress("2002:0:0:0:0:0:100:2", network.ScopeUnknown), network.NewAddress("::1", network.ScopeMachineLocal), network.NewAddress("127.0.0.1", network.ScopeMachineLocal), network.NewAddress("localhost", network.ScopeMachineLocal), }, 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 mockedAPIState(flags mockedStateFlags) *mockAPIState { hasHostPort := flags&mockedHostPort == mockedHostPort hasEnvironTag := flags&mockedEnvironTag == mockedEnvironTag preferIPv6 := flags&mockedPreferIPv6 == mockedPreferIPv6 apiHostPorts := [][]network.HostPort{} if hasHostPort { ipv4Address := network.NewAddress("0.1.2.3", network.ScopeUnknown) ipv6Address := network.NewAddress("fc00::1", network.ScopeUnknown) if preferIPv6 { apiHostPorts = [][]network.HostPort{ network.AddressesWithPort([]network.Address{ipv6Address, ipv4Address}, 1234), } } else { apiHostPorts = [][]network.HostPort{ network.AddressesWithPort([]network.Address{ipv4Address, ipv6Address}, 1234), } } } environTag := "" if hasEnvironTag { environTag = "environment-fake-uuid" } return &mockAPIState{ apiHostPorts: apiHostPorts, environTag: environTag, } }
func (s *loginSuite) TestLoginAddrs(c *gc.C) { info, cleanup := s.setupMachineAndServer(c) defer cleanup() err := s.State.SetAPIHostPorts(nil) c.Assert(err, gc.IsNil) // Initially just the address we connect with is returned, // despite there being no APIHostPorts in state. connectedAddr, hostPorts := s.loginHostPorts(c, info) connectedAddrHost, connectedAddrPortString, err := net.SplitHostPort(connectedAddr) c.Assert(err, gc.IsNil) connectedAddrPort, err := strconv.Atoi(connectedAddrPortString) c.Assert(err, gc.IsNil) connectedAddrHostPorts := [][]network.HostPort{ []network.HostPort{{ network.NewAddress(connectedAddrHost, network.ScopeUnknown), connectedAddrPort, }}, } c.Assert(hostPorts, gc.DeepEquals, connectedAddrHostPorts) // After storing APIHostPorts in state, Login should store // all of them and the address we connected with. server1Addresses := []network.Address{{ Value: "server-1", Type: network.HostName, Scope: network.ScopePublic, }, { Value: "10.0.0.1", Type: network.IPv4Address, NetworkName: "internal", Scope: network.ScopeCloudLocal, }} server2Addresses := []network.Address{{ Value: "::1", Type: network.IPv6Address, NetworkName: "loopback", Scope: network.ScopeMachineLocal, }} stateAPIHostPorts := [][]network.HostPort{ network.AddressesWithPort(server1Addresses, 123), network.AddressesWithPort(server2Addresses, 456), } err = s.State.SetAPIHostPorts(stateAPIHostPorts) c.Assert(err, gc.IsNil) connectedAddr, hostPorts = s.loginHostPorts(c, info) // Now that we connected, we add the other stateAPIHostPorts. However, // the one we connected to comes first. stateAPIHostPorts = append(connectedAddrHostPorts, stateAPIHostPorts...) c.Assert(hostPorts, gc.DeepEquals, stateAPIHostPorts) }
// initAPIHostPorts sets the initial API host/port addresses in state. func initAPIHostPorts(c agent.ConfigSetter, st *state.State, addrs []network.Address, apiPort int) error { var hostPorts []network.HostPort // First try to select the correct address using the default space where all // API servers should be accessible on. spaceAddr, ok := network.SelectAddressBySpaces(addrs) if ok { logger.Debugf("selected %q as API address", spaceAddr.Value) hostPorts = network.AddressesWithPort([]network.Address{spaceAddr}, apiPort) } else { // Fallback to using all instead. hostPorts = network.AddressesWithPort(addrs, apiPort) } return st.SetAPIHostPorts([][]network.HostPort{hostPorts}) }
func (*suite) TestSetAPIHostPorts(c *gc.C) { conf, err := agent.NewAgentConfig(attributeParams) c.Assert(err, jc.ErrorIsNil) addrs, err := conf.APIAddresses() c.Assert(err, jc.ErrorIsNil) c.Assert(addrs, gc.DeepEquals, attributeParams.APIAddresses) // All the best candidate addresses for each server are // used. Cloud-local addresses are preferred. Otherwise, public // or unknown scope addresses are used. // // If a server has only machine-local addresses, or none // at all, then it will be excluded. server1 := network.NewAddresses("0.1.0.1", "0.1.0.2", "host.com") server1[0].Scope = network.ScopeCloudLocal server1[1].Scope = network.ScopeCloudLocal server1[2].Scope = network.ScopePublic server2 := network.NewAddresses("0.2.0.1", "0.2.0.2") server2[0].Scope = network.ScopePublic server2[1].Scope = network.ScopePublic server3 := network.NewAddresses("127.0.0.1") server3[0].Scope = network.ScopeMachineLocal server4 := network.NewAddresses("0.4.0.1", "elsewhere.net") server4[0].Scope = network.ScopeUnknown server4[1].Scope = network.ScopeUnknown conf.SetAPIHostPorts([][]network.HostPort{ network.AddressesWithPort(server1, 1111), network.AddressesWithPort(server2, 2222), network.AddressesWithPort(server3, 3333), network.AddressesWithPort(server4, 4444), }) addrs, err = conf.APIAddresses() c.Assert(err, jc.ErrorIsNil) c.Assert(addrs, gc.DeepEquals, []string{ "0.1.0.1:1111", "0.1.0.2:1111", "host.com:1111", "0.2.0.1:2222", "0.2.0.2:2222", "0.4.0.1:4444", "elsewhere.net:4444", }) }
// 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 names.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.RsyslogModeAccumulate, 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 := network.AddressesWithPort(network.NewAddresses("127.0.0.1"), 6541) err = s.State.SetAPIHostPorts([][]network.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 (s *APIAddressUpdaterSuite) TestAddressChange(c *gc.C) { setter := &apiAddressSetter{servers: make(chan [][]network.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 := [][]network.HostPort{network.AddressesWithPort( network.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) } }
// APIInfo returns an api.Info for the environment. The result is populated // with addresses and CA certificate, but no tag or password. func APIInfo(env Environ) (*api.Info, error) { instanceIds, err := env.ControllerInstances() if err != nil { return nil, err } logger.Debugf("ControllerInstances returned: %v", instanceIds) addrs, err := waitAnyInstanceAddresses(env, instanceIds) if err != nil { return nil, err } defaultSpaceAddr, ok := network.SelectAddressBySpace(addrs, network.DefaultSpace) if ok { addrs = []network.Address{defaultSpaceAddr} logger.Debugf("selected %q as API address in space %q", defaultSpaceAddr.Value, network.DefaultSpace) } else { logger.Warningf("using all API addresses (cannot pick by space %q): %+v", network.DefaultSpace, addrs) } config := env.Config() cert, hasCert := config.CACert() if !hasCert { return nil, errors.New("config has no CACert") } apiPort := config.APIPort() apiAddrs := network.HostPortsToStrings( network.AddressesWithPort(addrs, apiPort), ) uuid, uuidSet := config.UUID() if !uuidSet { return nil, errors.New("config has no UUID") } modelTag := names.NewModelTag(uuid) apiInfo := &api.Info{Addrs: apiAddrs, CACert: cert, ModelTag: modelTag} return apiInfo, nil }
// setBootstrapEndpointAddress writes the API endpoint address of the // bootstrap server into the connection information. This should only be run // once directly after Bootstrap. It assumes that there is just one instance // in the environment - the bootstrap instance. func (c *bootstrapCommand) setBootstrapEndpointAddress(environ environs.Environ) error { instances, err := allInstances(environ) if err != nil { return errors.Trace(err) } length := len(instances) if length == 0 { return errors.Errorf("found no instances, expected at least one") } if length > 1 { logger.Warningf("expected one instance, got %d", length) } bootstrapInstance := instances[0] // Don't use c.ConnectionEndpoint as it attempts to contact the state // server if no addresses are found in connection info. netAddrs, err := bootstrapInstance.Addresses() if err != nil { return errors.Annotate(err, "failed to get bootstrap instance addresses") } cfg := environ.Config() apiPort := cfg.APIPort() apiHostPorts := network.AddressesWithPort(netAddrs, apiPort) return juju.UpdateControllerAddresses(c.ClientStore(), c.controllerName, nil, apiHostPorts...) }
// mockedAPIState returns a mocked-up implementation // of api.Connection. The logical OR of the flags specifies // whether to include a fake host port and model tag // in the result. func mockedAPIState(flags mockedStateFlags) *mockAPIState { hasHostPort := flags&mockedHostPort == mockedHostPort hasModelTag := flags&mockedModelTag == mockedModelTag addr := "" apiHostPorts := [][]network.HostPort{} if hasHostPort { var apiAddrs []network.Address ipv4Address := network.NewAddress("0.1.2.3") ipv6Address := network.NewAddress("2001:db8::1") addr = net.JoinHostPort(ipv4Address.Value, "1234") apiAddrs = append(apiAddrs, ipv4Address, ipv6Address) apiHostPorts = [][]network.HostPort{ network.AddressesWithPort(apiAddrs, 1234), } } modelTag := "" if hasModelTag { modelTag = "model-df136476-12e9-11e4-8a70-b2227cce2b54" } return &mockAPIState{ apiHostPorts: apiHostPorts, modelTag: modelTag, controllerTag: testing.ControllerTag.Id(), addr: addr, } }
// APIInfo returns an api.Info for the environment. The result is populated // with addresses and CA certificate, but no tag or password. func APIInfo(env Environ) (*api.Info, error) { instanceIds, err := env.ControllerInstances() if err != nil { return nil, err } logger.Debugf("ControllerInstances returned: %v", instanceIds) addrs, err := waitAnyInstanceAddresses(env, instanceIds) if err != nil { return nil, err } config := env.Config() cert, hasCert := config.CACert() if !hasCert { return nil, errors.New("config has no CACert") } apiPort := config.APIPort() apiAddrs := network.HostPortsToStrings( network.AddressesWithPort(addrs, apiPort), ) uuid, uuidSet := config.UUID() if !uuidSet { return nil, errors.New("config has no UUID") } modelTag := names.NewModelTag(uuid) apiInfo := &api.Info{Addrs: apiAddrs, CACert: cert, ModelTag: modelTag} return apiInfo, nil }
func mockedAPIState(flags mockedStateFlags) *mockAPIState { hasHostPort := flags&mockedHostPort == mockedHostPort hasEnvironTag := flags&mockedEnvironTag == mockedEnvironTag preferIPv6 := flags&mockedPreferIPv6 == mockedPreferIPv6 addr := "" apiHostPorts := [][]network.HostPort{} if hasHostPort { var apiAddrs []network.Address ipv4Address := network.NewAddress("0.1.2.3") ipv6Address := network.NewAddress("2001:db8::1") if preferIPv6 { addr = net.JoinHostPort(ipv6Address.Value, "1234") apiAddrs = append(apiAddrs, ipv6Address, ipv4Address) } else { addr = net.JoinHostPort(ipv4Address.Value, "1234") apiAddrs = append(apiAddrs, ipv4Address, ipv6Address) } apiHostPorts = [][]network.HostPort{ network.AddressesWithPort(apiAddrs, 1234), } } environTag := "" if hasEnvironTag { environTag = "environment-df136476-12e9-11e4-8a70-b2227cce2b54" } return &mockAPIState{ apiHostPorts: apiHostPorts, environTag: environTag, addr: addr, } }
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 := [][]network.HostPort{network.AddressesWithPort( network.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 (*HostPortSuite) TestNewHostPorts(c *gc.C) { addrs := []string{"0.1.2.3", "fc00::1", "::1", "example.com"} expected := network.AddressesWithPort( network.NewAddresses(addrs...), 42, ) result := network.NewHostPorts(42, addrs...) c.Assert(result, gc.HasLen, len(addrs)) c.Assert(result, jc.DeepEquals, expected) }
func (*PortSuite) TestSortHostPorts(c *gc.C) { hps := network.AddressesWithPort( network.NewAddresses( "127.0.0.1", "localhost", "example.com", "::1", "fc00::1", "fe80::2", "172.16.0.1", "8.8.8.8", ), 1234, ) network.SortHostPorts(hps, false) c.Assert(hps, jc.DeepEquals, network.AddressesWithPort( network.NewAddresses( "localhost", "example.com", "127.0.0.1", "172.16.0.1", "8.8.8.8", "::1", "fc00::1", "fe80::2", ), 1234, )) network.SortHostPorts(hps, true) c.Assert(hps, jc.DeepEquals, network.AddressesWithPort( network.NewAddresses( "localhost", "example.com", "::1", "fc00::1", "fe80::2", "127.0.0.1", "172.16.0.1", "8.8.8.8", ), 1234, )) }
func (*PortSuite) TestAddressesWithPort(c *gc.C) { addrs := network.NewAddresses("0.1.2.3", "0.2.4.6") hps := network.AddressesWithPort(addrs, 999) c.Assert(hps, jc.DeepEquals, []network.HostPort{{ Address: network.NewAddress("0.1.2.3", network.ScopeUnknown), Port: 999, }, { Address: network.NewAddress("0.2.4.6", network.ScopeUnknown), Port: 999, }}) }
// hostPortTest returns the HostPort equivalent test to the // receiving selectTest. func (t selectTest) hostPortTest() hostPortTest { hps := network.AddressesWithPort(t.addresses, 9999) for i := range hps { hps[i].Port = i + 1 } return hostPortTest{ about: t.about, hostPorts: hps, expectedIndex: t.expectedIndex, } }
func (s *publishSuite) TestPublisherSortsHostPorts(c *gc.C) { ipV4First := network.AddressesWithPort(network.NewAddresses("testing1.invalid", "127.0.0.1", "::1"), 1234) ipV6First := network.AddressesWithPort(network.NewAddresses("testing1.invalid", "::1", "127.0.0.1"), 1234) check := func(preferIPv6 bool, publish, expect []network.HostPort) { var mock mockAPIHostPortsSetter statePublish := newPublisher(&mock, preferIPv6) for i := 0; i < 2; i++ { err := statePublish.publishAPIServers([][]network.HostPort{publish}, nil) c.Assert(err, gc.IsNil) } c.Assert(mock.calls, gc.Equals, 1) c.Assert(mock.apiHostPorts, gc.DeepEquals, [][]network.HostPort{expect}) } check(false, ipV6First, ipV4First) check(false, ipV4First, ipV4First) check(true, ipV4First, ipV6First) check(true, ipV6First, ipV6First) }
func (*HostPortSuite) TestAddressesWithPortAndHostsWithoutPort(c *gc.C) { addrs := network.NewAddresses("0.1.2.3", "0.2.4.6") hps := network.AddressesWithPort(addrs, 999) c.Assert(hps, jc.DeepEquals, []network.HostPort{{ Address: network.NewAddress("0.1.2.3"), Port: 999, }, { Address: network.NewAddress("0.2.4.6"), Port: 999, }}) c.Assert(network.HostsWithoutPort(hps), jc.DeepEquals, addrs) }
func (s *toolsSuite) TestToolsURLGetter(c *gc.C) { g := common.NewToolsURLGetter("my-uuid", mockAPIHostPortsGetter{ hostPorts: [][]network.HostPort{ network.AddressesWithPort( network.NewAddresses("0.1.2.3"), 1234, ), }, }) url, err := g.ToolsURL(version.Current) c.Assert(err, gc.IsNil) c.Assert(url, gc.Equals, "https://0.1.2.3:1234/environment/my-uuid/tools/"+version.Current.String()) }
func parseHostPort(s string) (network.HostPort, error) { addr, port, err := net.SplitHostPort(s) if err != nil { return network.HostPort{}, err } portNum, err := strconv.Atoi(port) if err != nil { return network.HostPort{}, fmt.Errorf("bad port number %q", port) } addrs := network.NewAddresses(addr) hostPorts := network.AddressesWithPort(addrs, portNum) return hostPorts[0], nil }
func (s *CacheChangedAPISuite) TestAPIEndpointNotMachineLocalOrLinkLocal(c *gc.C) { store := configstore.NewMem() info, err := store.CreateInfo("env-name") c.Assert(err, gc.IsNil) hostPorts := [][]network.HostPort{ network.AddressesWithPort([]network.Address{ network.NewAddress("1.0.0.1", network.ScopeUnknown), network.NewAddress("192.0.0.1", network.ScopeUnknown), network.NewAddress("127.0.0.1", network.ScopeUnknown), network.NewAddress("localhost", network.ScopeMachineLocal), network.NewAddress("::1", network.ScopeUnknown), network.NewAddress("fe80::1", network.ScopeUnknown), network.NewAddress("fc00::1", network.ScopeUnknown), network.NewAddress("2001:db8::1", network.ScopeUnknown), }, 1234), network.AddressesWithPort([]network.Address{ network.NewAddress("1.0.0.2", network.ScopeUnknown), network.NewAddress("2002:0:0:0:0:0:100:2", network.ScopeUnknown), network.NewAddress("::1", network.ScopeUnknown), network.NewAddress("127.0.0.1", network.ScopeUnknown), network.NewAddress("localhost", network.ScopeMachineLocal), }, 1235), } envTag := names.NewEnvironTag("fake-uuid") err = juju.CacheChangedAPIInfo(info, hostPorts, envTag.String()) c.Assert(err, gc.IsNil) endpoint := info.APIEndpoint() c.Check(endpoint.Addresses, gc.DeepEquals, []string{ "1.0.0.1:1234", "192.0.0.1:1234", "[fc00::1]:1234", "[2001:db8::1]:1234", "1.0.0.2:1235", "[2002:0:0:0:0:0:100:2]:1235", }) }
// SetBootstrapEndpointAddress writes the API endpoint address of the // bootstrap server into the connection information. This should only be run // once directly after Bootstrap. It assumes that there is just one instance // in the environment - the bootstrap instance. func (c *BootstrapCommand) SetBootstrapEndpointAddress(environ environs.Environ) error { instances, err := allInstances(environ) if err != nil { return errors.Trace(err) } length := len(instances) if length == 0 { return errors.Errorf("found no instances, expected at least one") } if length > 1 { logger.Warningf("expected one instance, got %d", length) } bootstrapInstance := instances[0] cfg := environ.Config() info, err := envcmd.ConnectionInfoForName(c.ConnectionName()) if err != nil { return errors.Annotate(err, "failed to get connection info") } // Don't use c.ConnectionEndpoint as it attempts to contact the state // server if no addresses are found in connection info. endpoint := info.APIEndpoint() netAddrs, err := bootstrapInstance.Addresses() if err != nil { return errors.Annotate(err, "failed to get bootstrap instance addresses") } apiPort := cfg.APIPort() apiHostPorts := network.AddressesWithPort(netAddrs, apiPort) addrs, hosts, addrsChanged := prepareEndpointsForCaching( info, [][]network.HostPort{apiHostPorts}, network.HostPort{}, ) if !addrsChanged { // Something's wrong we already have cached addresses? return errors.Annotate(err, "cached API endpoints unexpectedly exist") } endpoint.Addresses = addrs endpoint.Hostnames = hosts writer, err := c.ConnectionWriter() if err != nil { return errors.Annotate(err, "failed to get connection writer") } writer.SetAPIEndpoint(endpoint) err = writer.Write() if err != nil { return errors.Annotate(err, "failed to write API endpoint to connection info") } return nil }
func mockedAPIState(hasHostPort, hasEnvironTag bool) *mockAPIState { apiHostPorts := [][]network.HostPort{} if hasHostPort { address := network.NewAddress("0.1.2.3", network.ScopeUnknown) apiHostPorts = [][]network.HostPort{ network.AddressesWithPort([]network.Address{address}, 1234), } } environTag := "" if hasEnvironTag { environTag = "environment-fake-uuid" } return &mockAPIState{ apiHostPorts: apiHostPorts, environTag: environTag, } }
func (s *APIAddresserTests) TestAPIHostPorts(c *gc.C) { ipv6Addr := network.NewScopedAddress( "2001:DB8::1", network.ScopeCloudLocal, ) expectServerAddrs := [][]network.HostPort{ network.NewHostPorts(999, "0.1.2.24"), network.NewHostPorts(1234, "example.com"), network.AddressesWithPort([]network.Address{ipv6Addr}, 999), } err := s.state.SetAPIHostPorts(expectServerAddrs) c.Assert(err, jc.ErrorIsNil) serverAddrs, err := s.facade.APIHostPorts() c.Assert(err, jc.ErrorIsNil) c.Assert(serverAddrs, gc.DeepEquals, expectServerAddrs) }
// APIInfo returns an api.Info for the environment. The result is populated // with addresses and CA certificate, but no tag or password. func APIInfo(controllerUUID, modelUUID, caCert string, apiPort int, env Environ) (*api.Info, error) { instanceIds, err := env.ControllerInstances(controllerUUID) if err != nil { return nil, err } logger.Debugf("ControllerInstances returned: %v", instanceIds) addrs, err := waitAnyInstanceAddresses(env, instanceIds) if err != nil { return nil, err } apiAddrs := network.HostPortsToStrings( network.AddressesWithPort(addrs, apiPort), ) modelTag := names.NewModelTag(modelUUID) apiInfo := &api.Info{Addrs: apiAddrs, CACert: caCert, ModelTag: modelTag} return apiInfo, nil }
func (m *fakeMachine) setStateHostPort(hostPort string) { var mongoHostPorts []network.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 = network.AddressesWithPort(network.NewAddresses(host), port) mongoHostPorts[0].Scope = network.ScopeCloudLocal } m.mutate(func(doc *machineDoc) { doc.mongoHostPorts = mongoHostPorts }) }