Provisioning: Show alert when token is missing (#110088)
This commit is contained in:
@@ -19,6 +19,7 @@ import { FormPrompt } from 'app/core/components/FormPrompt/FormPrompt';
|
|||||||
|
|
||||||
import { TokenPermissionsInfo } from '../Shared/TokenPermissionsInfo';
|
import { TokenPermissionsInfo } from '../Shared/TokenPermissionsInfo';
|
||||||
import { getGitProviderFields, getLocalProviderFields } from '../Wizard/fields';
|
import { getGitProviderFields, getLocalProviderFields } from '../Wizard/fields';
|
||||||
|
import { InlineSecureValueWarning } from '../components/InlineSecureValueWarning';
|
||||||
import { useCreateOrUpdateRepository } from '../hooks/useCreateOrUpdateRepository';
|
import { useCreateOrUpdateRepository } from '../hooks/useCreateOrUpdateRepository';
|
||||||
import { RepositoryFormData } from '../types';
|
import { RepositoryFormData } from '../types';
|
||||||
import { dataToSpec } from '../utils/data';
|
import { dataToSpec } from '../utils/data';
|
||||||
@@ -48,6 +49,7 @@ export function ConfigForm({ data }: ConfigFormProps) {
|
|||||||
control,
|
control,
|
||||||
formState: { errors, isDirty },
|
formState: { errors, isDirty },
|
||||||
setValue,
|
setValue,
|
||||||
|
setError,
|
||||||
watch,
|
watch,
|
||||||
getValues,
|
getValues,
|
||||||
} = useForm<RepositoryFormData>({ defaultValues: getDefaultValues(data?.spec) });
|
} = useForm<RepositoryFormData>({ defaultValues: getDefaultValues(data?.spec) });
|
||||||
@@ -65,6 +67,17 @@ export function ConfigForm({ data }: ConfigFormProps) {
|
|||||||
const localFields = type === 'local' ? getLocalProviderFields(type) : null;
|
const localFields = type === 'local' ? getLocalProviderFields(type) : null;
|
||||||
const hasTokenInstructions = getHasTokenInstructions(type);
|
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(() => {
|
useEffect(() => {
|
||||||
if (request.isSuccess) {
|
if (request.isSuccess) {
|
||||||
const formData = getValues();
|
const formData = getValues();
|
||||||
@@ -108,6 +121,7 @@ export function ConfigForm({ data }: ConfigFormProps) {
|
|||||||
</Field>
|
</Field>
|
||||||
{gitFields && (
|
{gitFields && (
|
||||||
<>
|
<>
|
||||||
|
<InlineSecureValueWarning repo={data} />
|
||||||
<Field
|
<Field
|
||||||
noMargin
|
noMargin
|
||||||
label={gitFields.tokenConfig.label}
|
label={gitFields.tokenConfig.label}
|
||||||
@@ -126,6 +140,7 @@ export function ConfigForm({ data }: ConfigFormProps) {
|
|||||||
return (
|
return (
|
||||||
<SecretInput
|
<SecretInput
|
||||||
{...field}
|
{...field}
|
||||||
|
invalid={!!errors.token}
|
||||||
id={'token'}
|
id={'token'}
|
||||||
placeholder={gitFields.tokenConfig.placeholder}
|
placeholder={gitFields.tokenConfig.placeholder}
|
||||||
isConfigured={tokenConfigured}
|
isConfigured={tokenConfigured}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { Page } from 'app/core/components/Page/Page';
|
|||||||
import GettingStarted from './GettingStarted/GettingStarted';
|
import GettingStarted from './GettingStarted/GettingStarted';
|
||||||
import GettingStartedPage from './GettingStarted/GettingStartedPage';
|
import GettingStartedPage from './GettingStarted/GettingStartedPage';
|
||||||
import { RepositoryList } from './Shared/RepositoryList';
|
import { RepositoryList } from './Shared/RepositoryList';
|
||||||
|
import { InlineSecureValueWarning } from './components/InlineSecureValueWarning';
|
||||||
import { useRepositoryList } from './hooks/useRepositoryList';
|
import { useRepositoryList } from './hooks/useRepositoryList';
|
||||||
|
|
||||||
enum TabSelection {
|
enum TabSelection {
|
||||||
@@ -86,6 +87,7 @@ export default function HomePage() {
|
|||||||
</Trans>
|
</Trans>
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
<InlineSecureValueWarning items={items} />
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
isOpen={showDeleteModal}
|
isOpen={showDeleteModal}
|
||||||
title={t(
|
title={t(
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
|||||||
import { isNotFoundError } from 'app/features/alerting/unified/api/util';
|
import { isNotFoundError } from 'app/features/alerting/unified/api/util';
|
||||||
|
|
||||||
import { FilesView } from '../File/FilesView';
|
import { FilesView } from '../File/FilesView';
|
||||||
|
import { InlineSecureValueWarning } from '../components/InlineSecureValueWarning';
|
||||||
import { PROVISIONING_URL } from '../constants';
|
import { PROVISIONING_URL } from '../constants';
|
||||||
|
|
||||||
import { RepositoryActions } from './RepositoryActions';
|
import { RepositoryActions } from './RepositoryActions';
|
||||||
@@ -80,6 +81,7 @@ export default function RepositoryStatusPage() {
|
|||||||
</Trans>
|
</Trans>
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
<InlineSecureValueWarning repo={data} />
|
||||||
{notFound ? (
|
{notFound ? (
|
||||||
<EmptyState
|
<EmptyState
|
||||||
message={t('provisioning.repository-status-page.not-found-message', 'Repository not found')}
|
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 { locationService } from '@grafana/runtime';
|
||||||
import { Badge, BadgeColor, IconName } from '@grafana/ui';
|
import { Badge, BadgeColor, IconName } from '@grafana/ui';
|
||||||
import { Repository } from 'app/api/clients/provisioning/v0alpha1';
|
import { Repository } from 'app/api/clients/provisioning/v0alpha1';
|
||||||
@@ -13,6 +14,26 @@ export function StatusBadge({ repo }: StatusBadgeProps) {
|
|||||||
return null;
|
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 tooltip: string | undefined = undefined;
|
||||||
let color: BadgeColor = 'purple';
|
let color: BadgeColor = 'purple';
|
||||||
let text = 'Unknown';
|
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"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -9039,6 +9039,7 @@
|
|||||||
"name-line-width": "Line width",
|
"name-line-width": "Line width",
|
||||||
"name-stacking": "Stacking"
|
"name-stacking": "Stacking"
|
||||||
},
|
},
|
||||||
|
"inline-token-warning-badge-tooltip": "The method to save the token is to re-enter it in the repository settings.",
|
||||||
"inspector": {
|
"inspector": {
|
||||||
"inspect-data-tab": {
|
"inspect-data-tab": {
|
||||||
"loading": "Loading",
|
"loading": "Loading",
|
||||||
@@ -11442,6 +11443,8 @@
|
|||||||
"title-delete-all-configured-repositories": "Delete all configured repositories",
|
"title-delete-all-configured-repositories": "Delete all configured repositories",
|
||||||
"title-legacy-storage-detected": "Legacy storage detected"
|
"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": {
|
"job-status": {
|
||||||
"label-view-details": "View details",
|
"label-view-details": "View details",
|
||||||
"loading-finished-job": "Loading finished job...",
|
"loading-finished-job": "Loading finished job...",
|
||||||
|
|||||||
Reference in New Issue
Block a user