diff --git a/.eslintrc.js b/.eslintrc.js index ad6ac0b328ce1..af44f330c171b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -470,9 +470,7 @@ const AXIOS_LEGACY_CONSUMERS = [ 'x-pack/solutions/security/plugins/security_solution/common/endpoint/format_axios_error.ts', 'x-pack/solutions/security/plugins/security_solution/common/endpoint/utils/**/*.{js,mjs,ts,tsx}', 'x-pack/solutions/security/plugins/security_solution/scripts/endpoint/**/*.{js,mjs,ts,tsx}', - 'x-pack/solutions/security/plugins/security_solution/scripts/telemetry/**/*.{js,mjs,ts,tsx}', 'x-pack/solutions/security/plugins/security_solution/server/integration_tests/**/*.{js,mjs,ts,tsx}', - 'x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/scripts/**/*.{js,mjs,ts,tsx}', 'x-pack/solutions/security/plugins/security_solution/server/lib/telemetry/**/*.{js,mjs,ts,tsx}', 'x-pack/solutions/security/test/security_solution_api_integration/config/services/**/*.{js,mjs,ts,tsx}', 'x-pack/solutions/security/test/security_solution_cypress/cypress/support/**/*.{js,mjs,ts,tsx}', diff --git a/x-pack/solutions/security/plugins/security_solution/scripts/telemetry/build_ebt_data_view.test.ts b/x-pack/solutions/security/plugins/security_solution/scripts/telemetry/build_ebt_data_view.test.ts index ac6320c2bfebb..063a4fb58eed6 100644 --- a/x-pack/solutions/security/plugins/security_solution/scripts/telemetry/build_ebt_data_view.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/scripts/telemetry/build_ebt_data_view.test.ts @@ -6,15 +6,9 @@ */ /* eslint-disable @typescript-eslint/no-explicit-any */ -import axios from 'axios'; import { flattenSchema, upsertRuntimeFields } from './build_ebt_data_view'; -jest.mock('axios', () => ({ - __esModule: true, - default: { - put: jest.fn(), - }, -})); +const mockedFetch = jest.spyOn(global, 'fetch'); describe('upsertRuntimeFields', () => { const url = 'http://fake_url'; @@ -26,7 +20,7 @@ describe('upsertRuntimeFields', () => { beforeEach(() => { jest.resetAllMocks(); - (axios.put as jest.Mock).mockResolvedValue({}); + mockedFetch.mockResolvedValue(new Response(null, { status: 200 })); }); test('sends one PUT per string field with correct payload and headers', async () => { @@ -38,26 +32,30 @@ describe('upsertRuntimeFields', () => { await upsertRuntimeFields(fields, url, headers); - expect(axios.put).toHaveBeenCalledTimes(3); + expect(mockedFetch).toHaveBeenCalledTimes(3); - const calls = (axios.put as jest.Mock).mock.calls.map(([callUrl, payload, opts]) => ({ - callUrl, - name: payload.name, - type: payload.runtimeField?.type, - opts, - })); + const calls = mockedFetch.mock.calls.map(([callUrl, opts]) => { + const payload = JSON.parse(opts?.body as string); + return { + callUrl, + method: opts?.method, + name: payload.name, + type: payload.runtimeField?.type, + headers: opts?.headers, + }; + }); const names = new Set(calls.map((c) => c.name)); const types = new Set(calls.map((c) => c.type)); const urls = new Set(calls.map((c) => c.callUrl)); - const allHeadersOk = calls.every( - (c) => JSON.stringify(c.opts?.headers) === JSON.stringify(headers) - ); + const allHeadersOk = calls.every((c) => JSON.stringify(c.headers) === JSON.stringify(headers)); + const allMethodsOk = calls.every((c) => c.method === 'PUT'); expect(names).toEqual(new Set(['properties.a', 'properties.nested.b', 'properties.deep.x.y'])); expect(types).toEqual(new Set(['keyword', 'long', 'date'])); expect(urls).toEqual(new Set([url])); expect(allHeadersOk).toBe(true); + expect(allMethodsOk).toBe(true); }); test('ignores non-string field values', async () => { @@ -70,15 +68,16 @@ describe('upsertRuntimeFields', () => { await upsertRuntimeFields(fields as any, url, headers); - expect(axios.put).toHaveBeenCalledTimes(1); - const [callUrl, payload, opts] = (axios.put as jest.Mock).mock.calls[0]; + expect(mockedFetch).toHaveBeenCalledTimes(1); + const [callUrl, opts] = mockedFetch.mock.calls[0]; expect(callUrl).toBe(url); - expect(payload).toEqual({ + expect(opts?.method).toBe('PUT'); + expect(JSON.parse(opts?.body as string)).toEqual({ name: 'properties.ok', runtimeField: { type: 'ip' }, }); - expect(opts).toEqual({ headers }); + expect(opts?.headers).toEqual(headers); }); test('handles dotted field names correctly', async () => { @@ -88,7 +87,8 @@ describe('upsertRuntimeFields', () => { await upsertRuntimeFields(fields, url, headers); - const [, payload] = (axios.put as jest.Mock).mock.calls[0]; + const [, opts] = mockedFetch.mock.calls[0]; + const payload = JSON.parse(opts?.body as string); expect(payload.name).toBe('properties.one.two.three'); expect(payload.runtimeField.type).toBe('double'); }); diff --git a/x-pack/solutions/security/plugins/security_solution/scripts/telemetry/build_ebt_data_view.ts b/x-pack/solutions/security/plugins/security_solution/scripts/telemetry/build_ebt_data_view.ts index 54ddfb93dcb9f..d4f570b786d27 100755 --- a/x-pack/solutions/security/plugins/security_solution/scripts/telemetry/build_ebt_data_view.ts +++ b/x-pack/solutions/security/plugins/security_solution/scripts/telemetry/build_ebt_data_view.ts @@ -6,7 +6,6 @@ */ import { ToolingLog } from '@kbn/tooling-log'; -import axios from 'axios'; import { events as genAiEvents } from '@kbn/elastic-assistant-plugin/server/lib/telemetry/event_based_telemetry'; import { isObject } from 'lodash'; @@ -77,13 +76,16 @@ async function cli(): Promise { try { logger.info(`Fetching data view "${dataViewName}"...`); - const { - data: { data_view: ourDataView }, - } = await axios.get(dataViewApiUrl, { + const response = await fetch(dataViewApiUrl, { headers: requestHeaders, }); + if (!response.ok) { + throw new Error(`${response.status}:${await response.text()}`); + } + + const responseBody = (await response.json()) as { data_view: unknown }; - if (!ourDataView) { + if (!responseBody.data_view) { throw new Error( `Data view "${dataViewName}" not found, check your data view is spelled correctly and is defined in the ${spaceId} space` ); @@ -210,9 +212,14 @@ export async function upsertRuntimeFields( }; try { - await axios.put(requestUrl, payload, { + const response = await fetch(requestUrl, { + method: 'PUT', headers: requestHeaders, + body: JSON.stringify(payload), }); + if (!response.ok) { + throw new Error(`${response.status}:${await response.text()}`); + } } catch (error) { throw new Error(`Error upserting field '${fieldName}: ${fieldType}' - ${error.message}`); } diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.ts index 04b09feb1a153..4687bd3009477 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.ts @@ -5,7 +5,6 @@ * 2.0. */ -import axios from 'axios'; import yargs from 'yargs'; import { ToolingLog } from '@kbn/tooling-log'; import { @@ -46,20 +45,22 @@ async function cli(): Promise { const requestHeaders = { Authorization: `Basic ${btoa(`${USERNAME}:${PASSWORD}`)}`, 'kbn-xsrf': 'xxx', + 'Content-Type': 'application/json', }; try { logger.info(`Creating role "${role}"...`); - await axios.put( - `${KIBANA_URL}/api/security/role/${role}`, - { + const response = await fetch(`${KIBANA_URL}/api/security/role/${role}`, { + method: 'PUT', + headers: requestHeaders, + body: JSON.stringify({ elasticsearch: selectedRoleDefinition.elasticsearch, kibana: selectedRoleDefinition.kibana, - }, - { - headers: requestHeaders, - } - ); + }), + }); + if (!response.ok) { + throw new Error(`${response.status}:${await response.text()}`); + } logger.info(`Role "${role}" has been created`); } catch (e) { @@ -69,18 +70,19 @@ async function cli(): Promise { try { logger.info(`Creating user "${userName}"...`); - await axios.put( - `${ELASTICSEARCH_URL}/_security/user/${userName}`, - { + const response = await fetch(`${ELASTICSEARCH_URL}/_security/user/${userName}`, { + method: 'PUT', + headers: requestHeaders, + body: JSON.stringify({ password, roles: [role], full_name: role, email: `role@example.com`, - }, - { - headers: requestHeaders, - } - ); + }), + }); + if (!response.ok) { + throw new Error(`${response.status}:${await response.text()}`); + } logger.info(`User "${userName}" has been created (password "${password}")`); } catch (e) {