in pkg/operator/rules.go [222:365]
func (r *rulesReconciler) ensureRuleConfigs(ctx context.Context, projectID, location, cluster string, compression monitoringv1.CompressionType) error {
logger, _ := logr.FromContext(ctx)
// Re-generate the configmap that's loaded by the rule-evaluator.
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: r.opts.OperatorNamespace,
Name: nameRulesGenerated,
Labels: map[string]string{
LabelAppName: NameRuleEvaluator,
},
},
// Ensure there's always at least an empty, uncompressed dummy file as the evaluator
// expects at least one match.
Data: map[string]string{
"empty.yaml": "",
},
}
// Generate a final rule file for each Rules resource.
//
// Depending on the scope level (global, cluster, namespace) the rules will be generated
// so that queries are constrained to the appropriate project_id, cluster, and namespace
// labels and that they are preserved through query aggregations and appear on the
// output data.
//
// The location is not scoped as it's not a meaningful boundary for "human access"
// to data as clusters may span locations.
var rulesList monitoringv1.RulesList
if err := r.client.List(ctx, &rulesList); err != nil {
return fmt.Errorf("list rules: %w", err)
}
now := metav1.Now()
conditionSuccess := &monitoringv1.MonitoringCondition{
Type: monitoringv1.ConfigurationCreateSuccess,
Status: corev1.ConditionTrue,
}
var statusUpdates []monitoringv1.MonitoringCRD
for i := range rulesList.Items {
rs := &rulesList.Items[i]
result, err := rs.RuleGroupsConfig(projectID, location, cluster)
if err != nil {
msg := "generating rule config failed"
if rs.Status.SetMonitoringCondition(rs.GetGeneration(), now, &monitoringv1.MonitoringCondition{
Type: monitoringv1.ConfigurationCreateSuccess,
Status: corev1.ConditionFalse,
Message: msg,
Reason: err.Error(),
}) {
statusUpdates = append(statusUpdates, rs)
}
logger.Error(err, "convert rules", "err", err, "namespace", rs.Namespace, "name", rs.Name)
continue
}
filename := fmt.Sprintf("rules__%s__%s.yaml", rs.Namespace, rs.Name)
if err := setConfigMapData(cm, compression, filename, result); err != nil {
return err
}
if rs.Status.SetMonitoringCondition(rs.GetGeneration(), now, conditionSuccess) {
statusUpdates = append(statusUpdates, rs)
}
}
var clusterRulesList monitoringv1.ClusterRulesList
if err := r.client.List(ctx, &clusterRulesList); err != nil {
return fmt.Errorf("list cluster rules: %w", err)
}
for i := range clusterRulesList.Items {
rs := &clusterRulesList.Items[i]
result, err := rs.RuleGroupsConfig(projectID, location, cluster)
if err != nil {
msg := "generating rule config failed"
if rs.Status.SetMonitoringCondition(rs.Generation, now, &monitoringv1.MonitoringCondition{
Type: monitoringv1.ConfigurationCreateSuccess,
Status: corev1.ConditionFalse,
Message: msg,
Reason: err.Error(),
}) {
statusUpdates = append(statusUpdates, rs)
}
logger.Error(err, "convert rules", "err", err, "namespace", rs.Namespace, "name", rs.Name)
continue
}
filename := fmt.Sprintf("clusterrules__%s.yaml", rs.Name)
if err := setConfigMapData(cm, compression, filename, result); err != nil {
return err
}
if rs.Status.SetMonitoringCondition(rs.GetGeneration(), now, conditionSuccess) {
statusUpdates = append(statusUpdates, rs)
}
}
var globalRulesList monitoringv1.GlobalRulesList
if err := r.client.List(ctx, &globalRulesList); err != nil {
return fmt.Errorf("list global rules: %w", err)
}
for i := range globalRulesList.Items {
rs := &globalRulesList.Items[i]
result, err := rs.RuleGroupsConfig()
if err != nil {
msg := "generating rule config failed"
if rs.Status.SetMonitoringCondition(rs.Generation, now, &monitoringv1.MonitoringCondition{
Type: monitoringv1.ConfigurationCreateSuccess,
Status: corev1.ConditionFalse,
Message: msg,
Reason: err.Error(),
}) {
statusUpdates = append(statusUpdates, rs)
}
logger.Error(err, "convert rules", "err", err, "namespace", rs.Namespace, "name", rs.Name)
continue
}
filename := fmt.Sprintf("globalrules__%s.yaml", rs.Name)
if err := setConfigMapData(cm, compression, filename, result); err != nil {
return err
}
if rs.Status.SetMonitoringCondition(rs.GetGeneration(), now, conditionSuccess) {
statusUpdates = append(statusUpdates, rs)
}
}
// Create or update generated rule ConfigMap.
if err := r.client.Update(ctx, cm); apierrors.IsNotFound(err) {
if err := r.client.Create(ctx, cm); err != nil {
return fmt.Errorf("create generated rules: %w", err)
}
} else if err != nil {
return fmt.Errorf("update generated rules: %w", err)
}
var errs []error
for _, obj := range statusUpdates {
if err := patchMonitoringStatus(ctx, r.client, obj, obj.GetMonitoringStatus()); err != nil {
errs = append(errs, err)
}
}
return errors.Join(errs...)
}