mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 19:13:14 -04:00
## Summary Updating the ES client to 9.0. Resolves #116102 ## What changes? **Breaking change**: `body` has been removed. Most of the changes are about bringing all the content inside the body as a root attribute to the API params: ```diff const response = await client.search({ index: 'test', - body: { query: { match_all: {} } - } }) ``` For this reason, enabling the "Hide whitespace changes" option when reviewing is recommended. Some exceptions to this rule: * Bulk APIs replace the `body` array with `operations` array (direct replacement) * Index Put Settings API replace `body` array with `settings` (direct replacement) * Msearch replaces the `body` array with `searches` array (direct replacement) * Document Index API replaces `body` with `document` (direct replacement) * Create Repository replaces `body` with `repository` (direct replacement) Because of a known issue in the client (https://github.com/elastic/elasticsearch-js/issues/2584), there's still an escape hatch to send data in the body in case the specific use case requires it via `// @ts-expect-error elasticsearch@9.0.0 https://github.com/elastic/elasticsearch-js/issues/2584`, but it shouldn't be abused because we lose types. In this PR we've used it in those scenarios where we reuse the response of a GET as the body of a PUT/POST. ### Other changes * `estypes` can be imported from the root of the library as `import type { estypes } from '@elastic/elasticsearch';` * `estypesWithBody` have been removed * `requestTimeout`'s 30s default has been removed in the client. This PR explicitly adds the setting in all client usages. ### Identify risks - [x] The client places unknown properties as querystring, risking body params leaking there, and causing 400 errors from ES => Solved by forcing `body` usage there via `// @ts-expect-error elasticsearch@9.0.0 https://github.com/elastic/elasticsearch-js/issues/2584`. The next version of the client will address this. - [x] We need to run the MKI tests to make sure that we're not breaking anything there => https://elastic.slack.com/archives/C04HT4P1YS3/p1739528112482629?thread_ts=1739480136.231439&cid=C04HT4P1YS3 --------- Co-authored-by: Gloria Hornero <gloria.hornero@elastic.co>
150 lines
5.2 KiB
TypeScript
150 lines
5.2 KiB
TypeScript
/*
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
* or more contributor license agreements. Licensed under the "Elastic License
|
|
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
|
* Public License v 1"; you may not use this file except in compliance with, at
|
|
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
|
* License v3.0 only", or the "Server Side Public License, v 1".
|
|
*/
|
|
|
|
import expect from '@kbn/expect';
|
|
import { getUrl } from '@kbn/test';
|
|
|
|
import { hasKibanaBooted } from '../fixtures/test_helpers';
|
|
import { getElasticsearchCaCertificate } from '../fixtures/tls_tools';
|
|
import type { FtrProviderContext } from '../ftr_provider_context';
|
|
|
|
export default function (context: FtrProviderContext) {
|
|
const supertest = context.getService('supertest');
|
|
const es = context.getService('es');
|
|
const log = context.getService('log');
|
|
const config = context.getService('config');
|
|
|
|
describe('Interactive setup APIs - Enrollment flow', function () {
|
|
this.tags(['skipCloud', 'skipFIPS']);
|
|
|
|
let kibanaVerificationCode: string;
|
|
let elasticsearchCaFingerprint: string;
|
|
before(async () => {
|
|
const esServerConfig = config.get('servers.elasticsearch');
|
|
elasticsearchCaFingerprint = (
|
|
await getElasticsearchCaCertificate(esServerConfig.host, esServerConfig.port)
|
|
).fingerprint256.replace(/:/g, '');
|
|
|
|
kibanaVerificationCode = (
|
|
await supertest.get('/test_endpoints/verification_code').expect(200)
|
|
).body.verificationCode;
|
|
});
|
|
|
|
let enrollmentAPIKey: string;
|
|
beforeEach(async () => {
|
|
const apiResponse = await es.security.createApiKey({ name: 'enrollment_api_key' });
|
|
enrollmentAPIKey = Buffer.from(`${apiResponse.id}:${apiResponse.api_key}`).toString('base64');
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await es.security.invalidateApiKey({ name: 'enrollment_api_key' });
|
|
});
|
|
|
|
it('fails to enroll with invalid authentication code', async () => {
|
|
const esHost = getUrl.baseUrl(config.get('servers.elasticsearch'));
|
|
const enrollPayload = {
|
|
apiKey: enrollmentAPIKey,
|
|
code: '000000',
|
|
caFingerprint: elasticsearchCaFingerprint,
|
|
hosts: [esHost],
|
|
};
|
|
|
|
log.debug(`Enroll payload ${JSON.stringify(enrollPayload)}`);
|
|
|
|
await supertest
|
|
.post('/internal/interactive_setup/enroll')
|
|
.set('kbn-xsrf', 'xxx')
|
|
.send(enrollPayload)
|
|
.expect(403, { statusCode: 403, error: 'Forbidden', message: 'Forbidden' });
|
|
});
|
|
|
|
it('fails to enroll with invalid CA fingerprint', async () => {
|
|
const esHost = getUrl.baseUrl(config.get('servers.elasticsearch'));
|
|
const enrollPayload = {
|
|
apiKey: enrollmentAPIKey,
|
|
code: kibanaVerificationCode,
|
|
caFingerprint: '3FDAEE71A3604070E6AE6B01412D19772DE5AE129F69C413F0453B293D9BE65D',
|
|
hosts: [esHost],
|
|
};
|
|
|
|
log.debug(`Enroll payload ${JSON.stringify(enrollPayload)}`);
|
|
|
|
await supertest
|
|
.post('/internal/interactive_setup/enroll')
|
|
.set('kbn-xsrf', 'xxx')
|
|
.send(enrollPayload)
|
|
.expect(500, {
|
|
statusCode: 500,
|
|
error: 'Internal Server Error',
|
|
message: 'Failed to enroll.',
|
|
attributes: { type: 'enroll_failure' },
|
|
});
|
|
});
|
|
|
|
it('fails to enroll with invalid api key', async function () {
|
|
const esServerConfig = config.get('servers.elasticsearch');
|
|
const enrollPayload = {
|
|
apiKey: enrollmentAPIKey,
|
|
code: kibanaVerificationCode,
|
|
caFingerprint: elasticsearchCaFingerprint,
|
|
hosts: [getUrl.baseUrl(esServerConfig)],
|
|
};
|
|
|
|
log.debug(`Enroll payload ${JSON.stringify(enrollPayload)}`);
|
|
|
|
// Invalidate API key.
|
|
await es.security.invalidateApiKey({ name: 'enrollment_api_key' });
|
|
|
|
await supertest
|
|
.post('/internal/interactive_setup/enroll')
|
|
.set('kbn-xsrf', 'xxx')
|
|
.send(enrollPayload)
|
|
.expect(500, {
|
|
statusCode: 500,
|
|
error: 'Internal Server Error',
|
|
message: 'Failed to enroll.',
|
|
attributes: { type: 'enroll_failure' },
|
|
});
|
|
});
|
|
|
|
it('should be able to enroll with valid authentication code', async function () {
|
|
this.timeout(60000);
|
|
|
|
const esServerConfig = config.get('servers.elasticsearch');
|
|
const enrollPayload = {
|
|
apiKey: enrollmentAPIKey,
|
|
code: kibanaVerificationCode,
|
|
caFingerprint: elasticsearchCaFingerprint,
|
|
hosts: [getUrl.baseUrl(esServerConfig)],
|
|
};
|
|
|
|
log.debug(`Enroll payload ${JSON.stringify(enrollPayload)}`);
|
|
|
|
await supertest
|
|
.post('/internal/interactive_setup/enroll')
|
|
.set('kbn-xsrf', 'xxx')
|
|
.send(enrollPayload)
|
|
.expect(204, {});
|
|
|
|
// Enroll should no longer accept requests.
|
|
await supertest
|
|
.post('/internal/interactive_setup/enroll')
|
|
.set('kbn-xsrf', 'xxx')
|
|
.send(enrollPayload)
|
|
.expect(400, {
|
|
error: 'Bad Request',
|
|
message: 'Cannot process request outside of preboot stage.',
|
|
statusCode: 400,
|
|
attributes: { type: 'outside_preboot_stage' },
|
|
});
|
|
|
|
expect(await hasKibanaBooted(context)).to.be(true);
|
|
});
|
|
});
|
|
}
|