Added: reload server config by sending it a message

gofmt

PR feedback: test that a regular account can not reload

PR feedback: set response.Data to nil on success
This commit is contained in:
Lev Brouk
2023-07-13 15:01:24 -07:00
parent e1a00a883c
commit 1ce772c1a0
2 changed files with 87 additions and 0 deletions

View File

@@ -60,6 +60,7 @@ const (
serverDirectReqSubj = "$SYS.REQ.SERVER.%s.%s"
serverPingReqSubj = "$SYS.REQ.SERVER.PING.%s"
serverStatsPingReqSubj = "$SYS.REQ.SERVER.PING" // use $SYS.REQ.SERVER.PING.STATSZ instead
serverReloadReqSubj = "$SYS.REQ.SERVER.%s.RELOAD" // with server ID
leafNodeConnectEventSubj = "$SYS.ACCOUNT.%s.LEAFNODE.CONNECT" // for internal use only
remoteLatencyEventSubj = "$SYS.LATENCY.M2.%s"
inboxRespSubj = "$SYS._INBOX.%s.%s"
@@ -1207,6 +1208,12 @@ func (s *Server) initEventTracking() {
if _, err := s.sysSubscribeInternal(accSubsSubj, s.noInlineCallback(s.debugSubscribers)); err != nil {
s.Errorf("Error setting up internal debug service for subscribers: %v", err)
}
// Listen for requests to reload the server configuration.
subject = fmt.Sprintf(serverReloadReqSubj, s.info.ID)
if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.reloadConfig)); err != nil {
s.Errorf("Error setting up internal tracking: %v", err)
}
}
// UserInfo returns basic information to a user about bound account and user permissions.
@@ -2679,6 +2686,19 @@ func (s *Server) nsubsRequest(sub *subscription, c *client, _ *Account, subject,
s.sendInternalMsgLocked(reply, _EMPTY_, nil, nsubs)
}
// accountClaimUpdate will receive claim updates for accounts.
func (s *Server) reloadConfig(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
if !s.eventsRunning() {
return
}
optz := &EventFilterOptions{}
s.zReq(c, reply, hdr, msg, optz, optz, func() (interface{}, error) {
// Reload the server config, as requested.
return nil, s.Reload()
})
}
// Helper to grab account name for a client.
func accForClient(c *client) string {
if c.acc != nil {

View File

@@ -2535,6 +2535,73 @@ func TestServerEventsStatszSingleServer(t *testing.T) {
checkSubsPending(t, sub, 1)
}
func TestServerEventsReload(t *testing.T) {
conf := createConfFile(t, []byte(`
listen: "127.0.0.1:-1"
accounts: {
$SYS { users [{user: "admin", password: "p1d"}]}
test { users [{user: "foo", password: "bar"}]}
}
ping_interval: "100ms"
`))
opts := LoadConfig(conf)
opts.Trace = true
opts.Debug = true
opts.TraceVerbose = true
s := RunServer(opts)
defer s.Shutdown()
subject := fmt.Sprintf("$SYS.REQ.SERVER.%s.RELOAD", s.info.ID)
// Connect as a test user and make sure the reload endpoint is not
// accessible.
ncTest, _ := jsClientConnect(t, s, nats.UserInfo("foo", "bar"))
defer ncTest.Close()
testReply := ncTest.NewRespInbox()
sub, err := ncTest.SubscribeSync(testReply)
require_NoError(t, err)
err = ncTest.PublishRequest(subject, testReply, nil)
require_NoError(t, err)
_, err = sub.NextMsg(time.Second)
require_Error(t, err)
require_True(t, s.getOpts().PingInterval == 100*time.Millisecond)
// rewrite the config file with a different ping interval
err = os.WriteFile(conf, []byte(`
listen: "127.0.0.1:-1"
accounts: {
$SYS { users [{user: "admin", password: "p1d"}]}
test { users [{user: "foo", password: "bar"}]}
}
ping_interval: "200ms"
`), 0666)
require_NoError(t, err)
// Connect as a system user and make sure if there is
// subscription interest that we will receive updates.
nc, _ := jsClientConnect(t, s, nats.UserInfo("admin", "p1d"))
defer nc.Close()
// Request the server to reload and wait for the response.
// subject := fmt.Sprintf("$SYS.REQ.SERVER.%s.RELOAD", s.info.ID)
reply := nc.NewRespInbox()
sub, err = nc.SubscribeSync(reply)
require_NoError(t, err)
err = nc.PublishRequest(subject, reply, nil)
require_NoError(t, err)
msg, err := sub.NextMsg(time.Second)
require_NoError(t, err)
apiResp := ServerAPIResponse{}
err = json.Unmarshal(msg.Data, &apiResp)
require_NoError(t, err)
require_True(t, apiResp.Data.(string) == "OK")
// See that the ping interval has changed.
require_True(t, s.getOpts().PingInterval == 200*time.Millisecond)
}
func Benchmark_GetHash(b *testing.B) {
b.StopTimer()
// Get 100 random names