Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
6ed1c54
Change app name and change default tab to snapshots
jen-huang Jun 5, 2019
de3c2c2
Fix i18n issues
jen-huang Jun 5, 2019
6dda580
UI placeholder for deleting snapshots
jen-huang Jun 5, 2019
a1d8c8d
Merge remote-tracking branch 'upstream/master' into feature/snapshot-…
jen-huang Jun 6, 2019
21f8e5d
Add bulk snapshot delete endpoint and test, adjust UI delete components
jen-huang Jun 7, 2019
098cf76
Merge remote-tracking branch 'upstream/master' into feature/snapshot-…
jen-huang Jun 10, 2019
259cfbe
Add restore action buttons
jen-huang Jun 11, 2019
bb48ae0
Set up restore snapshot form entry
jen-huang Jun 11, 2019
46be0da
Add RestoreSettings type
jen-huang Jun 14, 2019
67d5476
Restore step general
jen-huang Jun 17, 2019
e0e82a8
Merge remote-tracking branch 'upstream/master' into feature/snapshot-…
jen-huang Jun 17, 2019
10b380b
Combobox for ignore settings
jen-huang Jun 18, 2019
3a452ef
Code editor for modifying index settings
jen-huang Jun 18, 2019
d44ec39
Truncate list of indices in snapshot details and provide link to show…
jen-huang Jun 18, 2019
53fdeb8
Disable include global state option for snapshots that don't have glo…
jen-huang Jun 18, 2019
ef57466
Add step titles, rename General to Logistics
jen-huang Jun 18, 2019
be1172d
Committing deleted file
jen-huang Jun 18, 2019
7ac5a52
Change repository detail settings to reverse list style
jen-huang Jun 18, 2019
df0dd7c
Review summary tab and placeholder json tab
jen-huang Jun 18, 2019
395772e
Add restore wizard validation
jen-huang Jun 19, 2019
3f17e1e
Add restore serialization
jen-huang Jun 19, 2019
64f87ab
Create restore endpoint and integration
jen-huang Jun 19, 2019
dd2797d
Merge remote-tracking branch 'upstream/master' into feature/snapshot-…
jen-huang Jun 20, 2019
4b37d00
Move new files to /legacy
jen-huang Jun 20, 2019
731c4d6
Fix bugs, add search filter bar to indices list
jen-huang Jun 20, 2019
8f0fbe5
Allow de/select all of indices
jen-huang Jun 21, 2019
8563714
Merge remote-tracking branch 'upstream/master' into feature/snapshot-…
jen-huang Jun 24, 2019
45c0548
Create new recovery status tab
jen-huang Jun 24, 2019
fc8bc50
Prefix hook methods with `use`
jen-huang Jun 24, 2019
a6f0a13
Remove unnecessary RouteComponentProps
jen-huang Jun 24, 2019
c4fbf4b
Add get all snapshot recoveries endpoint, deserialization, types, and…
jen-huang Jun 24, 2019
3b11591
Merge remote-tracking branch 'upstream/master' into feature/snapshot-…
jen-huang Jun 24, 2019
18a3062
Merge remote-tracking branch 'upstream/master' into feature/snapshot-…
jen-huang Jun 25, 2019
8f1a7ab
Remove unused timeout variable; enhance to allow polling (interval'd …
jen-huang Jun 26, 2019
cc55ad1
Add recovery table
jen-huang Jun 26, 2019
772fd8f
Use shim'd i18n
jen-huang Jun 26, 2019
7263352
Adjust disabled restore state
jen-huang Jun 26, 2019
94c5130
Fix invariant error
jen-huang Jun 26, 2019
469fbd2
Fix partial restore label
jen-huang Jun 26, 2019
a701055
Fix misc bugs
jen-huang Jun 26, 2019
950f0ff
Address copywriting feedback
jen-huang Jun 27, 2019
ed52296
Address i18n feedback
jen-huang Jun 27, 2019
59785b6
Address PR feedback
jen-huang Jun 27, 2019
a6bebbd
Rename recovery to restore
jen-huang Jun 27, 2019
eb3f03d
Add toggle show/hide link to restore wizard summary
jen-huang Jun 27, 2019
a223042
Merge branch 'master' of github.com:elastic/kibana into feature/snaps…
jen-huang Jun 27, 2019
b437a19
Fix snapshot tests due to changes in includeGlobalState deserializati…
jen-huang Jun 28, 2019
5bf2e94
Fix EuiCard warning
jen-huang Jun 28, 2019
7b7a1f1
Merge remote-tracking branch 'upstream/master' into feature/snapshot-…
jen-huang Jun 28, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion x-pack/legacy/plugins/snapshot_restore/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const PLUGIN = {
MINIMUM_LICENSE_REQUIRED: LICENSE_TYPE_BASIC as LicenseType,
getI18nName: (i18n: any): string => {
return i18n.translate('xpack.snapshotRestore.appName', {
defaultMessage: 'Snapshot Repositories',
defaultMessage: 'Snapshot and Restore',
});
},
};
Expand Down
1 change: 1 addition & 0 deletions x-pack/legacy/plugins/snapshot_restore/common/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
export { flatten } from './flatten';
export { serializeRestoreSettings } from './restore_settings_serialization';
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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 { serializeRestoreSettings } from './restore_settings_serialization';

describe('restore_settings_serialization()', () => {
it('should serialize blank restore settings', () => {
expect(serializeRestoreSettings({})).toEqual({});
});

it('should serialize partial restore settings', () => {
expect(serializeRestoreSettings({})).toEqual({});
expect(
serializeRestoreSettings({
indices: ['foo', 'bar'],
ignoreIndexSettings: ['setting1'],
partial: true,
})
).toEqual({
indices: ['foo', 'bar'],
ignore_index_settings: ['setting1'],
partial: true,
});
});

it('should serialize full restore settings', () => {
expect(
serializeRestoreSettings({
indices: ['foo', 'bar'],
renamePattern: 'capture_pattern',
renameReplacement: 'replacement_pattern',
includeGlobalState: true,
partial: true,
indexSettings: '{"modified_setting":123}',
ignoreIndexSettings: ['setting1'],
})
).toEqual({
indices: ['foo', 'bar'],
rename_pattern: 'capture_pattern',
rename_replacement: 'replacement_pattern',
include_global_state: true,
partial: true,
index_settings: { modified_setting: 123 },
ignore_index_settings: ['setting1'],
});
});

it('should skip serialization of invalid json index settings', () => {
expect(
serializeRestoreSettings({
indexSettings: '{"invalid_setting:123,}',
})
).toEqual({});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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 { RestoreSettings, RestoreSettingsEs } from '../types';

const removeUndefinedSettings = (settings: RestoreSettingsEs): RestoreSettingsEs => {
return Object.entries(settings).reduce((sts: RestoreSettingsEs, [key, value]) => {
if (value !== undefined) {
sts[key as keyof RestoreSettingsEs] = value;
}
return sts;
}, {});
};

export function serializeRestoreSettings(restoreSettings: RestoreSettings): RestoreSettingsEs {
const {
indices,
renamePattern,
renameReplacement,
includeGlobalState,
partial,
indexSettings,
ignoreIndexSettings,
} = restoreSettings;

let parsedIndexSettings: RestoreSettingsEs['index_settings'] | undefined;
if (indexSettings) {
try {
parsedIndexSettings = JSON.parse(indexSettings);
} catch (e) {
// Silently swallow parsing errors since parsing validation is done on client
// so we should never reach this point
}
}

const settings: RestoreSettingsEs = {
indices,
rename_pattern: renamePattern,
rename_replacement: renameReplacement,
include_global_state: includeGlobalState,
partial,
index_settings: parsedIndexSettings,
ignore_index_settings: ignoreIndexSettings,
};

return removeUndefinedSettings(settings);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@

export * from './repository';
export * from './snapshot';
export * from './restore';
127 changes: 127 additions & 0 deletions x-pack/legacy/plugins/snapshot_restore/common/types/restore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* 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.
*/

export interface RestoreSettings {
indices?: string[];
renamePattern?: string;
renameReplacement?: string;
includeGlobalState?: boolean;
partial?: boolean;
indexSettings?: string;
ignoreIndexSettings?: string[];
}

export interface RestoreSettingsEs {
indices?: string[];
rename_pattern?: string;
rename_replacement?: string;
include_global_state?: boolean;
partial?: boolean;
index_settings?: { [key: string]: any };
ignore_index_settings?: string[];
}

export interface SnapshotRestore {
index: string;
latestActivityTimeInMillis: number;
shards: Array<Partial<SnapshotRestoreShard>>;
isComplete: boolean;
}

export interface SnapshotRestoreShard {
id: number;
primary: boolean;
stage: string;
snapshot: string;
repository: string;
version: string;

targetHost: string;
targetNode: string;

/** e.g. '2019-04-05T21:56:40.438Z' */
startTime: string;
startTimeInMillis: number;
/** e.g. '2019-04-05T21:56:40.438Z' */
stopTime: string;
stopTimeInMillis: number;
totalTime: string;
totalTimeInMillis: number;

bytesTotal: number;
bytesRecovered: number;
bytesPercent: string;

filesTotal: number;
filesRecovered: number;
filesPercent: string;
}

export interface SnapshotRestoreShardEs {
id: number;
type: string;
stage: string;
primary: boolean;
/** e.g. '2019-04-05T21:56:40.438Z' */
start_time: string;
start_time_in_millis: number;
/** e.g. '2019-04-05T21:56:40.438Z' */
stop_time: string;
stop_time_in_millis: number;
total_time: string;
total_time_in_millis: number;
source: {
repository: string;
snapshot: string;
version: string;
index: string;
restoreUUID: string;
};
target: {
id: string;
host: string;
transport_address: string;
ip: string;
name: string;
};
index: {
size: {
total: string;
total_in_bytes: number;
reused: string;
reused_in_bytes: number;
recovered: string;
recovered_in_bytes: number;
percent: string;
};
files: {
total: number;
reused: number;
recovered: number;
percent: string;
};
total_time: string;
total_time_in_millis: number;
source_throttle_time: string;
source_throttle_time_in_millis: number;
target_throttle_time: string;
target_throttle_time_in_millis: number;
};
translog: {
recovered: number;
total: number;
percent: string;
total_on_start: number;
total_time: string;
total_time_in_millis: number;
};
verify_index: {
check_index_time: string;
check_index_time_in_millis: number;
total_time: string;
total_time_in_millis: number;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface SnapshotDetails {
versionId: number;
version: string;
indices: string[];
includeGlobalState: number;
includeGlobalState: boolean;
state: string;
/** e.g. '2019-04-05T21:56:40.438Z' */
startTime: string;
Expand Down
1 change: 1 addition & 0 deletions x-pack/legacy/plugins/snapshot_restore/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function snapshotRestore(kibana: any) {
publicDir: resolve(__dirname, 'public'),
require: ['kibana', 'elasticsearch', 'xpack_main'],
uiExports: {
styleSheetPaths: resolve(__dirname, 'public/app/index.scss'),
managementSections: ['plugins/snapshot_restore'],
},
init(server: Legacy.Server) {
Expand Down
20 changes: 15 additions & 5 deletions x-pack/legacy/plugins/snapshot_restore/public/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { EuiPageContent, EuiEmptyPrompt } from '@elastic/eui';

import { SectionLoading, SectionError } from './components';
import { BASE_PATH, DEFAULT_SECTION, Section } from './constants';
import { RepositoryAdd, RepositoryEdit, SnapshotRestoreHome } from './sections';
import { loadPermissions } from './services/http';
import { RepositoryAdd, RepositoryEdit, RestoreSnapshot, SnapshotRestoreHome } from './sections';
import { useLoadPermissions } from './services/http';
import { useAppDependencies } from './index';

export const App: React.FunctionComponent = () => {
Expand All @@ -29,7 +29,7 @@ export const App: React.FunctionComponent = () => {
hasPermission: true,
missingClusterPrivileges: [],
},
} = loadPermissions();
} = useLoadPermissions();

if (loadingPermissions) {
return (
Expand Down Expand Up @@ -73,7 +73,7 @@ export const App: React.FunctionComponent = () => {
<p>
<FormattedMessage
id="xpack.snapshotRestore.app.deniedPermissionDescription"
defaultMessage="To use Snapshot Repositories, you must have {clusterPrivilegesCount,
defaultMessage="To use Snapshot and Restore, you must have {clusterPrivilegesCount,
plural, one {this cluster privilege} other {these cluster privileges}}: {clusterPrivileges}."
values={{
clusterPrivileges: missingClusterPrivileges.join(', '),
Expand All @@ -87,7 +87,7 @@ export const App: React.FunctionComponent = () => {
);
}

const sections: Section[] = ['repositories', 'snapshots'];
const sections: Section[] = ['repositories', 'snapshots', 'restore_status'];
const sectionsRegex = sections.join('|');

return (
Expand All @@ -100,6 +100,16 @@ export const App: React.FunctionComponent = () => {
path={`${BASE_PATH}/:section(${sectionsRegex})/:repositoryName?/:snapshotId*`}
component={SnapshotRestoreHome}
/>
<Redirect
exact
from={`${BASE_PATH}/restore/:repositoryName`}
to={`${BASE_PATH}/snapshots`}
/>
<Route
exact
path={`${BASE_PATH}/restore/:repositoryName/:snapshotId*`}
component={RestoreSnapshot}
/>
<Redirect from={`${BASE_PATH}`} to={`${BASE_PATH}/${DEFAULT_SECTION}`} />
</Switch>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ export { RepositoryVerificationBadge } from './repository_verification_badge';
export { RepositoryTypeLogo } from './repository_type_logo';
export { SectionError } from './section_error';
export { SectionLoading } from './section_loading';
export { SnapshotDeleteProvider } from './snapshot_delete_provider';
export { RestoreSnapshotForm } from './restore_snapshot_form';
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { REPOSITORY_TYPES } from '../../../../common/constants';

import { useAppDependencies } from '../../index';
import { documentationLinksService } from '../../services/documentation';
import { loadRepositoryTypes } from '../../services/http';
import { useLoadRepositoryTypes } from '../../services/http';
import { textService } from '../../services/text';
import { RepositoryValidation } from '../../services/validation';
import { SectionError, SectionLoading, RepositoryTypeLogo } from '../';
Expand Down Expand Up @@ -56,7 +56,7 @@ export const RepositoryFormStepOne: React.FunctionComponent<Props> = ({
error: repositoryTypesError,
loading: repositoryTypesLoading,
data: repositoryTypes = [],
} = loadRepositoryTypes();
} = useLoadRepositoryTypes();

const hasValidationErrors: boolean = !validation.isValid;

Expand Down Expand Up @@ -143,6 +143,7 @@ export const RepositoryFormStepOne: React.FunctionComponent<Props> = ({
<EuiCard
title={displayName}
icon={<RepositoryTypeLogo type={type} size="l" />}
description={<Fragment />} /* EuiCard requires `description` */
footer={
<EuiButtonEmpty
href={documentationLinksService.getRepositoryTypeDocUrl(type)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Prevent switch controls from moving around when toggling content
*/
.snapshotRestore__restoreForm__stepLogistics,
.snapshotRestore__restoreForm__stepSettings {
.euiFormRow--hasEmptyLabelSpace {
min-height: auto;
margin-top: $euiFontSizeXS + $euiSizeS + ($euiSizeXXL / 4);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/

export { RestoreSnapshotForm } from './restore_snapshot_form';
Loading