diff --git a/pkg/registry/apis/provisioning/register.go b/pkg/registry/apis/provisioning/register.go index ffe315f63b6..472f0a088ec 100644 --- a/pkg/registry/apis/provisioning/register.go +++ b/pkg/registry/apis/provisioning/register.go @@ -355,7 +355,11 @@ func (b *APIBuilder) GetAuthorizer() authorizer.Authorizer { } else { return authorizer.DecisionDeny, "editor role is required", nil } - + case "status": + if id.GetOrgRole().Includes(identity.RoleViewer) && a.GetVerb() == apiutils.VerbGet { + return authorizer.DecisionAllow, "", nil + } + return authorizer.DecisionDeny, "users cannot update the status of a repository", nil default: if id.GetIsGrafanaAdmin() { return authorizer.DecisionAllow, "", nil diff --git a/public/app/features/provisioning/Wizard/ProvisioningWizard.test.tsx b/public/app/features/provisioning/Wizard/ProvisioningWizard.test.tsx index 3fe7eeb57dc..e6d46be3471 100644 --- a/public/app/features/provisioning/Wizard/ProvisioningWizard.test.tsx +++ b/public/app/features/provisioning/Wizard/ProvisioningWizard.test.tsx @@ -7,6 +7,7 @@ import { useCreateRepositoryJobsMutation, useGetFrontendSettingsQuery, useGetRepositoryFilesQuery, + useGetRepositoryStatusQuery, useGetResourceStatsQuery, } from 'app/api/clients/provisioning/v0alpha1'; @@ -29,6 +30,7 @@ jest.mock('app/api/clients/provisioning/v0alpha1', () => ({ ...jest.requireActual('app/api/clients/provisioning/v0alpha1'), useGetFrontendSettingsQuery: jest.fn(), useGetRepositoryFilesQuery: jest.fn(), + useGetRepositoryStatusQuery: jest.fn(), useGetResourceStatsQuery: jest.fn(), useCreateRepositoryJobsMutation: jest.fn(), })); @@ -43,6 +45,9 @@ const mockUseGetFrontendSettingsQuery = useGetFrontendSettingsQuery as jest.Mock const mockUseGetRepositoryFilesQuery = useGetRepositoryFilesQuery as jest.MockedFunction< typeof useGetRepositoryFilesQuery >; +const mockUseGetRepositoryStatusQuery = useGetRepositoryStatusQuery as jest.MockedFunction< + typeof useGetRepositoryStatusQuery +>; const mockUseGetResourceStatsQuery = useGetResourceStatsQuery as jest.MockedFunction; const mockUseCreateRepositoryJobsMutation = useCreateRepositoryJobsMutation as jest.MockedFunction< typeof useCreateRepositoryJobsMutation @@ -131,6 +136,23 @@ describe('ProvisioningWizard', () => { refetch: jest.fn(), }); + mockUseGetRepositoryStatusQuery.mockReturnValue({ + data: { + status: { + health: { + healthy: true, + checked: true, + message: '', + }, + }, + }, + isLoading: false, + isFetching: false, + isError: false, + error: null, + refetch: jest.fn(), + }); + mockUseGetResourceStatsQuery.mockReturnValue({ data: { instance: [], diff --git a/public/app/features/provisioning/Wizard/SynchronizeStep.tsx b/public/app/features/provisioning/Wizard/SynchronizeStep.tsx index 09ab5ff7a24..3e7a70292e6 100644 --- a/public/app/features/provisioning/Wizard/SynchronizeStep.tsx +++ b/public/app/features/provisioning/Wizard/SynchronizeStep.tsx @@ -40,7 +40,9 @@ export function SynchronizeStep({ isLegacyStorage, onCancel, isCancelling }: Syn message: repositoryHealthMessages, checked, } = repositoryStatusQuery?.data?.status?.health || {}; - const isButtonDisabled = checked !== undefined && isRepositoryHealthy === false; + + const hasError = repositoryStatusQuery.isError; + const isButtonDisabled = hasError || (checked !== undefined && isRepositoryHealthy === false); const startSynchronization = async () => { const [history] = getValues(['migrate.history']); @@ -65,7 +67,18 @@ export function SynchronizeStep({ isLegacyStorage, onCancel, isCancelling }: Syn to the repository and provisioned back into the instance. - {repositoryHealthMessages && !isRepositoryHealthy && ( + {hasError && ( + + )} + {repositoryHealthMessages && !isRepositoryHealthy && !hasError && ( - {isRepositoryHealthy === false ? ( + {hasError || isRepositoryHealthy === false ? (