Alerting: Remove start page of legacy upgrade preview (#82010)

Alerting: Remove start page of upgrade preview

Alerting upgrade page will now always show the summary table even before
upgrading any alerts or notification channels. There a few reasons for this:

- The information on the start page is redundant as it's now contained in the
documentation.
- Previously, if some unexpected issue prevented performing a full upgrade, a
user would have limited to no means to using the preview tool to help fix the
problem. This is because you could not see the summary table until the full
upgrade was performed at least once. Now, you can upgrade individual alerts and
notification channels from the beginning.
This commit is contained in:
Matthew Jacobson
2024-02-15 17:34:00 -05:00
committed by GitHub
parent 8de9c4c373
commit 118e4a50b7
4 changed files with 45 additions and 302 deletions

View File

@@ -35,9 +35,9 @@ func (srv *UpgradeSrv) RoutePostUpgradeOrg(c *contextmodel.ReqContext) 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 ErrResp(http.StatusConflict, err, "Upgrade already in progress")
}
return response.Error(http.StatusInternalServerError, "Server error", err)
return ErrResp(http.StatusInternalServerError, err, "Server error")
}
return response.JSON(http.StatusOK, summary)
}
@@ -46,9 +46,9 @@ func (srv *UpgradeSrv) RouteGetOrgUpgrade(c *contextmodel.ReqContext) response.R
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 ErrResp(http.StatusConflict, err, "Upgrade already in progress")
}
return response.Error(http.StatusInternalServerError, "Server error", err)
return ErrResp(http.StatusInternalServerError, err, "Server error")
}
return response.JSON(http.StatusOK, state)
}
@@ -57,9 +57,9 @@ func (srv *UpgradeSrv) RouteDeleteOrgUpgrade(c *contextmodel.ReqContext) respons
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 ErrResp(http.StatusConflict, err, "Upgrade already in progress")
}
return response.Error(http.StatusInternalServerError, "Server error", err)
return ErrResp(http.StatusInternalServerError, err, "Server error")
}
return response.JSON(http.StatusOK, util.DynMap{"message": "Grafana Alerting resources deleted for this organization."})
}
@@ -78,9 +78,9 @@ func (srv *UpgradeSrv) RoutePostUpgradeAlert(c *contextmodel.ReqContext, dashboa
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 ErrResp(http.StatusConflict, err, "Upgrade already in progress")
}
return response.Error(http.StatusInternalServerError, "Server error", err)
return ErrResp(http.StatusInternalServerError, err, "Server error")
}
return response.JSON(http.StatusOK, summary)
}
@@ -94,9 +94,9 @@ func (srv *UpgradeSrv) RoutePostUpgradeDashboard(c *contextmodel.ReqContext, das
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 ErrResp(http.StatusConflict, err, "Upgrade already in progress")
}
return response.Error(http.StatusInternalServerError, "Server error", err)
return ErrResp(http.StatusInternalServerError, err, "Server error")
}
return response.JSON(http.StatusOK, summary)
}
@@ -105,9 +105,9 @@ func (srv *UpgradeSrv) RoutePostUpgradeAllDashboards(c *contextmodel.ReqContext)
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 ErrResp(http.StatusConflict, err, "Upgrade already in progress")
}
return response.Error(http.StatusInternalServerError, "Server error", err)
return ErrResp(http.StatusInternalServerError, err, "Server error")
}
return response.JSON(http.StatusOK, summary)
}
@@ -121,9 +121,9 @@ func (srv *UpgradeSrv) RoutePostUpgradeChannel(c *contextmodel.ReqContext, chann
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 ErrResp(http.StatusConflict, err, "Upgrade already in progress")
}
return response.Error(http.StatusInternalServerError, "Server error", err)
return ErrResp(http.StatusInternalServerError, err, "Server error")
}
return response.JSON(http.StatusOK, summary)
}
@@ -132,9 +132,9 @@ func (srv *UpgradeSrv) RoutePostUpgradeAllChannels(c *contextmodel.ReqContext) r
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 ErrResp(http.StatusConflict, err, "Upgrade already in progress")
}
return response.Error(http.StatusInternalServerError, "Server error", err)
return ErrResp(http.StatusInternalServerError, err, "Server error")
}
return response.JSON(http.StatusOK, summary)
}

View File

@@ -73,13 +73,23 @@ func ProvideService(
type operation func(ctx context.Context) (*definitions.OrgMigrationSummary, error)
// verifyTry verifies that the org has been migrated, and then attempts to execute the operation. If another operation
// is already in progress, ErrUpgradeInProgress will be returned.
func (ms *migrationService) verifyTry(ctx context.Context, orgID int64, op operation) (definitions.OrgMigrationSummary, error) {
if err := ms.verifyMigrated(ctx, orgID); err != nil {
return definitions.OrgMigrationSummary{}, err
// tryAndSet attempts to execute the operation and then sets the migrated status to true.
// If another operation is already in progress, ErrUpgradeInProgress will be returned
func (ms *migrationService) tryAndSet(ctx context.Context, orgID int64, op operation) (definitions.OrgMigrationSummary, error) {
opAndSet := func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
s, err := op(ctx)
if err != nil {
return nil, err
}
err = ms.migrationStore.SetMigrated(ctx, orgID, true)
if err != nil {
return nil, fmt.Errorf("setting migration status: %w", err)
}
return s, nil
}
return ms.try(ctx, op)
return ms.try(ctx, opAndSet)
}
// try attempts to execute the operation. If another operation is already in progress, ErrUpgradeInProgress will be returned.
@@ -110,7 +120,7 @@ func (ms *migrationService) try(ctx context.Context, op operation) (definitions.
// MigrateChannel migrates a single legacy notification channel to a unified alerting contact point.
func (ms *migrationService) MigrateChannel(ctx context.Context, orgID int64, channelID int64) (definitions.OrgMigrationSummary, error) {
return ms.verifyTry(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
return ms.tryAndSet(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
summary := definitions.OrgMigrationSummary{}
om := ms.newOrgMigration(orgID)
oldState, err := om.migrationStore.GetOrgMigrationState(ctx, orgID)
@@ -161,7 +171,7 @@ func (ms *migrationService) MigrateChannel(ctx context.Context, orgID int64, cha
// MigrateAllChannels migrates all legacy notification channel to unified alerting contact points.
func (ms *migrationService) MigrateAllChannels(ctx context.Context, orgID int64, skipExisting bool) (definitions.OrgMigrationSummary, error) {
return ms.verifyTry(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
return ms.tryAndSet(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
summary := definitions.OrgMigrationSummary{}
om := ms.newOrgMigration(orgID)
pairs, err := om.migrateOrgChannels(ctx)
@@ -181,7 +191,7 @@ func (ms *migrationService) MigrateAllChannels(ctx context.Context, orgID int64,
// MigrateAlert migrates a single dashboard alert from legacy alerting to unified alerting.
func (ms *migrationService) MigrateAlert(ctx context.Context, orgID int64, dashboardID int64, panelID int64) (definitions.OrgMigrationSummary, error) {
return ms.verifyTry(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
return ms.tryAndSet(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
summary := definitions.OrgMigrationSummary{}
om := ms.newOrgMigration(orgID)
oldState, err := om.migrationStore.GetOrgMigrationState(ctx, orgID)
@@ -238,7 +248,7 @@ func (ms *migrationService) MigrateAlert(ctx context.Context, orgID int64, dashb
// MigrateDashboardAlerts migrates all legacy dashboard alerts from a single dashboard to unified alerting.
func (ms *migrationService) MigrateDashboardAlerts(ctx context.Context, orgID int64, dashboardID int64, skipExisting bool) (definitions.OrgMigrationSummary, error) {
return ms.verifyTry(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
return ms.tryAndSet(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
summary := definitions.OrgMigrationSummary{}
om := ms.newOrgMigration(orgID)
alerts, err := ms.migrationStore.GetDashboardAlerts(ctx, orgID, dashboardID)
@@ -259,7 +269,7 @@ func (ms *migrationService) MigrateDashboardAlerts(ctx context.Context, orgID in
// MigrateAllDashboardAlerts migrates all legacy alerts to unified alerting contact points.
func (ms *migrationService) MigrateAllDashboardAlerts(ctx context.Context, orgID int64, skipExisting bool) (definitions.OrgMigrationSummary, error) {
return ms.verifyTry(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
return ms.tryAndSet(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
summary := definitions.OrgMigrationSummary{}
om := ms.newOrgMigration(orgID)
dashboardUpgrades, err := om.migrateOrgAlerts(ctx)
@@ -279,7 +289,7 @@ func (ms *migrationService) MigrateAllDashboardAlerts(ctx context.Context, orgID
// MigrateOrg executes the migration for a single org.
func (ms *migrationService) MigrateOrg(ctx context.Context, orgID int64, skipExisting bool) (definitions.OrgMigrationSummary, error) {
return ms.try(ctx, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
return ms.tryAndSet(ctx, orgID, func(ctx context.Context) (*definitions.OrgMigrationSummary, error) {
summary := definitions.OrgMigrationSummary{}
ms.log.Info("Starting legacy migration for org", "orgId", orgID, "skipExisting", skipExisting)
om := ms.newOrgMigration(orgID)
@@ -293,11 +303,6 @@ func (ms *migrationService) MigrateOrg(ctx context.Context, orgID int64, skipExi
return nil, err
}
err = ms.migrationStore.SetMigrated(ctx, orgID, true)
if err != nil {
return nil, fmt.Errorf("setting migration status: %w", err)
}
summary.Add(s)
return &summary, nil
})
@@ -306,9 +311,6 @@ func (ms *migrationService) MigrateOrg(ctx context.Context, orgID int64, skipExi
// GetOrgMigrationState returns the current migration state for an org. This is a potentially expensive operation as it
// requires re-hydrating the entire migration state from the database against all current alerting resources.
func (ms *migrationService) GetOrgMigrationState(ctx context.Context, orgID int64) (*definitions.OrgMigrationState, error) {
if migrated, err := ms.migrationStore.IsMigrated(ctx, orgID); err != nil || !migrated {
return &definitions.OrgMigrationState{OrgID: orgID}, err
}
dState, err := ms.migrationStore.GetOrgMigrationState(ctx, orgID)
if err != nil {
return nil, err
@@ -525,18 +527,6 @@ func (ms *migrationService) RevertAllOrgs(ctx context.Context) error {
return err
}
// verifyMigrated returns an error if the org has not been migrated.
func (ms *migrationService) verifyMigrated(ctx context.Context, orgID int64) error {
migrated, err := ms.migrationStore.IsMigrated(ctx, orgID)
if err != nil {
return fmt.Errorf("check if migrated: %w", err)
}
if !migrated {
return fmt.Errorf("not migrated")
}
return nil
}
// fromDashboardUpgrades converts DashboardUpgrades to their api representation. This requires rehydrating information
// from the database for the current state of dashboards, alerts, and rules.
func (ms *migrationService) fromDashboardUpgrades(ctx context.Context, orgID int64, migratedDashboards map[int64]*migrationStore.DashboardUpgrade, amConfig *migmodels.Alertmanager) ([]*definitions.DashboardUpgrade, error) {
@@ -616,7 +606,7 @@ func (ms *migrationService) fromDashboardUpgrades(ctx context.Context, orgID int
} else {
// We could potentially set an error here, but it's not really an error. It just means that the
// user deleted the migrated rule after the migration. This could just as easily be intentional.
ms.log.Info("Could not find rule for migrated alert", "alertId", a.ID, "ruleUid", p.NewRuleUID)
ms.log.Debug("Could not find rule for migrated alert", "alertId", a.ID, "ruleUid", p.NewRuleUID)
}
}
}