From a0e17737c006631a018edc0e4258642f9ecc8708 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Thu, 12 Dec 2019 23:04:30 -0500 Subject: [PATCH 01/14] Added repository cleanup button. Added logic for spinner while loading, added new repository request, type and telemetry metric. --- .../common/types/repository.ts | 12 +++ .../public/app/constants/index.ts | 1 + .../repository_details/repository_details.tsx | 99 ++++++++++++++++++- .../app/services/http/repository_requests.ts | 12 +++ 4 files changed, 122 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts b/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts index 5900d53afa0b4..8561aacf343b5 100644 --- a/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts +++ b/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts @@ -156,4 +156,16 @@ export interface InvalidRepositoryVerification { error: object; } +export interface ValidRepositoryCleanup { + cleaned: true; + response: object; +} + +export interface InvalidRepositoryCleanup { + cleaned: false; + error: object; +} + export type RepositoryVerification = ValidRepositoryVerification | InvalidRepositoryVerification; + +export type RepositoryCleanup = ValidRepositoryCleanup | InvalidRepositoryCleanup; diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/constants/index.ts b/x-pack/legacy/plugins/snapshot_restore/public/app/constants/index.ts index 844394deb4f8d..481516479df4e 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/constants/index.ts +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/constants/index.ts @@ -103,6 +103,7 @@ export const UIM_REPOSITORY_DELETE = 'repository_delete'; export const UIM_REPOSITORY_DELETE_MANY = 'repository_delete_many'; export const UIM_REPOSITORY_SHOW_DETAILS_CLICK = 'repository_show_details_click'; export const UIM_REPOSITORY_DETAIL_PANEL_VERIFY = 'repository_detail_panel_verify'; +export const UIM_REPOSITORY_DETAIL_PANEL_CLEANUP = 'repository_detail_panel_cleanup'; export const UIM_SNAPSHOT_LIST_LOAD = 'snapshot_list_load'; export const UIM_SNAPSHOT_SHOW_DETAILS_CLICK = 'snapshot_show_details_click'; export const UIM_SNAPSHOT_DETAIL_PANEL_SUMMARY_TAB = 'snapshot_detail_panel_summary_tab'; diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx index c03162bae8bd2..3d2092d12e591 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx @@ -28,12 +28,17 @@ import { documentationLinksService } from '../../../../services/documentation'; import { useLoadRepository, verifyRepository as verifyRepositoryRequest, + cleanupRepository as cleanupRepositoryRequest, } from '../../../../services/http'; import { textService } from '../../../../services/text'; import { linkToSnapshots, linkToEditRepository } from '../../../../services/navigation'; import { REPOSITORY_TYPES } from '../../../../../../common/constants'; -import { Repository, RepositoryVerification } from '../../../../../../common/types'; +import { + Repository, + RepositoryVerification, + RepositoryCleanup, +} from '../../../../../../common/types'; import { RepositoryDeleteProvider, SectionError, @@ -61,7 +66,9 @@ export const RepositoryDetails: React.FunctionComponent = ({ const { FormattedMessage } = i18n; const { error, data: repositoryDetails } = useLoadRepository(repositoryName); const [verification, setVerification] = useState(undefined); + const [cleanup, setCleanup] = useState(undefined); const [isLoadingVerification, setIsLoadingVerification] = useState(false); + const [isLoadingCleanup, setIsLoadingCleanup] = useState(false); const verifyRepository = async () => { setIsLoadingVerification(true); @@ -70,11 +77,20 @@ export const RepositoryDetails: React.FunctionComponent = ({ setIsLoadingVerification(false); }; - // Reset verification state when repository name changes, either from adjust URL or clicking + const cleanupRepository = async () => { + setIsLoadingCleanup(true); + const { data } = await cleanupRepositoryRequest(repositoryName); + setCleanup(data); + setIsLoadingCleanup(false); + }; + + // Reset verification state and cleanup when repository name changes, either from adjust URL or clicking // into a different repository in table list. useEffect(() => { setVerification(undefined); setIsLoadingVerification(false); + setCleanup(undefined); + setIsLoadingCleanup(false); }, [repositoryName]); const renderBody = () => { @@ -231,6 +247,8 @@ export const RepositoryDetails: React.FunctionComponent = ({ {renderVerification()} + + {renderCleanup()} ); }; @@ -318,6 +336,83 @@ export const RepositoryDetails: React.FunctionComponent = ({ ); + const renderCleanup = () => ( + + +

+ +

+
+ {cleanup ? ( + + + +

+ +

+
+ + {cleanup ? ( + + } + /> + ) : null} + + + + +
+ ) : ( + + + + + + + )} +
+ ); + const renderFooter = () => { return ( diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/services/http/repository_requests.ts b/x-pack/legacy/plugins/snapshot_restore/public/app/services/http/repository_requests.ts index 171e949ccee75..a2d8e5ea00300 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/services/http/repository_requests.ts +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/services/http/repository_requests.ts @@ -11,6 +11,7 @@ import { UIM_REPOSITORY_DELETE, UIM_REPOSITORY_DELETE_MANY, UIM_REPOSITORY_DETAIL_PANEL_VERIFY, + UIM_REPOSITORY_DETAIL_PANEL_CLEANUP, } from '../../constants'; import { uiMetricService } from '../ui_metric'; import { httpService } from './http'; @@ -44,6 +45,17 @@ export const verifyRepository = async (name: Repository['name']) => { return result; }; +export const cleanupRepository = async (name: Repository['name']) => { + const result = await sendRequest({ + path: httpService.addBasePath(`_snapshot/${encodeURIComponent(name)}/_cleanup`), + method: 'post', + }); + + const { trackUiMetric } = uiMetricService; + trackUiMetric(UIM_REPOSITORY_DETAIL_PANEL_CLEANUP); + return result; +}; + export const useLoadRepositoryTypes = () => { return useRequest({ path: httpService.addBasePath(`${API_BASE_PATH}repository_types`), From 77c90769d53d928aa32eeffcbf11e38722d7efaf Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Fri, 13 Dec 2019 16:51:06 -0500 Subject: [PATCH 02/14] Added additional bindings for server side to hit the cleanup endpoint. --- src/core/server/elasticsearch/api_types.ts | 2 ++ .../core_plugins/elasticsearch/index.d.ts | 2 ++ .../repository_details/repository_details.tsx | 2 +- .../app/services/http/repository_requests.ts | 5 +++- .../server/routes/api/repositories.ts | 26 +++++++++++++++++++ 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/core/server/elasticsearch/api_types.ts b/src/core/server/elasticsearch/api_types.ts index 5f2b61eb4935f..2388d9b89fb75 100644 --- a/src/core/server/elasticsearch/api_types.ts +++ b/src/core/server/elasticsearch/api_types.ts @@ -143,6 +143,7 @@ import { TasksCancelParams, TasksGetParams, TasksListParams, + SnapshotCleanupRepositoryParams, } from 'elasticsearch'; /** @@ -298,6 +299,7 @@ export interface APICaller { (endpoint: 'snapshot.restore', params: SnapshotRestoreParams, options?: CallAPIOptions): ReturnType; (endpoint: 'snapshot.status', params: SnapshotStatusParams, options?: CallAPIOptions): ReturnType; (endpoint: 'snapshot.verifyRepository', params: SnapshotVerifyRepositoryParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'snapshot.cleanupRepository', params: SnapshotCleanupRepositoryParams, options?: CallAPIOptions): ReturnType; // tasks namespace (endpoint: 'tasks.cancel', params: TasksCancelParams, options?: CallAPIOptions): ReturnType; diff --git a/src/legacy/core_plugins/elasticsearch/index.d.ts b/src/legacy/core_plugins/elasticsearch/index.d.ts index 4cbb1c82cc1e4..b0df5f071b904 100644 --- a/src/legacy/core_plugins/elasticsearch/index.d.ts +++ b/src/legacy/core_plugins/elasticsearch/index.d.ts @@ -140,6 +140,7 @@ import { SnapshotRestoreParams, SnapshotStatusParams, SnapshotVerifyRepositoryParams, + SnapshotCleanupRepositoryParams, // tasks TasksCancelParams, TasksGetParams, @@ -341,6 +342,7 @@ export interface CallClusterWithRequest { (request: Request, endpoint: 'snapshot.restore', params: SnapshotRestoreParams, options?: CallClusterOptions): ReturnType; (request: Request, endpoint: 'snapshot.status', params: SnapshotStatusParams, options?: CallClusterOptions): ReturnType; (request: Request, endpoint: 'snapshot.verifyRepository', params: SnapshotVerifyRepositoryParams, options?: CallClusterOptions): ReturnType; + (request: Request, endpoint: 'snapshot.cleanupRepository', params: SnapshotCleanupRepositoryParams, options?: CallClusterOptions): ReturnType; // tasks namespace (request: Request, endpoint: 'tasks.cancel', params: TasksCancelParams, options?: CallClusterOptions): ReturnType; diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx index 3d2092d12e591..8b03644af6fb8 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx @@ -80,7 +80,7 @@ export const RepositoryDetails: React.FunctionComponent = ({ const cleanupRepository = async () => { setIsLoadingCleanup(true); const { data } = await cleanupRepositoryRequest(repositoryName); - setCleanup(data); + setCleanup(data.cleanup); setIsLoadingCleanup(false); }; diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/services/http/repository_requests.ts b/x-pack/legacy/plugins/snapshot_restore/public/app/services/http/repository_requests.ts index a2d8e5ea00300..b92f21ea6a9b6 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/services/http/repository_requests.ts +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/services/http/repository_requests.ts @@ -47,8 +47,11 @@ export const verifyRepository = async (name: Repository['name']) => { export const cleanupRepository = async (name: Repository['name']) => { const result = await sendRequest({ - path: httpService.addBasePath(`_snapshot/${encodeURIComponent(name)}/_cleanup`), + path: httpService.addBasePath( + `${API_BASE_PATH}repositories/${encodeURIComponent(name)}/cleanup` + ), method: 'post', + body: undefined, }); const { trackUiMetric } = uiMetricService; diff --git a/x-pack/legacy/plugins/snapshot_restore/server/routes/api/repositories.ts b/x-pack/legacy/plugins/snapshot_restore/server/routes/api/repositories.ts index 13f44d2a1aeeb..c394bafeef1f0 100644 --- a/x-pack/legacy/plugins/snapshot_restore/server/routes/api/repositories.ts +++ b/x-pack/legacy/plugins/snapshot_restore/server/routes/api/repositories.ts @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { cleanup } from '@testing-library/react'; import { Router, RouterRouteHandler } from '../../../../../server/lib/create_router'; import { wrapCustomError, @@ -15,6 +16,7 @@ import { RepositoryType, RepositoryVerification, SlmPolicyEs, + RepositoryCleanup, } from '../../../common/types'; import { Plugins } from '../../../shim'; @@ -34,6 +36,7 @@ export function registerRepositoriesRoutes(router: Router, plugins: Plugins) { router.get('repositories', getAllHandler); router.get('repositories/{name}', getOneHandler); router.get('repositories/{name}/verify', getVerificationHandler); + router.post('repositories/{name}/cleanup', getCleanupHandler); router.put('repositories', createHandler); router.put('repositories/{name}', updateHandler); router.delete('repositories/{names}', deleteHandler); @@ -172,6 +175,29 @@ export const getVerificationHandler: RouterRouteHandler = async ( }; }; +export const getCleanupHandler: RouterRouteHandler = async ( + req, + callWithRequest +): Promise<{ + cleanup: RepositoryCleanup | {}; +}> => { + const { name } = req.params; + const cleanupResults = await callWithRequest('snapshot.cleanupRepository', { + repository: name, + }).catch(e => ({ + cleaned: false, + error: e.response ? JSON.parse(e.response) : e, + })); + return { + cleanup: cleanupResults.errorgi + ? cleanupResults + : { + cleaned: true, + response: cleanupResults, + }, + }; +}; + export const getTypesHandler: RouterRouteHandler = async () => { // In ECE/ESS, do not enable the default types const types: RepositoryType[] = isCloudEnabled ? [] : [...DEFAULT_REPOSITORY_TYPES]; From a3f48b6a844d681899e5125f4782b961265b4466 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Tue, 17 Dec 2019 09:15:04 -0500 Subject: [PATCH 03/14] fix cleanup request --- src/core/server/elasticsearch/api_types.ts | 2 -- .../core_plugins/elasticsearch/index.d.ts | 2 -- .../common/types/repository.ts | 12 -------- ...asticsearch_slm.ts => elasticsearch_sr.ts} | 30 ++++++++++++++----- .../server/routes/api/policy.ts | 18 +++++------ .../server/routes/api/repositories.ts | 11 +++---- .../server/routes/api/snapshots.ts | 2 +- .../plugins/snapshot_restore/server/shim.ts | 2 +- 8 files changed, 39 insertions(+), 40 deletions(-) rename x-pack/legacy/plugins/snapshot_restore/server/client/{elasticsearch_slm.ts => elasticsearch_sr.ts} (73%) diff --git a/src/core/server/elasticsearch/api_types.ts b/src/core/server/elasticsearch/api_types.ts index 2388d9b89fb75..5f2b61eb4935f 100644 --- a/src/core/server/elasticsearch/api_types.ts +++ b/src/core/server/elasticsearch/api_types.ts @@ -143,7 +143,6 @@ import { TasksCancelParams, TasksGetParams, TasksListParams, - SnapshotCleanupRepositoryParams, } from 'elasticsearch'; /** @@ -299,7 +298,6 @@ export interface APICaller { (endpoint: 'snapshot.restore', params: SnapshotRestoreParams, options?: CallAPIOptions): ReturnType; (endpoint: 'snapshot.status', params: SnapshotStatusParams, options?: CallAPIOptions): ReturnType; (endpoint: 'snapshot.verifyRepository', params: SnapshotVerifyRepositoryParams, options?: CallAPIOptions): ReturnType; - (endpoint: 'snapshot.cleanupRepository', params: SnapshotCleanupRepositoryParams, options?: CallAPIOptions): ReturnType; // tasks namespace (endpoint: 'tasks.cancel', params: TasksCancelParams, options?: CallAPIOptions): ReturnType; diff --git a/src/legacy/core_plugins/elasticsearch/index.d.ts b/src/legacy/core_plugins/elasticsearch/index.d.ts index b0df5f071b904..4cbb1c82cc1e4 100644 --- a/src/legacy/core_plugins/elasticsearch/index.d.ts +++ b/src/legacy/core_plugins/elasticsearch/index.d.ts @@ -140,7 +140,6 @@ import { SnapshotRestoreParams, SnapshotStatusParams, SnapshotVerifyRepositoryParams, - SnapshotCleanupRepositoryParams, // tasks TasksCancelParams, TasksGetParams, @@ -342,7 +341,6 @@ export interface CallClusterWithRequest { (request: Request, endpoint: 'snapshot.restore', params: SnapshotRestoreParams, options?: CallClusterOptions): ReturnType; (request: Request, endpoint: 'snapshot.status', params: SnapshotStatusParams, options?: CallClusterOptions): ReturnType; (request: Request, endpoint: 'snapshot.verifyRepository', params: SnapshotVerifyRepositoryParams, options?: CallClusterOptions): ReturnType; - (request: Request, endpoint: 'snapshot.cleanupRepository', params: SnapshotCleanupRepositoryParams, options?: CallClusterOptions): ReturnType; // tasks namespace (request: Request, endpoint: 'tasks.cancel', params: TasksCancelParams, options?: CallClusterOptions): ReturnType; diff --git a/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts b/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts index 8561aacf343b5..5900d53afa0b4 100644 --- a/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts +++ b/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts @@ -156,16 +156,4 @@ export interface InvalidRepositoryVerification { error: object; } -export interface ValidRepositoryCleanup { - cleaned: true; - response: object; -} - -export interface InvalidRepositoryCleanup { - cleaned: false; - error: object; -} - export type RepositoryVerification = ValidRepositoryVerification | InvalidRepositoryVerification; - -export type RepositoryCleanup = ValidRepositoryCleanup | InvalidRepositoryCleanup; diff --git a/x-pack/legacy/plugins/snapshot_restore/server/client/elasticsearch_slm.ts b/x-pack/legacy/plugins/snapshot_restore/server/client/elasticsearch_sr.ts similarity index 73% rename from x-pack/legacy/plugins/snapshot_restore/server/client/elasticsearch_slm.ts rename to x-pack/legacy/plugins/snapshot_restore/server/client/elasticsearch_sr.ts index 82fe30aaa7d2e..794bf99c3d918 100644 --- a/x-pack/legacy/plugins/snapshot_restore/server/client/elasticsearch_slm.ts +++ b/x-pack/legacy/plugins/snapshot_restore/server/client/elasticsearch_sr.ts @@ -7,10 +7,10 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) => { const ca = components.clientAction.factory; - Client.prototype.slm = components.clientAction.namespaceFactory(); - const slm = Client.prototype.slm.prototype; + Client.prototype.sr = components.clientAction.namespaceFactory(); + const sr = Client.prototype.sr.prototype; - slm.policies = ca({ + sr.policies = ca({ urls: [ { fmt: '/_slm/policy', @@ -19,7 +19,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) method: 'GET', }); - slm.policy = ca({ + sr.policy = ca({ urls: [ { fmt: '/_slm/policy/<%=name%>', @@ -33,7 +33,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) method: 'GET', }); - slm.deletePolicy = ca({ + sr.deletePolicy = ca({ urls: [ { fmt: '/_slm/policy/<%=name%>', @@ -47,7 +47,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) method: 'DELETE', }); - slm.executePolicy = ca({ + sr.executePolicy = ca({ urls: [ { fmt: '/_slm/policy/<%=name%>/_execute', @@ -61,7 +61,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) method: 'PUT', }); - slm.updatePolicy = ca({ + sr.updatePolicy = ca({ urls: [ { fmt: '/_slm/policy/<%=name%>', @@ -75,7 +75,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) method: 'PUT', }); - slm.executeRetention = ca({ + sr.executeRetention = ca({ urls: [ { fmt: '/_slm/_execute_retention', @@ -83,4 +83,18 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) ], method: 'POST', }); + + sr.cleanupRepository = ca({ + urls: [ + { + fmt: '/_snapshot/<%=name%>/_cleanup', + req: { + name: { + type: 'string', + }, + }, + }, + ], + method: 'POST', + }); }; diff --git a/x-pack/legacy/plugins/snapshot_restore/server/routes/api/policy.ts b/x-pack/legacy/plugins/snapshot_restore/server/routes/api/policy.ts index bbfc82b8a6de9..9f434ac10c16a 100644 --- a/x-pack/legacy/plugins/snapshot_restore/server/routes/api/policy.ts +++ b/x-pack/legacy/plugins/snapshot_restore/server/routes/api/policy.ts @@ -40,7 +40,7 @@ export const getAllHandler: RouterRouteHandler = async ( // Get policies const policiesByName: { [key: string]: SlmPolicyEs; - } = await callWithRequest('slm.policies', { + } = await callWithRequest('sr.policies', { human: true, }); @@ -62,7 +62,7 @@ export const getOneHandler: RouterRouteHandler = async ( const { name } = req.params; const policiesByName: { [key: string]: SlmPolicyEs; - } = await callWithRequest('slm.policy', { + } = await callWithRequest('sr.policy', { name, human: true, }); @@ -82,7 +82,7 @@ export const getOneHandler: RouterRouteHandler = async ( export const executeHandler: RouterRouteHandler = async (req, callWithRequest) => { const { name } = req.params; - const { snapshot_name: snapshotName } = await callWithRequest('slm.executePolicy', { + const { snapshot_name: snapshotName } = await callWithRequest('sr.executePolicy', { name, }); return { snapshotName }; @@ -98,7 +98,7 @@ export const deleteHandler: RouterRouteHandler = async (req, callWithRequest) => await Promise.all( policyNames.map(name => { - return callWithRequest('slm.deletePolicy', { name }) + return callWithRequest('sr.deletePolicy', { name }) .then(() => response.itemsDeleted.push(name)) .catch(e => response.errors.push({ @@ -122,7 +122,7 @@ export const createHandler: RouterRouteHandler = async (req, callWithRequest) => // Check that policy with the same name doesn't already exist try { - const policyByName = await callWithRequest('slm.policy', { name }); + const policyByName = await callWithRequest('sr.policy', { name }); if (policyByName[name]) { throw conflictError; } @@ -134,7 +134,7 @@ export const createHandler: RouterRouteHandler = async (req, callWithRequest) => } // Otherwise create new policy - return await callWithRequest('slm.updatePolicy', { + return await callWithRequest('sr.updatePolicy', { name, body: serializePolicy(policy), }); @@ -146,10 +146,10 @@ export const updateHandler: RouterRouteHandler = async (req, callWithRequest) => // Check that policy with the given name exists // If it doesn't exist, 404 will be thrown by ES and will be returned - await callWithRequest('slm.policy', { name }); + await callWithRequest('sr.policy', { name }); // Otherwise update policy - return await callWithRequest('slm.updatePolicy', { + return await callWithRequest('sr.updatePolicy', { name, body: serializePolicy(policy), }); @@ -210,5 +210,5 @@ export const updateRetentionSettingsHandler: RouterRouteHandler = async (req, ca }; export const executeRetentionHandler: RouterRouteHandler = async (_req, callWithRequest) => { - return await callWithRequest('slm.executeRetention'); + return await callWithRequest('sr.executeRetention'); }; diff --git a/x-pack/legacy/plugins/snapshot_restore/server/routes/api/repositories.ts b/x-pack/legacy/plugins/snapshot_restore/server/routes/api/repositories.ts index 324c03d9c84c3..3d67494da4aad 100644 --- a/x-pack/legacy/plugins/snapshot_restore/server/routes/api/repositories.ts +++ b/x-pack/legacy/plugins/snapshot_restore/server/routes/api/repositories.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { cleanup } from '@testing-library/react'; import { Router, RouterRouteHandler } from '../../../../../server/lib/create_router'; import { wrapCustomError, @@ -77,7 +76,7 @@ export const getAllHandler: RouterRouteHandler = async ( try { const policiesByName: { [key: string]: SlmPolicyEs; - } = await callWithRequest('slm.policies', { + } = await callWithRequest('sr.policies', { human: true, }); const managedRepositoryPolicy = Object.entries(policiesByName) @@ -182,14 +181,16 @@ export const getCleanupHandler: RouterRouteHandler = async ( cleanup: RepositoryCleanup | {}; }> => { const { name } = req.params; - const cleanupResults = await callWithRequest('snapshot.cleanupRepository', { - repository: name, + + const cleanupResults = await callWithRequest('sr.cleanupRepository', { + name, }).catch(e => ({ cleaned: false, error: e.response ? JSON.parse(e.response) : e, })); + return { - cleanup: cleanupResults.errorgi + cleanup: cleanupResults.error ? cleanupResults : { cleaned: true, diff --git a/x-pack/legacy/plugins/snapshot_restore/server/routes/api/snapshots.ts b/x-pack/legacy/plugins/snapshot_restore/server/routes/api/snapshots.ts index 042a2dfeaf6b5..0d34d6a6b1b31 100644 --- a/x-pack/legacy/plugins/snapshot_restore/server/routes/api/snapshots.ts +++ b/x-pack/legacy/plugins/snapshot_restore/server/routes/api/snapshots.ts @@ -38,7 +38,7 @@ export const getAllHandler: RouterRouteHandler = async ( // Attempt to retrieve policies // This could fail if user doesn't have access to read SLM policies try { - const policiesByName = await callWithRequest('slm.policies'); + const policiesByName = await callWithRequest('sr.policies'); policies = Object.keys(policiesByName); } catch (e) { // Silently swallow error as policy names aren't required in UI diff --git a/x-pack/legacy/plugins/snapshot_restore/server/shim.ts b/x-pack/legacy/plugins/snapshot_restore/server/shim.ts index 84c9ddf8e0bea..d64f35c64f11e 100644 --- a/x-pack/legacy/plugins/snapshot_restore/server/shim.ts +++ b/x-pack/legacy/plugins/snapshot_restore/server/shim.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import { Legacy } from 'kibana'; import { createRouter, Router } from '../../../server/lib/create_router'; import { registerLicenseChecker } from '../../../server/lib/register_license_checker'; -import { elasticsearchJsPlugin } from './client/elasticsearch_slm'; +import { elasticsearchJsPlugin } from './client/elasticsearch_sr'; import { CloudSetup } from '../../../../plugins/cloud/server'; export interface Core { http: { From 004b93f02221cb90de2f15da4a29a3f803ac8494 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Wed, 18 Dec 2019 01:20:35 -0500 Subject: [PATCH 04/14] Added data test subject to the code editors to differentiate them and fixed a broken inport of RepositoryCleanup. --- .../snapshot_restore/common/types/repository.ts | 12 ++++++++++++ .../repository_details/repository_details.tsx | 2 ++ 2 files changed, 14 insertions(+) diff --git a/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts b/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts index 5900d53afa0b4..b9b26c5590324 100644 --- a/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts +++ b/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts @@ -157,3 +157,15 @@ export interface InvalidRepositoryVerification { } export type RepositoryVerification = ValidRepositoryVerification | InvalidRepositoryVerification; + +export interface SuccessfulRepositoryCleanup { + cleaned: true; + response: object; +} + +export interface FailedRepositoryCleanup { + cleaned: false; + error: object; +} + +export type RepositoryCleanup = FailedRepositoryCleanup | SuccessfulRepositoryCleanup; diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx index 8b03644af6fb8..db19300e15420 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx @@ -279,6 +279,7 @@ export const RepositoryDetails: React.FunctionComponent = ({ {verification ? ( = ({ {cleanup ? ( Date: Fri, 20 Dec 2019 19:04:15 -0500 Subject: [PATCH 05/14] Added files for a component integration test. The tests are failing right now so we need to get those green. Added a functional test. Need to set up kbn-es to be able to set up a file repository before being able to run the functional tests. --- .../helpers/http_requests.ts | 11 +++++ .../helpers/repository_detail.helpers.ts | 43 +++++++++++++++++++ .../repository_detail.test.ts | 8 ++++ .../public/app/sections/home/home.tsx | 2 +- .../apps/snapshot_restore/home_page.ts | 18 ++++++++ x-pack/test/functional/config.js | 2 +- .../page_objects/snapshot_restore_page.ts | 4 ++ 7 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_detail.helpers.ts create mode 100644 x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/repository_detail.test.ts diff --git a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/http_requests.ts b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/http_requests.ts index d9f2c1b510a14..cb2e94df75609 100644 --- a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/http_requests.ts @@ -95,6 +95,16 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { ]); }; + const setCleanupRepositoryResponse = (response?: HttpResponse, error?: any) => { + const status = error ? error.status || 503 : 200; + + server.respondWith('POST', `${API_BASE_PATH}repositories/:name/cleanup`, [ + status, + { 'Content-Type': 'application/json' }, + JSON.stringify(response), + ]); + }; + const setGetPolicyResponse = (response?: HttpResponse) => { server.respondWith('GET', `${API_BASE_PATH}policy/:name`, [ 200, @@ -113,6 +123,7 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { setLoadIndicesResponse, setAddPolicyResponse, setGetPolicyResponse, + setCleanupRepositoryResponse, }; }; diff --git a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_detail.helpers.ts b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_detail.helpers.ts new file mode 100644 index 0000000000000..0d9266bd4fb49 --- /dev/null +++ b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_detail.helpers.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { EuiButton } from '@elastic/eui'; +import { registerTestBed, TestBed } from '../../../../../../test_utils'; +import { WithProviders } from './providers'; + +const initTestBed = registerTestBed(WithProviders(EuiButton), { + doMountAsync: true, +}); + +export interface RepositoryDetailTestBed extends TestBed { + actions: { + clickCleanupRepositoryButton: () => void; + getResponseText: () => void; + }; +} + +export const setup = async (): Promise => { + const testBed = await initTestBed(); + + // User actions + const clickCleanupRepositoryButton = () => { + testBed.find('cleanupRepositoryButton').simulate('click'); + }; + + const getResponseText = () => { + // + }; + return { + ...testBed, + actions: { + clickCleanupRepositoryButton, + getResponseText, + }, + }; +}; + +export type RepositoryDetailTestSubjects = TestSubjects; + +type TestSubjects = 'cleanupRepositoryButton' | `cleanupRepositoryResponseEditor`; diff --git a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/repository_detail.test.ts b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/repository_detail.test.ts new file mode 100644 index 0000000000000..1b4c0227db998 --- /dev/null +++ b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/repository_detail.test.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +// TODO: Add Component Integration test for cleanup repository +// TODO: Add component integration test for repository verification. +// TODO: Add component integration test for repository detail. diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/home.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/home.tsx index 35d5c0b610b3c..f89aa869b3366 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/home.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/home.tsx @@ -150,7 +150,7 @@ export const SnapshotRestoreHome: React.FunctionComponent onSectionChange(tab.id)} isSelected={tab.id === section} key={tab.id} - data-test-subj="tab" + data-test-subj={tab.id.toLowerCase() + '_tab'} > {tab.name} diff --git a/x-pack/test/functional/apps/snapshot_restore/home_page.ts b/x-pack/test/functional/apps/snapshot_restore/home_page.ts index 99d3ea7834e6b..b92e2868c6b92 100644 --- a/x-pack/test/functional/apps/snapshot_restore/home_page.ts +++ b/x-pack/test/functional/apps/snapshot_restore/home_page.ts @@ -10,6 +10,8 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default ({ getPageObjects, getService }: FtrProviderContext) => { const pageObjects = getPageObjects(['common', 'snapshotRestore']); const log = getService('log'); + const es = getService('legacyEs'); + // const testSubjects = getService('testSubjects'); describe('Home page', function() { this.tags('smoke'); @@ -26,5 +28,21 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const repositoriesButton = await pageObjects.snapshotRestore.registerRepositoryButton(); expect(await repositoriesButton.isDisplayed()).to.be(true); }); + + it('Reposiories Tab', async () => { + before(async () => { + await es.snapshot.createRepository({ + repository: 'my-repository', + body: { + type: 'fs', + }, + verify: true, + }); + + it('cleanup repository', async () => { + await pageObjects.snapshotRestore.navToRepositories(); + }); + }); + }); }); }; diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index 8981c94b83578..e0f945466eeb9 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -68,7 +68,7 @@ export default async function({ readConfigFile }) { esTestCluster: { license: 'trial', from: 'snapshot', - serverArgs: [], + serverArgs: ['path.repo=/tmp/'], }, kbnTestServer: { diff --git a/x-pack/test/functional/page_objects/snapshot_restore_page.ts b/x-pack/test/functional/page_objects/snapshot_restore_page.ts index 25bdfc7075727..ea1d2ae7d8b12 100644 --- a/x-pack/test/functional/page_objects/snapshot_restore_page.ts +++ b/x-pack/test/functional/page_objects/snapshot_restore_page.ts @@ -8,6 +8,7 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function SnapshotRestorePageProvider({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); + // const wait = getService('waitFor'); return { async appTitleText() { @@ -16,5 +17,8 @@ export function SnapshotRestorePageProvider({ getService }: FtrProviderContext) async registerRepositoryButton() { return await testSubjects.find('registerRepositoryButton'); }, + async navToRepositories() { + await testSubjects.click('repositories_tab'); + }, }; } From f86725aa5628d1c6440f530c5a74057fbdcc80cb Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Thu, 26 Dec 2019 18:29:53 -0500 Subject: [PATCH 06/14] Added change to the way data-test-subjects were created for the repository list table so that columns can be individually identified. Added functional test to allow checking the details of repositories. --- .../repository_table/repository_table.tsx | 7 +-- .../apps/snapshot_restore/home_page.ts | 21 +++++++-- .../page_objects/snapshot_restore_page.ts | 43 ++++++++++++++++++- 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_table/repository_table.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_table/repository_table.tsx index 4b5270b44d593..a0528c6fccf37 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_table/repository_table.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_table/repository_table.tsx @@ -61,7 +61,7 @@ export const RepositoryTable: React.FunctionComponent = ({ trackUiMetric(UIM_REPOSITORY_SHOW_DETAILS_CLICK)} href={openRepositoryDetailsUrl(name)} - data-test-subj="repositoryLink" + data-test-subj={'repositoryLink_' + name} > {name} @@ -96,6 +96,7 @@ export const RepositoryTable: React.FunctionComponent = ({ }, }, { + field: 'actions', name: i18n.translate('xpack.snapshotRestore.repositoryList.table.actionsColumnTitle', { defaultMessage: 'Actions', }), @@ -302,8 +303,8 @@ export const RepositoryTable: React.FunctionComponent = ({ rowProps={() => ({ 'data-test-subj': 'row', })} - cellProps={() => ({ - 'data-test-subj': 'cell', + cellProps={(item, field) => ({ + 'data-test-subj': `${field.name}_cell`, })} data-test-subj="repositoryTable" /> diff --git a/x-pack/test/functional/apps/snapshot_restore/home_page.ts b/x-pack/test/functional/apps/snapshot_restore/home_page.ts index b92e2868c6b92..be815db834c91 100644 --- a/x-pack/test/functional/apps/snapshot_restore/home_page.ts +++ b/x-pack/test/functional/apps/snapshot_restore/home_page.ts @@ -11,7 +11,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const pageObjects = getPageObjects(['common', 'snapshotRestore']); const log = getService('log'); const es = getService('legacyEs'); - // const testSubjects = getService('testSubjects'); describe('Home page', function() { this.tags('smoke'); @@ -29,18 +28,32 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { expect(await repositoriesButton.isDisplayed()).to.be(true); }); - it('Reposiories Tab', async () => { + describe('Reposiories Tab', async () => { before(async () => { await es.snapshot.createRepository({ repository: 'my-repository', body: { type: 'fs', + settings: { + location: '/tmp/es-backups/', + compress: true, + }, }, verify: true, }); + await pageObjects.snapshotRestore.navToRepositories(); + }); - it('cleanup repository', async () => { - await pageObjects.snapshotRestore.navToRepositories(); + it('cleanup repository', async () => { + await pageObjects.snapshotRestore.viewRepositoryDetails('my-repository'); + const cleanupResponse = await pageObjects.snapshotRestore.performRepositoryCleanup(); + expect(cleanupResponse).to.contain('results'); + expect(cleanupResponse).to.contain('deleted_bytes'); + expect(cleanupResponse).to.contain('deleted_blobs'); + }); + after(async () => { + await es.snapshot.deleteRepository({ + repository: 'my-repository', }); }); }); diff --git a/x-pack/test/functional/page_objects/snapshot_restore_page.ts b/x-pack/test/functional/page_objects/snapshot_restore_page.ts index ea1d2ae7d8b12..11b0495ce12ab 100644 --- a/x-pack/test/functional/page_objects/snapshot_restore_page.ts +++ b/x-pack/test/functional/page_objects/snapshot_restore_page.ts @@ -4,11 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ +import { map as mapAsync } from 'bluebird'; import { FtrProviderContext } from '../ftr_provider_context'; export function SnapshotRestorePageProvider({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); - // const wait = getService('waitFor'); + const retry = getService('retry'); return { async appTitleText() { @@ -19,6 +20,46 @@ export function SnapshotRestorePageProvider({ getService }: FtrProviderContext) }, async navToRepositories() { await testSubjects.click('repositories_tab'); + await retry.waitForWithTimeout( + 'Wait for register repository button to be on page', + 10000, + async () => { + return await testSubjects.isDisplayed('registerRepositoryButton'); + } + ); + }, + async getRepoList() { + const table = await testSubjects.find('repositoryTable'); + const rows = await table.findAllByCssSelector('[data-test-subj="row"]'); + return await mapAsync(rows, async row => { + return { + repoName: await ( + await row.findByCssSelector('[data-test-subj="Name_cell"]') + ).getVisibleText(), + repoLink: await ( + await row.findByCssSelector('[data-test-subj="Name_cell"]') + ).findByCssSelector('a'), + repoType: await ( + await row.findByCssSelector('[data-test-subj="Type_cell"]') + ).getVisibleText(), + repoEdit: await row.findByCssSelector('[data-test-subj="editRepositoryButton"]'), + repoDelete: await row.findByCssSelector('[data-test-subj="deleteRepositoryButton"]'), + }; + }); + }, + async viewRepositoryDetails(name: string) { + const repos = await this.getRepoList(); + if (repos.length === 1) { + const repoToView = repos.filter(r => (r.repoName = name))[0]; + await repoToView.repoLink.click(); + } + await retry.waitForWithTimeout(`Repo title should be ${name}`, 10000, async () => { + return (await testSubjects.getVisibleText('title')) === name; + }); + }, + async performRepositoryCleanup() { + await testSubjects.click('cleanupRepositoryButton'); + return await testSubjects.getVisibleText('cleanupCodeEditor'); }, }; } From 6ad982da894f75733f33f32d2dddaf7add05f7f1 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Thu, 26 Dec 2019 22:24:58 -0500 Subject: [PATCH 07/14] Removed the jest tests for repository details until we get jest fixed. --- .../helpers/repository_detail.helpers.ts | 43 ------------------- .../repository_detail.test.ts | 8 ---- 2 files changed, 51 deletions(-) delete mode 100644 x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_detail.helpers.ts delete mode 100644 x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/repository_detail.test.ts diff --git a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_detail.helpers.ts b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_detail.helpers.ts deleted file mode 100644 index 0d9266bd4fb49..0000000000000 --- a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_detail.helpers.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { EuiButton } from '@elastic/eui'; -import { registerTestBed, TestBed } from '../../../../../../test_utils'; -import { WithProviders } from './providers'; - -const initTestBed = registerTestBed(WithProviders(EuiButton), { - doMountAsync: true, -}); - -export interface RepositoryDetailTestBed extends TestBed { - actions: { - clickCleanupRepositoryButton: () => void; - getResponseText: () => void; - }; -} - -export const setup = async (): Promise => { - const testBed = await initTestBed(); - - // User actions - const clickCleanupRepositoryButton = () => { - testBed.find('cleanupRepositoryButton').simulate('click'); - }; - - const getResponseText = () => { - // - }; - return { - ...testBed, - actions: { - clickCleanupRepositoryButton, - getResponseText, - }, - }; -}; - -export type RepositoryDetailTestSubjects = TestSubjects; - -type TestSubjects = 'cleanupRepositoryButton' | `cleanupRepositoryResponseEditor`; diff --git a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/repository_detail.test.ts b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/repository_detail.test.ts deleted file mode 100644 index 1b4c0227db998..0000000000000 --- a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/repository_detail.test.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -// TODO: Add Component Integration test for cleanup repository -// TODO: Add component integration test for repository verification. -// TODO: Add component integration test for repository detail. From 0d0c4703d2323646fd66ccc147c105ab4216b046 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Tue, 7 Jan 2020 20:14:41 -0500 Subject: [PATCH 08/14] Fixed jest test to reflect updated test subjects. --- .../client_integration/helpers/home.helpers.ts | 7 +++++-- .../__jest__/client_integration/home.test.ts | 11 +++++++++-- .../repository_table/repository_table.tsx | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/home.helpers.ts b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/home.helpers.ts index 79a4eeb6dc48b..777471e209adc 100644 --- a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/home.helpers.ts +++ b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/helpers/home.helpers.ts @@ -99,7 +99,7 @@ export const setup = async (): Promise => { const tabs = ['snapshots', 'repositories']; testBed - .find('tab') + .find(`${tab}_tab`) .at(tabs.indexOf(tab)) .simulate('click'); }; @@ -360,7 +360,10 @@ export type TestSubjects = | 'state' | 'state.title' | 'state.value' - | 'tab' + | 'repositories_tab' + | 'snapshots_tab' + | 'policies_tab' + | 'restore_status_tab' | 'tableHeaderCell_durationInMillis_3' | 'tableHeaderCell_durationInMillis_3.tableHeaderSortButton' | 'tableHeaderCell_indices_4' diff --git a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/home.test.ts b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/home.test.ts index aa659441043ae..517c7a0059a7e 100644 --- a/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/home.test.ts +++ b/x-pack/legacy/plugins/snapshot_restore/__jest__/client_integration/home.test.ts @@ -88,8 +88,15 @@ describe('', () => { test('should have 4 tabs', () => { const { find } = testBed; - expect(find('tab').length).toBe(4); - expect(find('tab').map(t => t.text())).toEqual([ + const tabs = [ + find('snapshots_tab'), + find('repositories_tab'), + find('policies_tab'), + find('restore_status_tab'), + ]; + + expect(tabs.length).toBe(4); + expect(tabs.map(t => t.text())).toEqual([ 'Snapshots', 'Repositories', 'Policies', diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_table/repository_table.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_table/repository_table.tsx index a0528c6fccf37..1df06f67c35b1 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_table/repository_table.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_table/repository_table.tsx @@ -61,7 +61,7 @@ export const RepositoryTable: React.FunctionComponent = ({ trackUiMetric(UIM_REPOSITORY_SHOW_DETAILS_CLICK)} href={openRepositoryDetailsUrl(name)} - data-test-subj={'repositoryLink_' + name} + data-test-subj="repositoryLink" > {name} From e9e9dbf8a1a8f55883a5e9f031702b61bb75e386 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Wed, 8 Jan 2020 03:22:14 -0500 Subject: [PATCH 09/14] Made changes per feedback in PR comments. --- .../repository_details/repository_details.tsx | 138 ++++++------------ .../page_objects/snapshot_restore_page.ts | 2 +- 2 files changed, 49 insertions(+), 91 deletions(-) diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx index db19300e15420..c642c94e5f73a 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx @@ -8,7 +8,6 @@ import { EuiButton, EuiButtonEmpty, EuiCallOut, - EuiCodeEditor, EuiFlexGroup, EuiFlexItem, EuiFlyout, @@ -19,6 +18,8 @@ import { EuiLink, EuiSpacer, EuiTitle, + EuiCodeBlock, + EuiText, } from '@elastic/eui'; import 'brace/theme/textmate'; @@ -278,37 +279,13 @@ export const RepositoryDetails: React.FunctionComponent = ({ {verification ? ( - + {JSON.stringify( verification.valid ? verification.response : verification.error, null, 2 )} - setOptions={{ - showLineNumbers: false, - tabSize: 2, - maxLines: Infinity, - }} - editorProps={{ - $blockScrolling: Infinity, - }} - showGutter={false} - minLines={6} - aria-label={ - - } - /> + ) : null} @@ -338,81 +315,62 @@ export const RepositoryDetails: React.FunctionComponent = ({ ); const renderCleanup = () => ( - + <>

{cleanup ? ( - -

- -

-
+ +

+ You can clean up a repository to delete any unreferenced data from a snapshot. This + may provide storage space savings. Note: If you regularly delete snapshots, this + functionality will likely not be as beneficial and should be used less frequently. +

+
- {cleanup ? ( - - } - /> - ) : null} - - - - -
- ) : ( - - - - + +

+ +

+
+ + {JSON.stringify(cleanup.response, null, 2)} + + + ) : ( + -
+ )}
- )} -
+ ) : null} + + + + + ); const renderFooter = () => { diff --git a/x-pack/test/functional/page_objects/snapshot_restore_page.ts b/x-pack/test/functional/page_objects/snapshot_restore_page.ts index 11b0495ce12ab..d4278a2bd242f 100644 --- a/x-pack/test/functional/page_objects/snapshot_restore_page.ts +++ b/x-pack/test/functional/page_objects/snapshot_restore_page.ts @@ -59,7 +59,7 @@ export function SnapshotRestorePageProvider({ getService }: FtrProviderContext) }, async performRepositoryCleanup() { await testSubjects.click('cleanupRepositoryButton'); - return await testSubjects.getVisibleText('cleanupCodeEditor'); + return await testSubjects.getVisibleText('cleanupCodeBlock'); }, }; } From f61a139714afc84c2b5f291658f12288f3485006 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Wed, 8 Jan 2020 17:14:42 -0500 Subject: [PATCH 10/14] Fixed i10n issues using . Removed reference to blueBird and used Promise.all(). Fixed all nits in PR comments. --- .../repository_details/repository_details.tsx | 46 ++++++++++++------- .../translations/translations/ja-JP.json | 3 +- .../translations/translations/zh-CN.json | 3 +- .../apps/snapshot_restore/home_page.ts | 4 +- .../page_objects/snapshot_restore_page.ts | 34 +++++++------- 5 files changed, 51 insertions(+), 39 deletions(-) diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx index c642c94e5f73a..d4aab9cbb99fd 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx @@ -248,7 +248,7 @@ export const RepositoryDetails: React.FunctionComponent = ({ {renderVerification()} - + {renderCleanup()} ); @@ -324,16 +324,19 @@ export const RepositoryDetails: React.FunctionComponent = ({ /> - {cleanup ? ( - - - -

- You can clean up a repository to delete any unreferenced data from a snapshot. This + + +

+ +

+
+ {cleanup ? ( + <> {cleanup?.cleaned ? (
@@ -350,13 +353,22 @@ export const RepositoryDetails: React.FunctionComponent = ({
) : ( - + +

+ +

+

+ +

+
)} -
+ ) : null} = ({ > diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 09d71814e5bf0..83e4e6452b367 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10966,7 +10966,6 @@ "xpack.snapshotRestore.repositoryDetails.typeS3.serverSideEncryptionLabel": "サーバー側エコシステム", "xpack.snapshotRestore.repositoryDetails.typeS3.storageClassLabel": "ストレージクラス", "xpack.snapshotRestore.repositoryDetails.typeTitle": "レポジトリタイプ", - "xpack.snapshotRestore.repositoryDetails.verificationDetails": "認証情報レポジトリ「{name}」", "xpack.snapshotRestore.repositoryDetails.verificationDetailsTitle": "詳細", "xpack.snapshotRestore.repositoryDetails.verificationTitle": "認証ステータス", "xpack.snapshotRestore.repositoryDetails.verifyButtonLabel": "レポジトリを検証", @@ -12702,4 +12701,4 @@ "xpack.licensing.welcomeBanner.licenseIsExpiredDescription.updateYourLicenseLinkText": "ライセンスを更新", "xpack.licensing.welcomeBanner.licenseIsExpiredTitle": "ご使用の {licenseType} ライセンスは期限切れです" } -} +} \ No newline at end of file diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e221cba874bcd..6b1f224b2ad9b 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -11055,7 +11055,6 @@ "xpack.snapshotRestore.repositoryDetails.typeS3.serverSideEncryptionLabel": "服务器端加密", "xpack.snapshotRestore.repositoryDetails.typeS3.storageClassLabel": "存储类", "xpack.snapshotRestore.repositoryDetails.typeTitle": "存储库类型", - "xpack.snapshotRestore.repositoryDetails.verificationDetails": "验证详情存储库“{name}”", "xpack.snapshotRestore.repositoryDetails.verificationDetailsTitle": "详情", "xpack.snapshotRestore.repositoryDetails.verificationTitle": "验证状态", "xpack.snapshotRestore.repositoryDetails.verifyButtonLabel": "验证存储库", @@ -12791,4 +12790,4 @@ "xpack.licensing.welcomeBanner.licenseIsExpiredDescription.updateYourLicenseLinkText": "更新您的许可", "xpack.licensing.welcomeBanner.licenseIsExpiredTitle": "您的{licenseType}许可已过期" } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/apps/snapshot_restore/home_page.ts b/x-pack/test/functional/apps/snapshot_restore/home_page.ts index be815db834c91..608c7f321a08f 100644 --- a/x-pack/test/functional/apps/snapshot_restore/home_page.ts +++ b/x-pack/test/functional/apps/snapshot_restore/home_page.ts @@ -28,7 +28,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { expect(await repositoriesButton.isDisplayed()).to.be(true); }); - describe('Reposiories Tab', async () => { + describe('Repositories Tab', async () => { before(async () => { await es.snapshot.createRepository({ repository: 'my-repository', @@ -46,7 +46,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { it('cleanup repository', async () => { await pageObjects.snapshotRestore.viewRepositoryDetails('my-repository'); + await pageObjects.common.sleep(25000); const cleanupResponse = await pageObjects.snapshotRestore.performRepositoryCleanup(); + await pageObjects.common.sleep(25000); expect(cleanupResponse).to.contain('results'); expect(cleanupResponse).to.contain('deleted_bytes'); expect(cleanupResponse).to.contain('deleted_blobs'); diff --git a/x-pack/test/functional/page_objects/snapshot_restore_page.ts b/x-pack/test/functional/page_objects/snapshot_restore_page.ts index d4278a2bd242f..1c8ba9f633111 100644 --- a/x-pack/test/functional/page_objects/snapshot_restore_page.ts +++ b/x-pack/test/functional/page_objects/snapshot_restore_page.ts @@ -3,8 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - -import { map as mapAsync } from 'bluebird'; import { FtrProviderContext } from '../ftr_provider_context'; export function SnapshotRestorePageProvider({ getService }: FtrProviderContext) { @@ -31,21 +29,23 @@ export function SnapshotRestorePageProvider({ getService }: FtrProviderContext) async getRepoList() { const table = await testSubjects.find('repositoryTable'); const rows = await table.findAllByCssSelector('[data-test-subj="row"]'); - return await mapAsync(rows, async row => { - return { - repoName: await ( - await row.findByCssSelector('[data-test-subj="Name_cell"]') - ).getVisibleText(), - repoLink: await ( - await row.findByCssSelector('[data-test-subj="Name_cell"]') - ).findByCssSelector('a'), - repoType: await ( - await row.findByCssSelector('[data-test-subj="Type_cell"]') - ).getVisibleText(), - repoEdit: await row.findByCssSelector('[data-test-subj="editRepositoryButton"]'), - repoDelete: await row.findByCssSelector('[data-test-subj="deleteRepositoryButton"]'), - }; - }); + return await Promise.all( + rows.map(async row => { + return { + repoName: await ( + await row.findByCssSelector('[data-test-subj="Name_cell"]') + ).getVisibleText(), + repoLink: await ( + await row.findByCssSelector('[data-test-subj="Name_cell"]') + ).findByCssSelector('a'), + repoType: await ( + await row.findByCssSelector('[data-test-subj="Type_cell"]') + ).getVisibleText(), + repoEdit: await row.findByCssSelector('[data-test-subj="editRepositoryButton"]'), + repoDelete: await row.findByCssSelector('[data-test-subj="deleteRepositoryButton"]'), + }; + }) + ); }, async viewRepositoryDetails(name: string) { const repos = await this.getRepoList(); From 590a90482a1e58a95aebb8efe505214a7c2702d9 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Wed, 8 Jan 2020 19:48:41 -0500 Subject: [PATCH 11/14] Added i10n fixes for header. --- .../plugins/snapshot_restore/common/types/repository.ts | 2 +- .../repository_list/repository_details/repository_details.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts b/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts index b9b26c5590324..fd18eabf9e7c7 100644 --- a/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts +++ b/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts @@ -165,7 +165,7 @@ export interface SuccessfulRepositoryCleanup { export interface FailedRepositoryCleanup { cleaned: false; - error: object; + error: string; } export type RepositoryCleanup = FailedRepositoryCleanup | SuccessfulRepositoryCleanup; diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx index d4aab9cbb99fd..ee0b6f68afca8 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx @@ -338,7 +338,7 @@ export const RepositoryDetails: React.FunctionComponent = ({ {cleanup ? ( <> - {cleanup?.cleaned ? ( + {cleanup.cleaned ? (

@@ -363,7 +363,7 @@ export const RepositoryDetails: React.FunctionComponent = ({

From dae7208bd86c018c171a13d66a1ecb9bfcae4895 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Wed, 8 Jan 2020 20:02:34 -0500 Subject: [PATCH 12/14] Added i10n fixes for header. --- .../plugins/snapshot_restore/common/types/repository.ts | 2 +- .../repository_details/repository_details.tsx | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts b/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts index fd18eabf9e7c7..b9b26c5590324 100644 --- a/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts +++ b/x-pack/legacy/plugins/snapshot_restore/common/types/repository.ts @@ -165,7 +165,7 @@ export interface SuccessfulRepositoryCleanup { export interface FailedRepositoryCleanup { cleaned: false; - error: string; + error: object; } export type RepositoryCleanup = FailedRepositoryCleanup | SuccessfulRepositoryCleanup; diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx index ee0b6f68afca8..5b13bcb78fe9c 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx @@ -360,12 +360,7 @@ export const RepositoryDetails: React.FunctionComponent = ({ defaultMessage="Sorry, there was an error cleaning the repository." />

-

- -

+

{cleanup.error ? cleanup.error.toString() : '503: Unknown error'}

)} From c065f88e9b5dbe3d5c9ed61f41c9acb7779cada7 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Thu, 9 Jan 2020 15:59:24 -0500 Subject: [PATCH 13/14] Added name parameter for i18n strings. --- .../repository_details/repository_details.tsx | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx index 5b13bcb78fe9c..922d58511ec0e 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx @@ -353,14 +353,23 @@ export const RepositoryDetails: React.FunctionComponent = ({

) : ( - +

- + {JSON.stringify( + cleanup.error + ? cleanup.error + : i18n.translate( + 'xpack.snapshotRestore.repositoryDetails.cleanupUnknownError', + { defaultMessage: '503: Unknown error' } + ) + )}

-

{cleanup.error ? cleanup.error.toString() : '503: Unknown error'}

)} From 558ff5ee03431dd318fa6750948e775a53781897 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Fri, 10 Jan 2020 23:11:15 -0500 Subject: [PATCH 14/14] Removed i18n string from JSON.stringify call since it's already a string. --- .../repository_details/repository_details.tsx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx index 922d58511ec0e..0a3fcfc2ec6e7 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_details/repository_details.tsx @@ -361,14 +361,11 @@ export const RepositoryDetails: React.FunctionComponent = ({ })} >

- {JSON.stringify( - cleanup.error - ? cleanup.error - : i18n.translate( - 'xpack.snapshotRestore.repositoryDetails.cleanupUnknownError', - { defaultMessage: '503: Unknown error' } - ) - )} + {cleanup.error + ? JSON.stringify(cleanup.error) + : i18n.translate('xpack.snapshotRestore.repositoryDetails.cleanupUnknownError', { + defaultMessage: '503: Unknown error', + })}

)}