Alerting: Remove url based external alertmanagers config (#57918)

* Remove URL-based alertmanagers from endpoint config

* WIP

* Add migration and alertmanagers from admin_configuration

* Empty comment removed

* set BasicAuth true when user is present in url

* Remove Alertmanagers from GET /admin_config payload

* Remove URL-based alertmanager configuration from UI

* Fix new uid generation in external alertmanagers migration

* Fix tests for URL-based external alertmanagers

* Fix API tests

* Add more tests, move migration code to separate file, and remove possible am duplicate urls

* Fix edge cases in migration

* Fix imports

* Remove useless fields and fix created_at/updated_at retrieval

Co-authored-by: George Robinson <george.robinson@grafana.com>
Co-authored-by: Konrad Lalik <konrad.lalik@grafana.com>
This commit is contained in:
Alex Moreno
2022-11-10 16:34:13 +01:00
committed by GitHub
parent 738e023d13
commit 45facbba11
21 changed files with 411 additions and 796 deletions

View File

@@ -12,6 +12,8 @@ import (
"github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"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"
"github.com/grafana/grafana/pkg/services/ngalert/sender"
@@ -111,11 +113,64 @@ func TestAdminConfiguration_SendingToExternalAlertmanagers(t *testing.T) {
require.Equal(t, "At least one Alertmanager must be provided or configured as a datasource that handles alerts to choose this option", res["message"])
}
// Add an alertmanager datasource
{
cmd := datasources.AddDataSourceCommand{
OrgId: 1,
Name: "AM1",
Type: datasources.DS_ALERTMANAGER,
Access: "proxy",
Url: fakeAM1.URL(),
JsonData: simplejson.NewFromAny(map[string]interface{}{
"handleGrafanaManagedAlerts": true,
"implementation": "prometheus",
}),
}
buf := bytes.Buffer{}
enc := json.NewEncoder(&buf)
err := enc.Encode(&cmd)
require.NoError(t, err)
dataSourcesUrl := fmt.Sprintf("http://grafana:password@%s/api/datasources", grafanaListedAddr)
resp := postRequest(t, dataSourcesUrl, buf.String(), http.StatusOK) // nolint
b, err := io.ReadAll(resp.Body)
require.NoError(t, err)
var res map[string]interface{}
err = json.Unmarshal(b, &res)
require.NoError(t, err)
require.Equal(t, "Datasource added", res["message"])
}
// Add another alertmanager datasource
{
cmd := datasources.AddDataSourceCommand{
OrgId: 1,
Name: "AM2",
Type: datasources.DS_ALERTMANAGER,
Access: "proxy",
Url: fakeAM2.URL(),
JsonData: simplejson.NewFromAny(map[string]interface{}{
"handleGrafanaManagedAlerts": true,
"implementation": "prometheus",
}),
}
buf := bytes.Buffer{}
enc := json.NewEncoder(&buf)
err := enc.Encode(&cmd)
require.NoError(t, err)
dataSourcesUrl := fmt.Sprintf("http://grafana:password@%s/api/datasources", grafanaListedAddr)
resp := postRequest(t, dataSourcesUrl, buf.String(), http.StatusOK) // nolint
b, err := io.ReadAll(resp.Body)
require.NoError(t, err)
var res map[string]interface{}
err = json.Unmarshal(b, &res)
require.NoError(t, err)
require.Equal(t, "Datasource added", res["message"])
}
// Now, lets re-set external Alertmanagers for main organisation
// and make it so that only the external Alertmanagers handle the alerts.
{
ac := apimodels.PostableNGalertConfig{
Alertmanagers: []string{fakeAM1.URL(), fakeAM2.URL()},
AlertmanagersChoice: apimodels.AlertmanagersChoice(ngmodels.ExternalAlertmanagers.String()),
}
buf := bytes.Buffer{}
@@ -139,7 +194,7 @@ func TestAdminConfiguration_SendingToExternalAlertmanagers(t *testing.T) {
resp := getRequest(t, alertsURL, http.StatusOK) // nolint
b, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.JSONEq(t, fmt.Sprintf("{\"alertmanagers\":[\"%s\",\"%s\"], \"alertmanagersChoice\": %q}\n", fakeAM1.URL(), fakeAM2.URL(), ngmodels.ExternalAlertmanagers), string(b))
require.JSONEq(t, fmt.Sprintf("{\"alertmanagersChoice\": %q}\n", ngmodels.ExternalAlertmanagers), string(b))
}
// With the configuration set, we should eventually discover those Alertmanagers.
@@ -214,12 +269,37 @@ func TestAdminConfiguration_SendingToExternalAlertmanagers(t *testing.T) {
}, 60*time.Second, 5*time.Second)
}
// Add an alertmanager datasource fot the other organisation
{
cmd := datasources.AddDataSourceCommand{
OrgId: 2,
Name: "AM3",
Type: datasources.DS_ALERTMANAGER,
Access: "proxy",
Url: fakeAM3.URL(),
JsonData: simplejson.NewFromAny(map[string]interface{}{
"handleGrafanaManagedAlerts": true,
"implementation": "prometheus",
}),
}
buf := bytes.Buffer{}
enc := json.NewEncoder(&buf)
err := enc.Encode(&cmd)
require.NoError(t, err)
dataSourcesUrl := fmt.Sprintf("http://admin-42:admin-42@%s/api/datasources", grafanaListedAddr)
resp := postRequest(t, dataSourcesUrl, buf.String(), http.StatusOK) // nolint
b, err := io.ReadAll(resp.Body)
require.NoError(t, err)
var res map[string]interface{}
err = json.Unmarshal(b, &res)
require.NoError(t, err)
require.Equal(t, "Datasource added", res["message"])
}
// Now, lets re-set external Alertmanagers for the other organisation.
// Sending an empty value for AlertmanagersChoice should default to AllAlertmanagers.
{
ac := apimodels.PostableNGalertConfig{
Alertmanagers: []string{fakeAM3.URL()},
}
ac := apimodels.PostableNGalertConfig{}
buf := bytes.Buffer{}
enc := json.NewEncoder(&buf)
err := enc.Encode(&ac)
@@ -241,7 +321,7 @@ func TestAdminConfiguration_SendingToExternalAlertmanagers(t *testing.T) {
resp := getRequest(t, alertsURL, http.StatusOK) // nolint
b, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.JSONEq(t, fmt.Sprintf("{\"alertmanagers\":[\"%s\"], \"alertmanagersChoice\": %q}\n", fakeAM3.URL(), ngmodels.AllAlertmanagers), string(b))
require.JSONEq(t, fmt.Sprintf("{\"alertmanagersChoice\": %q}\n", ngmodels.AllAlertmanagers), string(b))
}
// With the configuration set, we should eventually not discover Alertmanagers.