77 "fmt"
88 "net/http"
99 "slices"
10+ "strings"
1011 "time"
1112
1213 "github.com/fasthttp/router"
@@ -156,6 +157,13 @@ func (h *ConfigHandler) getConfig(ctx *fasthttp.RequestCtx) {
156157 }
157158 mapConfig ["proxy_config" ] = proxyConfig
158159 }
160+ // Fetching restart required config
161+ restartConfig , err := h .store .ConfigStore .GetRestartRequiredConfig (ctx )
162+ if err != nil {
163+ logger .Warn (fmt .Sprintf ("failed to get restart required config from store: %v" , err ))
164+ } else if restartConfig != nil {
165+ mapConfig ["restart_required" ] = restartConfig
166+ }
159167 }
160168 SendJSON (ctx , mapConfig )
161169}
@@ -209,6 +217,7 @@ func (h *ConfigHandler) updateConfig(ctx *fasthttp.RequestCtx) {
209217 updatedConfig := currentConfig
210218
211219 shouldReloadTelemetryPlugin := false
220+ var restartReasons []string
212221
213222 if payload .ClientConfig .DropExcessRequests != currentConfig .DropExcessRequests {
214223 h .configManager .UpdateDropExcessRequests (ctx , payload .ClientConfig .DropExcessRequests )
@@ -218,19 +227,42 @@ func (h *ConfigHandler) updateConfig(ctx *fasthttp.RequestCtx) {
218227 if ! slices .Equal (payload .ClientConfig .PrometheusLabels , currentConfig .PrometheusLabels ) {
219228 updatedConfig .PrometheusLabels = payload .ClientConfig .PrometheusLabels
220229 shouldReloadTelemetryPlugin = true
230+ restartReasons = append (restartReasons , "Prometheus labels" )
221231 }
222232
223233 if ! slices .Equal (payload .ClientConfig .AllowedOrigins , currentConfig .AllowedOrigins ) {
224234 updatedConfig .AllowedOrigins = payload .ClientConfig .AllowedOrigins
235+ restartReasons = append (restartReasons , "Allowed origins" )
225236 }
226237
238+ if payload .ClientConfig .InitialPoolSize != currentConfig .InitialPoolSize {
239+ restartReasons = append (restartReasons , "Initial pool size" )
240+ }
227241 updatedConfig .InitialPoolSize = payload .ClientConfig .InitialPoolSize
242+
243+ if payload .ClientConfig .EnableLogging != currentConfig .EnableLogging {
244+ restartReasons = append (restartReasons , "Logging enabled" )
245+ }
228246 updatedConfig .EnableLogging = payload .ClientConfig .EnableLogging
247+
248+ if payload .ClientConfig .DisableContentLogging != currentConfig .DisableContentLogging {
249+ restartReasons = append (restartReasons , "Content logging" )
250+ }
229251 updatedConfig .DisableContentLogging = payload .ClientConfig .DisableContentLogging
252+
253+ if payload .ClientConfig .EnableGovernance != currentConfig .EnableGovernance {
254+ restartReasons = append (restartReasons , "Governance enabled" )
255+ }
230256 updatedConfig .EnableGovernance = payload .ClientConfig .EnableGovernance
257+
231258 updatedConfig .EnforceGovernanceHeader = payload .ClientConfig .EnforceGovernanceHeader
232259 updatedConfig .AllowDirectKeys = payload .ClientConfig .AllowDirectKeys
260+
261+ if payload .ClientConfig .MaxRequestBodySizeMB != currentConfig .MaxRequestBodySizeMB {
262+ restartReasons = append (restartReasons , "Max request body size" )
263+ }
233264 updatedConfig .MaxRequestBodySizeMB = payload .ClientConfig .MaxRequestBodySizeMB
265+
234266 updatedConfig .EnableLiteLLMFallbacks = payload .ClientConfig .EnableLiteLLMFallbacks
235267
236268 // Validate LogRetentionDays
@@ -337,7 +369,7 @@ func (h *ConfigHandler) updateConfig(ctx *fasthttp.RequestCtx) {
337369 // }
338370 }
339371 // Checking auth config and trying to update if required
340- if payload .AuthConfig != nil && payload . AuthConfig . IsEnabled {
372+ if payload .AuthConfig != nil {
341373 // Getting current governance config
342374 authConfig , err := h .store .ConfigStore .GetAuthConfig (ctx )
343375 if err != nil {
@@ -347,29 +379,52 @@ func (h *ConfigHandler) updateConfig(ctx *fasthttp.RequestCtx) {
347379 return
348380 }
349381 }
350- if authConfig == nil && payload .AuthConfig .IsEnabled && (payload .AuthConfig .AdminUserName == "" || payload .AuthConfig .AdminPassword == "" ) {
351- SendError (ctx , fasthttp .StatusBadRequest , "auth username and password must be provided" )
352- return
382+
383+ // Check if auth config has changed (for restart required flag)
384+ authChanged := false
385+ if authConfig == nil {
386+ // No existing config, any enabled state is a change
387+ if payload .AuthConfig .IsEnabled {
388+ authChanged = true
389+ }
390+ } else {
391+ // Compare with existing config
392+ if payload .AuthConfig .IsEnabled != authConfig .IsEnabled ||
393+ payload .AuthConfig .AdminUserName != authConfig .AdminUserName ||
394+ payload .AuthConfig .DisableAuthOnInference != authConfig .DisableAuthOnInference ||
395+ (payload .AuthConfig .AdminPassword != "<redacted>" && payload .AuthConfig .AdminPassword != "" ) {
396+ authChanged = true
397+ }
353398 }
354- // Fetching current Auth config
355- if payload .AuthConfig .AdminUserName != "" {
356- if payload .AuthConfig .AdminPassword == "<redacted>" {
357- if authConfig == nil || authConfig .AdminPassword == "" {
358- SendError (ctx , fasthttp .StatusBadRequest , "auth password must be provided" )
359- return
360- }
361- // Assuming that password hasn't been changed
362- payload .AuthConfig .AdminPassword = authConfig .AdminPassword
363- } else {
364- // Password has been changed
365- // We will hash the password
366- hashedPassword , err := encrypt .Hash (payload .AuthConfig .AdminPassword )
367- if err != nil {
368- logger .Warn (fmt .Sprintf ("failed to hash password: %v" , err ))
369- SendError (ctx , fasthttp .StatusInternalServerError , fmt .Sprintf ("failed to hash password: %v" , err ))
370- return
399+ if authChanged {
400+ restartReasons = append (restartReasons , "Authentication" )
401+ }
402+
403+ if payload .AuthConfig .IsEnabled {
404+ if authConfig == nil && (payload .AuthConfig .AdminUserName == "" || payload .AuthConfig .AdminPassword == "" ) {
405+ SendError (ctx , fasthttp .StatusBadRequest , "auth username and password must be provided" )
406+ return
407+ }
408+ // Fetching current Auth config
409+ if payload .AuthConfig .AdminUserName != "" {
410+ if payload .AuthConfig .AdminPassword == "<redacted>" {
411+ if authConfig == nil || authConfig .AdminPassword == "" {
412+ SendError (ctx , fasthttp .StatusBadRequest , "auth password must be provided" )
413+ return
414+ }
415+ // Assuming that password hasn't been changed
416+ payload .AuthConfig .AdminPassword = authConfig .AdminPassword
417+ } else {
418+ // Password has been changed
419+ // We will hash the password
420+ hashedPassword , err := encrypt .Hash (payload .AuthConfig .AdminPassword )
421+ if err != nil {
422+ logger .Warn (fmt .Sprintf ("failed to hash password: %v" , err ))
423+ SendError (ctx , fasthttp .StatusInternalServerError , fmt .Sprintf ("failed to hash password: %v" , err ))
424+ return
425+ }
426+ payload .AuthConfig .AdminPassword = string (hashedPassword )
371427 }
372- payload .AuthConfig .AdminPassword = string (hashedPassword )
373428 }
374429 }
375430 err = h .configManager .UpdateAuthConfig (ctx , payload .AuthConfig )
@@ -379,6 +434,18 @@ func (h *ConfigHandler) updateConfig(ctx *fasthttp.RequestCtx) {
379434 return
380435 }
381436 }
437+
438+ // Set restart required flag if any restart-requiring configs changed
439+ if len (restartReasons ) > 0 {
440+ reason := fmt .Sprintf ("%s settings have been updated. A restart is required for changes to take full effect." , strings .Join (restartReasons , ", " ))
441+ if err := h .store .ConfigStore .SetRestartRequiredConfig (ctx , & configstoreTables.RestartRequiredConfig {
442+ Required : true ,
443+ Reason : reason ,
444+ }); err != nil {
445+ logger .Warn (fmt .Sprintf ("failed to set restart required config: %v" , err ))
446+ }
447+ }
448+
382449 ctx .SetStatusCode (fasthttp .StatusOK )
383450 SendJSON (ctx , map [string ]any {
384451 "status" : "success" ,
@@ -530,6 +597,14 @@ func (h *ConfigHandler) updateProxyConfig(ctx *fasthttp.RequestCtx) {
530597 return
531598 }
532599
600+ // Set restart required flag for proxy config changes
601+ if err := h .store .ConfigStore .SetRestartRequiredConfig (ctx , & configstoreTables.RestartRequiredConfig {
602+ Required : true ,
603+ Reason : "Proxy configuration has been updated. A restart is required for all changes to take full effect." ,
604+ }); err != nil {
605+ logger .Warn (fmt .Sprintf ("failed to set restart required config: %v" , err ))
606+ }
607+
533608 ctx .SetStatusCode (fasthttp .StatusOK )
534609 SendJSON (ctx , map [string ]any {
535610 "status" : "success" ,
0 commit comments