1
1
package alertmanager
2
2
3
3
import (
4
+ "encoding/json"
4
5
"flag"
5
6
"fmt"
6
7
"html/template"
@@ -382,14 +383,14 @@ func (am *MultitenantAlertmanager) addNewConfigs(cfgs map[string]configs.View) {
382
383
}
383
384
384
385
func (am * MultitenantAlertmanager ) transformConfig (userID string , amConfig * amconfig.Config ) (* amconfig.Config , error ) {
385
- if amConfig == nil && am .fallbackConfig != nil {
386
- log .Infof ("using fallback configuration for %v" , userID )
387
- amConfig = am .fallbackConfig
388
- }
389
386
if amConfig == nil { // shouldn't happen, but check just in case
390
387
return nil , fmt .Errorf ("no usable Cortex configuration for %v" , userID )
391
388
}
392
- newConfig := * amConfig // take a copy to modify
389
+ newConfig , err := copyConfig (amConfig )
390
+ if err != nil {
391
+ log .Errorf ("cannot copy config: %s" , err )
392
+ return nil , err
393
+ }
393
394
// Magic ability to configure a Slack receiver if config requests it
394
395
if am .cfg .AutoSlackRoot != "" {
395
396
for _ , r := range newConfig .Receivers {
@@ -401,7 +402,28 @@ func (am *MultitenantAlertmanager) transformConfig(userID string, amConfig *amco
401
402
}
402
403
}
403
404
404
- return & newConfig , nil
405
+ return newConfig , nil
406
+ }
407
+
408
+ // deep copy because of config struct contains a lot of references types (slices of pointers tec)
409
+ // this copy works even if we add/change other fields of config
410
+ // or if fields are changing somewhere else in the code
411
+ func copyConfig (config * amconfig.Config ) (* amconfig.Config , error ) {
412
+ configBytes , err := json .Marshal (config )
413
+ if err != nil {
414
+ log .Errorf ("cannot marshal config to json, error: %s" , err )
415
+ return nil , err
416
+ }
417
+
418
+ newConfig := & amconfig.Config {}
419
+
420
+ err = json .Unmarshal (configBytes , newConfig )
421
+ if err != nil {
422
+ log .Errorf ("cannot unmarshal json to config, error: %s" , err )
423
+ return nil , err
424
+ }
425
+
426
+ return newConfig , nil
405
427
}
406
428
407
429
// setConfig applies the given configuration to the alertmanager for `userID`,
0 commit comments