Skip to content

Commit

Permalink
fix: loopDetected condition never applied
Browse files Browse the repository at this point in the history
chore: Move InvalidSpec loopDetection above Grafana instance fetching
  • Loading branch information
Baarsgaard committed Jan 30, 2025
1 parent 33863dc commit 1a90230
Showing 1 changed file with 27 additions and 32 deletions.
59 changes: 27 additions & 32 deletions controllers/notificationpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,31 @@ func (r *GrafanaNotificationPolicyReconciler) Reconcile(ctx context.Context, req
}
removeInvalidSpec(&notificationPolicy.Status.Conditions)

// Assemble routes and check for loops
var mergedRoutes []*v1beta1.GrafanaNotificationPolicyRoute
if notificationPolicy.Spec.Route.RouteSelector != nil || notificationPolicy.Spec.Route.HasRouteSelector() {
mergedRoutes, err = assembleNotificationPolicyRoutes(ctx, r.Client, notificationPolicy)

if errors.Is(err, ErrLoopDetected) {
meta.SetStatusCondition(&notificationPolicy.Status.Conditions, metav1.Condition{
Type: conditionNotificationPolicyLoopDetected,
Status: metav1.ConditionTrue,
ObservedGeneration: notificationPolicy.Generation,
Reason: "LoopDetected",
Message: fmt.Sprintf("Loop detected in notification policy routes: %s", err.Error()),
})
meta.RemoveStatusCondition(&notificationPolicy.Status.Conditions, conditionNotificationPolicySynchronized)
return ctrl.Result{}, fmt.Errorf("failed to assemble notification policy routes: %w", err)
}

if err != nil {
r.Recorder.Event(notificationPolicy, corev1.EventTypeWarning, "AssemblyFailed", fmt.Sprintf("Failed to assemble GrafanaNotificationPolicy using routeSelectors: %v", err))
return ctrl.Result{}, fmt.Errorf("failed to assemble GrafanaNotificationPolicy using routeSelectors: %w", err)
}
}

meta.RemoveStatusCondition(&notificationPolicy.Status.Conditions, conditionNotificationPolicyLoopDetected)

instances, err := GetScopedMatchingInstances(ctx, r.Client, notificationPolicy)
if err != nil {
setNoMatchingInstancesCondition(&notificationPolicy.Status.Conditions, notificationPolicy.Generation, err)
Expand All @@ -132,16 +157,6 @@ func (r *GrafanaNotificationPolicyReconciler) Reconcile(ctx context.Context, req
removeNoMatchingInstance(&notificationPolicy.Status.Conditions)
log.Info("found matching Grafana instances for notificationPolicy", "count", len(instances))

var mergedRoutes []*v1beta1.GrafanaNotificationPolicyRoute

if notificationPolicy.Spec.Route.RouteSelector != nil || notificationPolicy.Spec.Route.HasRouteSelector() {
mergedRoutes, err = assembleNotificationPolicyRoutes(ctx, r.Client, notificationPolicy)
if err := r.handleAssembleError(err, notificationPolicy); err != nil {
return ctrl.Result{}, err
}
}
meta.RemoveStatusCondition(&notificationPolicy.Status.Conditions, conditionNotificationPolicyLoopDetected)

applyErrors := make(map[string]string)
for _, grafana := range instances {
// can be removed in go 1.22+
Expand Down Expand Up @@ -212,12 +227,12 @@ func assembleNotificationPolicyRoutes(ctx context.Context, k8sClient client.Clie
matchedRoute := &routes[i]
key := matchedRoute.NamespacedResource()

if _, exists := visitedGlobal[key]; !exists {
if !visitedGlobal[key] {
mergedRoutes = append(mergedRoutes, matchedRoute)
visitedGlobal[key] = true
}

if _, exists := visitedChilds[key]; exists {
if visitedChilds[key] {
return fmt.Errorf("%w: %s exists", ErrLoopDetected, key)
}
visitedChilds[key] = true
Expand Down Expand Up @@ -450,23 +465,3 @@ func statusDiscoveredRoutes(routes []*v1beta1.GrafanaNotificationPolicyRoute) []
func setInvalidSpecMutuallyExclusive(conditions *[]metav1.Condition, generation int64) {
setInvalidSpec(conditions, generation, "FieldsMutuallyExclusive", "RouteSelector and Routes are mutually exclusive")
}

// handleAssembleError handles errors during notification policy assembly
func (r *GrafanaNotificationPolicyReconciler) handleAssembleError(err error, notificationPolicy *grafanav1beta1.GrafanaNotificationPolicy) error {
if err == nil {
return nil
}

if errors.Is(err, ErrLoopDetected) {
meta.SetStatusCondition(&notificationPolicy.Status.Conditions, metav1.Condition{
Type: conditionNotificationPolicyLoopDetected,
Status: metav1.ConditionTrue,
ObservedGeneration: notificationPolicy.Generation,
Reason: "LoopDetected",
Message: fmt.Sprintf("Loop detected in notification policy routes: %s", err.Error()),
})
return nil
}
r.Recorder.Event(notificationPolicy, corev1.EventTypeWarning, "AssemblyFailed", fmt.Sprintf("Failed to assemble GrafanaNotificationPolicy using routeSelectors: %v", err))
return fmt.Errorf("failed to assemble GrafanaNotificationPolicy using routeSelectors: %w", err)
}

0 comments on commit 1a90230

Please sign in to comment.