From 306905c8f8b84286e4868d7a7ffe1a07b53455f2 Mon Sep 17 00:00:00 2001 From: Konrad Szwarc Date: Thu, 15 Jan 2026 14:30:49 +0100 Subject: [PATCH 1/6] Improve osquery API integration tests with proper setup and assertions --- .../api_integration/apis/osquery/assets.ts | 97 ++++++++++ .../apis/osquery/fleet_wrapper.ts | 172 ++++++++++++++++++ .../api_integration/apis/osquery/index.ts | 6 + .../apis/osquery/live_queries.ts | 102 +++++++++++ .../api_integration/apis/osquery/packs.ts | 124 +++++++++---- .../apis/osquery/privileges_check.ts | 26 +++ .../apis/osquery/saved_queries.ts | 84 +++++++++ .../api_integration/apis/osquery/status.ts | 118 ++++++++++++ 8 files changed, 691 insertions(+), 38 deletions(-) create mode 100644 x-pack/platform/test/api_integration/apis/osquery/assets.ts create mode 100644 x-pack/platform/test/api_integration/apis/osquery/fleet_wrapper.ts create mode 100644 x-pack/platform/test/api_integration/apis/osquery/live_queries.ts create mode 100644 x-pack/platform/test/api_integration/apis/osquery/privileges_check.ts create mode 100644 x-pack/platform/test/api_integration/apis/osquery/saved_queries.ts create mode 100644 x-pack/platform/test/api_integration/apis/osquery/status.ts diff --git a/x-pack/platform/test/api_integration/apis/osquery/assets.ts b/x-pack/platform/test/api_integration/apis/osquery/assets.ts new file mode 100644 index 0000000000000..e141c2cb000ef --- /dev/null +++ b/x-pack/platform/test/api_integration/apis/osquery/assets.ts @@ -0,0 +1,97 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; +import type { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const fleetAndAgents = getService('fleetAndAgents'); + const kibanaServer = getService('kibanaServer'); + const fleetApiVersion = '2023-10-31'; + + const getAssetsStatus = () => + supertest + .get('/internal/osquery/assets') + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.internal.v1); + + const updateAssetsStatus = () => + supertest + .post('/internal/osquery/assets/update') + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.internal.v1); + + describe('Assets', () => { + let osqueryPackageVersion: string | undefined; + + before(async () => { + await kibanaServer.savedObjects.cleanStandardList(); + await fleetAndAgents.setup(); + + const { body: osqueryPackageResponse } = await supertest + .get('/api/fleet/epm/packages/osquery_manager') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .set('x-elastic-internal-product', 'security-solution'); + + osqueryPackageVersion = osqueryPackageResponse.item?.version; + + if (osqueryPackageVersion) { + await supertest + .post(`/api/fleet/epm/packages/osquery_manager/${osqueryPackageVersion}`) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .send({ force: true }) + .expect(200); + } + }); + + after(async () => { + if (osqueryPackageVersion) { + await supertest + .delete(`/api/fleet/epm/packages/osquery_manager/${osqueryPackageVersion}`) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion); + } + + await kibanaServer.savedObjects.cleanStandardList(); + }); + + it('returns prebuilt pack assets status with install, update, and upToDate arrays', async () => { + const response = await getAssetsStatus(); + + expect(response.status).to.be(200); + expect(response.body).to.have.property('install'); + expect(response.body).to.have.property('update'); + expect(response.body).to.have.property('upToDate'); + expect(response.body.install).to.be.an('array'); + expect(response.body.update).to.be.an('array'); + expect(response.body.upToDate).to.be.an('array'); + }); + + it('installs prebuilt pack assets and returns updated status', async () => { + const updateResponse = await updateAssetsStatus(); + + expect(updateResponse.status).to.be(200); + expect(updateResponse.body).to.have.property('install'); + expect(updateResponse.body).to.have.property('update'); + expect(updateResponse.body).to.have.property('upToDate'); + + const statusAfterUpdate = await getAssetsStatus(); + expect(statusAfterUpdate.status).to.be(200); + + const totalAssets = + statusAfterUpdate.body.install.length + + statusAfterUpdate.body.update.length + + statusAfterUpdate.body.upToDate.length; + expect(totalAssets).to.be.greaterThan(0); + }); + }); +} diff --git a/x-pack/platform/test/api_integration/apis/osquery/fleet_wrapper.ts b/x-pack/platform/test/api_integration/apis/osquery/fleet_wrapper.ts new file mode 100644 index 0000000000000..c26c705adad5c --- /dev/null +++ b/x-pack/platform/test/api_integration/apis/osquery/fleet_wrapper.ts @@ -0,0 +1,172 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; +import type { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const fleetAndAgents = getService('fleetAndAgents'); + const kibanaServer = getService('kibanaServer'); + const fleetApiVersion = '2023-10-31'; + + const getWithInternalHeaders = (path: string) => + supertest + .get(path) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.internal.v1); + + const postWithInternalHeaders = (path: string) => + supertest + .post(path) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.internal.v1); + + describe('Fleet wrapper', () => { + let agentPolicyId: string; + let agentId: string; + let packagePolicyId: string | undefined; + + before(async () => { + await kibanaServer.savedObjects.cleanStandardList(); + await fleetAndAgents.setup(); + + const { body: agentPolicyResponse } = await supertest + .post('/api/fleet/agent_policies') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .send({ + name: `Osquery policy ${Date.now()}`, + namespace: 'default', + }); + + agentPolicyId = agentPolicyResponse.item.id; + agentId = `osquery-agent-${Date.now()}`; + + const { body: osqueryPackageResponse } = await supertest + .get('/api/fleet/epm/packages/osquery_manager') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .set('x-elastic-internal-product', 'security-solution'); + + const { body: packagePolicyResponse } = await supertest + .post('/api/fleet/package_policies') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .send({ + policy_id: agentPolicyId, + package: { + name: 'osquery_manager', + version: osqueryPackageResponse.item?.version, + }, + name: `Osquery policy ${Date.now()}`, + description: '', + namespace: 'default', + inputs: { + 'osquery_manager-osquery': { + enabled: true, + streams: {}, + }, + }, + }); + + packagePolicyId = packagePolicyResponse.item?.id; + + await fleetAndAgents.generateAgent('online', agentId, agentPolicyId); + }); + + after(async () => { + if (agentPolicyId) { + await supertest + .post('/api/fleet/agent_policies/delete') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .send({ agentPolicyId }); + } + + if (packagePolicyId) { + await supertest + .post('/api/fleet/package_policies/delete') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .send({ packagePolicyIds: [packagePolicyId] }); + } + + await kibanaServer.savedObjects.cleanStandardList(); + }); + + it('lists agents', async () => { + const response = await getWithInternalHeaders( + '/internal/osquery/fleet_wrapper/agents?page=1&perPage=20&showInactive=false&kuery=' + ); + + expect(response.status).to.be(200); + expect(response.body.total).to.be.greaterThan(0); + expect(response.body).to.have.property('agents'); + expect(response.body).to.have.property('groups'); + }); + + it('returns bulk agent details', async () => { + const response = await postWithInternalHeaders( + '/internal/osquery/fleet_wrapper/agents/_bulk' + ).send({ + agentIds: [agentId], + }); + + expect(response.status).to.be(200); + expect(response.body.agents.some((agent: { id: string }) => agent.id === agentId)).to.be( + true + ); + }); + + it('lists agent policies', async () => { + const response = await getWithInternalHeaders( + '/internal/osquery/fleet_wrapper/agent_policies' + ); + + expect(response.status).to.be(200); + expect(response.body).to.be.an('array'); + }); + + it('reads an agent policy', async () => { + const response = await getWithInternalHeaders( + `/internal/osquery/fleet_wrapper/agent_policies/${agentPolicyId}` + ); + + expect(response.status).to.be(200); + expect(response.body.item.id).to.be(agentPolicyId); + }); + + it('returns agent status for policy', async () => { + const response = await getWithInternalHeaders( + `/internal/osquery/fleet_wrapper/agent_status?policyId=${agentPolicyId}` + ); + + expect(response.status).to.be(200); + }); + + it('lists package policies', async () => { + const response = await getWithInternalHeaders( + '/internal/osquery/fleet_wrapper/package_policies' + ); + + expect(response.status).to.be(200); + expect(response.body).to.have.property('items'); + }); + + it('returns agent details', async () => { + const response = await getWithInternalHeaders( + `/internal/osquery/fleet_wrapper/agents/${agentId}` + ); + + expect(response.status).to.be(200); + expect(response.body.item.id).to.be(agentId); + }); + }); +} diff --git a/x-pack/platform/test/api_integration/apis/osquery/index.ts b/x-pack/platform/test/api_integration/apis/osquery/index.ts index d6e6338defabe..c84f5d1851083 100644 --- a/x-pack/platform/test/api_integration/apis/osquery/index.ts +++ b/x-pack/platform/test/api_integration/apis/osquery/index.ts @@ -10,5 +10,11 @@ import type { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('Osquery Endpoints', () => { loadTestFile(require.resolve('./packs')); + loadTestFile(require.resolve('./assets')); + loadTestFile(require.resolve('./fleet_wrapper')); + loadTestFile(require.resolve('./saved_queries')); + loadTestFile(require.resolve('./privileges_check')); + loadTestFile(require.resolve('./status')); + loadTestFile(require.resolve('./live_queries')); }); } diff --git a/x-pack/platform/test/api_integration/apis/osquery/live_queries.ts b/x-pack/platform/test/api_integration/apis/osquery/live_queries.ts new file mode 100644 index 0000000000000..bab8c36178456 --- /dev/null +++ b/x-pack/platform/test/api_integration/apis/osquery/live_queries.ts @@ -0,0 +1,102 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; +import type { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const es = getService('es'); + + const actionIndex = '.logs-osquery_manager.actions-default'; + + const createActionDoc = async () => { + const actionId = `action-${Date.now()}`; + const queryActionId = `query-${Date.now()}`; + + await es.index({ + index: actionIndex, + id: actionId, + refresh: 'wait_for', + document: { + action_id: actionId, + '@timestamp': new Date().toISOString(), + expiration: new Date(Date.now() + 5 * 60 * 1000).toISOString(), + agent_selection: { all: true }, + agents: ['test-agent-1'], + user_id: 'elastic', + queries: [ + { + action_id: queryActionId, + id: 'query-1', + query: 'select 1;', + agents: ['test-agent-1'], + }, + ], + }, + }); + + return { actionId, queryActionId }; + }; + + const deleteActionDoc = async (actionId: string) => { + await es.deleteByQuery({ + index: actionIndex, + allow_no_indices: true, + ignore_unavailable: true, + refresh: true, + query: { + term: { + action_id: actionId, + }, + }, + }); + }; + + describe('Live queries', () => { + let actionId: string; + let queryActionId: string; + + before(async () => { + const created = await createActionDoc(); + actionId = created.actionId; + queryActionId = created.queryActionId; + }); + + after(async () => { + if (actionId) { + await deleteActionDoc(actionId); + } + }); + + it('fetches live query details by action id', async () => { + const detailsResponse = await supertest + .get(`/api/osquery/live_queries/${actionId}`) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1); + + expect(detailsResponse.status).to.be(200); + expect(detailsResponse.body.data.action_id).to.be(actionId); + expect(detailsResponse.body.data).to.have.property('queries'); + expect(detailsResponse.body.data.queries).to.be.an('array'); + expect(detailsResponse.body.data.queries[0].action_id).to.be(queryActionId); + }); + + it('fetches live query results for specific query', async () => { + const resultsResponse = await supertest + .get(`/api/osquery/live_queries/${actionId}/results/${queryActionId}`) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1); + + expect(resultsResponse.status).to.be(200); + expect(resultsResponse.body).to.have.property('data'); + expect(resultsResponse.body.data).to.have.property('edges'); + expect(resultsResponse.body.data).to.have.property('total'); + }); + }); +} diff --git a/x-pack/platform/test/api_integration/apis/osquery/packs.ts b/x-pack/platform/test/api_integration/apis/osquery/packs.ts index bf9f9eeccff0c..23324320f82d3 100644 --- a/x-pack/platform/test/api_integration/apis/osquery/packs.ts +++ b/x-pack/platform/test/api_integration/apis/osquery/packs.ts @@ -6,6 +6,9 @@ */ import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; +import type { Test } from 'supertest'; import type { FtrProviderContext } from '../../ftr_provider_context'; const getDefaultPack = ({ policyIds = [] }: { policyIds?: string[] }) => ({ @@ -44,77 +47,116 @@ limit 1000;`; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); + const fleetAndAgents = getService('fleetAndAgents'); + const fleetApiVersion = '2023-10-31'; - // FLAKY: https://github.com/elastic/kibana/issues/133259 - describe.skip('Packs', () => { + const withFleetHeaders = (request: Test) => + request.set('kbn-xsrf', 'true').set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion); + + const withOsqueryHeaders = (request: Test) => + request.set('kbn-xsrf', 'true').set('elastic-api-version', API_VERSIONS.public.v1); + + describe('Packs', () => { let packId: string = ''; let hostedPolicy: Record; let packagePolicyId: string; + let osqueryPackageVersion: string | undefined; before(async () => { await getService('kibanaServer').savedObjects.cleanStandardList(); await getService('esArchiver').load( 'x-pack/platform/test/fixtures/es_archives/fleet/empty_fleet_server' ); + + await fleetAndAgents.setup(); + + const { body: osqueryPackageResponse } = await supertest + .get('/api/fleet/epm/packages/osquery_manager') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .set('x-elastic-internal-product', 'security-solution'); + + osqueryPackageVersion = osqueryPackageResponse.item?.version; + + if (osqueryPackageVersion) { + await withFleetHeaders( + supertest.post(`/api/fleet/epm/packages/osquery_manager/${osqueryPackageVersion}`) + ) + .send({ force: true }) + .expect(200); + } }); after(async () => { await getService('kibanaServer').savedObjects.cleanStandardList(); await getService('esArchiver').unload( 'x-pack/platform/test/fixtures/es_archives/fleet/empty_fleet_server' ); + if (packagePolicyId) { + await withFleetHeaders(supertest.post('/api/fleet/package_policies/delete')).send({ + packagePolicyIds: [packagePolicyId], + }); + } await supertest - .post(`/api/fleet/agent_policies/delete`) - .set('kbn-xsrf', 'xxxx') + .post('/api/fleet/agent_policies/delete') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) .send({ agentPolicyId: hostedPolicy.id }); + + if (osqueryPackageVersion) { + await withFleetHeaders( + supertest.delete(`/api/fleet/epm/packages/osquery_manager/${osqueryPackageVersion}`) + ); + } }); it('create route should return 200 and multi line query, but single line query in packs config', async () => { const { body: { item: agentPolicy }, } = await supertest - .post(`/api/fleet/agent_policies`) - .set('kbn-xsrf', 'xxxx') + .post('/api/fleet/agent_policies') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) .send({ name: `Hosted policy from ${Date.now()}`, namespace: 'default', - }); + }) + .expect(200); + hostedPolicy = agentPolicy; - const packagePolicyResponse = await supertest + const { + body: { item: packagePolicy }, + } = await supertest .post('/api/fleet/package_policies') .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) .send({ - enabled: true, package: { name: 'osquery_manager', - version: '1.2.1', - title: 'test', + version: osqueryPackageVersion, + }, + inputs: { + 'osquery_manager-osquery': { + enabled: true, + streams: {}, + }, }, - inputs: [], namespace: 'default', - policy_id: hostedPolicy.id, + policy_ids: [hostedPolicy.id], name: 'TEST', description: '123', - id: '123', - }); - - if (!packagePolicyResponse.body.item) { - // eslint-disable-next-line no-console - console.error({ MISSING: packagePolicyResponse }); - } + }) + .expect(200); - expect(packagePolicyResponse.status).to.be(200); + packagePolicyId = packagePolicy.id; - packagePolicyId = packagePolicyResponse.body.item.id; + const createPackResponse = await withOsqueryHeaders(supertest.post('/api/osquery/packs')) + .send(getDefaultPack({ policyIds: [hostedPolicy.id] })) + .expect(200); - const createPackResponse = await supertest - .post('/api/osquery/packs') - .set('kbn-xsrf', 'true') - .send(getDefaultPack({ policyIds: [hostedPolicy.id] })); - - packId = createPackResponse.body.data.id; - expect(createPackResponse.status).to.be(200); + packId = createPackResponse.body.data.saved_object_id; + expect(packId).to.be.ok(); - const pack = await supertest.get('/api/osquery/packs/' + packId).set('kbn-xsrf', 'true'); + const pack = await withOsqueryHeaders(supertest.get('/api/osquery/packs/' + packId)); expect(pack.status).to.be(200); expect(pack.body.data.queries.testQuery.query).to.be(multiLineQuery); @@ -123,7 +165,10 @@ export default function ({ getService }: FtrProviderContext) { body: { item: { inputs }, }, - } = await supertest.get(`/api/fleet/package_policies/${packagePolicyId}`); + } = await supertest + .get(`/api/fleet/package_policies/${packagePolicyId}`) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion); expect(inputs[0].config.osquery.value.packs.TestPack.queries.testQuery.query).to.be( singleLineQuery @@ -131,21 +176,24 @@ export default function ({ getService }: FtrProviderContext) { }); it('update route should return 200 and multi line query, but single line query in packs config', async () => { - const updatePackResponse = await supertest - .put('/api/osquery/packs/' + packId) - .set('kbn-xsrf', 'true') - .send(getDefaultPack({ policyIds: [hostedPolicy.id] })); + expect(packId).to.be.ok(); + const updatePackResponse = await withOsqueryHeaders( + supertest.put('/api/osquery/packs/' + packId) + ).send(getDefaultPack({ policyIds: [hostedPolicy.id] })); expect(updatePackResponse.status).to.be(200); - expect(updatePackResponse.body.data.id).to.be(packId); - const pack = await supertest.get('/api/osquery/packs/' + packId).set('kbn-xsrf', 'true'); + expect(updatePackResponse.body.data.saved_object_id).to.be(packId); + const pack = await withOsqueryHeaders(supertest.get('/api/osquery/packs/' + packId)); expect(pack.body.data.queries.testQuery.query).to.be(multiLineQuery); const { body: { item: { inputs }, }, - } = await supertest.get(`/api/fleet/package_policies/${packagePolicyId}`); + } = await supertest + .get(`/api/fleet/package_policies/${packagePolicyId}`) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion); expect(inputs[0].config.osquery.value.packs.TestPack.queries.testQuery.query).to.be( singleLineQuery diff --git a/x-pack/platform/test/api_integration/apis/osquery/privileges_check.ts b/x-pack/platform/test/api_integration/apis/osquery/privileges_check.ts new file mode 100644 index 0000000000000..a27063b551507 --- /dev/null +++ b/x-pack/platform/test/api_integration/apis/osquery/privileges_check.ts @@ -0,0 +1,26 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; +import type { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + + describe('Privileges check', () => { + it('returns true for superuser with full index access', async () => { + const response = await supertest + .get('/internal/osquery/privileges_check') + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.internal.v1); + + expect(response.status).to.be(200); + expect(response.text).to.be('true'); + }); + }); +} diff --git a/x-pack/platform/test/api_integration/apis/osquery/saved_queries.ts b/x-pack/platform/test/api_integration/apis/osquery/saved_queries.ts new file mode 100644 index 0000000000000..925a6429e4348 --- /dev/null +++ b/x-pack/platform/test/api_integration/apis/osquery/saved_queries.ts @@ -0,0 +1,84 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; +import type { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + + const createSavedQuery = (id: string) => + supertest + .post('/api/osquery/saved_queries') + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .send({ + id, + query: 'select 1;', + interval: '3600', + }); + + const getSavedQuery = (savedObjectId: string) => + supertest + .get(`/api/osquery/saved_queries/${savedObjectId}`) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1); + + const deleteSavedQuery = (savedObjectId: string) => + supertest + .delete(`/api/osquery/saved_queries/${savedObjectId}`) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1); + + const updateSavedQuery = (savedObjectId: string, id: string) => + supertest + .put(`/api/osquery/saved_queries/${savedObjectId}`) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .send({ + id, + query: 'select 2;', + interval: 3600, + }); + + const findSavedQueries = () => + supertest + .get('/api/osquery/saved_queries?page=1&pageSize=20') + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1); + + describe('Saved queries', () => { + it('creates, reads, and deletes a saved query', async () => { + const savedQueryId = `saved-query-${Date.now()}`; + + const createResponse = await createSavedQuery(savedQueryId); + expect(createResponse.status).to.be(200); + const savedObjectId = createResponse.body.data.saved_object_id; + + const readResponse = await getSavedQuery(savedObjectId); + expect(readResponse.status).to.be(200); + expect(readResponse.body.data.id).to.be(savedQueryId); + + const updatedSavedQueryId = `${savedQueryId}-updated`; + const updateResponse = await updateSavedQuery(savedObjectId, updatedSavedQueryId); + expect(updateResponse.status).to.be(200); + expect(updateResponse.body.data.id).to.be(updatedSavedQueryId); + + const findResponse = await findSavedQueries(); + expect(findResponse.status).to.be(200); + expect( + findResponse.body.data.some( + (savedQuery: { id: string }) => savedQuery.id === updatedSavedQueryId + ) + ).to.be(true); + + const deleteResponse = await deleteSavedQuery(savedObjectId); + expect(deleteResponse.status).to.be(200); + }); + }); +} diff --git a/x-pack/platform/test/api_integration/apis/osquery/status.ts b/x-pack/platform/test/api_integration/apis/osquery/status.ts new file mode 100644 index 0000000000000..0ef0b07c83787 --- /dev/null +++ b/x-pack/platform/test/api_integration/apis/osquery/status.ts @@ -0,0 +1,118 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; +import type { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const fleetAndAgents = getService('fleetAndAgents'); + const kibanaServer = getService('kibanaServer'); + const fleetApiVersion = '2023-10-31'; + + describe('Status', () => { + let agentPolicyId: string; + let packagePolicyId: string | undefined; + let osqueryPackageVersion: string | undefined; + + before(async () => { + await kibanaServer.savedObjects.cleanStandardList(); + await fleetAndAgents.setup(); + + const { body: osqueryPackageResponse } = await supertest + .get('/api/fleet/epm/packages/osquery_manager') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .set('x-elastic-internal-product', 'security-solution'); + + osqueryPackageVersion = osqueryPackageResponse.item?.version; + + if (osqueryPackageVersion) { + await supertest + .post(`/api/fleet/epm/packages/osquery_manager/${osqueryPackageVersion}`) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .send({ force: true }) + .expect(200); + } + + const { body: agentPolicyResponse } = await supertest + .post('/api/fleet/agent_policies') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .send({ + name: `Osquery status test policy ${Date.now()}`, + namespace: 'default', + }); + + agentPolicyId = agentPolicyResponse.item.id; + + const { body: packagePolicyResponse } = await supertest + .post('/api/fleet/package_policies') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .send({ + policy_id: agentPolicyId, + package: { + name: 'osquery_manager', + version: osqueryPackageVersion, + }, + name: `Osquery status test ${Date.now()}`, + namespace: 'default', + inputs: { + 'osquery_manager-osquery': { + enabled: true, + streams: {}, + }, + }, + }); + + packagePolicyId = packagePolicyResponse.item?.id; + }); + + after(async () => { + if (packagePolicyId) { + await supertest + .post('/api/fleet/package_policies/delete') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .send({ packagePolicyIds: [packagePolicyId] }); + } + + if (agentPolicyId) { + await supertest + .post('/api/fleet/agent_policies/delete') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion) + .send({ agentPolicyId }); + } + + if (osqueryPackageVersion) { + await supertest + .delete(`/api/fleet/epm/packages/osquery_manager/${osqueryPackageVersion}`) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion); + } + + await kibanaServer.savedObjects.cleanStandardList(); + }); + + it('returns osquery installation status with package info', async () => { + const response = await supertest + .get('/internal/osquery/status') + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.internal.v1); + + expect(response.status).to.be(200); + expect(response.body).to.have.property('name', 'osquery_manager'); + expect(response.body).to.have.property('version'); + expect(response.body).to.have.property('install_status'); + }); + }); +} From 84ca302c572fe85f7782ce16ab765d83add1f7f6 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 16 Jan 2026 10:16:13 +0000 Subject: [PATCH 2/6] Changes from node scripts/lint_ts_projects --fix --- x-pack/platform/test/tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/test/tsconfig.json b/x-pack/platform/test/tsconfig.json index 932e4aa0155d1..2f447952f99df 100644 --- a/x-pack/platform/test/tsconfig.json +++ b/x-pack/platform/test/tsconfig.json @@ -180,6 +180,7 @@ "@kbn/streamlang", "@kbn/dashboard-plugin", "@kbn/automatic-import-v2-plugin", - "@kbn/connector-specs" + "@kbn/connector-specs", + "@kbn/osquery-plugin" ] } From 30ca2deb21f7d6eeafd0f45bfcfa1795962b49c5 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 16 Jan 2026 10:27:37 +0000 Subject: [PATCH 3/6] Changes from node scripts/regenerate_moon_projects.js --update --- x-pack/platform/test/moon.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/platform/test/moon.yml b/x-pack/platform/test/moon.yml index 8b2f641bff049..20e237ad2d19e 100644 --- a/x-pack/platform/test/moon.yml +++ b/x-pack/platform/test/moon.yml @@ -169,6 +169,7 @@ dependsOn: - '@kbn/dashboard-plugin' - '@kbn/automatic-import-v2-plugin' - '@kbn/connector-specs' + - '@kbn/osquery-plugin' tags: - test-helper - package From ece7a22e90a623dd0b8d9dafe9520712a76f016c Mon Sep 17 00:00:00 2001 From: Konrad Szwarc Date: Fri, 16 Jan 2026 11:28:16 +0100 Subject: [PATCH 4/6] Remove osquery plugin import to fix tsconfig reference error --- .../test/api_integration/apis/osquery/assets.ts | 6 +++--- .../api_integration/apis/osquery/fleet_wrapper.ts | 6 +++--- .../api_integration/apis/osquery/live_queries.ts | 6 +++--- .../test/api_integration/apis/osquery/packs.ts | 4 ++-- .../api_integration/apis/osquery/privileges_check.ts | 4 ++-- .../api_integration/apis/osquery/saved_queries.ts | 12 ++++++------ .../test/api_integration/apis/osquery/status.ts | 4 ++-- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/x-pack/platform/test/api_integration/apis/osquery/assets.ts b/x-pack/platform/test/api_integration/apis/osquery/assets.ts index e141c2cb000ef..4b32afbe17b29 100644 --- a/x-pack/platform/test/api_integration/apis/osquery/assets.ts +++ b/x-pack/platform/test/api_integration/apis/osquery/assets.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; -import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; import type { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { @@ -15,18 +14,19 @@ export default function ({ getService }: FtrProviderContext) { const fleetAndAgents = getService('fleetAndAgents'); const kibanaServer = getService('kibanaServer'); const fleetApiVersion = '2023-10-31'; + const osqueryInternalApiVersion = '1'; const getAssetsStatus = () => supertest .get('/internal/osquery/assets') .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.internal.v1); + .set('elastic-api-version', osqueryInternalApiVersion); const updateAssetsStatus = () => supertest .post('/internal/osquery/assets/update') .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.internal.v1); + .set('elastic-api-version', osqueryInternalApiVersion); describe('Assets', () => { let osqueryPackageVersion: string | undefined; diff --git a/x-pack/platform/test/api_integration/apis/osquery/fleet_wrapper.ts b/x-pack/platform/test/api_integration/apis/osquery/fleet_wrapper.ts index c26c705adad5c..4f98224fed9b0 100644 --- a/x-pack/platform/test/api_integration/apis/osquery/fleet_wrapper.ts +++ b/x-pack/platform/test/api_integration/apis/osquery/fleet_wrapper.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; -import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; import type { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { @@ -15,18 +14,19 @@ export default function ({ getService }: FtrProviderContext) { const fleetAndAgents = getService('fleetAndAgents'); const kibanaServer = getService('kibanaServer'); const fleetApiVersion = '2023-10-31'; + const osqueryInternalApiVersion = '1'; const getWithInternalHeaders = (path: string) => supertest .get(path) .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.internal.v1); + .set('elastic-api-version', osqueryInternalApiVersion); const postWithInternalHeaders = (path: string) => supertest .post(path) .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.internal.v1); + .set('elastic-api-version', osqueryInternalApiVersion); describe('Fleet wrapper', () => { let agentPolicyId: string; diff --git a/x-pack/platform/test/api_integration/apis/osquery/live_queries.ts b/x-pack/platform/test/api_integration/apis/osquery/live_queries.ts index bab8c36178456..3f8e26a0f1db8 100644 --- a/x-pack/platform/test/api_integration/apis/osquery/live_queries.ts +++ b/x-pack/platform/test/api_integration/apis/osquery/live_queries.ts @@ -6,12 +6,12 @@ */ import expect from '@kbn/expect'; -import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; import type { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const es = getService('es'); + const osqueryPublicApiVersion = '2023-10-31'; const actionIndex = '.logs-osquery_manager.actions-default'; @@ -78,7 +78,7 @@ export default function ({ getService }: FtrProviderContext) { const detailsResponse = await supertest .get(`/api/osquery/live_queries/${actionId}`) .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.public.v1); + .set('elastic-api-version', osqueryPublicApiVersion); expect(detailsResponse.status).to.be(200); expect(detailsResponse.body.data.action_id).to.be(actionId); @@ -91,7 +91,7 @@ export default function ({ getService }: FtrProviderContext) { const resultsResponse = await supertest .get(`/api/osquery/live_queries/${actionId}/results/${queryActionId}`) .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.public.v1); + .set('elastic-api-version', osqueryPublicApiVersion); expect(resultsResponse.status).to.be(200); expect(resultsResponse.body).to.have.property('data'); diff --git a/x-pack/platform/test/api_integration/apis/osquery/packs.ts b/x-pack/platform/test/api_integration/apis/osquery/packs.ts index 23324320f82d3..10f96833bf40c 100644 --- a/x-pack/platform/test/api_integration/apis/osquery/packs.ts +++ b/x-pack/platform/test/api_integration/apis/osquery/packs.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; -import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; import type { Test } from 'supertest'; import type { FtrProviderContext } from '../../ftr_provider_context'; @@ -49,12 +48,13 @@ export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const fleetAndAgents = getService('fleetAndAgents'); const fleetApiVersion = '2023-10-31'; + const osqueryPublicApiVersion = '2023-10-31'; const withFleetHeaders = (request: Test) => request.set('kbn-xsrf', 'true').set(ELASTIC_HTTP_VERSION_HEADER, fleetApiVersion); const withOsqueryHeaders = (request: Test) => - request.set('kbn-xsrf', 'true').set('elastic-api-version', API_VERSIONS.public.v1); + request.set('kbn-xsrf', 'true').set('elastic-api-version', osqueryPublicApiVersion); describe('Packs', () => { let packId: string = ''; diff --git a/x-pack/platform/test/api_integration/apis/osquery/privileges_check.ts b/x-pack/platform/test/api_integration/apis/osquery/privileges_check.ts index a27063b551507..ecccf499a5929 100644 --- a/x-pack/platform/test/api_integration/apis/osquery/privileges_check.ts +++ b/x-pack/platform/test/api_integration/apis/osquery/privileges_check.ts @@ -6,18 +6,18 @@ */ import expect from '@kbn/expect'; -import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; import type { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); + const osqueryInternalApiVersion = '1'; describe('Privileges check', () => { it('returns true for superuser with full index access', async () => { const response = await supertest .get('/internal/osquery/privileges_check') .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.internal.v1); + .set('elastic-api-version', osqueryInternalApiVersion); expect(response.status).to.be(200); expect(response.text).to.be('true'); diff --git a/x-pack/platform/test/api_integration/apis/osquery/saved_queries.ts b/x-pack/platform/test/api_integration/apis/osquery/saved_queries.ts index 925a6429e4348..73f9bba3652b2 100644 --- a/x-pack/platform/test/api_integration/apis/osquery/saved_queries.ts +++ b/x-pack/platform/test/api_integration/apis/osquery/saved_queries.ts @@ -6,17 +6,17 @@ */ import expect from '@kbn/expect'; -import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; import type { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); + const osqueryPublicApiVersion = '2023-10-31'; const createSavedQuery = (id: string) => supertest .post('/api/osquery/saved_queries') .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.public.v1) + .set('elastic-api-version', osqueryPublicApiVersion) .send({ id, query: 'select 1;', @@ -27,19 +27,19 @@ export default function ({ getService }: FtrProviderContext) { supertest .get(`/api/osquery/saved_queries/${savedObjectId}`) .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.public.v1); + .set('elastic-api-version', osqueryPublicApiVersion); const deleteSavedQuery = (savedObjectId: string) => supertest .delete(`/api/osquery/saved_queries/${savedObjectId}`) .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.public.v1); + .set('elastic-api-version', osqueryPublicApiVersion); const updateSavedQuery = (savedObjectId: string, id: string) => supertest .put(`/api/osquery/saved_queries/${savedObjectId}`) .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.public.v1) + .set('elastic-api-version', osqueryPublicApiVersion) .send({ id, query: 'select 2;', @@ -50,7 +50,7 @@ export default function ({ getService }: FtrProviderContext) { supertest .get('/api/osquery/saved_queries?page=1&pageSize=20') .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.public.v1); + .set('elastic-api-version', osqueryPublicApiVersion); describe('Saved queries', () => { it('creates, reads, and deletes a saved query', async () => { diff --git a/x-pack/platform/test/api_integration/apis/osquery/status.ts b/x-pack/platform/test/api_integration/apis/osquery/status.ts index 0ef0b07c83787..fc0b6bf01fb69 100644 --- a/x-pack/platform/test/api_integration/apis/osquery/status.ts +++ b/x-pack/platform/test/api_integration/apis/osquery/status.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; -import { API_VERSIONS } from '@kbn/osquery-plugin/common/constants'; import type { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { @@ -15,6 +14,7 @@ export default function ({ getService }: FtrProviderContext) { const fleetAndAgents = getService('fleetAndAgents'); const kibanaServer = getService('kibanaServer'); const fleetApiVersion = '2023-10-31'; + const osqueryInternalApiVersion = '1'; describe('Status', () => { let agentPolicyId: string; @@ -107,7 +107,7 @@ export default function ({ getService }: FtrProviderContext) { const response = await supertest .get('/internal/osquery/status') .set('kbn-xsrf', 'true') - .set('elastic-api-version', API_VERSIONS.internal.v1); + .set('elastic-api-version', osqueryInternalApiVersion); expect(response.status).to.be(200); expect(response.body).to.have.property('name', 'osquery_manager'); From dee4c0b918bb53a4e831f6abc17e52988a8d665c Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 16 Jan 2026 10:44:31 +0000 Subject: [PATCH 5/6] Changes from node scripts/lint_ts_projects --fix --- x-pack/platform/test/tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/platform/test/tsconfig.json b/x-pack/platform/test/tsconfig.json index 2f447952f99df..79fba4ccfb058 100644 --- a/x-pack/platform/test/tsconfig.json +++ b/x-pack/platform/test/tsconfig.json @@ -181,6 +181,5 @@ "@kbn/dashboard-plugin", "@kbn/automatic-import-v2-plugin", "@kbn/connector-specs", - "@kbn/osquery-plugin" ] } From 0a5bbdf50fed124679eaa89d24986c595ee111a5 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 16 Jan 2026 10:56:16 +0000 Subject: [PATCH 6/6] Changes from node scripts/regenerate_moon_projects.js --update --- x-pack/platform/test/moon.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/platform/test/moon.yml b/x-pack/platform/test/moon.yml index 20e237ad2d19e..8b2f641bff049 100644 --- a/x-pack/platform/test/moon.yml +++ b/x-pack/platform/test/moon.yml @@ -169,7 +169,6 @@ dependsOn: - '@kbn/dashboard-plugin' - '@kbn/automatic-import-v2-plugin' - '@kbn/connector-specs' - - '@kbn/osquery-plugin' tags: - test-helper - package