Provisioning: Show alert when token is missing (#110088)

This commit is contained in:
Ryan McKinley
2025-08-27 05:34:27 +00:00
committed by GitHub
parent b83ca0712b
commit 88cd7df18d
6 changed files with 75 additions and 0 deletions
@@ -19,6 +19,7 @@ import { FormPrompt } from 'app/core/components/FormPrompt/FormPrompt';
import { TokenPermissionsInfo } from '../Shared/TokenPermissionsInfo';
import { getGitProviderFields, getLocalProviderFields } from '../Wizard/fields';
import { InlineSecureValueWarning } from '../components/InlineSecureValueWarning';
import { useCreateOrUpdateRepository } from '../hooks/useCreateOrUpdateRepository';
import { RepositoryFormData } from '../types';
import { dataToSpec } from '../utils/data';
@@ -48,6 +49,7 @@ export function ConfigForm({ data }: ConfigFormProps) {
control,
formState: { errors, isDirty },
setValue,
setError,
watch,
getValues,
} = useForm<RepositoryFormData>({ defaultValues: getDefaultValues(data?.spec) });
@@ -65,6 +67,17 @@ export function ConfigForm({ data }: ConfigFormProps) {
const localFields = type === 'local' ? getLocalProviderFields(type) : null;
const hasTokenInstructions = getHasTokenInstructions(type);
// TODO: this should be removed after 12.2 is released
useEffect(() => {
if (isGitBased && !data?.secure?.token) {
setTokenConfigured(false);
setError('token', {
type: 'manual',
message: `Enter your ${gitFields?.tokenConfig.label ?? 'access token'}`,
});
}
}, [data, gitFields, setTokenConfigured, setError, isGitBased]);
useEffect(() => {
if (request.isSuccess) {
const formData = getValues();
@@ -108,6 +121,7 @@ export function ConfigForm({ data }: ConfigFormProps) {
</Field>
{gitFields && (
<>
<InlineSecureValueWarning repo={data} />
<Field
noMargin
label={gitFields.tokenConfig.label}
@@ -126,6 +140,7 @@ export function ConfigForm({ data }: ConfigFormProps) {
return (
<SecretInput
{...field}
invalid={!!errors.token}
id={'token'}
placeholder={gitFields.tokenConfig.placeholder}
isConfigured={tokenConfigured}
@@ -11,6 +11,7 @@ import { Page } from 'app/core/components/Page/Page';
import GettingStarted from './GettingStarted/GettingStarted';
import GettingStartedPage from './GettingStarted/GettingStartedPage';
import { RepositoryList } from './Shared/RepositoryList';
import { InlineSecureValueWarning } from './components/InlineSecureValueWarning';
import { useRepositoryList } from './hooks/useRepositoryList';
enum TabSelection {
@@ -86,6 +87,7 @@ export default function HomePage() {
</Trans>
</Alert>
)}
<InlineSecureValueWarning items={items} />
<ConfirmModal
isOpen={showDeleteModal}
title={t(
@@ -11,6 +11,7 @@ import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { isNotFoundError } from 'app/features/alerting/unified/api/util';
import { FilesView } from '../File/FilesView';
import { InlineSecureValueWarning } from '../components/InlineSecureValueWarning';
import { PROVISIONING_URL } from '../constants';
import { RepositoryActions } from './RepositoryActions';
@@ -80,6 +81,7 @@ export default function RepositoryStatusPage() {
</Trans>
</Alert>
)}
<InlineSecureValueWarning repo={data} />
{notFound ? (
<EmptyState
message={t('provisioning.repository-status-page.not-found-message', 'Repository not found')}
@@ -1,3 +1,4 @@
import { t } from '@grafana/i18n';
import { locationService } from '@grafana/runtime';
import { Badge, BadgeColor, IconName } from '@grafana/ui';
import { Repository } from 'app/api/clients/provisioning/v0alpha1';
@@ -13,6 +14,26 @@ export function StatusBadge({ repo }: StatusBadgeProps) {
return null;
}
// TODO: remove after 12.2
if (repo.spec?.type !== 'local' && !repo.secure?.token?.name) {
return (
<Badge
color={'red'}
icon={'exclamation-triangle'}
style={{ cursor: 'pointer' }}
text={t('provisioning.inline-token-warning-badge-text', 'Token needs to be saved again')}
tooltip={t(
'inline-token-warning-badge-tooltip',
'The method to save the token is to re-enter it in the repository settings.'
)}
onClick={() => {
// navigate to edit page, rather than view page
locationService.push(`${PROVISIONING_URL}/${repo.metadata?.name}/edit`);
}}
/>
);
}
let tooltip: string | undefined = undefined;
let color: BadgeColor = 'purple';
let text = 'Unknown';
@@ -0,0 +1,32 @@
import { t } from '@grafana/i18n';
import { Alert } from '@grafana/ui';
import { Repository } from 'app/api/clients/provisioning/v0alpha1';
interface Props {
repo?: Repository;
items?: Repository[];
}
// TODO: remove this after 12.2
export function InlineSecureValueWarning({ repo, items }: Props) {
const isRepoValid = (r?: Repository) => r?.spec?.type === 'local' || !!r?.secure?.token?.name;
if (isRepoValid(repo)) {
return null;
}
// When a list is passed in, show an error if anything is missing
if (items?.every(isRepoValid)) {
return null;
}
return (
<Alert
title={t(
'provisioning.inline-secure-values-warning',
'You need to save your access tokens again due to a system update'
)}
severity="error"
/>
);
}
+3
View File
@@ -9039,6 +9039,7 @@
"name-line-width": "Line width",
"name-stacking": "Stacking"
},
"inline-token-warning-badge-tooltip": "The method to save the token is to re-enter it in the repository settings.",
"inspector": {
"inspect-data-tab": {
"loading": "Loading",
@@ -11442,6 +11443,8 @@
"title-delete-all-configured-repositories": "Delete all configured repositories",
"title-legacy-storage-detected": "Legacy storage detected"
},
"inline-secure-values-warning": "You need to save your access tokens again due to a system update",
"inline-token-warning-badge-text": "Token needs to be saved again",
"job-status": {
"label-view-details": "View details",
"loading-finished-job": "Loading finished job...",