Skip to content

Commit

Permalink
Merge 65cc218 into 04deabf
Browse files Browse the repository at this point in the history
  • Loading branch information
kozlovic committed Mar 20, 2019
2 parents 04deabf + 65cc218 commit 886ab30
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 38 deletions.
3 changes: 0 additions & 3 deletions server/gateway.go
Expand Up @@ -379,9 +379,6 @@ func (s *Server) gatewayAcceptLoop(ch chan struct{}) {
// Write resolved port back to options.
opts.Gateway.Port = l.Addr().(*net.TCPAddr).Port
}
// Keep track of actual listen port. This will be needed in case of
// config reload.
s.gatewayActualPort = opts.Gateway.Port
// Possibly override Host/Port based on Gateway.Advertise
if err := s.setGatewayInfoHostPort(info, opts); err != nil {
s.Fatalf("Error setting gateway INFO with Gateway.Advertise value of %s, err=%v", opts.Gateway.Advertise, err)
Expand Down
47 changes: 28 additions & 19 deletions server/reload.go
Expand Up @@ -28,6 +28,10 @@ import (
// startup. This should not be modified once the server has started.
var FlagSnapshot *Options

type reloadContext struct {
oldClusterPerms *RoutePermissions
}

// option is a hot-swappable configuration setting.
type option interface {
// Apply the server option.
Expand Down Expand Up @@ -511,14 +515,17 @@ func (s *Server) Reload() error {
return err
}

curOpts := s.getOpts()

// Wipe trusted keys if needed when we have an operator.
if len(s.opts.TrustedOperators) > 0 && len(s.opts.TrustedKeys) > 0 {
s.opts.TrustedKeys = nil
if len(curOpts.TrustedOperators) > 0 && len(curOpts.TrustedKeys) > 0 {
curOpts.TrustedKeys = nil
}

clientOrgPort := s.clientActualPort
clusterOrgPort := s.clusterActualPort
gatewayOrgPort := s.gatewayActualPort
clientOrgPort := curOpts.Port
clusterOrgPort := curOpts.Cluster.Port
gatewayOrgPort := curOpts.Gateway.Port

s.mu.Unlock()

// Apply flags over config file settings.
Expand All @@ -531,7 +538,7 @@ func (s *Server) Reload() error {

setBaselineOptions(newOpts)

// processOptions sets Port to 0 if set to -1 (RANDOM port)
// setBaselineOptions sets Port to 0 if set to -1 (RANDOM port)
// If that's the case, set it to the saved value when the accept loop was
// created.
if newOpts.Port == 0 {
Expand All @@ -545,7 +552,7 @@ func (s *Server) Reload() error {
newOpts.Gateway.Port = gatewayOrgPort
}

if err := s.reloadOptions(newOpts); err != nil {
if err := s.reloadOptions(curOpts, newOpts); err != nil {
return err
}
s.mu.Lock()
Expand Down Expand Up @@ -581,17 +588,22 @@ func applyBoolFlags(newOpts, flagOpts *Options) {

// reloadOptions reloads the server config with the provided options. If an
// option that doesn't support hot-swapping is changed, this returns an error.
func (s *Server) reloadOptions(newOpts *Options) error {
func (s *Server) reloadOptions(curOpts, newOpts *Options) error {
// Apply to the new options some of the options that may have been set
// that can't be configured in the config file (this can happen in
// applications starting NATS Server programmatically).
newOpts.CustomClientAuthentication = curOpts.CustomClientAuthentication
newOpts.CustomRouterAuthentication = curOpts.CustomRouterAuthentication

changed, err := s.diffOptions(newOpts)
if err != nil {
return err
}
s.mu.Lock()
// Need to save off previous cluster permissions
s.oldClusterPerms = s.opts.Cluster.Permissions
s.mu.Unlock()
// Create a context that is used to pass special info that we may need
// while applying the new options.
ctx := reloadContext{oldClusterPerms: curOpts.Cluster.Permissions}
s.setOpts(newOpts)
s.applyOptions(changed)
s.applyOptions(&ctx, changed)
return nil
}

Expand Down Expand Up @@ -730,7 +742,7 @@ func (s *Server) diffOptions(newOpts *Options) ([]option, error) {
return diffOpts, nil
}

func (s *Server) applyOptions(opts []option) {
func (s *Server) applyOptions(ctx *reloadContext, opts []option) {
var (
reloadLogging = false
reloadAuth = false
Expand All @@ -756,7 +768,7 @@ func (s *Server) applyOptions(opts []option) {
s.reloadAuthorization()
}
if reloadClusterPerms {
s.reloadClusterPermissions()
s.reloadClusterPermissions(ctx.oldClusterPerms)
}

s.Noticef("Reloaded server configuration")
Expand Down Expand Up @@ -889,17 +901,14 @@ func (s *Server) clientHasMovedToDifferentAccount(c *client) bool {
// update INFO protocol so that remote can resend their local
// subs if needed, and sending local subs matching cluster's
// import subjects.
func (s *Server) reloadClusterPermissions() {
func (s *Server) reloadClusterPermissions(oldPerms *RoutePermissions) {
s.mu.Lock()
var (
infoJSON []byte
oldPerms = s.oldClusterPerms
newPerms = s.opts.Cluster.Permissions
routes = make(map[uint64]*client, len(s.routes))
withNewProto int
)
// We can clear this now that we have captured it with oldPerms.
s.oldClusterPerms = nil
// Get all connected routes
for i, route := range s.routes {
// Count the number of routes that can understand receiving INFO updates.
Expand Down
28 changes: 28 additions & 0 deletions server/reload_test.go
Expand Up @@ -3203,6 +3203,8 @@ func TestConfigReloadNotPreventedByGateways(t *testing.T) {
}

func TestConfigReloadBoolFlags(t *testing.T) {
defer func() { FlagSnapshot = nil }()

logfile := "logtime.log"
defer os.Remove(logfile)
template := `
Expand Down Expand Up @@ -3638,3 +3640,29 @@ func TestConfigReloadMaxControlLineWithClients(t *testing.T) {
mcl, opts.MaxControlLine)
}
}

type testCustomAuth struct{}

func (ca *testCustomAuth) Check(c ClientAuthentication) bool { return true }

func TestConfigReloadIgnoreCustomAuth(t *testing.T) {
conf := createConfFile(t, []byte(`
port: -1
`))
opts := LoadConfig(conf)

ca := &testCustomAuth{}
opts.CustomClientAuthentication = ca
opts.CustomRouterAuthentication = ca

s := RunServer(opts)
defer s.Shutdown()

if err := s.Reload(); err != nil {
t.Fatalf("Error during reload: %v", err)
}

if s.getOpts().CustomClientAuthentication != ca || s.getOpts().CustomRouterAuthentication != ca {
t.Fatalf("Custom auth missing")
}
}
3 changes: 0 additions & 3 deletions server/route.go
Expand Up @@ -1418,9 +1418,6 @@ func (s *Server) routeAcceptLoop(ch chan struct{}) {
// Write resolved port back to options.
opts.Cluster.Port = l.Addr().(*net.TCPAddr).Port
}
// Keep track of actual listen port. This will be needed in case of
// config reload.
s.clusterActualPort = opts.Cluster.Port
// Check for Auth items
if opts.Cluster.Username != "" {
info.AuthRequired = true
Expand Down
13 changes: 0 additions & 13 deletions server/server.go
Expand Up @@ -143,16 +143,6 @@ type Server struct {
gatewayListener net.Listener // Accept listener
gateway *srvGateway

// These store the real client/cluster listen ports. They are
// required during config reload to reset the Options (after
// reload) to the actual listen port values.
clientActualPort int
clusterActualPort int
gatewayActualPort int

// Use during reload
oldClusterPerms *RoutePermissions

// Used by tests to check that http.Servers do
// not set any timeout.
monitoringServer *http.Server
Expand Down Expand Up @@ -1090,9 +1080,6 @@ func (s *Server) AcceptLoop(clr chan struct{}) {
// Write resolved port back to options.
opts.Port = l.Addr().(*net.TCPAddr).Port
}
// Keep track of actual listen port. This will be needed in case of
// config reload.
s.clientActualPort = opts.Port

// Now that port has been set (if it was set to RANDOM), set the
// server's info Host/Port with either values from Options or
Expand Down

0 comments on commit 886ab30

Please sign in to comment.