Files
grafana/pkg/services/ngalert/api/tooling/definitions/alertmanager_validation.go
T
Matthew Jacobson 9f9c4b3da3 Alerting: Template preview enhancements (#103817)
API Changes:

- Fixes validation in template CRUD API to be closer to how the running 
  alertmanager will use the template. Should remove some incorrect 
  validation errors.

- Adds some missing default placeholder labels to receiver testing that 
  are used during template testing but missing during receiver testing


Template Preview:

- Replaced basic preview with a readonly CodeEditor for better whitespace 
  and alignment clarity (also adds support for future syntax highlighting 
  in template previews for upcoming webhook payload templates)

Template Selector (Receiver Form):

- Refactored to use same components as Template editor for preview.
- Fixed preview to work with multi-definition templates
- Fixed copy to correctly copy the template contents instead of 
  {{ template "<name>" . }}.

Template Editor:

- Fixed detection of when to display functions vs snippets in multi-line 
  expressions
2025-04-11 09:27:19 -04:00

58 lines
1.3 KiB
Go

package definitions
import (
"fmt"
"regexp"
"strings"
"github.com/prometheus/alertmanager/template"
"gopkg.in/yaml.v3"
)
func (t *NotificationTemplate) Validate() error {
if t.Name == "" {
return fmt.Errorf("template must have a name")
}
if t.Template == "" {
return fmt.Errorf("template must have content")
}
content := strings.TrimSpace(t.Template)
found, err := regexp.MatchString(`\{\{\s*define`, content)
if err != nil {
return fmt.Errorf("failed to match regex: %w", err)
}
if !found {
lines := strings.Split(content, "\n")
for i, s := range lines {
lines[i] = " " + s
}
content = strings.Join(lines, "\n")
content = fmt.Sprintf("{{ define \"%s\" }}\n%s\n{{ end }}", t.Name, content)
}
t.Template = content
// Validate template contents. We try to stick as close to what will actually happen when the templates are parsed
// by the alertmanager as possible.
tmpl, err := template.New()
if err != nil {
return fmt.Errorf("failed to create template: %w", err)
}
if err := tmpl.Parse(strings.NewReader(t.Template)); err != nil {
return fmt.Errorf("invalid template: %w", err)
}
return nil
}
func (mt *MuteTimeInterval) Validate() error {
s, err := yaml.Marshal(mt.MuteTimeInterval)
if err != nil {
return err
}
if err = yaml.Unmarshal(s, &(mt.MuteTimeInterval)); err != nil {
return err
}
return nil
}