[MM-28692] Include config diffs in audit record for config changing API calls (#17623)
* Replace config generator * Cleanup * Some renaming and docs additions to add clarity * Cleanup logging related methods * Cleanup emitter * Fix TestDefaultsGenerator * Move feature flags synchronization logic out of config package * Remove unnecessary util functions * Simplify load/set logic * Refine semantics and add some test to cover them * Remove unnecessary deep copies * Improve logic further * Fix license header * Review file store tests * Fix test * Fix test * Avoid additional write during initialization * More consistent naming * Update app/feature_flags.go Co-authored-by: Christopher Speller <crspeller@gmail.com> * Update config/store.go Co-authored-by: Christopher Speller <crspeller@gmail.com> * Update config/store.go Co-authored-by: Christopher Speller <crspeller@gmail.com> * Update config/store.go Co-authored-by: Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> * Make ConfigStore.Set() return both old and new configs * Implement config diff function * Make app.SaveConfig return previous and current configs * Add config diff to audit record * Fix returned configs * Include high level test * Move FF synchronizer to its own package * Remove unidiomatic use of sync.Once * Add some comments * Rename function * More comment * Save config diff in audit record for local endpoints * Enable audit for config set/reset commands * Improve tests output Co-authored-by: Christopher Speller <crspeller@gmail.com> Co-authored-by: Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
ca9d8ab0a4
Коммит
e1b13c10fc
@@ -284,7 +284,7 @@ type AppIface interface {
|
||||
// in the server and revoke them
|
||||
RevokeSessionsFromAllUsers() *model.AppError
|
||||
// SaveConfig replaces the active configuration, optionally notifying cluster peers.
|
||||
SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) *model.AppError
|
||||
SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError)
|
||||
// SearchAllChannels returns a list of channels, the total count of the results of the search (if the paginate search option is true), and an error.
|
||||
SearchAllChannels(term string, opts model.ChannelSearchOpts) (*model.ChannelListWithTeamData, int64, *model.AppError)
|
||||
// SearchAllTeams returns a team list and the total count of the results
|
||||
|
||||
@@ -54,7 +54,7 @@ func (s *Server) UpdateConfig(f func(*model.Config)) {
|
||||
old := s.Config()
|
||||
updated := old.Clone()
|
||||
f(updated)
|
||||
if _, err := s.configStore.Set(updated); err != nil {
|
||||
if _, _, err := s.configStore.Set(updated); err != nil {
|
||||
mlog.Error("Failed to update config", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
@@ -405,12 +405,13 @@ func (a *App) GetEnvironmentConfig(filter func(reflect.StructField) bool) map[st
|
||||
}
|
||||
|
||||
// SaveConfig replaces the active configuration, optionally notifying cluster peers.
|
||||
func (s *Server) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) *model.AppError {
|
||||
oldCfg, err := s.configStore.Set(newCfg)
|
||||
// It returns both the previous and current configs.
|
||||
func (s *Server) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError) {
|
||||
oldCfg, newCfg, err := s.configStore.Set(newCfg)
|
||||
if errors.Cause(err) == config.ErrReadOnlyConfiguration {
|
||||
return model.NewAppError("saveConfig", "ent.cluster.save_config.error", nil, err.Error(), http.StatusForbidden)
|
||||
return nil, nil, model.NewAppError("saveConfig", "ent.cluster.save_config.error", nil, err.Error(), http.StatusForbidden)
|
||||
} else if err != nil {
|
||||
return model.NewAppError("saveConfig", "app.save_config.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return nil, nil, model.NewAppError("saveConfig", "app.save_config.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
if s.startMetrics && *s.Config().MetricsSettings.Enable {
|
||||
@@ -423,19 +424,18 @@ func (s *Server) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage
|
||||
}
|
||||
|
||||
if s.Cluster != nil {
|
||||
newCfg = s.configStore.RemoveEnvironmentOverrides(newCfg)
|
||||
oldCfg = s.configStore.RemoveEnvironmentOverrides(oldCfg)
|
||||
err := s.Cluster.ConfigChanged(oldCfg, newCfg, sendConfigChangeClusterMessage)
|
||||
err := s.Cluster.ConfigChanged(s.configStore.RemoveEnvironmentOverrides(oldCfg),
|
||||
s.configStore.RemoveEnvironmentOverrides(newCfg), sendConfigChangeClusterMessage)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return oldCfg, newCfg, nil
|
||||
}
|
||||
|
||||
// SaveConfig replaces the active configuration, optionally notifying cluster peers.
|
||||
func (a *App) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) *model.AppError {
|
||||
func (a *App) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError) {
|
||||
return a.Srv().SaveConfig(newCfg, sendConfigChangeClusterMessage)
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ func (s *Server) doAdvancedPermissionsMigration() {
|
||||
config := s.Config()
|
||||
if *config.ServiceSettings.DEPRECATED_DO_NOT_USE_AllowEditPost == model.ALLOW_EDIT_POST_ALWAYS {
|
||||
*config.ServiceSettings.PostEditTimeLimit = -1
|
||||
if err := s.SaveConfig(config, true); err != nil {
|
||||
if _, _, err := s.SaveConfig(config, true); err != nil {
|
||||
mlog.Error("Failed to update config in Advanced Permissions Phase 1 Migration.", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13392,7 +13392,7 @@ func (a *OpenTracingAppLayer) SaveComplianceReport(job *model.Compliance) (*mode
|
||||
return resultVar0, resultVar1
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) *model.AppError {
|
||||
func (a *OpenTracingAppLayer) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError) {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SaveConfig")
|
||||
|
||||
@@ -13404,14 +13404,14 @@ func (a *OpenTracingAppLayer) SaveConfig(newCfg *model.Config, sendConfigChangeC
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
resultVar0 := a.app.SaveConfig(newCfg, sendConfigChangeClusterMessage)
|
||||
resultVar0, resultVar1, resultVar2 := a.app.SaveConfig(newCfg, sendConfigChangeClusterMessage)
|
||||
|
||||
if resultVar0 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar0))
|
||||
if resultVar2 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar2))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return resultVar0
|
||||
return resultVar0, resultVar1, resultVar2
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) SaveReactionForPost(c *request.Context, reaction *model.Reaction) (*model.Reaction, *model.AppError) {
|
||||
|
||||
@@ -402,7 +402,7 @@ func (s *Server) enablePlugin(id string) *model.AppError {
|
||||
})
|
||||
|
||||
// This call will implicitly invoke SyncPluginsActiveState which will activate enabled plugins.
|
||||
if err := s.SaveConfig(s.Config(), true); err != nil {
|
||||
if _, _, err := s.SaveConfig(s.Config(), true); err != nil {
|
||||
if err.Id == "ent.cluster.save_config.error" {
|
||||
return model.NewAppError("EnablePlugin", "app.plugin.cluster.save_config.app_error", nil, "", http.StatusInternalServerError)
|
||||
}
|
||||
@@ -449,7 +449,7 @@ func (s *Server) disablePlugin(id string) *model.AppError {
|
||||
s.unregisterPluginCommands(id)
|
||||
|
||||
// This call will implicitly invoke SyncPluginsActiveState which will deactivate disabled plugins.
|
||||
if err := s.SaveConfig(s.Config(), true); err != nil {
|
||||
if _, _, err := s.SaveConfig(s.Config(), true); err != nil {
|
||||
return model.NewAppError("DisablePlugin", "app.plugin.config.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,8 @@ func (api *PluginAPI) GetUnsanitizedConfig() *model.Config {
|
||||
}
|
||||
|
||||
func (api *PluginAPI) SaveConfig(config *model.Config) *model.AppError {
|
||||
return api.app.SaveConfig(config, true)
|
||||
_, _, err := api.app.SaveConfig(config, true)
|
||||
return err
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetPluginConfig() map[string]interface{} {
|
||||
@@ -123,7 +124,8 @@ func (api *PluginAPI) GetPluginConfig() map[string]interface{} {
|
||||
func (api *PluginAPI) SavePluginConfig(pluginConfig map[string]interface{}) *model.AppError {
|
||||
cfg := api.app.GetSanitizedConfig()
|
||||
cfg.PluginSettings.Plugins[api.manifest.Id] = pluginConfig
|
||||
return api.app.SaveConfig(cfg, true)
|
||||
_, _, err := api.app.SaveConfig(cfg, true)
|
||||
return err
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetBundlePath() (string, error) {
|
||||
|
||||
Ссылка в новой задаче
Block a user