mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
parent
52faf4cdec
commit
f3957539a5
8 changed files with 83 additions and 294 deletions
|
@ -22,7 +22,7 @@ const testBedConfig: TestBedConfig = {
|
|||
|
||||
const initTestBed = registerTestBed(WithAppDependencies(SnapshotRestoreHome), testBedConfig);
|
||||
|
||||
export interface HomeTestBed extends TestBed<HomeTestSubjects> {
|
||||
export interface HomeTestBed extends TestBed {
|
||||
actions: {
|
||||
clickReloadButton: () => void;
|
||||
selectRepositoryAt: (index: number) => void;
|
||||
|
@ -115,271 +115,3 @@ export const setup = async (): Promise<HomeTestBed> => {
|
|||
},
|
||||
};
|
||||
};
|
||||
|
||||
type HomeTestSubjects = TestSubjects | ThreeLevelDepth | NonVisibleTestSubjects;
|
||||
|
||||
type NonVisibleTestSubjects =
|
||||
| 'snapshotDetail.sectionLoading'
|
||||
| 'sectionLoading'
|
||||
| 'emptyPrompt'
|
||||
| 'emptyPrompt.documentationLink'
|
||||
| 'emptyPrompt.title'
|
||||
| 'emptyPrompt.registerRepositoryButton'
|
||||
| 'repositoryDetail.sectionLoading'
|
||||
| 'snapshotDetail.indexFailure';
|
||||
|
||||
type ThreeLevelDepth =
|
||||
| 'snapshotDetail.uuid.value'
|
||||
| 'snapshotDetail.state.value'
|
||||
| 'snapshotDetail.version.value'
|
||||
| 'snapshotDetail.includeGlobalState.value'
|
||||
| 'snapshotDetail.indices.title'
|
||||
| 'snapshotDetail.startTime.value'
|
||||
| 'snapshotDetail.endTime.value'
|
||||
| 'snapshotDetail.indexFailure.index'
|
||||
| 'snapshotDetail.indices.value';
|
||||
|
||||
export type TestSubjects =
|
||||
| 'appTitle'
|
||||
| 'cell'
|
||||
| 'cell.repositoryLink'
|
||||
| 'cell.snapshotLink'
|
||||
| 'checkboxSelectAll'
|
||||
| 'checkboxSelectRow-my-repo'
|
||||
| 'closeButton'
|
||||
| 'content'
|
||||
| 'content.documentationLink'
|
||||
| 'content.duration'
|
||||
| 'content.endTime'
|
||||
| 'content.includeGlobalState'
|
||||
| 'content.indices'
|
||||
| 'content.repositoryType'
|
||||
| 'content.snapshotCount'
|
||||
| 'content.startTime'
|
||||
| 'content.state'
|
||||
| 'content.title'
|
||||
| 'content.uuid'
|
||||
| 'content.value'
|
||||
| 'content.verifyRepositoryButton'
|
||||
| 'content.version'
|
||||
| 'deleteRepositoryButton'
|
||||
| 'detailTitle'
|
||||
| 'documentationLink'
|
||||
| 'duration'
|
||||
| 'duration.title'
|
||||
| 'duration.value'
|
||||
| 'editRepositoryButton'
|
||||
| 'endTime'
|
||||
| 'endTime.title'
|
||||
| 'endTime.value'
|
||||
| 'euiFlyoutCloseButton'
|
||||
| 'includeGlobalState'
|
||||
| 'includeGlobalState.title'
|
||||
| 'includeGlobalState.value'
|
||||
| 'indices'
|
||||
| 'indices.title'
|
||||
| 'indices.value'
|
||||
| 'registerRepositoryButton'
|
||||
| 'reloadButton'
|
||||
| 'repositoryDetail'
|
||||
| 'repositoryDetail.content'
|
||||
| 'repositoryDetail.documentationLink'
|
||||
| 'repositoryDetail.euiFlyoutCloseButton'
|
||||
| 'repositoryDetail.repositoryType'
|
||||
| 'repositoryDetail.snapshotCount'
|
||||
| 'repositoryDetail.srRepositoryDetailsDeleteActionButton'
|
||||
| 'repositoryDetail.srRepositoryDetailsFlyoutCloseButton'
|
||||
| 'repositoryDetail.title'
|
||||
| 'repositoryDetail.verifyRepositoryButton'
|
||||
| 'repositoryLink'
|
||||
| 'repositoryList'
|
||||
| 'repositoryList.cell'
|
||||
| 'repositoryList.checkboxSelectAll'
|
||||
| 'repositoryList.checkboxSelectRow-my-repo'
|
||||
| 'repositoryList.content'
|
||||
| 'repositoryList.deleteRepositoryButton'
|
||||
| 'repositoryList.documentationLink'
|
||||
| 'repositoryList.editRepositoryButton'
|
||||
| 'repositoryList.euiFlyoutCloseButton'
|
||||
| 'repositoryList.registerRepositoryButton'
|
||||
| 'repositoryList.reloadButton'
|
||||
| 'repositoryList.repositoryDetail'
|
||||
| 'repositoryList.repositoryLink'
|
||||
| 'repositoryList.repositoryTable'
|
||||
| 'repositoryList.repositoryType'
|
||||
| 'repositoryList.row'
|
||||
| 'repositoryList.snapshotCount'
|
||||
| 'repositoryList.srRepositoryDetailsDeleteActionButton'
|
||||
| 'repositoryList.srRepositoryDetailsFlyoutCloseButton'
|
||||
| 'repositoryList.tableHeaderCell_name_0'
|
||||
| 'repositoryList.tableHeaderCell_type_1'
|
||||
| 'repositoryList.tableHeaderSortButton'
|
||||
| 'repositoryList.title'
|
||||
| 'repositoryList.verifyRepositoryButton'
|
||||
| 'repositoryTable'
|
||||
| 'repositoryTable.cell'
|
||||
| 'repositoryTable.checkboxSelectAll'
|
||||
| 'repositoryTable.checkboxSelectRow-my-repo'
|
||||
| 'repositoryTable.deleteRepositoryButton'
|
||||
| 'repositoryTable.editRepositoryButton'
|
||||
| 'repositoryTable.repositoryLink'
|
||||
| 'repositoryTable.row'
|
||||
| 'repositoryTable.tableHeaderCell_name_0'
|
||||
| 'repositoryTable.tableHeaderCell_type_1'
|
||||
| 'repositoryTable.tableHeaderSortButton'
|
||||
| 'repositoryType'
|
||||
| 'row'
|
||||
| 'row.cell'
|
||||
| 'row.checkboxSelectRow-my-repo'
|
||||
| 'row.deleteRepositoryButton'
|
||||
| 'row.editRepositoryButton'
|
||||
| 'row.repositoryLink'
|
||||
| 'row.snapshotLink'
|
||||
| 'snapshotCount'
|
||||
| 'snapshotDetail'
|
||||
| 'snapshotDetail.closeButton'
|
||||
| 'snapshotDetail.content'
|
||||
| 'snapshotDetail.detailTitle'
|
||||
| 'snapshotDetail.duration'
|
||||
| 'snapshotDetail.endTime'
|
||||
| 'snapshotDetail.euiFlyoutCloseButton'
|
||||
| 'snapshotDetail.includeGlobalState'
|
||||
| 'snapshotDetail.indices'
|
||||
| 'snapshotDetail.repositoryLink'
|
||||
| 'snapshotDetail.startTime'
|
||||
| 'snapshotDetail.state'
|
||||
| 'snapshotDetail.tab'
|
||||
| 'snapshotDetail.title'
|
||||
| 'snapshotDetail.uuid'
|
||||
| 'snapshotDetail.value'
|
||||
| 'snapshotDetail.version'
|
||||
| 'snapshotLink'
|
||||
| 'snapshotList'
|
||||
| 'snapshotListEmpty'
|
||||
| 'snapshotList.cell'
|
||||
| 'snapshotList.closeButton'
|
||||
| 'snapshotList.content'
|
||||
| 'snapshotList.detailTitle'
|
||||
| 'snapshotList.duration'
|
||||
| 'snapshotList.endTime'
|
||||
| 'snapshotList.euiFlyoutCloseButton'
|
||||
| 'snapshotList.includeGlobalState'
|
||||
| 'snapshotList.indices'
|
||||
| 'snapshotList.reloadButton'
|
||||
| 'snapshotList.repositoryLink'
|
||||
| 'snapshotList.row'
|
||||
| 'snapshotList.snapshotDetail'
|
||||
| 'snapshotList.snapshotLink'
|
||||
| 'snapshotList.snapshotTable'
|
||||
| 'snapshotList.startTime'
|
||||
| 'snapshotList.state'
|
||||
| 'snapshotList.tab'
|
||||
| 'snapshotList.tableHeaderCell_durationInMillis_3'
|
||||
| 'snapshotList.tableHeaderCell_indices_4'
|
||||
| 'snapshotList.tableHeaderCell_repository_1'
|
||||
| 'snapshotList.tableHeaderCell_snapshot_0'
|
||||
| 'snapshotList.tableHeaderCell_startTimeInMillis_2'
|
||||
| 'snapshotList.tableHeaderSortButton'
|
||||
| 'snapshotList.title'
|
||||
| 'snapshotList.uuid'
|
||||
| 'snapshotList.value'
|
||||
| 'snapshotList.version'
|
||||
| 'snapshotRestoreApp'
|
||||
| 'snapshotRestoreApp.appTitle'
|
||||
| 'snapshotRestoreApp.cell'
|
||||
| 'snapshotRestoreApp.checkboxSelectAll'
|
||||
| 'snapshotRestoreApp.checkboxSelectRow-my-repo'
|
||||
| 'snapshotRestoreApp.closeButton'
|
||||
| 'snapshotRestoreApp.content'
|
||||
| 'snapshotRestoreApp.deleteRepositoryButton'
|
||||
| 'snapshotRestoreApp.detailTitle'
|
||||
| 'snapshotRestoreApp.documentationLink'
|
||||
| 'snapshotRestoreApp.duration'
|
||||
| 'snapshotRestoreApp.editRepositoryButton'
|
||||
| 'snapshotRestoreApp.endTime'
|
||||
| 'snapshotRestoreApp.euiFlyoutCloseButton'
|
||||
| 'snapshotRestoreApp.includeGlobalState'
|
||||
| 'snapshotRestoreApp.indices'
|
||||
| 'snapshotRestoreApp.registerRepositoryButton'
|
||||
| 'snapshotRestoreApp.reloadButton'
|
||||
| 'snapshotRestoreApp.repositoryDetail'
|
||||
| 'snapshotRestoreApp.repositoryLink'
|
||||
| 'snapshotRestoreApp.repositoryList'
|
||||
| 'snapshotRestoreApp.repositoryTable'
|
||||
| 'snapshotRestoreApp.repositoryType'
|
||||
| 'snapshotRestoreApp.row'
|
||||
| 'snapshotRestoreApp.snapshotCount'
|
||||
| 'snapshotRestoreApp.snapshotDetail'
|
||||
| 'snapshotRestoreApp.snapshotLink'
|
||||
| 'snapshotRestoreApp.snapshotList'
|
||||
| 'snapshotRestoreApp.snapshotTable'
|
||||
| 'snapshotRestoreApp.srRepositoryDetailsDeleteActionButton'
|
||||
| 'snapshotRestoreApp.srRepositoryDetailsFlyoutCloseButton'
|
||||
| 'snapshotRestoreApp.startTime'
|
||||
| 'snapshotRestoreApp.state'
|
||||
| 'snapshotRestoreApp.tab'
|
||||
| 'snapshotRestoreApp.tableHeaderCell_durationInMillis_3'
|
||||
| 'snapshotRestoreApp.tableHeaderCell_indices_4'
|
||||
| 'snapshotRestoreApp.tableHeaderCell_name_0'
|
||||
| 'snapshotRestoreApp.tableHeaderCell_repository_1'
|
||||
| 'snapshotRestoreApp.tableHeaderCell_snapshot_0'
|
||||
| 'snapshotRestoreApp.tableHeaderCell_startTimeInMillis_2'
|
||||
| 'snapshotRestoreApp.tableHeaderCell_type_1'
|
||||
| 'snapshotRestoreApp.tableHeaderSortButton'
|
||||
| 'snapshotRestoreApp.title'
|
||||
| 'snapshotRestoreApp.uuid'
|
||||
| 'snapshotRestoreApp.value'
|
||||
| 'snapshotRestoreApp.verifyRepositoryButton'
|
||||
| 'snapshotRestoreApp.version'
|
||||
| 'snapshotTable'
|
||||
| 'snapshotTable.cell'
|
||||
| 'snapshotTable.repositoryLink'
|
||||
| 'snapshotTable.row'
|
||||
| 'snapshotTable.snapshotLink'
|
||||
| 'snapshotTable.tableHeaderCell_durationInMillis_3'
|
||||
| 'snapshotTable.tableHeaderCell_indices_4'
|
||||
| 'snapshotTable.tableHeaderCell_repository_1'
|
||||
| 'snapshotTable.tableHeaderCell_snapshot_0'
|
||||
| 'snapshotTable.tableHeaderCell_startTimeInMillis_2'
|
||||
| 'snapshotTable.tableHeaderSortButton'
|
||||
| 'srRepositoryDetailsDeleteActionButton'
|
||||
| 'srRepositoryDetailsFlyoutCloseButton'
|
||||
| 'startTime'
|
||||
| 'startTime.title'
|
||||
| 'startTime.value'
|
||||
| 'state'
|
||||
| 'state.title'
|
||||
| 'state.value'
|
||||
| 'repositories_tab'
|
||||
| 'snapshots_tab'
|
||||
| 'policies_tab'
|
||||
| 'restore_status_tab'
|
||||
| 'tableHeaderCell_durationInMillis_3'
|
||||
| 'tableHeaderCell_durationInMillis_3.tableHeaderSortButton'
|
||||
| 'tableHeaderCell_indices_4'
|
||||
| 'tableHeaderCell_indices_4.tableHeaderSortButton'
|
||||
| 'tableHeaderCell_name_0'
|
||||
| 'tableHeaderCell_name_0.tableHeaderSortButton'
|
||||
| 'tableHeaderCell_repository_1'
|
||||
| 'tableHeaderCell_repository_1.tableHeaderSortButton'
|
||||
| 'tableHeaderCell_shards.failed_6'
|
||||
| 'tableHeaderCell_shards.total_5'
|
||||
| 'tableHeaderCell_snapshot_0'
|
||||
| 'tableHeaderCell_snapshot_0.tableHeaderSortButton'
|
||||
| 'tableHeaderCell_startTimeInMillis_2'
|
||||
| 'tableHeaderCell_startTimeInMillis_2.tableHeaderSortButton'
|
||||
| 'tableHeaderCell_type_1'
|
||||
| 'tableHeaderCell_type_1.tableHeaderSortButton'
|
||||
| 'tableHeaderSortButton'
|
||||
| 'title'
|
||||
| 'uuid'
|
||||
| 'uuid.title'
|
||||
| 'uuid.value'
|
||||
| 'value'
|
||||
| 'verifyRepositoryButton'
|
||||
| 'version'
|
||||
| 'version.title'
|
||||
| 'version.value'
|
||||
| 'maxSnapshotsWarning'
|
||||
| 'repositoryErrorsWarning'
|
||||
| 'repositoryErrorsPrompt';
|
||||
|
|
|
@ -92,11 +92,12 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => {
|
|||
|
||||
const setCleanupRepositoryResponse = (response?: HttpResponse, error?: any) => {
|
||||
const status = error ? error.status || 503 : 200;
|
||||
const body = error ? JSON.stringify(error) : JSON.stringify(response);
|
||||
|
||||
server.respondWith('POST', `${API_BASE_PATH}repositories/:name/cleanup`, [
|
||||
status,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify(response),
|
||||
body,
|
||||
]);
|
||||
};
|
||||
|
||||
|
|
|
@ -372,6 +372,60 @@ describe('<SnapshotRestoreHome />', () => {
|
|||
expect(latestRequest.method).toBe('GET');
|
||||
expect(latestRequest.url).toBe(`${API_BASE_PATH}repositories/${repo1.name}/verify`);
|
||||
});
|
||||
|
||||
describe('clean repository', () => {
|
||||
test('shows results when request succeeds', async () => {
|
||||
httpRequestsMockHelpers.setCleanupRepositoryResponse({
|
||||
cleanup: {
|
||||
cleaned: true,
|
||||
response: {
|
||||
results: {
|
||||
deleted_bytes: 0,
|
||||
deleted_blobs: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const { exists, find, component } = testBed;
|
||||
await act(async () => {
|
||||
find('repositoryDetail.cleanupRepositoryButton').simulate('click');
|
||||
});
|
||||
component.update();
|
||||
|
||||
const latestRequest = server.requests[server.requests.length - 1];
|
||||
expect(latestRequest.method).toBe('POST');
|
||||
expect(latestRequest.url).toBe(`${API_BASE_PATH}repositories/${repo1.name}/cleanup`);
|
||||
|
||||
expect(exists('repositoryDetail.cleanupCodeBlock')).toBe(true);
|
||||
expect(exists('repositoryDetail.cleanupError')).toBe(false);
|
||||
});
|
||||
|
||||
test('shows error when success fails', async () => {
|
||||
httpRequestsMockHelpers.setCleanupRepositoryResponse({
|
||||
cleanup: {
|
||||
cleaned: false,
|
||||
error: {
|
||||
message: 'Error message',
|
||||
statusCode: 400,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const { exists, find, component } = testBed;
|
||||
await act(async () => {
|
||||
find('repositoryDetail.cleanupRepositoryButton').simulate('click');
|
||||
});
|
||||
component.update();
|
||||
|
||||
const latestRequest = server.requests[server.requests.length - 1];
|
||||
expect(latestRequest.method).toBe('POST');
|
||||
expect(latestRequest.url).toBe(`${API_BASE_PATH}repositories/${repo1.name}/cleanup`);
|
||||
|
||||
expect(exists('repositoryDetail.cleanupCodeBlock')).toBe(false);
|
||||
expect(exists('repositoryDetail.cleanupError')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the repository has been fetched (and has snapshots)', () => {
|
||||
|
|
|
@ -356,21 +356,16 @@ export const RepositoryDetails: React.FunctionComponent<Props> = ({
|
|||
</EuiCodeBlock>
|
||||
</div>
|
||||
) : (
|
||||
<EuiCallOut
|
||||
color="danger"
|
||||
iconType="alert"
|
||||
title={i18n.translate('xpack.snapshotRestore.repositoryDetails.cleanupErrorTitle', {
|
||||
defaultMessage: 'Sorry, there was an error cleaning the repository.',
|
||||
})}
|
||||
>
|
||||
<p>
|
||||
{cleanup.error
|
||||
? JSON.stringify(cleanup.error)
|
||||
: i18n.translate('xpack.snapshotRestore.repositoryDetails.cleanupUnknownError', {
|
||||
defaultMessage: '503: Unknown error',
|
||||
})}
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<SectionError
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.snapshotRestore.repositoryDetails.cleanupErrorTitle"
|
||||
defaultMessage="Error cleaning repository"
|
||||
/>
|
||||
}
|
||||
error={cleanup.error as Error}
|
||||
data-test-subj="cleanupError"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
|
|
|
@ -34,7 +34,7 @@ export const wrapEsError = (err: any, statusCodeToMessageMap: any = {}) => {
|
|||
root_cause = [], // eslint-disable-line @typescript-eslint/naming-convention
|
||||
caused_by = {}, // eslint-disable-line @typescript-eslint/naming-convention
|
||||
} = {},
|
||||
} = JSON.parse(response);
|
||||
} = typeof response === 'string' ? JSON.parse(response) : response;
|
||||
|
||||
// If no custom message if specified for the error's status code, just
|
||||
// wrap the error as a Boom error response, include the additional information from ES, and return it
|
||||
|
|
|
@ -233,12 +233,21 @@ export function registerRepositoriesRoutes({
|
|||
try {
|
||||
const { body: cleanupResults } = await clusterClient.asCurrentUser.snapshot
|
||||
.cleanupRepository({ name })
|
||||
.catch((e) => ({
|
||||
body: {
|
||||
cleaned: false,
|
||||
error: e.response ? JSON.parse(e.response) : e,
|
||||
},
|
||||
}));
|
||||
.catch((e) => {
|
||||
// This API returns errors in a non-standard format, which we'll need to
|
||||
// munge to be compatible with wrapEsError.
|
||||
const normalizedError = {
|
||||
statusCode: e.meta.body.status,
|
||||
response: e.meta.body,
|
||||
};
|
||||
|
||||
return {
|
||||
body: {
|
||||
cleaned: false,
|
||||
error: wrapEsError(normalizedError),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return res.ok({
|
||||
body: {
|
||||
|
|
|
@ -23236,7 +23236,6 @@
|
|||
"xpack.snapshotRestore.repositoryDetails.cleanupErrorTitle": "申し訳ありません。リポジトリのクリーンアップ中にエラーが発生しました。",
|
||||
"xpack.snapshotRestore.repositoryDetails.cleanupRepositoryMessage": "スナップショットから参照されていないデータを削除するには、リポジトリをクリーンアップすることができます。これにより、ストレージ領域を解放できる場合があります。注:定期的にスナップショットを削除する場合は、この機能の利点が得られない可能性が高いため、使用頻度を低くしてください。",
|
||||
"xpack.snapshotRestore.repositoryDetails.cleanupTitle": "リポジトリのクリーンアップ",
|
||||
"xpack.snapshotRestore.repositoryDetails.cleanupUnknownError": "503:不明なエラー",
|
||||
"xpack.snapshotRestore.repositoryDetails.closeButtonLabel": "閉じる",
|
||||
"xpack.snapshotRestore.repositoryDetails.editButtonLabel": "編集",
|
||||
"xpack.snapshotRestore.repositoryDetails.genericSettingsDescription": "レポジトリ「{name}」のランダムな設定です",
|
||||
|
|
|
@ -23625,7 +23625,6 @@
|
|||
"xpack.snapshotRestore.repositoryDetails.cleanupErrorTitle": "抱歉,清理存储库时出错。",
|
||||
"xpack.snapshotRestore.repositoryDetails.cleanupRepositoryMessage": "您可以清理存储库,以从快照中删除任何未引用的数据。这可节省存储空间。注意:如果定时删除快照,此功能可能并不那么有用,不应频繁使用。",
|
||||
"xpack.snapshotRestore.repositoryDetails.cleanupTitle": "存储库清理",
|
||||
"xpack.snapshotRestore.repositoryDetails.cleanupUnknownError": "503:未知错误",
|
||||
"xpack.snapshotRestore.repositoryDetails.closeButtonLabel": "关闭",
|
||||
"xpack.snapshotRestore.repositoryDetails.editButtonLabel": "编辑",
|
||||
"xpack.snapshotRestore.repositoryDetails.genericSettingsDescription": "存储库“{name}”的只读设置",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue