@@ -71,6 +71,14 @@ const (
7171	recordingRuleFilter  string  =  "record" 
7272)
7373
74+ type  DisabledRuleGroupErr  struct  {
75+ 	Message  string 
76+ }
77+ 
78+ func  (e  * DisabledRuleGroupErr ) Error () string  {
79+ 	return  e .Message 
80+ }
81+ 
7482// Config is the configuration for the recording rules server. 
7583type  Config  struct  {
7684	// This is used for template expansion in alerts; must be a valid URL. 
@@ -415,9 +423,19 @@ func tokenForGroup(g *rulespb.RuleGroupDesc) uint32 {
415423	return  ringHasher .Sum32 ()
416424}
417425
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 ) {
419427	hash  :=  tokenForGroup (g )
420428
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 ("skipping rule group %s, within namespace %s, owned by %s" , g .Name , g .Namespace , g .User )}
437+ 		}
438+ 	}
421439	rlrs , err  :=  r .Get (hash , RingOp , nil , nil , nil )
422440	if  err  !=  nil  {
423441		return  false , errors .Wrap (err , "error reading ring to verify rule group ownership" )
@@ -544,7 +562,7 @@ func (r *Ruler) listRulesShardingDefault(ctx context.Context) (map[string]rulesp
544562
545563	filteredConfigs  :=  make (map [string ]rulespb.RuleGroupList )
546564	for  userID , groups  :=  range  configs  {
547- 		filtered  :=  filterRuleGroups (userID , groups , r .ring , r .lifecycler .GetInstanceAddr (), r .logger , r .ringCheckErrors )
565+ 		filtered  :=  filterRuleGroups (userID , groups , r .limits . DisabledRuleGroups ( userID ),  r . ring , r .lifecycler .GetInstanceAddr (), r .logger , r .ringCheckErrors )
548566		if  len (filtered ) >  0  {
549567			filteredConfigs [userID ] =  filtered 
550568		}
@@ -602,7 +620,7 @@ func (r *Ruler) listRulesShuffleSharding(ctx context.Context) (map[string]rulesp
602620					return  errors .Wrapf (err , "failed to fetch rule groups for user %s" , userID )
603621				}
604622
605- 				filtered  :=  filterRuleGroups (userID , groups , userRings [userID ], r .lifecycler .GetInstanceAddr (), r .logger , r .ringCheckErrors )
623+ 				filtered  :=  filterRuleGroups (userID , groups , r . limits . DisabledRuleGroups ( userID ),  userRings [userID ], r .lifecycler .GetInstanceAddr (), r .logger , r .ringCheckErrors )
606624				if  len (filtered ) ==  0  {
607625					continue 
608626				}
@@ -624,15 +642,21 @@ func (r *Ruler) listRulesShuffleSharding(ctx context.Context) (map[string]rulesp
624642// 
625643// Reason why this function is not a method on Ruler is to make sure we don't accidentally use r.ring, 
626644// 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  {
645+ func  filterRuleGroups (userID  string , ruleGroups  []* rulespb.RuleGroupDesc , disabledRuleGroups  validation. DisabledRuleGroups ,  ring  ring.ReadRing , instanceAddr  string , log  log.Logger , ringCheckErrors  prometheus.Counter ) []* rulespb.RuleGroupDesc  {
628646	// Prune the rule group to only contain rules that this ruler is responsible for, based on ring. 
629647	var  result  []* rulespb.RuleGroupDesc 
630648	for  _ , g  :=  range  ruleGroups  {
631- 		owned , err  :=  instanceOwnsRuleGroup (ring , g , instanceAddr )
649+ 		owned , err  :=  instanceOwnsRuleGroup (ring , g , disabledRuleGroups ,  instanceAddr )
632650		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 
651+ 			switch  e  :=  err .(type ) {
652+ 			case  * DisabledRuleGroupErr :
653+ 				level .Info (log ).Log ("msg" , e .Message )
654+ 				continue 
655+ 			default :
656+ 				ringCheckErrors .Inc ()
657+ 				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 )
658+ 				continue 
659+ 			}
636660		}
637661
638662		if  owned  {
0 commit comments