From 79e63cc6544978dce3e74177638ba59b1286742a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20S=C3=A1nchez?= Date: Thu, 19 Aug 2021 19:45:55 +0200 Subject: [PATCH 01/14] [Security solution] [Endpoint] Remove linked policy from trusted apps when removing endpoint integration (#108347) * Remove policy from trusted app when this is removed from fleet * Fleet: run package delete external callbacks when the Agent Policy is deleted --- .../fleet/register_fleet_policy_callbacks.ts | 9 ++- x-pack/plugins/fleet/common/mocks.ts | 13 +++- x-pack/plugins/fleet/server/mocks/index.ts | 5 +- .../server/routes/package_policy/handlers.ts | 1 + .../server/services/agent_policy.test.ts | 35 +++++++++ .../fleet/server/services/agent_policy.ts | 10 ++- .../server/services/package_policy.test.ts | 78 +++++++++++++++++++ .../fleet/server/services/package_policy.ts | 45 ++++++++--- .../plugins/fleet/server/types/extensions.ts | 6 +- .../endpoint/endpoint_app_context_services.ts | 6 ++ .../fleet_integration.test.ts | 72 ++++++++++++++++- .../fleet_integration/fleet_integration.ts | 23 ++++++ .../remove_policy_from_trusted_apps.ts | 61 +++++++++++++++ 13 files changed, 340 insertions(+), 24 deletions(-) create mode 100644 x-pack/plugins/security_solution/server/fleet_integration/handlers/remove_policy_from_trusted_apps.ts diff --git a/x-pack/plugins/apm/server/lib/fleet/register_fleet_policy_callbacks.ts b/x-pack/plugins/apm/server/lib/fleet/register_fleet_policy_callbacks.ts index 428378178afc8..6fcd0433e2e83 100644 --- a/x-pack/plugins/apm/server/lib/fleet/register_fleet_policy_callbacks.ts +++ b/x-pack/plugins/apm/server/lib/fleet/register_fleet_policy_callbacks.ts @@ -7,8 +7,7 @@ import { APMPlugin, APMRouteHandlerResources } from '../..'; import { - ExternalCallback, - PostPackagePolicyDeleteCallback, + PostPackagePolicyCreateCallback, PutPackagePolicyUpdateCallback, } from '../../../../fleet/server'; import { @@ -60,7 +59,9 @@ export async function registerFleetPolicyCallbacks({ }); } -type ExternalCallbackParams = Parameters; +type ExternalCallbackParams = + | Parameters + | Parameters; export type PackagePolicy = NewPackagePolicy | UpdatePackagePolicy; type Context = ExternalCallbackParams[1]; type Request = ExternalCallbackParams[2]; @@ -81,7 +82,7 @@ function registerPackagePolicyExternalCallback({ logger: NonNullable; }) { const callbackFn: - | PostPackagePolicyDeleteCallback + | PostPackagePolicyCreateCallback | PutPackagePolicyUpdateCallback = async ( packagePolicy: PackagePolicy, context: Context, diff --git a/x-pack/plugins/fleet/common/mocks.ts b/x-pack/plugins/fleet/common/mocks.ts index 7ea4be0ee35c6..eb81ea2d6a0ac 100644 --- a/x-pack/plugins/fleet/common/mocks.ts +++ b/x-pack/plugins/fleet/common/mocks.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { NewPackagePolicy, PackagePolicy } from './types'; +import type { NewPackagePolicy, PackagePolicy, DeletePackagePoliciesResponse } from './types'; export const createNewPackagePolicyMock = (): NewPackagePolicy => { return { @@ -45,3 +45,14 @@ export const createPackagePolicyMock = (): PackagePolicy => { ], }; }; + +export const deletePackagePolicyMock = (): DeletePackagePoliciesResponse => { + const newPackagePolicy = createNewPackagePolicyMock(); + return [ + { + id: 'c6d16e42-c32d-4dce-8a88-113cfe276ad1', + success: true, + package: newPackagePolicy.package, + }, + ]; +}; diff --git a/x-pack/plugins/fleet/server/mocks/index.ts b/x-pack/plugins/fleet/server/mocks/index.ts index 9f07dfac9670b..43b455045e72b 100644 --- a/x-pack/plugins/fleet/server/mocks/index.ts +++ b/x-pack/plugins/fleet/server/mocks/index.ts @@ -62,7 +62,7 @@ export const xpackMocks = { createRequestHandlerContext: createCoreRequestHandlerContextMock, }; -export const createPackagePolicyServiceMock = () => { +export const createPackagePolicyServiceMock = (): jest.Mocked => { return { compilePackagePolicyInputs: jest.fn(), buildPackagePolicyFromPackage: jest.fn(), @@ -75,10 +75,11 @@ export const createPackagePolicyServiceMock = () => { listIds: jest.fn(), update: jest.fn(), runExternalCallbacks: jest.fn(), + runDeleteExternalCallbacks: jest.fn(), upgrade: jest.fn(), getUpgradeDryRunDiff: jest.fn(), getUpgradePackagePolicyInfo: jest.fn(), - } as jest.Mocked; + }; }; /** diff --git a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts index b9f0f6c69d4e7..77e7a2c4ede1a 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts @@ -181,6 +181,7 @@ export const deletePackagePolicyHandler: RequestHandler< } catch (error) { const logger = appContextService.getLogger(); logger.error(`An error occurred executing external callback: ${error}`); + logger.error(error); } return response.ok({ body, diff --git a/x-pack/plugins/fleet/server/services/agent_policy.test.ts b/x-pack/plugins/fleet/server/services/agent_policy.test.ts index a020b95ca3302..3267b2b7e2665 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.test.ts @@ -12,6 +12,9 @@ import type { AgentPolicy, NewAgentPolicy, Output } from '../types'; import { agentPolicyService } from './agent_policy'; import { agentPolicyUpdateEventHandler } from './agent_policy_update'; +import { getAgentsByKuery } from './agents'; +import { packagePolicyService } from './package_policy'; + function getSavedObjectMock(agentPolicyAttributes: any) { const mock = savedObjectsClientMock.create(); mock.get.mockImplementation(async (type: string, id: string) => { @@ -63,6 +66,8 @@ jest.mock('./output', () => { }); jest.mock('./agent_policy_update'); +jest.mock('./agents'); +jest.mock('./package_policy'); function getAgentPolicyUpdateMock() { return (agentPolicyUpdateEventHandler as unknown) as jest.Mock< @@ -123,6 +128,36 @@ describe('agent policy', () => { }); }); + describe('delete', () => { + let soClient: ReturnType; + let esClient: ReturnType['asInternalUser']; + + beforeEach(() => { + soClient = getSavedObjectMock({ revision: 1, package_policies: ['package-1'] }); + esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + + (getAgentsByKuery as jest.Mock).mockResolvedValue({ + agents: [], + total: 0, + page: 1, + perPage: 10, + }); + + (packagePolicyService.delete as jest.Mock).mockResolvedValue([ + { + id: 'package-1', + }, + ]); + }); + + it('should run package policy delete external callbacks', async () => { + await agentPolicyService.delete(soClient, esClient, 'mocked'); + expect(packagePolicyService.runDeleteExternalCallbacks).toHaveBeenCalledWith([ + { id: 'package-1' }, + ]); + }); + }); + describe('bumpRevision', () => { it('should call agentPolicyUpdateEventHandler with updated event once', async () => { const soClient = getSavedObjectMock({ diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index d3cccd4c07f3c..8539db05ffb54 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -45,6 +45,7 @@ import type { FleetServerPolicy, Installation, Output, + DeletePackagePoliciesResponse, } from '../../common'; import { AgentPolicyNameExistsError, HostedAgentPolicyRestrictionRelatedError } from '../errors'; import { @@ -616,7 +617,7 @@ class AgentPolicyService { } if (agentPolicy.package_policies && agentPolicy.package_policies.length) { - await packagePolicyService.delete( + const deletedPackagePolicies: DeletePackagePoliciesResponse = await packagePolicyService.delete( soClient, esClient, agentPolicy.package_policies as string[], @@ -624,6 +625,13 @@ class AgentPolicyService { skipUnassignFromAgentPolicies: true, } ); + try { + await packagePolicyService.runDeleteExternalCallbacks(deletedPackagePolicies); + } catch (error) { + const logger = appContextService.getLogger(); + logger.error(`An error occurred executing external callback: ${error}`); + logger.error(error); + } } if (agentPolicy.is_preconfigured) { diff --git a/x-pack/plugins/fleet/server/services/package_policy.test.ts b/x-pack/plugins/fleet/server/services/package_policy.test.ts index 66128c7e6c3e2..204650574e92a 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.test.ts @@ -20,6 +20,12 @@ import type { PutPackagePolicyUpdateCallback, PostPackagePolicyCreateCallback } import { createAppContextStartContractMock, xpackMocks } from '../mocks'; +import type { PostPackagePolicyDeleteCallback } from '../types'; + +import type { DeletePackagePoliciesResponse } from '../../common'; + +import { IngestManagerError } from '../errors'; + import { packagePolicyService } from './package_policy'; import { appContextService } from './app_context'; @@ -815,6 +821,78 @@ describe('Package policy service', () => { }); }); + describe('runDeleteExternalCallbacks', () => { + let callbackOne: jest.MockedFunction; + let callbackTwo: jest.MockedFunction; + let callingOrder: string[]; + let deletedPackagePolicies: DeletePackagePoliciesResponse; + + beforeEach(() => { + appContextService.start(createAppContextStartContractMock()); + callingOrder = []; + deletedPackagePolicies = [ + { id: 'a', success: true }, + { id: 'a', success: true }, + ]; + callbackOne = jest.fn(async (deletedPolicies) => { + callingOrder.push('one'); + }); + callbackTwo = jest.fn(async (deletedPolicies) => { + callingOrder.push('two'); + }); + appContextService.addExternalCallback('postPackagePolicyDelete', callbackOne); + appContextService.addExternalCallback('postPackagePolicyDelete', callbackTwo); + }); + + afterEach(() => { + appContextService.stop(); + }); + + it('should execute external callbacks', async () => { + await packagePolicyService.runDeleteExternalCallbacks(deletedPackagePolicies); + + expect(callbackOne).toHaveBeenCalledWith(deletedPackagePolicies); + expect(callbackTwo).toHaveBeenCalledWith(deletedPackagePolicies); + expect(callingOrder).toEqual(['one', 'two']); + }); + + it("should execute all external callbacks even if one throw's", async () => { + callbackOne.mockImplementation(async (deletedPolicies) => { + callingOrder.push('one'); + throw new Error('foo'); + }); + await expect( + packagePolicyService.runDeleteExternalCallbacks(deletedPackagePolicies) + ).rejects.toThrow(IngestManagerError); + expect(callingOrder).toEqual(['one', 'two']); + }); + + it('should provide an array of errors encountered by running external callbacks', async () => { + let error: IngestManagerError; + const callbackOneError = new Error('foo 1'); + const callbackTwoError = new Error('foo 2'); + + callbackOne.mockImplementation(async (deletedPolicies) => { + callingOrder.push('one'); + throw callbackOneError; + }); + callbackTwo.mockImplementation(async (deletedPolicies) => { + callingOrder.push('two'); + throw callbackTwoError; + }); + + await packagePolicyService.runDeleteExternalCallbacks(deletedPackagePolicies).catch((e) => { + error = e; + }); + + expect(error!.message).toEqual( + '2 encountered while executing package delete external callbacks' + ); + expect(error!.meta).toEqual([callbackOneError, callbackTwoError]); + expect(callingOrder).toEqual(['one', 'two']); + }); + }); + describe('runExternalCallbacks', () => { let context: ReturnType; let request: KibanaRequest; diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index 561cbef952f8d..61152b07f793b 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -428,9 +428,9 @@ class PackagePolicyService { name: packagePolicy.name, success: true, package: { - name: packagePolicy.name, - title: '', - version: packagePolicy.version || '', + name: packagePolicy.package?.name || '', + title: packagePolicy.package?.title || '', + version: packagePolicy.package?.version || '', }, }); } catch (error) { @@ -642,7 +642,9 @@ class PackagePolicyService { public async runExternalCallbacks( externalCallbackType: A, - packagePolicy: NewPackagePolicy | DeletePackagePoliciesResponse, + packagePolicy: A extends 'postPackagePolicyDelete' + ? DeletePackagePoliciesResponse + : NewPackagePolicy, context: RequestHandlerContext, request: KibanaRequest ): Promise; @@ -653,14 +655,7 @@ class PackagePolicyService { request: KibanaRequest ): Promise { if (externalCallbackType === 'postPackagePolicyDelete') { - const externalCallbacks = appContextService.getExternalCallbacks(externalCallbackType); - if (externalCallbacks && externalCallbacks.size > 0) { - for (const callback of externalCallbacks) { - if (Array.isArray(packagePolicy)) { - await callback(packagePolicy, context, request); - } - } - } + return await this.runDeleteExternalCallbacks(packagePolicy as DeletePackagePoliciesResponse); } else { if (!Array.isArray(packagePolicy)) { let newData = packagePolicy; @@ -682,6 +677,32 @@ class PackagePolicyService { } } } + + public async runDeleteExternalCallbacks( + deletedPackagePolicies: DeletePackagePoliciesResponse + ): Promise { + const externalCallbacks = appContextService.getExternalCallbacks('postPackagePolicyDelete'); + const errorsThrown: Error[] = []; + + if (externalCallbacks && externalCallbacks.size > 0) { + for (const callback of externalCallbacks) { + // Failures from an external callback should not prevent other external callbacks from being + // executed. Errors (if any) will be collected and `throw`n after processing the entire set + try { + await callback(deletedPackagePolicies); + } catch (error) { + errorsThrown.push(error); + } + } + + if (errorsThrown.length > 0) { + throw new IngestManagerError( + `${errorsThrown.length} encountered while executing package delete external callbacks`, + errorsThrown + ); + } + } + } } function assignStreamIdToInput(packagePolicyId: string, input: NewPackagePolicyInput) { diff --git a/x-pack/plugins/fleet/server/types/extensions.ts b/x-pack/plugins/fleet/server/types/extensions.ts index bca9cc016f828..a7f4a422cc2ae 100644 --- a/x-pack/plugins/fleet/server/types/extensions.ts +++ b/x-pack/plugins/fleet/server/types/extensions.ts @@ -7,6 +7,8 @@ import type { KibanaRequest, RequestHandlerContext } from 'kibana/server'; +import type { DeepReadonly } from 'utility-types'; + import type { DeletePackagePoliciesResponse, NewPackagePolicy, @@ -14,9 +16,7 @@ import type { } from '../../common'; export type PostPackagePolicyDeleteCallback = ( - deletedPackagePolicies: DeletePackagePoliciesResponse, - context: RequestHandlerContext, - request: KibanaRequest + deletedPackagePolicies: DeepReadonly ) => Promise; export type PostPackagePolicyCreateCallback = ( diff --git a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts index 1a2e1a7c4ee6f..5a47c8a616c00 100644 --- a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts +++ b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts @@ -22,6 +22,7 @@ import { PluginStartContract as AlertsPluginStartContract } from '../../../alert import { getPackagePolicyCreateCallback, getPackagePolicyUpdateCallback, + getPackagePolicyDeleteCallback, } from '../fleet_integration/fleet_integration'; import { ManifestManager } from './services/artifacts'; import { AppClientFactory } from '../client'; @@ -102,6 +103,11 @@ export class EndpointAppContextService { 'packagePolicyUpdate', getPackagePolicyUpdateCallback(dependencies.logger, dependencies.licenseService) ); + + dependencies.registerIngestCallback( + 'postPackagePolicyDelete', + getPackagePolicyDeleteCallback(dependencies.exceptionListsClient, this.experimentalFeatures) + ); } } diff --git a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts index 56c462de54c52..d0bbb3b346ea8 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts @@ -6,7 +6,7 @@ */ import { httpServerMock, loggingSystemMock } from 'src/core/server/mocks'; -import { createNewPackagePolicyMock } from '../../../fleet/common/mocks'; +import { createNewPackagePolicyMock, deletePackagePolicyMock } from '../../../fleet/common/mocks'; import { policyFactory, policyFactoryWithoutPaidFeatures, @@ -14,6 +14,7 @@ import { import { buildManifestManagerMock } from '../endpoint/services/artifacts/manifest_manager/manifest_manager.mock'; import { getPackagePolicyCreateCallback, + getPackagePolicyDeleteCallback, getPackagePolicyUpdateCallback, } from './fleet_integration'; import { KibanaRequest } from 'kibana/server'; @@ -28,6 +29,7 @@ import { EndpointDocGenerator } from '../../common/endpoint/generate_data'; import { ProtectionModes } from '../../common/endpoint/types'; import type { SecuritySolutionRequestHandlerContext } from '../types'; import { getExceptionListClientMock } from '../../../lists/server/services/exception_lists/exception_list_client.mock'; +import { getExceptionListSchemaMock } from '../../../lists/common/schemas/response/exception_list_schema.mock'; import { ExceptionListClient } from '../../../lists/server'; import { InternalArtifactCompleteSchema } from '../endpoint/schemas/artifacts'; import { ManifestManager } from '../endpoint/services/artifacts/manifest_manager'; @@ -35,6 +37,12 @@ import { getMockArtifacts, toArtifactRecords } from '../endpoint/lib/artifacts/m import { Manifest } from '../endpoint/lib/artifacts'; import { NewPackagePolicy } from '../../../fleet/common/types/models'; import { ManifestSchema } from '../../common/endpoint/schema/manifest'; +import { + allowedExperimentalValues, + ExperimentalFeatures, +} from '../../common/experimental_features'; +import { DeletePackagePoliciesResponse } from '../../../fleet/common'; +import { ExceptionListSchema } from '@kbn/securitysolution-io-ts-list-types'; describe('ingest_integration tests ', () => { let endpointAppContextMock: EndpointAppContextServiceStartContract; @@ -282,4 +290,66 @@ describe('ingest_integration tests ', () => { expect(updatedPolicyConfig.inputs[0]!.config!.policy.value).toEqual(mockPolicy); }); }); + + describe('package policy delete callback with trusted apps by policy enabled', () => { + const invokeDeleteCallback = async ( + experimentalFeatures?: ExperimentalFeatures + ): Promise => { + const callback = getPackagePolicyDeleteCallback(exceptionListClient, experimentalFeatures); + await callback(deletePackagePolicyMock()); + }; + + let removedPolicies: DeletePackagePoliciesResponse; + let policyId: string; + let fakeTA: ExceptionListSchema; + + beforeEach(() => { + removedPolicies = deletePackagePolicyMock(); + policyId = removedPolicies[0].id; + fakeTA = { + ...getExceptionListSchemaMock(), + tags: [`policy:${policyId}`], + }; + + exceptionListClient.findExceptionListItem = jest + .fn() + .mockResolvedValueOnce({ data: [fakeTA], total: 1 }); + exceptionListClient.updateExceptionListItem = jest + .fn() + .mockResolvedValueOnce({ ...fakeTA, tags: [] }); + }); + + it('removes policy from trusted app FF enabled', async () => { + await invokeDeleteCallback({ + ...allowedExperimentalValues, + trustedAppsByPolicyEnabled: true, // Needs to be enabled, it needs also a test with this disabled. + }); + + expect(exceptionListClient.findExceptionListItem).toHaveBeenCalledWith({ + filter: `exception-list-agnostic.attributes.tags:"policy:${policyId}"`, + listId: 'endpoint_trusted_apps', + namespaceType: 'agnostic', + page: 1, + perPage: 50, + sortField: undefined, + sortOrder: undefined, + }); + + expect(exceptionListClient.updateExceptionListItem).toHaveBeenCalledWith({ + ...fakeTA, + namespaceType: fakeTA.namespace_type, + osTypes: fakeTA.os_types, + tags: [], + }); + }); + + it("doesn't remove policy from trusted app FF disabled", async () => { + await invokeDeleteCallback({ + ...allowedExperimentalValues, + }); + + expect(exceptionListClient.findExceptionListItem).toHaveBeenCalledTimes(0); + expect(exceptionListClient.updateExceptionListItem).toHaveBeenCalledTimes(0); + }); + }); }); diff --git a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts index 62c7b3719d6a6..09810a6c88c3d 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts @@ -11,9 +11,12 @@ import { PluginStartContract as AlertsStartContract } from '../../../alerting/se import { SecurityPluginStart } from '../../../security/server'; import { PostPackagePolicyCreateCallback, + PostPackagePolicyDeleteCallback, PutPackagePolicyUpdateCallback, } from '../../../fleet/server'; + import { NewPackagePolicy, UpdatePackagePolicy } from '../../../fleet/common'; + import { NewPolicyData, PolicyConfig } from '../../common/endpoint/types'; import { ManifestManager } from '../endpoint/services'; import { AppClientFactory } from '../client'; @@ -22,6 +25,8 @@ import { installPrepackagedRules } from './handlers/install_prepackaged_rules'; import { createPolicyArtifactManifest } from './handlers/create_policy_artifact_manifest'; import { createDefaultPolicy } from './handlers/create_default_policy'; import { validatePolicyAgainstLicense } from './handlers/validate_policy_against_license'; +import { removePolicyFromTrustedApps } from './handlers/remove_policy_from_trusted_apps'; +import { ExperimentalFeatures } from '../../common/experimental_features'; const isEndpointPackagePolicy = ( packagePolicy: T @@ -126,3 +131,21 @@ export const getPackagePolicyUpdateCallback = ( return newPackagePolicy; }; }; + +export const getPackagePolicyDeleteCallback = ( + exceptionsClient: ExceptionListClient | undefined, + experimentalFeatures: ExperimentalFeatures | undefined +): PostPackagePolicyDeleteCallback => { + return async (deletePackagePolicy): Promise => { + if (!exceptionsClient) { + return; + } + const policiesToRemove: Array> = []; + for (const policy of deletePackagePolicy) { + if (isEndpointPackagePolicy(policy) && experimentalFeatures?.trustedAppsByPolicyEnabled) { + policiesToRemove.push(removePolicyFromTrustedApps(exceptionsClient, policy)); + } + } + await Promise.all(policiesToRemove); + }; +}; diff --git a/x-pack/plugins/security_solution/server/fleet_integration/handlers/remove_policy_from_trusted_apps.ts b/x-pack/plugins/security_solution/server/fleet_integration/handlers/remove_policy_from_trusted_apps.ts new file mode 100644 index 0000000000000..88af71508f33a --- /dev/null +++ b/x-pack/plugins/security_solution/server/fleet_integration/handlers/remove_policy_from_trusted_apps.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '@kbn/securitysolution-list-constants'; +import { ExceptionListClient } from '../../../../lists/server'; +import { PostPackagePolicyDeleteCallback } from '../../../../fleet/server'; + +/** + * Removes policy from trusted apps + */ +export const removePolicyFromTrustedApps = async ( + exceptionsClient: ExceptionListClient, + policy: Parameters[0][0] +) => { + let page = 1; + + const findTrustedAppsByPolicy = async (currentPage: number) => { + return exceptionsClient.findExceptionListItem({ + listId: ENDPOINT_TRUSTED_APPS_LIST_ID, + filter: `exception-list-agnostic.attributes.tags:"policy:${policy.id}"`, + namespaceType: 'agnostic', + page: currentPage, + perPage: 50, + sortField: undefined, + sortOrder: undefined, + }); + }; + + let findResponse = await findTrustedAppsByPolicy(page); + if (!findResponse) { + return; + } + const trustedApps = findResponse.data; + + while (findResponse && (trustedApps.length < findResponse.total || findResponse.data.length)) { + page += 1; + findResponse = await findTrustedAppsByPolicy(page); + if (findResponse) { + trustedApps.push(...findResponse.data); + } + } + + const updates = []; + for (const trustedApp of trustedApps) { + updates.push( + exceptionsClient.updateExceptionListItem({ + ...trustedApp, + itemId: trustedApp.item_id, + namespaceType: trustedApp.namespace_type, + osTypes: trustedApp.os_types, + tags: trustedApp.tags.filter((currentPolicy) => currentPolicy !== `policy:${policy.id}`), + }) + ); + } + + await Promise.all(updates); +}; From a7fe773bb81544f47d7138c9c9606ec412cd8d95 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 19 Aug 2021 19:13:33 +0100 Subject: [PATCH 02/14] chore(NA): moving @kbn/plugin-helpers to babel transpiler (#109085) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-plugin-helpers/.babelrc | 3 +++ packages/kbn-plugin-helpers/BUILD.bazel | 25 +++++++++++++++++------ packages/kbn-plugin-helpers/package.json | 4 ++-- packages/kbn-plugin-helpers/tsconfig.json | 5 +++-- 4 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 packages/kbn-plugin-helpers/.babelrc diff --git a/packages/kbn-plugin-helpers/.babelrc b/packages/kbn-plugin-helpers/.babelrc new file mode 100644 index 0000000000000..7da72d1779128 --- /dev/null +++ b/packages/kbn-plugin-helpers/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["@kbn/babel-preset/node_preset"] +} diff --git a/packages/kbn-plugin-helpers/BUILD.bazel b/packages/kbn-plugin-helpers/BUILD.bazel index 9242701770a86..d7744aecac26e 100644 --- a/packages/kbn-plugin-helpers/BUILD.bazel +++ b/packages/kbn-plugin-helpers/BUILD.bazel @@ -1,6 +1,7 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") +load("//src/dev/bazel:index.bzl", "jsts_transpiler") PKG_BASE_NAME = "kbn-plugin-helpers" PKG_REQUIRE_NAME = "@kbn/plugin-helpers" @@ -26,7 +27,7 @@ NPM_MODULE_EXTRA_FILES = [ "README.md" ] -SRC_DEPS = [ +RUNTIME_DEPS = [ "//packages/kbn-dev-utils", "//packages/kbn-optimizer", "//packages/kbn-utils", @@ -41,6 +42,13 @@ SRC_DEPS = [ ] TYPES_DEPS = [ + "//packages/kbn-dev-utils", + "//packages/kbn-optimizer", + "//packages/kbn-utils", + "@npm//del", + "@npm//execa", + "@npm//globby", + "@npm//load-json-file", "@npm//@types/extract-zip", "@npm//@types/gulp-zip", "@npm//@types/inquirer", @@ -49,7 +57,11 @@ TYPES_DEPS = [ "@npm//@types/vinyl-fs", ] -DEPS = SRC_DEPS + TYPES_DEPS +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) ts_config( name = "tsconfig", @@ -61,13 +73,14 @@ ts_config( ) ts_project( - name = "tsc", + name = "tsc_types", args = ['--pretty'], srcs = SRCS, - deps = DEPS, + deps = TYPES_DEPS, declaration = True, declaration_map = True, - out_dir = "target", + emit_declaration_only = True, + out_dir = "target_types", source_map = True, root_dir = "src", tsconfig = ":tsconfig", @@ -76,7 +89,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = DEPS + [":tsc"], + deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/kbn-plugin-helpers/package.json b/packages/kbn-plugin-helpers/package.json index 1f4df52a03304..21ed8f46f52fa 100644 --- a/packages/kbn-plugin-helpers/package.json +++ b/packages/kbn-plugin-helpers/package.json @@ -7,8 +7,8 @@ "kibana": { "devOnly": true }, - "main": "target/index.js", - "types": "target/index.d.ts", + "main": "target_node/index.js", + "types": "target_types/index.d.ts", "bin": { "plugin-helpers": "bin/plugin-helpers.js" } diff --git a/packages/kbn-plugin-helpers/tsconfig.json b/packages/kbn-plugin-helpers/tsconfig.json index 22adf020187ba..34f3ec5e67503 100644 --- a/packages/kbn-plugin-helpers/tsconfig.json +++ b/packages/kbn-plugin-helpers/tsconfig.json @@ -1,12 +1,13 @@ { "extends": "../../tsconfig.bazel.json", "compilerOptions": { - "outDir": "target", - "target": "ES2018", "declaration": true, "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", "sourceMap": true, "sourceRoot": "../../../../packages/kbn-plugin-helpers/src", + "target": "ES2018", "types": [ "jest", "node" From 91910dbecd195ec2be865b822cc73b094f01d519 Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Thu, 19 Aug 2021 20:14:02 +0200 Subject: [PATCH 03/14] Bringing cypress tests back (#109129) * fixes threshold cypress tests * add ticket command * fixes threshold cypress tests * add ticket command * fixes 'Creates a new case with timeline and opens the timeline' test * unskips navigation tests * removes 'sets correct classes when the user starts dragging a host, but is not hovering over the data providers' test since we are not supporting drag and drop on timeline * removes drag and drop related tests from 'data_providers.spec.ts' * modifies todo on skipped exceptions tests to add more clarity * fixes 'attach' to case and local storage test Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../integration/cases/creation.spec.ts | 8 +-- .../detection_alerts/attach_to_case.spec.ts | 7 ++- .../detection_rules/threshold_rule.spec.ts | 3 +- .../integration/exceptions/from_alert.spec.ts | 2 +- .../integration/exceptions/from_rule.spec.ts | 2 +- .../integration/header/navigation.spec.ts | 4 +- .../timelines/data_providers.spec.ts | 50 +------------------ .../timelines/flyout_button.spec.ts | 13 +---- .../timelines/local_storage.spec.ts | 12 +++-- .../cypress/screens/hosts/all_hosts.ts | 2 - .../cypress/screens/hosts/external_events.ts | 8 --- .../cypress/screens/timeline.ts | 9 +--- .../cypress/tasks/create_new_rule.ts | 4 +- .../cypress/tasks/hosts/all_hosts.ts | 46 +---------------- .../cypress/tasks/timeline.ts | 17 ++++--- 15 files changed, 34 insertions(+), 153 deletions(-) delete mode 100644 x-pack/plugins/security_solution/cypress/screens/hosts/external_events.ts diff --git a/x-pack/plugins/security_solution/cypress/integration/cases/creation.spec.ts b/x-pack/plugins/security_solution/cypress/integration/cases/creation.spec.ts index 9e3b775156cab..028439ce6c3a4 100644 --- a/x-pack/plugins/security_solution/cypress/integration/cases/creation.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/cases/creation.spec.ts @@ -11,7 +11,6 @@ import { ALL_CASES_CLOSED_CASES_STATS, ALL_CASES_COMMENTS_COUNT, ALL_CASES_IN_PROGRESS_CASES_STATS, - ALL_CASES_ITEM_ACTIONS_BTN, ALL_CASES_NAME, ALL_CASES_OPEN_CASES_COUNT, ALL_CASES_OPEN_CASES_STATS, @@ -26,7 +25,6 @@ import { import { CASE_DETAILS_DESCRIPTION, CASE_DETAILS_PAGE_TITLE, - // CASE_DETAILS_PUSH_TO_EXTERNAL_SERVICE_BTN, CASE_DETAILS_STATUS, CASE_DETAILS_TAGS, CASE_DETAILS_USER_ACTION_DESCRIPTION_USERNAME, @@ -67,8 +65,8 @@ describe('Cases', () => { .as('mycase') ); }); - // TODO: enable once attach timeline to cases is re-enabled - it.skip('Creates a new case with timeline and opens the timeline', function () { + + it('Creates a new case with timeline and opens the timeline', function () { loginAndWaitForPageWithoutDateRange(CASES_URL); goToCreateNewCase(); fillCasesMandatoryfields(this.mycase); @@ -92,7 +90,6 @@ describe('Cases', () => { cy.get(ALL_CASES_COMMENTS_COUNT).should('have.text', '0'); cy.get(ALL_CASES_OPENED_ON).should('include.text', 'ago'); cy.get(ALL_CASES_SERVICE_NOW_INCIDENT).should('have.text', 'Not pushed'); - cy.get(ALL_CASES_ITEM_ACTIONS_BTN).should('exist'); goToCaseDetails(); @@ -108,7 +105,6 @@ describe('Cases', () => { cy.get(CASE_DETAILS_USERNAMES).eq(REPORTER).should('have.text', this.mycase.reporter); cy.get(CASE_DETAILS_USERNAMES).eq(PARTICIPANTS).should('have.text', this.mycase.reporter); cy.get(CASE_DETAILS_TAGS).should('have.text', expectedTags); - // cy.get(CASE_DETAILS_PUSH_TO_EXTERNAL_SERVICE_BTN).should('have.attr', 'disabled'); openCaseTimeline(); diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_alerts/attach_to_case.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_alerts/attach_to_case.spec.ts index 9ffade9abbb02..348b03b7f6399 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_alerts/attach_to_case.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_alerts/attach_to_case.spec.ts @@ -23,8 +23,7 @@ const loadDetectionsPage = (role: ROLES) => { waitForAlertsToPopulate(); }; -// TODO: This test may need changes in our UI based on RBAC -describe.skip('Alerts timeline', () => { +describe('Alerts timeline', () => { before(() => { // First we login as a privileged user to create alerts. cleanKibana(); @@ -45,7 +44,7 @@ describe.skip('Alerts timeline', () => { }); it('should not allow user with read only privileges to attach alerts to cases', () => { - cy.get(TIMELINE_CONTEXT_MENU_BTN).first().click(); + cy.get(TIMELINE_CONTEXT_MENU_BTN).first().click({ force: true }); cy.get(ATTACH_ALERT_TO_CASE_BUTTON).should('not.exist'); }); }); @@ -56,7 +55,7 @@ describe.skip('Alerts timeline', () => { }); it('should allow a user with crud privileges to attach alerts to cases', () => { - cy.get(TIMELINE_CONTEXT_MENU_BTN).first().click(); + cy.get(TIMELINE_CONTEXT_MENU_BTN).first().click({ force: true }); cy.get(ATTACH_ALERT_TO_CASE_BUTTON).first().should('not.be.disabled'); }); }); diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/threshold_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/threshold_rule.spec.ts index 588642fb69d0e..7bfc9631f7269 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/threshold_rule.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/threshold_rule.spec.ts @@ -81,8 +81,7 @@ import { loginAndWaitForPageWithoutDateRange } from '../../tasks/login'; import { ALERTS_URL } from '../../urls/navigation'; -// TODO: Alert counts and preview results not showing correct values. Need to fix this test -describe.skip('Detection rules, threshold', () => { +describe('Detection rules, threshold', () => { let rule = getNewThresholdRule(); const expectedUrls = getNewThresholdRule().referenceUrls.join(''); const expectedFalsePositives = getNewThresholdRule().falsePositivesExamples.join(''); diff --git a/x-pack/plugins/security_solution/cypress/integration/exceptions/from_alert.spec.ts b/x-pack/plugins/security_solution/cypress/integration/exceptions/from_alert.spec.ts index 369e65ebf1bdd..002aa0bbc2b1e 100644 --- a/x-pack/plugins/security_solution/cypress/integration/exceptions/from_alert.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/exceptions/from_alert.spec.ts @@ -64,7 +64,7 @@ describe('From alert', () => { esArchiverUnload('auditbeat_for_exceptions2'); }); - // TODO: Looks like the signal is missing some fields. Need to update to make sure it shows up + // TODO: Unskip the test when `https://github.com/elastic/kibana/issues/108244` it is fixed it.skip('Creates an exception and deletes it', () => { addExceptionFromFirstAlert(); addsException(getException()); diff --git a/x-pack/plugins/security_solution/cypress/integration/exceptions/from_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/exceptions/from_rule.spec.ts index 16863ab651353..c4e1d882d1853 100644 --- a/x-pack/plugins/security_solution/cypress/integration/exceptions/from_rule.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/exceptions/from_rule.spec.ts @@ -62,7 +62,7 @@ describe('From rule', () => { esArchiverUnload('auditbeat_for_exceptions2'); }); - // TODO: Looks like the signal is missing some fields. Need to update to make sure it shows up + // TODO: Unskip the test when `https://github.com/elastic/kibana/issues/108244` it is fixed it.skip('Creates an exception and deletes it', () => { goToExceptionsTab(); addsExceptionFromRuleSettings(getException()); diff --git a/x-pack/plugins/security_solution/cypress/integration/header/navigation.spec.ts b/x-pack/plugins/security_solution/cypress/integration/header/navigation.spec.ts index 16278c919a046..15982f1674351 100644 --- a/x-pack/plugins/security_solution/cypress/integration/header/navigation.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/header/navigation.spec.ts @@ -51,7 +51,7 @@ import { } from '../../screens/kibana_navigation'; import { cleanKibana } from '../../tasks/common'; -describe.skip('top-level navigation common to all pages in the Security app', () => { +describe('top-level navigation common to all pages in the Security app', () => { before(() => { cleanKibana(); loginAndWaitForPage(TIMELINES_URL); @@ -111,7 +111,7 @@ describe.skip('top-level navigation common to all pages in the Security app', () }); }); -describe.skip('Kibana navigation to all pages in the Security app ', () => { +describe('Kibana navigation to all pages in the Security app ', () => { before(() => { loginAndWaitForPage(KIBANA_HOME); }); diff --git a/x-pack/plugins/security_solution/cypress/integration/timelines/data_providers.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timelines/data_providers.spec.ts index 5e851cecbd86b..de754f8602667 100644 --- a/x-pack/plugins/security_solution/cypress/integration/timelines/data_providers.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/timelines/data_providers.spec.ts @@ -6,23 +6,12 @@ */ import { - TIMELINE_DATA_PROVIDERS, - TIMELINE_DATA_PROVIDERS_EMPTY, TIMELINE_DROPPED_DATA_PROVIDERS, TIMELINE_DATA_PROVIDERS_ACTION_MENU, - IS_DRAGGING_DATA_PROVIDERS, TIMELINE_FLYOUT_HEADER, - TIMELINE_FLYOUT, } from '../../screens/timeline'; -import { HOSTS_NAMES_DRAGGABLE } from '../../screens/hosts/all_hosts'; -import { - dragAndDropFirstHostToTimeline, - dragFirstHostToEmptyTimelineDataProviders, - unDragFirstHostToEmptyTimelineDataProviders, - dragFirstHostToTimeline, - waitForAllHostsToBeLoaded, -} from '../../tasks/hosts/all_hosts'; +import { waitForAllHostsToBeLoaded } from '../../tasks/hosts/all_hosts'; import { loginAndWaitForPage } from '../../tasks/login'; import { openTimelineUsingToggle } from '../../tasks/security_main'; @@ -44,22 +33,6 @@ describe('timeline data providers', () => { closeTimeline(); }); - it.skip('renders the data provider of a host dragged from the All Hosts widget on the hosts page', () => { - dragAndDropFirstHostToTimeline(); - openTimelineUsingToggle(); - cy.get(`${TIMELINE_FLYOUT} ${TIMELINE_DROPPED_DATA_PROVIDERS}`) - .first() - .invoke('text') - .then((dataProviderText) => { - cy.get(HOSTS_NAMES_DRAGGABLE) - .first() - .invoke('text') - .should((hostname) => { - expect(dataProviderText).to.eq(`host.name: "${hostname}"AND`); - }); - }); - }); - it('displays the data provider action menu when Enter is pressed', (done) => { openTimelineUsingToggle(); addDataProvider({ field: 'host.name', operator: 'exists' }).then(() => { @@ -77,25 +50,4 @@ describe('timeline data providers', () => { done(); }); }); - - it.skip('sets correct classes when the user starts dragging a host, but is not hovering over the data providers', () => { - dragFirstHostToTimeline(); - - cy.get(IS_DRAGGING_DATA_PROVIDERS) - .find(TIMELINE_DATA_PROVIDERS) - .filter(':visible') - .should('have.class', 'drop-target-data-providers'); - }); - - it.skip('render an extra highlighted area in dataProvider when the user starts dragging a host AND is hovering over the data providers', () => { - dragFirstHostToEmptyTimelineDataProviders(); - - cy.get(IS_DRAGGING_DATA_PROVIDERS) - .find(TIMELINE_DATA_PROVIDERS_EMPTY) - .children() - .should('exist'); - - // Release the dragging item so the cursor can peform other action - unDragFirstHostToEmptyTimelineDataProviders(); - }); }); diff --git a/x-pack/plugins/security_solution/cypress/integration/timelines/flyout_button.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timelines/flyout_button.spec.ts index ac34d65f0fd0a..2ee658c666665 100644 --- a/x-pack/plugins/security_solution/cypress/integration/timelines/flyout_button.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/timelines/flyout_button.spec.ts @@ -8,14 +8,12 @@ import { TIMELINE_BOTTOM_BAR_TOGGLE_BUTTON } from '../../screens/security_main'; import { CREATE_NEW_TIMELINE, - IS_DRAGGING_DATA_PROVIDERS, - TIMELINE_DATA_PROVIDERS, TIMELINE_FLYOUT_HEADER, TIMELINE_SETTINGS_ICON, } from '../../screens/timeline'; import { cleanKibana } from '../../tasks/common'; -import { dragFirstHostToTimeline, waitForAllHostsToBeLoaded } from '../../tasks/hosts/all_hosts'; +import { waitForAllHostsToBeLoaded } from '../../tasks/hosts/all_hosts'; import { loginAndWaitForPage } from '../../tasks/login'; import { closeTimelineUsingCloseButton, @@ -78,13 +76,4 @@ describe('timeline flyout button', () => { cy.get('[data-test-subj="nav-search-option"]').its('length').should('be.gte', 1); closeTimelineUsingCloseButton(); }); - - it.skip('sets correct classes when the user starts dragging a host, but is not hovering over the data providers', () => { - dragFirstHostToTimeline(); - - cy.get(IS_DRAGGING_DATA_PROVIDERS) - .find(TIMELINE_DATA_PROVIDERS) - .filter(':visible') - .should('have.class', 'drop-target-data-providers'); - }); }); diff --git a/x-pack/plugins/security_solution/cypress/integration/timelines/local_storage.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timelines/local_storage.spec.ts index f6be213f59d7e..617f04697c951 100644 --- a/x-pack/plugins/security_solution/cypress/integration/timelines/local_storage.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/timelines/local_storage.spec.ts @@ -10,12 +10,11 @@ import { loginAndWaitForPage } from '../../tasks/login'; import { HOSTS_URL } from '../../urls/navigation'; import { openEvents } from '../../tasks/hosts/main'; import { DATAGRID_HEADERS } from '../../screens/timeline'; -import { TABLE_COLUMN_EVENTS_MESSAGE } from '../../screens/hosts/external_events'; import { waitsForEventsToBeLoaded } from '../../tasks/hosts/events'; import { removeColumn } from '../../tasks/timeline'; // TODO: Fix bug in persisting the columns of timeline -describe.skip('persistent timeline', () => { +describe('persistent timeline', () => { beforeEach(() => { cleanKibana(); loginAndWaitForPage(HOSTS_URL); @@ -27,8 +26,11 @@ describe.skip('persistent timeline', () => { }); it('persist the deletion of a column', function () { - cy.get(DATAGRID_HEADERS).eq(TABLE_COLUMN_EVENTS_MESSAGE).should('have.text', 'message'); - removeColumn(TABLE_COLUMN_EVENTS_MESSAGE); + const MESSAGE_COLUMN = 'message'; + const MESSAGE_COLUMN_POSITION = 2; + + cy.get(DATAGRID_HEADERS).eq(MESSAGE_COLUMN_POSITION).should('have.text', MESSAGE_COLUMN); + removeColumn(MESSAGE_COLUMN); cy.get(DATAGRID_HEADERS).should('have.length', this.expectedNumberOfTimelineColumns); @@ -36,6 +38,6 @@ describe.skip('persistent timeline', () => { waitsForEventsToBeLoaded(); cy.get(DATAGRID_HEADERS).should('have.length', this.expectedNumberOfTimelineColumns); - cy.get(DATAGRID_HEADERS).each(($el) => expect($el.text()).not.equal('message')); + cy.get(DATAGRID_HEADERS).each(($el) => expect($el.text()).not.equal(MESSAGE_COLUMN)); }); }); diff --git a/x-pack/plugins/security_solution/cypress/screens/hosts/all_hosts.ts b/x-pack/plugins/security_solution/cypress/screens/hosts/all_hosts.ts index cf1bac421b447..b76add918beaf 100644 --- a/x-pack/plugins/security_solution/cypress/screens/hosts/all_hosts.ts +++ b/x-pack/plugins/security_solution/cypress/screens/hosts/all_hosts.ts @@ -8,5 +8,3 @@ export const ALL_HOSTS_TABLE = '[data-test-subj="table-allHosts-loading-false"]'; export const HOSTS_NAMES = '[data-test-subj="render-content-host.name"] a.euiLink'; - -export const HOSTS_NAMES_DRAGGABLE = '[data-test-subj="render-content-host.name"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/hosts/external_events.ts b/x-pack/plugins/security_solution/cypress/screens/hosts/external_events.ts deleted file mode 100644 index 01f82f8944432..0000000000000 --- a/x-pack/plugins/security_solution/cypress/screens/hosts/external_events.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const TABLE_COLUMN_EVENTS_MESSAGE = 2; diff --git a/x-pack/plugins/security_solution/cypress/screens/timeline.ts b/x-pack/plugins/security_solution/cypress/screens/timeline.ts index 0b9d39d6b0c21..4cf5d2f87f7a9 100644 --- a/x-pack/plugins/security_solution/cypress/screens/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/screens/timeline.ts @@ -39,6 +39,8 @@ export const DATAGRID_HEADERS = export const FAVORITE_TIMELINE = '[data-test-subj="timeline-favorite-filled-star"]'; +export const FIELD_BROWSER = '[data-test-subj="show-field-browser"]'; + export const GRAPH_TAB_BUTTON = '[data-test-subj="timelineTabs-graph"]'; export const HEADER = '[data-test-subj="header"]'; @@ -143,12 +145,8 @@ export const TIMELINE_CORRELATION_INPUT = '[data-test-subj="eqlQueryBarTextInput export const TIMELINE_CORRELATION_TAB = '[data-test-subj="timelineTabs-eql"]'; -export const IS_DRAGGING_DATA_PROVIDERS = '.is-dragging'; - export const TIMELINE_BOTTOM_BAR_CONTAINER = '[data-test-subj="timeline-bottom-bar-container"]'; -export const TIMELINE_DATA_PROVIDERS = '[data-test-subj="dataProviders"]'; - export const TIMELINE_DATA_PROVIDERS_ACTION_MENU = '[data-test-subj="providerActions"]'; export const TIMELINE_ADD_FIELD_BUTTON = '[data-test-subj="addField"]'; @@ -161,9 +159,6 @@ export const TIMELINE_DATA_PROVIDER_VALUE = `[data-test-subj="value"]`; export const SAVE_DATA_PROVIDER_BTN = `[data-test-subj="save"]`; -export const TIMELINE_DATA_PROVIDERS_EMPTY = - '[data-test-subj="dataProviders"] [data-test-subj="empty"]'; - export const TIMELINE_DESCRIPTION = '[data-test-subj="timeline-description"]'; export const TIMELINE_DESCRIPTION_INPUT = '[data-test-subj="save-timeline-description"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts index 9a500f81ec45f..63d1cbbc883b0 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts @@ -293,7 +293,8 @@ export const fillDefineThresholdRuleAndContinue = (rule: ThresholdRule) => { const thresholdField = 0; const threshold = 1; - const typeThresholdField = ($el: Cypress.ObjectLike) => cy.wrap($el).type(rule.thresholdField); + const typeThresholdField = ($el: Cypress.ObjectLike) => + cy.wrap($el).type(rule.thresholdField, { delay: 35 }); cy.get(IMPORT_QUERY_FROM_SAVED_TIMELINE_LINK).click(); cy.get(TIMELINE(rule.timeline.id!)).click(); @@ -301,6 +302,7 @@ export const fillDefineThresholdRuleAndContinue = (rule: ThresholdRule) => { cy.get(THRESHOLD_INPUT_AREA) .find(INPUT) .then((inputs) => { + cy.wrap(inputs[thresholdField]).click(); cy.wrap(inputs[thresholdField]).pipe(typeThresholdField); cy.get(THRESHOLD_FIELD_SELECTION).click({ force: true }); cy.wrap(inputs[threshold]).clear().type(rule.threshold); diff --git a/x-pack/plugins/security_solution/cypress/tasks/hosts/all_hosts.ts b/x-pack/plugins/security_solution/cypress/tasks/hosts/all_hosts.ts index 317a35708de57..cdae0437eb565 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/hosts/all_hosts.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/hosts/all_hosts.ts @@ -5,52 +5,8 @@ * 2.0. */ -import { ALL_HOSTS_TABLE, HOSTS_NAMES_DRAGGABLE, HOSTS_NAMES } from '../../screens/hosts/all_hosts'; -import { TIMELINE_DATA_PROVIDERS, TIMELINE_DATA_PROVIDERS_EMPTY } from '../../screens/timeline'; +import { ALL_HOSTS_TABLE, HOSTS_NAMES } from '../../screens/hosts/all_hosts'; -import { drag, dragWithoutDrop, drop } from '../../tasks/common'; - -export const dragAndDropFirstHostToTimeline = () => { - cy.get(HOSTS_NAMES_DRAGGABLE) - .first() - .then((firstHost) => drag(firstHost)); - cy.get(TIMELINE_DATA_PROVIDERS) - .filter(':visible') - .then((dataProvidersDropArea) => drop(dataProvidersDropArea)); -}; - -export const dragFirstHostToEmptyTimelineDataProviders = () => { - cy.get(HOSTS_NAMES_DRAGGABLE) - .first() - .then((host) => drag(host)); - - cy.get(TIMELINE_DATA_PROVIDERS_EMPTY) - .filter(':visible') - .then((dataProvidersDropArea) => dragWithoutDrop(dataProvidersDropArea)); -}; - -export const unDragFirstHostToEmptyTimelineDataProviders = () => { - cy.get(HOSTS_NAMES_DRAGGABLE) - .first() - .then((host) => { - cy.wrap(host) - .trigger('mousemove', { - button: 0, - clientX: host[0].getBoundingClientRect().left, - clientY: host[0].getBoundingClientRect().top, - force: true, - }) - .wait(300) - .trigger('mouseup', { force: true }) - .wait(300); - }); -}; - -export const dragFirstHostToTimeline = () => { - cy.get(HOSTS_NAMES_DRAGGABLE) - .first() - .then((host) => drag(host)); -}; export const openFirstHostDetails = () => { cy.get(HOSTS_NAMES).first().click({ force: true }); }; diff --git a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts index 4a61a94e4acea..03ccb784bd259 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts @@ -8,6 +8,7 @@ import { Timeline, TimelineFilter } from '../objects/timeline'; import { ALL_CASES_CREATE_NEW_CASE_TABLE_BTN } from '../screens/all_cases'; +import { FIELDS_BROWSER_CHECKBOX } from '../screens/fields_browser'; import { LOADING_INDICATOR } from '../screens/security_header'; import { @@ -20,7 +21,7 @@ import { CLOSE_TIMELINE_BTN, COMBO_BOX, CREATE_NEW_TIMELINE, - DATAGRID_HEADERS, + FIELD_BROWSER, ID_FIELD, ID_HEADER_FIELD, ID_TOGGLE_FIELD, @@ -70,6 +71,8 @@ import { REFRESH_BUTTON, TIMELINE } from '../screens/timelines'; import { drag, drop } from '../tasks/common'; +import { closeFieldsBrowser, filterFieldsBrowser } from '../tasks/fields_browser'; + export const hostExistsQuery = 'host.name: *'; export const addDescriptionToTimeline = (description: string) => { @@ -327,13 +330,11 @@ export const dragAndDropIdToggleFieldToTimeline = () => { .then((headersDropArea) => drop(headersDropArea)); }; -export const removeColumn = (column: number) => { - cy.get(DATAGRID_HEADERS) - .eq(column) - .click() - .within(() => { - cy.get('button').eq(0).click({ force: true }); - }); +export const removeColumn = (columnName: string) => { + cy.get(FIELD_BROWSER).first().click(); + filterFieldsBrowser(columnName); + cy.get(FIELDS_BROWSER_CHECKBOX(columnName)).click(); + closeFieldsBrowser(); }; export const resetFields = () => { From 63db90b0c494b7e53451ae2c7560021c65110727 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Thu, 19 Aug 2021 14:33:29 -0400 Subject: [PATCH 04/14] [ML] Anomaly detection: Adds functional test for delayed data chart flyout (#109026) * wip add delayed data functional test * adds delayed data functional test * add menu check for stability and reorganize functions * ensure describe block is self contained --- .../datafeed_chart_flyout.tsx | 245 +++++++++--------- .../apps/ml/anomaly_detection/annotations.ts | 23 ++ .../services/ml/job_annotations_table.ts | 46 ++++ 3 files changed, 193 insertions(+), 121 deletions(-) diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/datafeed_chart_flyout.tsx b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/datafeed_chart_flyout.tsx index 0879a657d7fa9..17ff5db2768d6 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/datafeed_chart_flyout.tsx +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/datafeed_chart_flyout.tsx @@ -185,8 +185,9 @@ export const DatafeedChartFlyout: FC = ({ jobId, end, aria-label={i18n.translate('xpack.ml.jobsList.datafeedChart.datafeedChartFlyoutAriaLabel', { defaultMessage: 'Datafeed chart flyout', })} + data-test-subj="mlAnnotationsViewDatafeedFlyout" > - + @@ -308,143 +309,145 @@ export const DatafeedChartFlyout: FC = ({ jobId, end, - - - - - {showModelSnapshots ? ( - } - markerPosition={Position.Top} - style={{ - line: { - strokeWidth: 3, - stroke: euiTheme.euiColorVis1, - opacity: 0.5, +
+ + - ) : null} - {showAnnotations ? ( - <> - } - markerPosition={Position.Top} - style={{ - line: { - strokeWidth: 3, - stroke: euiTheme.euiColorDangerText, - opacity: 0.5, - }, - }} - /> - - - ) : null} - {messageData.length > 0 ? ( - <> + + + {showModelSnapshots ? ( } + dataValues={modelSnapshotData} + marker={} markerPosition={Position.Top} style={{ line: { strokeWidth: 3, - stroke: euiTheme.euiColorAccent, + stroke: euiTheme.euiColorVis1, opacity: 0.5, }, }} /> - - ) : null} - - - + ) : null} + {showAnnotations ? ( + <> + } + markerPosition={Position.Top} + style={{ + line: { + strokeWidth: 3, + stroke: euiTheme.euiColorDangerText, + opacity: 0.5, + }, + }} + /> + + + ) : null} + {messageData.length > 0 ? ( + <> + } + markerPosition={Position.Top} + style={{ + line: { + strokeWidth: 3, + stroke: euiTheme.euiColorAccent, + opacity: 0.5, + }, + }} + /> + + ) : null} + + + +
{ + await ml.api.indexAnnotation(annotation as Partial, annotationId); + }); + + it('displays delayed data chart for annotation', async () => { + await ml.testExecution.logTestStep( + 'should display delayed data action in annotations table' + ); + + await ml.navigation.navigateToMl(); + await ml.navigation.navigateToJobManagement(); + await ml.jobTable.waitForJobsToLoad(); + await ml.jobTable.filterWithSearchString(jobId, 1); + await ml.jobTable.openAnnotationsTab(jobId); + + await ml.jobAnnotations.openDatafeedChartFlyout(annotationId, jobId); + await ml.jobAnnotations.assertDelayedDataChartExists(); + }); + }); + describe('deleting', function () { const annotationId = `delete-annotation-id-${Date.now()}`; diff --git a/x-pack/test/functional/services/ml/job_annotations_table.ts b/x-pack/test/functional/services/ml/job_annotations_table.ts index 0acba253cb056..90b47e9f8b455 100644 --- a/x-pack/test/functional/services/ml/job_annotations_table.ts +++ b/x-pack/test/functional/services/ml/job_annotations_table.ts @@ -341,5 +341,51 @@ export function MachineLearningJobAnnotationsProvider({ getService }: FtrProvide await this.setAnnotationText(text); }); } + + public async assertAnnotationsDelayedDataChartActionExists() { + await retry.tryForTime(1000, async () => { + await testSubjects.existOrFail('mlAnnotationsActionViewDatafeed'); + }); + } + + public async ensureAllMenuPopoversClosed() { + await retry.tryForTime(5000, async () => { + await browser.pressKeys(browser.keys.ESCAPE); + const popoverExists = await find.existsByCssSelector('euiContextMenuPanel'); + expect(popoverExists).to.eql(false, 'All popovers should be closed'); + }); + } + + public async ensureAnnotationsActionsMenuOpen(annotationId: string) { + await retry.tryForTime(10 * 1000, async () => { + await this.ensureAllMenuPopoversClosed(); + await testSubjects.click( + `mlAnnotationsTableRow row-${annotationId} > euiCollapsedItemActionsButton`, + 30 * 1000 + ); + await find.existsByCssSelector('euiContextMenuPanel'); + }); + } + + public async openDatafeedChartFlyout(annotationId: string, jobId: string) { + await retry.tryForTime(10 * 1000, async () => { + await this.ensureAnnotationsActionsMenuOpen(annotationId); + await this.assertAnnotationsDelayedDataChartActionExists(); + + await testSubjects.clickWhenNotDisabled('mlAnnotationsActionViewDatafeed'); + await testSubjects.existOrFail('mlAnnotationsViewDatafeedFlyout'); + await testSubjects.existOrFail('mlAnnotationsViewDatafeedFlyoutTitle'); + + const title = await testSubjects.getVisibleText('mlAnnotationsViewDatafeedFlyoutTitle'); + expect(title).to.eql( + `Datafeed chart for ${jobId}`, + `Expected annotations flyout title to be 'Datafeed chart for ${jobId}' but got ${title}` + ); + }); + } + + public async assertDelayedDataChartExists() { + await testSubjects.existOrFail('mlAnnotationsViewDatafeedFlyoutChart'); + } })(); } From cfd5dad17404bfbac53d7b5d2f346f6b2904ebb8 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 19 Aug 2021 19:40:50 +0100 Subject: [PATCH 05/14] chore(NA): moving @kbn/optimizer to babel transpiler (#109231) * chore(NA): adds 7.16 into backportrc * chore(NA): moving @kbn/optimizer to babel transpiler --- packages/kbn-optimizer/.babelrc | 4 +++ packages/kbn-optimizer/BUILD.bazel | 34 +++++++++++++++---- packages/kbn-optimizer/babel.config.js | 12 ------- packages/kbn-optimizer/package.json | 4 +-- packages/kbn-optimizer/tsconfig.json | 3 +- .../kbn-test/src/jest/setup/babel_polyfill.js | 2 +- 6 files changed, 37 insertions(+), 22 deletions(-) create mode 100644 packages/kbn-optimizer/.babelrc delete mode 100644 packages/kbn-optimizer/babel.config.js diff --git a/packages/kbn-optimizer/.babelrc b/packages/kbn-optimizer/.babelrc new file mode 100644 index 0000000000000..1685d1644d94a --- /dev/null +++ b/packages/kbn-optimizer/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@kbn/babel-preset/node_preset"], + "ignore": ["**/*.test.js"] +} diff --git a/packages/kbn-optimizer/BUILD.bazel b/packages/kbn-optimizer/BUILD.bazel index ddf2a05519682..7f04aa4b262b0 100644 --- a/packages/kbn-optimizer/BUILD.bazel +++ b/packages/kbn-optimizer/BUILD.bazel @@ -1,5 +1,6 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") +load("//src/dev/bazel:index.bzl", "jsts_transpiler") PKG_BASE_NAME = "kbn-optimizer" PKG_REQUIRE_NAME = "@kbn/optimizer" @@ -29,7 +30,7 @@ NPM_MODULE_EXTRA_FILES = [ "README.md" ] -SRC_DEPS = [ +RUNTIME_DEPS = [ "//packages/kbn-config", "//packages/kbn-dev-utils", "//packages/kbn-std", @@ -59,6 +60,22 @@ SRC_DEPS = [ ] TYPES_DEPS = [ + "//packages/kbn-config", + "//packages/kbn-dev-utils", + "//packages/kbn-std", + "//packages/kbn-ui-shared-deps", + "//packages/kbn-utils", + "@npm//chalk", + "@npm//clean-webpack-plugin", + "@npm//cpy", + "@npm//del", + "@npm//execa", + "@npm//jest-diff", + "@npm//lmdb-store", + "@npm//pirates", + "@npm//resize-observer-polyfill", + "@npm//rxjs", + "@npm//zlib", "@npm//@types/compression-webpack-plugin", "@npm//@types/jest", "@npm//@types/json-stable-stringify", @@ -72,7 +89,11 @@ TYPES_DEPS = [ "@npm//@types/webpack-sources", ] -DEPS = SRC_DEPS + TYPES_DEPS +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) ts_config( name = "tsconfig", @@ -84,13 +105,14 @@ ts_config( ) ts_project( - name = "tsc", + name = "tsc_types", args = ['--pretty'], srcs = SRCS, - deps = DEPS, + deps = TYPES_DEPS, declaration = True, declaration_map = True, - out_dir = "target", + emit_declaration_only = True, + out_dir = "target_types", source_map = True, root_dir = "src", tsconfig = ":tsconfig", @@ -99,7 +121,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = DEPS + [":tsc"], + deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/kbn-optimizer/babel.config.js b/packages/kbn-optimizer/babel.config.js deleted file mode 100644 index e3a412717fb6e..0000000000000 --- a/packages/kbn-optimizer/babel.config.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - presets: ['@kbn/babel-preset/node_preset'], - ignore: ['**/*.test.js'], -}; diff --git a/packages/kbn-optimizer/package.json b/packages/kbn-optimizer/package.json index d23512f7c418d..488e1b5dbfde8 100644 --- a/packages/kbn-optimizer/package.json +++ b/packages/kbn-optimizer/package.json @@ -3,6 +3,6 @@ "version": "1.0.0", "private": true, "license": "SSPL-1.0 OR Elastic License 2.0", - "main": "./target/index.js", - "types": "./target/index.d.ts" + "main": "./target_node/index.js", + "types": "./target_types/index.d.ts" } \ No newline at end of file diff --git a/packages/kbn-optimizer/tsconfig.json b/packages/kbn-optimizer/tsconfig.json index 047c98db8a806..5fbd02106e777 100644 --- a/packages/kbn-optimizer/tsconfig.json +++ b/packages/kbn-optimizer/tsconfig.json @@ -1,9 +1,10 @@ { "extends": "../../tsconfig.bazel.json", "compilerOptions": { - "outDir": "./target/types", "declaration": true, "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "./target_types", "rootDir": "./src", "sourceMap": true, "sourceRoot": "../../../../packages/kbn-optimizer/src", diff --git a/packages/kbn-test/src/jest/setup/babel_polyfill.js b/packages/kbn-test/src/jest/setup/babel_polyfill.js index 7dda4cceec65c..7981eb668f38f 100644 --- a/packages/kbn-test/src/jest/setup/babel_polyfill.js +++ b/packages/kbn-test/src/jest/setup/babel_polyfill.js @@ -9,4 +9,4 @@ // Note: In theory importing the polyfill should not be needed, as Babel should // include the necessary polyfills when using `@babel/preset-env`, but for some // reason it did not work. See https://github.com/elastic/kibana/issues/14506 -import '@kbn/optimizer/target/node/polyfill'; +import '@kbn/optimizer/target_node/node/polyfill'; From 7f68ff269c4f996950136b94498f6ddd857042e4 Mon Sep 17 00:00:00 2001 From: Tre Date: Thu, 19 Aug 2021 19:48:26 +0100 Subject: [PATCH 06/14] [Archive Migration] x-pack..dashboard_view_mode (#108503) --- .../dashboard_mode/dashboard_view_mode.js | 85 ++--- .../dashboard_view_mode/data.json.gz | Bin 1938 -> 0 bytes .../dashboard_view_mode/mappings.json | 308 ------------------ .../kbn_archiver/dashboard_view_mode.json | 303 +++++++++++++++++ 4 files changed, 323 insertions(+), 373 deletions(-) delete mode 100644 x-pack/test/functional/es_archives/dashboard_view_mode/data.json.gz delete mode 100644 x-pack/test/functional/es_archives/dashboard_view_mode/mappings.json create mode 100644 x-pack/test/functional/fixtures/kbn_archiver/dashboard_view_mode.json diff --git a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js index b3f15e2dffa0b..74f4dca06c717 100644 --- a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js +++ b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js @@ -15,7 +15,6 @@ export default function ({ getService, getPageObjects }) { const pieChart = getService('pieChart'); const security = getService('security'); const testSubjects = getService('testSubjects'); - const dashboardAddPanel = getService('dashboardAddPanel'); const dashboardPanelActions = getService('dashboardPanelActions'); const appsMenu = getService('appsMenu'); const filterBar = getService('filterBar'); @@ -30,7 +29,6 @@ export default function ({ getService, getPageObjects }) { 'share', ]); const dashboardName = 'Dashboard View Mode Test Dashboard'; - const savedSearchName = 'Saved search for dashboard'; describe('Dashboard View Mode', function () { this.tags(['skipFirefox']); @@ -38,83 +36,40 @@ export default function ({ getService, getPageObjects }) { before('initialize tests', async () => { log.debug('Dashboard View Mode:initTests'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); - await esArchiver.load('x-pack/test/functional/es_archives/dashboard_view_mode'); + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/dashboard_view_mode' + ); await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash-*' }); await browser.setWindowSize(1600, 1000); - await PageObjects.common.navigateToApp('discover'); - await PageObjects.timePicker.setHistoricalDataRange(); - await PageObjects.discover.saveSearch(savedSearchName); - await PageObjects.common.navigateToApp('dashboard'); - await PageObjects.dashboard.clickNewDashboard(); - await dashboardAddPanel.addSavedSearch(savedSearchName); - await PageObjects.dashboard.addVisualizations( - PageObjects.dashboard.getTestVisualizationNames() + }); + + after(async () => { + await kibanaServer.importExport.unload( + 'x-pack/test/functional/fixtures/kbn_archiver/dashboard_view_mode' ); - await PageObjects.dashboard.saveDashboard(dashboardName); + const types = [ + 'search', + 'dashboard', + 'visualization', + 'search-session', + 'core-usage-stats', + 'event_loop_delays_daily', + 'search-telemetry', + 'core-usage-stats', + ]; + await kibanaServer.savedObjects.clean({ types }); }); describe('Dashboard viewer', () => { - before('Create logstash data role', async () => { - await PageObjects.settings.navigateTo(); - await testSubjects.click('roles'); - await PageObjects.security.clickCreateNewRole(); - - await testSubjects.setValue('roleFormNameInput', 'logstash-data'); - await PageObjects.security.addIndexToRole('logstash-*'); - await PageObjects.security.addPrivilegeToRole('read'); - await PageObjects.security.clickSaveEditRole(); - }); - - before('Create dashboard only mode user', async () => { - await PageObjects.settings.navigateTo(); - await PageObjects.security.createUser({ - username: 'dashuser', - password: '123456', - confirm_password: '123456', - email: 'example@example.com', - full_name: 'dashuser', - roles: ['kibana_dashboard_only_user', 'logstash-data'], - }); - }); - - before('Create user with mixes roles', async () => { - await PageObjects.security.createUser({ - username: 'mixeduser', - password: '123456', - confirm_password: '123456', - email: 'example@example.com', - full_name: 'mixeduser', - roles: ['kibana_dashboard_only_user', 'kibana_admin', 'logstash-data'], - }); - }); - - before('Create user with dashboard and superuser role', async () => { - await PageObjects.security.createUser({ - username: 'mysuperuser', - password: '123456', - confirm_password: '123456', - email: 'example@example.com', - full_name: 'mixeduser', - roles: ['kibana_dashboard_only_user', 'superuser'], - }); - }); - after(async () => { await security.testUser.restoreDefaults(); }); it('shows only the dashboard app link', async () => { - await security.testUser.setRoles( - ['test_logstash_reader', 'kibana_dashboard_only_user'], - false - ); - + await security.testUser.setRoles(['test_logstash_reader', 'kibana_dashboard_only_user']); await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.security.forceLogout(); - await PageObjects.security.login('test_user', 'changeme'); - const appLinks = await appsMenu.readLinks(); expect(appLinks).to.have.length(1); expect(appLinks[0]).to.have.property('text', 'Dashboard'); diff --git a/x-pack/test/functional/es_archives/dashboard_view_mode/data.json.gz b/x-pack/test/functional/es_archives/dashboard_view_mode/data.json.gz deleted file mode 100644 index 8d2e399dfce29f48c33860136faa0893bde0ad38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1938 zcmV;D2W|KtiwFP!000026YX5xZre5#zVB0Lz8o4m$+iOZRg-2LHZ*AvXC1maFlgym z;zEfUNyTvkKgV{x`@O)hrx~z4#||mVmTVpg+xTyq(lMpIkrtGQy`G??qc3qa5S&+ zuc%^1J?)AQT7@p?KoPYRWnOQ*0wGI{?bWGNns2P=W>_P{2~2~=*hVOAG}El~*oKr7 zK~h=jAO~?uV*SS6E;h-8Pfv+Zl&~{C)$dFQlVDrWA~ci->VUCVa0P79t~EsBSU_7dc-nO5V+NIeD0byi?>F;@iHaq8( zp-pp#2-D=?5d%xmBI!0`KaM_1NxnACk#=6aG|=D>1uv-x83d)X+juFDKoV6596Gui zbP^!ym|XwBd8#M-vx-Es*O=T=r4_x~-LvE~6464lvj2sp9I`^IcdvRr;Ud*Sfli;6 z!%QmyAk%40R0Ekpl>V0}mCJswHzpFDJ?~~lFNEp8V}8}c85C35ljyND1ljv;@b%!F z=e&nz8Xyrw@B8CH`IpfGH`CURYwc6QR`;{+u6c!#S?RmOPDz+(_LU*f6!WZJu4kP# zjUXAO`@&$)LZJ$$<+xB)$H<8ca>1`Cf<-W%1)9ea!PJaFInb~(-zJ>Kz!P+=Q7mZm za4^NMyCLTyqG%4AjcE`)6%bOZP^*l*M%w>K=x6|ACr7=5$ofmrcsL|BdTL^xkzVRv zv~Bca(5OPd1caSh3+-08^mJjazDdgsXf~#~8L;7vC2ZB-(Q(JfU1bW!t_u!uK3ZdK zczjD~3~$#7O${&&C@*=Y6NN61`^HE5QyQtnE51rToH2AQWmk}?!>NK$j4m6yW@Ftl zwS>Z2Ji%EoVd&^ z5-wd1pOP@48FZ`t1~+kl(d<$>)B=qh3jYGbo$G8RPx2H}t~VEaNe1fJ=~z3yp_YH) zKjjg{#be|)`r1u3UzB6EcRX4eN~&O_+nq0se!?c@*8;7!_Hbx4v(MpJG3IDr`ZIH@ zK%l3uCwmJHl`|?g^qL&hiT7rqqI^gV_umfl16N$;k-7`VS}-Se()A{j<6LsIp;TaV zK2k?9|FG4My~%Z0ahpQ59Rbx(mqt0K_E=);`3h>rG0>P@CCin6Guj+Ddv^xl2UjxZ znRLy@ixi}EpEOh(U|f2;sqPyhJGR)hbZIKHRp}?LIF6K3gpQBQ+|SKL^6d?(xkh=t zx$XFP#XoOFK0G+!Mu&C2&E%bJ>c@hvPqTg6KWI`Hv#VvvkE_$ya#iTX)wBr}ZFkfBx$^1rK5yeatfO)XQc9oXNB^q3i-n&Ftua6S}oz{yFL{n+usU!MKkBlxyr*M_D=gl z0j&~m(Mfe_@J5S{6Fx1A3TxlWlyjA6QDq|#qT+JSOzP6CQf@6>jxZ}TeH?yH(;XdI|< Date: Thu, 19 Aug 2021 21:19:20 +0200 Subject: [PATCH 07/14] [Upgrade Assistant] Overview page should reference nextMajor (#109222) * Should use nextMajor instead of currentMajor * Fix small CR changes --- .../helpers/overview.helpers.ts | 2 + .../overview/overview.test.tsx | 39 +++++++++++++++++++ .../components/overview/overview.tsx | 12 +++--- .../review_logs_step/review_logs_step.tsx | 6 +-- .../overview/upgrade_step/upgrade_step.tsx | 12 +++--- 5 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/overview.test.tsx diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/overview.helpers.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/overview.helpers.ts index 93826497b8630..96e12d4806ee3 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/overview.helpers.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/overview.helpers.ts @@ -76,4 +76,6 @@ export type OverviewTestSubjects = | 'upgradeSetupDocsLink' | 'upgradeSetupCloudLink' | 'deprecationWarningCallout' + | 'whatsNewLink' + | 'documentationLink' | 'upgradeStatusError'; diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/overview.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/overview.test.tsx new file mode 100644 index 0000000000000..0acf5ae65c6cc --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/overview.test.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { mockKibanaSemverVersion } from '../../../common/constants'; +import { OverviewTestBed, setupOverviewPage, setupEnvironment } from '../helpers'; + +describe('Overview Page', () => { + let testBed: OverviewTestBed; + const { server } = setupEnvironment(); + + beforeEach(async () => { + testBed = await setupOverviewPage(); + testBed.component.update(); + }); + + afterAll(() => { + server.restore(); + }); + + describe('Documentation links', () => { + test('Has a whatsNew link and it references nextMajor version', () => { + const { exists, find } = testBed; + const nextMajor = mockKibanaSemverVersion.major + 1; + + expect(exists('whatsNewLink')).toBe(true); + expect(find('whatsNewLink').text()).toContain(`${nextMajor}.0`); + }); + + test('Has a link for upgrade assistant in page header', () => { + const { exists } = testBed; + + expect(exists('documentationLink')).toBe(true); + }); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx index bd076dd600216..b7cac67ca5a96 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx @@ -27,7 +27,7 @@ import { getUpgradeStep } from './upgrade_step'; export const Overview: FunctionComponent = () => { const { kibanaVersionInfo, breadcrumbs, docLinks, api } = useAppContext(); - const { currentMajor } = kibanaVersionInfo; + const { nextMajor } = kibanaVersionInfo; useEffect(() => { async function sendTelemetryData() { @@ -68,12 +68,12 @@ export const Overview: FunctionComponent = () => { , ]} > - + @@ -83,9 +83,9 @@ export const Overview: FunctionComponent = () => { diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/review_logs_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/review_logs_step.tsx index 2da31a3801dd0..4ebde8b5f847a 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/review_logs_step.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/review_logs_step.tsx @@ -20,7 +20,7 @@ const i18nTexts = { }), }; -export const getReviewLogsStep = ({ currentMajor }: { currentMajor: number }): EuiStepProps => { +export const getReviewLogsStep = ({ nextMajor }: { nextMajor: number }): EuiStepProps => { return { title: i18nTexts.reviewStepTitle, status: 'incomplete', @@ -30,8 +30,8 @@ export const getReviewLogsStep = ({ currentMajor }: { currentMajor: number }): E

diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/upgrade_step/upgrade_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/upgrade_step/upgrade_step.tsx index 9b66a28e81cd8..d66a408cfce77 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/upgrade_step/upgrade_step.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/upgrade_step/upgrade_step.tsx @@ -21,10 +21,10 @@ import type { DocLinksStart } from 'src/core/public'; import { useKibana } from '../../../../shared_imports'; const i18nTexts = { - upgradeStepTitle: (currentMajor: number) => + upgradeStepTitle: (nextMajor: number) => i18n.translate('xpack.upgradeAssistant.overview.upgradeStepTitle', { - defaultMessage: 'Install {currentMajor}.0', - values: { currentMajor }, + defaultMessage: 'Install {nextMajor}.0', + values: { nextMajor }, }), upgradeStepDescription: i18n.translate('xpack.upgradeAssistant.overview.upgradeStepDescription', { defaultMessage: @@ -117,12 +117,12 @@ const UpgradeStep = ({ docLinks }: { docLinks: DocLinksStart }) => { interface Props { docLinks: DocLinksStart; - currentMajor: number; + nextMajor: number; } -export const getUpgradeStep = ({ docLinks, currentMajor }: Props): EuiStepProps => { +export const getUpgradeStep = ({ docLinks, nextMajor }: Props): EuiStepProps => { return { - title: i18nTexts.upgradeStepTitle(currentMajor), + title: i18nTexts.upgradeStepTitle(nextMajor), status: 'incomplete', children: , }; From 7369bdf36059166c1c52b55eb3039ccaac6d0219 Mon Sep 17 00:00:00 2001 From: Sandra G Date: Thu, 19 Aug 2021 15:38:49 -0400 Subject: [PATCH 08/14] [Monitoring] document monitoring.ui.ccs.enabled (#109318) * monitoring.ui.ccs.enabled doc * fix links --- docs/settings/monitoring-settings.asciidoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/settings/monitoring-settings.asciidoc b/docs/settings/monitoring-settings.asciidoc index 6483442248cea..31148f0abf4e1 100644 --- a/docs/settings/monitoring-settings.asciidoc +++ b/docs/settings/monitoring-settings.asciidoc @@ -37,6 +37,10 @@ For more information, see monitoring back-end does not run and {kib} stats are not sent to the monitoring cluster. +| `monitoring.ui.ccs.enabled` + | Set to `true` (default) to enable {ref}/modules-cross-cluster-search.html[cross-cluster search] of your monitoring data. The {ref}/modules-remote-clusters.html#remote-cluster-settings[`remote_cluster_client`] role must exist on each node. + + | `monitoring.ui.elasticsearch.hosts` | Specifies the location of the {es} cluster where your monitoring data is stored. By default, this is the same as <>. This setting enables From 1fd7038b34084052895bb926b80c2301e4588de9 Mon Sep 17 00:00:00 2001 From: Jonathan Buttner <56361221+jonathan-buttner@users.noreply.github.com> Date: Thu, 19 Aug 2021 16:01:39 -0400 Subject: [PATCH 09/14] [Cases] Include rule registry client for updating alert statuses (#108588) * Trying to get import to work * Plumbed alerts client through and logging errors * No longer need the ES cluster client * Fixing types * Fixing imports * Fixing integration tests and refactoring * Throwing an error when rule registry is disabled * Reworking alert update and get to catch errors * Adding tests and fixing errors --- x-pack/plugins/cases/kibana.json | 1 + .../plugins/cases/server/client/alerts/get.ts | 14 +- .../cases/server/client/alerts/types.ts | 12 +- .../server/client/alerts/update_status.ts | 4 +- .../cases/server/client/attachments/add.ts | 34 +- .../plugins/cases/server/client/cases/push.ts | 65 +- .../cases/server/client/cases/update.ts | 27 +- x-pack/plugins/cases/server/client/factory.ts | 19 +- .../cases/server/client/sub_cases/update.ts | 21 +- x-pack/plugins/cases/server/client/types.ts | 3 +- .../server/common/models/commentable_case.ts | 34 +- .../connectors/servicenow/sir_format.test.ts | 159 +- .../connectors/servicenow/sir_format.ts | 36 +- x-pack/plugins/cases/server/plugin.ts | 7 +- .../server/services/alerts/index.test.ts | 81 +- .../cases/server/services/alerts/index.ts | 137 +- .../cases/server/services/alerts/types.ts | 13 + x-pack/plugins/cases/tsconfig.json | 1 + x-pack/plugins/rule_registry/server/index.ts | 1 + x-pack/plugins/rule_registry/server/mocks.ts | 2 + .../tests/common/cases/patch_cases.ts | 10 +- .../common/client/update_alert_status.ts | 6 +- .../tests/common/comments/post_comment.ts | 2 +- .../tests/common/sub_cases/patch_sub_cases.ts | 8 +- .../cases/signals/default/data.json.gz | Bin 5586 -> 3945 bytes .../cases/signals/default/mappings.json | 1926 ++++++++- .../cases/signals/duplicate_ids/data.json.gz | Bin 5513 -> 3876 bytes .../cases/signals/duplicate_ids/mappings.json | 3713 ++++++++++++++++- 28 files changed, 5794 insertions(+), 542 deletions(-) create mode 100644 x-pack/plugins/cases/server/services/alerts/types.ts diff --git a/x-pack/plugins/cases/kibana.json b/x-pack/plugins/cases/kibana.json index ebac6295166df..3889c559238b3 100644 --- a/x-pack/plugins/cases/kibana.json +++ b/x-pack/plugins/cases/kibana.json @@ -10,6 +10,7 @@ "id":"cases", "kibanaVersion":"kibana", "optionalPlugins":[ + "ruleRegistry", "security", "spaces" ], diff --git a/x-pack/plugins/cases/server/client/alerts/get.ts b/x-pack/plugins/cases/server/client/alerts/get.ts index 2048ccae4fa60..391279aab5a83 100644 --- a/x-pack/plugins/cases/server/client/alerts/get.ts +++ b/x-pack/plugins/cases/server/client/alerts/get.ts @@ -12,19 +12,11 @@ export const get = async ( { alertsInfo }: AlertGet, clientArgs: CasesClientArgs ): Promise => { - const { alertsService, scopedClusterClient, logger } = clientArgs; + const { alertsService, logger } = clientArgs; if (alertsInfo.length === 0) { return []; } - const alerts = await alertsService.getAlerts({ alertsInfo, scopedClusterClient, logger }); - if (!alerts) { - return []; - } - - return alerts.docs.map((alert) => ({ - id: alert._id, - index: alert._index, - ...alert._source, - })); + const alerts = await alertsService.getAlerts({ alertsInfo, logger }); + return alerts ?? []; }; diff --git a/x-pack/plugins/cases/server/client/alerts/types.ts b/x-pack/plugins/cases/server/client/alerts/types.ts index 95cd9ae33bff9..6b3a49f20d1e5 100644 --- a/x-pack/plugins/cases/server/client/alerts/types.ts +++ b/x-pack/plugins/cases/server/client/alerts/types.ts @@ -7,17 +7,7 @@ import { CaseStatuses } from '../../../common/api'; import { AlertInfo } from '../../common'; - -interface Alert { - id: string; - index: string; - destination?: { - ip: string; - }; - source?: { - ip: string; - }; -} +import { Alert } from '../../services/alerts/types'; export type CasesClientGetAlertsResponse = Alert[]; diff --git a/x-pack/plugins/cases/server/client/alerts/update_status.ts b/x-pack/plugins/cases/server/client/alerts/update_status.ts index a0684b59241b0..9c8cc33264413 100644 --- a/x-pack/plugins/cases/server/client/alerts/update_status.ts +++ b/x-pack/plugins/cases/server/client/alerts/update_status.ts @@ -16,6 +16,6 @@ export const updateStatus = async ( { alerts }: UpdateAlertsStatusArgs, clientArgs: CasesClientArgs ): Promise => { - const { alertsService, scopedClusterClient, logger } = clientArgs; - await alertsService.updateAlertsStatus({ alerts, scopedClusterClient, logger }); + const { alertsService, logger } = clientArgs; + await alertsService.updateAlertsStatus({ alerts, logger }); }; diff --git a/x-pack/plugins/cases/server/client/attachments/add.ts b/x-pack/plugins/cases/server/client/attachments/add.ts index 166ae2ae65012..5393a108d6af2 100644 --- a/x-pack/plugins/cases/server/client/attachments/add.ts +++ b/x-pack/plugins/cases/server/client/attachments/add.ts @@ -40,12 +40,7 @@ import { } from '../../services/user_actions/helpers'; import { AttachmentService, CasesService, CaseUserActionService } from '../../services'; -import { - createCaseError, - CommentableCase, - createAlertUpdateRequest, - isCommentRequestTypeGenAlert, -} from '../../common'; +import { createCaseError, CommentableCase, isCommentRequestTypeGenAlert } from '../../common'; import { CasesClientArgs, CasesClientInternal } from '..'; import { decodeCommentRequest } from '../utils'; @@ -195,22 +190,9 @@ const addGeneratedAlerts = async ( user: userDetails, commentReq: query, id: savedObjectID, + casesClientInternal, }); - if ( - (newComment.attributes.type === CommentType.alert || - newComment.attributes.type === CommentType.generatedAlert) && - caseInfo.attributes.settings.syncAlerts - ) { - const alertsToUpdate = createAlertUpdateRequest({ - comment: query, - status: subCase.attributes.status, - }); - await casesClientInternal.alerts.updateStatus({ - alerts: alertsToUpdate, - }); - } - await userActionService.bulkCreate({ unsecuredSavedObjectsClient, actions: [ @@ -386,19 +368,9 @@ export const addComment = async ( user: userInfo, commentReq: query, id: savedObjectID, + casesClientInternal, }); - if (newComment.attributes.type === CommentType.alert && updatedCase.settings.syncAlerts) { - const alertsToUpdate = createAlertUpdateRequest({ - comment: query, - status: updatedCase.status, - }); - - await casesClientInternal.alerts.updateStatus({ - alerts: alertsToUpdate, - }); - } - await userActionService.bulkCreate({ unsecuredSavedObjectsClient, actions: [ diff --git a/x-pack/plugins/cases/server/client/cases/push.ts b/x-pack/plugins/cases/server/client/cases/push.ts index 3048cf01bb3ba..80e69d53e9e8b 100644 --- a/x-pack/plugins/cases/server/client/cases/push.ts +++ b/x-pack/plugins/cases/server/client/cases/push.ts @@ -6,7 +6,7 @@ */ import Boom from '@hapi/boom'; -import { SavedObjectsFindResponse, SavedObject } from 'kibana/server'; +import { SavedObjectsFindResponse, SavedObject, Logger } from 'kibana/server'; import { ActionConnector, @@ -22,26 +22,16 @@ import { import { buildCaseUserActionItem } from '../../services/user_actions/helpers'; import { createIncident, getCommentContextFromAttributes } from './utils'; -import { createCaseError, flattenCaseSavedObject, getAlertInfoFromComments } from '../../common'; +import { + AlertInfo, + createCaseError, + flattenCaseSavedObject, + getAlertInfoFromComments, +} from '../../common'; import { CasesClient, CasesClientArgs, CasesClientInternal } from '..'; import { Operations } from '../../authorization'; import { casesConnectors } from '../../connectors'; - -/** - * Returns true if the case should be closed based on the configuration settings and whether the case - * is a collection. Collections are not closable because we aren't allowing their status to be changed. - * In the future we could allow push to close all the sub cases of a collection but that's not currently supported. - */ -function shouldCloseByPush( - configureSettings: SavedObjectsFindResponse, - caseInfo: SavedObject -): boolean { - return ( - configureSettings.total > 0 && - configureSettings.saved_objects[0].attributes.closure_type === 'close-by-pushing' && - caseInfo.attributes.type !== CaseType.collection - ); -} +import { CasesClientGetAlertsResponse } from '../alerts/types'; /** * Parameters for pushing a case to an external system @@ -106,9 +96,7 @@ export const push = async ( const alertsInfo = getAlertInfoFromComments(theCase?.comments); - const alerts = await casesClientInternal.alerts.get({ - alertsInfo, - }); + const alerts = await getAlertsCatchErrors({ casesClientInternal, alertsInfo, logger }); const getMappingsResponse = await casesClientInternal.configuration.getMappings({ connector: theCase.connector, @@ -278,3 +266,38 @@ export const push = async ( throw createCaseError({ message: `Failed to push case: ${error}`, error, logger }); } }; + +async function getAlertsCatchErrors({ + casesClientInternal, + alertsInfo, + logger, +}: { + casesClientInternal: CasesClientInternal; + alertsInfo: AlertInfo[]; + logger: Logger; +}): Promise { + try { + return await casesClientInternal.alerts.get({ + alertsInfo, + }); + } catch (error) { + logger.error(`Failed to retrieve alerts during push: ${error}`); + return []; + } +} + +/** + * Returns true if the case should be closed based on the configuration settings and whether the case + * is a collection. Collections are not closable because we aren't allowing their status to be changed. + * In the future we could allow push to close all the sub cases of a collection but that's not currently supported. + */ +function shouldCloseByPush( + configureSettings: SavedObjectsFindResponse, + caseInfo: SavedObject +): boolean { + return ( + configureSettings.total > 0 && + configureSettings.saved_objects[0].attributes.closure_type === 'close-by-pushing' && + caseInfo.attributes.type !== CaseType.collection + ); +} diff --git a/x-pack/plugins/cases/server/client/cases/update.ts b/x-pack/plugins/cases/server/client/cases/update.ts index ed19444414d57..611c9e09fa76e 100644 --- a/x-pack/plugins/cases/server/client/cases/update.ts +++ b/x-pack/plugins/cases/server/client/cases/update.ts @@ -12,6 +12,7 @@ import { fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; import { + Logger, SavedObject, SavedObjectsClientContract, SavedObjectsFindResponse, @@ -307,12 +308,14 @@ async function updateAlerts({ caseService, unsecuredSavedObjectsClient, casesClientInternal, + logger, }: { casesWithSyncSettingChangedToOn: UpdateRequestWithOriginalCase[]; casesWithStatusChangedAndSynced: UpdateRequestWithOriginalCase[]; caseService: CasesService; unsecuredSavedObjectsClient: SavedObjectsClientContract; casesClientInternal: CasesClientInternal; + logger: Logger; }) { /** * It's possible that a case ID can appear multiple times in each array. I'm intentionally placing the status changes @@ -361,7 +364,9 @@ async function updateAlerts({ [] ); - await casesClientInternal.alerts.updateStatus({ alerts: alertsToUpdate }); + await casesClientInternal.alerts.updateStatus({ + alerts: alertsToUpdate, + }); } function partitionPatchRequest( @@ -562,15 +567,6 @@ export const update = async ( ); }); - // Update the alert's status to match any case status or sync settings changes - await updateAlerts({ - casesWithStatusChangedAndSynced, - casesWithSyncSettingChangedToOn, - caseService, - unsecuredSavedObjectsClient, - casesClientInternal, - }); - const returnUpdatedCase = myCases.saved_objects .filter((myCase) => updatedCases.saved_objects.some((updatedCase) => updatedCase.id === myCase.id) @@ -598,6 +594,17 @@ export const update = async ( }), }); + // Update the alert's status to match any case status or sync settings changes + // Attempt to do this after creating/changing the other entities just in case it fails + await updateAlerts({ + casesWithStatusChangedAndSynced, + casesWithSyncSettingChangedToOn, + caseService, + unsecuredSavedObjectsClient, + casesClientInternal, + logger, + }); + return CasesResponseRt.encode(returnUpdatedCase); } catch (error) { const idVersions = cases.cases.map((caseInfo) => ({ diff --git a/x-pack/plugins/cases/server/client/factory.ts b/x-pack/plugins/cases/server/client/factory.ts index 2fae6996f4aa2..a1a3ccdd3bc52 100644 --- a/x-pack/plugins/cases/server/client/factory.ts +++ b/x-pack/plugins/cases/server/client/factory.ts @@ -5,12 +5,7 @@ * 2.0. */ -import { - KibanaRequest, - SavedObjectsServiceStart, - Logger, - ElasticsearchClient, -} from 'kibana/server'; +import { KibanaRequest, SavedObjectsServiceStart, Logger } from 'kibana/server'; import { SecurityPluginSetup, SecurityPluginStart } from '../../../security/server'; import { SAVED_OBJECT_TYPES } from '../../common'; import { Authorization } from '../authorization/authorization'; @@ -25,8 +20,8 @@ import { } from '../services'; import { PluginStartContract as FeaturesPluginStart } from '../../../features/server'; import { PluginStartContract as ActionsPluginStart } from '../../../actions/server'; +import { RuleRegistryPluginStartContract } from '../../../rule_registry/server'; import { LensServerPluginSetup } from '../../../lens/server'; - import { AuthorizationAuditLogger } from '../authorization'; import { CasesClient, createCasesClient } from '.'; @@ -36,6 +31,7 @@ interface CasesClientFactoryArgs { getSpace: GetSpaceFn; featuresPluginStart: FeaturesPluginStart; actionsPluginStart: ActionsPluginStart; + ruleRegistryPluginStart?: RuleRegistryPluginStartContract; lensEmbeddableFactory: LensServerPluginSetup['lensEmbeddableFactory']; } @@ -69,12 +65,10 @@ export class CasesClientFactory { */ public async create({ request, - scopedClusterClient, savedObjectsService, }: { request: KibanaRequest; savedObjectsService: SavedObjectsServiceStart; - scopedClusterClient: ElasticsearchClient; }): Promise { if (!this.isInitialized || !this.options) { throw new Error('CasesClientFactory must be initialized before calling create'); @@ -94,9 +88,12 @@ export class CasesClientFactory { const caseService = new CasesService(this.logger, this.options?.securityPluginStart?.authc); const userInfo = caseService.getUser({ request }); + const alertsClient = await this.options.ruleRegistryPluginStart?.getRacClientWithRequest( + request + ); + return createCasesClient({ - alertsService: new AlertService(), - scopedClusterClient, + alertsService: new AlertService(alertsClient), unsecuredSavedObjectsClient: savedObjectsService.getScopedClient(request, { includedHiddenTypes: SAVED_OBJECT_TYPES, // this tells the security plugin to not perform SO authorization and audit logging since we are handling diff --git a/x-pack/plugins/cases/server/client/sub_cases/update.ts b/x-pack/plugins/cases/server/client/sub_cases/update.ts index c8cb96cbb6b8c..56610ea6858e3 100644 --- a/x-pack/plugins/cases/server/client/sub_cases/update.ts +++ b/x-pack/plugins/cases/server/client/sub_cases/update.ts @@ -246,7 +246,9 @@ async function updateAlerts({ [] ); - await casesClientInternal.alerts.updateStatus({ alerts: alertsToUpdate }); + await casesClientInternal.alerts.updateStatus({ + alerts: alertsToUpdate, + }); } catch (error) { throw createCaseError({ message: `Failed to update alert status while updating sub cases: ${JSON.stringify( @@ -355,14 +357,6 @@ export async function update({ ); }); - await updateAlerts({ - caseService, - unsecuredSavedObjectsClient, - casesClientInternal, - subCasesToSync: subCasesToSyncAlertsFor, - logger: clientArgs.logger, - }); - const returnUpdatedSubCases = updatedCases.saved_objects.reduce( (acc, updatedSO) => { const originalSubCase = subCasesMap.get(updatedSO.id); @@ -394,6 +388,15 @@ export async function update({ }), }); + // attempt to update the status of the alerts after creating all the user actions just in case it fails + await updateAlerts({ + caseService, + unsecuredSavedObjectsClient, + casesClientInternal, + subCasesToSync: subCasesToSyncAlertsFor, + logger: clientArgs.logger, + }); + return SubCasesResponseRt.encode(returnUpdatedSubCases); } catch (error) { const idVersions = query.subCases.map((subCase) => ({ diff --git a/x-pack/plugins/cases/server/client/types.ts b/x-pack/plugins/cases/server/client/types.ts index 27829d2539c7d..3979c19949d9a 100644 --- a/x-pack/plugins/cases/server/client/types.ts +++ b/x-pack/plugins/cases/server/client/types.ts @@ -6,7 +6,7 @@ */ import type { PublicMethodsOf } from '@kbn/utility-types'; -import { ElasticsearchClient, SavedObjectsClientContract, Logger } from 'kibana/server'; +import { SavedObjectsClientContract, Logger } from 'kibana/server'; import { User } from '../../common'; import { Authorization } from '../authorization/authorization'; import { @@ -24,7 +24,6 @@ import { LensServerPluginSetup } from '../../../lens/server'; * Parameters for initializing a cases client */ export interface CasesClientArgs { - readonly scopedClusterClient: ElasticsearchClient; readonly caseConfigureService: CaseConfigureService; readonly caseService: CasesService; readonly connectorMappingsService: ConnectorMappingsService; diff --git a/x-pack/plugins/cases/server/common/models/commentable_case.ts b/x-pack/plugins/cases/server/common/models/commentable_case.ts index 856d6378d5900..e540332b1ff84 100644 --- a/x-pack/plugins/cases/server/common/models/commentable_case.ts +++ b/x-pack/plugins/cases/server/common/models/commentable_case.ts @@ -34,10 +34,16 @@ import { CommentRequestUserType, CaseAttributes, } from '../../../common'; -import { flattenCommentSavedObjects, flattenSubCaseSavedObject, transformNewComment } from '..'; +import { + createAlertUpdateRequest, + flattenCommentSavedObjects, + flattenSubCaseSavedObject, + transformNewComment, +} from '..'; import { AttachmentService, CasesService } from '../../services'; import { createCaseError } from '../error'; import { countAlertsForID } from '../index'; +import { CasesClientInternal } from '../../client'; import { getOrUpdateLensReferences } from '../utils'; interface UpdateCommentResp { @@ -273,11 +279,13 @@ export class CommentableCase { user, commentReq, id, + casesClientInternal, }: { createdDate: string; user: User; commentReq: CommentRequest; id: string; + casesClientInternal: CasesClientInternal; }): Promise { try { if (commentReq.type === CommentType.alert) { @@ -294,6 +302,10 @@ export class CommentableCase { throw Boom.badRequest('The owner field of the comment must match the case'); } + // Let's try to sync the alert's status before creating the attachment, that way if the alert doesn't exist + // we'll throw an error early before creating the attachment + await this.syncAlertStatus(commentReq, casesClientInternal); + let references = this.buildRefsToCase(); if (commentReq.type === CommentType.user && commentReq?.comment) { @@ -331,6 +343,26 @@ export class CommentableCase { } } + private async syncAlertStatus( + commentRequest: CommentRequest, + casesClientInternal: CasesClientInternal + ) { + if ( + (commentRequest.type === CommentType.alert || + commentRequest.type === CommentType.generatedAlert) && + this.settings.syncAlerts + ) { + const alertsToUpdate = createAlertUpdateRequest({ + comment: commentRequest, + status: this.status, + }); + + await casesClientInternal.alerts.updateStatus({ + alerts: alertsToUpdate, + }); + } + } + private formatCollectionForEncoding(totalComment: number) { return { id: this.collection.id, diff --git a/x-pack/plugins/cases/server/connectors/servicenow/sir_format.test.ts b/x-pack/plugins/cases/server/connectors/servicenow/sir_format.test.ts index fa103d4c1142d..7a1efe8b366d0 100644 --- a/x-pack/plugins/cases/server/connectors/servicenow/sir_format.test.ts +++ b/x-pack/plugins/cases/server/connectors/servicenow/sir_format.test.ts @@ -24,7 +24,7 @@ describe('ITSM formatter', () => { } as CaseResponse; it('it formats correctly without alerts', async () => { - const res = await format(theCase, []); + const res = format(theCase, []); expect(res).toEqual({ dest_ip: null, source_ip: null, @@ -38,7 +38,7 @@ describe('ITSM formatter', () => { it('it formats correctly when fields do not exist ', async () => { const invalidFields = { connector: { fields: null } } as CaseResponse; - const res = await format(invalidFields, []); + const res = format(invalidFields, []); expect(res).toEqual({ dest_ip: null, source_ip: null, @@ -55,25 +55,31 @@ describe('ITSM formatter', () => { { id: 'alert-1', index: 'index-1', - destination: { ip: '192.168.1.1' }, - source: { ip: '192.168.1.2' }, - file: { - hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + source: { + destination: { ip: '192.168.1.1' }, + source: { ip: '192.168.1.2' }, + file: { + hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + }, + url: { full: 'https://attack.com' }, }, - url: { full: 'https://attack.com' }, }, { id: 'alert-2', index: 'index-2', - destination: { ip: '192.168.1.4' }, - source: { ip: '192.168.1.3' }, - file: { - hash: { sha256: '60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752' }, + source: { + source: { + ip: '192.168.1.3', + }, + destination: { ip: '192.168.1.4' }, + file: { + hash: { sha256: '60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752' }, + }, + url: { full: 'https://attack.com/api' }, }, - url: { full: 'https://attack.com/api' }, }, ]; - const res = await format(theCase, alerts); + const res = format(theCase, alerts); expect(res).toEqual({ dest_ip: '192.168.1.1,192.168.1.4', source_ip: '192.168.1.2,192.168.1.3', @@ -86,30 +92,109 @@ describe('ITSM formatter', () => { }); }); + it('it ignores alerts with an error', async () => { + const alerts = [ + { + id: 'alert-1', + index: 'index-1', + error: new Error('an error'), + source: { + destination: { ip: '192.168.1.1' }, + source: { ip: '192.168.1.2' }, + file: { + hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + }, + url: { full: 'https://attack.com' }, + }, + }, + { + id: 'alert-2', + index: 'index-2', + source: { + source: { + ip: '192.168.1.3', + }, + destination: { ip: '192.168.1.4' }, + file: { + hash: { sha256: '60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752' }, + }, + url: { full: 'https://attack.com/api' }, + }, + }, + ]; + const res = format(theCase, alerts); + expect(res).toEqual({ + dest_ip: '192.168.1.4', + source_ip: '192.168.1.3', + category: 'Denial of Service', + subcategory: 'Inbound DDos', + malware_hash: '60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752', + malware_url: 'https://attack.com/api', + priority: '2 - High', + }); + }); + + it('it ignores alerts without a source field', async () => { + const alerts = [ + { + id: 'alert-1', + index: 'index-1', + }, + { + id: 'alert-2', + index: 'index-2', + source: { + source: { + ip: '192.168.1.3', + }, + destination: { ip: '192.168.1.4' }, + file: { + hash: { sha256: '60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752' }, + }, + url: { full: 'https://attack.com/api' }, + }, + }, + ]; + const res = format(theCase, alerts); + expect(res).toEqual({ + dest_ip: '192.168.1.4', + source_ip: '192.168.1.3', + category: 'Denial of Service', + subcategory: 'Inbound DDos', + malware_hash: '60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752', + malware_url: 'https://attack.com/api', + priority: '2 - High', + }); + }); + it('it handles duplicates correctly', async () => { const alerts = [ { id: 'alert-1', index: 'index-1', - destination: { ip: '192.168.1.1' }, - source: { ip: '192.168.1.2' }, - file: { - hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + source: { + destination: { ip: '192.168.1.1' }, + source: { ip: '192.168.1.2' }, + file: { + hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + }, + url: { full: 'https://attack.com' }, }, - url: { full: 'https://attack.com' }, }, { id: 'alert-2', index: 'index-2', - destination: { ip: '192.168.1.1' }, - source: { ip: '192.168.1.3' }, - file: { - hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + source: { + destination: { ip: '192.168.1.1' }, + source: { ip: '192.168.1.3' }, + file: { + hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + }, + url: { full: 'https://attack.com/api' }, }, - url: { full: 'https://attack.com/api' }, }, ]; - const res = await format(theCase, alerts); + const res = format(theCase, alerts); expect(res).toEqual({ dest_ip: '192.168.1.1', source_ip: '192.168.1.2,192.168.1.3', @@ -126,22 +211,26 @@ describe('ITSM formatter', () => { { id: 'alert-1', index: 'index-1', - destination: { ip: '192.168.1.1' }, - source: { ip: '192.168.1.2' }, - file: { - hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + source: { + destination: { ip: '192.168.1.1' }, + source: { ip: '192.168.1.2' }, + file: { + hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + }, + url: { full: 'https://attack.com' }, }, - url: { full: 'https://attack.com' }, }, { id: 'alert-2', index: 'index-2', - destination: { ip: '192.168.1.1' }, - source: { ip: '192.168.1.3' }, - file: { - hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + source: { + destination: { ip: '192.168.1.1' }, + source: { ip: '192.168.1.3' }, + file: { + hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' }, + }, + url: { full: 'https://attack.com/api' }, }, - url: { full: 'https://attack.com/api' }, }, ]; @@ -150,7 +239,7 @@ describe('ITSM formatter', () => { connector: { fields: { ...theCase.connector.fields, destIp: false, malwareHash: false } }, } as CaseResponse; - const res = await format(newCase, alerts); + const res = format(newCase, alerts); expect(res).toEqual({ dest_ip: null, source_ip: '192.168.1.2,192.168.1.3', diff --git a/x-pack/plugins/cases/server/connectors/servicenow/sir_format.ts b/x-pack/plugins/cases/server/connectors/servicenow/sir_format.ts index b48a1b7f734c8..88b8f79d3ba5b 100644 --- a/x-pack/plugins/cases/server/connectors/servicenow/sir_format.ts +++ b/x-pack/plugins/cases/server/connectors/servicenow/sir_format.ts @@ -44,23 +44,25 @@ export const format: ServiceNowSIRFormat = (theCase, alerts) => { ); if (fieldsToAdd.length > 0) { - sirFields = alerts.reduce>((acc, alert) => { - fieldsToAdd.forEach((alertField) => { - const field = get(alertFieldMapping[alertField].alertPath, alert); - if (field && !manageDuplicate[alertFieldMapping[alertField].sirFieldKey].has(field)) { - manageDuplicate[alertFieldMapping[alertField].sirFieldKey].add(field); - acc = { - ...acc, - [alertFieldMapping[alertField].sirFieldKey]: `${ - acc[alertFieldMapping[alertField].sirFieldKey] != null - ? `${acc[alertFieldMapping[alertField].sirFieldKey]},${field}` - : field - }`, - }; - } - }); - return acc; - }, sirFields); + sirFields = alerts + .filter((alert) => !alert.error && alert.source != null) + .reduce>((acc, alert) => { + fieldsToAdd.forEach((alertField) => { + const field = get(alertFieldMapping[alertField].alertPath, alert.source); + if (field && !manageDuplicate[alertFieldMapping[alertField].sirFieldKey].has(field)) { + manageDuplicate[alertFieldMapping[alertField].sirFieldKey].add(field); + acc = { + ...acc, + [alertFieldMapping[alertField].sirFieldKey]: `${ + acc[alertFieldMapping[alertField].sirFieldKey] != null + ? `${acc[alertFieldMapping[alertField].sirFieldKey]},${field}` + : field + }`, + }; + } + }); + return acc; + }, sirFields); } return { diff --git a/x-pack/plugins/cases/server/plugin.ts b/x-pack/plugins/cases/server/plugin.ts index bb1be163585a8..49220fc716034 100644 --- a/x-pack/plugins/cases/server/plugin.ts +++ b/x-pack/plugins/cases/server/plugin.ts @@ -32,6 +32,7 @@ import type { CasesRequestHandlerContext } from './types'; import { CasesClientFactory } from './client/factory'; import { SpacesPluginStart } from '../../spaces/server'; import { PluginStartContract as FeaturesPluginStart } from '../../features/server'; +import { RuleRegistryPluginStartContract } from '../../rule_registry/server'; import { LensServerPluginSetup } from '../../lens/server'; function createConfig(context: PluginInitializerContext) { @@ -49,6 +50,7 @@ export interface PluginsStart { features: FeaturesPluginStart; spaces?: SpacesPluginStart; actions: ActionsPluginStart; + ruleRegistry?: RuleRegistryPluginStartContract; } /** @@ -137,15 +139,13 @@ export class CasePlugin { }, featuresPluginStart: plugins.features, actionsPluginStart: plugins.actions, + ruleRegistryPluginStart: plugins.ruleRegistry, lensEmbeddableFactory: this.lensEmbeddableFactory!, }); - const client = core.elasticsearch.client; - const getCasesClientWithRequest = async (request: KibanaRequest): Promise => { return this.clientFactory.create({ request, - scopedClusterClient: client.asScoped(request).asCurrentUser, savedObjectsService: core.savedObjects, }); }; @@ -171,7 +171,6 @@ export class CasePlugin { return this.clientFactory.create({ request, - scopedClusterClient: context.core.elasticsearch.client.asCurrentUser, savedObjectsService: savedObjects, }); }, diff --git a/x-pack/plugins/cases/server/services/alerts/index.test.ts b/x-pack/plugins/cases/server/services/alerts/index.test.ts index 28c3a6278d544..0e1ad03a32af2 100644 --- a/x-pack/plugins/cases/server/services/alerts/index.test.ts +++ b/x-pack/plugins/cases/server/services/alerts/index.test.ts @@ -5,56 +5,75 @@ * 2.0. */ -import { KibanaRequest } from 'kibana/server'; import { CaseStatuses } from '../../../common'; import { AlertService, AlertServiceContract } from '.'; -import { elasticsearchServiceMock, loggingSystemMock } from 'src/core/server/mocks'; +import { loggingSystemMock } from 'src/core/server/mocks'; +import { ruleRegistryMocks } from '../../../../rule_registry/server/mocks'; +import { AlertsClient } from '../../../../rule_registry/server'; +import { PublicMethodsOf } from '@kbn/utility-types'; describe('updateAlertsStatus', () => { - const esClient = elasticsearchServiceMock.createElasticsearchClient(); const logger = loggingSystemMock.create().get('case'); + let alertsClient: jest.Mocked>; + let alertService: AlertServiceContract; + + beforeEach(async () => { + alertsClient = ruleRegistryMocks.createAlertsClientMock.create(); + alertService = new AlertService(alertsClient); + jest.restoreAllMocks(); + }); describe('happy path', () => { - let alertService: AlertServiceContract; const args = { alerts: [{ id: 'alert-id-1', index: '.siem-signals', status: CaseStatuses.closed }], - request: {} as KibanaRequest, - scopedClusterClient: esClient, logger, }; - beforeEach(async () => { - alertService = new AlertService(); - jest.restoreAllMocks(); + it('updates the status of the alert correctly', async () => { + await alertService.updateAlertsStatus(args); + + expect(alertsClient.update).toHaveBeenCalledWith({ + id: 'alert-id-1', + index: '.siem-signals', + status: CaseStatuses.closed, + }); }); - test('it update the status of the alert correctly', async () => { - await alertService.updateAlertsStatus(args); + it('translates the in-progress status to acknowledged', async () => { + await alertService.updateAlertsStatus({ + alerts: [{ id: 'alert-id-1', index: '.siem-signals', status: CaseStatuses['in-progress'] }], + logger, + }); - expect(esClient.bulk).toHaveBeenCalledWith({ - body: [ - { update: { _id: 'alert-id-1', _index: '.siem-signals' } }, - { - doc: { - signal: { - status: CaseStatuses.closed, - }, - }, - }, - ], + expect(alertsClient.update).toHaveBeenCalledWith({ + id: 'alert-id-1', + index: '.siem-signals', + status: 'acknowledged', }); }); - describe('unhappy path', () => { - it('ignores empty indices', async () => { - expect( - await alertService.updateAlertsStatus({ - alerts: [{ id: 'alert-id-1', index: '', status: CaseStatuses.closed }], - scopedClusterClient: esClient, - logger, - }) - ).toBeUndefined(); + it('defaults an unknown status to open', async () => { + await alertService.updateAlertsStatus({ + alerts: [{ id: 'alert-id-1', index: '.siem-signals', status: 'bananas' as CaseStatuses }], + logger, + }); + + expect(alertsClient.update).toHaveBeenCalledWith({ + id: 'alert-id-1', + index: '.siem-signals', + status: 'open', }); }); }); + + describe('unhappy path', () => { + it('ignores empty indices', async () => { + expect( + await alertService.updateAlertsStatus({ + alerts: [{ id: 'alert-id-1', index: '', status: CaseStatuses.closed }], + logger, + }) + ).toBeUndefined(); + }); + }); }); diff --git a/x-pack/plugins/cases/server/services/alerts/index.ts b/x-pack/plugins/cases/server/services/alerts/index.ts index e33b0385bc123..ccb0fca4f995f 100644 --- a/x-pack/plugins/cases/server/services/alerts/index.ts +++ b/x-pack/plugins/cases/server/services/alerts/index.ts @@ -9,56 +9,67 @@ import { isEmpty } from 'lodash'; import type { PublicMethodsOf } from '@kbn/utility-types'; -import { ElasticsearchClient, Logger } from 'kibana/server'; -import { MAX_ALERTS_PER_SUB_CASE } from '../../../common'; +import { Logger } from 'kibana/server'; +import { CaseStatuses, MAX_ALERTS_PER_SUB_CASE } from '../../../common'; import { AlertInfo, createCaseError } from '../../common'; import { UpdateAlertRequest } from '../../client/alerts/types'; +import { AlertsClient } from '../../../../rule_registry/server'; +import { Alert } from './types'; +import { STATUS_VALUES } from '../../../../rule_registry/common/technical_rule_data_field_names'; export type AlertServiceContract = PublicMethodsOf; interface UpdateAlertsStatusArgs { alerts: UpdateAlertRequest[]; - scopedClusterClient: ElasticsearchClient; logger: Logger; } interface GetAlertsArgs { alertsInfo: AlertInfo[]; - scopedClusterClient: ElasticsearchClient; logger: Logger; } -interface Alert { - _id: string; - _index: string; - _source: Record; -} - -interface AlertsResponse { - docs: Alert[]; -} - function isEmptyAlert(alert: AlertInfo): boolean { return isEmpty(alert.id) || isEmpty(alert.index); } export class AlertService { - constructor() {} + constructor(private readonly alertsClient?: PublicMethodsOf) {} - public async updateAlertsStatus({ alerts, scopedClusterClient, logger }: UpdateAlertsStatusArgs) { + public async updateAlertsStatus({ alerts, logger }: UpdateAlertsStatusArgs) { try { - const body = alerts - .filter((alert) => !isEmptyAlert(alert)) - .flatMap((alert) => [ - { update: { _id: alert.id, _index: alert.index } }, - { doc: { signal: { status: alert.status } } }, - ]); - - if (body.length <= 0) { + if (!this.alertsClient) { + throw new Error( + 'Alert client is undefined, the rule registry plugin must be enabled to updated the status of alerts' + ); + } + + const alertsToUpdate = alerts.filter((alert) => !isEmptyAlert(alert)); + + if (alertsToUpdate.length <= 0) { return; } - return scopedClusterClient.bulk({ body }); + const updatedAlerts = await Promise.allSettled( + alertsToUpdate.map((alert) => + this.alertsClient?.update({ + id: alert.id, + index: alert.index, + status: translateStatus({ alert, logger }), + _version: undefined, + }) + ) + ); + + updatedAlerts.forEach((updatedAlert, index) => { + if (updatedAlert.status === 'rejected') { + logger.error( + `Failed to update status for alert: ${JSON.stringify(alertsToUpdate[index])}: ${ + updatedAlert.reason + }` + ); + } + }); } catch (error) { throw createCaseError({ message: `Failed to update alert status ids: ${JSON.stringify(alerts)}: ${error}`, @@ -68,25 +79,51 @@ export class AlertService { } } - public async getAlerts({ - scopedClusterClient, - alertsInfo, - logger, - }: GetAlertsArgs): Promise { + public async getAlerts({ alertsInfo, logger }: GetAlertsArgs): Promise { try { - const docs = alertsInfo - .filter((alert) => !isEmptyAlert(alert)) - .slice(0, MAX_ALERTS_PER_SUB_CASE) - .map((alert) => ({ _id: alert.id, _index: alert.index })); + if (!this.alertsClient) { + throw new Error( + 'Alert client is undefined, the rule registry plugin must be enabled to retrieve alerts' + ); + } - if (docs.length <= 0) { + const alertsToGet = alertsInfo + .filter((alert) => !isEmpty(alert)) + .slice(0, MAX_ALERTS_PER_SUB_CASE); + + if (alertsToGet.length <= 0) { return; } - const results = await scopedClusterClient.mget({ body: { docs } }); + const retrievedAlerts = await Promise.allSettled( + alertsToGet.map(({ id, index }) => this.alertsClient?.get({ id, index })) + ); + + retrievedAlerts.forEach((alert, index) => { + if (alert.status === 'rejected') { + logger.error( + `Failed to retrieve alert: ${JSON.stringify(alertsToGet[index])}: ${alert.reason}` + ); + } + }); - // @ts-expect-error @elastic/elasticsearch _source is optional - return results.body; + return retrievedAlerts.map((alert, index) => { + let source: unknown | undefined; + let error: Error | undefined; + + if (alert.status === 'fulfilled') { + source = alert.value; + } else { + error = alert.reason; + } + + return { + id: alertsToGet[index].id, + index: alertsToGet[index].index, + source, + error, + }; + }); } catch (error) { throw createCaseError({ message: `Failed to retrieve alerts ids: ${JSON.stringify(alertsInfo)}: ${error}`, @@ -96,3 +133,27 @@ export class AlertService { } } } + +function translateStatus({ + alert, + logger, +}: { + alert: UpdateAlertRequest; + logger: Logger; +}): STATUS_VALUES { + const translatedStatuses: Record = { + [CaseStatuses.open]: 'open', + [CaseStatuses['in-progress']]: 'acknowledged', + [CaseStatuses.closed]: 'closed', + }; + + const translatedStatus = translatedStatuses[alert.status]; + if (!translatedStatus) { + logger.error( + `Unable to translate case status ${alert.status} during alert update: ${JSON.stringify( + alert + )}` + ); + } + return translatedStatus ?? 'open'; +} diff --git a/x-pack/plugins/cases/server/services/alerts/types.ts b/x-pack/plugins/cases/server/services/alerts/types.ts new file mode 100644 index 0000000000000..5ddc57fa5861c --- /dev/null +++ b/x-pack/plugins/cases/server/services/alerts/types.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface Alert { + id: string; + index: string; + error?: Error; + source?: unknown; +} diff --git a/x-pack/plugins/cases/tsconfig.json b/x-pack/plugins/cases/tsconfig.json index 1c9373e023366..d7c123ce3970b 100644 --- a/x-pack/plugins/cases/tsconfig.json +++ b/x-pack/plugins/cases/tsconfig.json @@ -22,6 +22,7 @@ // Required from './kibana.json' { "path": "../actions/tsconfig.json" }, + { "path": "../rule_registry/tsconfig.json" }, { "path": "../triggers_actions_ui/tsconfig.json"}, { "path": "../../../src/plugins/es_ui_shared/tsconfig.json" }, { "path": "../../../src/plugins/kibana_react/tsconfig.json" }, diff --git a/x-pack/plugins/rule_registry/server/index.ts b/x-pack/plugins/rule_registry/server/index.ts index 19257845fabe4..2a609aa3bef7e 100644 --- a/x-pack/plugins/rule_registry/server/index.ts +++ b/x-pack/plugins/rule_registry/server/index.ts @@ -29,6 +29,7 @@ export { } from './utils/create_lifecycle_executor'; export { createPersistenceRuleTypeFactory } from './utils/create_persistence_rule_type_factory'; export * from './utils/persistence_types'; +export type { AlertsClient } from './alert_data_client/alerts_client'; export const plugin = (initContext: PluginInitializerContext) => new RuleRegistryPlugin(initContext); diff --git a/x-pack/plugins/rule_registry/server/mocks.ts b/x-pack/plugins/rule_registry/server/mocks.ts index 395b53e229d64..269eff182633f 100644 --- a/x-pack/plugins/rule_registry/server/mocks.ts +++ b/x-pack/plugins/rule_registry/server/mocks.ts @@ -5,10 +5,12 @@ * 2.0. */ +import { alertsClientMock } from './alert_data_client/alerts_client.mock'; import { ruleDataPluginServiceMock } from './rule_data_plugin_service/rule_data_plugin_service.mock'; import { createLifecycleAlertServicesMock } from './utils/lifecycle_alert_services_mock'; export const ruleRegistryMocks = { createLifecycleAlertServices: createLifecycleAlertServicesMock, createRuleDataPluginService: ruleDataPluginServiceMock.create, + createAlertsClientMock: alertsClientMock, }; diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts index e2a7512940250..63b2f2e9b90ed 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts @@ -535,8 +535,8 @@ export default ({ getService }: FtrProviderContext): void => { }); it('should update the status of multiple alerts attached to multiple cases', async () => { - const signalID = '5f2b9ec41f8febb1c06b5d1045aeabb9874733b7617e88a370510f2fb3a41a5d'; - const signalID2 = '4d0f4b1533e46b66b43bdd0330d23f39f2cf42a7253153270e38d30cce9ff0c6'; + const signalID = '4679431ee0ba3209b6fcd60a255a696886fe0a7d18f5375de510ff5b68fa6b78'; + const signalID2 = '1023bcfea939643c5e51fd8df53797e0ea693cee547db579ab56d96402365c1e'; // does NOT updates alert status when adding comments and syncAlerts=false const individualCase1 = await createCase(supertest, { @@ -653,7 +653,7 @@ export default ({ getService }: FtrProviderContext): void => { CaseStatuses.closed ); expect(signals.get(defaultSignalsIndex)?.get(signalID2)?._source?.signal.status).to.be( - CaseStatuses['in-progress'] + 'acknowledged' ); }); }); @@ -846,7 +846,7 @@ export default ({ getService }: FtrProviderContext): void => { .send(getQuerySignalIds([alert._id])) .expect(200); - expect(updatedAlert.hits.hits[0]._source?.signal.status).eql('in-progress'); + expect(updatedAlert.hits.hits[0]._source?.signal.status).eql('acknowledged'); }); it('does NOT updates alert status when the status is updated and syncAlerts=false', async () => { @@ -970,7 +970,7 @@ export default ({ getService }: FtrProviderContext): void => { .send(getQuerySignalIds([alert._id])) .expect(200); - expect(updatedAlert.hits.hits[0]._source?.signal.status).eql('in-progress'); + expect(updatedAlert.hits.hits[0]._source?.signal.status).eql('acknowledged'); }); it('it does NOT updates alert status when syncAlerts is turned off', async () => { diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/common/client/update_alert_status.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/common/client/update_alert_status.ts index 15df0f0b40d0f..d2949c9728989 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/common/client/update_alert_status.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/common/client/update_alert_status.ts @@ -35,8 +35,8 @@ export default ({ getService }: FtrProviderContext): void => { }); it('should update the status of multiple alerts attached to multiple cases using the cases client', async () => { - const signalID = '5f2b9ec41f8febb1c06b5d1045aeabb9874733b7617e88a370510f2fb3a41a5d'; - const signalID2 = '4d0f4b1533e46b66b43bdd0330d23f39f2cf42a7253153270e38d30cce9ff0c6'; + const signalID = '4679431ee0ba3209b6fcd60a255a696886fe0a7d18f5375de510ff5b68fa6b78'; + const signalID2 = '1023bcfea939643c5e51fd8df53797e0ea693cee547db579ab56d96402365c1e'; // does NOT updates alert status when adding comments and syncAlerts=false const individualCase1 = await createCase(supertest, { @@ -160,7 +160,7 @@ export default ({ getService }: FtrProviderContext): void => { CaseStatuses.closed ); expect(signals.get(defaultSignalsIndex)?.get(signalID2)?._source?.signal.status).to.be( - CaseStatuses['in-progress'] + 'acknowledged' ); }); }); diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/common/comments/post_comment.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/common/comments/post_comment.ts index ecd05a2717e08..f4c31c052cddd 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/common/comments/post_comment.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/common/comments/post_comment.ts @@ -394,7 +394,7 @@ export default ({ getService }: FtrProviderContext): void => { .send(getQuerySignalIds([alert._id])) .expect(200); - expect(updatedAlert.hits.hits[0]._source.signal.status).eql('in-progress'); + expect(updatedAlert.hits.hits[0]._source.signal.status).eql('acknowledged'); }); it('should NOT change the status of the alert if sync alert is off', async () => { diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/common/sub_cases/patch_sub_cases.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/common/sub_cases/patch_sub_cases.ts index 45fada30ab567..340fdfbf77de1 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/common/sub_cases/patch_sub_cases.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/common/sub_cases/patch_sub_cases.ts @@ -129,7 +129,7 @@ export default function ({ getService }: FtrProviderContext) { signals = await getSignalsWithES({ es, indices: defaultSignalsIndex, ids: signalID }); expect(signals.get(defaultSignalsIndex)?.get(signalID)?._source?.signal.status).to.be( - CaseStatuses['in-progress'] + 'acknowledged' ); }); @@ -200,7 +200,7 @@ export default function ({ getService }: FtrProviderContext) { CaseStatuses['in-progress'] ); expect(signals.get(defaultSignalsIndex)?.get(signalID2)?._source?.signal.status).to.be( - CaseStatuses['in-progress'] + 'acknowledged' ); }); @@ -321,7 +321,7 @@ export default function ({ getService }: FtrProviderContext) { CaseStatuses.closed ); expect(signals.get(defaultSignalsIndex)?.get(signalID2)?._source?.signal.status).to.be( - CaseStatuses['in-progress'] + 'acknowledged' ); }); @@ -470,7 +470,7 @@ export default function ({ getService }: FtrProviderContext) { // alerts should be updated now that the expect(signals.get(defaultSignalsIndex)?.get(signalID)?._source?.signal.status).to.be( - CaseStatuses['in-progress'] + 'acknowledged' ); expect(signals.get(defaultSignalsIndex)?.get(signalID2)?._source?.signal.status).to.be( CaseStatuses.closed diff --git a/x-pack/test/functional/es_archives/cases/signals/default/data.json.gz b/x-pack/test/functional/es_archives/cases/signals/default/data.json.gz index 6caae322450e44b439e17bc8b6cf6445a4a9940c..51a1c96980e77311c8506a5f5311f88b6d0f1177 100644 GIT binary patch literal 3945 zcmV-v50>yBiwFq9d>UZ@17u-zVJ>QOZ*BnXomr3EwjIFV{V9ZfEW$BK@sgkFwkaAE zX@h!;An67Jp0l#0kyg^|RrtG?(pxJGQ~yHb=}+2*z3B(SsB|Dl<{IIlM)!~u~S6e5&n)uGlBT8oA$oGT-asR>R`7X5lUo3@yn6b zs_yYbuB!8SYAe|+GmXnKUM|}6(z3FPthn)&|Fe7QpKq7Ad-mIR{ez+~Bt$X?up=4} z!~8)}&OpdGw~RALjcyO+NA?0@&8U2YYcQw4#ap5uUqz+fQ4Uak^(Rqs(_ z^@>j>j;H%_FNd~dA!>iXNh>+jmayl9NT*~y>Zot@e1 zJjn`M%err`w^MO-GvC;e1;lA=)XKG|<7cT?l~hU7Uw;7|ZItDCf4Zrmjrv9sI)WWg5{H0z z^8{q*6mU}Gh&@ zh;<`_U6(tz-1w=srjDA6?HW+qJ{0jH_FFk0`ntz?yTkr&%;R+?_*k#^Fu&LGeCsuL zm2A}YjXS@g`#WSMcDq~$aN~2NGeU94Kj*R-Ig(L9yssEOyAU1{!Ow$rd;|LBdYP*fydUjbmu39|2x3t}&Yi*kj%6Squ;pgF1 zIG=#od7hPV6<^xpo8sc6vI9@it5al6w6e^uKm>cy%0`+wb;v~!I4dDQ$SM$V1AP=I zt&utkC8WJ}X}a^%&4fplx@VhYo`OGss*uZaed2!@$amqBsS@~#gCe;yai#oWfkBa1 ztA+R6!veoOcDzZWj)SK@mHT854B}%--)K{I*j+6Bd0aMuz)9HO>_jdXEAPST!cQyf z{ZY3#)^=GorQL#5Ue7m~c@utgE$v8<(K>aM_80OgR&wdHU!U*KWuDJhMKjy;s>n2q#!aW=ijl3VeC56NQP$9Ha?xy$uj_sNyY5+d ztLAJ`yTs#iUz@3UW2SsHj1H8|Q@_MIU^v>9U(zOSWz-OAu>z3u2oU8YPzE7DozLpH zq<(Is@4(l#a}5Hn#tZK?jY=+#FS$Cet=U~wvZ`wIcIgwMZdtam6XPEBVkok!+#I#I z(To%E>v)?Z7Iz;bqfrOG5B{>;E{B+8RobG*b+S~(jrp!FR;W?i6jPs_%oLh%8*#4Vbq0B&&}u%o*>->>4M&& zt{3=?LAs!Wy4r4e)U$QzU7lU}iJsde+3`CTtzHDbyP&98R9C7C$cFr`yM%iZJQ-5M z4fUxAWj@H#*a9JHiM9wb^Q`@n@t8I_^*c*nqmRjK!#oz99+B#c=2lB z-~-+5!yImKUpUzIx#M1U=y#t$2iY^w!8_&fwbH@Ypv{~5foa^h~=Dy#t=Iyef_nv%zJ!!%CgPqMn*QA2vux$XLD z)Ub4nii^@~&~a+mUcfz>q4SCqhCbFZ%F8%GUc^--EZ|T`LJ)Nk5yzR~p+WCK3=bUQ z011u(Lr$WBSiLY{`0-Wnj8_8;ALxM}=7WR#0>ic&9(Tk;SNsHE$e#fi-YJK#6&St_ z1$zQ8L=OXoA6;YxUzDqA0)`VXoPgm33|qw$Fr0wlu+3KjhH;fkMjSdX#(?48k3Ah2 zDq>vZe72w=VVp6;9CKl0Et6acV+3ji#$z;KkIH6<+y)pppU zKCcT5lTw!DjuxiHrx!sBbHWo{!Lh3Tu{7_SBtKG5?%%=ZTO1%++*JMMso zF8B$cP&@-Dyi*QeD=2&&3ibq0h#v+D&%^U`c3z|ePM~lCg%c>8Kw+zR0)-PO9JcvN zpzuZ;d=V+)+KRE0;JqJvhBphPw8EmuNMn(ch&ZFD)uB=@GR#PYkucIS7&(MP9)^k< z=%@%aq!DyG_V)!qVJjd#`F_jwIvc2EE>)a(pVU*kcD$jprHdDc-EEh=;E zja(VKSdS^jX4h*z;o`<_o%~!Q(K=8Z2v2>k8k|AV5W|eS}RhT#liQ~SpPCDT;NRt;%_w!nA9Q7{uWXh{ZU9NQFRKD82QT6hulJ zfJ6ud(JYj#W4)i}rYOzKI=3I4Sqo$lK4P1jM7-YX!Lc-3a2KZ^SeI_@IWV|=YonwI z>gKi>THL*@>3Z8{ng=88dm8_q>ECW$K6njzYxhy#61J`WjImyE&+LccVcT)Bl0G-D z;-$}uywTres!o2g!M-Ti79DEpXH&c15eib-G;aiYzPD0u>xXaaG3J{MYb?=dL?d-g z%bJ5g3`Yo4%pjrdUvjd+IY(+7dv&>9X+6K7e$dU+Hl}}HrFqh?voY_TTJ^Kh<)qv2 z;lNC{qB+={HpjhMuI1*#FCR|7|FKJJcYA!ShmGG32_62vgz36=x~~0ZuWOG7uV3B0 zRM{sx;!XCT;~%HN`+uMQ?Vtbp;q;f`)r1d28t#<%peJdJP$&i|bGO!RG3AY)?|>`j zMSST^-eQ2|#x^JzVD*1lFE82#GT5AT&cYgk@x5#pBvpxXiEd&z%J=g{_)n zX9}<8JD>;p--mhN;J)7hwVm*|8y-61$A1Sz&@-UBJLT}Teh2hA6zmJ3JarS?=GQ4H zE|#};0(%qKo50=#_FBag*qgxKu+3Nc4hY={A;>unJH%uw!FxY8iVOb-oKjw%B7^_{ D7lFVE literal 5586 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 diff --git a/x-pack/test/functional/es_archives/cases/signals/duplicate_ids/mappings.json b/x-pack/test/functional/es_archives/cases/signals/duplicate_ids/mappings.json index 97b2897150212..6ec0622bfce71 100644 --- a/x-pack/test/functional/es_archives/cases/signals/duplicate_ids/mappings.json +++ b/x-pack/test/functional/es_archives/cases/signals/duplicate_ids/mappings.json @@ -2,6 +2,9 @@ "type": "index", "value": { "aliases": { + ".alerts-security.alerts-default": { + "is_write_index": false + }, ".siem-signals-default": { "is_write_index": true } @@ -9,7 +12,8 @@ "index": ".siem-signals-default-000001", "mappings": { "_meta": { - "version": 14 + "aliases_version": 1, + "version": 55 }, "dynamic": "false", "properties": { @@ -18,6 +22,14 @@ }, "agent": { "properties": { + "build": { + "properties": { + "original": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "ephemeral_id": { "ignore_above": 1024, "type": "keyword" @@ -101,6 +113,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -120,6 +136,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -127,6 +147,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -157,6 +181,10 @@ "ignore_above": 1024, "type": "keyword" }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, "top_level_domain": { "ignore_above": 1024, "type": "keyword" @@ -214,6 +242,10 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" } } } @@ -226,6 +258,10 @@ "id": { "ignore_above": 1024, "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -253,6 +289,18 @@ } } }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "provider": { "ignore_above": 1024, "type": "keyword" @@ -260,6 +308,14 @@ "region": { "ignore_above": 1024, "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } } } }, @@ -315,6 +371,19 @@ } } }, + "data_stream": { + "properties": { + "dataset": { + "type": "keyword" + }, + "namespace": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + } + }, "destination": { "properties": { "address": { @@ -355,6 +424,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -374,6 +447,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -381,6 +458,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -411,6 +492,10 @@ "ignore_above": 1024, "type": "keyword" }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, "top_level_domain": { "ignore_above": 1024, "type": "keyword" @@ -468,6 +553,10 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" } } } @@ -480,6 +569,10 @@ "exists": { "type": "boolean" }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, "status": { "ignore_above": 1024, "type": "keyword" @@ -488,6 +581,10 @@ "ignore_above": 1024, "type": "keyword" }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, "trusted": { "type": "boolean" }, @@ -513,6 +610,10 @@ "sha512": { "ignore_above": 1024, "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -526,6 +627,10 @@ }, "pe": { "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, "company": { "ignore_above": 1024, "type": "keyword" @@ -538,6 +643,10 @@ "ignore_above": 1024, "type": "keyword" }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, "original_file_name": { "ignore_above": 1024, "type": "keyword" @@ -728,6 +837,10 @@ "ignore_above": 1024, "type": "keyword" }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, "reference": { "ignore_above": 1024, "type": "keyword" @@ -775,6 +888,10 @@ "exists": { "type": "boolean" }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, "status": { "ignore_above": 1024, "type": "keyword" @@ -783,6 +900,10 @@ "ignore_above": 1024, "type": "keyword" }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, "trusted": { "type": "boolean" }, @@ -838,6 +959,10 @@ "sha512": { "ignore_above": 1024, "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -876,6 +1001,10 @@ }, "pe": { "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, "company": { "ignore_above": 1024, "type": "keyword" @@ -888,6 +1017,10 @@ "ignore_above": 1024, "type": "keyword" }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, "original_file_name": { "ignore_above": 1024, "type": "keyword" @@ -918,6 +1051,112 @@ "uid": { "ignore_above": 1024, "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "doc_values": false, + "index": false, + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } } } }, @@ -998,6 +1237,32 @@ "ignore_above": 1024, "type": "keyword" }, + "cpu": { + "properties": { + "usage": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "disk": { + "properties": { + "read": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "write": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, "domain": { "ignore_above": 1024, "type": "keyword" @@ -1008,6 +1273,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -1027,6 +1296,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -1034,6 +1307,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -1056,6 +1333,30 @@ "ignore_above": 1024, "type": "keyword" }, + "network": { + "properties": { + "egress": { + "properties": { + "bytes": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "ingress": { + "properties": { + "bytes": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + } + } + }, "os": { "properties": { "family": { @@ -1090,6 +1391,10 @@ "ignore_above": 1024, "type": "keyword" }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, "version": { "ignore_above": 1024, "type": "keyword" @@ -1156,6 +1461,10 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" } } } @@ -1185,10 +1494,18 @@ "bytes": { "type": "long" }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, "method": { "ignore_above": 1024, "type": "keyword" }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, "referrer": { "ignore_above": 1024, "type": "keyword" @@ -1217,6 +1534,10 @@ "bytes": { "type": "long" }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, "status_code": { "type": "long" } @@ -1244,11 +1565,475 @@ } } }, - "labels": { - "type": "object" + "kibana": { + "properties": { + "alert": { + "properties": { + "ancestors": { + "properties": { + "depth": { + "path": "signal.ancestors.depth", + "type": "alias" + }, + "id": { + "path": "signal.ancestors.id", + "type": "alias" + }, + "index": { + "path": "signal.ancestors.index", + "type": "alias" + }, + "type": { + "path": "signal.ancestors.type", + "type": "alias" + } + } + }, + "depth": { + "path": "signal.depth", + "type": "alias" + }, + "original_event": { + "properties": { + "action": { + "path": "signal.original_event.action", + "type": "alias" + }, + "category": { + "path": "signal.original_event.category", + "type": "alias" + }, + "code": { + "path": "signal.original_event.code", + "type": "alias" + }, + "created": { + "path": "signal.original_event.created", + "type": "alias" + }, + "dataset": { + "path": "signal.original_event.dataset", + "type": "alias" + }, + "duration": { + "path": "signal.original_event.duration", + "type": "alias" + }, + "end": { + "path": "signal.original_event.end", + "type": "alias" + }, + "hash": { + "path": "signal.original_event.hash", + "type": "alias" + }, + "id": { + "path": "signal.original_event.id", + "type": "alias" + }, + "kind": { + "path": "signal.original_event.kind", + "type": "alias" + }, + "module": { + "path": "signal.original_event.module", + "type": "alias" + }, + "outcome": { + "path": "signal.original_event.outcome", + "type": "alias" + }, + "provider": { + "path": "signal.original_event.provider", + "type": "alias" + }, + "reason": { + "path": "signal.original_event.reason", + "type": "alias" + }, + "risk_score": { + "path": "signal.original_event.risk_score", + "type": "alias" + }, + "risk_score_norm": { + "path": "signal.original_event.risk_score_norm", + "type": "alias" + }, + "sequence": { + "path": "signal.original_event.sequence", + "type": "alias" + }, + "severity": { + "path": "signal.original_event.severity", + "type": "alias" + }, + "start": { + "path": "signal.original_event.start", + "type": "alias" + }, + "timezone": { + "path": "signal.original_event.timezone", + "type": "alias" + }, + "type": { + "path": "signal.original_event.type", + "type": "alias" + } + } + }, + "original_time": { + "path": "signal.original_time", + "type": "alias" + }, + "reason": { + "path": "signal.reason", + "type": "alias" + }, + "risk_score": { + "path": "signal.rule.risk_score", + "type": "alias" + }, + "rule": { + "properties": { + "author": { + "path": "signal.rule.author", + "type": "alias" + }, + "building_block_type": { + "path": "signal.rule.building_block_type", + "type": "alias" + }, + "consumer": { + "type": "constant_keyword", + "value": "siem" + }, + "created_at": { + "path": "signal.rule.created_at", + "type": "alias" + }, + "created_by": { + "path": "signal.rule.created_by", + "type": "alias" + }, + "description": { + "path": "signal.rule.description", + "type": "alias" + }, + "enabled": { + "path": "signal.rule.enabled", + "type": "alias" + }, + "false_positives": { + "path": "signal.rule.false_positives", + "type": "alias" + }, + "from": { + "path": "signal.rule.from", + "type": "alias" + }, + "id": { + "path": "signal.rule.id", + "type": "alias" + }, + "immutable": { + "path": "signal.rule.immutable", + "type": "alias" + }, + "index": { + "path": "signal.rule.index", + "type": "alias" + }, + "interval": { + "path": "signal.rule.interval", + "type": "alias" + }, + "language": { + "path": "signal.rule.language", + "type": "alias" + }, + "license": { + "path": "signal.rule.license", + "type": "alias" + }, + "max_signals": { + "path": "signal.rule.max_signals", + "type": "alias" + }, + "name": { + "path": "signal.rule.name", + "type": "alias" + }, + "note": { + "path": "signal.rule.note", + "type": "alias" + }, + "producer": { + "type": "constant_keyword", + "value": "siem" + }, + "query": { + "path": "signal.rule.query", + "type": "alias" + }, + "references": { + "path": "signal.rule.references", + "type": "alias" + }, + "risk_score_mapping": { + "properties": { + "field": { + "path": "signal.rule.risk_score_mapping.field", + "type": "alias" + }, + "operator": { + "path": "signal.rule.risk_score_mapping.operator", + "type": "alias" + }, + "value": { + "path": "signal.rule.risk_score_mapping.value", + "type": "alias" + } + } + }, + "rule_id": { + "path": "signal.rule.rule_id", + "type": "alias" + }, + "rule_name_override": { + "path": "signal.rule.rule_name_override", + "type": "alias" + }, + "rule_type_id": { + "type": "constant_keyword", + "value": "siem.signals" + }, + "saved_id": { + "path": "signal.rule.saved_id", + "type": "alias" + }, + "severity_mapping": { + "properties": { + "field": { + "path": "signal.rule.severity_mapping.field", + "type": "alias" + }, + "operator": { + "path": "signal.rule.severity_mapping.operator", + "type": "alias" + }, + "severity": { + "path": "signal.rule.severity_mapping.severity", + "type": "alias" + }, + "value": { + "path": "signal.rule.severity_mapping.value", + "type": "alias" + } + } + }, + "tags": { + "path": "signal.rule.tags", + "type": "alias" + }, + "threat": { + "properties": { + "framework": { + "path": "signal.rule.threat.framework", + "type": "alias" + }, + "tactic": { + "properties": { + "id": { + "path": "signal.rule.threat.tactic.id", + "type": "alias" + }, + "name": { + "path": "signal.rule.threat.tactic.name", + "type": "alias" + }, + "reference": { + "path": "signal.rule.threat.tactic.reference", + "type": "alias" + } + } + }, + "technique": { + "properties": { + "id": { + "path": "signal.rule.threat.technique.id", + "type": "alias" + }, + "name": { + "path": "signal.rule.threat.technique.name", + "type": "alias" + }, + "reference": { + "path": "signal.rule.threat.technique.reference", + "type": "alias" + }, + "subtechnique": { + "properties": { + "id": { + "path": "signal.rule.threat.technique.subtechnique.id", + "type": "alias" + }, + "name": { + "path": "signal.rule.threat.technique.subtechnique.name", + "type": "alias" + }, + "reference": { + "path": "signal.rule.threat.technique.subtechnique.reference", + "type": "alias" + } + } + } + } + } + } + }, + "threat_index": { + "path": "signal.rule.threat_index", + "type": "alias" + }, + "threat_indicator_path": { + "path": "signal.rule.threat_indicator_path", + "type": "alias" + }, + "threat_language": { + "path": "signal.rule.threat_language", + "type": "alias" + }, + "threat_mapping": { + "properties": { + "entries": { + "properties": { + "field": { + "path": "signal.rule.threat_mapping.entries.field", + "type": "alias" + }, + "type": { + "path": "signal.rule.threat_mapping.entries.type", + "type": "alias" + }, + "value": { + "path": "signal.rule.threat_mapping.entries.value", + "type": "alias" + } + } + } + } + }, + "threat_query": { + "path": "signal.rule.threat_query", + "type": "alias" + }, + "threshold": { + "properties": { + "field": { + "path": "signal.rule.threshold.field", + "type": "alias" + }, + "value": { + "path": "signal.rule.threshold.value", + "type": "alias" + } + } + }, + "timeline_id": { + "path": "signal.rule.timeline_id", + "type": "alias" + }, + "timeline_title": { + "path": "signal.rule.timeline_title", + "type": "alias" + }, + "to": { + "path": "signal.rule.to", + "type": "alias" + }, + "type": { + "path": "signal.rule.type", + "type": "alias" + }, + "updated_at": { + "path": "signal.rule.updated_at", + "type": "alias" + }, + "updated_by": { + "path": "signal.rule.updated_by", + "type": "alias" + }, + "version": { + "path": "signal.rule.version", + "type": "alias" + } + } + }, + "severity": { + "path": "signal.rule.severity", + "type": "alias" + }, + "threshold_result": { + "properties": { + "cardinality": { + "properties": { + "field": { + "path": "signal.threshold_result.cardinality.field", + "type": "alias" + }, + "value": { + "path": "signal.threshold_result.cardinality.value", + "type": "alias" + } + } + }, + "count": { + "path": "signal.threshold_result.count", + "type": "alias" + }, + "from": { + "path": "signal.threshold_result.from", + "type": "alias" + }, + "terms": { + "properties": { + "field": { + "path": "signal.threshold_result.terms.field", + "type": "alias" + }, + "value": { + "path": "signal.threshold_result.terms.value", + "type": "alias" + } + } + } + } + }, + "workflow_status": { + "path": "signal.status", + "type": "alias" + } + } + }, + "space_ids": { + "type": "constant_keyword", + "value": "default" + } + } + }, + "labels": { + "type": "object" }, "log": { "properties": { + "file": { + "properties": { + "path": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "level": { "ignore_above": 1024, "type": "keyword" @@ -1434,6 +2219,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -1453,6 +2242,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -1460,6 +2253,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -1548,6 +2345,10 @@ "ignore_above": 1024, "type": "keyword" }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, "version": { "ignore_above": 1024, "type": "keyword" @@ -1576,6 +2377,54 @@ } } }, + "orchestrator": { + "properties": { + "api_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "cluster": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "organization": { "properties": { "id": { @@ -1726,6 +2575,10 @@ "exists": { "type": "boolean" }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, "status": { "ignore_above": 1024, "type": "keyword" @@ -1734,6 +2587,10 @@ "ignore_above": 1024, "type": "keyword" }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, "trusted": { "type": "boolean" }, @@ -1786,6 +2643,10 @@ "sha512": { "ignore_above": 1024, "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -1813,6 +2674,10 @@ "exists": { "type": "boolean" }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, "status": { "ignore_above": 1024, "type": "keyword" @@ -1821,6 +2686,10 @@ "ignore_above": 1024, "type": "keyword" }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, "trusted": { "type": "boolean" }, @@ -1873,6 +2742,10 @@ "sha512": { "ignore_above": 1024, "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -1886,22 +2759,54 @@ "ignore_above": 1024, "type": "keyword" }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { + "pe": { "properties": { - "id": { - "type": "long" + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" }, "name": { "ignore_above": 1024, @@ -1936,6 +2841,10 @@ }, "pe": { "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, "company": { "ignore_above": 1024, "type": "keyword" @@ -1948,6 +2857,10 @@ "ignore_above": 1024, "type": "keyword" }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, "original_file_name": { "ignore_above": 1024, "type": "keyword" @@ -2048,6 +2961,10 @@ "ignore_above": 1024, "type": "keyword" }, + "hosts": { + "ignore_above": 1024, + "type": "keyword" + }, "ip": { "type": "ip" }, @@ -2141,6 +3058,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -2160,6 +3081,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -2167,6 +3092,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -2197,6 +3126,10 @@ "ignore_above": 1024, "type": "keyword" }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, "top_level_domain": { "ignore_above": 1024, "type": "keyword" @@ -2254,6 +3187,10 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" } } } @@ -2382,6 +3319,9 @@ "provider": { "type": "keyword" }, + "reason": { + "type": "keyword" + }, "risk_score": { "type": "float" }, @@ -2451,6 +3391,9 @@ } } }, + "reason": { + "type": "keyword" + }, "rule": { "properties": { "author": { @@ -2612,6 +3555,38 @@ } } }, + "threat_filters": { + "type": "object" + }, + "threat_index": { + "type": "keyword" + }, + "threat_indicator_path": { + "type": "keyword" + }, + "threat_language": { + "type": "keyword" + }, + "threat_mapping": { + "properties": { + "entries": { + "properties": { + "field": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "value": { + "type": "keyword" + } + } + } + } + }, + "threat_query": { + "type": "keyword" + }, "threshold": { "properties": { "field": { @@ -2656,11 +3631,31 @@ }, "threshold_result": { "properties": { + "cardinality": { + "properties": { + "field": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, "count": { "type": "long" }, - "value": { - "type": "keyword" + "from": { + "type": "date" + }, + "terms": { + "properties": { + "field": { + "type": "keyword" + }, + "value": { + "type": "keyword" + } + } } } } @@ -2706,6 +3701,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -2725,6 +3724,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -2732,6 +3735,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -2762,6 +3769,10 @@ "ignore_above": 1024, "type": "keyword" }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, "top_level_domain": { "ignore_above": 1024, "type": "keyword" @@ -2819,11 +3830,23 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" } } } } }, + "span": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "tags": { "ignore_above": 1024, "type": "keyword" @@ -2834,129 +3857,492 @@ "ignore_above": 1024, "type": "keyword" }, - "tactic": { + "indicator": { "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } }, - "name": { + "confidence": { "ignore_above": 1024, "type": "keyword" }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "technique": { - "properties": { - "id": { + "dataset": { "ignore_above": 1024, "type": "keyword" }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" + "description": { + "type": "wildcard" }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "tls": { - "properties": { - "cipher": { - "ignore_above": 1024, - "type": "keyword" - }, - "client": { - "properties": { - "certificate": { + "domain": { "ignore_above": 1024, "type": "keyword" }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" + "email": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } }, - "hash": { + "event": { "properties": { - "md5": { + "action": { "ignore_above": 1024, "type": "keyword" }, - "sha1": { + "category": { "ignore_above": 1024, "type": "keyword" }, - "sha256": { + "code": { "ignore_above": 1024, "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - }, - "supported_ciphers": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "curve": { - "ignore_above": 1024, - "type": "keyword" - }, - "established": { - "type": "boolean" - }, - "next_protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "resumed": { - "type": "boolean" - }, - "server": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "doc_values": false, + "ignore_above": 1024, + "index": false, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "first_seen": { + "type": "date" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "last_seen": { + "type": "date" + }, + "marking": { + "properties": { + "tlp": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "matched": { + "properties": { + "atomic": { + "ignore_above": 1024, + "type": "keyword" + }, + "field": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner_stats": { + "type": "long" + }, + "sightings": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "subtechnique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "doc_values": false, + "index": false, + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" }, "hash": { "properties": { @@ -2991,6 +4377,112 @@ "subject": { "ignore_above": 1024, "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "doc_values": false, + "index": false, + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } } } }, @@ -3077,6 +4569,10 @@ "ignore_above": 1024, "type": "keyword" }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, "top_level_domain": { "ignore_above": 1024, "type": "keyword" @@ -3089,10 +4585,130 @@ }, "user": { "properties": { + "changes": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "domain": { "ignore_above": 1024, "type": "keyword" }, + "effective": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "email": { "ignore_above": 1024, "type": "keyword" @@ -3140,6 +4756,70 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + }, + "target": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } } } }, @@ -3201,6 +4881,10 @@ "ignore_above": 1024, "type": "keyword" }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, "version": { "ignore_above": 1024, "type": "keyword" @@ -3320,7 +5004,8 @@ "index": ".siem-signals-default-000002", "mappings": { "_meta": { - "version": 14 + "aliases_version": 1, + "version": 55 }, "dynamic": "false", "properties": { @@ -3329,6 +5014,14 @@ }, "agent": { "properties": { + "build": { + "properties": { + "original": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "ephemeral_id": { "ignore_above": 1024, "type": "keyword" @@ -3412,6 +5105,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -3431,6 +5128,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -3438,6 +5139,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -3468,6 +5173,10 @@ "ignore_above": 1024, "type": "keyword" }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, "top_level_domain": { "ignore_above": 1024, "type": "keyword" @@ -3525,6 +5234,10 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" } } } @@ -3537,6 +5250,10 @@ "id": { "ignore_above": 1024, "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -3564,6 +5281,18 @@ } } }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "provider": { "ignore_above": 1024, "type": "keyword" @@ -3571,6 +5300,14 @@ "region": { "ignore_above": 1024, "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } } } }, @@ -3626,6 +5363,19 @@ } } }, + "data_stream": { + "properties": { + "dataset": { + "type": "keyword" + }, + "namespace": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + } + }, "destination": { "properties": { "address": { @@ -3666,6 +5416,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -3685,6 +5439,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -3692,6 +5450,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -3722,6 +5484,10 @@ "ignore_above": 1024, "type": "keyword" }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, "top_level_domain": { "ignore_above": 1024, "type": "keyword" @@ -3779,6 +5545,10 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" } } } @@ -3791,6 +5561,10 @@ "exists": { "type": "boolean" }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, "status": { "ignore_above": 1024, "type": "keyword" @@ -3799,6 +5573,10 @@ "ignore_above": 1024, "type": "keyword" }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, "trusted": { "type": "boolean" }, @@ -3824,6 +5602,10 @@ "sha512": { "ignore_above": 1024, "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -3837,6 +5619,10 @@ }, "pe": { "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, "company": { "ignore_above": 1024, "type": "keyword" @@ -3849,6 +5635,10 @@ "ignore_above": 1024, "type": "keyword" }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, "original_file_name": { "ignore_above": 1024, "type": "keyword" @@ -4039,6 +5829,10 @@ "ignore_above": 1024, "type": "keyword" }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, "reference": { "ignore_above": 1024, "type": "keyword" @@ -4086,6 +5880,10 @@ "exists": { "type": "boolean" }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, "status": { "ignore_above": 1024, "type": "keyword" @@ -4094,6 +5892,10 @@ "ignore_above": 1024, "type": "keyword" }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, "trusted": { "type": "boolean" }, @@ -4149,6 +5951,10 @@ "sha512": { "ignore_above": 1024, "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -4187,6 +5993,10 @@ }, "pe": { "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, "company": { "ignore_above": 1024, "type": "keyword" @@ -4199,6 +6009,10 @@ "ignore_above": 1024, "type": "keyword" }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, "original_file_name": { "ignore_above": 1024, "type": "keyword" @@ -4229,6 +6043,112 @@ "uid": { "ignore_above": 1024, "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "doc_values": false, + "index": false, + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } } } }, @@ -4309,6 +6229,32 @@ "ignore_above": 1024, "type": "keyword" }, + "cpu": { + "properties": { + "usage": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "disk": { + "properties": { + "read": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "write": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, "domain": { "ignore_above": 1024, "type": "keyword" @@ -4319,6 +6265,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -4338,6 +6288,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -4345,6 +6299,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -4367,6 +6325,30 @@ "ignore_above": 1024, "type": "keyword" }, + "network": { + "properties": { + "egress": { + "properties": { + "bytes": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "ingress": { + "properties": { + "bytes": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + } + } + }, "os": { "properties": { "family": { @@ -4401,6 +6383,10 @@ "ignore_above": 1024, "type": "keyword" }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, "version": { "ignore_above": 1024, "type": "keyword" @@ -4467,6 +6453,10 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" } } } @@ -4493,65 +6483,533 @@ } } }, - "bytes": { - "type": "long" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" + "bytes": { + "type": "long" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kibana": { + "properties": { + "alert": { + "properties": { + "ancestors": { + "properties": { + "depth": { + "path": "signal.ancestors.depth", + "type": "alias" + }, + "id": { + "path": "signal.ancestors.id", + "type": "alias" + }, + "index": { + "path": "signal.ancestors.index", + "type": "alias" + }, + "type": { + "path": "signal.ancestors.type", + "type": "alias" + } + } + }, + "depth": { + "path": "signal.depth", + "type": "alias" + }, + "original_event": { + "properties": { + "action": { + "path": "signal.original_event.action", + "type": "alias" + }, + "category": { + "path": "signal.original_event.category", + "type": "alias" + }, + "code": { + "path": "signal.original_event.code", + "type": "alias" + }, + "created": { + "path": "signal.original_event.created", + "type": "alias" + }, + "dataset": { + "path": "signal.original_event.dataset", + "type": "alias" + }, + "duration": { + "path": "signal.original_event.duration", + "type": "alias" + }, + "end": { + "path": "signal.original_event.end", + "type": "alias" + }, + "hash": { + "path": "signal.original_event.hash", + "type": "alias" + }, + "id": { + "path": "signal.original_event.id", + "type": "alias" + }, + "kind": { + "path": "signal.original_event.kind", + "type": "alias" + }, + "module": { + "path": "signal.original_event.module", + "type": "alias" + }, + "outcome": { + "path": "signal.original_event.outcome", + "type": "alias" + }, + "provider": { + "path": "signal.original_event.provider", + "type": "alias" + }, + "reason": { + "path": "signal.original_event.reason", + "type": "alias" + }, + "risk_score": { + "path": "signal.original_event.risk_score", + "type": "alias" + }, + "risk_score_norm": { + "path": "signal.original_event.risk_score_norm", + "type": "alias" + }, + "sequence": { + "path": "signal.original_event.sequence", + "type": "alias" + }, + "severity": { + "path": "signal.original_event.severity", + "type": "alias" + }, + "start": { + "path": "signal.original_event.start", + "type": "alias" + }, + "timezone": { + "path": "signal.original_event.timezone", + "type": "alias" + }, + "type": { + "path": "signal.original_event.type", + "type": "alias" + } + } + }, + "original_time": { + "path": "signal.original_time", + "type": "alias" + }, + "reason": { + "path": "signal.reason", + "type": "alias" + }, + "risk_score": { + "path": "signal.rule.risk_score", + "type": "alias" + }, + "rule": { + "properties": { + "author": { + "path": "signal.rule.author", + "type": "alias" + }, + "building_block_type": { + "path": "signal.rule.building_block_type", + "type": "alias" + }, + "consumer": { + "type": "constant_keyword", + "value": "siem" + }, + "created_at": { + "path": "signal.rule.created_at", + "type": "alias" + }, + "created_by": { + "path": "signal.rule.created_by", + "type": "alias" + }, + "description": { + "path": "signal.rule.description", + "type": "alias" + }, + "enabled": { + "path": "signal.rule.enabled", + "type": "alias" + }, + "false_positives": { + "path": "signal.rule.false_positives", + "type": "alias" + }, + "from": { + "path": "signal.rule.from", + "type": "alias" + }, + "id": { + "path": "signal.rule.id", + "type": "alias" + }, + "immutable": { + "path": "signal.rule.immutable", + "type": "alias" + }, + "index": { + "path": "signal.rule.index", + "type": "alias" + }, + "interval": { + "path": "signal.rule.interval", + "type": "alias" + }, + "language": { + "path": "signal.rule.language", + "type": "alias" + }, + "license": { + "path": "signal.rule.license", + "type": "alias" + }, + "max_signals": { + "path": "signal.rule.max_signals", + "type": "alias" + }, + "name": { + "path": "signal.rule.name", + "type": "alias" + }, + "note": { + "path": "signal.rule.note", + "type": "alias" + }, + "producer": { + "type": "constant_keyword", + "value": "siem" + }, + "query": { + "path": "signal.rule.query", + "type": "alias" + }, + "references": { + "path": "signal.rule.references", + "type": "alias" + }, + "risk_score_mapping": { + "properties": { + "field": { + "path": "signal.rule.risk_score_mapping.field", + "type": "alias" + }, + "operator": { + "path": "signal.rule.risk_score_mapping.operator", + "type": "alias" + }, + "value": { + "path": "signal.rule.risk_score_mapping.value", + "type": "alias" + } + } + }, + "rule_id": { + "path": "signal.rule.rule_id", + "type": "alias" + }, + "rule_name_override": { + "path": "signal.rule.rule_name_override", + "type": "alias" + }, + "rule_type_id": { + "type": "constant_keyword", + "value": "siem.signals" + }, + "saved_id": { + "path": "signal.rule.saved_id", + "type": "alias" + }, + "severity_mapping": { + "properties": { + "field": { + "path": "signal.rule.severity_mapping.field", + "type": "alias" + }, + "operator": { + "path": "signal.rule.severity_mapping.operator", + "type": "alias" + }, + "severity": { + "path": "signal.rule.severity_mapping.severity", + "type": "alias" + }, + "value": { + "path": "signal.rule.severity_mapping.value", + "type": "alias" + } + } + }, + "tags": { + "path": "signal.rule.tags", + "type": "alias" + }, + "threat": { + "properties": { + "framework": { + "path": "signal.rule.threat.framework", + "type": "alias" + }, + "tactic": { + "properties": { + "id": { + "path": "signal.rule.threat.tactic.id", + "type": "alias" + }, + "name": { + "path": "signal.rule.threat.tactic.name", + "type": "alias" + }, + "reference": { + "path": "signal.rule.threat.tactic.reference", + "type": "alias" + } + } + }, + "technique": { + "properties": { + "id": { + "path": "signal.rule.threat.technique.id", + "type": "alias" + }, + "name": { + "path": "signal.rule.threat.technique.name", + "type": "alias" + }, + "reference": { + "path": "signal.rule.threat.technique.reference", + "type": "alias" + }, + "subtechnique": { + "properties": { + "id": { + "path": "signal.rule.threat.technique.subtechnique.id", + "type": "alias" + }, + "name": { + "path": "signal.rule.threat.technique.subtechnique.name", + "type": "alias" + }, + "reference": { + "path": "signal.rule.threat.technique.subtechnique.reference", + "type": "alias" + } + } + } + } + } + } + }, + "threat_index": { + "path": "signal.rule.threat_index", + "type": "alias" + }, + "threat_indicator_path": { + "path": "signal.rule.threat_indicator_path", + "type": "alias" + }, + "threat_language": { + "path": "signal.rule.threat_language", + "type": "alias" + }, + "threat_mapping": { + "properties": { + "entries": { + "properties": { + "field": { + "path": "signal.rule.threat_mapping.entries.field", + "type": "alias" + }, + "type": { + "path": "signal.rule.threat_mapping.entries.type", + "type": "alias" + }, + "value": { + "path": "signal.rule.threat_mapping.entries.value", + "type": "alias" + } + } + } + } + }, + "threat_query": { + "path": "signal.rule.threat_query", + "type": "alias" + }, + "threshold": { + "properties": { + "field": { + "path": "signal.rule.threshold.field", + "type": "alias" + }, + "value": { + "path": "signal.rule.threshold.value", + "type": "alias" + } + } + }, + "timeline_id": { + "path": "signal.rule.timeline_id", + "type": "alias" + }, + "timeline_title": { + "path": "signal.rule.timeline_title", + "type": "alias" + }, + "to": { + "path": "signal.rule.to", + "type": "alias" + }, + "type": { + "path": "signal.rule.type", + "type": "alias" + }, + "updated_at": { + "path": "signal.rule.updated_at", + "type": "alias" + }, + "updated_by": { + "path": "signal.rule.updated_by", + "type": "alias" + }, + "version": { + "path": "signal.rule.version", + "type": "alias" + } + } + }, + "severity": { + "path": "signal.rule.severity", + "type": "alias" }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "response": { - "properties": { - "body": { + "threshold_result": { "properties": { - "bytes": { - "type": "long" + "cardinality": { + "properties": { + "field": { + "path": "signal.threshold_result.cardinality.field", + "type": "alias" + }, + "value": { + "path": "signal.threshold_result.cardinality.value", + "type": "alias" + } + } }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" + "count": { + "path": "signal.threshold_result.count", + "type": "alias" + }, + "from": { + "path": "signal.threshold_result.from", + "type": "alias" + }, + "terms": { + "properties": { + "field": { + "path": "signal.threshold_result.terms.field", + "type": "alias" + }, + "value": { + "path": "signal.threshold_result.terms.value", + "type": "alias" } - }, - "ignore_above": 1024, - "type": "keyword" + } } } }, - "bytes": { - "type": "long" - }, - "status_code": { - "type": "long" + "workflow_status": { + "path": "signal.status", + "type": "alias" } } }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" + "space_ids": { + "type": "constant_keyword", + "value": "default" } } }, @@ -4560,6 +7018,14 @@ }, "log": { "properties": { + "file": { + "properties": { + "path": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "level": { "ignore_above": 1024, "type": "keyword" @@ -4745,6 +7211,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -4764,6 +7234,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -4771,6 +7245,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -4859,6 +7337,10 @@ "ignore_above": 1024, "type": "keyword" }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, "version": { "ignore_above": 1024, "type": "keyword" @@ -4887,6 +7369,54 @@ } } }, + "orchestrator": { + "properties": { + "api_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "cluster": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "organization": { "properties": { "id": { @@ -5037,6 +7567,10 @@ "exists": { "type": "boolean" }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, "status": { "ignore_above": 1024, "type": "keyword" @@ -5045,6 +7579,10 @@ "ignore_above": 1024, "type": "keyword" }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, "trusted": { "type": "boolean" }, @@ -5097,6 +7635,10 @@ "sha512": { "ignore_above": 1024, "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -5124,6 +7666,10 @@ "exists": { "type": "boolean" }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, "status": { "ignore_above": 1024, "type": "keyword" @@ -5132,6 +7678,10 @@ "ignore_above": 1024, "type": "keyword" }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, "trusted": { "type": "boolean" }, @@ -5184,6 +7734,10 @@ "sha512": { "ignore_above": 1024, "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -5197,6 +7751,38 @@ "ignore_above": 1024, "type": "keyword" }, + "pe": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "pgid": { "type": "long" }, @@ -5247,6 +7833,10 @@ }, "pe": { "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, "company": { "ignore_above": 1024, "type": "keyword" @@ -5259,6 +7849,10 @@ "ignore_above": 1024, "type": "keyword" }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, "original_file_name": { "ignore_above": 1024, "type": "keyword" @@ -5359,6 +7953,10 @@ "ignore_above": 1024, "type": "keyword" }, + "hosts": { + "ignore_above": 1024, + "type": "keyword" + }, "ip": { "type": "ip" }, @@ -5452,6 +8050,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -5471,6 +8073,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -5478,6 +8084,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -5508,6 +8118,10 @@ "ignore_above": 1024, "type": "keyword" }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, "top_level_domain": { "ignore_above": 1024, "type": "keyword" @@ -5565,6 +8179,10 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" } } } @@ -5693,6 +8311,9 @@ "provider": { "type": "keyword" }, + "reason": { + "type": "keyword" + }, "risk_score": { "type": "float" }, @@ -5762,6 +8383,9 @@ } } }, + "reason": { + "type": "keyword" + }, "rule": { "properties": { "author": { @@ -5923,6 +8547,38 @@ } } }, + "threat_filters": { + "type": "object" + }, + "threat_index": { + "type": "keyword" + }, + "threat_indicator_path": { + "type": "keyword" + }, + "threat_language": { + "type": "keyword" + }, + "threat_mapping": { + "properties": { + "entries": { + "properties": { + "field": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "value": { + "type": "keyword" + } + } + } + } + }, + "threat_query": { + "type": "keyword" + }, "threshold": { "properties": { "field": { @@ -5967,11 +8623,31 @@ }, "threshold_result": { "properties": { + "cardinality": { + "properties": { + "field": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, "count": { "type": "long" }, - "value": { - "type": "keyword" + "from": { + "type": "date" + }, + "terms": { + "properties": { + "field": { + "type": "keyword" + }, + "value": { + "type": "keyword" + } + } } } } @@ -6017,6 +8693,10 @@ "ignore_above": 1024, "type": "keyword" }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, "continent_name": { "ignore_above": 1024, "type": "keyword" @@ -6036,6 +8716,10 @@ "ignore_above": 1024, "type": "keyword" }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, "region_iso_code": { "ignore_above": 1024, "type": "keyword" @@ -6043,6 +8727,10 @@ "region_name": { "ignore_above": 1024, "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" } } }, @@ -6069,7 +8757,11 @@ "port": { "type": "long" }, - "registered_domain": { + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { "ignore_above": 1024, "type": "keyword" }, @@ -6130,11 +8822,23 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" } } } } }, + "span": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "tags": { "ignore_above": 1024, "type": "keyword" @@ -6145,6 +8849,241 @@ "ignore_above": 1024, "type": "keyword" }, + "indicator": { + "properties": { + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "confidence": { + "ignore_above": 1024, + "type": "keyword" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "type": "wildcard" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "doc_values": false, + "ignore_above": 1024, + "index": false, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "first_seen": { + "type": "date" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "last_seen": { + "type": "date" + }, + "marking": { + "properties": { + "tlp": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "matched": { + "properties": { + "atomic": { + "ignore_above": 1024, + "type": "keyword" + }, + "field": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner_stats": { + "type": "long" + }, + "sightings": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, "tactic": { "properties": { "id": { @@ -6180,6 +9119,28 @@ "reference": { "ignore_above": 1024, "type": "keyword" + }, + "subtechnique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } } } } @@ -6242,6 +9203,112 @@ "supported_ciphers": { "ignore_above": 1024, "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "doc_values": false, + "index": false, + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } } } }, @@ -6302,6 +9369,112 @@ "subject": { "ignore_above": 1024, "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "doc_values": false, + "index": false, + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } } } }, @@ -6388,6 +9561,10 @@ "ignore_above": 1024, "type": "keyword" }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, "top_level_domain": { "ignore_above": 1024, "type": "keyword" @@ -6400,10 +9577,130 @@ }, "user": { "properties": { + "changes": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "domain": { "ignore_above": 1024, "type": "keyword" }, + "effective": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "email": { "ignore_above": 1024, "type": "keyword" @@ -6451,6 +9748,70 @@ }, "ignore_above": 1024, "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + }, + "target": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } } } }, @@ -6512,6 +9873,10 @@ "ignore_above": 1024, "type": "keyword" }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, "version": { "ignore_above": 1024, "type": "keyword" From 6317202fb6f2464e112fa92ad89283a2c11821e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Thu, 19 Aug 2021 16:29:27 -0400 Subject: [PATCH 10/14] [APM] Hash-based links into APM app don't work (#108777) * fixing navigation issues * addressing PR comments --- .../components/routing/apm_route_config.tsx | 6 ++ .../public/components/routing/home/index.tsx | 4 +- .../public/components/routing/redirect_to.tsx | 63 ++++++++++++------- 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx b/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx index 922662e25ab20..b751ef3f71190 100644 --- a/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx +++ b/x-pack/plugins/apm/public/components/routing/apm_route_config.tsx @@ -53,6 +53,12 @@ const apmRoutes = route([ }), }), ]), + defaults: { + query: { + rangeFrom: 'now-15m', + rangeTo: 'now', + }, + }, }, { path: '/', diff --git a/x-pack/plugins/apm/public/components/routing/home/index.tsx b/x-pack/plugins/apm/public/components/routing/home/index.tsx index ce74a48fd8c86..d1304e192ddce 100644 --- a/x-pack/plugins/apm/public/components/routing/home/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/home/index.tsx @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import { Outlet } from '@kbn/typed-react-router-config'; import * as t from 'io-ts'; import React from 'react'; -import { Redirect } from 'react-router-dom'; +import { RedirectTo } from '../redirect_to'; import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { environmentRt } from '../../../../common/environment_rt'; import { BackendDetailOverview } from '../../app/backend_detail_overview'; @@ -121,7 +121,7 @@ export const home = { }, { path: '/', - element: , + element: , }, ], } as const; diff --git a/x-pack/plugins/apm/public/components/routing/redirect_to.tsx b/x-pack/plugins/apm/public/components/routing/redirect_to.tsx index 68ff2fce77f13..7e5e01cadbf3e 100644 --- a/x-pack/plugins/apm/public/components/routing/redirect_to.tsx +++ b/x-pack/plugins/apm/public/components/routing/redirect_to.tsx @@ -6,33 +6,50 @@ */ import React from 'react'; -import { Redirect, RouteComponentProps } from 'react-router-dom'; +import { Location } from 'history'; +import { Redirect, useLocation, RouteComponentProps } from 'react-router-dom'; /** - * Given a path, redirect to that location, preserving the search and maintaining - * backward-compatibilty with legacy (pre-7.9) hash-based URLs. + * Function that returns a react component to redirect to a given pathname removing hash-based URLs + * @param pathname */ -export function redirectTo(to: string) { +export function redirectTo(pathname: string) { return ({ location }: RouteComponentProps<{}>) => { - let resolvedUrl: URL | undefined; + return ; + }; +} - // Redirect root URLs with a hash to support backward compatibility with URLs - // from before we switched to the non-hash platform history. - if (location.pathname === '' && location.hash.length > 0) { - // We just want the search and pathname so the host doesn't matter - resolvedUrl = new URL(location.hash.slice(1), 'http://localhost'); - to = resolvedUrl.pathname; - } +/** + * React component to redirect to a given pathname removing hash-based URLs + * @param param0 + */ +export function RedirectTo({ pathname }: { pathname: string }) { + const location = useLocation(); + return ; +} - return ( - - ); - }; +interface Props { + location: Location; + pathname: string; +} + +/** + * Given a pathname, redirect to that location, preserving the search and maintaining + * backward-compatibilty with legacy (pre-7.9) hash-based URLs. + */ +function RenderRedirectTo(props: Props) { + const { location } = props; + let search = location.search; + let pathname = props.pathname; + + // Redirect root URLs with a hash to support backward compatibility with URLs + // from before we switched to the non-hash platform history. + if (location.pathname === '' && location.hash.length > 0) { + // We just want the search and pathname so the host doesn't matter + const resolvedUrl = new URL(location.hash.slice(1), 'http://localhost'); + search = resolvedUrl.search; + pathname = resolvedUrl.pathname; + } + + return ; } From e14f81451828733f1cc81152f5a483a08baf43cb Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 19 Aug 2021 22:02:15 +0100 Subject: [PATCH 11/14] skip flaky suite (#109329) --- x-pack/test/functional/apps/uptime/synthetics_integration.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/uptime/synthetics_integration.ts b/x-pack/test/functional/apps/uptime/synthetics_integration.ts index 6d468b32d7018..5a8ca33df791a 100644 --- a/x-pack/test/functional/apps/uptime/synthetics_integration.ts +++ b/x-pack/test/functional/apps/uptime/synthetics_integration.ts @@ -111,7 +111,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); }); - describe('create new policy', () => { + // FLAKY: https://github.com/elastic/kibana/issues/109329 + describe.skip('create new policy', () => { let version: string; before(async () => { await uptimeService.syntheticsPackage.deletePolicyByName('system-1'); From 96dfabd51b5ef4fa791fde0ff4d0bb51b80c0956 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 19 Aug 2021 23:00:44 +0100 Subject: [PATCH 12/14] skip failing es promotion suite (#109349) --- x-pack/test/functional/apps/security/users.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/security/users.js b/x-pack/test/functional/apps/security/users.js index 8730ee3aeeaf2..6f9af40badd05 100644 --- a/x-pack/test/functional/apps/security/users.js +++ b/x-pack/test/functional/apps/security/users.js @@ -12,7 +12,8 @@ export default function ({ getService, getPageObjects }) { const config = getService('config'); const log = getService('log'); - describe('users', function () { + // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/109349 + describe.skip('users', function () { before(async () => { log.debug('users'); await PageObjects.settings.navigateTo(); From d155a94fcec95cb6f99e879b099652623fc80451 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 19 Aug 2021 23:09:49 +0100 Subject: [PATCH 13/14] skip failing es promotion suite (#109351) --- .../test/functional/apps/dashboard_mode/dashboard_view_mode.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js index 74f4dca06c717..af7d16969c605 100644 --- a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js +++ b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js @@ -62,7 +62,8 @@ export default function ({ getService, getPageObjects }) { await kibanaServer.savedObjects.clean({ types }); }); - describe('Dashboard viewer', () => { + // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/109351 + describe.skip('Dashboard viewer', () => { after(async () => { await security.testUser.restoreDefaults(); }); From 442d9c3274bb923ee48098e4b34c9a71a689605b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Thu, 19 Aug 2021 19:46:05 -0400 Subject: [PATCH 14/14] [APM] Rum service details doesn't show any data (#109117) * removing existing filter * fixing unit test * replacing terms agg for should filter * fixing test --- .../__snapshots__/queries.test.ts.snap | 12 ++++----- .../server/lib/services/get_service_agent.ts | 26 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap index 1b5df64dd8d00..ce8a8bcb8930d 100644 --- a/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap @@ -64,8 +64,8 @@ Object { }, "body": Object { "_source": Array [ - "service.runtime.name", "agent.name", + "service.runtime.name", ], "query": Object { "bool": Object { @@ -84,17 +84,17 @@ Object { }, }, }, - Object { - "exists": Object { - "field": "service.runtime.name", - }, - }, Object { "exists": Object { "field": "agent.name", }, }, ], + "should": Object { + "exists": Object { + "field": "service.runtime.name", + }, + }, }, }, "size": 1, diff --git a/x-pack/plugins/apm/server/lib/services/get_service_agent.ts b/x-pack/plugins/apm/server/lib/services/get_service_agent.ts index 2a6ec74bc0d1a..e99fd6b9ff278 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_agent.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_agent.ts @@ -16,14 +16,14 @@ import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getProcessorEventForAggregatedTransactions } from '../helpers/aggregated_transactions'; interface ServiceAgent { - service?: { - runtime: { - name: string; - }; - }; agent?: { name: string; }; + service?: { + runtime?: { + name?: string; + }; + }; } export async function getServiceAgent({ @@ -50,23 +50,23 @@ export async function getServiceAgent({ }, body: { size: 1, - _source: [SERVICE_RUNTIME_NAME, AGENT_NAME], + _source: [AGENT_NAME, SERVICE_RUNTIME_NAME], query: { bool: { filter: [ { term: { [SERVICE_NAME]: serviceName } }, ...rangeQuery(start, end), - { - exists: { - field: SERVICE_RUNTIME_NAME, - }, - }, { exists: { field: AGENT_NAME, }, }, ], + should: { + exists: { + field: SERVICE_RUNTIME_NAME, + }, + }, }, }, }, @@ -80,6 +80,6 @@ export async function getServiceAgent({ return {}; } - const { service, agent } = response.hits.hits[0]._source as ServiceAgent; - return { agentName: agent?.name, runtimeName: service?.runtime.name }; + const { agent, service } = response.hits.hits[0]._source as ServiceAgent; + return { agentName: agent?.name, runtimeName: service?.runtime?.name }; }