mirror of
https://github.com/grafana/grafana.git
synced 2025-01-10 08:03:58 -06:00
Alerting: Prevent inhibition rules in Grafana Alertmanager (#81712)
This commit prevents saving configurations containing inhibition rules in Grafana Alertmanager. It does not reject inhibition rules when using external Alertmanagers, such as Mimir. This meant the validation had to be put in the MultiOrgAlertmanager instead of in the validation of PostableUserConfig. We can remove this when inhibition rules are supported in Grafana Managed Alerts.
This commit is contained in:
parent
88feccf632
commit
0726c7c3fa
@ -156,6 +156,13 @@ func (moa *MultiOrgAlertmanager) gettableUserConfigFromAMConfigString(ctx contex
|
||||
}
|
||||
|
||||
func (moa *MultiOrgAlertmanager) ApplyAlertmanagerConfiguration(ctx context.Context, org int64, config definitions.PostableUserConfig) error {
|
||||
// We cannot add this validation to PostableUserConfig as that struct is used for both
|
||||
// Grafana Alertmanager (where inhibition rules are not supported) and External Alertmanagers
|
||||
// (including Mimir) where inhibition rules are supported.
|
||||
if len(config.AlertmanagerConfig.InhibitRules) > 0 {
|
||||
return errors.New("inhibition rules are not supported")
|
||||
}
|
||||
|
||||
// Get the last known working configuration
|
||||
_, err := moa.configStore.GetLatestAlertmanagerConfiguration(ctx, org)
|
||||
if err != nil {
|
||||
|
@ -10,11 +10,13 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/expr"
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
"github.com/prometheus/alertmanager/pkg/labels"
|
||||
"github.com/prometheus/common/model"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/expr"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
@ -352,3 +354,49 @@ func TestIntegrationAdminConfiguration_SendingToExternalAlertmanagers(t *testing
|
||||
}, 16*time.Second, 8*time.Second) // the sync interval is 2s so after 8s all alertmanagers (if any) most probably are started
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntegrationAdminConfiguration_CannotCreateInhibitionRules(t *testing.T) {
|
||||
testinfra.SQLiteIntegrationTest(t)
|
||||
dir, path := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{
|
||||
DisableLegacyAlerting: true,
|
||||
EnableUnifiedAlerting: true,
|
||||
AppModeProduction: true,
|
||||
})
|
||||
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
|
||||
createUser(t, store, user.CreateUserCommand{
|
||||
DefaultOrgRole: string(org.RoleAdmin),
|
||||
Password: "admin",
|
||||
Login: "admin",
|
||||
})
|
||||
client := newAlertingApiClient(grafanaListedAddr, "admin", "admin")
|
||||
|
||||
cfg := apimodels.PostableUserConfig{
|
||||
AlertmanagerConfig: apimodels.PostableApiAlertingConfig{
|
||||
Config: apimodels.Config{
|
||||
Route: &apimodels.Route{
|
||||
Receiver: "test",
|
||||
},
|
||||
InhibitRules: []config.InhibitRule{{
|
||||
SourceMatchers: config.Matchers{{
|
||||
Type: labels.MatchEqual,
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
}},
|
||||
TargetMatchers: config.Matchers{{
|
||||
Type: labels.MatchEqual,
|
||||
Name: "bar",
|
||||
Value: "baz",
|
||||
}},
|
||||
}},
|
||||
},
|
||||
Receivers: []*apimodels.PostableApiReceiver{{
|
||||
Receiver: config.Receiver{
|
||||
Name: "test",
|
||||
},
|
||||
}},
|
||||
},
|
||||
}
|
||||
ok, err := client.PostConfiguration(t, cfg)
|
||||
require.False(t, ok)
|
||||
require.EqualError(t, err, "inhibition rules are not supported")
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package alerting
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@ -341,6 +342,39 @@ func (a apiClient) UpdateAlertRuleOrgQuota(t *testing.T, orgID int64, limit int6
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
}
|
||||
|
||||
func (a apiClient) PostConfiguration(t *testing.T, c apimodels.PostableUserConfig) (bool, error) {
|
||||
t.Helper()
|
||||
|
||||
b, err := json.Marshal(c)
|
||||
require.NoError(t, err)
|
||||
|
||||
u := fmt.Sprintf("%s/api/alertmanager/grafana/config/api/v1/alerts", a.url)
|
||||
req, err := http.NewRequest(http.MethodPost, u, bytes.NewReader(b))
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
|
||||
defer func() {
|
||||
_ = resp.Body.Close()
|
||||
}()
|
||||
b, err = io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
data := struct {
|
||||
Message string `json:"message"`
|
||||
}{}
|
||||
require.NoError(t, json.Unmarshal(b, &data))
|
||||
|
||||
if resp.StatusCode == http.StatusAccepted {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, errors.New(data.Message)
|
||||
}
|
||||
|
||||
func (a apiClient) PostRulesGroupWithStatus(t *testing.T, folder string, group *apimodels.PostableRuleGroupConfig) (apimodels.UpdateRuleGroupResponse, int, string) {
|
||||
t.Helper()
|
||||
buf := bytes.Buffer{}
|
||||
|
Loading…
Reference in New Issue
Block a user