dd0a2d4cff
This moves some of the validation logic for rule groups from the legacy storage layer to the validator.
60 lines
2.3 KiB
Go
60 lines
2.3 KiB
Go
package util
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"github.com/grafana/grafana-app-sdk/resource"
|
|
model "github.com/grafana/grafana/apps/alerting/rules/pkg/apis/alerting/v0alpha1"
|
|
)
|
|
|
|
// ValidateGroupLabels enforces the cross-field rules for group-related labels.
|
|
//
|
|
// Rules enforced:
|
|
// - On create, group-related labels must not be set.
|
|
// - If one of group or group-index is set, the other must also be set.
|
|
// - group-index must be an integer.
|
|
// - On update, group/group-index can only be present if they were present on the old object.
|
|
//
|
|
// Pass current labels and, when available, the previous object's labels. The previous labels
|
|
// may be nil when there is no old object (e.g., create operations).
|
|
func ValidateGroupLabels(labels map[string]string, oldLabels map[string]string, action resource.AdmissionAction) error {
|
|
groupStr, groupExists := labels[model.GroupLabelKey]
|
|
groupIndexStr, groupIndexStrExists := labels[model.GroupIndexLabelKey]
|
|
|
|
if groupExists || groupIndexStrExists {
|
|
if action == resource.AdmissionActionCreate {
|
|
return fmt.Errorf("cannot set group when creating a new rule")
|
|
}
|
|
if groupExists && !groupIndexStrExists {
|
|
return fmt.Errorf("%s must be set when %s is set", model.GroupIndexLabelKey, model.GroupLabelKey)
|
|
}
|
|
if groupIndexStrExists && !groupExists {
|
|
return fmt.Errorf("%s must be set when %s is set", model.GroupLabelKey, model.GroupIndexLabelKey)
|
|
}
|
|
// Disallow empty values when labels are present
|
|
if groupExists && groupStr == "" {
|
|
return fmt.Errorf("%s cannot be empty", model.GroupLabelKey)
|
|
}
|
|
if groupIndexStrExists && groupIndexStr == "" {
|
|
return fmt.Errorf("%s cannot be empty", model.GroupIndexLabelKey)
|
|
}
|
|
if _, err := strconv.Atoi(groupIndexStr); err != nil {
|
|
return fmt.Errorf("invalid %s: %w", model.GroupIndexLabelKey, err)
|
|
}
|
|
|
|
// On updates, ensure that group and group-index are only set if the old object had them set
|
|
if oldLabels != nil {
|
|
_, oldGroupExists := oldLabels[model.GroupLabelKey]
|
|
_, oldGroupIndexExists := oldLabels[model.GroupIndexLabelKey]
|
|
if groupExists && !oldGroupExists {
|
|
return fmt.Errorf("cannot set group when updating un-grouped rule")
|
|
}
|
|
if groupIndexStrExists && !oldGroupIndexExists {
|
|
return fmt.Errorf("cannot set group-index when updating un-grouped rule")
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|