Advisor: Allow to retry checks for a single element (#104279)

This commit is contained in:
Andres Martinez Gotor
2025-04-24 12:00:32 +02:00
committed by GitHub
parent 10df5d6f23
commit edeff68645
16 changed files with 255 additions and 13 deletions

View File

@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"slices"
"sync"
"github.com/grafana/grafana-app-sdk/resource"
@ -76,6 +77,72 @@ func processCheck(ctx context.Context, client resource.Client, obj resource.Obje
}, resource.PatchOptions{}, obj)
}
func processCheckRetry(ctx context.Context, client resource.Client, obj resource.Object, check checks.Check) error {
status := checks.GetStatusAnnotation(obj)
if status == "" || status == checks.StatusAnnotationError {
// Check not processed yet or errored
return nil
}
// Get the item to retry from the annotation
itemToRetry := checks.GetRetryAnnotation(obj)
if itemToRetry == "" {
// No item to retry, nothing to do
return nil
}
c, ok := obj.(*advisorv0alpha1.Check)
if !ok {
return fmt.Errorf("invalid object type")
}
// Get the items to check
item, err := check.Item(ctx, itemToRetry)
if err != nil {
setErr := checks.SetStatusAnnotation(ctx, client, obj, checks.StatusAnnotationError)
if setErr != nil {
return setErr
}
return fmt.Errorf("error initializing check: %w", err)
}
// Run the steps
steps := check.Steps()
failures, err := runStepsInParallel(ctx, &c.Spec, steps, []any{item})
if err != nil {
setErr := checks.SetStatusAnnotation(ctx, client, obj, checks.StatusAnnotationError)
if setErr != nil {
return setErr
}
return fmt.Errorf("error running steps: %w", err)
}
// Pull failures from the report for the items to retry
c.CheckStatus.Report.Failures = slices.DeleteFunc(c.CheckStatus.Report.Failures, func(f advisorv0alpha1.CheckReportFailure) bool {
if f.ItemID == itemToRetry {
for _, newFailure := range failures {
if newFailure.StepID == f.StepID {
// Same failure found, keep it
return false
}
}
// Failure no longer found, remove it
return true
}
// Failure not in the list of items to retry, keep it
return false
})
// Delete the retry annotation to mark the check as processed
annotations := obj.GetAnnotations()
delete(annotations, checks.RetryAnnotation)
return client.PatchInto(ctx, obj.GetStaticMetadata().Identifier(), resource.PatchRequest{
Operations: []resource.PatchOperation{{
Operation: resource.PatchOpAdd,
Path: "/status/report",
Value: c.CheckStatus.Report,
}, {
Operation: resource.PatchOpAdd,
Path: "/metadata/annotations",
Value: annotations,
}},
}, resource.PatchOptions{}, obj)
}
func runStepsInParallel(ctx context.Context, spec *advisorv0alpha1.CheckSpec, steps []checks.Step, items []any) ([]advisorv0alpha1.CheckReportFailure, error) {
reportFailures := []advisorv0alpha1.CheckReportFailure{}
var internalErr error