diff --git a/x-pack/test/api_integration/services/usage_api.ts b/x-pack/test/api_integration/services/usage_api.ts index 500212d96ddfc..14ead21c86d2b 100644 --- a/x-pack/test/api_integration/services/usage_api.ts +++ b/x-pack/test/api_integration/services/usage_api.ts @@ -20,21 +20,38 @@ export interface UsageStatsPayloadTestFriendly extends UsageStatsPayload { export function UsageAPIProvider({ getService }: FtrProviderContext) { const supertest = getService('supertest'); - async function getTelemetryStats(payload: { - unencrypted: true; - refreshCache?: boolean; - }): Promise>; - async function getTelemetryStats(payload: { - unencrypted: false; - refreshCache?: boolean; - }): Promise>; - async function getTelemetryStats(payload: { - unencrypted?: boolean; - refreshCache?: boolean; - }): Promise> { + async function getTelemetryStats( + payload: { + unencrypted: true; + refreshCache?: boolean; + }, + options?: { authHeader: Record } + ): Promise>; + async function getTelemetryStats( + payload: { + unencrypted: false; + refreshCache?: boolean; + }, + options?: { authHeader: Record } + ): Promise>; + async function getTelemetryStats( + payload: { + unencrypted: false; + refreshCache?: boolean; + }, + options?: { authHeader: Record } + ): Promise>; + async function getTelemetryStats( + payload: { + unencrypted?: boolean; + refreshCache?: boolean; + }, + options?: { authHeader: Record } + ): Promise> { const { body } = await supertest .post('/internal/telemetry/clusters/_stats') .set('kbn-xsrf', 'xxx') + .set(options?.authHeader ?? {}) .set(ELASTIC_HTTP_VERSION_HEADER, '2') .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send({ refreshCache: true, ...payload }) diff --git a/x-pack/test_serverless/api_integration/services/slo_api.ts b/x-pack/test_serverless/api_integration/services/slo_api.ts index 7312905589cb7..96b7f9e518f31 100644 --- a/x-pack/test_serverless/api_integration/services/slo_api.ts +++ b/x-pack/test_serverless/api_integration/services/slo_api.ts @@ -10,6 +10,7 @@ import { FetchHistoricalSummaryResponse, } from '@kbn/slo-schema'; import * as t from 'io-ts'; +import type { RoleCredentials } from '../../shared/services'; import { FtrProviderContext } from '../ftr_provider_context'; type DurationUnit = 'm' | 'h' | 'd' | 'w' | 'M'; @@ -70,50 +71,58 @@ type FetchHistoricalSummaryParams = t.OutputOf< export function SloApiProvider({ getService }: FtrProviderContext) { const es = getService('es'); const supertest = getService('supertest'); + const svlCommonApi = getService('svlCommonApi'); const retry = getService('retry'); const requestTimeout = 30 * 1000; const retryTimeout = 180 * 1000; return { - async create(slo: SloParams) { + async create(slo: SloParams, roleAuthc: RoleCredentials) { const { body } = await supertest .post(`/api/observability/slos`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .send(slo); return body; }, - async delete(sloId: string) { + async delete({ sloId, roleAuthc }: { sloId: string; roleAuthc: RoleCredentials }) { const response = await supertest .delete(`/api/observability/slos/${sloId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader); return response; }, async fetchHistoricalSummary( - params: FetchHistoricalSummaryParams + params: FetchHistoricalSummaryParams, + roleAuthc: RoleCredentials ): Promise { const { body } = await supertest .post(`/internal/observability/slos/_historical_summary`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .send(params); return body; }, - async waitForSloToBeDeleted(sloId: string) { + async waitForSloToBeDeleted({ + sloId, + roleAuthc, + }: { + sloId: string; + roleAuthc: RoleCredentials; + }) { if (!sloId) { throw new Error(`sloId is undefined`); } return await retry.tryForTime(retryTimeout, async () => { const response = await supertest .delete(`/api/observability/slos/${sloId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .timeout(requestTimeout); if (!response.ok) { throw new Error(`slodId [${sloId}] was not deleted`); @@ -122,15 +131,15 @@ export function SloApiProvider({ getService }: FtrProviderContext) { }); }, - async waitForSloCreated({ sloId }: { sloId: string }) { + async waitForSloCreated({ sloId, roleAuthc }: { sloId: string; roleAuthc: RoleCredentials }) { if (!sloId) { throw new Error(`'sloId is undefined`); } return await retry.tryForTime(retryTimeout, async () => { const response = await supertest .get(`/api/observability/slos/${sloId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .timeout(requestTimeout); if (response.body.id === undefined) { throw new Error(`No slo with id ${sloId} found`); @@ -187,16 +196,14 @@ export function SloApiProvider({ getService }: FtrProviderContext) { async deleteAllSLOs() { const response = await supertest .get(`/api/observability/slos/_definitions`) - .set('kbn-xsrf', 'true') - .set('x-elastic-internal-origin', 'foo') + .set(svlCommonApi.getInternalRequestHeader()) .send() .expect(200); await Promise.all( response.body.results.map(({ id }: { id: string }) => { return supertest .delete(`/api/observability/slos/${id}`) - .set('kbn-xsrf', 'true') - .set('x-elastic-internal-origin', 'foo') + .set(svlCommonApi.getInternalRequestHeader()) .send() .expect(204); }) diff --git a/x-pack/test_serverless/api_integration/services/svl_cases/api.ts b/x-pack/test_serverless/api_integration/services/svl_cases/api.ts index 7089655551fbe..c01365861c2d3 100644 --- a/x-pack/test_serverless/api_integration/services/svl_cases/api.ts +++ b/x-pack/test_serverless/api_integration/services/svl_cases/api.ts @@ -5,13 +5,13 @@ * 2.0. */ -import type SuperTest from 'supertest'; import { CASES_URL } from '@kbn/cases-plugin/common'; import { Case, CaseSeverity, CaseStatuses } from '@kbn/cases-plugin/common/types/domain'; import type { CasePostRequest } from '@kbn/cases-plugin/common/types/api'; import { ConnectorTypes } from '@kbn/cases-plugin/common/types/domain'; import { CasesFindResponse } from '@kbn/cases-plugin/common/types/api'; import { kbnTestConfig, kibanaTestSuperuserServerless } from '@kbn/test'; +import type { RoleCredentials } from '../../../shared/services'; import { FtrProviderContext } from '../../ftr_provider_context'; export interface User { @@ -23,13 +23,8 @@ export interface User { export function SvlCasesApiServiceProvider({ getService }: FtrProviderContext) { const kbnServer = getService('kibanaServer'); - const supertest = getService('supertest'); - - const superUser: User = { - username: 'superuser', - password: 'superuser', - roles: ['superuser'], - }; + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const svlCommonApi = getService('svlCommonApi'); const defaultUser = { email: null, @@ -57,22 +52,6 @@ export function SvlCasesApiServiceProvider({ getService }: FtrProviderContext) { }; return { - setupAuth({ - apiCall, - headers, - auth, - }: { - apiCall: SuperTest.Test; - headers: Record; - auth?: { user: User; space: string | null } | null; - }): SuperTest.Test { - if (!Object.hasOwn(headers, 'Cookie') && auth != null) { - return apiCall.auth(auth.user.username, auth.user.password); - } - - return apiCall; - }, - getSpaceUrlPrefix(spaceId: string | undefined | null) { return spaceId && spaceId !== 'default' ? `/s/${spaceId}` : ``; }, @@ -139,65 +118,65 @@ export function SvlCasesApiServiceProvider({ getService }: FtrProviderContext) { async createCase( params: CasePostRequest, - expectedHttpCode: number = 200, - auth: { user: User; space: string | null } | null = { user: superUser, space: null }, - headers: Record = {} + roleAuthc: RoleCredentials, + expectedHttpCode: number = 200 ): Promise { - const apiCall = supertest.post(`${CASES_URL}`); - - this.setupAuth({ apiCall, headers, auth }); + const apiCall = supertestWithoutAuth.post(`${CASES_URL}`); const response = await apiCall - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .set(headers) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .send(params) .expect(expectedHttpCode); return response.body; }, - async findCases({ - query = {}, - expectedHttpCode = 200, - auth = { user: superUser, space: null }, - }: { - query?: Record; - expectedHttpCode?: number; - auth?: { user: User; space: string | null }; - }): Promise { - const { body: res } = await supertest - .get(`${this.getSpaceUrlPrefix(auth.space)}${CASES_URL}/_find`) - .auth(auth.user.username, auth.user.password) + async findCases( + { + query = {}, + expectedHttpCode = 200, + space = 'default', + }: { + query?: Record; + expectedHttpCode?: number; + space?: string; + }, + roleAuthc: RoleCredentials + ): Promise { + const { body: res } = await supertestWithoutAuth + .get(`${this.getSpaceUrlPrefix(space)}${CASES_URL}/_find`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .query({ sortOrder: 'asc', ...query }) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') .send() .expect(expectedHttpCode); return res; }, - async getCase({ - caseId, - includeComments = false, - expectedHttpCode = 200, - auth = { user: superUser, space: null }, - }: { - caseId: string; - includeComments?: boolean; - expectedHttpCode?: number; - auth?: { user: User; space: string | null }; - }): Promise { - const { body: theCase } = await supertest + async getCase( + { + caseId, + space = 'default', + includeComments = false, + expectedHttpCode = 200, + }: { + caseId: string; + space?: string; + includeComments?: boolean; + expectedHttpCode?: number; + }, + roleAuthc: RoleCredentials + ): Promise { + const { body: theCase } = await supertestWithoutAuth .get( `${this.getSpaceUrlPrefix( - auth?.space + space )}${CASES_URL}/${caseId}?includeComments=${includeComments}` ) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .auth(auth.user.username, auth.user.password) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .expect(expectedHttpCode); return theCase; diff --git a/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts b/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts index 26f72d754c4d6..3e0f400d35e78 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts @@ -54,7 +54,6 @@ export default function ({ getService }: FtrProviderContext) { let roleAdmin: RoleCredentials; let internalReqHeader: InternalRequestHeader; const supertest = getService('supertest'); - const esClient = getService('es'); const objectRemover = new ObjectRemover(supertest); diff --git a/x-pack/test_serverless/api_integration/test_suites/common/alerting/rules.ts b/x-pack/test_serverless/api_integration/test_suites/common/alerting/rules.ts index 70d8f07cc8b84..5c6120c8bd60f 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/alerting/rules.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/alerting/rules.ts @@ -31,7 +31,7 @@ import { waitForExecutionEventLog, waitForNumRuleRuns, } from './helpers/alerting_wait_for_helpers'; -import { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); @@ -60,14 +60,8 @@ export default function ({ getService }: FtrProviderContext) { }); afterEach(async () => { - await supertest - .delete(`/api/actions/connector/${connectorId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); - await supertest - .delete(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + await supertest.delete(`/api/actions/connector/${connectorId}`).set(internalReqHeader); + await supertest.delete(`/api/alerting/rule/${ruleId}`).set(internalReqHeader); await esClient.deleteByQuery({ index: '.kibana-event-log-*', conflicts: 'proceed', diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/apm_api_integration/common/apm_api_supertest.ts b/x-pack/test_serverless/api_integration/test_suites/observability/apm_api_integration/common/apm_api_supertest.ts index 62db8c2eddda4..1478ba20a007d 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/apm_api_integration/common/apm_api_supertest.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/apm_api_integration/common/apm_api_supertest.ts @@ -14,6 +14,7 @@ import type { import { Config, kbnTestConfig, kibanaTestSuperuserServerless } from '@kbn/test'; import type { APIEndpoint } from '@kbn/apm-plugin/server'; import { formatRequest } from '@kbn/server-route-repository'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../../shared/services'; import { InheritedFtrProviderContext } from '../../../../services'; export function createApmApiClient(st: supertest.Agent) { @@ -21,20 +22,18 @@ export function createApmApiClient(st: supertest.Agent) { options: { type?: 'form-data'; endpoint: TEndpoint; + roleAuthc: RoleCredentials; + internalReqHeader: InternalRequestHeader; } & APIClientRequestParamsOf & { params?: { query?: { _inspect?: boolean } } } ): Promise> => { - const { endpoint, type } = options; + const { endpoint, type, roleAuthc, internalReqHeader } = options; const params = 'params' in options ? (options.params as Record) : {}; const { method, pathname, version } = formatRequest(endpoint, params.path); const url = format({ pathname, query: params?.query }); - const headers: Record = { - 'kbn-xsrf': 'foo', - 'x-elastic-internal-origin': 'foo', - }; - + const headers: Record = { ...internalReqHeader, ...roleAuthc.apiKeyHeader }; if (version) { headers['Elastic-Api-Version'] = version; } diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/apm_api_integration/feature_flags.ts b/x-pack/test_serverless/api_integration/test_suites/observability/apm_api_integration/feature_flags.ts index 279a1e0970b57..9701107994e56 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/apm_api_integration/feature_flags.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/apm_api_integration/feature_flags.ts @@ -6,6 +6,7 @@ */ import expect from 'expect'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; import { APMFtrContextProvider } from './common/services'; import { ApmApiClient } from './common/apm_api_supertest'; @@ -49,7 +50,11 @@ const SAMPLE_SOURCEMAP = { mappings: 'A,AAAB;;ABCDE;', }; -async function uploadSourcemap(apmApiClient: ApmApiClient) { +async function uploadSourcemap( + apmApiClient: ApmApiClient, + roleAuthc: RoleCredentials, + internalReqHeader: InternalRequestHeader +) { const response = await apmApiClient.slsUser({ endpoint: 'POST /api/apm/sourcemaps 2023-10-31', type: 'form-data', @@ -61,14 +66,30 @@ async function uploadSourcemap(apmApiClient: ApmApiClient) { sourcemap: JSON.stringify(SAMPLE_SOURCEMAP), }, }, + roleAuthc, + internalReqHeader, }); return response.body; } export default function ({ getService }: APMFtrContextProvider) { const apmApiClient = getService('apmApiClient'); + const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); describe('apm feature flags', () => { + let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; + + before(async () => { + internalReqHeader = svlCommonApi.getInternalRequestHeader(); + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + }); + + after(async () => { + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + }); + describe('fleet migrations', () => { it('rejects requests to save apm server schema', async () => { try { @@ -81,6 +102,8 @@ export default function ({ getService }: APMFtrContextProvider) { }, }, }, + roleAuthc, + internalReqHeader, }); } catch (err) { expect(err.res.status).toBe(fleetMigrationResponse.statusCode); @@ -92,6 +115,8 @@ export default function ({ getService }: APMFtrContextProvider) { try { await apmApiClient.slsUser({ endpoint: 'GET /internal/apm/fleet/apm_server_schema/unsupported', + roleAuthc, + internalReqHeader, }); } catch (err) { expect(err.res.status).toBe(fleetMigrationResponse.statusCode); @@ -103,6 +128,8 @@ export default function ({ getService }: APMFtrContextProvider) { try { await apmApiClient.slsUser({ endpoint: 'GET /internal/apm/fleet/migration_check', + roleAuthc, + internalReqHeader, }); } catch (err) { expect(err.res.status).toBe(fleetMigrationResponse.statusCode); @@ -116,6 +143,8 @@ export default function ({ getService }: APMFtrContextProvider) { try { await apmApiClient.slsUser({ endpoint: 'GET /api/apm/settings/agent-configuration 2023-10-31', + roleAuthc, + internalReqHeader, }); } catch (err) { expect(err.res.status).toBe(agentConfigurationResponse.statusCode); @@ -127,6 +156,8 @@ export default function ({ getService }: APMFtrContextProvider) { try { await apmApiClient.slsUser({ endpoint: 'GET /api/apm/settings/agent-configuration/view 2023-10-31', + roleAuthc, + internalReqHeader, }); } catch (err) { expect(err.res.status).toBe(agentConfigurationResponse.statusCode); @@ -143,6 +174,8 @@ export default function ({ getService }: APMFtrContextProvider) { service: {}, }, }, + roleAuthc, + internalReqHeader, }); } catch (err) { expect(err.res.status).toBe(agentConfigurationResponse.statusCode); @@ -160,6 +193,8 @@ export default function ({ getService }: APMFtrContextProvider) { settings: { transaction_sample_rate: '0.55' }, }, }, + roleAuthc, + internalReqHeader, }); } catch (err) { expect(err.res.status).toBe(agentConfigurationResponse.statusCode); @@ -177,6 +212,8 @@ export default function ({ getService }: APMFtrContextProvider) { etag: '7312bdcc34999629a3d39df24ed9b2a7553c0c39', }, }, + roleAuthc, + internalReqHeader, }); } catch (err) { expect(err.res.status).toBe(agentConfigurationResponse.statusCode); @@ -190,6 +227,8 @@ export default function ({ getService }: APMFtrContextProvider) { try { await apmApiClient.slsUser({ endpoint: 'GET /api/apm/sourcemaps 2023-10-31', + roleAuthc, + internalReqHeader, }); } catch (err) { expect(err.res.status).toBe(sourceMapsResponse.statusCode); @@ -199,7 +238,7 @@ export default function ({ getService }: APMFtrContextProvider) { it('rejects requests to upload source maps', async () => { try { - await uploadSourcemap(apmApiClient); + await uploadSourcemap(apmApiClient, roleAuthc, internalReqHeader); } catch (err) { expect(err.res.status).toBe(sourceMapsResponse.statusCode); expect(err.res.body).toStrictEqual(sourceMapsResponse); @@ -211,6 +250,8 @@ export default function ({ getService }: APMFtrContextProvider) { await apmApiClient.slsUser({ endpoint: 'DELETE /api/apm/sourcemaps/{id} 2023-10-31', params: { path: { id: 'foo' } }, + roleAuthc, + internalReqHeader, }); } catch (err) { expect(err.res.status).toBe(sourceMapsResponse.statusCode); diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/burn_rate_rule/burn_rate_rule.ts b/x-pack/test_serverless/api_integration/test_suites/observability/burn_rate_rule/burn_rate_rule.ts index d16169aa77f39..1d5dd1de80a9f 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/burn_rate_rule/burn_rate_rule.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/burn_rate_rule/burn_rate_rule.ts @@ -14,7 +14,7 @@ import { cleanup, Dataset, generate, PartialConfig } from '@kbn/data-forge'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { RoleCredentials } from '../../../../shared/services'; +import { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; export default function ({ getService }: FtrProviderContext) { const esClient = getService('es'); @@ -25,7 +25,9 @@ export default function ({ getService }: FtrProviderContext) { const dataViewApi = getService('dataViewApi'); const sloApi = getService('sloApi'); const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; describe('Burn rate rule', () => { const RULE_TYPE_ID = 'slo.rules.burnRate'; @@ -41,6 +43,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + internalReqHeader = svlCommonApi.getInternalRequestHeader(); dataForgeConfig = { schedule: [ { @@ -63,17 +66,12 @@ export default function ({ getService }: FtrProviderContext) { id: DATA_VIEW_ID, title: DATA_VIEW, }); + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); }); after(async () => { - await supertest - .delete(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); - await supertest - .delete(`/api/actions/connector/${actionId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + await supertest.delete(`/api/alerting/rule/${ruleId}`).set(internalReqHeader); + await supertest.delete(`/api/actions/connector/${actionId}`).set(internalReqHeader); await esClient.deleteByQuery({ index: '.kibana-event-log-*', query: { term: { 'rule.id': ruleId } }, @@ -82,10 +80,7 @@ export default function ({ getService }: FtrProviderContext) { await dataViewApi.delete({ id: DATA_VIEW_ID, }); - await supertest - .delete('/api/observability/slos/my-custom-id') - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + await supertest.delete('/api/observability/slos/my-custom-id').set(internalReqHeader); await esDeleteAllIndices([ALERT_ACTION_INDEX, ...dataForgeIndices]); await cleanup({ client: esClient, config: dataForgeConfig, logger }); @@ -100,29 +95,32 @@ export default function ({ getService }: FtrProviderContext) { indexName: ALERT_ACTION_INDEX, }); - await sloApi.create({ - id: 'my-custom-id', - name: 'my custom name', - description: 'my custom description', - indicator: { - type: 'sli.kql.custom', - params: { - index: DATA_VIEW, - good: 'system.cpu.total.norm.pct > 1', - total: 'system.cpu.total.norm.pct: *', - timestampField: '@timestamp', + await sloApi.create( + { + id: 'my-custom-id', + name: 'my custom name', + description: 'my custom description', + indicator: { + type: 'sli.kql.custom', + params: { + index: DATA_VIEW, + good: 'system.cpu.total.norm.pct > 1', + total: 'system.cpu.total.norm.pct: *', + timestampField: '@timestamp', + }, }, + timeWindow: { + duration: '7d', + type: 'rolling', + }, + budgetingMethod: 'occurrences', + objective: { + target: 0.999, + }, + groupBy: '*', }, - timeWindow: { - duration: '7d', - type: 'rolling', - }, - budgetingMethod: 'occurrences', - objective: { - target: 0.999, - }, - groupBy: '*', - }); + roleAuthc + ); const dependencyRule = await alertingApi.createRule({ roleAuthc, diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/find_cases.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/find_cases.ts index c28247b3cea0b..e18c8fd55ba7b 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/cases/find_cases.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/find_cases.ts @@ -5,19 +5,28 @@ * 2.0. */ +import { CasePostRequest } from '@kbn/cases-plugin/common/types/api'; import expect from '@kbn/expect'; +import type { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default ({ getService }: FtrProviderContext): void => { const svlCases = getService('svlCases'); + const svlUserManager = getService('svlUserManager'); let findCasesResp: any; - let postCaseReq: any; + let postCaseReq: CasePostRequest; describe('find_cases', () => { + let roleAuthc: RoleCredentials; before(async () => { findCasesResp = svlCases.api.getFindCasesResp(); postCaseReq = svlCases.api.getPostCaseReq('observability'); + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + }); + + after(async () => { + await svlUserManager.invalidateApiKeyForRole(roleAuthc); }); afterEach(async () => { @@ -25,16 +34,16 @@ export default ({ getService }: FtrProviderContext): void => { }); it('should return empty response', async () => { - const cases = await svlCases.api.findCases({}); + const cases = await svlCases.api.findCases({}, roleAuthc); expect(cases).to.eql(findCasesResp); }); it('should return cases', async () => { - const a = await svlCases.api.createCase(postCaseReq); - const b = await svlCases.api.createCase(postCaseReq); - const c = await svlCases.api.createCase(postCaseReq); + const a = await svlCases.api.createCase(postCaseReq, roleAuthc); + const b = await svlCases.api.createCase(postCaseReq, roleAuthc); + const c = await svlCases.api.createCase(postCaseReq, roleAuthc); - const cases = await svlCases.api.findCases({}); + const cases = await svlCases.api.findCases({}, roleAuthc); expect(cases).to.eql({ ...findCasesResp, @@ -45,14 +54,22 @@ export default ({ getService }: FtrProviderContext): void => { }); it('returns empty response when trying to find cases with owner as cases', async () => { - const cases = await svlCases.api.findCases({ query: { owner: 'cases' } }); + const cases = await svlCases.api.findCases( + { + query: { owner: 'cases' }, + }, + roleAuthc + ); expect(cases).to.eql(findCasesResp); }); it('returns empty response when trying to find cases with owner as securitySolution', async () => { - const cases = await svlCases.api.findCases({ - query: { owner: 'securitySolution' }, - }); + const cases = await svlCases.api.findCases( + { + query: { owner: 'securitySolution' }, + }, + roleAuthc + ); expect(cases).to.eql(findCasesResp); }); }); diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts index 30fbe518085cb..717d02715f3ba 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts @@ -6,28 +6,47 @@ */ import expect from '@kbn/expect'; - +import type { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default ({ getService }: FtrProviderContext): void => { const svlCases = getService('svlCases'); + const svlUserManager = getService('svlUserManager'); describe('get_case', () => { + let roleAuthc: RoleCredentials; + + before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + }); + + after(async () => { + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + }); + afterEach(async () => { await svlCases.api.deleteCases(); }); it('should return a case', async () => { const postedCase = await svlCases.api.createCase( - svlCases.api.getPostCaseRequest('observability') + svlCases.api.getPostCaseRequest('observability'), + roleAuthc ); - const theCase = await svlCases.api.getCase({ - caseId: postedCase.id, - includeComments: true, - }); + const theCase = await svlCases.api.getCase( + { + caseId: postedCase.id, + includeComments: true, + }, + roleAuthc + ); + + const { created_by: createdBy, ...data } = + svlCases.omit.removeServerGeneratedPropertiesFromCase(theCase); + const { created_by: _, ...expectedData } = svlCases.api.postCaseResp('observability'); - const data = svlCases.omit.removeServerGeneratedPropertiesFromCase(theCase); - expect(data).to.eql(svlCases.api.postCaseResp('observability')); + expect(data).to.eql(expectedData); + expect(createdBy).to.have.keys('full_name', 'email', 'username'); expect(data.comments?.length).to.eql(0); }); }); diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts index 79f180a5092ff..ccc1d5f79aee2 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts @@ -7,13 +7,24 @@ import expect from '@kbn/expect'; import { ConnectorTypes } from '@kbn/cases-plugin/common/types/domain'; - +import type { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default ({ getService }: FtrProviderContext): void => { const svlCases = getService('svlCases'); + const svlUserManager = getService('svlUserManager'); describe('post_case', () => { + let roleAuthc: RoleCredentials; + + before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + }); + + after(async () => { + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + }); + afterEach(async () => { await svlCases.api.deleteCases(); }); @@ -29,6 +40,7 @@ export default ({ getService }: FtrProviderContext): void => { fields: { issueType: 'Task', priority: 'High', parent: null }, }, }), + roleAuthc, 200 ) ); @@ -40,6 +52,7 @@ export default ({ getService }: FtrProviderContext): void => { svlCases.api.getPostCaseRequest('observability', { owner: 'securitySolution', }), + roleAuthc, 403 ) ); @@ -51,6 +64,7 @@ export default ({ getService }: FtrProviderContext): void => { svlCases.api.getPostCaseRequest('observability', { owner: 'cases', }), + roleAuthc, 403 ) ); diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts index 4a1e97c83cb27..e0f207ef2ee94 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts @@ -13,10 +13,11 @@ import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import { parseSearchParams } from '@kbn/share-plugin/common/url_service'; import { omit } from 'lodash'; import { COMPARATORS } from '@kbn/alerting-comparators'; +import { kbnTestConfig } from '@kbn/test'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { ISO_DATE_REGEX } from './constants'; import { ActionDocument, LogsExplorerLocatorParsedParams } from './typings'; -import { RoleCredentials } from '../../../../shared/services'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; export default function ({ getService }: FtrProviderContext) { const esClient = getService('es'); @@ -25,8 +26,10 @@ export default function ({ getService }: FtrProviderContext) { const alertingApi = getService('alertingApi'); const dataViewApi = getService('dataViewApi'); const logger = getService('log'); + const svlCommonApi = getService('svlCommonApi'); const svlUserManager = getService('svlUserManager'); let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; describe('Custom Threshold rule - AVG - PCT - FIRED', () => { const CUSTOM_THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default'; @@ -42,6 +45,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + internalReqHeader = svlCommonApi.getInternalRequestHeader(); dataForgeConfig = { schedule: [ { @@ -71,14 +75,8 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await supertest - .delete(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); - await supertest - .delete(`/api/actions/connector/${actionId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + await supertest.delete(`/api/alerting/rule/${ruleId}`).set(internalReqHeader); + await supertest.delete(`/api/actions/connector/${actionId}`).set(internalReqHeader); await esClient.deleteByQuery({ index: CUSTOM_THRESHOLD_RULE_ALERT_INDEX, query: { term: { 'kibana.alert.rule.uuid': ruleId } }, @@ -234,9 +232,10 @@ export default function ({ getService }: FtrProviderContext) { docCountTarget: 1, }); + const { protocol, hostname, port } = kbnTestConfig.getUrlParts(); expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold'); expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql( - `http://localhost:5620/app/observability/alerts/${alertId}` + `${protocol}://${hostname}${port ? `:${port}` : ''}/app/observability/alerts/${alertId}` ); expect(resp.hits.hits[0]._source?.reason).eql( `Average system.cpu.user.pct is 250%, above the threshold of 50%. (duration: 5 mins, data view: ${DATA_VIEW_NAME})` diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_no_data.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_no_data.ts index 333c34f68ab4d..90d6c5f29f799 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_no_data.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_no_data.ts @@ -12,10 +12,11 @@ import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import { parseSearchParams } from '@kbn/share-plugin/common/url_service'; import { omit } from 'lodash'; import { COMPARATORS } from '@kbn/alerting-comparators'; +import { kbnTestConfig } from '@kbn/test'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { ISO_DATE_REGEX } from './constants'; import { ActionDocument, LogsExplorerLocatorParsedParams } from './typings'; -import { RoleCredentials } from '../../../../shared/services'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; export default function ({ getService }: FtrProviderContext) { const esClient = getService('es'); @@ -24,7 +25,9 @@ export default function ({ getService }: FtrProviderContext) { const dataViewApi = getService('dataViewApi'); const esDeleteAllIndices = getService('esDeleteAllIndices'); const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; describe('Custom Threshold rule - AVG - PCT - NoData', () => { const CUSTOM_THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default'; @@ -38,6 +41,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + internalReqHeader = svlCommonApi.getInternalRequestHeader(); await dataViewApi.create({ name: DATA_VIEW_NAME, id: DATA_VIEW_ID, @@ -46,14 +50,8 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await supertest - .delete(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); - await supertest - .delete(`/api/actions/connector/${actionId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + await supertest.delete(`/api/alerting/rule/${ruleId}`).set(internalReqHeader); + await supertest.delete(`/api/actions/connector/${actionId}`).set(internalReqHeader); await esClient.deleteByQuery({ index: CUSTOM_THRESHOLD_RULE_ALERT_INDEX, query: { term: { 'kibana.alert.rule.uuid': ruleId } }, @@ -210,9 +208,10 @@ export default function ({ getService }: FtrProviderContext) { docCountTarget: 1, }); + const { protocol, hostname, port } = kbnTestConfig.getUrlParts(); expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold'); expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql( - `http://localhost:5620/app/observability/alerts/${alertId}` + `${protocol}://${hostname}${port ? `:${port}` : ''}/app/observability/alerts/${alertId}` ); expect(resp.hits.hits[0]._source?.reason).eql( 'Average system.cpu.user.pct reported no data in the last 5m' diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts index 1fc2bab9afa40..53f39bdec4319 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts @@ -17,7 +17,8 @@ import { COMPARATORS } from '@kbn/alerting-comparators'; import { FIRED_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/custom_threshold/constants'; import expect from '@kbn/expect'; import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; -import { RoleCredentials } from '../../../../shared/services'; +import { kbnTestConfig } from '@kbn/test'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { ActionDocument } from './typings'; @@ -29,7 +30,9 @@ export default function ({ getService }: FtrProviderContext) { const alertingApi = getService('alertingApi'); const dataViewApi = getService('dataViewApi'); const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; describe('Custom Threshold rule - CUSTOM_EQ - AVG - BYTES - FIRED', () => { const CUSTOM_THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default'; @@ -44,6 +47,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + internalReqHeader = svlCommonApi.getInternalRequestHeader(); dataForgeConfig = { schedule: [ { @@ -74,14 +78,8 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await supertest - .delete(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); - await supertest - .delete(`/api/actions/connector/${actionId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + await supertest.delete(`/api/alerting/rule/${ruleId}`).set(internalReqHeader); + await supertest.delete(`/api/actions/connector/${actionId}`).set(internalReqHeader); await esClient.deleteByQuery({ index: CUSTOM_THRESHOLD_RULE_ALERT_INDEX, query: { term: { 'kibana.alert.rule.uuid': ruleId } }, @@ -241,9 +239,10 @@ export default function ({ getService }: FtrProviderContext) { docCountTarget: 1, }); + const { protocol, hostname, port } = kbnTestConfig.getUrlParts(); expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold'); expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql( - `http://localhost:5620/app/observability/alerts/${alertId}` + `${protocol}://${hostname}${port ? `:${port}` : ''}/app/observability/alerts/${alertId}` ); expect(resp.hits.hits[0]._source?.reason).eql( `Custom equation is 1 B, above the threshold of 0.9 B. (duration: 1 min, data view: ${DATA_VIEW})` diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts index 84f1d74527fdf..de32e95f1a939 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts @@ -13,10 +13,11 @@ import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import { parseSearchParams } from '@kbn/share-plugin/common/url_service'; import { omit } from 'lodash'; import { COMPARATORS } from '@kbn/alerting-comparators'; +import { kbnTestConfig } from '@kbn/test'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { ISO_DATE_REGEX } from './constants'; import { ActionDocument, LogsExplorerLocatorParsedParams } from './typings'; -import { RoleCredentials } from '../../../../shared/services'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; export default function ({ getService }: FtrProviderContext) { const esClient = getService('es'); @@ -26,7 +27,9 @@ export default function ({ getService }: FtrProviderContext) { const alertingApi = getService('alertingApi'); const dataViewApi = getService('dataViewApi'); const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; describe('Custom Threshold rule - DOCUMENTS_COUNT - FIRED', () => { const CUSTOM_THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default'; @@ -42,6 +45,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + internalReqHeader = svlCommonApi.getInternalRequestHeader(); dataForgeConfig = { schedule: [ { @@ -75,14 +79,8 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await supertest - .delete(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); - await supertest - .delete(`/api/actions/connector/${actionId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + await supertest.delete(`/api/alerting/rule/${ruleId}`).set(internalReqHeader); + await supertest.delete(`/api/actions/connector/${actionId}`).set(internalReqHeader); await esClient.deleteByQuery({ index: CUSTOM_THRESHOLD_RULE_ALERT_INDEX, query: { term: { 'kibana.alert.rule.uuid': ruleId } }, @@ -239,9 +237,11 @@ export default function ({ getService }: FtrProviderContext) { docCountTarget: 1, }); + const { protocol, hostname, port } = kbnTestConfig.getUrlParts(); + expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold'); expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql( - `http://localhost:5620/app/observability/alerts/${alertId}` + `${protocol}://${hostname}${port ? `:${port}` : ''}/app/observability/alerts/${alertId}` ); expect(resp.hits.hits[0]._source?.reason).eql( diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts index 59c9e393df956..7caf393c3dbd3 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts @@ -20,7 +20,7 @@ import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import { COMPARATORS } from '@kbn/alerting-comparators'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { ActionDocument } from './typings'; -import { RoleCredentials } from '../../../../shared/services'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; export default function ({ getService }: FtrProviderContext) { const esClient = getService('es'); @@ -29,9 +29,11 @@ export default function ({ getService }: FtrProviderContext) { const logger = getService('log'); const alertingApi = getService('alertingApi'); const dataViewApi = getService('dataViewApi'); - let alertId: string; const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); + let alertId: string; let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; describe('Custom Threshold rule - GROUP_BY - FIRED', () => { const CUSTOM_THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default'; @@ -45,6 +47,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + internalReqHeader = svlCommonApi.getInternalRequestHeader(); dataForgeConfig = { schedule: [ { @@ -75,14 +78,8 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await supertest - .delete(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); - await supertest - .delete(`/api/actions/connector/${actionId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + await supertest.delete(`/api/alerting/rule/${ruleId}`).set(internalReqHeader); + await supertest.delete(`/api/actions/connector/${actionId}`).set(internalReqHeader); await esClient.deleteByQuery({ index: CUSTOM_THRESHOLD_RULE_ALERT_INDEX, query: { term: { 'kibana.alert.rule.uuid': ruleId } }, @@ -123,7 +120,11 @@ export default function ({ getService }: FtrProviderContext) { timeSize: 1, timeUnit: 'm', metrics: [ - { name: 'A', field: 'system.cpu.total.norm.pct', aggType: Aggregators.AVERAGE }, + { + name: 'A', + field: 'system.cpu.total.norm.pct', + aggType: Aggregators.AVERAGE, + }, ], }, ], @@ -265,7 +266,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold'); expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql( - `${protocol}://${hostname}:${port}/app/observability/alerts/${alertId}` + `${protocol}://${hostname}${port ? `:${port}` : ''}/app/observability/alerts/${alertId}` ); expect(resp.hits.hits[0]._source?.reason).eql( `Average system.cpu.total.norm.pct is 80%, above or equal the threshold of 20%. (duration: 1 min, data view: ${DATA_VIEW}, group: host-0,container-0)` diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/p99_pct_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/p99_pct_fired.ts index aa00aa6a7b0a6..461654677ef13 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/p99_pct_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/p99_pct_fired.ts @@ -13,10 +13,11 @@ import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import { parseSearchParams } from '@kbn/share-plugin/common/url_service'; import { omit } from 'lodash'; import { COMPARATORS } from '@kbn/alerting-comparators'; +import { kbnTestConfig } from '@kbn/test'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { ISO_DATE_REGEX } from './constants'; import { ActionDocument, LogsExplorerLocatorParsedParams } from './typings'; -import { RoleCredentials } from '../../../../shared/services'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; export default function ({ getService }: FtrProviderContext) { const esClient = getService('es'); @@ -25,7 +26,9 @@ export default function ({ getService }: FtrProviderContext) { const alertingApi = getService('alertingApi'); const logger = getService('log'); const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; describe('Custom Threshold rule - P99 - PCT - FIRED', () => { const CUSTOM_THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default'; @@ -52,6 +55,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + internalReqHeader = svlCommonApi.getInternalRequestHeader(); dataForgeConfig = { schedule: [ { @@ -77,14 +81,8 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await supertest - .delete(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); - await supertest - .delete(`/api/actions/connector/${actionId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + await supertest.delete(`/api/alerting/rule/${ruleId}`).set(internalReqHeader); + await supertest.delete(`/api/actions/connector/${actionId}`).set(internalReqHeader); await esClient.deleteByQuery({ index: CUSTOM_THRESHOLD_RULE_ALERT_INDEX, query: { term: { 'kibana.alert.rule.uuid': ruleId } }, @@ -238,9 +236,10 @@ export default function ({ getService }: FtrProviderContext) { docCountTarget: 1, }); + const { protocol, hostname, port } = kbnTestConfig.getUrlParts(); expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold'); expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql( - `http://localhost:5620/app/observability/alerts/${alertId}` + `${protocol}://${hostname}${port ? `:${port}` : ''}/app/observability/alerts/${alertId}` ); expect(resp.hits.hits[0]._source?.reason).eql( `99th percentile of system.cpu.user.pct is 250%, above the threshold of 50%. (duration: 5 mins, data view: ${DATA_VIEW_NAME})` diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/common/dataset_quality_api_supertest.ts b/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/common/dataset_quality_api_supertest.ts index f1d746b49ff06..83aec6feb343d 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/common/dataset_quality_api_supertest.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/common/dataset_quality_api_supertest.ts @@ -11,6 +11,7 @@ import type { APIClientRequestParamsOf, APIReturnType } from '@kbn/dataset-quali import { Config, kbnTestConfig, kibanaTestSuperuserServerless } from '@kbn/test'; import type { APIEndpoint } from '@kbn/dataset-quality-plugin/server/routes'; import { formatRequest } from '@kbn/server-route-repository'; +import { InternalRequestHeader, RoleCredentials } from '../../../../../shared/services'; import { InheritedFtrProviderContext } from '../../../../services'; export function createDatasetQualityApiClient(st: supertest.Agent) { @@ -18,20 +19,18 @@ export function createDatasetQualityApiClient(st: supertest.Agent) { options: { type?: 'form-data'; endpoint: TEndpoint; + roleAuthc: RoleCredentials; + internalReqHeader: InternalRequestHeader; } & APIClientRequestParamsOf & { params?: { query?: { _inspect?: boolean } } } ): Promise> => { - const { endpoint, type } = options; + const { endpoint, type, internalReqHeader, roleAuthc } = options; const params = 'params' in options ? (options.params as Record) : {}; const { method, pathname, version } = formatRequest(endpoint, params.path); const url = format({ pathname, query: params?.query }); - const headers: Record = { - 'kbn-xsrf': 'foo', - 'x-elastic-internal-origin': 'foo', - }; - + const headers: Record = { ...internalReqHeader, ...roleAuthc.apiKeyHeader }; if (version) { headers['Elastic-Api-Version'] = version; } diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_details.ts b/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_details.ts index 1a4db10f140dc..563e3d53afd69 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_details.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_details.ts @@ -7,6 +7,7 @@ import { log, timerange } from '@kbn/apm-synthtrace-client'; import expect from '@kbn/expect'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; import { expectToReject } from './utils'; import { DatasetQualityApiClient, @@ -17,6 +18,8 @@ import { DatasetQualityFtrContextProvider } from './common/services'; export default function ({ getService }: DatasetQualityFtrContextProvider) { const datasetQualityApiClient: DatasetQualityApiClient = getService('datasetQualityApiClient'); const synthtrace = getService('logSynthtraceEsClient'); + const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); const start = '2023-12-11T18:00:00.000Z'; const end = '2023-12-11T18:01:00.000Z'; const type = 'logs'; @@ -25,7 +28,11 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { const serviceName = 'my-service'; const hostName = 'synth-host'; - async function callApi(dataStream: string) { + async function callApi( + dataStream: string, + roleAuthc: RoleCredentials, + internalReqHeader: InternalRequestHeader + ) { return await datasetQualityApiClient.slsUser({ endpoint: 'GET /internal/dataset_quality/data_streams/{dataStream}/details', params: { @@ -37,12 +44,19 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { end, }, }, + roleAuthc, + internalReqHeader, }); } describe('gets the data stream details', () => { + let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; + before(async () => { - await synthtrace.index([ + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + internalReqHeader = svlCommonApi.getInternalRequestHeader(); + return synthtrace.index([ timerange(start, end) .interval('1m') .rate(1) @@ -61,11 +75,14 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { ), ]); }); + after(async () => { + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + }); it('returns error when dataStream param is not provided', async () => { const expectedMessage = 'Data Stream name cannot be empty'; const err = await expectToReject(() => - callApi(encodeURIComponent(' ')) + callApi(encodeURIComponent(' '), roleAuthc, internalReqHeader) ); expect(err.res.status).to.be(400); expect(err.res.body.message.indexOf(expectedMessage)).to.greaterThan(-1); @@ -74,17 +91,17 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { it('returns {} if matching data stream is not available', async () => { const nonExistentDataSet = 'Non-existent'; const nonExistentDataStream = `${type}-${nonExistentDataSet}-${namespace}`; - const resp = await callApi(nonExistentDataStream); + const resp = await callApi(nonExistentDataStream, roleAuthc, internalReqHeader); expect(resp.body).empty(); }); it('returns "sizeBytes" as null in serverless', async () => { - const resp = await callApi(`${type}-${dataset}-${namespace}`); + const resp = await callApi(`${type}-${dataset}-${namespace}`, roleAuthc, internalReqHeader); expect(resp.body.sizeBytes).to.be(null); }); it('returns service.name and host.name correctly', async () => { - const resp = await callApi(`${type}-${dataset}-${namespace}`); + const resp = await callApi(`${type}-${dataset}-${namespace}`, roleAuthc, internalReqHeader); expect(resp.body.services).to.eql({ ['service.name']: [serviceName] }); expect(resp.body.hosts?.['host.name']).to.eql([hostName]); }); diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_settings.ts b/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_settings.ts index a0ea813a83931..5c99f690abf8e 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_settings.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_settings.ts @@ -7,6 +7,7 @@ import { log, timerange } from '@kbn/apm-synthtrace-client'; import expect from '@kbn/expect'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; import { expectToReject, getDataStreamSettingsOfEarliestIndex, rolloverDataStream } from './utils'; import { DatasetQualityApiClient, @@ -17,6 +18,8 @@ import { DatasetQualityFtrContextProvider } from './common/services'; export default function ({ getService }: DatasetQualityFtrContextProvider) { const datasetQualityApiClient: DatasetQualityApiClient = getService('datasetQualityApiClient'); const synthtrace = getService('logSynthtraceEsClient'); + const svlCommonApi = getService('svlCommonApi'); + const svlUserManager = getService('svlUserManager'); const esClient = getService('es'); const start = '2023-12-11T18:00:00.000Z'; const end = '2023-12-11T18:01:00.000Z'; @@ -26,7 +29,11 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { const serviceName = 'my-service'; const hostName = 'synth-host'; - async function callApi(dataStream: string) { + async function callApi( + dataStream: string, + roleAuthc: RoleCredentials, + internalReqHeader: InternalRequestHeader + ) { return await datasetQualityApiClient.slsUser({ endpoint: 'GET /internal/dataset_quality/data_streams/{dataStream}/settings', params: { @@ -34,12 +41,18 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { dataStream, }, }, + roleAuthc, + internalReqHeader, }); } describe('gets the data stream settings', () => { + let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; before(async () => { - await synthtrace.index([ + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + internalReqHeader = svlCommonApi.getInternalRequestHeader(); + return synthtrace.index([ timerange(start, end) .interval('1m') .rate(1) @@ -59,10 +72,14 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { ]); }); + after(async () => { + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + }); + it('returns error when dataStream param is not provided', async () => { const expectedMessage = 'Data Stream name cannot be empty'; const err = await expectToReject(() => - callApi(encodeURIComponent(' ')) + callApi(encodeURIComponent(' '), roleAuthc, internalReqHeader) ); expect(err.res.status).to.be(400); expect(err.res.body.message.indexOf(expectedMessage)).to.greaterThan(-1); @@ -71,7 +88,7 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { it('returns {} if matching data stream is not available', async () => { const nonExistentDataSet = 'Non-existent'; const nonExistentDataStream = `${type}-${nonExistentDataSet}-${namespace}`; - const resp = await callApi(nonExistentDataStream); + const resp = await callApi(nonExistentDataStream, roleAuthc, internalReqHeader); expect(resp.body).empty(); }); @@ -80,7 +97,7 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { esClient, `${type}-${dataset}-${namespace}` ); - const resp = await callApi(`${type}-${dataset}-${namespace}`); + const resp = await callApi(`${type}-${dataset}-${namespace}`, roleAuthc, internalReqHeader); expect(resp.body.createdOn).to.be(Number(dataStreamSettings?.index?.creation_date)); }); @@ -90,7 +107,7 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { esClient, `${type}-${dataset}-${namespace}` ); - const resp = await callApi(`${type}-${dataset}-${namespace}`); + const resp = await callApi(`${type}-${dataset}-${namespace}`, roleAuthc, internalReqHeader); expect(resp.body.createdOn).to.be(Number(dataStreamSettings?.index?.creation_date)); }); diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/es_query_rule/es_query_rule.ts b/x-pack/test_serverless/api_integration/test_suites/observability/es_query_rule/es_query_rule.ts index b473f62c4f108..c7afd2ff5a165 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/es_query_rule/es_query_rule.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/es_query_rule/es_query_rule.ts @@ -38,14 +38,9 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await supertest - .delete(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); - await supertest - .delete(`/api/actions/connector/${actionId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + await supertest.delete(`/api/alerting/rule/${ruleId}`).set(internalReqHeader); + await supertest.delete(`/api/actions/connector/${actionId}`).set(internalReqHeader); + await esClient.deleteByQuery({ index: '.kibana-event-log-*', query: { term: { 'rule.id': ruleId } }, diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts b/x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts index 547d16399bdab..85cd638bdde5b 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts @@ -6,6 +6,7 @@ */ import expect from 'expect'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { expectDefaultElasticsearchOutput, @@ -14,24 +15,35 @@ import { export default function (ctx: FtrProviderContext) { const svlCommonApi = ctx.getService('svlCommonApi'); - const supertest = ctx.getService('supertest'); + const svlUserManager = ctx.getService('svlUserManager'); + const supertestWithoutAuth = ctx.getService('supertestWithoutAuth'); describe('fleet', function () { let defaultFleetServerHostUrl: string = ''; let defaultEsOutputUrl: string = ''; + let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; before(async () => { + internalReqHeader = svlCommonApi.getInternalRequestHeader(); defaultFleetServerHostUrl = await expectDefaultFleetServer(ctx); expect(defaultFleetServerHostUrl).not.toBe(''); defaultEsOutputUrl = await expectDefaultElasticsearchOutput(ctx); expect(defaultEsOutputUrl).not.toBe(''); + + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + }); + + after(async () => { + await svlUserManager.invalidateApiKeyForRole(roleAuthc); }); it('rejects request to create a new fleet server hosts if host url is different from default', async () => { - const { body, status } = await supertest + const { body, status } = await supertestWithoutAuth .post('/api/fleet/fleet_server_hosts') - .set(svlCommonApi.getInternalRequestHeader()) + .set(internalReqHeader) + .set(roleAuthc.apiKeyHeader) .send({ name: 'test', host_urls: ['https://localhost:8221'], @@ -47,9 +59,10 @@ export default function (ctx: FtrProviderContext) { }); it('accepts request to create a new fleet server hosts if host url is same as default', async () => { - const { body, status } = await supertest + const { body, status } = await supertestWithoutAuth .post('/api/fleet/fleet_server_hosts') - .set(svlCommonApi.getInternalRequestHeader()) + .set(internalReqHeader) + .set(roleAuthc.apiKeyHeader) .send({ name: 'Test Fleet server host', host_urls: [defaultFleetServerHostUrl], @@ -65,9 +78,10 @@ export default function (ctx: FtrProviderContext) { }); it('rejects request to create a new elasticsearch output if host is different from default', async () => { - const { body, status } = await supertest + const { body, status } = await supertestWithoutAuth .post('/api/fleet/outputs') - .set(svlCommonApi.getInternalRequestHeader()) + .set(internalReqHeader) + .set(roleAuthc.apiKeyHeader) .send({ name: 'Test output', type: 'elasticsearch', @@ -83,9 +97,10 @@ export default function (ctx: FtrProviderContext) { }); it('accepts request to create a new elasticsearch output if host url is same as default', async () => { - const { body, status } = await supertest + const { body, status } = await supertestWithoutAuth .post('/api/fleet/outputs') - .set(svlCommonApi.getInternalRequestHeader()) + .set(internalReqHeader) + .set(roleAuthc.apiKeyHeader) .send({ name: 'Test output', type: 'elasticsearch', diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/infra/infra.ts b/x-pack/test_serverless/api_integration/test_suites/observability/infra/infra.ts index d6fad63b9751b..78b385ba301e1 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/infra/infra.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/infra/infra.ts @@ -10,8 +10,7 @@ import type { GetInfraMetricsRequestBodyPayload, GetInfraMetricsResponsePayload, } from '@kbn/infra-plugin/common/http_api'; - -import { kbnTestConfig, kibanaTestSuperuserServerless } from '@kbn/test'; +import type { RoleCredentials } from '../../../../shared/services'; import type { FtrProviderContext } from '../../../ftr_provider_context'; import { DATES, ARCHIVE_NAME } from './constants'; @@ -23,67 +22,77 @@ const timeRange = { export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); - const supertest = getService('supertest'); - const username = kbnTestConfig.getUrlParts(kibanaTestSuperuserServerless).username || ''; - const password = kbnTestConfig.getUrlParts(kibanaTestSuperuserServerless).password || ''; + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); const fetchInfraHosts = async ( - body: GetInfraMetricsRequestBodyPayload + body: GetInfraMetricsRequestBodyPayload, + roleAuthc: RoleCredentials ): Promise => { - const response = await supertest + const response = await supertestWithoutAuth .post('/api/metrics/infra') - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .auth(username, password) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .send(body) .expect(200); return response.body; }; describe('API /metrics/infra', () => { + let roleAuthc: RoleCredentials; describe('works', () => { describe('with host asset', () => { - before(async () => esArchiver.load(ARCHIVE_NAME)); - after(async () => esArchiver.unload(ARCHIVE_NAME)); + before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + return esArchiver.load(ARCHIVE_NAME); + }); + after(async () => { + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + return esArchiver.unload(ARCHIVE_NAME); + }); it('received data', async () => { - const infraHosts = await fetchInfraHosts({ - type: 'host', - limit: 100, - metrics: [ - { - type: 'rx', - }, - { - type: 'tx', - }, - { - type: 'memory', - }, - { - type: 'cpu', - }, - { - type: 'diskSpaceUsage', - }, - { - type: 'memoryFree', + const infraHosts = await fetchInfraHosts( + { + type: 'host', + limit: 100, + metrics: [ + { + type: 'rx', + }, + { + type: 'tx', + }, + { + type: 'memory', + }, + { + type: 'cpu', + }, + { + type: 'diskSpaceUsage', + }, + { + type: 'memoryFree', + }, + ], + query: { + bool: { + must: [], + filter: [], + should: [], + must_not: [], + }, }, - ], - query: { - bool: { - must: [], - filter: [], - should: [], - must_not: [], + range: { + from: timeRange.from, + to: timeRange.to, }, + sourceId: 'default', }, - range: { - from: timeRange.from, - to: timeRange.to, - }, - sourceId: 'default', - }); + roleAuthc + ); if (infraHosts) { const { nodes } = infraHosts; diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/infra/metadata.ts b/x-pack/test_serverless/api_integration/test_suites/observability/infra/metadata.ts index 4b21967d6460e..b711674ebb95e 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/infra/metadata.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/infra/metadata.ts @@ -10,7 +10,7 @@ import type { InfraMetadata, InfraMetadataRequest, } from '@kbn/infra-plugin/common/http_api/metadata_api'; -import { kbnTestConfig, kibanaTestSuperuserServerless } from '@kbn/test'; +import type { RoleCredentials } from '../../../../shared/services'; import type { FtrProviderContext } from '../../../ftr_provider_context'; import { DATES, ARCHIVE_NAME } from './constants'; @@ -22,34 +22,45 @@ const timeRange = { export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); - const supertest = getService('supertest'); - const username = kbnTestConfig.getUrlParts(kibanaTestSuperuserServerless).username || ''; - const password = kbnTestConfig.getUrlParts(kibanaTestSuperuserServerless).password || ''; + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); - const fetchMetadata = async (body: InfraMetadataRequest): Promise => { - const response = await supertest + const fetchMetadata = async ( + body: InfraMetadataRequest, + roleAuthc: RoleCredentials + ): Promise => { + const response = await supertestWithoutAuth .post('/api/infra/metadata') - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .auth(username, password) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .send(body) .expect(200); return response.body; }; describe('API /infra/metadata', () => { + let roleAuthc: RoleCredentials; describe('works', () => { describe('Host asset type', () => { - before(async () => esArchiver.load(ARCHIVE_NAME)); - after(async () => esArchiver.unload(ARCHIVE_NAME)); - + before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + await esArchiver.load(ARCHIVE_NAME); + }); + after(async () => { + await esArchiver.unload(ARCHIVE_NAME); + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + }); it('with serverless existing host', async () => { - const metadata = await fetchMetadata({ - sourceId: 'default', - nodeId: 'serverless-host', - nodeType: 'host', - timeRange, - }); + const metadata = await fetchMetadata( + { + sourceId: 'default', + nodeId: 'serverless-host', + nodeType: 'host', + timeRange, + }, + roleAuthc + ); if (metadata) { expect(metadata.features.length).to.be(4); diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/infra/processes.ts b/x-pack/test_serverless/api_integration/test_suites/observability/infra/processes.ts index 14e072fb03897..e6f490ec4bfae 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/infra/processes.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/infra/processes.ts @@ -11,27 +11,33 @@ import { ProcessListAPIResponseRT, } from '@kbn/infra-plugin/common/http_api/host_details/process_list'; import { decodeOrThrow } from '@kbn/infra-plugin/common/runtime_types'; -import { kbnTestConfig, kibanaTestSuperuserServerless } from '@kbn/test'; +import type { RoleCredentials } from '../../../../shared/services'; + import type { FtrProviderContext } from '../../../ftr_provider_context'; import { DATES, ARCHIVE_NAME } from './constants'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); - const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); describe('API /metrics/process_list', () => { - const username = kbnTestConfig.getUrlParts(kibanaTestSuperuserServerless).username || ''; - const password = kbnTestConfig.getUrlParts(kibanaTestSuperuserServerless).password || ''; - - before(async () => esArchiver.load(ARCHIVE_NAME)); - after(async () => esArchiver.unload(ARCHIVE_NAME)); + let roleAuthc: RoleCredentials; + before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + await esArchiver.load(ARCHIVE_NAME); + }); + after(async () => { + await esArchiver.unload(ARCHIVE_NAME); + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + }); it('works', async () => { - const response = await supertest + const response = await supertestWithoutAuth .post('/api/metrics/process_list') - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .auth(username, password) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .send( ProcessListAPIRequestRT.encode({ hostTerm: { diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/infra/snapshot.ts b/x-pack/test_serverless/api_integration/test_suites/observability/infra/snapshot.ts index ff6d5a5a4785e..1b3d5ba899b1e 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/infra/snapshot.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/infra/snapshot.ts @@ -10,48 +10,60 @@ import type { SnapshotNodeResponse, SnapshotRequest, } from '@kbn/infra-plugin/common/http_api/snapshot_api'; -import { kbnTestConfig, kibanaTestSuperuserServerless } from '@kbn/test'; +import type { RoleCredentials } from '../../../../shared/services'; import type { FtrProviderContext } from '../../../ftr_provider_context'; import { DATES, ARCHIVE_NAME } from './constants'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); - const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); + const fetchSnapshot = async ( - body: SnapshotRequest + body: SnapshotRequest, + roleAuthc: RoleCredentials ): Promise => { - const username = kbnTestConfig.getUrlParts(kibanaTestSuperuserServerless).username || ''; - const password = kbnTestConfig.getUrlParts(kibanaTestSuperuserServerless).password || ''; - const response = await supertest + const response = await supertestWithoutAuth .post('/api/metrics/snapshot') - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .auth(username, password) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) .send(body) .expect(200); return response.body; }; describe('API /metrics/snapshot', () => { + let roleAuthc: RoleCredentials; + describe('Snapshot nodes', () => { const { min, max } = DATES.serverlessTestingHost; - before(async () => esArchiver.load(ARCHIVE_NAME)); - after(async () => esArchiver.unload(ARCHIVE_NAME)); + before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + await esArchiver.load(ARCHIVE_NAME); + }); + after(async () => { + await esArchiver.unload(ARCHIVE_NAME); + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + }); it('should work', async () => { - const snapshot = await fetchSnapshot({ - sourceId: 'default', - timerange: { - to: max, - from: min, - interval: '10m', + const snapshot = await fetchSnapshot( + { + sourceId: 'default', + timerange: { + to: max, + from: min, + interval: '10m', + }, + metrics: [{ type: 'cpu' }], + nodeType: 'host', + groupBy: [], + includeTimeseries: false, }, - metrics: [{ type: 'cpu' }], - nodeType: 'host', - groupBy: [], - includeTimeseries: false, - }); + roleAuthc + ); if (!snapshot) { return; diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/slos/create_slo.ts b/x-pack/test_serverless/api_integration/test_suites/observability/slos/create_slo.ts index d8caf935906d0..02ac42ad6e81a 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/slos/create_slo.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/slos/create_slo.ts @@ -15,6 +15,7 @@ import { getSLOSummaryPipelineId, SLO_SUMMARY_TEMP_INDEX_NAME, } from '@kbn/slo-plugin/common/constants'; +import type { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; interface ExpectedTransforms { @@ -50,6 +51,8 @@ export default function ({ getService }: FtrProviderContext) { const sloApi = getService('sloApi'); const kibanaServer = getService('kibanaServer'); const transform = getService('transform'); + const svlUserManager = getService('svlUserManager'); + const svlCommonApi = getService('svlCommonApi'); describe('create_slo', () => { // DATE_VIEW should match the index template: @@ -57,6 +60,7 @@ export default function ({ getService }: FtrProviderContext) { const DATE_VIEW = 'kbn-data-forge-fake_hosts'; const DATA_VIEW_ID = 'data-view-id'; let infraDataIndex: string; + let roleAuthc: RoleCredentials; before(async () => { infraDataIndex = await generate({ @@ -70,6 +74,7 @@ export default function ({ getService }: FtrProviderContext) { title: DATE_VIEW, }); await kibanaServer.savedObjects.cleanStandardList(); + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); }); after(async () => { @@ -78,57 +83,57 @@ export default function ({ getService }: FtrProviderContext) { }); await supertest .delete('/api/observability/slos/my-custom-id1') - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + .set(svlCommonApi.getInternalRequestHeader()); await supertest .delete('/api/observability/slos/my-custom-id2') - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + .set(svlCommonApi.getInternalRequestHeader()); await supertest .delete('/api/observability/slos/my-custom-id3') - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + .set(svlCommonApi.getInternalRequestHeader()); await supertest .delete('/api/observability/slos/my-custom-id4') - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); + .set(svlCommonApi.getInternalRequestHeader()); await esDeleteAllIndices([infraDataIndex]); await cleanup({ esClient, logger }); await kibanaServer.savedObjects.clean({ types: [SO_SLO_TYPE] }); await transform.api.cleanTransformIndices(); + await svlUserManager.invalidateApiKeyForRole(roleAuthc); }); describe('non partition by SLO', () => { const sloId = 'my-custom-id1'; before(async () => { - await sloApi.create({ - id: sloId, - name: 'my custom name', - description: 'my custom description', - indicator: { - type: 'sli.kql.custom', - params: { - index: infraDataIndex, - good: 'system.cpu.total.norm.pct > 1', - total: 'system.cpu.total.norm.pct: *', - timestampField: '@timestamp', + await sloApi.create( + { + id: sloId, + name: 'my custom name', + description: 'my custom description', + indicator: { + type: 'sli.kql.custom', + params: { + index: infraDataIndex, + good: 'system.cpu.total.norm.pct > 1', + total: 'system.cpu.total.norm.pct: *', + timestampField: '@timestamp', + }, }, + timeWindow: { + duration: '7d', + type: 'rolling', + }, + budgetingMethod: 'occurrences', + objective: { + target: 0.999, + }, + groupBy: ALL_VALUE, }, - timeWindow: { - duration: '7d', - type: 'rolling', - }, - budgetingMethod: 'occurrences', - objective: { - target: 0.999, - }, - groupBy: ALL_VALUE, - }); + roleAuthc + ); }); it('saves the SLO definition', async () => { @@ -158,6 +163,7 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .set('x-elastic-internal-origin', 'foo') .set('elastic-api-version', '1') + .set(roleAuthc.apiKeyHeader) .send(); transform.api.assertResponseStatusCode(200, status, body); assertTransformsResponseBody(body, expectedTransforms); @@ -182,7 +188,10 @@ export default function ({ getService }: FtrProviderContext) { }); it('finds the created SLO', async () => { - const createdSlo = await sloApi.waitForSloCreated({ sloId }); + const createdSlo = await sloApi.waitForSloCreated({ + sloId, + roleAuthc, + }); expect(createdSlo.id).to.be(sloId); expect(createdSlo.groupBy).to.be(ALL_VALUE); }); @@ -191,32 +200,38 @@ export default function ({ getService }: FtrProviderContext) { describe('SLO with long description', () => { it('creates an SLO with description over 256 characters', async () => { const sloId = 'my-custom-id2'; - await sloApi.create({ - id: sloId, - name: 'my super long SLO name and description', - description: - 'Lorem Ipsum has been the industry standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. ', - indicator: { - type: 'sli.kql.custom', - params: { - index: infraDataIndex, - good: 'system.cpu.total.norm.pct > 1', - total: 'system.cpu.total.norm.pct: *', - timestampField: '@timestamp', + await sloApi.create( + { + id: sloId, + name: 'my super long SLO name and description', + description: + 'Lorem Ipsum has been the industry standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. ', + indicator: { + type: 'sli.kql.custom', + params: { + index: infraDataIndex, + good: 'system.cpu.total.norm.pct > 1', + total: 'system.cpu.total.norm.pct: *', + timestampField: '@timestamp', + }, }, + timeWindow: { + duration: '7d', + type: 'rolling', + }, + budgetingMethod: 'occurrences', + objective: { + target: 0.999, + }, + groupBy: '*', }, - timeWindow: { - duration: '7d', - type: 'rolling', - }, - budgetingMethod: 'occurrences', - objective: { - target: 0.999, - }, - groupBy: '*', - }); + roleAuthc + ); - const createdSlo = await sloApi.waitForSloCreated({ sloId }); + const createdSlo = await sloApi.waitForSloCreated({ + sloId, + roleAuthc, + }); expect(createdSlo.id).to.be(sloId); }); }); @@ -224,31 +239,37 @@ export default function ({ getService }: FtrProviderContext) { describe('SLO with special characters in the description', () => { it("creates an SLO that has ' character in the description", async () => { const sloId = 'my-custom-id3'; - await sloApi.create({ - id: sloId, - name: 'my SLO with weird characters in the description', - description: - "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.", - indicator: { - type: 'sli.kql.custom', - params: { - index: infraDataIndex, - good: 'system.cpu.total.norm.pct > 1', - total: 'system.cpu.total.norm.pct: *', - timestampField: '@timestamp', + await sloApi.create( + { + id: sloId, + name: 'my SLO with weird characters in the description', + description: + "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.", + indicator: { + type: 'sli.kql.custom', + params: { + index: infraDataIndex, + good: 'system.cpu.total.norm.pct > 1', + total: 'system.cpu.total.norm.pct: *', + timestampField: '@timestamp', + }, }, + timeWindow: { + duration: '7d', + type: 'rolling', + }, + budgetingMethod: 'occurrences', + objective: { + target: 0.999, + }, + groupBy: '*', }, - timeWindow: { - duration: '7d', - type: 'rolling', - }, - budgetingMethod: 'occurrences', - objective: { - target: 0.999, - }, - groupBy: '*', + roleAuthc + ); + const createdSlo = await sloApi.waitForSloCreated({ + sloId, + roleAuthc, }); - const createdSlo = await sloApi.waitForSloCreated({ sloId }); expect(createdSlo.id).to.be(sloId); }); }); @@ -256,30 +277,36 @@ export default function ({ getService }: FtrProviderContext) { describe('partition by SLO', () => { it('creates a partition by SLO', async () => { const sloId = 'my-custom-id4'; - await sloApi.create({ - id: sloId, - name: 'Group by SLO', - description: 'This is a group by SLO.', - indicator: { - type: 'sli.kql.custom', - params: { - index: infraDataIndex, - good: 'system.cpu.total.norm.pct > 1', - total: 'system.cpu.total.norm.pct: *', - timestampField: '@timestamp', + await sloApi.create( + { + id: sloId, + name: 'Group by SLO', + description: 'This is a group by SLO.', + indicator: { + type: 'sli.kql.custom', + params: { + index: infraDataIndex, + good: 'system.cpu.total.norm.pct > 1', + total: 'system.cpu.total.norm.pct: *', + timestampField: '@timestamp', + }, }, + timeWindow: { + duration: '7d', + type: 'rolling', + }, + budgetingMethod: 'occurrences', + objective: { + target: 0.999, + }, + groupBy: 'host.name', }, - timeWindow: { - duration: '7d', - type: 'rolling', - }, - budgetingMethod: 'occurrences', - objective: { - target: 0.999, - }, - groupBy: 'host.name', + roleAuthc + ); + const createdSlo = await sloApi.waitForSloCreated({ + sloId, + roleAuthc, }); - const createdSlo = await sloApi.waitForSloCreated({ sloId }); expect(createdSlo.id).to.be(sloId); expect(createdSlo.groupBy).not.to.be(ALL_VALUE); expect(createdSlo.groupBy).to.be('host.name'); @@ -320,6 +347,7 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .set('x-elastic-internal-origin', 'foo') .set('elastic-api-version', '1') + .set(roleAuthc.apiKeyHeader) .send(); transform.api.assertResponseStatusCode(200, status, body); assertTransformsResponseBody(body, expectedTransforms); diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/slos/delete_slo.ts b/x-pack/test_serverless/api_integration/test_suites/observability/slos/delete_slo.ts index f49cd75a23edc..6546fc585fb3e 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/slos/delete_slo.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/slos/delete_slo.ts @@ -18,9 +18,9 @@ import { SLO_DESTINATION_INDEX_PATTERN, SLO_SUMMARY_DESTINATION_INDEX_PATTERN, } from '@kbn/slo-plugin/common/constants'; -import { ElasticsearchClient } from '@kbn/core/server'; - +import type { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; + export default function ({ getService }: FtrProviderContext) { const esClient = getService('es'); const logger = getService('log'); @@ -31,12 +31,9 @@ export default function ({ getService }: FtrProviderContext) { const esDeleteAllIndices = getService('esDeleteAllIndices'); const dataViewApi = getService('dataViewApi'); + const svlUserManager = getService('svlUserManager'); - const fetchSloSummaryPipeline = async ( - client: ElasticsearchClient, - sloId: string, - sloRevision: number - ) => { + const fetchSloSummaryPipeline = async (sloId: string, sloRevision: number) => { try { return await esClient.ingest.getPipeline({ id: getSLOSummaryPipelineId(sloId, sloRevision), @@ -55,6 +52,7 @@ export default function ({ getService }: FtrProviderContext) { const DATA_VIEW_ID = 'data-view-id'; let infraDataIndex: string; let sloId: string; + let roleAuthc: RoleCredentials; before(async () => { await sloApi.deleteAllSLOs(); @@ -70,6 +68,7 @@ export default function ({ getService }: FtrProviderContext) { title: DATE_VIEW, }); await kibanaServer.savedObjects.cleanStandardList(); + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); }); after(async () => { @@ -79,34 +78,38 @@ export default function ({ getService }: FtrProviderContext) { await sloApi.deleteAllSLOs(); await esDeleteAllIndices([infraDataIndex]); await cleanup({ esClient, logger }); + await svlUserManager.invalidateApiKeyForRole(roleAuthc); }); describe('non partition by SLO', () => { it('deletes the SLO definition, transforms, ingest pipeline and data', async () => { - const createdSlo = await sloApi.create({ - name: 'my custom name', - description: 'my custom description', - indicator: { - type: 'sli.kql.custom', - params: { - index: infraDataIndex, - good: 'system.cpu.total.norm.pct > 1', - total: 'system.cpu.total.norm.pct: *', - timestampField: '@timestamp', + const createdSlo = await sloApi.create( + { + name: 'my custom name', + description: 'my custom description', + indicator: { + type: 'sli.kql.custom', + params: { + index: infraDataIndex, + good: 'system.cpu.total.norm.pct > 1', + total: 'system.cpu.total.norm.pct: *', + timestampField: '@timestamp', + }, }, + timeWindow: { + duration: '7d', + type: 'rolling', + }, + budgetingMethod: 'occurrences', + objective: { + target: 0.999, + }, + groupBy: ALL_VALUE, }, - timeWindow: { - duration: '7d', - type: 'rolling', - }, - budgetingMethod: 'occurrences', - objective: { - target: 0.999, - }, - groupBy: ALL_VALUE, - }); + roleAuthc + ); sloId = createdSlo.id; - await sloApi.waitForSloCreated({ sloId }); + await sloApi.waitForSloCreated({ sloId, roleAuthc }); // Saved Object const savedObject = await kibanaServer.savedObjects.find({ @@ -123,7 +126,7 @@ export default function ({ getService }: FtrProviderContext) { await transform.api.waitForTransformToExist(sloSummaryTransformId); // Ingest pipeline - const pipelineResponse = await fetchSloSummaryPipeline(esClient, sloId, sloRevision); + const pipelineResponse = await fetchSloSummaryPipeline(sloId, sloRevision); expect(pipelineResponse[getSLOSummaryPipelineId(sloId, sloRevision)]).not.to.be(undefined); // RollUp and Summary data @@ -140,7 +143,10 @@ export default function ({ getService }: FtrProviderContext) { expect(sloSummaryData.hits.hits.length > 0).to.be(true); // Delete the SLO - const response = await sloApi.waitForSloToBeDeleted(sloId); + const response = await sloApi.waitForSloToBeDeleted({ + sloId, + roleAuthc, + }); expect(response.status).to.be(204); // Saved object definition diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/slos/fetch_historical_summary.ts b/x-pack/test_serverless/api_integration/test_suites/observability/slos/fetch_historical_summary.ts index 75d8ae3af1f3c..7ce23be8fb4fc 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/slos/fetch_historical_summary.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/slos/fetch_historical_summary.ts @@ -13,22 +13,26 @@ import { import { ALL_VALUE } from '@kbn/slo-schema'; import moment from 'moment'; +import { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const esClient = getService('es'); const esDeleteAllIndices = getService('esDeleteAllIndices'); const sloApi = getService('sloApi'); + const svlUserManager = getService('svlUserManager'); const SLO_ID = 'slo-fake-1'; - // Failing: See https://github.com/elastic/kibana/issues/183748 - describe.skip('fetch historical summary', () => { + describe('fetch historical summary', () => { + let roleAuthc: RoleCredentials; + before(async () => { const now = moment().startOf('minute'); const curr = now.clone().subtract(30, 'days'); const end = now.clone().add(5, 'minutes'); const batchOperations = []; + while (curr.isSameOrBefore(end)) { batchOperations.push([ { index: { _index: SLO_DESTINATION_INDEX_NAME } }, @@ -55,31 +59,36 @@ export default function ({ getService }: FtrProviderContext) { }); await esClient.indices.refresh({ index: SLO_DESTINATION_INDEX_NAME }); + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); }); after(async () => { await esDeleteAllIndices(SLO_DESTINATION_INDEX_PATTERN); + await svlUserManager.invalidateApiKeyForRole(roleAuthc); }); it('computes the historical summary for a rolling occurrences SLO', async () => { - const response = await sloApi.fetchHistoricalSummary({ - list: [ - { - sloId: SLO_ID, - instanceId: ALL_VALUE, - timeWindow: { - duration: '7d', - type: 'rolling', - }, - budgetingMethod: 'occurrences', - objective: { - target: 0.9, + const response = await sloApi.fetchHistoricalSummary( + { + list: [ + { + sloId: SLO_ID, + instanceId: ALL_VALUE, + timeWindow: { + duration: '7d', + type: 'rolling', + }, + budgetingMethod: 'occurrences', + objective: { + target: 0.9, + }, + groupBy: ALL_VALUE, + revision: 1, }, - groupBy: ALL_VALUE, - revision: 1, - }, - ], - }); + ], + }, + roleAuthc + ); expect(response[0].sloId).to.eql(SLO_ID); expect(response[0].instanceId).to.eql(ALL_VALUE); const numberOfBuckets = response[0].data.length; @@ -96,26 +105,29 @@ export default function ({ getService }: FtrProviderContext) { }); it('computes the historical summary for a rolling timeslices SLO', async () => { - const response = await sloApi.fetchHistoricalSummary({ - list: [ - { - sloId: SLO_ID, - instanceId: ALL_VALUE, - timeWindow: { - duration: '7d', - type: 'rolling', - }, - budgetingMethod: 'timeslices', - objective: { - target: 0.9, - timesliceTarget: 0.8, - timesliceWindow: '1m', + const response = await sloApi.fetchHistoricalSummary( + { + list: [ + { + sloId: SLO_ID, + instanceId: ALL_VALUE, + timeWindow: { + duration: '7d', + type: 'rolling', + }, + budgetingMethod: 'timeslices', + objective: { + target: 0.9, + timesliceTarget: 0.8, + timesliceWindow: '1m', + }, + groupBy: ALL_VALUE, + revision: 1, }, - groupBy: ALL_VALUE, - revision: 1, - }, - ], - }); + ], + }, + roleAuthc + ); expect(response[0].sloId).to.eql(SLO_ID); expect(response[0].instanceId).to.eql(ALL_VALUE); const numberOfBuckets = response[0].data.length; diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/snapshot_telemetry.ts b/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/snapshot_telemetry.ts index f0fc2a357156e..d0986e1b6d7ae 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/snapshot_telemetry.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/snapshot_telemetry.ts @@ -12,19 +12,29 @@ import xpackRootTelemetrySchema from '@kbn/telemetry-collection-xpack-plugin/sch import ossPluginsTelemetrySchema from '@kbn/telemetry-plugin/schema/oss_plugins.json'; import xpackPluginsTelemetrySchema from '@kbn/telemetry-collection-xpack-plugin/schema/xpack_plugins.json'; import { assertTelemetryPayload } from '@kbn/telemetry-tools'; +import type { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; import type { UsageStatsPayloadTestFriendly } from '../../../../../test/api_integration/services/usage_api'; export default function ({ getService }: FtrProviderContext) { const usageApi = getService('usageAPI'); + const svlUserManager = getService('svlUserManager'); describe('Snapshot telemetry', function () { let stats: UsageStatsPayloadTestFriendly; + let roleAuthc: RoleCredentials; before(async () => { - const [unencryptedPayload] = await usageApi.getTelemetryStats({ unencrypted: true }); + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + const [unencryptedPayload] = await usageApi.getTelemetryStats( + { unencrypted: true }, + { authHeader: roleAuthc.apiKeyHeader } + ); stats = unencryptedPayload.stats; }); + after(async () => { + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + }); it('should pass the schema validation (ensures BWC with Classic offering)', () => { const root = deepmerge(ossRootTelemetrySchema, xpackRootTelemetrySchema); @@ -39,7 +49,10 @@ export default function ({ getService }: FtrProviderContext) { }); it('includes the serverless info in the body', async () => { - const [unencryptedPayload] = await usageApi.getTelemetryStats({ unencrypted: true }); + const [unencryptedPayload] = await usageApi.getTelemetryStats( + { unencrypted: true }, + { authHeader: roleAuthc.apiKeyHeader } + ); expect( unencryptedPayload.stats.stack_stats.kibana?.plugins?.telemetry?.labels?.serverless diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/telemetry_config.ts b/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/telemetry_config.ts index f773f8143be5f..1d9b29ee48f10 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/telemetry_config.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/telemetry_config.ts @@ -6,15 +6,15 @@ */ import { expect } from 'expect'; +import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default function telemetryConfigTest({ getService }: FtrProviderContext) { const svlCommonApi = getService('svlCommonApi'); - const supertest = getService('supertest'); + const svlUserManager = getService('svlUserManager'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); - // failsOnMKI, see https://github.com/elastic/kibana/issues/180348 describe('/api/telemetry/v2/config API Telemetry config', function () { - this.tags(['failsOnMKI']); const baseConfig = { allowChangingOptInStatus: false, optIn: true, @@ -24,34 +24,49 @@ export default function telemetryConfigTest({ getService }: FtrProviderContext) serverless: 'observability', }, }; + let roleAuthc: RoleCredentials; + let internalReqHeader: InternalRequestHeader; + + before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + internalReqHeader = svlCommonApi.getInternalRequestHeader(); + }); + + after(async () => { + await svlUserManager.invalidateApiKeyForRole(roleAuthc); + }); it('GET should get the default config', async () => { - const { body } = await supertest + const { body } = await supertestWithoutAuth .get('/api/telemetry/v2/config') - .set(svlCommonApi.getCommonRequestHeader()) + .set(internalReqHeader) + .set(roleAuthc.apiKeyHeader) .expect(200); expect(body).toMatchObject(baseConfig); }); - // coreApp.allowDynamicConfigOverrides is disabled it.skip('GET should get updated labels after dynamically updating them', async () => { - await supertest + await supertestWithoutAuth .put('/internal/core/_settings') - .set(svlCommonApi.getInternalRequestHeader()) + .set(internalReqHeader) + .set(roleAuthc.apiKeyHeader) .set('elastic-api-version', '1') .send({ 'telemetry.labels.journeyName': 'my-ftr-test' }) .expect(200, { ok: true }); - await supertest + const response = await supertestWithoutAuth .get('/api/telemetry/v2/config') - .set(svlCommonApi.getCommonRequestHeader()) - .expect(200, { - ...baseConfig, - labels: { - ...baseConfig.labels, - journeyName: 'my-ftr-test', - }, - }); + .set(internalReqHeader) + .set(roleAuthc.apiKeyHeader); + + expect(response.status).toBe(200); + expect(response.body).toEqual({ + ...baseConfig, + labels: expect.objectContaining({ + ...baseConfig.labels, + journeyName: 'my-ftr-test', + }), + }); }); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/find_cases.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/find_cases.ts index ee44874a67fac..a42e3204c11d3 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/cases/find_cases.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/find_cases.ts @@ -6,19 +6,23 @@ */ import expect from '@kbn/expect'; +import { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default ({ getService }: FtrProviderContext): void => { const svlCases = getService('svlCases'); + const svlUserManager = getService('svlUserManager'); let findCasesResp: any; let postCaseReq: any; describe('find_cases', () => { + let roleAuthc: RoleCredentials; describe('basic tests', () => { before(async () => { findCasesResp = svlCases.api.getFindCasesResp(); postCaseReq = svlCases.api.getPostCaseReq('securitySolution'); + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); }); afterEach(async () => { @@ -26,16 +30,16 @@ export default ({ getService }: FtrProviderContext): void => { }); it('should return empty response', async () => { - const cases = await svlCases.api.findCases({}); + const cases = await svlCases.api.findCases({}, roleAuthc); expect(cases).to.eql(findCasesResp); }); it('should return cases', async () => { - const a = await svlCases.api.createCase(postCaseReq); - const b = await svlCases.api.createCase(postCaseReq); - const c = await svlCases.api.createCase(postCaseReq); + const a = await svlCases.api.createCase(postCaseReq, roleAuthc); + const b = await svlCases.api.createCase(postCaseReq, roleAuthc); + const c = await svlCases.api.createCase(postCaseReq, roleAuthc); - const cases = await svlCases.api.findCases({}); + const cases = await svlCases.api.findCases({}, roleAuthc); expect(cases).to.eql({ ...findCasesResp, @@ -46,14 +50,17 @@ export default ({ getService }: FtrProviderContext): void => { }); it('returns empty response when trying to find cases with owner as cases', async () => { - const cases = await svlCases.api.findCases({ query: { owner: 'cases' } }); + const cases = await svlCases.api.findCases({ query: { owner: 'cases' } }, roleAuthc); expect(cases).to.eql(findCasesResp); }); it('returns empty response when trying to find cases with owner as observability', async () => { - const cases = await svlCases.api.findCases({ - query: { owner: 'observability' }, - }); + const cases = await svlCases.api.findCases( + { + query: { owner: 'observability' }, + }, + roleAuthc + ); expect(cases).to.eql(findCasesResp); }); }); diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts index fe3c02a7342a9..a5aaca18dae62 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts @@ -6,27 +6,41 @@ */ import expect from '@kbn/expect'; +import type { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default ({ getService }: FtrProviderContext): void => { const svlCases = getService('svlCases'); + const svlUserManager = getService('svlUserManager'); describe('get_case', () => { + let roleAuthc: RoleCredentials; + before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + }); + afterEach(async () => { await svlCases.api.deleteCases(); }); it('should return a case', async () => { const postedCase = await svlCases.api.createCase( - svlCases.api.getPostCaseRequest('securitySolution') + svlCases.api.getPostCaseRequest('securitySolution'), + roleAuthc + ); + const theCase = await svlCases.api.getCase( + { + caseId: postedCase.id, + includeComments: true, + }, + roleAuthc ); - const theCase = await svlCases.api.getCase({ - caseId: postedCase.id, - includeComments: true, - }); - const data = svlCases.omit.removeServerGeneratedPropertiesFromCase(theCase); - expect(data).to.eql(svlCases.api.postCaseResp('securitySolution')); + const { created_by: createdBy, ...data } = + svlCases.omit.removeServerGeneratedPropertiesFromCase(theCase); + const { created_by: _, ...expectedData } = svlCases.api.postCaseResp('securitySolution'); + expect(data).to.eql(expectedData); + expect(createdBy).to.have.keys('full_name', 'email', 'username'); expect(data.comments?.length).to.eql(0); }); }); diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts index db5967654de85..5b26ab4f3d313 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts @@ -7,44 +7,44 @@ import expect from '@kbn/expect'; import { ConnectorTypes } from '@kbn/cases-plugin/common/types/domain'; - +import type { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default ({ getService }: FtrProviderContext): void => { const svlCases = getService('svlCases'); + const svlUserManager = getService('svlUserManager'); describe('post_case', () => { + let roleAuthc: RoleCredentials; + before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); + }); + afterEach(async () => { await svlCases.api.deleteCases(); }); it('should create a case', async () => { - const postedCase = await svlCases.api.createCase( - svlCases.api.getPostCaseRequest('securitySolution', { - connector: { - id: '123', - name: 'Jira', - type: ConnectorTypes.jira, - fields: { issueType: 'Task', priority: 'High', parent: null }, - }, - }) - ); - const data = svlCases.omit.removeServerGeneratedPropertiesFromCase(postedCase); + const payload = svlCases.api.getPostCaseRequest('securitySolution', { + connector: { + id: '123', + name: 'Jira', + type: ConnectorTypes.jira, + fields: { issueType: 'Task', priority: 'High', parent: null }, + }, + }); + const postedCase = await svlCases.api.createCase(payload, roleAuthc); - expect(data).to.eql( - svlCases.api.postCaseResp( - 'securitySolution', - null, - svlCases.api.getPostCaseRequest('securitySolution', { - connector: { - id: '123', - name: 'Jira', - type: ConnectorTypes.jira, - fields: { issueType: 'Task', priority: 'High', parent: null }, - }, - }) - ) + const { created_by: createdBy, ...data } = + svlCases.omit.removeServerGeneratedPropertiesFromCase(postedCase); + const { created_by: _, ...expected } = svlCases.api.postCaseResp( + 'securitySolution', + null, + payload ); + + expect(data).to.eql(expected); + expect(createdBy).to.have.keys('full_name', 'email', 'username'); }); it('should throw 403 when trying to create a case with observability as owner', async () => { @@ -53,6 +53,7 @@ export default ({ getService }: FtrProviderContext): void => { svlCases.api.getPostCaseRequest('securitySolution', { owner: 'observability', }), + roleAuthc, 403 ) ); @@ -64,6 +65,7 @@ export default ({ getService }: FtrProviderContext): void => { svlCases.api.getPostCaseRequest('securitySolution', { owner: 'cases', }), + roleAuthc, 403 ) ); diff --git a/x-pack/test_serverless/functional/test_suites/observability/screenshot_creation/response_ops_docs/cases/list_view.ts b/x-pack/test_serverless/functional/test_suites/observability/screenshot_creation/response_ops_docs/cases/list_view.ts index e20029f5ebce1..3cfbd7134b792 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/screenshot_creation/response_ops_docs/cases/list_view.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/screenshot_creation/response_ops_docs/cases/list_view.ts @@ -6,6 +6,7 @@ */ import { OBSERVABILITY_OWNER } from '@kbn/cases-plugin/common'; +import type { RoleCredentials } from '../../../../../../shared/services'; import { FtrProviderContext } from '../../../../../ftr_provider_context'; import { navigateToCasesApp } from '../../../../../../shared/lib/cases'; @@ -16,18 +17,22 @@ export default function ({ getPageObject, getPageObjects, getService }: FtrProvi const svlCommonScreenshots = getService('svlCommonScreenshots'); const screenshotDirectories = ['response_ops_docs', 'observability_cases']; const testSubjects = getService('testSubjects'); + const svlUserManager = getService('svlUserManager'); const owner = OBSERVABILITY_OWNER; let caseIdMonitoring: string; describe('list view', function () { + let roleAuthc: RoleCredentials; before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); await svlCases.api.createCase( svlCases.api.getPostCaseRequest(owner, { title: 'Metrics inventory', tags: ['IBM resilient'], description: 'Test.', owner, - }) + }), + roleAuthc ); await svlCases.api.createCase( @@ -36,7 +41,8 @@ export default function ({ getPageObject, getPageObjects, getService }: FtrProvi tags: ['jira'], description: 'Test.', owner, - }) + }), + roleAuthc ); const caseMonitoring = await svlCases.api.createCase( @@ -45,7 +51,8 @@ export default function ({ getPageObject, getPageObjects, getService }: FtrProvi tags: ['swimlane'], description: 'Test.', owner, - }) + }), + roleAuthc ); caseIdMonitoring = caseMonitoring.id; }); diff --git a/x-pack/test_serverless/functional/test_suites/security/screenshot_creation/response_ops_docs/cases/list_view.ts b/x-pack/test_serverless/functional/test_suites/security/screenshot_creation/response_ops_docs/cases/list_view.ts index b7de775a9a7ce..7b9200b3b747b 100644 --- a/x-pack/test_serverless/functional/test_suites/security/screenshot_creation/response_ops_docs/cases/list_view.ts +++ b/x-pack/test_serverless/functional/test_suites/security/screenshot_creation/response_ops_docs/cases/list_view.ts @@ -7,6 +7,7 @@ import { SECURITY_SOLUTION_OWNER } from '@kbn/cases-plugin/common'; import { CaseSeverity } from '@kbn/cases-plugin/common/types/domain'; +import type { RoleCredentials } from '../../../../../../shared/services'; import { FtrProviderContext } from '../../../../../ftr_provider_context'; import { navigateToCasesApp } from '../../../../../../shared/lib/cases'; @@ -17,11 +18,14 @@ export default function ({ getPageObject, getPageObjects, getService }: FtrProvi const svlCommonScreenshots = getService('svlCommonScreenshots'); const screenshotDirectories = ['response_ops_docs', 'security_cases']; const testSubjects = getService('testSubjects'); + const svlUserManager = getService('svlUserManager'); const owner = SECURITY_SOLUTION_OWNER; let caseIdSuspiciousEmail: string; describe('list view', function () { + let roleAuthc: RoleCredentials; before(async () => { + roleAuthc = await svlUserManager.createApiKeyForRole('admin'); await svlCases.api.createCase( svlCases.api.getPostCaseRequest(owner, { title: 'Unusual processes identified', @@ -29,7 +33,8 @@ export default function ({ getPageObject, getPageObjects, getService }: FtrProvi description: 'Test.', owner, severity: CaseSeverity.HIGH, - }) + }), + roleAuthc ); const caseSuspiciousEmail = await svlCases.api.createCase( @@ -38,7 +43,8 @@ export default function ({ getPageObject, getPageObjects, getService }: FtrProvi tags: ['email', 'phishing'], description: 'Several employees have received suspicious emails from an unknown address.', owner, - }) + }), + roleAuthc ); caseIdSuspiciousEmail = caseSuspiciousEmail.id; @@ -49,7 +55,8 @@ export default function ({ getPageObject, getPageObjects, getService }: FtrProvi description: 'Test.', owner, severity: CaseSeverity.MEDIUM, - }) + }), + roleAuthc ); });