@@ -71,6 +71,14 @@ const (
71
71
recordingRuleFilter string = "record"
72
72
)
73
73
74
+ type DisabledRuleGroupErr struct {
75
+ Message string
76
+ }
77
+
78
+ func (e * DisabledRuleGroupErr ) Error () string {
79
+ return e .Message
80
+ }
81
+
74
82
// Config is the configuration for the recording rules server.
75
83
type Config struct {
76
84
// This is used for template expansion in alerts; must be a valid URL.
@@ -415,9 +423,19 @@ func tokenForGroup(g *rulespb.RuleGroupDesc) uint32 {
415
423
return ringHasher .Sum32 ()
416
424
}
417
425
418
- func instanceOwnsRuleGroup (r ring.ReadRing , g * rulespb.RuleGroupDesc , instanceAddr string ) (bool , error ) {
426
+ func instanceOwnsRuleGroup (r ring.ReadRing , g * rulespb.RuleGroupDesc , disabledRuleGroups validation. DisabledRuleGroups , instanceAddr string ) (bool , error ) {
419
427
hash := tokenForGroup (g )
420
428
429
+ for _ , disabledGroup := range disabledRuleGroups {
430
+
431
+ if hash == tokenForGroup (& rulespb.RuleGroupDesc {
432
+ Name : disabledGroup .Name ,
433
+ Namespace : disabledGroup .Namespace ,
434
+ User : disabledGroup .User ,
435
+ }) {
436
+ return false , & DisabledRuleGroupErr {Message : fmt .Sprintf ("rule group %s, namespace %s, user %s is disabled" , g .Name , g .Namespace , g .User )}
437
+ }
438
+ }
421
439
rlrs , err := r .Get (hash , RingOp , nil , nil , nil )
422
440
if err != nil {
423
441
return false , errors .Wrap (err , "error reading ring to verify rule group ownership" )
@@ -533,7 +551,37 @@ func (r *Ruler) listRules(ctx context.Context) (result map[string]rulespb.RuleGr
533
551
}
534
552
535
553
func (r * Ruler ) listRulesNoSharding (ctx context.Context ) (map [string ]rulespb.RuleGroupList , error ) {
536
- return r .store .ListAllRuleGroups (ctx )
554
+ allRuleGroups , err := r .store .ListAllRuleGroups (ctx )
555
+ if err != nil {
556
+ return nil , err
557
+ }
558
+ for userID , groups := range allRuleGroups {
559
+ disabledRuleGroupsForUser := r .limits .DisabledRuleGroups (userID )
560
+ if len (disabledRuleGroupsForUser ) == 0 {
561
+ continue
562
+ }
563
+ filteredGroupsForUser := rulespb.RuleGroupList {}
564
+ for _ , group := range groups {
565
+ if ! ruleGroupDisabled (group , disabledRuleGroupsForUser ) {
566
+ filteredGroupsForUser = append (filteredGroupsForUser , group )
567
+ } else {
568
+ level .Info (r .logger ).Log ("msg" , "rule group disabled" , "rule group name" , group .Name , "namespace" , group .Namespace , "user" , group .User )
569
+ }
570
+ }
571
+ allRuleGroups [userID ] = filteredGroupsForUser
572
+ }
573
+ return allRuleGroups , nil
574
+ }
575
+
576
+ func ruleGroupDisabled (ruleGroup * rulespb.RuleGroupDesc , disabledRuleGroupsForUser validation.DisabledRuleGroups ) bool {
577
+ for _ , disabledRuleGroupForUser := range disabledRuleGroupsForUser {
578
+ if ruleGroup .Namespace == disabledRuleGroupForUser .Namespace &&
579
+ ruleGroup .Name == disabledRuleGroupForUser .Name &&
580
+ ruleGroup .User == disabledRuleGroupForUser .User {
581
+ return true
582
+ }
583
+ }
584
+ return false
537
585
}
538
586
539
587
func (r * Ruler ) listRulesShardingDefault (ctx context.Context ) (map [string ]rulespb.RuleGroupList , error ) {
@@ -544,7 +592,7 @@ func (r *Ruler) listRulesShardingDefault(ctx context.Context) (map[string]rulesp
544
592
545
593
filteredConfigs := make (map [string ]rulespb.RuleGroupList )
546
594
for userID , groups := range configs {
547
- filtered := filterRuleGroups (userID , groups , r .ring , r .lifecycler .GetInstanceAddr (), r .logger , r .ringCheckErrors )
595
+ filtered := filterRuleGroups (userID , groups , r .limits . DisabledRuleGroups ( userID ), r . ring , r .lifecycler .GetInstanceAddr (), r .logger , r .ringCheckErrors )
548
596
if len (filtered ) > 0 {
549
597
filteredConfigs [userID ] = filtered
550
598
}
@@ -602,7 +650,7 @@ func (r *Ruler) listRulesShuffleSharding(ctx context.Context) (map[string]rulesp
602
650
return errors .Wrapf (err , "failed to fetch rule groups for user %s" , userID )
603
651
}
604
652
605
- filtered := filterRuleGroups (userID , groups , userRings [userID ], r .lifecycler .GetInstanceAddr (), r .logger , r .ringCheckErrors )
653
+ filtered := filterRuleGroups (userID , groups , r . limits . DisabledRuleGroups ( userID ), userRings [userID ], r .lifecycler .GetInstanceAddr (), r .logger , r .ringCheckErrors )
606
654
if len (filtered ) == 0 {
607
655
continue
608
656
}
@@ -624,15 +672,21 @@ func (r *Ruler) listRulesShuffleSharding(ctx context.Context) (map[string]rulesp
624
672
//
625
673
// Reason why this function is not a method on Ruler is to make sure we don't accidentally use r.ring,
626
674
// but only ring passed as parameter.
627
- func filterRuleGroups (userID string , ruleGroups []* rulespb.RuleGroupDesc , ring ring.ReadRing , instanceAddr string , log log.Logger , ringCheckErrors prometheus.Counter ) []* rulespb.RuleGroupDesc {
675
+ func filterRuleGroups (userID string , ruleGroups []* rulespb.RuleGroupDesc , disabledRuleGroups validation. DisabledRuleGroups , ring ring.ReadRing , instanceAddr string , log log.Logger , ringCheckErrors prometheus.Counter ) []* rulespb.RuleGroupDesc {
628
676
// Prune the rule group to only contain rules that this ruler is responsible for, based on ring.
629
677
var result []* rulespb.RuleGroupDesc
630
678
for _ , g := range ruleGroups {
631
- owned , err := instanceOwnsRuleGroup (ring , g , instanceAddr )
679
+ owned , err := instanceOwnsRuleGroup (ring , g , disabledRuleGroups , instanceAddr )
632
680
if err != nil {
633
- ringCheckErrors .Inc ()
634
- level .Error (log ).Log ("msg" , "failed to check if the ruler replica owns the rule group" , "user" , userID , "namespace" , g .Namespace , "group" , g .Name , "err" , err )
635
- continue
681
+ switch e := err .(type ) {
682
+ case * DisabledRuleGroupErr :
683
+ level .Info (log ).Log ("msg" , e .Message )
684
+ continue
685
+ default :
686
+ ringCheckErrors .Inc ()
687
+ level .Error (log ).Log ("msg" , "failed to check if the ruler replica owns the rule group" , "user" , userID , "namespace" , g .Namespace , "group" , g .Name , "err" , err )
688
+ continue
689
+ }
636
690
}
637
691
638
692
if owned {
0 commit comments