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..4b32afbe17b29 --- /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 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 osqueryInternalApiVersion = '1'; + + const getAssetsStatus = () => + supertest + .get('/internal/osquery/assets') + .set('kbn-xsrf', 'true') + .set('elastic-api-version', osqueryInternalApiVersion); + + const updateAssetsStatus = () => + supertest + .post('/internal/osquery/assets/update') + .set('kbn-xsrf', 'true') + .set('elastic-api-version', osqueryInternalApiVersion); + + 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..4f98224fed9b0 --- /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 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 osqueryInternalApiVersion = '1'; + + const getWithInternalHeaders = (path: string) => + supertest + .get(path) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', osqueryInternalApiVersion); + + const postWithInternalHeaders = (path: string) => + supertest + .post(path) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', osqueryInternalApiVersion); + + 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..3f8e26a0f1db8 --- /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 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'; + + 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', osqueryPublicApiVersion); + + 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', osqueryPublicApiVersion); + + 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..10f96833bf40c 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,8 @@ */ import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import type { Test } from 'supertest'; import type { FtrProviderContext } from '../../ftr_provider_context'; const getDefaultPack = ({ policyIds = [] }: { policyIds?: string[] }) => ({ @@ -44,77 +46,117 @@ limit 1000;`; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); + const fleetAndAgents = getService('fleetAndAgents'); + const fleetApiVersion = '2023-10-31'; + const osqueryPublicApiVersion = '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', osqueryPublicApiVersion); + + 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..ecccf499a5929 --- /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 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', 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 new file mode 100644 index 0000000000000..73f9bba3652b2 --- /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 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', osqueryPublicApiVersion) + .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', osqueryPublicApiVersion); + + const deleteSavedQuery = (savedObjectId: string) => + supertest + .delete(`/api/osquery/saved_queries/${savedObjectId}`) + .set('kbn-xsrf', 'true') + .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', osqueryPublicApiVersion) + .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', osqueryPublicApiVersion); + + 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..fc0b6bf01fb69 --- /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 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 osqueryInternalApiVersion = '1'; + + 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', osqueryInternalApiVersion); + + 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'); + }); + }); +}