mirror of
https://github.com/grafana/grafana.git
synced 2025-02-14 17:43:35 -06:00
This PR has two steps that together create a functional dry-run capability for the migration. By enabling the feature flag alertingPreviewUpgrade when on legacy alerting it will: a. Allow all Grafana Alerting background services except for the scheduler to start (multiorg alertmanager, state manager, routes, …). b. Allow the UI to show Grafana Alerting pages alongside legacy ones (with appropriate in-app warnings that UA is not actually running). c. Show a new “Alerting Upgrade” page and register associated /api/v1/upgrade endpoints that will allow the user to upgrade their organization live without restart and present a summary of the upgrade in a table.
141 lines
5.2 KiB
Go
141 lines
5.2 KiB
Go
package api
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/grafana/grafana/pkg/api/response"
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
|
"github.com/grafana/grafana/pkg/services/ngalert/migration"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
"github.com/grafana/grafana/pkg/util"
|
|
)
|
|
|
|
type UpgradeSrv struct {
|
|
log log.Logger
|
|
upgradeService migration.UpgradeService
|
|
cfg *setting.Cfg
|
|
}
|
|
|
|
func NewUpgradeSrc(
|
|
log log.Logger,
|
|
upgradeService migration.UpgradeService,
|
|
cfg *setting.Cfg,
|
|
) *UpgradeSrv {
|
|
return &UpgradeSrv{
|
|
log: log,
|
|
upgradeService: upgradeService,
|
|
cfg: cfg,
|
|
}
|
|
}
|
|
|
|
func (srv *UpgradeSrv) RoutePostUpgradeOrg(c *contextmodel.ReqContext) response.Response {
|
|
summary, err := srv.upgradeService.MigrateOrg(c.Req.Context(), c.OrgID, c.QueryBool("skipExisting"))
|
|
if err != nil {
|
|
if errors.Is(err, migration.ErrUpgradeInProgress) {
|
|
return response.Error(http.StatusConflict, "Upgrade already in progress", err)
|
|
}
|
|
return response.Error(http.StatusInternalServerError, "Server error", err)
|
|
}
|
|
return response.JSON(http.StatusOK, summary)
|
|
}
|
|
|
|
func (srv *UpgradeSrv) RouteGetOrgUpgrade(c *contextmodel.ReqContext) response.Response {
|
|
state, err := srv.upgradeService.GetOrgMigrationState(c.Req.Context(), c.OrgID)
|
|
if err != nil {
|
|
if errors.Is(err, migration.ErrUpgradeInProgress) {
|
|
return response.Error(http.StatusConflict, "Upgrade already in progress", err)
|
|
}
|
|
return response.Error(http.StatusInternalServerError, "Server error", err)
|
|
}
|
|
return response.JSON(http.StatusOK, state)
|
|
}
|
|
|
|
func (srv *UpgradeSrv) RouteDeleteOrgUpgrade(c *contextmodel.ReqContext) response.Response {
|
|
err := srv.upgradeService.RevertOrg(c.Req.Context(), c.OrgID)
|
|
if err != nil {
|
|
if errors.Is(err, migration.ErrUpgradeInProgress) {
|
|
return response.Error(http.StatusConflict, "Upgrade already in progress", err)
|
|
}
|
|
return response.Error(http.StatusInternalServerError, "Server error", err)
|
|
}
|
|
return response.JSON(http.StatusOK, util.DynMap{"message": "Grafana Alerting resources deleted for this organization."})
|
|
}
|
|
|
|
func (srv *UpgradeSrv) RoutePostUpgradeAlert(c *contextmodel.ReqContext, dashboardIdParam string, panelIdParam string) response.Response {
|
|
dashboardId, err := strconv.ParseInt(dashboardIdParam, 10, 64)
|
|
if err != nil {
|
|
return ErrResp(http.StatusBadRequest, err, "failed to parse dashboardId")
|
|
}
|
|
|
|
panelId, err := strconv.ParseInt(panelIdParam, 10, 64)
|
|
if err != nil {
|
|
return ErrResp(http.StatusBadRequest, err, "failed to parse panelId")
|
|
}
|
|
|
|
summary, err := srv.upgradeService.MigrateAlert(c.Req.Context(), c.OrgID, dashboardId, panelId)
|
|
if err != nil {
|
|
if errors.Is(err, migration.ErrUpgradeInProgress) {
|
|
return response.Error(http.StatusConflict, "Upgrade already in progress", err)
|
|
}
|
|
return response.Error(http.StatusInternalServerError, "Server error", err)
|
|
}
|
|
return response.JSON(http.StatusOK, summary)
|
|
}
|
|
|
|
func (srv *UpgradeSrv) RoutePostUpgradeDashboard(c *contextmodel.ReqContext, dashboardIdParam string) response.Response {
|
|
dashboardId, err := strconv.ParseInt(dashboardIdParam, 10, 64)
|
|
if err != nil {
|
|
return ErrResp(http.StatusBadRequest, err, "failed to parse dashboardId")
|
|
}
|
|
|
|
summary, err := srv.upgradeService.MigrateDashboardAlerts(c.Req.Context(), c.OrgID, dashboardId, c.QueryBool("skipExisting"))
|
|
if err != nil {
|
|
if errors.Is(err, migration.ErrUpgradeInProgress) {
|
|
return response.Error(http.StatusConflict, "Upgrade already in progress", err)
|
|
}
|
|
return response.Error(http.StatusInternalServerError, "Server error", err)
|
|
}
|
|
return response.JSON(http.StatusOK, summary)
|
|
}
|
|
|
|
func (srv *UpgradeSrv) RoutePostUpgradeAllDashboards(c *contextmodel.ReqContext) response.Response {
|
|
summary, err := srv.upgradeService.MigrateAllDashboardAlerts(c.Req.Context(), c.OrgID, c.QueryBool("skipExisting"))
|
|
if err != nil {
|
|
if errors.Is(err, migration.ErrUpgradeInProgress) {
|
|
return response.Error(http.StatusConflict, "Upgrade already in progress", err)
|
|
}
|
|
return response.Error(http.StatusInternalServerError, "Server error", err)
|
|
}
|
|
return response.JSON(http.StatusOK, summary)
|
|
}
|
|
|
|
func (srv *UpgradeSrv) RoutePostUpgradeChannel(c *contextmodel.ReqContext, channelIdParam string) response.Response {
|
|
channelId, err := strconv.ParseInt(channelIdParam, 10, 64)
|
|
if err != nil {
|
|
return ErrResp(http.StatusBadRequest, err, "failed to parse channelId")
|
|
}
|
|
|
|
summary, err := srv.upgradeService.MigrateChannel(c.Req.Context(), c.OrgID, channelId)
|
|
if err != nil {
|
|
if errors.Is(err, migration.ErrUpgradeInProgress) {
|
|
return response.Error(http.StatusConflict, "Upgrade already in progress", err)
|
|
}
|
|
return response.Error(http.StatusInternalServerError, "Server error", err)
|
|
}
|
|
return response.JSON(http.StatusOK, summary)
|
|
}
|
|
|
|
func (srv *UpgradeSrv) RoutePostUpgradeAllChannels(c *contextmodel.ReqContext) response.Response {
|
|
summary, err := srv.upgradeService.MigrateAllChannels(c.Req.Context(), c.OrgID, c.QueryBool("skipExisting"))
|
|
if err != nil {
|
|
if errors.Is(err, migration.ErrUpgradeInProgress) {
|
|
return response.Error(http.StatusConflict, "Upgrade already in progress", err)
|
|
}
|
|
return response.Error(http.StatusInternalServerError, "Server error", err)
|
|
}
|
|
return response.JSON(http.StatusOK, summary)
|
|
}
|