Skip to content

Commit 85fa2ca

Browse files
authored
SavedObjects management: display explicit import error in case of failure and avoid invalid file to crash the server (#82406) (#82613)
* display error cause in case of import failure * avoid server crash when importing invalid file * remove unused translations * fix unit tests * change savedObjects.maxImportPayloadBytes default to 25mb * fix types and logic # Conflicts: # test/functional/apps/management/_import_objects.ts
1 parent a5c2a13 commit 85fa2ca

File tree

24 files changed

+165
-46
lines changed

24 files changed

+165
-46
lines changed

src/core/server/core_usage_data/core_usage_data_service.mock.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ const createStartContractMock = () => {
108108
},
109109
savedObjects: {
110110
maxImportExportSizeBytes: 10000,
111-
maxImportPayloadBytes: 10485760,
111+
maxImportPayloadBytes: 26214400,
112112
},
113113
},
114114
environment: {

src/core/server/core_usage_data/core_usage_data_service.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ describe('CoreUsageDataService', () => {
188188
},
189189
"savedObjects": Object {
190190
"maxImportExportSizeBytes": 10000,
191-
"maxImportPayloadBytes": 10485760,
191+
"maxImportPayloadBytes": 26214400,
192192
},
193193
},
194194
"environment": Object {

src/core/server/mocks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export function pluginInitializerContextConfigMock<T>(config: T) {
7272
},
7373
path: { data: '/tmp' },
7474
savedObjects: {
75-
maxImportPayloadBytes: new ByteSizeValue(10485760),
75+
maxImportPayloadBytes: new ByteSizeValue(26214400),
7676
},
7777
};
7878

src/core/server/plugins/plugin_context.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ describe('createPluginInitializerContext', () => {
9393
pingTimeout: duration(30, 's'),
9494
},
9595
path: { data: fromRoot('data') },
96-
savedObjects: { maxImportPayloadBytes: new ByteSizeValue(10485760) },
96+
savedObjects: { maxImportPayloadBytes: new ByteSizeValue(26214400) },
9797
});
9898
});
9999

src/core/server/saved_objects/routes/import.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,19 @@ export const registerImportRoute = (router: IRouter, config: SavedObjectConfig)
7171
return res.badRequest({ body: `Invalid file extension ${fileExtension}` });
7272
}
7373

74+
let readStream: Readable;
75+
try {
76+
readStream = await createSavedObjectsStreamFromNdJson(file);
77+
} catch (e) {
78+
return res.badRequest({
79+
body: e,
80+
});
81+
}
82+
7483
const result = await importSavedObjectsFromStream({
7584
savedObjectsClient: context.core.savedObjects.client,
7685
typeRegistry: context.core.savedObjects.typeRegistry,
77-
readStream: createSavedObjectsStreamFromNdJson(file),
86+
readStream,
7887
objectLimit: maxImportExportSize,
7988
overwrite,
8089
createNewCopies,

src/core/server/saved_objects/routes/integration_tests/export.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type SetupServerReturn = UnwrapPromise<ReturnType<typeof setupServer>>;
3333
const exportSavedObjectsToStream = exportMock.exportSavedObjectsToStream as jest.Mock;
3434
const allowedTypes = ['index-pattern', 'search'];
3535
const config = {
36-
maxImportPayloadBytes: 10485760,
36+
maxImportPayloadBytes: 26214400,
3737
maxImportExportSize: 10000,
3838
} as SavedObjectConfig;
3939

src/core/server/saved_objects/routes/integration_tests/import.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ type SetupServerReturn = UnwrapPromise<ReturnType<typeof setupServer>>;
3030

3131
const { v4: uuidv4 } = jest.requireActual('uuid');
3232
const allowedTypes = ['index-pattern', 'visualization', 'dashboard'];
33-
const config = { maxImportPayloadBytes: 10485760, maxImportExportSize: 10000 } as SavedObjectConfig;
33+
const config = { maxImportPayloadBytes: 26214400, maxImportExportSize: 10000 } as SavedObjectConfig;
3434
const URL = '/internal/saved_objects/_import';
3535

3636
describe(`POST ${URL}`, () => {

src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type SetupServerReturn = UnwrapPromise<ReturnType<typeof setupServer>>;
2929

3030
const { v4: uuidv4 } = jest.requireActual('uuid');
3131
const allowedTypes = ['index-pattern', 'visualization', 'dashboard'];
32-
const config = { maxImportPayloadBytes: 10485760, maxImportExportSize: 10000 } as SavedObjectConfig;
32+
const config = { maxImportPayloadBytes: 26214400, maxImportExportSize: 10000 } as SavedObjectConfig;
3333
const URL = '/api/saved_objects/_resolve_import_errors';
3434

3535
describe(`POST ${URL}`, () => {

src/core/server/saved_objects/routes/resolve_import_errors.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,19 @@ export const registerResolveImportErrorsRoute = (router: IRouter, config: SavedO
7878
return res.badRequest({ body: `Invalid file extension ${fileExtension}` });
7979
}
8080

81+
let readStream: Readable;
82+
try {
83+
readStream = await createSavedObjectsStreamFromNdJson(file);
84+
} catch (e) {
85+
return res.badRequest({
86+
body: e,
87+
});
88+
}
89+
8190
const result = await resolveSavedObjectsImportErrors({
8291
typeRegistry: context.core.savedObjects.typeRegistry,
8392
savedObjectsClient: context.core.savedObjects.client,
84-
readStream: createSavedObjectsStreamFromNdJson(file),
93+
readStream,
8594
retries: req.body.retries,
8695
objectLimit: maxImportExportSize,
8796
createNewCopies: req.query.createNewCopies,

src/core/server/saved_objects/routes/utils.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ async function readStreamToCompletion(stream: Readable) {
2727

2828
describe('createSavedObjectsStreamFromNdJson', () => {
2929
it('transforms an ndjson stream into a stream of saved objects', async () => {
30-
const savedObjectsStream = createSavedObjectsStreamFromNdJson(
30+
const savedObjectsStream = await createSavedObjectsStreamFromNdJson(
3131
new Readable({
3232
read() {
3333
this.push('{"id": "foo", "type": "foo-type"}\n');
@@ -52,7 +52,7 @@ describe('createSavedObjectsStreamFromNdJson', () => {
5252
});
5353

5454
it('skips empty lines', async () => {
55-
const savedObjectsStream = createSavedObjectsStreamFromNdJson(
55+
const savedObjectsStream = await createSavedObjectsStreamFromNdJson(
5656
new Readable({
5757
read() {
5858
this.push('{"id": "foo", "type": "foo-type"}\n');
@@ -79,7 +79,7 @@ describe('createSavedObjectsStreamFromNdJson', () => {
7979
});
8080

8181
it('filters the export details entry from the stream', async () => {
82-
const savedObjectsStream = createSavedObjectsStreamFromNdJson(
82+
const savedObjectsStream = await createSavedObjectsStreamFromNdJson(
8383
new Readable({
8484
read() {
8585
this.push('{"id": "foo", "type": "foo-type"}\n');

0 commit comments

Comments
 (0)