-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
migrate savedObjects routes to core #56734
migrate savedObjects routes to core #56734
Conversation
Pinging @elastic/kibana-platform (Team:Platform) |
if ((types?.length ?? 0) > 0 && (objects?.length ?? 0) > 0) { | ||
throw Boom.badRequest(`Can't specify both "types" and "objects" properties when exporting`); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The route validation was using an nand(types, objects)
. As we don't have the equivalent in config-schema (probably for the best), I moved this check in the actual service method. This probably is it's place anyway.
I also had to fix some calls that were actually sending both (with types being used as they are exclude in the business logic)
types: ['index-pattern', 'search'], | ||
objects: [ | ||
{ | ||
type: 'index-pattern', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment on get_sorted_objects_for_export.ts
router.handleLegacyErrors(async (context, req, res) => { | ||
const savedObject = await context.core.savedObjects.client.bulkUpdate(req.body); | ||
return res.ok({ body: savedObject }); | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The savedObject service actually throws boom
errors. I had to wrap the handlers using handleLegacyErrors
.
import { | ||
createPromiseFromStreams, | ||
createMapStream, | ||
createConcatStream, | ||
} from '../../../../legacy/utils/streams'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole SO import/export APIs rely on our legacy stream utilities. As we don't want to loose the (not yet used but anyway) http streaming feature for the export and import, I kept using them (changing that would mean some structural changes in the getSortedObjectsForExport
method and it's underlying components. This is not the first time we are importing this in core SO code though. We probably will have to move it to core at some point (FTR services also uses them, so this will not be removed when we remove legacy, at least no without rewrite), but the PR is already big, did not want to do it here.
export const savedObjectsConfig = { | ||
path: 'savedObjects', | ||
schema: schema.object({ | ||
maxImportPayloadBytes: schema.number({ defaultValue: 10485760 }), | ||
maxImportExportSize: schema.number({ defaultValue: 10000 }), | ||
}), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the import/export routes, I now need the 'real' savedObject config. What we called that previously was the config for the migrations
config namespace. I created the SavedObjectConfig
class to 'merge' them. I kept the migrations properties as an underlying object to avoid breaking every signature in the SO migrator code, and also because I think this isolation makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a blocker, just curious: Do we want to move migrations
--> savedObjects.migration
in the future? Will we have migrations fields in v8 with saved objects v2? @rudolf
// eslint-disable-next-line @kbn/eslint/no-restricted-paths | ||
import { SavedObjectReference } from '../../../../core/server'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is server code (SO migrations), but outside of the server
folder, which explains the disabled rule
loadTestFile(require.resolve('./csp')); | ||
loadTestFile(require.resolve('./prototype_pollution')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test was using a legacy SO endpoint to test against prototype pollution. We don't have yet that kind of protection in NP. After discussion with @legrego, we agreed to delete the test, and to properly reimplement it when the feature would lands to NP.
objects: options.objects, | ||
savedObjectsClient, | ||
types: eligibleTypes, | ||
types: options.objects.length > 0 ? undefined : eligibleTypes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As explained in a previous comment, When sending both objects
and types
, only objects
were used. However the validation to not send both was performed in the route handler. As I moved it to the service, I had to adapt some calls to no longer send both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@legrego do you happen to recall why we used to always be passing in eligibleTypes
here? It looks like this was being ignored... I'm tempted to say we should just always pass in undefined
here if that's the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The intent was to prevent namespace agnostic types from being specified, but that's handled on the subsequent call to importSavedObjects
, so I agree we should just always pass undefined
here, rather than eligibleTypes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack, will just remove the types
parameter from the call then
describe('Routes', () => { | ||
it('should create 12 routes', () => { | ||
savedObjectsMixin(mockKbnServer, mockServer); | ||
expect(mockServer.route).toHaveBeenCalledTimes(12); | ||
}); | ||
it('should add POST /api/saved_objects/_bulk_create', () => { | ||
savedObjectsMixin(mockKbnServer, mockServer); | ||
expect(mockServer.route).toHaveBeenCalledWith( | ||
expect.objectContaining({ path: '/api/saved_objects/_bulk_create', method: 'POST' }) | ||
); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is already covered by the API integration tests, so I did not move these tests to core. Tell me if I should.
|
||
return server; | ||
} | ||
httpSetup.registerRouteHandlerContext(coreId, 'core', async (ctx, req, res) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you already created the mock, we can expose it and document a usage example. can be done in a separate PR ofc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
created #57844
router.handleLegacyErrors(async (context, req, res) => { | ||
const { overwrite } = req.query; | ||
const file = req.body.file as FileStream; | ||
const fileExtension = extname(file.hapi.filename).toLowerCase(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't checked, but believe we should be able to access filename via Content-Disposition
header https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Content-Disposition
is not a header in multipart/form-data
, it's included in the actual payload. The only way to get the file name is to access the parsed payload, and HAPI do the parsing and exposes the name in this property. We can't do differently without tricky changes.
FYI, an example of such request in a 'json' format is
const request = {
method: 'POST',
url: '/api/saved_objects/_import',
payload: [
'--EXAMPLE',
'Content-Disposition: form-data; name="file"; filename="export.ndjson"',
'Content-Type: application/ndjson',
'',
'{"type":"index-pattern","id":"my-pattern","attributes":{"title":"my-pattern-*"}}',
'--EXAMPLE--',
].join('\r\n'),
headers: {
'content-Type': 'multipart/form-data; boundary=EXAMPLE',
},
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commented in #56944 let's merge as is
export const savedObjectsConfig = { | ||
path: 'savedObjects', | ||
schema: schema.object({ | ||
maxImportPayloadBytes: schema.number({ defaultValue: 10485760 }), | ||
maxImportExportSize: schema.number({ defaultValue: 10000 }), | ||
}), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a blocker, just curious: Do we want to move migrations
--> savedObjects.migration
in the future? Will we have migrations fields in v8 with saved objects v2? @rudolf
💚 Build SucceededHistory
To update your PR or re-run it, just comment with: |
* migrate `get` route * migrate `create` route * migrate `delete` route * migrate `find` route * migrate `update` route * migrate `bulk_get` route * migrate `bulk_create` route * remove route-related mixin tests * migrate `bulk_update` route * fix expectTypeRequired assertion * migrate `log_legacy_imports` route * migrate `export` route * fix karma tests * array is better than object in some situations. * remove prototype pollution tests * adapt ftr assertions * adapt ftr assertions * adapt yet more ftr assertions * migrate `import` route * fix test tests * fix getSortedObjectsForExport usages * fix snapshots * fix so ui exports usages due to merge * create router with prefix * creates `savedObjects` namespace config in addition to `migrations` * migrate `resolve_import_errors` route * remove old types file * fix FTR assertion * remove types parameter from copy_to_space * move route tests to integration_tests * use byteSize instead of number * fix unit tests * add has_reference query parameter Co-authored-by: Mikhail Shustov <[email protected]>
* migrate `get` route * migrate `create` route * migrate `delete` route * migrate `find` route * migrate `update` route * migrate `bulk_get` route * migrate `bulk_create` route * remove route-related mixin tests * migrate `bulk_update` route * fix expectTypeRequired assertion * migrate `log_legacy_imports` route * migrate `export` route * fix karma tests * array is better than object in some situations. * remove prototype pollution tests * adapt ftr assertions * adapt ftr assertions * adapt yet more ftr assertions * migrate `import` route * fix test tests * fix getSortedObjectsForExport usages * fix snapshots * fix so ui exports usages due to merge * create router with prefix * creates `savedObjects` namespace config in addition to `migrations` * migrate `resolve_import_errors` route * remove old types file * fix FTR assertion * remove types parameter from copy_to_space * move route tests to integration_tests * use byteSize instead of number * fix unit tests * add has_reference query parameter Co-authored-by: Mikhail Shustov <[email protected]> Co-authored-by: Pierre Gayvallet <[email protected]>
Summary
Fix #50321
Migrate the
/api/saved_objects/*
routes fromlegacy
tocore
Checklist
For maintainers