mirror of
https://github.com/grafana/grafana.git
synced 2024-11-24 09:50:29 -06:00
Alerting: Enable interpolation for notification policies in file provisioning (#58956)
This commit is contained in:
parent
d5274dfdda
commit
41b3398eb4
@ -1,26 +1,54 @@
|
||||
package alerting
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/values"
|
||||
)
|
||||
|
||||
type NotificiationPolicyV1 struct {
|
||||
OrgID values.Int64Value `json:"orgId" yaml:"orgId"`
|
||||
Policy definitions.Route `json:",inline" yaml:",inline"`
|
||||
OrgID values.Int64Value `json:"orgId" yaml:"orgId"`
|
||||
// We use JSONValue here, as we want to have interpolation the values.
|
||||
Policy values.JSONValue `json:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
func (v1 *NotificiationPolicyV1) mapToModel() NotificiationPolicy {
|
||||
func (v1 *NotificiationPolicyV1) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
err := v1.Policy.UnmarshalYAML(unmarshal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// As we also want to unmarshal the orgId and any other field that might be
|
||||
// added in the future we create an alias type that prevents recursion
|
||||
// and just uses the default marshler.
|
||||
type plain NotificiationPolicyV1
|
||||
return unmarshal((*plain)(v1))
|
||||
}
|
||||
|
||||
func (v1 *NotificiationPolicyV1) mapToModel() (NotificiationPolicy, error) {
|
||||
orgID := v1.OrgID.Value()
|
||||
if orgID < 1 {
|
||||
orgID = 1
|
||||
}
|
||||
// we don't need any further validation here as it's done by
|
||||
// the notification policy service
|
||||
var route definitions.Route
|
||||
// We need the string json representation, so we marshal the policy back
|
||||
// as a string and interpolate it at the same time.
|
||||
data, err := json.Marshal(v1.Policy.Value())
|
||||
if err != nil {
|
||||
return NotificiationPolicy{}, err
|
||||
}
|
||||
// Now we can take the interpolated string json represtenation of the policy
|
||||
// and unmarshal it in the concrete type.
|
||||
err = json.Unmarshal(data, &route)
|
||||
if err != nil {
|
||||
return NotificiationPolicy{}, err
|
||||
}
|
||||
// We don't need any further validation here as it's done by
|
||||
// the notification policy service.
|
||||
return NotificiationPolicy{
|
||||
OrgID: orgID,
|
||||
Policy: v1.Policy,
|
||||
}
|
||||
Policy: route,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type NotificiationPolicy struct {
|
||||
|
@ -0,0 +1,37 @@
|
||||
package alerting
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNotificationPolicy(t *testing.T) {
|
||||
const (
|
||||
envKey = "NOTIFIER_EMAIL_REMINDER_FREQUENCY"
|
||||
envValue = "4h"
|
||||
)
|
||||
err := os.Setenv(envKey, envValue)
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
_ = os.Unsetenv(envKey)
|
||||
}()
|
||||
data := `orgId: 123
|
||||
receiver: test
|
||||
continue: true
|
||||
repeat_interval: ${NOTIFIER_EMAIL_REMINDER_FREQUENCY}
|
||||
`
|
||||
var model NotificiationPolicyV1
|
||||
|
||||
err = yaml.Unmarshal([]byte(data), &model)
|
||||
require.NoError(t, err)
|
||||
np, err := model.mapToModel()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(123), np.OrgID)
|
||||
require.Equal(t, "test", np.Policy.Receiver)
|
||||
require.True(t, np.Policy.Continue)
|
||||
require.Equal(t, envValue, np.Policy.RepeatInterval.String())
|
||||
}
|
@ -51,7 +51,9 @@ func (fileV1 *AlertingFileV1) MapToModel() (AlertingFile, error) {
|
||||
if err := fileV1.mapContactPoint(&alertingFile); err != nil {
|
||||
return AlertingFile{}, fmt.Errorf("failure parsing contact points: %w", err)
|
||||
}
|
||||
fileV1.mapPolicies(&alertingFile)
|
||||
if err := fileV1.mapPolicies(&alertingFile); err != nil {
|
||||
return AlertingFile{}, fmt.Errorf("failure parsing policies: %w", err)
|
||||
}
|
||||
if err := fileV1.mapMuteTimes(&alertingFile); err != nil {
|
||||
return AlertingFile{}, fmt.Errorf("failure parsing mute times: %w", err)
|
||||
}
|
||||
@ -89,13 +91,18 @@ func (fileV1 *AlertingFileV1) mapMuteTimes(alertingFile *AlertingFile) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fileV1 *AlertingFileV1) mapPolicies(alertingFile *AlertingFile) {
|
||||
func (fileV1 *AlertingFileV1) mapPolicies(alertingFile *AlertingFile) error {
|
||||
for _, npV1 := range fileV1.Policies {
|
||||
alertingFile.Policies = append(alertingFile.Policies, npV1.mapToModel())
|
||||
np, err := npV1.mapToModel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
alertingFile.Policies = append(alertingFile.Policies, np)
|
||||
}
|
||||
for _, orgIDV1 := range fileV1.ResetPolicies {
|
||||
alertingFile.ResetPolicies = append(alertingFile.ResetPolicies, OrgID(orgIDV1.Value()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fileV1 *AlertingFileV1) mapContactPoint(alertingFile *AlertingFile) error {
|
||||
|
Loading…
Reference in New Issue
Block a user