diff --git a/server/client.go b/server/client.go index 4298b015..07bb929d 100644 --- a/server/client.go +++ b/server/client.go @@ -173,6 +173,7 @@ const ( Revocation InternalClient MsgHeaderViolation + ClusterNameConflict ) // Some flags passed to processMsgResultsEx diff --git a/server/configs/cluster.conf b/server/configs/cluster.conf index 30833c1c..6b87f853 100644 --- a/server/configs/cluster.conf +++ b/server/configs/cluster.conf @@ -14,6 +14,7 @@ pid_file: '/tmp/nats_cluster_test.pid' cluster { host: 127.0.0.1 port: 4244 + name: "abc" authorization { user: route_user diff --git a/server/configs/listen.conf b/server/configs/listen.conf index 3e0de562..00990919 100644 --- a/server/configs/listen.conf +++ b/server/configs/listen.conf @@ -7,4 +7,5 @@ https: 127.0.0.1:9443 cluster { listen: 127.0.0.1:4244 + name: "abc" } diff --git a/server/configs/reload/reload.conf b/server/configs/reload/reload.conf index 97fa2cfe..613033a7 100644 --- a/server/configs/reload/reload.conf +++ b/server/configs/reload/reload.conf @@ -32,5 +32,6 @@ authorization { cluster { listen: 127.0.0.1:-1 + name: "abc" no_advertise: true # enable on reload } diff --git a/server/configs/reload/srv_a_1.conf b/server/configs/reload/srv_a_1.conf index a3be57e8..89241b6a 100644 --- a/server/configs/reload/srv_a_1.conf +++ b/server/configs/reload/srv_a_1.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:-1 cluster { listen: 127.0.0.1:7244 + name: "abc" routes = [ nats-route://127.0.0.1:7246 diff --git a/server/configs/reload/srv_a_2.conf b/server/configs/reload/srv_a_2.conf index fd8a542c..5cd88c36 100644 --- a/server/configs/reload/srv_a_2.conf +++ b/server/configs/reload/srv_a_2.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:-1 cluster { listen: 127.0.0.1:7244 + name: "abc" routes = [ nats-route://tyler:foo@127.0.0.1:7246 # Use route credentials diff --git a/server/configs/reload/srv_a_3.conf b/server/configs/reload/srv_a_3.conf index fd7fe291..ff6d005a 100644 --- a/server/configs/reload/srv_a_3.conf +++ b/server/configs/reload/srv_a_3.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:-1 cluster { listen: 127.0.0.1:7244 + name: "abc" routes = [ nats-route://127.0.0.1:7247 # Remove srv b route and add srv c diff --git a/server/configs/reload/srv_a_4.conf b/server/configs/reload/srv_a_4.conf index 3b064c05..501a57c1 100644 --- a/server/configs/reload/srv_a_4.conf +++ b/server/configs/reload/srv_a_4.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:-1 cluster { listen: 127.0.0.1:7244 + name: "abc" } no_sys_acc: true diff --git a/server/configs/reload/srv_b_1.conf b/server/configs/reload/srv_b_1.conf index 27b6dcf6..33369e0f 100644 --- a/server/configs/reload/srv_b_1.conf +++ b/server/configs/reload/srv_b_1.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:-1 cluster { listen: 127.0.0.1:7246 + name: "abc" } no_sys_acc: true diff --git a/server/configs/reload/srv_b_2.conf b/server/configs/reload/srv_b_2.conf index 68c4a9cc..b3fbdb1c 100644 --- a/server/configs/reload/srv_b_2.conf +++ b/server/configs/reload/srv_b_2.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:-1 cluster { listen: 127.0.0.1:7246 + name: "abc" # Enable route authorization. authorization { diff --git a/server/configs/reload/srv_c_1.conf b/server/configs/reload/srv_c_1.conf index 553bdb2b..0e27c674 100644 --- a/server/configs/reload/srv_c_1.conf +++ b/server/configs/reload/srv_c_1.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:-1 cluster { listen: 127.0.0.1:7247 + name: "abc" } no_sys_acc: true diff --git a/server/configs/reload/test.conf b/server/configs/reload/test.conf index d818b6bb..adf89b92 100644 --- a/server/configs/reload/test.conf +++ b/server/configs/reload/test.conf @@ -7,5 +7,6 @@ logtime: false cluster { listen: 127.0.0.1:-1 + name: "abc" no_advertise: false } diff --git a/server/configs/seed.conf b/server/configs/seed.conf index 54b781b1..16b8f540 100644 --- a/server/configs/seed.conf +++ b/server/configs/seed.conf @@ -6,4 +6,5 @@ http: 127.0.0.1:9222 cluster { listen: 127.0.0.1:7248 + name: "abc" } diff --git a/server/configs/seed_tls.conf b/server/configs/seed_tls.conf index 206bb703..4dd45c6a 100644 --- a/server/configs/seed_tls.conf +++ b/server/configs/seed_tls.conf @@ -6,6 +6,7 @@ http: 127.0.0.1:9222 cluster { listen: 127.0.0.1:7248 + name: "abc" tls { # Route cert diff --git a/server/configs/srv_a.conf b/server/configs/srv_a.conf index a19e6e51..209bdd44 100644 --- a/server/configs/srv_a.conf +++ b/server/configs/srv_a.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:7222 cluster { listen: 127.0.0.1:7244 + name: "abc" authorization { user: ruser diff --git a/server/configs/srv_a_bcrypt.conf b/server/configs/srv_a_bcrypt.conf index 2343441a..ff1812c1 100644 --- a/server/configs/srv_a_bcrypt.conf +++ b/server/configs/srv_a_bcrypt.conf @@ -10,6 +10,7 @@ authorization { cluster { listen: 127.0.0.1:7244 + name: "abc" authorization { user: ruser diff --git a/server/configs/srv_b.conf b/server/configs/srv_b.conf index d6eddb65..65ea6413 100644 --- a/server/configs/srv_b.conf +++ b/server/configs/srv_b.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:7224 cluster { listen: 127.0.0.1:7246 + name: "abc" authorization { user: ruser diff --git a/server/configs/srv_b_bcrypt.conf b/server/configs/srv_b_bcrypt.conf index 62a9e78d..5de8a52b 100644 --- a/server/configs/srv_b_bcrypt.conf +++ b/server/configs/srv_b_bcrypt.conf @@ -10,6 +10,7 @@ authorization { cluster { listen: 127.0.0.1:7246 + name: "abc" authorization { user: ruser diff --git a/server/errors.go b/server/errors.go index 5562a9da..f9d46777 100644 --- a/server/errors.go +++ b/server/errors.go @@ -144,6 +144,12 @@ var ( // ErrMsgHeadersNotSupported signals the parser detected a message header // but they are not supported on this server. ErrMsgHeadersNotSupported = errors.New("message headers not supported") + + // ErrClusterNameConfigConflict signals that the options for cluster name in cluster and gateway are in conflict. + ErrClusterNameConfigConflict = errors.New("cluster name conflicts between cluster and gateway definitions") + + // ErrClusterNameRemoteConflict signals that a remote server has a different cluster name. + ErrClusterNameRemoteConflict = errors.New("cluster name from remote server conflicts") ) // configErr is a configuration error. diff --git a/server/events_test.go b/server/events_test.go index 4f6e0a6f..774b2f1b 100644 --- a/server/events_test.go +++ b/server/events_test.go @@ -95,6 +95,7 @@ func runTrustedCluster(t *testing.T) (*Server, *Options, *Server, *Options, nkey mr.Store(apub, jwt) optsA := DefaultOptions() + optsA.Cluster.Name = "TEST CLUSTER 22" optsA.Cluster.Host = "127.0.0.1" optsA.TrustedKeys = []string{pub} optsA.AccountResolver = mr @@ -138,6 +139,7 @@ func runTrustedGateways(t *testing.T) (*Server, *Options, *Server, *Options, nke mr.Store(apub, jwt) optsA := testDefaultOptionsForGateway("A") + optsA.Cluster.Name = "A" optsA.Cluster.Host = "127.0.0.1" optsA.TrustedKeys = []string{pub} optsA.AccountResolver = mr @@ -146,6 +148,7 @@ func runTrustedGateways(t *testing.T) (*Server, *Options, *Server, *Options, nke sa := RunServer(optsA) optsB := testGatewayOptionsFromToWithServers(t, "B", "A", sa) + optsB.Cluster.Name = "B" optsB.TrustedKeys = []string{pub} optsB.AccountResolver = mr optsB.SystemAccount = apub diff --git a/server/filestore.go b/server/filestore.go index dd821812..00e02d31 100644 --- a/server/filestore.go +++ b/server/filestore.go @@ -1568,11 +1568,12 @@ func (fs *fileStore) LoadMsg(seq uint64) (string, []byte, []byte, int64, error) return "", nil, nil, 0, err } +// State returns the current state of the stream. func (fs *fileStore) State() StreamState { fs.mu.RLock() - defer fs.mu.RUnlock() state := fs.state state.Consumers = len(fs.cfs) + fs.mu.RUnlock() return state } diff --git a/server/gateway_test.go b/server/gateway_test.go index 2066df76..a61df3dd 100644 --- a/server/gateway_test.go +++ b/server/gateway_test.go @@ -240,6 +240,7 @@ func testDefaultOptionsForGateway(name string) *Options { o := DefaultOptions() o.NoSystemAccount = true o.ServerName = name + o.Cluster.Name = name o.Gateway.Name = name o.Gateway.Host = "127.0.0.1" o.Gateway.Port = -1 @@ -1100,6 +1101,7 @@ func TestGatewayWrongDestination(t *testing.T) { cfg.resetConnAttempts() o2.Gateway.Name = "B" + o2.Cluster.Name = "B" s2 = runGatewayServer(o2) defer s2.Shutdown() @@ -2884,6 +2886,7 @@ func TestGatewayRoutedServerWithoutGatewayConfigured(t *testing.T) { waitForOutboundGateways(t, s2, 1, time.Second) o3 := DefaultOptions() + o3.Cluster.Name = "B" o3.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", s2.ClusterAddr().Port)) s3 := New(o3) defer s3.Shutdown() diff --git a/server/leafnode_test.go b/server/leafnode_test.go index 2afb1520..a2ad76fb 100644 --- a/server/leafnode_test.go +++ b/server/leafnode_test.go @@ -346,6 +346,7 @@ func TestLeafNodeBasicAuthFailover(t *testing.T) { content := ` listen: "127.0.0.1:-1" cluster { + name: "abc" listen: "127.0.0.1:-1" %s } @@ -948,6 +949,7 @@ func TestLeafNodeRemoteWrongPort(t *testing.T) { // Make sure we have all ports (client, route, gateway) and we will try // to create a leafnode to connection to each and make sure we get the error. oa.Cluster.NoAdvertise = test1.clusterAdvertise + oa.Cluster.Name = "A" oa.Cluster.Host = "127.0.0.1" oa.Cluster.Port = -1 oa.Gateway.Host = "127.0.0.1" @@ -963,6 +965,7 @@ func TestLeafNodeRemoteWrongPort(t *testing.T) { ob := DefaultOptions() ob.Cluster.NoAdvertise = test1.clusterAdvertise + ob.Cluster.Name = "A" ob.Cluster.Host = "127.0.0.1" ob.Cluster.Port = -1 ob.Routes = RoutesFromStr(fmt.Sprintf("nats://%s:%d", oa.Cluster.Host, oa.Cluster.Port)) @@ -1271,6 +1274,7 @@ func TestLeafNodeExportPermissionsNotForSpecialSubs(t *testing.T) { lo1 := DefaultOptions() lo1.Accounts = []*Account{NewAccount("SYS")} lo1.SystemAccount = "SYS" + lo1.Cluster.Name = "A" lo1.Gateway.Name = "A" lo1.Gateway.Port = -1 lo1.LeafNode.Host = "127.0.0.1" diff --git a/server/monitor_test.go b/server/monitor_test.go index 0393c084..6d0cc10b 100644 --- a/server/monitor_test.go +++ b/server/monitor_test.go @@ -1267,6 +1267,7 @@ func TestConnzWithRoutes(t *testing.T) { resetPreviousHTTPConnections() opts := DefaultMonitorOptions() opts.NoSystemAccount = true + opts.Cluster.Name = "A" opts.Cluster.Host = "127.0.0.1" opts.Cluster.Port = CLUSTER_PORT @@ -1277,6 +1278,7 @@ func TestConnzWithRoutes(t *testing.T) { Host: "127.0.0.1", Port: -1, Cluster: ClusterOpts{ + Name: "A", Host: "127.0.0.1", Port: -1, }, @@ -2003,6 +2005,7 @@ func TestMonitorRoutezRace(t *testing.T) { resetPreviousHTTPConnections() srvAOpts := DefaultMonitorOptions() srvAOpts.NoSystemAccount = true + srvAOpts.Cluster.Name = "B" srvAOpts.Cluster.Port = -1 srvA := RunServer(srvAOpts) defer srvA.Shutdown() @@ -2155,6 +2158,7 @@ func TestRoutezPermissions(t *testing.T) { resetPreviousHTTPConnections() opts := DefaultMonitorOptions() opts.NoSystemAccount = true + opts.Cluster.Name = "A" opts.Cluster.Host = "127.0.0.1" opts.Cluster.Port = -1 opts.Cluster.Permissions = &RoutePermissions{ @@ -2172,6 +2176,7 @@ func TestRoutezPermissions(t *testing.T) { opts = DefaultMonitorOptions() opts.Cluster.Host = "127.0.0.1" + opts.Cluster.Name = "A" opts.Cluster.Port = -1 routeURL, _ := url.Parse(fmt.Sprintf("nats-route://127.0.0.1:%d", s1.ClusterAddr().Port)) opts.Routes = []*url.URL{routeURL} @@ -2402,6 +2407,7 @@ func TestMonitorCluster(t *testing.T) { resetPreviousHTTPConnections() opts := DefaultMonitorOptions() opts.NoSystemAccount = true + opts.Cluster.Name = "A" opts.Cluster.Port = -1 opts.Cluster.AuthTimeout = 1 opts.Routes = RoutesFromStr("nats://127.0.0.1:1234") @@ -2447,6 +2453,8 @@ func TestMonitorClusterURLs(t *testing.T) { o2 := DefaultOptions() o2.Cluster.Host = "127.0.0.1" + o2.Cluster.Name = "A" + s2 := RunServer(o2) defer s2.Shutdown() @@ -2456,6 +2464,7 @@ func TestMonitorClusterURLs(t *testing.T) { port: -1 http: -1 cluster: { + name: "A" port: -1 routes [ %s diff --git a/server/opts.go b/server/opts.go index 2c812f3a..88a63a76 100644 --- a/server/opts.go +++ b/server/opts.go @@ -57,6 +57,7 @@ func NoErrOnUnknownFields(noError bool) { // NOTE: This structure is no longer used for monitoring endpoints // and json tags are deprecated and may be removed in the future. type ClusterOpts struct { + Name string `json:"-"` Host string `json:"addr,omitempty"` Port int `json:"cluster_port,omitempty"` Username string `json:"-"` @@ -1009,6 +1010,8 @@ func parseCluster(v interface{}, opts *Options, errors *[]error, warnings *[]err // Again, unwrap token value if line check is required. tk, mv = unwrapValue(mv, <) switch strings.ToLower(mk) { + case "name": + opts.Cluster.Name = mv.(string) case "listen": hp, err := parseListen(mv) if err != nil { @@ -3519,7 +3522,7 @@ func setBaselineOptions(opts *Options) { } } -// ConfigureOptions accepts a flag set and augment it with NATS Server +// ConfigureOptions accepts a flag set and augments it with NATS Server // specific flags. On success, an options structure is returned configured // based on the selected flags and/or configuration file. // The command line options take precedence to the ones in the configuration file. diff --git a/server/opts_test.go b/server/opts_test.go index d257b145..bb348f9b 100644 --- a/server/opts_test.go +++ b/server/opts_test.go @@ -344,6 +344,7 @@ func TestRouteFlagOverride(t *testing.T) { Host: "127.0.0.1", Port: 7222, Cluster: ClusterOpts{ + Name: "abc", Host: "127.0.0.1", Port: 7244, Username: "ruser", @@ -383,6 +384,7 @@ func TestClusterFlagsOverride(t *testing.T) { Host: "127.0.0.1", Port: 7222, Cluster: ClusterOpts{ + Name: "abc", Host: "127.0.0.1", Port: 7244, ListenStr: "nats://127.0.0.1:8224", @@ -419,6 +421,7 @@ func TestRouteFlagOverrideWithMultiple(t *testing.T) { Port: 7222, Cluster: ClusterOpts{ Host: "127.0.0.1", + Name: "abc", Port: 7244, Username: "ruser", Password: "top_secret", @@ -922,7 +925,7 @@ func TestNkeyUsersDefaultPermissionsConfig(t *testing.T) { } } ] - } + } } `)) checkPerms := func(permsDef *Permissions, permsNonDef *Permissions) { @@ -2757,3 +2760,27 @@ func TestReadOperatorAssertVersionFail(t *testing.T) { t.Fatal("expected different error got: ", err) } } + +func TestClusterNameAndGatewayNameConflict(t *testing.T) { + conf := createConfFile(t, []byte(` + listen: 127.0.0.1:-1 + cluster { + name: A + listen: 127.0.0.1:-1 + } + gateway { + name: B + listen: 127.0.0.1:-1 + } + `)) + defer os.Remove(conf) + + opts, err := ProcessConfigFile(conf) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if err := validateOptions(opts); err != ErrClusterNameConfigConflict { + t.Fatalf("Expected ErrClusterNameConfigConflict got %v", err) + } +} diff --git a/server/reload_test.go b/server/reload_test.go index 6c928494..8afe7d75 100644 --- a/server/reload_test.go +++ b/server/reload_test.go @@ -151,6 +151,7 @@ func TestConfigReloadUnsupported(t *testing.T) { MaxPingsOut: 2, WriteDeadline: 2 * time.Second, Cluster: ClusterOpts{ + Name: "abc", Host: "127.0.0.1", Port: -1, }, @@ -224,6 +225,7 @@ func TestConfigReloadInvalidConfig(t *testing.T) { MaxPingsOut: 2, WriteDeadline: 2 * time.Second, Cluster: ClusterOpts{ + Name: "abc", Host: "127.0.0.1", Port: -1, }, @@ -289,6 +291,7 @@ func TestConfigReload(t *testing.T) { MaxPingsOut: 2, WriteDeadline: 2 * time.Second, Cluster: ClusterOpts{ + Name: "abc", Host: "127.0.0.1", Port: server.ClusterAddr().Port, }, diff --git a/server/route.go b/server/route.go index 5b20501d..c2f44b66 100644 --- a/server/route.go +++ b/server/route.go @@ -89,6 +89,8 @@ type connectInfo struct { TLS bool `json:"tls_required"` Headers bool `json:"headers"` Name string `json:"name"` + Cluster string `json:"cluster"` + Dynamic bool `json:"cluster_dynamic,omitempty"` Gateway string `json:"gateway,omitempty"` } @@ -357,6 +359,7 @@ func (c *client) sendRouteConnect(tlsRequired bool) { user = userInfo.Username() pass, _ = userInfo.Password() } + s := c.srv cinfo := connectInfo{ Echo: true, Verbose: false, @@ -364,8 +367,10 @@ func (c *client) sendRouteConnect(tlsRequired bool) { User: user, Pass: pass, TLS: tlsRequired, - Name: c.srv.info.ID, - Headers: c.srv.supportsHeaders(), + Name: s.info.ID, + Headers: s.supportsHeaders(), + Cluster: s.info.Cluster, + Dynamic: s.isClusterNameDynamic(), } b, err := json.Marshal(cinfo) @@ -390,6 +395,7 @@ func (c *client) processRouteInfo(info *Info) { gacc.mu.RUnlock() supportsHeaders := c.srv.supportsHeaders() + clusterName := c.srv.ClusterName() c.mu.Lock() // Connection can be closed at any time (by auth timeout, etc). @@ -410,6 +416,20 @@ func (c *client) processRouteInfo(info *Info) { return } + // Detect if we have a mismatch of cluster names. + if info.Cluster != "" && info.Cluster != clusterName { + c.mu.Unlock() + // If we are dynamic we may update our cluster name. + if s.isClusterNameDynamic() && strings.Compare(clusterName, info.Cluster) < 0 { + s.setClusterName(info.Cluster) + s.removeAllRoutesExcept(c) + c.mu.Lock() + } else { + c.closeConnection(ClusterNameConflict) + return + } + } + // If this is an async INFO from an existing route... if c.flags.isSet(infoReceived) { remoteID := c.route.remoteID @@ -1489,6 +1509,11 @@ func (s *Server) routeAcceptLoop(ch chan struct{}) { port = 0 } + s.Noticef("Cluster name is %s", s.ClusterName()) + if s.isClusterNameDynamic() { + s.Warnf("Cluster name was dynamically generated, consider setting one") + } + hp := net.JoinHostPort(opts.Cluster.Host, strconv.Itoa(port)) l, e := net.Listen("tcp", hp) if e != nil { @@ -1524,6 +1549,7 @@ func (s *Server) routeAcceptLoop(ch chan struct{}) { Proto: proto, GatewayURL: s.getGatewayURL(), Headers: s.supportsHeaders(), + Cluster: s.info.Cluster, } // Set this if only if advertise is not disabled if !opts.Cluster.NoAdvertise { @@ -1615,8 +1641,8 @@ func (s *Server) setRouteInfoHostPortAndIP() error { func (s *Server) StartRouting(clientListenReady chan struct{}) { defer s.grWG.Done() - // Wait for the client listen port to be opened, and - // the possible ephemeral port to be selected. + // Wait for the client and and leafnode listen ports to be opened, + // and the possible ephemeral ports to be selected. <-clientListenReady // Spin up the accept loop @@ -1731,6 +1757,7 @@ func (c *client) processRouteConnect(srv *Server, arg []byte, lang string) error } // Unmarshal as a route connect protocol proto := &connectInfo{} + if err := json.Unmarshal(arg, proto); err != nil { return err } @@ -1748,6 +1775,32 @@ func (c *client) processRouteConnect(srv *Server, arg []byte, lang string) error perms = srv.getOpts().Cluster.Permissions } + clusterName := srv.ClusterName() + + // If we have a cluster name set, make sure it matches ours. + if proto.Cluster != clusterName { + shouldReject := true + // If we have a dynamic name we will do additional checks. + if srv.isClusterNameDynamic() { + if !proto.Dynamic || strings.Compare(clusterName, proto.Cluster) < 0 { + // We will take on their name since theirs is configured or higher then ours. + srv.setClusterName(proto.Cluster) + if !proto.Dynamic { + srv.getOpts().Cluster.Name = proto.Cluster + } + srv.removeAllRoutesExcept(c) + shouldReject = false + } + } + if shouldReject { + errTxt := fmt.Sprintf("Rejecting connection, cluster name %q does not match %q", proto.Cluster, srv.info.Cluster) + c.Errorf(errTxt) + c.sendErr(errTxt) + c.closeConnection(ClusterNameConflict) + return ErrClusterNameRemoteConflict + } + } + supportsHeaders := c.srv.supportsHeaders() // Grab connection name of remote route. @@ -1759,6 +1812,22 @@ func (c *client) processRouteConnect(srv *Server, arg []byte, lang string) error return nil } +// Called when we update our cluster name during negotiations with remotes. +func (s *Server) removeAllRoutesExcept(c *client) { + s.mu.Lock() + routes := make([]*client, 0, len(s.routes)) + for _, r := range s.routes { + if r != c { + routes = append(routes, r) + } + } + s.mu.Unlock() + + for _, r := range routes { + r.closeConnection(ClusterNameConflict) + } +} + func (s *Server) removeRoute(c *client) { var rID string var lnURL string diff --git a/server/routes_test.go b/server/routes_test.go index 5363362a..d7b7cc06 100644 --- a/server/routes_test.go +++ b/server/routes_test.go @@ -70,6 +70,7 @@ func TestRouteConfig(t *testing.T) { Password: "porkchop", AuthTimeout: 1.0, Cluster: ClusterOpts{ + Name: "abc", Host: "127.0.0.1", Port: 4244, Username: "route_user", @@ -1204,6 +1205,7 @@ func TestRouteRTT(t *testing.T) { func TestRouteCloseTLSConnection(t *testing.T) { opts := DefaultOptions() opts.DisableShortFirstPing = true + opts.Cluster.Name = "A" opts.Cluster.Host = "127.0.0.1" opts.Cluster.Port = -1 opts.Cluster.TLSTimeout = 100 @@ -1234,7 +1236,7 @@ func TestRouteCloseTLSConnection(t *testing.T) { if err := tlsConn.Handshake(); err != nil { t.Fatalf("Unexpected error during handshake: %v", err) } - connectOp := []byte("CONNECT {\"name\":\"route\",\"verbose\":false,\"pedantic\":false,\"tls_required\":true}\r\n") + connectOp := []byte("CONNECT {\"name\":\"route\",\"verbose\":false,\"pedantic\":false,\"tls_required\":true,\"cluster\":\"A\"}\r\n") if _, err := tlsConn.Write(connectOp); err != nil { t.Fatalf("Unexpected error writing CONNECT: %v", err) } diff --git a/server/server.go b/server/server.go index d35b6858..c7ff96b8 100644 --- a/server/server.go +++ b/server/server.go @@ -276,6 +276,7 @@ func NewServer(opts *Options) (*Server, error) { MaxPayload: opts.MaxPayload, JetStream: opts.JetStream, Headers: !opts.NoHeaderSupport, + Cluster: opts.Cluster.Name, } if tlsReq && !info.TLSRequired { @@ -322,8 +323,9 @@ func NewServer(opts *Options) (*Server, error) { return nil, err } - if s.gateway.enabled { - s.info.Cluster = s.getGatewayName() + // If we have a cluster definition but do not have a cluster name, create one. + if opts.Cluster.Port != 0 && opts.Cluster.Name == "" { + s.info.Cluster = nuid.Next() } // This is normally done in the AcceptLoop, once the @@ -414,6 +416,28 @@ func NewServer(opts *Options) (*Server, error) { return s, nil } +// clusterName returns our cluster name which could be dynamic. +func (s *Server) ClusterName() string { + s.mu.Lock() + cn := s.info.Cluster + s.mu.Unlock() + return cn +} + +// setClusterName will update the cluster name for this server. +func (s *Server) setClusterName(name string) { + s.mu.Lock() + s.info.Cluster = name + s.routeInfo.Cluster = name + s.mu.Unlock() + s.Noticef("Cluster name updated to %s", name) +} + +// Return whether the cluster name is dynamic. +func (s *Server) isClusterNameDynamic() bool { + return s.getOpts().Cluster.Name == "" +} + // ClientURL returns the URL used to connect clients. Helpful in testing // when we designate a random client port (-1). func (s *Server) ClientURL() string { @@ -426,6 +450,18 @@ func (s *Server) ClientURL() string { return fmt.Sprintf("%s%s:%d", scheme, opts.Host, opts.Port) } +func validateClusterName(o *Options) error { + // Check that cluster name if defined matches any gateway name. + if o.Gateway.Name != "" && o.Gateway.Name != o.Cluster.Name { + if o.Cluster.Name != "" { + return ErrClusterNameConfigConflict + } + // Set this here so we do not consider it dynamic. + o.Cluster.Name = o.Gateway.Name + } + return nil +} + func validateOptions(o *Options) error { if o.LameDuckDuration > 0 && o.LameDuckGracePeriod >= o.LameDuckDuration { return fmt.Errorf("lame duck grace period (%v) should be strictly lower than lame duck duration (%v)", @@ -449,6 +485,11 @@ func validateOptions(o *Options) error { if err := validateGatewayOptions(o); err != nil { return err } + // Check that cluster name if defined matches any gateway name. + if err := validateClusterName(o); err != nil { + return err + } + // Finally check websocket options. return validateWebsocketOptions(o) } diff --git a/server/server_test.go b/server/server_test.go index 0bd1f364..ed231886 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -58,7 +58,7 @@ func DefaultOptions() *Options { Host: "127.0.0.1", Port: -1, HTTPPort: -1, - Cluster: ClusterOpts{Port: -1}, + Cluster: ClusterOpts{Port: -1, Name: "abc"}, NoLog: true, NoSigs: true, Debug: true, @@ -900,6 +900,7 @@ func TestLameDuckMode(t *testing.T) { func TestLameDuckModeInfo(t *testing.T) { optsA := testWSOptions() + optsA.Cluster.Name = "abc" optsA.Cluster.Host = "127.0.0.1" optsA.Cluster.Port = -1 // Ensure that initial delay is set very high so that we can @@ -947,6 +948,7 @@ func TestLameDuckModeInfo(t *testing.T) { client.ReadString('\n') optsB := testWSOptions() + optsB.Cluster.Name = "abc" optsB.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port)) srvB := RunServer(optsB) defer srvB.Shutdown() @@ -974,6 +976,7 @@ func TestLameDuckModeInfo(t *testing.T) { optsC := testWSOptions() testSetLDMGracePeriod(optsA, 5*time.Second) + optsC.Cluster.Name = "abc" optsC.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port)) srvC := RunServer(optsC) defer srvC.Shutdown() @@ -986,6 +989,7 @@ func TestLameDuckModeInfo(t *testing.T) { checkConnectURLs(expected) optsD := testWSOptions() + optsD.Cluster.Name = "abc" optsD.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", srvA.ClusterAddr().Port)) srvD := RunServer(optsD) defer srvD.Shutdown() @@ -1341,6 +1345,7 @@ func TestInsecureSkipVerifyWarning(t *testing.T) { } o := DefaultOptions() + o.Cluster.Name = "A" o.Cluster.Port = -1 o.Cluster.TLSConfig = config.Clone() checkWarnReported(t, o, clusterTLSInsecureWarning) @@ -1516,6 +1521,7 @@ func TestConnectErrorReports(t *testing.T) { // Now try with gateways opts.LeafNode.Remotes = nil + opts.Cluster.Name = "A" opts.Gateway.Name = "A" opts.Gateway.Port = -1 opts.Gateway.Gateways = []*RemoteGatewayOpts{ @@ -1695,11 +1701,13 @@ func TestReconnectErrorReports(t *testing.T) { // Now try with gateways csOpts.LeafNode.Port = 0 + csOpts.Cluster.Name = "B" csOpts.Gateway.Name = "B" csOpts.Gateway.Port = -1 cs = RunServer(csOpts) opts.LeafNode.Remotes = nil + opts.Cluster.Name = "A" opts.Gateway.Name = "A" opts.Gateway.Port = -1 remoteGWPort := cs.GatewayAddr().Port diff --git a/test/cluster_test.go b/test/cluster_test.go index a2e01f12..1a0dd7b8 100644 --- a/test/cluster_test.go +++ b/test/cluster_test.go @@ -1,4 +1,4 @@ -// Copyright 2013-2019 The NATS Authors +// Copyright 2013-2020 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,7 +16,10 @@ package test import ( "errors" "fmt" + "math/rand" + "os" "runtime" + "strings" "testing" "time" @@ -515,3 +518,140 @@ func TestAutoUnsubscribePropagationOnClientDisconnect(t *testing.T) { t.Fatalf("%v", err) } } + +func TestClusterNameOption(t *testing.T) { + conf := createConfFile(t, []byte(` + listen: 127.0.0.1:-1 + cluster { + name: MyCluster + listen: 127.0.0.1:-1 + } + `)) + defer os.Remove(conf) + + s, opts := RunServerWithConfig(conf) + defer s.Shutdown() + + c := createClientConn(t, opts.Host, opts.Port) + defer c.Close() + + si := checkInfoMsg(t, c) + if si.Cluster != "MyCluster" { + t.Fatalf("Expected a cluster name of %q, got %q", "MyCluster", si.Cluster) + } +} + +func TestEphemeralClusterName(t *testing.T) { + conf := createConfFile(t, []byte(` + listen: 127.0.0.1:-1 + cluster { + listen: 127.0.0.1:-1 + } + `)) + defer os.Remove(conf) + + s, opts := RunServerWithConfig(conf) + defer s.Shutdown() + + c := createClientConn(t, opts.Host, opts.Port) + defer c.Close() + + si := checkInfoMsg(t, c) + if si.Cluster == "" { + t.Fatalf("Expected an ephemeral cluster name to be set") + } +} + +type captureErrLogger struct { + dummyLogger + ch chan string +} + +func (c *captureErrLogger) Errorf(format string, v ...interface{}) { + msg := fmt.Sprintf(format, v...) + select { + case c.ch <- msg: + default: + } +} + +func TestClusterNameConflictsDropRoutes(t *testing.T) { + ll := &captureErrLogger{ch: make(chan string, 4)} + + conf := createConfFile(t, []byte(` + listen: 127.0.0.1:-1 + cluster { + name: MyCluster33 + listen: 127.0.0.1:5244 + } + `)) + defer os.Remove(conf) + + s1, _ := RunServerWithConfig(conf) + defer s1.Shutdown() + s1.SetLogger(ll, false, false) + + conf2 := createConfFile(t, []byte(` + listen: 127.0.0.1:-1 + cluster { + name: MyCluster22 + listen: 127.0.0.1:-1 + routes = [nats-route://127.0.0.1:5244] + } + `)) + defer os.Remove(conf2) + + s2, _ := RunServerWithConfig(conf2) + defer s2.Shutdown() + s2.SetLogger(ll, false, false) + + select { + case msg := <-ll.ch: + if !strings.Contains(msg, "Rejecting connection") || !strings.Contains(msg, "does not match") { + t.Fatalf("Got bad error about cluster name mismatch") + } + case <-time.After(time.Second): + t.Fatalf("Expected an error, timed out") + } +} + +func TestClusterNameDynamicNegotiation(t *testing.T) { + conf := createConfFile(t, []byte(` + listen: 127.0.0.1:-1 + cluster {listen: 127.0.0.1:5244} + `)) + defer os.Remove(conf) + + seed, _ := RunServerWithConfig(conf) + defer seed.Shutdown() + + oconf := createConfFile(t, []byte(` + listen: 127.0.0.1:-1 + cluster { + listen: 127.0.0.1:-1 + routes = [nats-route://127.0.0.1:5244] + } + `)) + defer os.Remove(oconf) + + // Create a random number of additional servers, up to 20. + numServers := rand.Intn(20) + 1 + servers := make([]*server.Server, 0, numServers+1) + servers = append(servers, seed) + + for i := 0; i < numServers; i++ { + s, _ := RunServerWithConfig(oconf) + defer s.Shutdown() + servers = append(servers, s) + } + + // If this passes we should have all the same name. + checkClusterFormed(t, servers...) + + clusterName := seed.ClusterName() + for _, s := range servers { + if s.ClusterName() != clusterName { + t.Fatalf("Expected the cluster names to all be the same as %q, got %q", clusterName, s.ClusterName()) + } + } +} diff --git a/test/cluster_tls_test.go b/test/cluster_tls_test.go index f9788ad2..b19c46ee 100644 --- a/test/cluster_tls_test.go +++ b/test/cluster_tls_test.go @@ -101,6 +101,7 @@ func TestClusterTLSInsecure(t *testing.T) { confA := createConfFile(t, []byte(` port: -1 cluster { + name: "xyz" listen: "127.0.0.1:-1" tls { cert_file: "./configs/certs/server-noip.pem" @@ -119,6 +120,7 @@ func TestClusterTLSInsecure(t *testing.T) { bConfigTemplate := ` port: -1 cluster { + name: "xyz" listen: "127.0.0.1:-1" tls { cert_file: "./configs/certs/server-noip.pem" diff --git a/test/configs/auth_seed.conf b/test/configs/auth_seed.conf index a75dfc0a..893eb716 100644 --- a/test/configs/auth_seed.conf +++ b/test/configs/auth_seed.conf @@ -6,6 +6,7 @@ http: 8222 cluster { listen: 127.0.0.1:4248 + name: xyz authorization { user: ruser diff --git a/test/configs/cluster.conf b/test/configs/cluster.conf index a96167af..5894553a 100644 --- a/test/configs/cluster.conf +++ b/test/configs/cluster.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:5242 cluster { listen: 127.0.0.1:5244 + name: xyz authorization { user: route_user diff --git a/test/configs/new_cluster.conf b/test/configs/new_cluster.conf index 817695a5..166b80d7 100644 --- a/test/configs/new_cluster.conf +++ b/test/configs/new_cluster.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:5343 cluster { listen: 127.0.0.1:5344 + name: xyz # Routes are actively solicited and connected to from this server. # Other servers can connect to us if they supply the correct credentials diff --git a/test/configs/seed.conf b/test/configs/seed.conf index cc29c8bc..13f6462a 100644 --- a/test/configs/seed.conf +++ b/test/configs/seed.conf @@ -6,6 +6,7 @@ http: 8222 cluster { listen: 127.0.0.1:4248 + name: xyz } no_sys_acc: true diff --git a/test/configs/srv_a.conf b/test/configs/srv_a.conf index 9bf29532..13a5a77b 100644 --- a/test/configs/srv_a.conf +++ b/test/configs/srv_a.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:5222 cluster { listen: 127.0.0.1:5244 + name: xyz authorization { user: ruser diff --git a/test/configs/srv_a_leaf.conf b/test/configs/srv_a_leaf.conf index 4a8f6c6d..95a2d97f 100644 --- a/test/configs/srv_a_leaf.conf +++ b/test/configs/srv_a_leaf.conf @@ -8,6 +8,7 @@ leafnodes { cluster { listen: 127.0.0.1:5244 + name: xyz authorization { user: ruser diff --git a/test/configs/srv_a_perms.conf b/test/configs/srv_a_perms.conf index 08974fa4..96883c34 100644 --- a/test/configs/srv_a_perms.conf +++ b/test/configs/srv_a_perms.conf @@ -5,6 +5,7 @@ http: 127.0.0.1:5223 cluster { listen: 127.0.0.1:5244 + name: xyz authorization { user: ruser diff --git a/test/configs/srv_a_tls.conf b/test/configs/srv_a_tls.conf index 6a920251..735940df 100644 --- a/test/configs/srv_a_tls.conf +++ b/test/configs/srv_a_tls.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:5222 cluster { listen: 127.0.0.1:5244 + name: xyz tls { # Route cert diff --git a/test/configs/srv_b.conf b/test/configs/srv_b.conf index 5ad067c3..32d09f3a 100644 --- a/test/configs/srv_b.conf +++ b/test/configs/srv_b.conf @@ -5,6 +5,7 @@ http: 127.0.0.1:5225 cluster { listen: 127.0.0.1:5246 + name: xyz authorization { user: ruser diff --git a/test/configs/srv_b_tls.conf b/test/configs/srv_b_tls.conf index 61e2784c..1047b999 100644 --- a/test/configs/srv_b_tls.conf +++ b/test/configs/srv_b_tls.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:5224 cluster { listen: 127.0.0.1:5246 + name: xyz tls { # Route cert diff --git a/test/configs/srv_c.conf b/test/configs/srv_c.conf index b3b8fe5a..31def469 100644 --- a/test/configs/srv_c.conf +++ b/test/configs/srv_c.conf @@ -4,6 +4,7 @@ listen: 127.0.0.1:5226 cluster { listen: 127.0.0.1:5248 + name: xyz authorization { user: ruser diff --git a/test/leafnode_test.go b/test/leafnode_test.go index 30bee447..b19fb010 100644 --- a/test/leafnode_test.go +++ b/test/leafnode_test.go @@ -1633,6 +1633,7 @@ func TestLeadNodeExportImportComplexSetup(t *testing.T) { resolver = MEMORY cluster { port: -1 + name: xyz } leafnodes { listen: "127.0.0.1:-1" @@ -1649,6 +1650,7 @@ func TestLeadNodeExportImportComplexSetup(t *testing.T) { resolver = MEMORY cluster { port: -1 + name: xyz routes: ["nats://%s:%d"] } leafnodes { @@ -1811,6 +1813,7 @@ func TestLeafNodeInfoURLs(t *testing.T) { } { t.Run(test.name, func(t *testing.T) { opts := testDefaultOptionsForLeafNodes() + opts.Cluster.Name = "A" opts.Cluster.Port = -1 opts.LeafNode.Host = "127.0.0.1" if test.useAdvertise { @@ -1837,6 +1840,7 @@ func TestLeafNodeInfoURLs(t *testing.T) { lc.Close() opts2 := testDefaultOptionsForLeafNodes() + opts2.Cluster.Name = "A" opts2.Cluster.Port = -1 opts2.Routes = server.RoutesFromStr(fmt.Sprintf("nats://%s:%d", opts.Cluster.Host, opts.Cluster.Port)) opts2.LeafNode.Host = "127.0.0.1" @@ -2022,11 +2026,13 @@ func TestLeafNodeAdvertise(t *testing.T) { o2 := testDefaultOptionsForLeafNodes() o2.LeafNode.Advertise = fmt.Sprintf("127.0.0.1:%d", port) + o2.Cluster.Name = "A" o2.Cluster.Port = -1 s2 := RunServer(o2) defer s2.Shutdown() o1 := testDefaultOptionsForLeafNodes() + o1.Cluster.Name = "A" o1.Cluster.Port = -1 o1.Routes = server.RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", o2.Cluster.Port)) s1 := RunServer(o1) @@ -2180,6 +2186,7 @@ func TestLeafNodeConnectionLimitsCluster(t *testing.T) { resolver = MEMORY cluster { port: -1 + name: xyz } leafnodes { listen: "127.0.0.1:-1" @@ -2200,6 +2207,7 @@ func TestLeafNodeConnectionLimitsCluster(t *testing.T) { resolver = MEMORY cluster { port: -1 + name: xyz routes: ["nats://%s:%d"] } leafnodes { @@ -2358,9 +2366,10 @@ func TestLeafNodeSwitchGatewayToInterestModeOnly(t *testing.T) { // route connections to simulate. func TestLeafNodeResetsMSGProto(t *testing.T) { opts := testDefaultOptionsForLeafNodes() + opts.Cluster.Name = "xyz" opts.Cluster.Host = opts.Host opts.Cluster.Port = -1 - opts.Gateway.Name = "lproto" + opts.Gateway.Name = "xyz" opts.Gateway.Host = opts.Host opts.Gateway.Port = -1 opts.Accounts = []*server.Account{server.NewAccount("$SYS")} @@ -2381,7 +2390,7 @@ func TestLeafNodeResetsMSGProto(t *testing.T) { gw := createGatewayConn(t, opts.Gateway.Host, opts.Gateway.Port) defer gw.Close() - gwSend, gwExpect := setupGatewayConn(t, gw, "A", "lproto") + gwSend, gwExpect := setupGatewayConn(t, gw, "A", "xyz") gwSend("PING\r\n") gwExpect(pongRe) @@ -2964,6 +2973,7 @@ func runSolicitLeafCluster(t *testing.T, clusterName string, d1, d2 *cluster) *c rurl, _ := url.Parse(surl) o.LeafNode.Remotes = []*server.RemoteLeafOpts{{URLs: []*url.URL{rurl}}} o.LeafNode.ReconnectInterval = 100 * time.Millisecond + o.Cluster.Name = clusterName o.Cluster.Host = o.Host o.Cluster.Port = -1 s := RunServer(&o) @@ -2989,6 +2999,7 @@ func runSolicitLeafCluster(t *testing.T, clusterName string, d1, d2 *cluster) *c rurl, _ = url.Parse(surl) o2.LeafNode.Remotes = []*server.RemoteLeafOpts{{URLs: []*url.URL{rurl}}} o2.LeafNode.ReconnectInterval = 100 * time.Millisecond + o2.Cluster.Name = clusterName o2.Cluster.Host = o.Host o2.Cluster.Port = -1 o2.Routes = []*url.URL{curl} @@ -3107,6 +3118,7 @@ func TestLeafNodeCycleWithSolicited(t *testing.T) { func TestLeafNodeNoRaceGeneratingNonce(t *testing.T) { opts := testDefaultOptionsForLeafNodes() opts.Cluster.Port = -1 + opts.Cluster.Name = "xyz" s := RunServer(opts) defer s.Shutdown() @@ -3217,6 +3229,7 @@ func TestClusterTLSMixedIPAndDNS(t *testing.T) { } cluster { listen: "127.0.0.1:-1" + name: xyz } `)) srvA, optsA := RunServerWithConfig(confA) @@ -3235,6 +3248,7 @@ func TestClusterTLSMixedIPAndDNS(t *testing.T) { } cluster { listen: "127.0.0.1:-1" + name: xyz routes [ "nats://%s:%d" ] diff --git a/test/monitor_test.go b/test/monitor_test.go index 9007aa99..d103b68c 100644 --- a/test/monitor_test.go +++ b/test/monitor_test.go @@ -51,7 +51,7 @@ func runMonitorServerClusteredPair(t *testing.T) (*server.Server, *server.Server opts.Port = CLIENT_PORT opts.HTTPPort = MONITOR_PORT opts.HTTPHost = "127.0.0.1" - opts.Cluster = server.ClusterOpts{Host: "127.0.0.1", Port: 10223} + opts.Cluster = server.ClusterOpts{Name: "M", Host: "127.0.0.1", Port: 10223} opts.Routes = server.RoutesFromStr("nats-route://127.0.0.1:10222") opts.NoSystemAccount = true @@ -61,7 +61,7 @@ func runMonitorServerClusteredPair(t *testing.T) (*server.Server, *server.Server opts2.Port = CLIENT_PORT + 1 opts2.HTTPPort = MONITOR_PORT + 1 opts2.HTTPHost = "127.0.0.1" - opts2.Cluster = server.ClusterOpts{Host: "127.0.0.1", Port: 10222} + opts2.Cluster = server.ClusterOpts{Name: "M", Host: "127.0.0.1", Port: 10222} opts2.Routes = server.RoutesFromStr("nats-route://127.0.0.1:10223") opts2.NoSystemAccount = true diff --git a/test/operator_test.go b/test/operator_test.go index 47d549d3..2ee585c3 100644 --- a/test/operator_test.go +++ b/test/operator_test.go @@ -333,6 +333,7 @@ func TestReloadDoesNotWipeAccountsWithOperatorMode(t *testing.T) { cf := ` listen: 127.0.0.1:-1 cluster { + name: "A" listen: 127.0.0.1:-1 authorization { timeout: 2.2 @@ -456,6 +457,7 @@ func TestReloadDoesUpdateAccountsWithMemoryResolver(t *testing.T) { cf := ` listen: 127.0.0.1:-1 cluster { + name: "A" listen: 127.0.0.1:-1 authorization { timeout: 2.2 @@ -547,6 +549,7 @@ func TestReloadFailsWithBadAccountsWithMemoryResolver(t *testing.T) { cf := ` listen: 127.0.0.1:-1 cluster { + name: "A" listen: 127.0.0.1:-1 authorization { timeout: 2.2 @@ -610,6 +613,7 @@ func TestConnsRequestDoesNotLoadAccountCheckingConnLimits(t *testing.T) { cf := ` listen: 127.0.0.1:-1 cluster { + name: "A" listen: 127.0.0.1:-1 authorization { timeout: 2.2 diff --git a/test/opts_test.go b/test/opts_test.go index 0275989e..ae7f69e0 100644 --- a/test/opts_test.go +++ b/test/opts_test.go @@ -13,7 +13,9 @@ package test -import "testing" +import ( + "testing" +) func TestServerConfig(t *testing.T) { srv, opts := RunServerWithConfig("./configs/override.conf") diff --git a/test/routes_test.go b/test/routes_test.go index a40cdb14..b4d8816c 100644 --- a/test/routes_test.go +++ b/test/routes_test.go @@ -603,6 +603,7 @@ func TestRouteSendAsyncINFOToClients(t *testing.T) { sendRouteINFO := func(routeSend sendFun, routeExpect expectFun, urls []string) { routeInfo := server.Info{} routeInfo.ID = routeID + routeInfo.Cluster = "xyz" routeInfo.Host = "127.0.0.1" routeInfo.Port = 5222 routeInfo.ClientConnectURLs = urls @@ -1122,6 +1123,7 @@ func TestRoutesOnlyImportOrExport(t *testing.T) { cf := createConfFile(t, []byte(fmt.Sprintf(` port: -1 cluster { + name: "Z" port: -1 authorization { user: ivan diff --git a/test/service_latency_test.go b/test/service_latency_test.go index e19917e3..831056be 100644 --- a/test/service_latency_test.go +++ b/test/service_latency_test.go @@ -719,6 +719,7 @@ func TestServiceLatencyWithJWT(t *testing.T) { cf := ` listen: 127.0.0.1:-1 cluster { + name: "A" listen: 127.0.0.1:-1 authorization { timeout: 2.2 diff --git a/test/test.go b/test/test.go index 2f3d4ed0..81aedf6d 100644 --- a/test/test.go +++ b/test/test.go @@ -216,10 +216,10 @@ func doDefaultConnect(t tLogger, c net.Conn) { doConnect(t, c, false, false, false) } -const connectProto = "CONNECT {\"verbose\":false,\"user\":\"%s\",\"pass\":\"%s\",\"name\":\"%s\"}\r\n" +const routeConnectProto = "CONNECT {\"verbose\":false,\"user\":\"%s\",\"pass\":\"%s\",\"name\":\"%s\",\"cluster\":\"xyz\"}\r\n" func doRouteAuthConnect(t tLogger, c net.Conn, user, pass, id string) { - cs := fmt.Sprintf(connectProto, user, pass, id) + cs := fmt.Sprintf(routeConnectProto, user, pass, id) sendProto(t, c, cs) } diff --git a/test/tls_test.go b/test/tls_test.go index b5649198..8a470e36 100644 --- a/test/tls_test.go +++ b/test/tls_test.go @@ -553,6 +553,7 @@ func TestTLSRoutesCertificateCNBasedAuth(t *testing.T) { optsA.Host = "127.0.0.1" optsA.Port = 9335 + optsA.Cluster.Name = "xyz" optsA.Cluster.Host = optsA.Host optsA.Cluster.Port = 9935 optsA.Routes = server.RoutesFromStr(routeURLs) @@ -562,6 +563,7 @@ func TestTLSRoutesCertificateCNBasedAuth(t *testing.T) { optsB.Host = "127.0.0.1" optsB.Port = 9336 + optsB.Cluster.Name = "xyz" optsB.Cluster.Host = optsB.Host optsB.Cluster.Port = 9936 optsB.Routes = server.RoutesFromStr(routeURLs) @@ -571,6 +573,7 @@ func TestTLSRoutesCertificateCNBasedAuth(t *testing.T) { optsC.Host = "127.0.0.1" optsC.Port = 9337 + optsC.Cluster.Name = "xyz" optsC.Cluster.Host = optsC.Host optsC.Cluster.Port = 9937 optsC.Routes = server.RoutesFromStr(routeURLs)