Provisioning: Add Git Sync limitations warning and migrate resources checkbox
- Update SynchronizeStep alert to use warning severity with comprehensive Git Sync limitations - Add conditional warnings for instance sync (permissions loss, alerts/library panels loss) - Add conditional warnings for folder sync (folder structure changes, manual cleanup needed) - Add "Migrate existing resources" checkbox for folder sync mode - Update useCreateSyncJob hook to handle migrateResources option for folder sync - Extract i18n translations for new strings
This commit is contained in:
@@ -3,7 +3,7 @@ import { memo, useEffect, useState } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { Alert, Button, Field, Spinner, Stack, Text, TextLink } from '@grafana/ui';
|
||||
import { Alert, Button, Checkbox, Field, Spinner, Stack, Text, TextLink } from '@grafana/ui';
|
||||
import { Job, useGetRepositoryStatusQuery } from 'app/api/clients/provisioning/v0alpha1';
|
||||
|
||||
import { JobStatus } from '../Job/JobStatus';
|
||||
@@ -12,7 +12,7 @@ import { ProvisioningAlert } from '../Shared/ProvisioningAlert';
|
||||
import { useStepStatus } from './StepStatusContext';
|
||||
import { useCreateSyncJob } from './hooks/useCreateSyncJob';
|
||||
import { useResourceStats } from './hooks/useResourceStats';
|
||||
import { WizardFormData } from './types';
|
||||
import { Target, WizardFormData } from './types';
|
||||
|
||||
export interface SynchronizeStepProps {
|
||||
onCancel?: (repoName: string) => void;
|
||||
@@ -20,13 +20,15 @@ export interface SynchronizeStepProps {
|
||||
}
|
||||
|
||||
export const SynchronizeStep = memo(function SynchronizeStep({ onCancel, isCancelling }: SynchronizeStepProps) {
|
||||
const { watch } = useFormContext<WizardFormData>();
|
||||
const { watch, register, getValues } = useFormContext<WizardFormData>();
|
||||
const { setStepStatusInfo } = useStepStatus();
|
||||
const [repoName = '', syncTarget] = watch(['repositoryName', 'repository.sync.target']);
|
||||
const repoName = watch('repositoryName') ?? '';
|
||||
const syncTarget = watch('repository.sync.target');
|
||||
const { requiresMigration } = useResourceStats(repoName, syncTarget);
|
||||
const { createSyncJob } = useCreateSyncJob({
|
||||
repoName,
|
||||
requiresMigration,
|
||||
syncTarget,
|
||||
setStepStatusInfo,
|
||||
});
|
||||
const [job, setJob] = useState<Job>();
|
||||
@@ -63,7 +65,8 @@ export const SynchronizeStep = memo(function SynchronizeStep({ onCancel, isCance
|
||||
const isButtonDisabled = hasError || (checked !== undefined && isRepositoryHealthy === false) || healthStatusNotReady;
|
||||
|
||||
const startSynchronization = async () => {
|
||||
const response = await createSyncJob();
|
||||
const migrateResources = getValues('migrate.migrateResources');
|
||||
const response = await createSyncJob({ migrateResources });
|
||||
if (response) {
|
||||
setJob(response);
|
||||
}
|
||||
@@ -108,29 +111,76 @@ export const SynchronizeStep = memo(function SynchronizeStep({ onCancel, isCance
|
||||
)}
|
||||
{isRepositoryHealthy && (
|
||||
<Alert
|
||||
title={t(
|
||||
'provisioning.wizard.alert-title',
|
||||
'Important: No data or configuration will be lost. Dashboards remain accessible during migration, but changes made during this process may not be exported.'
|
||||
)}
|
||||
severity={'info'}
|
||||
title={t('provisioning.wizard.alert-title', 'Important: Review Git Sync limitations before proceeding')}
|
||||
severity={'warning'}
|
||||
>
|
||||
<ul style={{ marginLeft: '16px' }}>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-1">
|
||||
Resources can still be created, edited, or deleted during this process, but changes may not be exported.
|
||||
<Stack direction="column" gap={2}>
|
||||
<Text>
|
||||
<Trans i18nKey="provisioning.wizard.alert-intro">
|
||||
Please be aware of the following limitations. For more details, see the{' '}
|
||||
<TextLink
|
||||
external
|
||||
href="https://grafana.com/docs/grafana/latest/as-code/observability-as-code/provision-resources/intro-git-sync/"
|
||||
>
|
||||
Git Sync documentation
|
||||
</TextLink>
|
||||
.
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-2">
|
||||
Once provisioning is complete, resources will be marked as managed through external storage.
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-3">
|
||||
The duration of this process depends on the number of resources involved.
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
</Text>
|
||||
<ul style={{ marginLeft: '16px', marginTop: 0, marginBottom: 0 }}>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-1">
|
||||
Resources can still be created, edited, or deleted during this process, but changes may not be
|
||||
exported.
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-unsupported">
|
||||
Alerts and library panels are not supported in provisioned folders.
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-permissions">
|
||||
Fine-grained permissions are not supported. Default permissions apply: Admin, Editor, and Viewer roles
|
||||
are preserved with their standard access levels.
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-3">
|
||||
The duration of this process depends on the number of resources involved.
|
||||
</Trans>
|
||||
</li>
|
||||
{syncTarget === 'instance' && (
|
||||
<>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-instance-permissions">
|
||||
Fine-grained folder permissions will be lost and cannot be recovered.
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-instance-alerts">
|
||||
Existing alerts and library panels will be lost and will not be usable after migration.
|
||||
</Trans>
|
||||
</li>
|
||||
</>
|
||||
)}
|
||||
{syncTarget === 'folder' && (
|
||||
<>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-folder-structure">
|
||||
When migrating existing dashboards, the folder structure will be replicated in the repository.
|
||||
Original folders will be emptied of dashboards but may still contain alerts or library panels.
|
||||
</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-folder-cleanup">
|
||||
You may need to manually remove or manage original folders after migration.
|
||||
</Trans>
|
||||
</li>
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
<Text color="secondary" variant="bodySmall">
|
||||
<Trans i18nKey="provisioning.wizard.alert-point-4">
|
||||
Enterprise instance administrators can display an announcement banner to notify users that migration is
|
||||
in progress. See{' '}
|
||||
@@ -139,10 +189,29 @@ export const SynchronizeStep = memo(function SynchronizeStep({ onCancel, isCance
|
||||
</TextLink>{' '}
|
||||
for step-by-step instructions.
|
||||
</Trans>
|
||||
</li>
|
||||
</ul>
|
||||
</Text>
|
||||
</Stack>
|
||||
</Alert>
|
||||
)}
|
||||
{syncTarget === 'folder' && (
|
||||
<>
|
||||
<Text element="h3">
|
||||
<Trans i18nKey="provisioning.synchronize-step.synchronization-options">Synchronization options</Trans>
|
||||
</Text>
|
||||
<Field noMargin>
|
||||
<Checkbox
|
||||
{...register('migrate.migrateResources')}
|
||||
id="migrate-resources"
|
||||
label={t('provisioning.wizard.sync-option-migrate-resources', 'Migrate existing resources')}
|
||||
description={
|
||||
<Trans i18nKey="provisioning.synchronize-step.migrate-resources-description">
|
||||
Import existing dashboards from all folders into the new provisioned folder
|
||||
</Trans>
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
</>
|
||||
)}
|
||||
{healthStatusNotReady ? (
|
||||
<>
|
||||
<Stack>
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
import { t } from '@grafana/i18n';
|
||||
import { useCreateRepositoryJobsMutation } from 'app/api/clients/provisioning/v0alpha1';
|
||||
|
||||
import { StepStatusInfo } from '../types';
|
||||
import { StepStatusInfo, Target } from '../types';
|
||||
|
||||
export interface UseCreateSyncJobParams {
|
||||
repoName: string;
|
||||
requiresMigration: boolean;
|
||||
syncTarget?: Target;
|
||||
setStepStatusInfo?: (info: StepStatusInfo) => void;
|
||||
}
|
||||
|
||||
export function useCreateSyncJob({ repoName, requiresMigration, setStepStatusInfo }: UseCreateSyncJobParams) {
|
||||
export interface CreateSyncJobOptions {
|
||||
migrateResources?: boolean;
|
||||
}
|
||||
|
||||
export function useCreateSyncJob({
|
||||
repoName,
|
||||
requiresMigration,
|
||||
syncTarget,
|
||||
setStepStatusInfo,
|
||||
}: UseCreateSyncJobParams) {
|
||||
const [createJob, { isLoading }] = useCreateRepositoryJobsMutation();
|
||||
|
||||
const createSyncJob = async () => {
|
||||
const createSyncJob = async (options?: CreateSyncJobOptions) => {
|
||||
if (!repoName) {
|
||||
setStepStatusInfo?.({
|
||||
status: 'error',
|
||||
@@ -24,7 +34,13 @@ export function useCreateSyncJob({ repoName, requiresMigration, setStepStatusInf
|
||||
try {
|
||||
setStepStatusInfo?.({ status: 'running' });
|
||||
|
||||
const jobSpec = requiresMigration
|
||||
// Determine if we should run a migration job:
|
||||
// - For instance sync: always migrate if there are resources
|
||||
// - For folder sync: migrate only if user explicitly opted in via checkbox
|
||||
const shouldMigrate =
|
||||
syncTarget === 'instance' ? requiresMigration : syncTarget === 'folder' && options?.migrateResources;
|
||||
|
||||
const jobSpec = shouldMigrate
|
||||
? {
|
||||
migrate: {},
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ export type RepoType = RepositorySpec['type'];
|
||||
export interface MigrateFormData {
|
||||
history: boolean;
|
||||
identifier: boolean;
|
||||
migrateResources?: boolean;
|
||||
}
|
||||
|
||||
export interface WizardFormData {
|
||||
|
||||
@@ -12182,9 +12182,11 @@
|
||||
"tooltip-unhealthy-repository": "Unable to pull an unhealthy repository"
|
||||
},
|
||||
"synchronize-step": {
|
||||
"migrate-resources-description": "Import existing dashboards from all folders into the new provisioned folder",
|
||||
"repository-error": "Repository error",
|
||||
"repository-error-message": "Unable to check repository status. Please verify the repository configuration and try again.",
|
||||
"repository-unhealthy": "The repository cannot be synchronized. Cancel provisioning and try again once the issue has been resolved. See details below."
|
||||
"repository-unhealthy": "The repository cannot be synchronized. Cancel provisioning and try again once the issue has been resolved. See details below.",
|
||||
"synchronization-options": "Synchronization options"
|
||||
},
|
||||
"token-permissions-info": {
|
||||
"and-click": "and click",
|
||||
@@ -12201,11 +12203,17 @@
|
||||
},
|
||||
"warning-title-default": "Warning",
|
||||
"wizard": {
|
||||
"alert-intro": "Please be aware of the following limitations. For more details, see the <2>Git Sync documentation</2>.",
|
||||
"alert-point-1": "Resources can still be created, edited, or deleted during this process, but changes may not be exported.",
|
||||
"alert-point-2": "Once provisioning is complete, resources will be marked as managed through external storage.",
|
||||
"alert-point-3": "The duration of this process depends on the number of resources involved.",
|
||||
"alert-point-4": "Enterprise instance administrators can display an announcement banner to notify users that migration is in progress. See <2>this guide</2> for step-by-step instructions.",
|
||||
"alert-title": "Important: No data or configuration will be lost. Dashboards remain accessible during migration, but changes made during this process may not be exported.",
|
||||
"alert-point-folder-cleanup": "You may need to manually remove or manage original folders after migration.",
|
||||
"alert-point-folder-structure": "When migrating existing dashboards, the folder structure will be replicated in the repository. Original folders will be emptied of dashboards but may still contain alerts or library panels.",
|
||||
"alert-point-instance-alerts": "Existing alerts and library panels will be lost and will not be usable after migration.",
|
||||
"alert-point-instance-permissions": "Fine-grained folder permissions will be lost and cannot be recovered.",
|
||||
"alert-point-permissions": "Fine-grained permissions are not supported. Default permissions apply: Admin, Editor, and Viewer roles are preserved with their standard access levels.",
|
||||
"alert-point-unsupported": "Alerts and library panels are not supported in provisioned folders.",
|
||||
"alert-title": "Important: Review Git Sync limitations before proceeding",
|
||||
"button-cancel": "Cancel",
|
||||
"button-cancelling": "Cancelling...",
|
||||
"button-next": "Finish",
|
||||
@@ -12223,6 +12231,7 @@
|
||||
"step-finish": "Choose additional settings",
|
||||
"step-synchronize": "Synchronize with external storage",
|
||||
"sync-description": "Sync resources with external storage. After this one-time step, all future updates will be automatically saved to the repository and provisioned back into the instance.",
|
||||
"sync-option-migrate-resources": "Migrate existing resources",
|
||||
"title-bootstrap": "Choose what to synchronize",
|
||||
"title-connect": "Connect to external storage",
|
||||
"title-finish": "Choose additional settings",
|
||||
|
||||
Reference in New Issue
Block a user