2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  api  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 21:28:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/grafana/grafana/pkg/services/folder" 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									apimodels  "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ngmodels  "github.com/grafana/grafana/pkg/services/ngalert/models" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/grafana/grafana/pkg/services/ngalert/store" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/grafana/grafana/pkg/setting" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// validateRuleNode validates API model (definitions.PostableExtendedRuleNode) and converts it to models.AlertRule
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  validateRuleNode (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ruleNode  * apimodels . PostableExtendedRuleNode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									groupName  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									interval  time . Duration , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									orgId  int64 , 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 21:28:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									namespace  * folder . Folder , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									conditionValidator  func ( ngmodels . Condition )  error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg  * setting . UnifiedAlertingSettings )  ( * ngmodels . AlertRule ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 22:40:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									intervalSeconds ,  err  :=  validateInterval ( cfg ,  interval ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ruleNode . GrafanaManagedAlert  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "not Grafana managed alert rule" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if UID is specified then we can accept partial model. Therefore, some validation can be skipped as it will be patched later
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									canPatch  :=  ruleNode . GrafanaManagedAlert . UID  !=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ruleNode . GrafanaManagedAlert . Title  ==  ""  &&  ! canPatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . New ( "alert rule title cannot be empty" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( ruleNode . GrafanaManagedAlert . Title )  >  store . AlertRuleMaxTitleLength  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "alert rule title is too long. Max length is %d" ,  store . AlertRuleMaxTitleLength ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									noDataState  :=  ngmodels . NoData 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ruleNode . GrafanaManagedAlert . NoDataState  ==  ""  &&  canPatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										noDataState  =  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ruleNode . GrafanaManagedAlert . NoDataState  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										noDataState ,  err  =  ngmodels . NoDataStateFromString ( string ( ruleNode . GrafanaManagedAlert . NoDataState ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errorState  :=  ngmodels . AlertingErrState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ruleNode . GrafanaManagedAlert . ExecErrState  ==  ""  &&  canPatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errorState  =  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ruleNode . GrafanaManagedAlert . ExecErrState  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errorState ,  err  =  ngmodels . ErrStateFromString ( string ( ruleNode . GrafanaManagedAlert . ExecErrState ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( ruleNode . GrafanaManagedAlert . Data )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  canPatch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ruleNode . GrafanaManagedAlert . Condition  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  fmt . Errorf ( "%w: query is not specified by condition is. You must specify both query and condition to update existing alert rule" ,  ngmodels . ErrAlertRuleFailedValidation ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( "%w: no queries or expressions are found" ,  ngmodels . ErrAlertRuleFailedValidation ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( ruleNode . GrafanaManagedAlert . Data )  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cond  :=  ngmodels . Condition { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Condition :  ruleNode . GrafanaManagedAlert . Condition , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Data :       ruleNode . GrafanaManagedAlert . Data , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 22:40:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  =  conditionValidator ( cond ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( "failed to validate condition of alert rule %s: %w" ,  ruleNode . GrafanaManagedAlert . Title ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newAlertRule  :=  ngmodels . AlertRule { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										OrgID :            orgId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Title :            ruleNode . GrafanaManagedAlert . Title , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Condition :        ruleNode . GrafanaManagedAlert . Condition , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Data :             ruleNode . GrafanaManagedAlert . Data , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UID :              ruleNode . GrafanaManagedAlert . UID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										IntervalSeconds :  intervalSeconds , 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 21:28:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										NamespaceUID :     namespace . UID , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										RuleGroup :        groupName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										NoDataState :      noDataState , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ExecErrState :     errorState , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-30 23:46:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newAlertRule . For ,  err  =  validateForInterval ( ruleNode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ruleNode . ApiRuleNode  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newAlertRule . Annotations  =  ruleNode . ApiRuleNode . Annotations 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newAlertRule . Labels  =  ruleNode . ApiRuleNode . Labels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 22:05:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  newAlertRule . SetDashboardAndPanel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & newAlertRule ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 22:40:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  validateInterval ( cfg  * setting . UnifiedAlertingSettings ,  interval  time . Duration )  ( int64 ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									intervalSeconds  :=  int64 ( interval . Seconds ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									baseIntervalSeconds  :=  int64 ( cfg . BaseInterval . Seconds ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  interval  <=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ,  fmt . Errorf ( "rule evaluation interval must be positive duration that is multiple of the base interval %d seconds" ,  baseIntervalSeconds ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  intervalSeconds % baseIntervalSeconds  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ,  fmt . Errorf ( "rule evaluation interval %d should be multiple of the base interval of %d seconds" ,  int64 ( interval . Seconds ( ) ) ,  baseIntervalSeconds ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  intervalSeconds ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-30 23:46:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// validateForInterval validates ApiRuleNode.For and converts it to time.Duration. If the field is not specified returns 0 if GrafanaManagedAlert.UID is empty and -1 if it is not.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  validateForInterval ( ruleNode  * apimodels . PostableExtendedRuleNode )  ( time . Duration ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ruleNode . ApiRuleNode  ==  nil  ||  ruleNode . ApiRuleNode . For  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ruleNode . GrafanaManagedAlert . UID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ,  nil  // will be patched later with the real value of the current version of the rule
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ,  nil  // if it's a new rule, use the 0 as the default
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									duration  :=  time . Duration ( * ruleNode . ApiRuleNode . For ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  duration  <  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ,  fmt . Errorf ( "field `for` cannot be negative [%v]. 0 or any positive duration are allowed" ,  * ruleNode . ApiRuleNode . For ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  duration ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// validateRuleGroup validates API model (definitions.PostableRuleGroupConfig) and converts it to a collection of models.AlertRule.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Returns a slice that contains all rules described by API model or error if either group specification or an alert definition is not valid.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  validateRuleGroup (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ruleGroupConfig  * apimodels . PostableRuleGroupConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									orgId  int64 , 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 21:28:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									namespace  * folder . Folder , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									conditionValidator  func ( ngmodels . Condition )  error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg  * setting . UnifiedAlertingSettings )  ( [ ] * ngmodels . AlertRule ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ruleGroupConfig . Name  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . New ( "rule group name cannot be empty" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( ruleGroupConfig . Name )  >  store . AlertRuleMaxRuleGroupNameLength  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "rule group name is too long. Max length is %d" ,  store . AlertRuleMaxRuleGroupNameLength ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									interval  :=  time . Duration ( ruleGroupConfig . Interval ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  interval  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// if group interval is 0 (undefined) then we automatically fall back to the default interval
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										interval  =  cfg . DefaultRuleEvaluationInterval 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  interval  <  0  ||  int64 ( interval . Seconds ( ) ) % int64 ( cfg . BaseInterval . Seconds ( ) )  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "rule evaluation interval (%d second) should be positive number that is multiple of the base interval of %d seconds" ,  int64 ( interval . Seconds ( ) ) ,  int64 ( cfg . BaseInterval . Seconds ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TODO should we validate that interval is >= cfg.MinInterval? Currently, we allow to save but fix the specified interval if it is < cfg.MinInterval
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									result  :=  make ( [ ] * ngmodels . AlertRule ,  0 ,  len ( ruleGroupConfig . Rules ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uids  :=  make ( map [ string ] int ,  cap ( result ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  idx  :=  range  ruleGroupConfig . Rules  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rule ,  err  :=  validateRuleNode ( & ruleGroupConfig . Rules [ idx ] ,  ruleGroupConfig . Name ,  interval ,  orgId ,  namespace ,  conditionValidator ,  cfg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// TODO do not stop on the first failure but return all failures
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( "invalid rule specification at index [%d]: %w" ,  idx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rule . UID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  existingIdx ,  ok  :=  uids [ rule . UID ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  fmt . Errorf ( "rule [%d] has UID %s that is already assigned to another rule at index %d" ,  idx ,  rule . UID ,  existingIdx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uids [ rule . UID ]  =  idx 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-22 22:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rule . RuleGroupIndex  =  idx  +  1 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-24 00:30:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										result  =  append ( result ,  rule ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  result ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}