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:
co-authored by
George Robinson
Konrad Lalik
parent
738e023d13
commit
45facbba11
@@ -60,7 +60,6 @@ func (srv ConfigSrv) RouteGetNGalertConfig(c *models.ReqContext) response.Respon
|
||||
}
|
||||
|
||||
resp := apimodels.GettableNGalertConfig{
|
||||
Alertmanagers: cfg.Alertmanagers,
|
||||
AlertmanagersChoice: apimodels.AlertmanagersChoice(cfg.SendAlertsTo.String()),
|
||||
}
|
||||
return response.JSON(http.StatusOK, resp)
|
||||
@@ -81,21 +80,13 @@ func (srv ConfigSrv) RoutePostNGalertConfig(c *models.ReqContext, body apimodels
|
||||
return response.Error(500, "Couldn't fetch the external Alertmanagers from datasources", err)
|
||||
}
|
||||
|
||||
if sendAlertsTo == ngmodels.ExternalAlertmanagers &&
|
||||
len(body.Alertmanagers)+len(externalAlertmanagers) < 1 {
|
||||
if sendAlertsTo == ngmodels.ExternalAlertmanagers && len(externalAlertmanagers) < 1 {
|
||||
return response.Error(400, "At least one Alertmanager must be provided or configured as a datasource that handles alerts to choose this option", nil)
|
||||
}
|
||||
|
||||
cfg := &ngmodels.AdminConfiguration{
|
||||
Alertmanagers: body.Alertmanagers,
|
||||
SendAlertsTo: sendAlertsTo,
|
||||
OrgID: c.OrgID,
|
||||
}
|
||||
|
||||
if err := cfg.Validate(); err != nil {
|
||||
msg := "failed to validate admin configuration"
|
||||
srv.log.Error(msg, "error", err)
|
||||
return ErrResp(http.StatusBadRequest, err, msg)
|
||||
SendAlertsTo: sendAlertsTo,
|
||||
OrgID: c.OrgID,
|
||||
}
|
||||
|
||||
cmd := store.UpdateAdminConfigurationCmd{AdminConfiguration: cfg}
|
||||
|
||||
@@ -18,23 +18,13 @@ func TestExternalAlertmanagerChoice(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
alertmanagerChoice definitions.AlertmanagersChoice
|
||||
alertmanagers []string
|
||||
datasources []*datasources.DataSource
|
||||
statusCode int
|
||||
message string
|
||||
}{
|
||||
{
|
||||
name: "setting the choice to external by passing a plain url should succeed",
|
||||
alertmanagerChoice: definitions.ExternalAlertmanagers,
|
||||
alertmanagers: []string{"http://localhost:9000"},
|
||||
datasources: []*datasources.DataSource{},
|
||||
statusCode: http.StatusCreated,
|
||||
message: "admin configuration updated",
|
||||
},
|
||||
{
|
||||
name: "setting the choice to external by having a enabled external am datasource should succeed",
|
||||
alertmanagerChoice: definitions.ExternalAlertmanagers,
|
||||
alertmanagers: []string{},
|
||||
datasources: []*datasources.DataSource{
|
||||
{
|
||||
OrgId: 1,
|
||||
@@ -51,7 +41,6 @@ func TestExternalAlertmanagerChoice(t *testing.T) {
|
||||
{
|
||||
name: "setting the choice to external by having a disabled external am datasource should fail",
|
||||
alertmanagerChoice: definitions.ExternalAlertmanagers,
|
||||
alertmanagers: []string{},
|
||||
datasources: []*datasources.DataSource{
|
||||
{
|
||||
OrgId: 1,
|
||||
@@ -66,7 +55,6 @@ func TestExternalAlertmanagerChoice(t *testing.T) {
|
||||
{
|
||||
name: "setting the choice to external and having no am configured should fail",
|
||||
alertmanagerChoice: definitions.ExternalAlertmanagers,
|
||||
alertmanagers: []string{},
|
||||
datasources: []*datasources.DataSource{},
|
||||
statusCode: http.StatusBadRequest,
|
||||
message: "At least one Alertmanager must be provided or configured as a datasource that handles alerts to choose this option",
|
||||
@@ -74,7 +62,6 @@ func TestExternalAlertmanagerChoice(t *testing.T) {
|
||||
{
|
||||
name: "setting the choice to all and having no external am configured should succeed",
|
||||
alertmanagerChoice: definitions.AllAlertmanagers,
|
||||
alertmanagers: []string{},
|
||||
datasources: []*datasources.DataSource{},
|
||||
statusCode: http.StatusCreated,
|
||||
message: "admin configuration updated",
|
||||
@@ -82,7 +69,6 @@ func TestExternalAlertmanagerChoice(t *testing.T) {
|
||||
{
|
||||
name: "setting the choice to internal should always succeed",
|
||||
alertmanagerChoice: definitions.InternalAlertmanager,
|
||||
alertmanagers: []string{},
|
||||
datasources: []*datasources.DataSource{},
|
||||
statusCode: http.StatusCreated,
|
||||
message: "admin configuration updated",
|
||||
@@ -94,7 +80,6 @@ func TestExternalAlertmanagerChoice(t *testing.T) {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
sut := createAPIAdminSut(t, test.datasources)
|
||||
resp := sut.RoutePostNGalertConfig(ctx, definitions.PostableNGalertConfig{
|
||||
Alertmanagers: test.alertmanagers,
|
||||
AlertmanagersChoice: test.alertmanagerChoice,
|
||||
})
|
||||
var res map[string]interface{}
|
||||
|
||||
@@ -395,11 +395,6 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"DsPermissionType": {
|
||||
"description": "Datasource permission\nDescription:\n`0` - No Access\n`1` - Query\nEnum: 0,1",
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"Duration": {
|
||||
"format": "int64",
|
||||
"title": "Duration is a type used for marshalling durations.",
|
||||
@@ -1046,12 +1041,6 @@
|
||||
},
|
||||
"GettableNGalertConfig": {
|
||||
"properties": {
|
||||
"alertmanagers": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"alertmanagersChoice": {
|
||||
"enum": [
|
||||
"all",
|
||||
@@ -1984,12 +1973,6 @@
|
||||
},
|
||||
"PostableNGalertConfig": {
|
||||
"properties": {
|
||||
"alertmanagers": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"alertmanagersChoice": {
|
||||
"enum": [
|
||||
"all",
|
||||
@@ -3097,9 +3080,6 @@
|
||||
"Host": {
|
||||
"type": "string"
|
||||
},
|
||||
"OmitHost": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Opaque": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -3301,7 +3281,6 @@
|
||||
"type": "object"
|
||||
},
|
||||
"alertGroups": {
|
||||
"description": "AlertGroups alert groups",
|
||||
"items": {
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
@@ -3462,7 +3441,6 @@
|
||||
"type": "object"
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
@@ -3667,6 +3645,7 @@
|
||||
"type": "array"
|
||||
},
|
||||
"postableSilence": {
|
||||
"description": "PostableSilence postable silence",
|
||||
"properties": {
|
||||
"comment": {
|
||||
"description": "comment",
|
||||
|
||||
@@ -76,13 +76,11 @@ const (
|
||||
|
||||
// swagger:model
|
||||
type PostableNGalertConfig struct {
|
||||
Alertmanagers []string `json:"alertmanagers"`
|
||||
AlertmanagersChoice AlertmanagersChoice `json:"alertmanagersChoice"`
|
||||
}
|
||||
|
||||
// swagger:model
|
||||
type GettableNGalertConfig struct {
|
||||
Alertmanagers []string `json:"alertmanagers"`
|
||||
AlertmanagersChoice AlertmanagersChoice `json:"alertmanagersChoice"`
|
||||
}
|
||||
|
||||
|
||||
@@ -395,11 +395,6 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"DsPermissionType": {
|
||||
"description": "Datasource permission\nDescription:\n`0` - No Access\n`1` - Query\nEnum: 0,1",
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"Duration": {
|
||||
"format": "int64",
|
||||
"title": "Duration is a type used for marshalling durations.",
|
||||
@@ -1046,12 +1041,6 @@
|
||||
},
|
||||
"GettableNGalertConfig": {
|
||||
"properties": {
|
||||
"alertmanagers": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"alertmanagersChoice": {
|
||||
"enum": [
|
||||
"all",
|
||||
@@ -1984,12 +1973,6 @@
|
||||
},
|
||||
"PostableNGalertConfig": {
|
||||
"properties": {
|
||||
"alertmanagers": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"alertmanagersChoice": {
|
||||
"enum": [
|
||||
"all",
|
||||
@@ -3087,6 +3070,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
"URL": {
|
||||
"description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
|
||||
"properties": {
|
||||
"ForceQuery": {
|
||||
"type": "boolean"
|
||||
@@ -3097,9 +3081,6 @@
|
||||
"Host": {
|
||||
"type": "string"
|
||||
},
|
||||
"OmitHost": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Opaque": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -3122,7 +3103,7 @@
|
||||
"$ref": "#/definitions/Userinfo"
|
||||
}
|
||||
},
|
||||
"title": "URL is a custom URL type that allows validation at configuration load time.",
|
||||
"title": "A URL represents a parsed URL (technically, a URI reference).",
|
||||
"type": "object"
|
||||
},
|
||||
"Userinfo": {
|
||||
@@ -3302,6 +3283,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
"alertGroups": {
|
||||
"description": "AlertGroups alert groups",
|
||||
"items": {
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
@@ -3406,7 +3388,6 @@
|
||||
"type": "object"
|
||||
},
|
||||
"gettableAlert": {
|
||||
"description": "GettableAlert gettable alert",
|
||||
"properties": {
|
||||
"annotations": {
|
||||
"$ref": "#/definitions/labelSet"
|
||||
@@ -3462,13 +3443,13 @@
|
||||
"type": "object"
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"gettableSilence": {
|
||||
"description": "GettableSilence gettable silence",
|
||||
"properties": {
|
||||
"comment": {
|
||||
"description": "comment",
|
||||
@@ -3517,14 +3498,12 @@
|
||||
"type": "object"
|
||||
},
|
||||
"gettableSilences": {
|
||||
"description": "GettableSilences gettable silences",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableSilence"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"integration": {
|
||||
"description": "Integration integration",
|
||||
"properties": {
|
||||
"lastNotifyAttempt": {
|
||||
"description": "A timestamp indicating the last attempt to deliver a notification regardless of the outcome.\nFormat: date-time",
|
||||
@@ -3668,6 +3647,7 @@
|
||||
"type": "array"
|
||||
},
|
||||
"postableSilence": {
|
||||
"description": "PostableSilence postable silence",
|
||||
"properties": {
|
||||
"comment": {
|
||||
"description": "comment",
|
||||
|
||||
@@ -2828,11 +2828,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"DsPermissionType": {
|
||||
"description": "Datasource permission\nDescription:\n`0` - No Access\n`1` - Query\nEnum: 0,1",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"Duration": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
@@ -3483,12 +3478,6 @@
|
||||
"GettableNGalertConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"alertmanagers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"alertmanagersChoice": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@@ -4422,12 +4411,6 @@
|
||||
"PostableNGalertConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"alertmanagers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"alertmanagersChoice": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@@ -5524,8 +5507,9 @@
|
||||
}
|
||||
},
|
||||
"URL": {
|
||||
"description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
|
||||
"type": "object",
|
||||
"title": "URL is a custom URL type that allows validation at configuration load time.",
|
||||
"title": "A URL represents a parsed URL (technically, a URI reference).",
|
||||
"properties": {
|
||||
"ForceQuery": {
|
||||
"type": "boolean"
|
||||
@@ -5536,9 +5520,6 @@
|
||||
"Host": {
|
||||
"type": "string"
|
||||
},
|
||||
"OmitHost": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Opaque": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -5740,6 +5721,7 @@
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
"alertGroups": {
|
||||
"description": "AlertGroups alert groups",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
@@ -5845,7 +5827,6 @@
|
||||
}
|
||||
},
|
||||
"gettableAlert": {
|
||||
"description": "GettableAlert gettable alert",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"labels",
|
||||
@@ -5902,7 +5883,6 @@
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
@@ -5910,6 +5890,7 @@
|
||||
"$ref": "#/definitions/gettableAlerts"
|
||||
},
|
||||
"gettableSilence": {
|
||||
"description": "GettableSilence gettable silence",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"comment",
|
||||
@@ -5959,7 +5940,6 @@
|
||||
"$ref": "#/definitions/gettableSilence"
|
||||
},
|
||||
"gettableSilences": {
|
||||
"description": "GettableSilences gettable silences",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableSilence"
|
||||
@@ -5967,7 +5947,6 @@
|
||||
"$ref": "#/definitions/gettableSilences"
|
||||
},
|
||||
"integration": {
|
||||
"description": "Integration integration",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
@@ -6112,6 +6091,7 @@
|
||||
}
|
||||
},
|
||||
"postableSilence": {
|
||||
"description": "PostableSilence postable silence",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"comment",
|
||||
|
||||
Reference in New Issue
Block a user