mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 10:20:29 -06:00
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:
parent
8de9c4c373
commit
118e4a50b7
@ -59,7 +59,7 @@ When upgrading with either method, your legacy dashboard alerts and notification
|
||||
|
||||
In **Alerts & IRM**, the **Alerting** section provides a preview of Grafana Alerting where you can review and modify your upgraded alerts before finalizing the upgrade.
|
||||
|
||||
In the **Alerting (legacy) -> Alerting upgrade** section, you can initiate the process to automatically upgrade your existing alert rules and notification channels, and view a summary of the upgrade to Grafana Alerting.
|
||||
In the **Alerting (legacy) -> Alerting upgrade** section, you can upgrade your existing alert rules and notification channels, and view a summary of the upgrade to Grafana Alerting.
|
||||
|
||||
Finalize your upgrade by restarting Grafana with the `[unified_alerting]` section enabled in your configuration.
|
||||
|
||||
@ -70,8 +70,8 @@ Alerts generated by the new alerting system are visible in the **Alerting** sect
|
||||
### To upgrade with preview, complete the following steps.
|
||||
|
||||
1. **Preview the Upgrade**:
|
||||
- **Initiate the process**: Access the upgrade functionality within Grafana by visiting the **Alerting upgrade** page in the **Alerting (legacy)** section of the navigation panel. Click on "Preview upgrade" to initiate the process. This will automatically upgrade your existing alert rules and notification channels to the new Grafana Alerting system.
|
||||
- **Review the summary table:** Review the detailed table outlining how your existing alert rules and notification channels were mapped to resources in the new Grafana Alerting system.
|
||||
- **Initiate the process**: Access the upgrade functionality within Grafana by visiting the **Alerting upgrade** page in the **Alerting (legacy)** section of the navigation panel. From this page you can upgrade your existing alert rules and notification channels to the new Grafana Alerting system.
|
||||
- **Review the summary table:** Review the detailed table outlining how your existing alert rules and notification channels were upgraded to resources in the new Grafana Alerting system.
|
||||
2. **Investigate and Resolve Errors**:
|
||||
- **Identify errors**: Carefully examine the previewed upgrade:
|
||||
- Any alert rules or notification channels that couldn't be automatically upgraded will be highlighted with error indicators.
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,12 @@ import { useLocation } from 'react-router-dom';
|
||||
import { useLocalStorage } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2, UrlQueryMap } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Stack } from '@grafana/experimental';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import {
|
||||
Alert,
|
||||
Badge,
|
||||
Button,
|
||||
CallToActionCard,
|
||||
ConfirmModal,
|
||||
FilterInput,
|
||||
HorizontalGroup,
|
||||
@ -80,7 +78,6 @@ export const UpgradePage = () => {
|
||||
|
||||
const showError = isFetchError;
|
||||
const showLoading = isLoading;
|
||||
const showStart = !isLoading && !isFetchError && !hasData;
|
||||
const showData = !isLoading && !isFetchError && hasData;
|
||||
|
||||
return (
|
||||
@ -92,7 +89,6 @@ export const UpgradePage = () => {
|
||||
</Alert>
|
||||
)}
|
||||
{showLoading && <Loading text={'Loading...'} />}
|
||||
{showStart && <CTAElement />}
|
||||
{showData && (
|
||||
<>
|
||||
<ErrorSummary errors={errors} />
|
||||
@ -188,12 +184,12 @@ const CancelUpgradeButton = () => {
|
||||
icon={'trash-alt'}
|
||||
className={''}
|
||||
>
|
||||
{'Cancel upgrade'}
|
||||
{'Reset upgrade'}
|
||||
</Button>
|
||||
{showConfirmStartOver && (
|
||||
<ConfirmModal
|
||||
isOpen={true}
|
||||
title="Cancel upgrade"
|
||||
title="Reset upgrade"
|
||||
body={
|
||||
<Stack direction="column" gap={0.5}>
|
||||
<Text color="primary">All new Grafana Alerting resources will be deleted.</Text>
|
||||
@ -205,7 +201,7 @@ const CancelUpgradeButton = () => {
|
||||
<Text color="primary">No legacy alerts or notification channels will be affected.</Text>
|
||||
</Stack>
|
||||
}
|
||||
confirmText="Cancel upgrade"
|
||||
confirmText="Reset upgrade"
|
||||
onConfirm={cancelUpgrade}
|
||||
dismissText={'Keep reviewing'}
|
||||
onDismiss={() => setShowConfirmStartOver(false)}
|
||||
@ -240,249 +236,6 @@ function getActiveTabFromUrl(queryParams: UrlQueryMap): QueryParamValues {
|
||||
};
|
||||
}
|
||||
|
||||
const CTAElement = () => {
|
||||
const styles = useStyles2(getContentBoxStyles);
|
||||
const { useUpgradeOrgMutation } = upgradeApi;
|
||||
const [startUpgrade, { isLoading: isUpgradeLoading }] = useUpgradeOrgMutation({
|
||||
fixedCacheKey: 'upgrade-org-loading',
|
||||
});
|
||||
const [, { isLoading: isCancelLoading }] = upgradeApi.useCancelOrgUpgradeMutation({
|
||||
fixedCacheKey: 'cancel-org-upgrade-loading',
|
||||
});
|
||||
const isLoading = isUpgradeLoading || isCancelLoading;
|
||||
|
||||
const upgradeAlerting = async () => {
|
||||
await startUpgrade({ skipExisting: false });
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return <Loading text={isCancelLoading ? 'Cancelling upgrade...' : 'Upgrade in progress...'} />;
|
||||
}
|
||||
|
||||
const footer = (
|
||||
<>
|
||||
<span key="proTipFooter">
|
||||
<p>
|
||||
Note:{' '}
|
||||
{'Previewing the upgrade process will not affect your existing legacy alerts and can be stopped at any time.'}
|
||||
</p>
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
|
||||
const cta = (
|
||||
<div>
|
||||
<Stack direction="column" gap={1}>
|
||||
<Stack direction="row" gap={1}>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="primary"
|
||||
onClick={upgradeAlerting}
|
||||
icon={'bell'}
|
||||
className={''}
|
||||
data-testid={selectors.components.CallToActionCard.buttonV2('Preview upgrade')}
|
||||
>
|
||||
{'Preview upgrade'}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.grid}>
|
||||
<ContentBox className={styles.processBlock}>
|
||||
<h3 className={styles.header}>How it works</h3>
|
||||
<Stack direction="column" alignItems="space-between">
|
||||
<div className={styles.list}>
|
||||
<h4>Automatic Upgrade</h4>
|
||||
<div className={styles.step}>
|
||||
<p>
|
||||
The upgrade process seamlessly transfers your existing legacy alert rules and notification channels to
|
||||
the new Grafana Alerting system. This means your alerting configurations are preserved during the
|
||||
transition.
|
||||
</p>
|
||||
</div>
|
||||
<h4>Preview and Modification</h4>
|
||||
<div className={styles.step}>
|
||||
<p>
|
||||
Alert Rules, Contact Points, and Notification Policies generated during the upgrade are available for
|
||||
your review and potential adjustments. However, please note that they won't actively trigger alerts
|
||||
or send notifications at this stage.
|
||||
</p>
|
||||
</div>
|
||||
<h4>Limitations on Real-Time Updates</h4>
|
||||
<div className={styles.step}>
|
||||
<p>
|
||||
Any changes made to your configurations after initiating the upgrade won't be immediately reflected
|
||||
in the summary table. You have the flexibility to re-upgrade specific resources like dashboards, alert
|
||||
rules, and notification channels at any time.
|
||||
</p>
|
||||
</div>
|
||||
<h4>Cancellation and Restart</h4>
|
||||
<div className={styles.step}>
|
||||
<p>
|
||||
If necessary, you can cancel and restart the upgrade process. However, it's important to be aware
|
||||
that canceling the upgrade will result in the removal of all Grafana Alerting resources created during
|
||||
the process, including any manual modifications.
|
||||
</p>
|
||||
</div>
|
||||
<h4>Completing the Upgrade</h4>
|
||||
<div className={styles.step}>
|
||||
<p>
|
||||
To enable Grafana Alerting, you'll need to modify the Grafana configuration and restart. Until this
|
||||
step is completed, Grafana Alerting will remain inactive.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Stack>
|
||||
</ContentBox>
|
||||
<ContentBox className={styles.getStartedBlock}>
|
||||
<h3 className={styles.header}>Get started</h3>
|
||||
<Stack direction="column" alignItems="space-between">
|
||||
<div className={styles.list}>
|
||||
<h4>Step 1: Preview the Upgrade</h4>
|
||||
<div className={styles.step}>
|
||||
<p>
|
||||
Start the upgrade process by clicking on "Preview upgrade." This action will display a summary
|
||||
table showing how your existing alert rules and notification channels will be mapped to resources in the
|
||||
new Grafana Alerting system.
|
||||
</p>
|
||||
</div>
|
||||
<h4>Step 2: Investigate and Resolve Errors</h4>
|
||||
<div className={styles.step}>
|
||||
<p>
|
||||
Review the previewed upgrade carefully. Alert rules or notification channels that couldn't be
|
||||
automatically upgraded will be marked as errors. You have two options to address these errors:
|
||||
</p>
|
||||
<ul className={styles.list}>
|
||||
<li>
|
||||
Fix the issues on the legacy side: If possible, resolve the problems within your legacy alerting
|
||||
setup, and then attempt the upgrade again.
|
||||
</li>
|
||||
<li>
|
||||
Manually create new resources: If fixing legacy issues isn't feasible, manually create new alert
|
||||
rules, notification policies, or contact points in the new Grafana Alerting system to replace the
|
||||
problematic ones.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<h4>Step 3: Update Your As-Code Setup (Optional)</h4>
|
||||
<div className={styles.step}>
|
||||
<p>
|
||||
In the new Grafana Alerting, Legacy Alerting methods of provisioning will no longer work. If you use
|
||||
provisioning to manage alert rules and notification channels, you can export the upgraded versions to
|
||||
generate Grafana Alerting-compatible provisioning files. This can all be done before completeing the
|
||||
upgrade process.
|
||||
</p>
|
||||
</div>
|
||||
<h4>Step 4: Perform the Upgrade to Grafana Alerting</h4>
|
||||
<div className={styles.step}>
|
||||
<p>
|
||||
Once you are satisfied with the state of your Grafana Alerting setup, it's time to proceed with the
|
||||
upgrade:
|
||||
</p>
|
||||
<ul className={styles.list}>
|
||||
<li>
|
||||
Contact your Grafana server administrator to restart Grafana with the [unified_alerting] section
|
||||
enabled in your configuration.
|
||||
</li>
|
||||
<li>
|
||||
During this process, all organizations that have undergone the above upgrade process will continue to
|
||||
use their configured setup.
|
||||
</li>
|
||||
<li>
|
||||
Any organization that has not yet started the upgrade process will be automatically upgraded as part
|
||||
of this restart.
|
||||
</li>
|
||||
<li>
|
||||
Note: If the automatic upgrade fails for any reason, Grafana will not start, so it's safer to
|
||||
address any issues before initiating this step.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<Stack direction={'row'} alignItems={'center'} gap={0.5}>
|
||||
<Text color={'secondary'}>For more information, please refer to the</Text>
|
||||
<TextLink external href={'https://grafana.com/docs/grafana/latest/alerting/set-up/migrating-alerts/'}>
|
||||
Grafana Alerting Migration Guide
|
||||
</TextLink>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</ContentBox>
|
||||
<ContentBox className={styles.ctaBlock}>
|
||||
<CallToActionCard
|
||||
className={styles.ctaStyle}
|
||||
message={'Start the upgrade to the new Grafana Alerting.'}
|
||||
footer={footer}
|
||||
callToActionElement={cta}
|
||||
/>
|
||||
</ContentBox>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function ContentBox({ children, className }: React.PropsWithChildren<{ className?: string }>) {
|
||||
const styles = useStyles2(getContentBoxStyles);
|
||||
|
||||
return <div className={cx(styles.box, className)}>{children}</div>;
|
||||
}
|
||||
|
||||
const getContentBoxStyles = (theme: GrafanaTheme2) => {
|
||||
const color = theme.colors['warning'];
|
||||
return {
|
||||
box: css({
|
||||
padding: theme.spacing(2),
|
||||
backgroundColor: theme.colors.background.secondary,
|
||||
borderRadius: theme.shape.radius.default,
|
||||
}),
|
||||
|
||||
warningIcon: css({
|
||||
color: color.text,
|
||||
}),
|
||||
|
||||
grid: css({
|
||||
display: 'grid',
|
||||
gridTemplateRows: 'min-content auto auto',
|
||||
gridTemplateColumns: '1fr 1fr 1fr 1fr 1fr',
|
||||
gap: theme.spacing(2),
|
||||
}),
|
||||
|
||||
list: css({
|
||||
margin: `${theme.spacing(0)} ${theme.spacing(2)}`,
|
||||
'& > li': {
|
||||
marginBottom: theme.spacing(1),
|
||||
},
|
||||
}),
|
||||
|
||||
ctaStyle: css({
|
||||
textAlign: 'center',
|
||||
}),
|
||||
|
||||
processBlock: css({
|
||||
gridColumn: '1 / span 2',
|
||||
justifyContent: 'space-between',
|
||||
}),
|
||||
|
||||
getStartedBlock: css({
|
||||
gridColumn: '3 / span 3',
|
||||
justifyContent: 'space-between',
|
||||
}),
|
||||
|
||||
ctaBlock: css({
|
||||
gridColumn: '1 / span 5',
|
||||
}),
|
||||
|
||||
header: css({
|
||||
marginBottom: theme.spacing(2),
|
||||
}),
|
||||
|
||||
step: css({
|
||||
paddingLeft: theme.spacing(2),
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
const AlertTabContentWrapper = () => {
|
||||
const columns = useAlertColumns();
|
||||
const filterParam = 'alertFilter';
|
||||
|
Loading…
Reference in New Issue
Block a user