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
@@ -0,0 +1,125 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrations/ualert"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddExternalAlertmanagerToDatasourceMigration(mg *migrator.Migrator) {
|
||||
mg.AddMigration("migrate external alertmanagers to datsourcse", &externalAlertmanagerToDatasources{})
|
||||
}
|
||||
|
||||
type externalAlertmanagerToDatasources struct {
|
||||
migrator.MigrationBase
|
||||
}
|
||||
|
||||
type AdminConfiguration struct {
|
||||
OrgID int64 `xorm:"org_id"`
|
||||
|
||||
Alertmanagers []string
|
||||
|
||||
CreatedAt int64 `xorm:"created_at"`
|
||||
UpdatedAt int64 `xorm:"updated_at"`
|
||||
}
|
||||
|
||||
func (e externalAlertmanagerToDatasources) SQL(dialect migrator.Dialect) string {
|
||||
return "migrate external alertmanagers to datasource"
|
||||
}
|
||||
|
||||
func (e externalAlertmanagerToDatasources) Exec(sess *xorm.Session, mg *migrator.Migrator) error {
|
||||
var results []AdminConfiguration
|
||||
err := sess.SQL("SELECT org_id, alertmanagers, created_at, updated_at FROM ngalert_configuration").Find(&results)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, result := range results {
|
||||
for _, am := range removeDuplicates(result.Alertmanagers) {
|
||||
u, err := url.Parse(am)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uri := fmt.Sprintf("%s://%s%s", u.Scheme, u.Host, u.Path)
|
||||
|
||||
uid, err := generateNewDatasourceUid(sess, result.OrgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ds := &datasources.DataSource{
|
||||
OrgId: result.OrgID,
|
||||
Name: fmt.Sprintf("alertmanager-%s", uid),
|
||||
Type: "alertmanager",
|
||||
Access: "proxy",
|
||||
Url: uri,
|
||||
Created: time.Unix(result.CreatedAt, 0),
|
||||
Updated: time.Unix(result.UpdatedAt, 0),
|
||||
Uid: uid,
|
||||
Version: 1,
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
"handleGrafanaManagedAlerts": true,
|
||||
"implementation": "prometheus",
|
||||
}),
|
||||
SecureJsonData: map[string][]byte{},
|
||||
}
|
||||
|
||||
if u.User != nil {
|
||||
ds.BasicAuth = true
|
||||
ds.BasicAuthUser = u.User.Username()
|
||||
if password, ok := u.User.Password(); ok {
|
||||
ds.SecureJsonData = ualert.GetEncryptedJsonData(map[string]string{
|
||||
"basicAuthPassword": password,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
rowsAffected, err := sess.Table("data_source").Insert(ds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
return fmt.Errorf("expected 1 row, got %d", rowsAffected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeDuplicates(strs []string) []string {
|
||||
var res []string
|
||||
found := map[string]bool{}
|
||||
|
||||
for _, str := range strs {
|
||||
if found[str] {
|
||||
continue
|
||||
}
|
||||
found[str] = true
|
||||
res = append(res, str)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func generateNewDatasourceUid(sess *xorm.Session, orgId int64) (string, error) {
|
||||
for i := 0; i < 3; i++ {
|
||||
uid := util.GenerateShortUID()
|
||||
|
||||
exists, err := sess.Table("data_source").Where("uid = ? AND org_id = ?", uid, orgId).Exist()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return uid, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", datasources.ErrDataSourceFailedGenerateUniqueUid
|
||||
}
|
||||
@@ -105,6 +105,8 @@ func (*OSSMigrations) AddMigration(mg *Migrator) {
|
||||
accesscontrol.AddSeedAssignmentMigrations(mg)
|
||||
accesscontrol.AddManagedFolderAlertActionsRepeatFixedMigration(mg)
|
||||
|
||||
AddExternalAlertmanagerToDatasourceMigration(mg)
|
||||
|
||||
// TODO: This migration will be enabled later in the nested folder feature
|
||||
// implementation process. It is on hold so we can continue working on the
|
||||
// store implementation without impacting any grafana instances built off
|
||||
|
||||
Reference in New Issue
Block a user