From 37bc63c67a54c131488853d507815fa0050c6ac3 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 18 Jan 2022 10:39:34 +0100 Subject: [PATCH 1/9] change getRequestId to no longer generates UUID --- .../src/get_request_id.test.ts | 32 +++++++------------ .../src/get_request_id.ts | 12 ++++--- src/core/server/http/router/request.ts | 22 ++++++------- 3 files changed, 30 insertions(+), 36 deletions(-) diff --git a/packages/kbn-server-http-tools/src/get_request_id.test.ts b/packages/kbn-server-http-tools/src/get_request_id.test.ts index 1b098ed4842d3..6de0e15af86a7 100644 --- a/packages/kbn-server-http-tools/src/get_request_id.test.ts +++ b/packages/kbn-server-http-tools/src/get_request_id.test.ts @@ -8,20 +8,14 @@ import { getRequestId } from './get_request_id'; -jest.mock('uuid', () => ({ - v4: jest.fn().mockReturnValue('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'), -})); - describe('getRequestId', () => { describe('when allowFromAnyIp is true', () => { - it('generates a UUID if no x-opaque-id header is present', () => { + it('returns undefined if no x-opaque-id header is present', () => { const request = { headers: {}, raw: { req: { socket: { remoteAddress: '1.1.1.1' } } }, } as any; - expect(getRequestId(request, { allowFromAnyIp: true, ipAllowlist: [] })).toEqual( - 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' - ); + expect(getRequestId(request, { allowFromAnyIp: true, ipAllowlist: [] })).toBeUndefined(); }); it('uses x-opaque-id header value if present', () => { @@ -39,14 +33,12 @@ describe('getRequestId', () => { describe('when allowFromAnyIp is false', () => { describe('and ipAllowlist is empty', () => { - it('generates a UUID even if x-opaque-id header is present', () => { + it('returns undefined even if x-opaque-id header is present', () => { const request = { headers: { 'x-opaque-id': 'id from header' }, raw: { req: { socket: { remoteAddress: '1.1.1.1' } } }, } as any; - expect(getRequestId(request, { allowFromAnyIp: false, ipAllowlist: [] })).toEqual( - 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' - ); + expect(getRequestId(request, { allowFromAnyIp: false, ipAllowlist: [] })).toBeUndefined(); }); }); @@ -61,24 +53,24 @@ describe('getRequestId', () => { ); }); - it('generates a UUID if request comes from untrusted IP address', () => { + it('does not use x-opaque-id header if request comes from untrusted IP address', () => { const request = { headers: { 'x-opaque-id': 'id from header' }, raw: { req: { socket: { remoteAddress: '5.5.5.5' } } }, } as any; - expect(getRequestId(request, { allowFromAnyIp: false, ipAllowlist: ['1.1.1.1'] })).toEqual( - 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' - ); + expect( + getRequestId(request, { allowFromAnyIp: false, ipAllowlist: ['1.1.1.1'] }) + ).toBeUndefined(); }); - it('generates UUID if request comes from trusted IP address but no x-opaque-id header is present', () => { + it('returns undefined if request comes from trusted IP address but no x-opaque-id header is present', () => { const request = { headers: {}, raw: { req: { socket: { remoteAddress: '1.1.1.1' } } }, } as any; - expect(getRequestId(request, { allowFromAnyIp: false, ipAllowlist: ['1.1.1.1'] })).toEqual( - 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' - ); + expect( + getRequestId(request, { allowFromAnyIp: false, ipAllowlist: ['1.1.1.1'] }) + ).toBeUndefined(); }); }); }); diff --git a/packages/kbn-server-http-tools/src/get_request_id.ts b/packages/kbn-server-http-tools/src/get_request_id.ts index 3af70ecc3a7a3..9adc687f4d28e 100644 --- a/packages/kbn-server-http-tools/src/get_request_id.ts +++ b/packages/kbn-server-http-tools/src/get_request_id.ts @@ -7,16 +7,20 @@ */ import { Request } from '@hapi/hapi'; -import uuid from 'uuid'; +/** + * Return the requestId for this request from its `x-opaque-id` header, + * depending on the `server.requestId` configuration, or undefined + * if the value should not be used. + */ export function getRequestId( request: Request, { allowFromAnyIp, ipAllowlist }: { allowFromAnyIp: boolean; ipAllowlist: string[] } -): string { +): string | undefined { const remoteAddress = request.raw.req.socket?.remoteAddress; return allowFromAnyIp || // socket may be undefined in integration tests that connect via the http listener directly (remoteAddress && ipAllowlist.includes(remoteAddress)) - ? request.headers['x-opaque-id'] ?? uuid.v4() - : uuid.v4(); + ? request.headers['x-opaque-id'] + : undefined; } diff --git a/src/core/server/http/router/request.ts b/src/core/server/http/router/request.ts index e53a30124a420..2b31ea242f357 100644 --- a/src/core/server/http/router/request.ts +++ b/src/core/server/http/router/request.ts @@ -32,7 +32,7 @@ export interface KibanaRouteOptions extends RouteOptionsApp { * @internal */ export interface KibanaRequestState extends RequestApplicationState { - requestId: string; + requestId?: string; requestUuid: string; rewrittenUrl?: URL; traceId?: string; @@ -127,21 +127,19 @@ export class KibanaRequest< const body = routeValidator.getBody(req.payload, 'request body'); return { query, params, body }; } + /** - * A identifier to identify this request. + * The (optional) opaqueId of this request. * - * @remarks - * Depending on the user's configuration, this value may be sourced from the - * incoming request's `X-Opaque-Id` header which is not guaranteed to be unique - * per request. + * @remarks This value is sourced from the incoming request's `X-Opaque-Id` header + * which is not guaranteed to be unique per request. */ - public readonly id: string; + public readonly opaqueId?: string; /** * A UUID to identify this request. * - * @remarks - * This value is NOT sourced from the incoming request's `X-Opaque-Id` header. it - * is always a UUID uniquely identifying the request. + * @remarks This value is NOT sourced from the incoming request's `X-Opaque-Id` header. + * it is always a UUID uniquely identifying the request. */ public readonly uuid: string; /** a WHATWG URL standard object. */ @@ -186,11 +184,11 @@ export class KibanaRequest< // until that time we have to expose all the headers private readonly withoutSecretHeaders: boolean ) { - // The `requestId` and `requestUuid` properties will not be populated for requests that are 'faked' by internal systems that leverage + // The `opaqueId` and `requestUuid` properties will not be populated for requests that are 'faked' by internal systems that leverage // KibanaRequest in conjunction with scoped Elasticsearch and SavedObjectsClient in order to pass credentials. // In these cases, the ids default to a newly generated UUID. const appState = request.app as KibanaRequestState | undefined; - this.id = appState?.requestId ?? uuid.v4(); + this.opaqueId = appState?.requestId; this.uuid = appState?.requestUuid ?? uuid.v4(); this.rewrittenUrl = appState?.rewrittenUrl; From 468efa6452b4c29255324adc26cd4f46936f7b54 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 18 Jan 2022 11:00:34 +0100 Subject: [PATCH 2/9] start fixing stuff and tests --- .../server/elasticsearch/client/cluster_client.ts | 5 +++-- .../execution_context/execution_context_service.ts | 4 ++-- src/core/server/http/http_server.ts | 4 +++- .../server/http/integration_tests/request.test.ts | 2 +- src/core/server/http/router/request.test.ts | 12 ++++++------ 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/core/server/elasticsearch/client/cluster_client.ts b/src/core/server/elasticsearch/client/cluster_client.ts index 1744d7a41841b..e9f37a7bd369e 100644 --- a/src/core/server/elasticsearch/client/cluster_client.ts +++ b/src/core/server/elasticsearch/client/cluster_client.ts @@ -92,12 +92,13 @@ export class ClusterClient implements ICustomClusterClient { let scopedHeaders: Headers; if (isRealRequest(request)) { const requestHeaders = ensureRawRequest(request).headers ?? {}; - const requestIdHeaders = isKibanaRequest(request) ? { 'x-opaque-id': request.id } : {}; + const opaqueIdHeaders = + isKibanaRequest(request) && request.opaqueId ? { 'x-opaque-id': request.opaqueId } : {}; const authHeaders = this.getAuthHeaders(request) ?? {}; scopedHeaders = { ...filterHeaders(requestHeaders, this.config.requestHeadersWhitelist), - ...requestIdHeaders, + ...opaqueIdHeaders, ...authHeaders, }; } else { diff --git a/src/core/server/execution_context/execution_context_service.ts b/src/core/server/execution_context/execution_context_service.ts index 6e2b809e23043..54276e065c3f6 100644 --- a/src/core/server/execution_context/execution_context_service.ts +++ b/src/core/server/execution_context/execution_context_service.ts @@ -79,8 +79,8 @@ export class ExecutionContextService constructor(private readonly coreContext: CoreContext) { this.log = coreContext.logger.get('execution_context'); - this.contextStore = new AsyncLocalStorage(); - this.requestIdStore = new AsyncLocalStorage<{ requestId: string }>(); + this.contextStore = new AsyncLocalStorage(); + this.requestIdStore = new AsyncLocalStorage(); } setup(): InternalExecutionContextSetup { diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 348b5c4af3e58..7a6651c913bc5 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -340,7 +340,9 @@ export class HttpServer { const parentContext = executionContext?.getParentContextFrom(request.headers); if (parentContext) executionContext?.set(parentContext); - executionContext?.setRequestId(requestId); + if (requestId) { + executionContext?.setRequestId(requestId); + } request.app = { ...(request.app ?? {}), diff --git a/src/core/server/http/integration_tests/request.test.ts b/src/core/server/http/integration_tests/request.test.ts index a2560c2c39fad..42a8f170b3327 100644 --- a/src/core/server/http/integration_tests/request.test.ts +++ b/src/core/server/http/integration_tests/request.test.ts @@ -344,7 +344,7 @@ describe('KibanaRequest', () => { const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter('/'); router.get({ path: '/', validate: false }, async (context, req, res) => { - return res.ok({ body: { requestId: req.id } }); + return res.ok({ body: { requestId: req.opaqueId } }); }); await server.start(); diff --git a/src/core/server/http/router/request.test.ts b/src/core/server/http/router/request.test.ts index 800c97550dffc..2c67e34c9434b 100644 --- a/src/core/server/http/router/request.test.ts +++ b/src/core/server/http/router/request.test.ts @@ -16,31 +16,31 @@ import { httpServerMock } from '../http_server.mocks'; import { schema } from '@kbn/config-schema'; describe('KibanaRequest', () => { - describe('id property', () => { + describe('opaqueId property', () => { it('uses the request.app.requestId property if present', () => { const request = httpServerMock.createRawRequest({ app: { requestId: 'fakeId' }, }); const kibanaRequest = KibanaRequest.from(request); - expect(kibanaRequest.id).toEqual('fakeId'); + expect(kibanaRequest.opaqueId).toEqual('fakeId'); }); - it('generates a new UUID if request.app property is not present', () => { + it('is undefined if request.app property is not present', () => { // Undefined app property const request = httpServerMock.createRawRequest({ app: undefined, }); const kibanaRequest = KibanaRequest.from(request); - expect(kibanaRequest.id).toEqual('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'); + expect(kibanaRequest.opaqueId).toBeUndefined(); }); - it('generates a new UUID if request.app.requestId property is not present', () => { + it('is undefined if request.app.requestId property is not present', () => { // Undefined app.requestId property const request = httpServerMock.createRawRequest({ app: {}, }); const kibanaRequest = KibanaRequest.from(request); - expect(kibanaRequest.id).toEqual('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'); + expect(kibanaRequest.opaqueId).toBeUndefined(); }); }); From 9734eb929e66c27972d547948fb743d58b61414e Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 18 Jan 2022 11:03:22 +0100 Subject: [PATCH 3/9] fix plugin test data --- src/plugins/data/server/search/expressions/esaggs.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/data/server/search/expressions/esaggs.test.ts b/src/plugins/data/server/search/expressions/esaggs.test.ts index cc5b81657bc55..e1ddc6da7686e 100644 --- a/src/plugins/data/server/search/expressions/esaggs.test.ts +++ b/src/plugins/data/server/search/expressions/esaggs.test.ts @@ -57,7 +57,7 @@ describe('esaggs expression function - server', () => { jest.clearAllMocks(); mockHandlers = { abortSignal: jest.fn() as unknown as jest.Mocked, - getKibanaRequest: jest.fn().mockReturnValue({ id: 'hi' } as KibanaRequest), + getKibanaRequest: jest.fn().mockReturnValue({ opaqueId: 'hi' } as KibanaRequest), getSearchContext: jest.fn(), getSearchSessionId: jest.fn().mockReturnValue('abc123'), getExecutionContext: jest.fn(), From bc5aa3ddad586bcb9d2d6a30099ec984abe3be70 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 18 Jan 2022 11:12:59 +0100 Subject: [PATCH 4/9] fix audit service access --- x-pack/plugins/security/server/audit/audit_service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security/server/audit/audit_service.ts b/x-pack/plugins/security/server/audit/audit_service.ts index a29ec221b3474..78a96fc2eb140 100644 --- a/x-pack/plugins/security/server/audit/audit_service.ts +++ b/x-pack/plugins/security/server/audit/audit_service.ts @@ -166,7 +166,7 @@ export class AuditService { session_id: sessionId, ...event.kibana, }, - trace: { id: request.id }, + trace: { id: request.opaqueId }, }); }, }); From b288f90b3c929303b3b15433380cf751066c24f0 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 18 Jan 2022 11:26:30 +0100 Subject: [PATCH 5/9] update comment --- src/core/server/execution_context/execution_context_service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/execution_context/execution_context_service.ts b/src/core/server/execution_context/execution_context_service.ts index 54276e065c3f6..de25f53a6d344 100644 --- a/src/core/server/execution_context/execution_context_service.ts +++ b/src/core/server/execution_context/execution_context_service.ts @@ -154,7 +154,7 @@ export class ExecutionContextService private getAsHeader(): string | undefined { if (!this.enabled) return; - // requestId may not be present in the case of FakeRequest + // requestId may not be present if unspecified by the client or in the case of FakeRequest const requestId = this.requestIdStore.getStore()?.requestId ?? 'unknownId'; const executionContext = this.contextStore.getStore()?.toString(); const executionContextStr = executionContext ? `;kibana:${executionContext}` : ''; From 5e9efcfc6a0ce5c59ae99e86eb2c1077623e5590 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Thu, 20 Jan 2022 13:26:35 +0100 Subject: [PATCH 6/9] fix test --- src/plugins/data/server/search/expressions/esaggs.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/data/server/search/expressions/esaggs.test.ts b/src/plugins/data/server/search/expressions/esaggs.test.ts index e1ddc6da7686e..c2aa3247f4b43 100644 --- a/src/plugins/data/server/search/expressions/esaggs.test.ts +++ b/src/plugins/data/server/search/expressions/esaggs.test.ts @@ -81,7 +81,7 @@ describe('esaggs expression function - server', () => { test('calls getStartDependencies with the KibanaRequest', async () => { await definition().fn(null, args, mockHandlers).toPromise(); - expect(getStartDependencies).toHaveBeenCalledWith({ id: 'hi' }); + expect(getStartDependencies).toHaveBeenCalledWith({ opaqueId: 'hi' }); }); test('calls indexPatterns.create with the values provided by the subexpression arg', async () => { From fd2e8a7eb4f8234dbd73f2e336f42be715f0f106 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Thu, 20 Jan 2022 13:29:09 +0100 Subject: [PATCH 7/9] improve tsdoc --- src/core/server/http/router/request.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/server/http/router/request.ts b/src/core/server/http/router/request.ts index 2b31ea242f357..8e4681d5a0e47 100644 --- a/src/core/server/http/router/request.ts +++ b/src/core/server/http/router/request.ts @@ -132,7 +132,8 @@ export class KibanaRequest< * The (optional) opaqueId of this request. * * @remarks This value is sourced from the incoming request's `X-Opaque-Id` header - * which is not guaranteed to be unique per request. + * which is not guaranteed to be unique per request. When present, it should + * contain a userId in any format. */ public readonly opaqueId?: string; /** From 3256a6c5197a7335fbb421249156136f5b33964b Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Thu, 20 Jan 2022 13:44:40 +0100 Subject: [PATCH 8/9] update generated doc --- .../kibana-plugin-core-public.doclinksstart.md | 2 +- ...bana-plugin-core-server.kibanarequest.id.md | 18 ------------------ .../kibana-plugin-core-server.kibanarequest.md | 2 +- ...lugin-core-server.kibanarequest.opaqueid.md | 18 ++++++++++++++++++ src/core/server/server.api.md | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) delete mode 100644 docs/development/core/server/kibana-plugin-core-server.kibanarequest.id.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.kibanarequest.opaqueid.md diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md index 618aef54423bb..3eeb142c2664a 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md @@ -17,5 +17,5 @@ export interface DocLinksStart | --- | --- | --- | | [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) | string | | | [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) | string | | -| [links](./kibana-plugin-core-public.doclinksstart.links.md) | { readonly settings: string; readonly elasticStackGetStarted: string; readonly upgrade: { readonly upgradingElasticStack: string; }; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; readonly customLinks: string; readonly droppedTransactionSpans: string; readonly upgrading: string; readonly metaData: string; }; readonly canvas: { readonly guide: string; }; readonly cloud: { readonly indexManagement: string; }; readonly console: { readonly guide: string; }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; readonly urlDrilldownVariables: string; }; readonly discover: Record<string, string>; readonly filebeat: { readonly base: string; readonly installation: string; readonly configuration: string; readonly elasticsearchOutput: string; readonly elasticsearchModule: string; readonly startup: string; readonly exportedFields: string; readonly suricataModule: string; readonly zeekModule: string; }; readonly auditbeat: { readonly base: string; readonly auditdModule: string; readonly systemModule: string; }; readonly metricbeat: { readonly base: string; readonly configure: string; readonly httpEndpoint: string; readonly install: string; readonly start: string; }; readonly appSearch: { readonly apiRef: string; readonly apiClients: string; readonly apiKeys: string; readonly authentication: string; readonly crawlRules: string; readonly curations: string; readonly duplicateDocuments: string; readonly entryPoints: string; readonly guide: string; readonly indexingDocuments: string; readonly indexingDocumentsSchema: string; readonly logSettings: string; readonly metaEngines: string; readonly precisionTuning: string; readonly relevanceTuning: string; readonly resultSettings: string; readonly searchUI: string; readonly security: string; readonly synonyms: string; readonly webCrawler: string; readonly webCrawlerEventLogs: string; }; readonly enterpriseSearch: { readonly configuration: string; readonly licenseManagement: string; readonly mailService: string; readonly usersAccess: string; }; readonly workplaceSearch: { readonly apiKeys: string; readonly box: string; readonly confluenceCloud: string; readonly confluenceServer: string; readonly customSources: string; readonly customSourcePermissions: string; readonly documentPermissions: string; readonly dropbox: string; readonly externalIdentities: string; readonly gitHub: string; readonly gettingStarted: string; readonly gmail: string; readonly googleDrive: string; readonly indexingSchedule: string; readonly jiraCloud: string; readonly jiraServer: string; readonly oneDrive: string; readonly permissions: string; readonly salesforce: string; readonly security: string; readonly serviceNow: string; readonly sharePoint: string; readonly slack: string; readonly synch: string; readonly zendesk: string; }; readonly heartbeat: { readonly base: string; }; readonly libbeat: { readonly getStarted: string; }; readonly logstash: { readonly base: string; }; readonly functionbeat: { readonly base: string; }; readonly winlogbeat: { readonly base: string; }; readonly aggs: { readonly composite: string; readonly composite\_missing\_bucket: string; readonly date\_histogram: string; readonly date\_range: string; readonly date\_format\_pattern: string; readonly filter: string; readonly filters: string; readonly geohash\_grid: string; readonly histogram: string; readonly ip\_range: string; readonly range: string; readonly significant\_terms: string; readonly terms: string; readonly terms\_doc\_count\_error: string; readonly rare\_terms: string; readonly avg: string; readonly avg\_bucket: string; readonly max\_bucket: string; readonly min\_bucket: string; readonly sum\_bucket: string; readonly cardinality: string; readonly count: string; readonly cumulative\_sum: string; readonly derivative: string; readonly geo\_bounds: string; readonly geo\_centroid: string; readonly max: string; readonly median: string; readonly min: string; readonly moving\_avg: string; readonly percentile\_ranks: string; readonly serial\_diff: string; readonly std\_dev: string; readonly sum: string; readonly top\_hits: string; }; readonly runtimeFields: { readonly overview: string; readonly mapping: string; }; readonly scriptedFields: { readonly scriptFields: string; readonly scriptAggs: string; readonly painless: string; readonly painlessApi: string; readonly painlessLangSpec: string; readonly painlessSyntax: string; readonly painlessWalkthrough: string; readonly luceneExpressions: string; }; readonly search: { readonly sessions: string; readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; }; readonly addData: string; readonly kibana: string; readonly upgradeAssistant: { readonly overview: string; readonly batchReindex: string; readonly remoteReindex: string; }; readonly rollupJobs: string; readonly elasticsearch: Record<string, string>; readonly siem: { readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }; readonly securitySolution: { readonly trustedApps: string; readonly eventFilters: string; }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; readonly luceneQuerySyntax: string; readonly percolate: string; readonly queryDsl: string; }; readonly date: { readonly dateMath: string; readonly dateMathIndexNames: string; }; readonly management: Record<string, string>; readonly ml: Record<string, string>; readonly transforms: Record<string, string>; readonly visualize: Record<string, string>; readonly apis: Readonly<{ bulkIndexAlias: string; byteSizeUnits: string; createAutoFollowPattern: string; createFollower: string; createIndex: string; createSnapshotLifecyclePolicy: string; createRoleMapping: string; createRoleMappingTemplates: string; createRollupJobsRequest: string; createApiKey: string; createPipeline: string; createTransformRequest: string; cronExpressions: string; executeWatchActionModes: string; indexExists: string; openIndex: string; putComponentTemplate: string; painlessExecute: string; painlessExecuteAPIContexts: string; putComponentTemplateMetadata: string; putSnapshotLifecyclePolicy: string; putIndexTemplateV1: string; putWatch: string; simulatePipeline: string; timeUnits: string; updateTransform: string; }>; readonly observability: Readonly<{ guide: string; infrastructureThreshold: string; logsThreshold: string; metricsThreshold: string; monitorStatus: string; monitorUptime: string; tlsCertificate: string; uptimeDurationAnomaly: string; }>; readonly alerting: Record<string, string>; readonly maps: Readonly<{ guide: string; importGeospatialPrivileges: string; gdalTutorial: string; }>; readonly monitoring: Record<string, string>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; elasticsearchSettings: string; elasticsearchEnableSecurity: string; elasticsearchEnableApiKeys: string; indicesPrivileges: string; kibanaTLS: string; kibanaPrivileges: string; mappingRoles: string; mappingRolesFieldRules: string; runAsPrivilege: string; }>; readonly spaces: Readonly<{ kibanaLegacyUrlAliases: string; kibanaDisableLegacyUrlAliasesApi: string; }>; readonly watcher: Record<string, string>; readonly ccs: Record<string, string>; readonly plugins: { azureRepo: string; gcsRepo: string; hdfsRepo: string; s3Repo: string; snapshotRestoreRepos: string; mapperSize: string; }; readonly snapshotRestore: Record<string, string>; readonly ingest: Record<string, string>; readonly fleet: Readonly<{ beatsAgentComparison: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; settings: string; settingsFleetServerHostSettings: string; settingsFleetServerProxySettings: string; troubleshooting: string; elasticAgent: string; datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; installElasticAgentStandalone: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; apiKeysLearnMore: string; onPremRegistry: string; }>; readonly ecs: { readonly guide: string; }; readonly clients: { readonly guide: string; readonly goOverview: string; readonly javaIndex: string; readonly jsIntro: string; readonly netGuide: string; readonly perlGuide: string; readonly phpGuide: string; readonly pythonGuide: string; readonly rubyOverview: string; readonly rustGuide: string; }; readonly endpoints: { readonly troubleshooting: string; }; } | | +| [links](./kibana-plugin-core-public.doclinksstart.links.md) | { readonly settings: string; readonly elasticStackGetStarted: string; readonly upgrade: { readonly upgradingElasticStack: string; }; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; readonly customLinks: string; readonly droppedTransactionSpans: string; readonly upgrading: string; readonly metaData: string; }; readonly canvas: { readonly guide: string; }; readonly cloud: { readonly indexManagement: string; }; readonly console: { readonly guide: string; }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; readonly urlDrilldownVariables: string; }; readonly discover: Record<string, string>; readonly filebeat: { readonly base: string; readonly installation: string; readonly configuration: string; readonly elasticsearchOutput: string; readonly elasticsearchModule: string; readonly startup: string; readonly exportedFields: string; readonly suricataModule: string; readonly zeekModule: string; }; readonly auditbeat: { readonly base: string; readonly auditdModule: string; readonly systemModule: string; }; readonly metricbeat: { readonly base: string; readonly configure: string; readonly httpEndpoint: string; readonly install: string; readonly start: string; }; readonly appSearch: { readonly apiRef: string; readonly apiClients: string; readonly apiKeys: string; readonly authentication: string; readonly crawlRules: string; readonly curations: string; readonly duplicateDocuments: string; readonly entryPoints: string; readonly guide: string; readonly indexingDocuments: string; readonly indexingDocumentsSchema: string; readonly logSettings: string; readonly metaEngines: string; readonly precisionTuning: string; readonly relevanceTuning: string; readonly resultSettings: string; readonly searchUI: string; readonly security: string; readonly synonyms: string; readonly webCrawler: string; readonly webCrawlerEventLogs: string; }; readonly enterpriseSearch: { readonly configuration: string; readonly licenseManagement: string; readonly mailService: string; readonly usersAccess: string; }; readonly workplaceSearch: { readonly apiKeys: string; readonly box: string; readonly confluenceCloud: string; readonly confluenceServer: string; readonly customSources: string; readonly customSourcePermissions: string; readonly documentPermissions: string; readonly dropbox: string; readonly externalIdentities: string; readonly gitHub: string; readonly gettingStarted: string; readonly gmail: string; readonly googleDrive: string; readonly indexingSchedule: string; readonly jiraCloud: string; readonly jiraServer: string; readonly oneDrive: string; readonly permissions: string; readonly salesforce: string; readonly security: string; readonly serviceNow: string; readonly sharePoint: string; readonly slack: string; readonly synch: string; readonly zendesk: string; }; readonly heartbeat: { readonly base: string; }; readonly libbeat: { readonly getStarted: string; }; readonly logstash: { readonly base: string; }; readonly functionbeat: { readonly base: string; }; readonly winlogbeat: { readonly base: string; }; readonly aggs: { readonly composite: string; readonly composite\_missing\_bucket: string; readonly date\_histogram: string; readonly date\_range: string; readonly date\_format\_pattern: string; readonly filter: string; readonly filters: string; readonly geohash\_grid: string; readonly histogram: string; readonly ip\_range: string; readonly range: string; readonly significant\_terms: string; readonly terms: string; readonly terms\_doc\_count\_error: string; readonly rare\_terms: string; readonly avg: string; readonly avg\_bucket: string; readonly max\_bucket: string; readonly min\_bucket: string; readonly sum\_bucket: string; readonly cardinality: string; readonly count: string; readonly cumulative\_sum: string; readonly derivative: string; readonly geo\_bounds: string; readonly geo\_centroid: string; readonly max: string; readonly median: string; readonly min: string; readonly moving\_avg: string; readonly percentile\_ranks: string; readonly serial\_diff: string; readonly std\_dev: string; readonly sum: string; readonly top\_hits: string; }; readonly runtimeFields: { readonly overview: string; readonly mapping: string; }; readonly scriptedFields: { readonly scriptFields: string; readonly scriptAggs: string; readonly painless: string; readonly painlessApi: string; readonly painlessLangSpec: string; readonly painlessSyntax: string; readonly painlessWalkthrough: string; readonly luceneExpressions: string; }; readonly search: { readonly sessions: string; readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; }; readonly addData: string; readonly kibana: { readonly guide: string; readonly autocompleteSuggestions: string; }; readonly upgradeAssistant: { readonly overview: string; readonly batchReindex: string; readonly remoteReindex: string; }; readonly rollupJobs: string; readonly elasticsearch: Record<string, string>; readonly siem: { readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }; readonly securitySolution: { readonly trustedApps: string; readonly eventFilters: string; }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; readonly luceneQuery: string; readonly luceneQuerySyntax: string; readonly percolate: string; readonly queryDsl: string; }; readonly date: { readonly dateMath: string; readonly dateMathIndexNames: string; }; readonly management: Record<string, string>; readonly ml: Record<string, string>; readonly transforms: Record<string, string>; readonly visualize: Record<string, string>; readonly apis: Readonly<{ bulkIndexAlias: string; byteSizeUnits: string; createAutoFollowPattern: string; createFollower: string; createIndex: string; createSnapshotLifecyclePolicy: string; createRoleMapping: string; createRoleMappingTemplates: string; createRollupJobsRequest: string; createApiKey: string; createPipeline: string; createTransformRequest: string; cronExpressions: string; executeWatchActionModes: string; indexExists: string; multiSearch: string; openIndex: string; putComponentTemplate: string; painlessExecute: string; painlessExecuteAPIContexts: string; putComponentTemplateMetadata: string; putSnapshotLifecyclePolicy: string; putIndexTemplateV1: string; putWatch: string; searchPreference: string; simulatePipeline: string; timeUnits: string; unfreezeIndex: string; updateTransform: string; }>; readonly observability: Readonly<{ guide: string; infrastructureThreshold: string; logsThreshold: string; metricsThreshold: string; monitorStatus: string; monitorUptime: string; tlsCertificate: string; uptimeDurationAnomaly: string; }>; readonly alerting: Record<string, string>; readonly maps: Readonly<{ guide: string; importGeospatialPrivileges: string; gdalTutorial: string; }>; readonly monitoring: Record<string, string>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; elasticsearchSettings: string; elasticsearchEnableSecurity: string; elasticsearchEnableApiKeys: string; indicesPrivileges: string; kibanaTLS: string; kibanaPrivileges: string; mappingRoles: string; mappingRolesFieldRules: string; runAsPrivilege: string; }>; readonly spaces: Readonly<{ kibanaLegacyUrlAliases: string; kibanaDisableLegacyUrlAliasesApi: string; }>; readonly watcher: Record<string, string>; readonly ccs: Record<string, string>; readonly plugins: { azureRepo: string; gcsRepo: string; hdfsRepo: string; s3Repo: string; snapshotRestoreRepos: string; mapperSize: string; }; readonly snapshotRestore: Record<string, string>; readonly ingest: Record<string, string>; readonly fleet: Readonly<{ beatsAgentComparison: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; settings: string; settingsFleetServerHostSettings: string; settingsFleetServerProxySettings: string; troubleshooting: string; elasticAgent: string; datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; installElasticAgentStandalone: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; apiKeysLearnMore: string; onPremRegistry: string; }>; readonly ecs: { readonly guide: string; }; readonly clients: { readonly guide: string; readonly goOverview: string; readonly javaIndex: string; readonly jsIntro: string; readonly netGuide: string; readonly perlGuide: string; readonly phpGuide: string; readonly pythonGuide: string; readonly rubyOverview: string; readonly rustGuide: string; }; readonly endpoints: { readonly troubleshooting: string; }; } | | diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.id.md b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.id.md deleted file mode 100644 index 8cad5972cc164..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.id.md +++ /dev/null @@ -1,18 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [KibanaRequest](./kibana-plugin-core-server.kibanarequest.md) > [id](./kibana-plugin-core-server.kibanarequest.id.md) - -## KibanaRequest.id property - -A identifier to identify this request. - -Signature: - -```typescript -readonly id: string; -``` - -## Remarks - -Depending on the user's configuration, this value may be sourced from the incoming request's `X-Opaque-Id` header which is not guaranteed to be unique per request. - diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.md b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.md index f4e2dda2d5499..a3497c640eb2e 100644 --- a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.md +++ b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.md @@ -26,8 +26,8 @@ export declare class KibanaRequestHttpFetchOptions#asSystemRequest option. | +| [opaqueId?](./kibana-plugin-core-server.kibanarequest.opaqueid.md) | | string | (Optional) The (optional) opaqueId of this request. | | [params](./kibana-plugin-core-server.kibanarequest.params.md) | | Params | | | [query](./kibana-plugin-core-server.kibanarequest.query.md) | | Query | | | [rewrittenUrl?](./kibana-plugin-core-server.kibanarequest.rewrittenurl.md) | | URL | (Optional) URL rewritten in onPreRouting request interceptor. | diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.opaqueid.md b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.opaqueid.md new file mode 100644 index 0000000000000..660fc24f3c045 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.opaqueid.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [KibanaRequest](./kibana-plugin-core-server.kibanarequest.md) > [opaqueId](./kibana-plugin-core-server.kibanarequest.opaqueid.md) + +## KibanaRequest.opaqueId property + +The (optional) opaqueId of this request. + +Signature: + +```typescript +readonly opaqueId?: string; +``` + +## Remarks + +This value is sourced from the incoming request's `X-Opaque-Id` header which is not guaranteed to be unique per request. When present, it should contain a userId in any format. + diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 7230d986c1b88..baed2eec68d5e 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1333,8 +1333,8 @@ export class KibanaRequest(req: Request_2, routeSchemas?: RouteValidator | RouteValidatorFullConfig, withoutSecretHeaders?: boolean): KibanaRequest; readonly headers: Headers_2; - readonly id: string; readonly isSystemRequest: boolean; + readonly opaqueId?: string; // (undocumented) readonly params: Params; // (undocumented) From c10bd2da5d0881af2ead0ea759300b047440c14f Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Thu, 20 Jan 2022 16:45:57 +0100 Subject: [PATCH 9/9] fix uuid-base logic in test --- .../saved_objects/routes/integration_tests/import.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/server/saved_objects/routes/integration_tests/import.test.ts b/src/core/server/saved_objects/routes/integration_tests/import.test.ts index d5f994a3e01ea..80612e67c9a11 100644 --- a/src/core/server/saved_objects/routes/integration_tests/import.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/import.test.ts @@ -488,8 +488,7 @@ describe(`POST ${URL}`, () => { const mockUuid = jest.requireMock('uuid'); mockUuid.v4 = jest .fn() - .mockReturnValueOnce('foo') // a uuid.v4() is generated for the request.id - .mockReturnValueOnce('foo') // another uuid.v4() is used for the request.uuid + .mockReturnValueOnce('foo') // a uuid.v4() is used for the request.uuid .mockReturnValueOnce('new-id-1') .mockReturnValueOnce('new-id-2'); savedObjectsClient.bulkGet.mockResolvedValueOnce({ saved_objects: [mockIndexPattern] });