diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/create_schema_from_field_map.ts b/packages/kbn-alerts-as-data-utils/src/schemas/create_schema_from_field_map.ts index a0599d85fab33..68f1eb5c134e0 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/create_schema_from_field_map.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/create_schema_from_field_map.ts @@ -31,7 +31,7 @@ export const createSchemaFromFieldMap = ({ useAlert = false, useEcs = false, useLegacyAlerts = false, - flattened = false, + flattened = true, }: CreateSchemaFromFieldMapOpts) => { const lineWriters = { IMPORTS: createLineWriter(), diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/alert_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/alert_schema.ts index 4978d8b1fa1e4..62f0e732b8ce1 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/alert_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/alert_schema.ts @@ -68,59 +68,39 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint); // prettier-ignore const AlertRequired = rt.type({ '@timestamp': schemaDate, - kibana: rt.type({ - alert: rt.type({ - instance: rt.type({ - id: schemaString, - }), - rule: rt.type({ - category: schemaString, - consumer: schemaString, - name: schemaString, - producer: schemaString, - revision: schemaStringOrNumber, - rule_type_id: schemaString, - uuid: schemaString, - }), - status: schemaString, - uuid: schemaString, - }), - space_ids: schemaStringArray, - }), + 'kibana.alert.instance.id': schemaString, + 'kibana.alert.rule.category': schemaString, + 'kibana.alert.rule.consumer': schemaString, + 'kibana.alert.rule.name': schemaString, + 'kibana.alert.rule.producer': schemaString, + 'kibana.alert.rule.revision': schemaStringOrNumber, + 'kibana.alert.rule.rule_type_id': schemaString, + 'kibana.alert.rule.uuid': schemaString, + 'kibana.alert.status': schemaString, + 'kibana.alert.uuid': schemaString, + 'kibana.space_ids': schemaStringArray, }); const AlertOptional = rt.partial({ - event: rt.partial({ - action: schemaString, - kind: schemaString, - }), - kibana: rt.partial({ - alert: rt.partial({ - action_group: schemaString, - case_ids: schemaStringArray, - duration: rt.partial({ - us: schemaStringOrNumber, - }), - end: schemaDate, - flapping: schemaBoolean, - flapping_history: schemaBooleanArray, - last_detected: schemaDate, - maintenance_window_ids: schemaStringArray, - reason: schemaString, - rule: rt.partial({ - execution: rt.partial({ - uuid: schemaString, - }), - parameters: schemaUnknown, - tags: schemaStringArray, - }), - start: schemaDate, - time_range: schemaDateRange, - url: schemaString, - workflow_status: schemaString, - workflow_tags: schemaStringArray, - }), - version: schemaString, - }), + 'event.action': schemaString, + 'event.kind': schemaString, + 'kibana.alert.action_group': schemaString, + 'kibana.alert.case_ids': schemaStringArray, + 'kibana.alert.duration.us': schemaStringOrNumber, + 'kibana.alert.end': schemaDate, + 'kibana.alert.flapping': schemaBoolean, + 'kibana.alert.flapping_history': schemaBooleanArray, + 'kibana.alert.last_detected': schemaDate, + 'kibana.alert.maintenance_window_ids': schemaStringArray, + 'kibana.alert.reason': schemaString, + 'kibana.alert.rule.execution.uuid': schemaString, + 'kibana.alert.rule.parameters': schemaUnknown, + 'kibana.alert.rule.tags': schemaStringArray, + 'kibana.alert.start': schemaDate, + 'kibana.alert.time_range': schemaDateRange, + 'kibana.alert.url': schemaString, + 'kibana.alert.workflow_status': schemaString, + 'kibana.alert.workflow_tags': schemaStringArray, + 'kibana.version': schemaString, tags: schemaStringArray, }); diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/ecs_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/ecs_schema.ts index 8565f6838fc63..042153b2f7c0f 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/ecs_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/ecs_schema.ts @@ -68,1766 +68,1262 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint); // prettier-ignore const EcsRequired = rt.type({ '@timestamp': schemaDate, - ecs: rt.type({ - version: schemaString, - }), + 'ecs.version': schemaString, }); const EcsOptional = rt.partial({ - agent: rt.partial({ - build: rt.partial({ - original: schemaString, - }), - ephemeral_id: schemaString, - id: schemaString, - name: schemaString, - type: schemaString, - version: schemaString, - }), - client: rt.partial({ - address: schemaString, - as: rt.partial({ - number: schemaStringOrNumber, - organization: rt.partial({ - name: schemaString, - }), - }), - bytes: schemaStringOrNumber, - domain: schemaString, - geo: rt.partial({ - city_name: schemaString, - continent_code: schemaString, - continent_name: schemaString, - country_iso_code: schemaString, - country_name: schemaString, - location: schemaGeoPoint, - name: schemaString, - postal_code: schemaString, - region_iso_code: schemaString, - region_name: schemaString, - timezone: schemaString, - }), - ip: schemaString, - mac: schemaString, - nat: rt.partial({ - ip: schemaString, - port: schemaStringOrNumber, - }), - packets: schemaStringOrNumber, - port: schemaStringOrNumber, - registered_domain: schemaString, - subdomain: schemaString, - top_level_domain: schemaString, - user: rt.partial({ - domain: schemaString, - email: schemaString, - full_name: schemaString, - group: rt.partial({ - domain: schemaString, - id: schemaString, - name: schemaString, - }), - hash: schemaString, - id: schemaString, - name: schemaString, - roles: schemaStringArray, - }), - }), - cloud: rt.partial({ - account: rt.partial({ - id: schemaString, - name: schemaString, - }), - availability_zone: schemaString, - instance: rt.partial({ - id: schemaString, - name: schemaString, - }), - machine: rt.partial({ - type: schemaString, - }), - origin: rt.partial({ - account: rt.partial({ - id: schemaString, - name: schemaString, - }), - availability_zone: schemaString, - instance: rt.partial({ - id: schemaString, - name: schemaString, - }), - machine: rt.partial({ - type: schemaString, - }), - project: rt.partial({ - id: schemaString, - name: schemaString, - }), - provider: schemaString, - region: schemaString, - service: rt.partial({ - name: schemaString, - }), - }), - project: rt.partial({ - id: schemaString, - name: schemaString, - }), - provider: schemaString, - region: schemaString, - service: rt.partial({ - name: schemaString, - }), - target: rt.partial({ - account: rt.partial({ - id: schemaString, - name: schemaString, - }), - availability_zone: schemaString, - instance: rt.partial({ - id: schemaString, - name: schemaString, - }), - machine: rt.partial({ - type: schemaString, - }), - project: rt.partial({ - id: schemaString, - name: schemaString, - }), - provider: schemaString, - region: schemaString, - service: rt.partial({ - name: schemaString, - }), - }), - }), - container: rt.partial({ - cpu: rt.partial({ - usage: schemaStringOrNumber, - }), - disk: rt.partial({ - read: rt.partial({ - bytes: schemaStringOrNumber, - }), - write: rt.partial({ - bytes: schemaStringOrNumber, - }), - }), - id: schemaString, - image: rt.partial({ - hash: rt.partial({ - all: schemaStringArray, - }), - name: schemaString, - tag: schemaStringArray, - }), - memory: rt.partial({ - usage: schemaStringOrNumber, - }), - name: schemaString, - network: rt.partial({ - egress: rt.partial({ - bytes: schemaStringOrNumber, - }), - ingress: rt.partial({ - bytes: schemaStringOrNumber, - }), - }), - runtime: schemaString, - }), - destination: rt.partial({ - address: schemaString, - as: rt.partial({ - number: schemaStringOrNumber, - organization: rt.partial({ - name: schemaString, - }), - }), - bytes: schemaStringOrNumber, - domain: schemaString, - geo: rt.partial({ - city_name: schemaString, - continent_code: schemaString, - continent_name: schemaString, - country_iso_code: schemaString, - country_name: schemaString, - location: schemaGeoPoint, - name: schemaString, - postal_code: schemaString, - region_iso_code: schemaString, - region_name: schemaString, - timezone: schemaString, - }), - ip: schemaString, - mac: schemaString, - nat: rt.partial({ - ip: schemaString, - port: schemaStringOrNumber, - }), - packets: schemaStringOrNumber, - port: schemaStringOrNumber, - registered_domain: schemaString, - subdomain: schemaString, - top_level_domain: schemaString, - user: rt.partial({ - domain: schemaString, - email: schemaString, - full_name: schemaString, - group: rt.partial({ - domain: schemaString, - id: schemaString, - name: schemaString, - }), - hash: schemaString, - id: schemaString, - name: schemaString, - roles: schemaStringArray, - }), - }), - device: rt.partial({ - id: schemaString, - manufacturer: schemaString, - model: rt.partial({ - identifier: schemaString, - name: schemaString, - }), - }), - dll: rt.partial({ - code_signature: rt.partial({ - digest_algorithm: schemaString, - exists: schemaBoolean, - signing_id: schemaString, - status: schemaString, - subject_name: schemaString, - team_id: schemaString, - timestamp: schemaDate, - trusted: schemaBoolean, - valid: schemaBoolean, - }), - hash: rt.partial({ - md5: schemaString, - sha1: schemaString, - sha256: schemaString, - sha384: schemaString, - sha512: schemaString, - ssdeep: schemaString, - tlsh: schemaString, - }), - name: schemaString, - path: schemaString, - pe: rt.partial({ - architecture: schemaString, - company: schemaString, - description: schemaString, - file_version: schemaString, - imphash: schemaString, - original_file_name: schemaString, - pehash: schemaString, - product: schemaString, - }), - }), - dns: rt.partial({ - answers: rt.array( - rt.partial({ - class: schemaString, - data: schemaString, - name: schemaString, - ttl: schemaStringOrNumber, - type: schemaString, - }) - ), - header_flags: schemaStringArray, - id: schemaString, - op_code: schemaString, - question: rt.partial({ + 'agent.build.original': schemaString, + 'agent.ephemeral_id': schemaString, + 'agent.id': schemaString, + 'agent.name': schemaString, + 'agent.type': schemaString, + 'agent.version': schemaString, + 'client.address': schemaString, + 'client.as.number': schemaStringOrNumber, + 'client.as.organization.name': schemaString, + 'client.bytes': schemaStringOrNumber, + 'client.domain': schemaString, + 'client.geo.city_name': schemaString, + 'client.geo.continent_code': schemaString, + 'client.geo.continent_name': schemaString, + 'client.geo.country_iso_code': schemaString, + 'client.geo.country_name': schemaString, + 'client.geo.location': schemaGeoPoint, + 'client.geo.name': schemaString, + 'client.geo.postal_code': schemaString, + 'client.geo.region_iso_code': schemaString, + 'client.geo.region_name': schemaString, + 'client.geo.timezone': schemaString, + 'client.ip': schemaString, + 'client.mac': schemaString, + 'client.nat.ip': schemaString, + 'client.nat.port': schemaStringOrNumber, + 'client.packets': schemaStringOrNumber, + 'client.port': schemaStringOrNumber, + 'client.registered_domain': schemaString, + 'client.subdomain': schemaString, + 'client.top_level_domain': schemaString, + 'client.user.domain': schemaString, + 'client.user.email': schemaString, + 'client.user.full_name': schemaString, + 'client.user.group.domain': schemaString, + 'client.user.group.id': schemaString, + 'client.user.group.name': schemaString, + 'client.user.hash': schemaString, + 'client.user.id': schemaString, + 'client.user.name': schemaString, + 'client.user.roles': schemaStringArray, + 'cloud.account.id': schemaString, + 'cloud.account.name': schemaString, + 'cloud.availability_zone': schemaString, + 'cloud.instance.id': schemaString, + 'cloud.instance.name': schemaString, + 'cloud.machine.type': schemaString, + 'cloud.origin.account.id': schemaString, + 'cloud.origin.account.name': schemaString, + 'cloud.origin.availability_zone': schemaString, + 'cloud.origin.instance.id': schemaString, + 'cloud.origin.instance.name': schemaString, + 'cloud.origin.machine.type': schemaString, + 'cloud.origin.project.id': schemaString, + 'cloud.origin.project.name': schemaString, + 'cloud.origin.provider': schemaString, + 'cloud.origin.region': schemaString, + 'cloud.origin.service.name': schemaString, + 'cloud.project.id': schemaString, + 'cloud.project.name': schemaString, + 'cloud.provider': schemaString, + 'cloud.region': schemaString, + 'cloud.service.name': schemaString, + 'cloud.target.account.id': schemaString, + 'cloud.target.account.name': schemaString, + 'cloud.target.availability_zone': schemaString, + 'cloud.target.instance.id': schemaString, + 'cloud.target.instance.name': schemaString, + 'cloud.target.machine.type': schemaString, + 'cloud.target.project.id': schemaString, + 'cloud.target.project.name': schemaString, + 'cloud.target.provider': schemaString, + 'cloud.target.region': schemaString, + 'cloud.target.service.name': schemaString, + 'container.cpu.usage': schemaStringOrNumber, + 'container.disk.read.bytes': schemaStringOrNumber, + 'container.disk.write.bytes': schemaStringOrNumber, + 'container.id': schemaString, + 'container.image.hash.all': schemaStringArray, + 'container.image.name': schemaString, + 'container.image.tag': schemaStringArray, + 'container.memory.usage': schemaStringOrNumber, + 'container.name': schemaString, + 'container.network.egress.bytes': schemaStringOrNumber, + 'container.network.ingress.bytes': schemaStringOrNumber, + 'container.runtime': schemaString, + 'destination.address': schemaString, + 'destination.as.number': schemaStringOrNumber, + 'destination.as.organization.name': schemaString, + 'destination.bytes': schemaStringOrNumber, + 'destination.domain': schemaString, + 'destination.geo.city_name': schemaString, + 'destination.geo.continent_code': schemaString, + 'destination.geo.continent_name': schemaString, + 'destination.geo.country_iso_code': schemaString, + 'destination.geo.country_name': schemaString, + 'destination.geo.location': schemaGeoPoint, + 'destination.geo.name': schemaString, + 'destination.geo.postal_code': schemaString, + 'destination.geo.region_iso_code': schemaString, + 'destination.geo.region_name': schemaString, + 'destination.geo.timezone': schemaString, + 'destination.ip': schemaString, + 'destination.mac': schemaString, + 'destination.nat.ip': schemaString, + 'destination.nat.port': schemaStringOrNumber, + 'destination.packets': schemaStringOrNumber, + 'destination.port': schemaStringOrNumber, + 'destination.registered_domain': schemaString, + 'destination.subdomain': schemaString, + 'destination.top_level_domain': schemaString, + 'destination.user.domain': schemaString, + 'destination.user.email': schemaString, + 'destination.user.full_name': schemaString, + 'destination.user.group.domain': schemaString, + 'destination.user.group.id': schemaString, + 'destination.user.group.name': schemaString, + 'destination.user.hash': schemaString, + 'destination.user.id': schemaString, + 'destination.user.name': schemaString, + 'destination.user.roles': schemaStringArray, + 'device.id': schemaString, + 'device.manufacturer': schemaString, + 'device.model.identifier': schemaString, + 'device.model.name': schemaString, + 'dll.code_signature.digest_algorithm': schemaString, + 'dll.code_signature.exists': schemaBoolean, + 'dll.code_signature.signing_id': schemaString, + 'dll.code_signature.status': schemaString, + 'dll.code_signature.subject_name': schemaString, + 'dll.code_signature.team_id': schemaString, + 'dll.code_signature.timestamp': schemaDate, + 'dll.code_signature.trusted': schemaBoolean, + 'dll.code_signature.valid': schemaBoolean, + 'dll.hash.md5': schemaString, + 'dll.hash.sha1': schemaString, + 'dll.hash.sha256': schemaString, + 'dll.hash.sha384': schemaString, + 'dll.hash.sha512': schemaString, + 'dll.hash.ssdeep': schemaString, + 'dll.hash.tlsh': schemaString, + 'dll.name': schemaString, + 'dll.path': schemaString, + 'dll.pe.architecture': schemaString, + 'dll.pe.company': schemaString, + 'dll.pe.description': schemaString, + 'dll.pe.file_version': schemaString, + 'dll.pe.imphash': schemaString, + 'dll.pe.original_file_name': schemaString, + 'dll.pe.pehash': schemaString, + 'dll.pe.product': schemaString, + 'dns.answers': rt.array( + rt.partial({ class: schemaString, + data: schemaString, name: schemaString, - registered_domain: schemaString, - subdomain: schemaString, - top_level_domain: schemaString, + ttl: schemaStringOrNumber, type: schemaString, - }), - resolved_ip: schemaStringArray, - response_code: schemaString, - type: schemaString, - }), - email: rt.partial({ - attachments: rt.array( - rt.partial({ - file: rt.partial({ - extension: schemaString, - hash: rt.partial({ - md5: schemaString, - sha1: schemaString, - sha256: schemaString, - sha384: schemaString, - sha512: schemaString, - ssdeep: schemaString, - tlsh: schemaString, - }), - mime_type: schemaString, - name: schemaString, - size: schemaStringOrNumber, - }), - }) - ), - bcc: rt.partial({ - address: schemaStringArray, - }), - cc: rt.partial({ - address: schemaStringArray, - }), - content_type: schemaString, - delivery_timestamp: schemaDate, - direction: schemaString, - from: rt.partial({ - address: schemaStringArray, - }), - local_id: schemaString, - message_id: schemaString, - origination_timestamp: schemaDate, - reply_to: rt.partial({ - address: schemaStringArray, - }), - sender: rt.partial({ - address: schemaString, - }), - subject: schemaString, - to: rt.partial({ - address: schemaStringArray, - }), - x_mailer: schemaString, - }), - error: rt.partial({ - code: schemaString, - id: schemaString, - message: schemaString, - stack_trace: schemaString, - type: schemaString, - }), - event: rt.partial({ - action: schemaString, - agent_id_status: schemaString, - category: schemaStringArray, - code: schemaString, - created: schemaDate, - dataset: schemaString, - duration: schemaStringOrNumber, - end: schemaDate, - hash: schemaString, - id: schemaString, - ingested: schemaDate, - kind: schemaString, - module: schemaString, - original: schemaString, - outcome: schemaString, - provider: schemaString, - reason: schemaString, - reference: schemaString, - risk_score: schemaNumber, - risk_score_norm: schemaNumber, - sequence: schemaStringOrNumber, - severity: schemaStringOrNumber, - start: schemaDate, - timezone: schemaString, - type: schemaStringArray, - url: schemaString, - }), - faas: rt.partial({ - coldstart: schemaBoolean, - execution: schemaString, - id: schemaString, - name: schemaString, - version: schemaString, - }), - file: rt.partial({ - accessed: schemaDate, - attributes: schemaStringArray, - code_signature: rt.partial({ - digest_algorithm: schemaString, - exists: schemaBoolean, - signing_id: schemaString, - status: schemaString, - subject_name: schemaString, - team_id: schemaString, - timestamp: schemaDate, - trusted: schemaBoolean, - valid: schemaBoolean, - }), - created: schemaDate, - ctime: schemaDate, - device: schemaString, - directory: schemaString, - drive_letter: schemaString, - elf: rt.partial({ - architecture: schemaString, - byte_order: schemaString, - cpu_type: schemaString, - creation_date: schemaDate, - exports: schemaUnknownArray, - header: rt.partial({ - abi_version: schemaString, - class: schemaString, - data: schemaString, - entrypoint: schemaStringOrNumber, - object_version: schemaString, - os_abi: schemaString, - type: schemaString, - version: schemaString, - }), - imports: schemaUnknownArray, - sections: rt.array( - rt.partial({ - chi2: schemaStringOrNumber, - entropy: schemaStringOrNumber, - flags: schemaString, - name: schemaString, - physical_offset: schemaString, - physical_size: schemaStringOrNumber, - type: schemaString, - virtual_address: schemaStringOrNumber, - virtual_size: schemaStringOrNumber, - }) - ), - segments: rt.array( - rt.partial({ - sections: schemaString, - type: schemaString, - }) - ), - shared_libraries: schemaStringArray, - telfhash: schemaString, - }), - extension: schemaString, - fork_name: schemaString, - gid: schemaString, - group: schemaString, - hash: rt.partial({ - md5: schemaString, - sha1: schemaString, - sha256: schemaString, - sha384: schemaString, - sha512: schemaString, - ssdeep: schemaString, - tlsh: schemaString, - }), - inode: schemaString, - mime_type: schemaString, - mode: schemaString, - mtime: schemaDate, - name: schemaString, - owner: schemaString, - path: schemaString, - pe: rt.partial({ - architecture: schemaString, - company: schemaString, - description: schemaString, - file_version: schemaString, - imphash: schemaString, - original_file_name: schemaString, - pehash: schemaString, - product: schemaString, - }), - size: schemaStringOrNumber, - target_path: schemaString, - type: schemaString, - uid: schemaString, - x509: rt.partial({ - alternative_names: schemaStringArray, - issuer: rt.partial({ - common_name: schemaStringArray, - country: schemaStringArray, - distinguished_name: schemaString, - locality: schemaStringArray, - organization: schemaStringArray, - organizational_unit: schemaStringArray, - state_or_province: schemaStringArray, - }), - not_after: schemaDate, - not_before: schemaDate, - public_key_algorithm: schemaString, - public_key_curve: schemaString, - public_key_exponent: schemaStringOrNumber, - public_key_size: schemaStringOrNumber, - serial_number: schemaString, - signature_algorithm: schemaString, - subject: rt.partial({ - common_name: schemaStringArray, - country: schemaStringArray, - distinguished_name: schemaString, - locality: schemaStringArray, - organization: schemaStringArray, - organizational_unit: schemaStringArray, - state_or_province: schemaStringArray, - }), - version_number: schemaString, - }), - }), - group: rt.partial({ - domain: schemaString, - id: schemaString, - name: schemaString, - }), - host: rt.partial({ - architecture: schemaString, - boot: rt.partial({ - id: schemaString, - }), - cpu: rt.partial({ - usage: schemaStringOrNumber, - }), - disk: rt.partial({ - read: rt.partial({ - bytes: schemaStringOrNumber, - }), - write: rt.partial({ - bytes: schemaStringOrNumber, - }), - }), - domain: schemaString, - geo: rt.partial({ - city_name: schemaString, - continent_code: schemaString, - continent_name: schemaString, - country_iso_code: schemaString, - country_name: schemaString, - location: schemaGeoPoint, + }) + ), + 'dns.header_flags': schemaStringArray, + 'dns.id': schemaString, + 'dns.op_code': schemaString, + 'dns.question.class': schemaString, + 'dns.question.name': schemaString, + 'dns.question.registered_domain': schemaString, + 'dns.question.subdomain': schemaString, + 'dns.question.top_level_domain': schemaString, + 'dns.question.type': schemaString, + 'dns.resolved_ip': schemaStringArray, + 'dns.response_code': schemaString, + 'dns.type': schemaString, + 'email.attachments': rt.array( + rt.partial({ + 'file.extension': schemaString, + 'file.hash.md5': schemaString, + 'file.hash.sha1': schemaString, + 'file.hash.sha256': schemaString, + 'file.hash.sha384': schemaString, + 'file.hash.sha512': schemaString, + 'file.hash.ssdeep': schemaString, + 'file.hash.tlsh': schemaString, + 'file.mime_type': schemaString, + 'file.name': schemaString, + 'file.size': schemaStringOrNumber, + }) + ), + 'email.bcc.address': schemaStringArray, + 'email.cc.address': schemaStringArray, + 'email.content_type': schemaString, + 'email.delivery_timestamp': schemaDate, + 'email.direction': schemaString, + 'email.from.address': schemaStringArray, + 'email.local_id': schemaString, + 'email.message_id': schemaString, + 'email.origination_timestamp': schemaDate, + 'email.reply_to.address': schemaStringArray, + 'email.sender.address': schemaString, + 'email.subject': schemaString, + 'email.to.address': schemaStringArray, + 'email.x_mailer': schemaString, + 'error.code': schemaString, + 'error.id': schemaString, + 'error.message': schemaString, + 'error.stack_trace': schemaString, + 'error.type': schemaString, + 'event.action': schemaString, + 'event.agent_id_status': schemaString, + 'event.category': schemaStringArray, + 'event.code': schemaString, + 'event.created': schemaDate, + 'event.dataset': schemaString, + 'event.duration': schemaStringOrNumber, + 'event.end': schemaDate, + 'event.hash': schemaString, + 'event.id': schemaString, + 'event.ingested': schemaDate, + 'event.kind': schemaString, + 'event.module': schemaString, + 'event.original': schemaString, + 'event.outcome': schemaString, + 'event.provider': schemaString, + 'event.reason': schemaString, + 'event.reference': schemaString, + 'event.risk_score': schemaNumber, + 'event.risk_score_norm': schemaNumber, + 'event.sequence': schemaStringOrNumber, + 'event.severity': schemaStringOrNumber, + 'event.start': schemaDate, + 'event.timezone': schemaString, + 'event.type': schemaStringArray, + 'event.url': schemaString, + 'faas.coldstart': schemaBoolean, + 'faas.execution': schemaString, + 'faas.id': schemaString, + 'faas.name': schemaString, + 'faas.version': schemaString, + 'file.accessed': schemaDate, + 'file.attributes': schemaStringArray, + 'file.code_signature.digest_algorithm': schemaString, + 'file.code_signature.exists': schemaBoolean, + 'file.code_signature.signing_id': schemaString, + 'file.code_signature.status': schemaString, + 'file.code_signature.subject_name': schemaString, + 'file.code_signature.team_id': schemaString, + 'file.code_signature.timestamp': schemaDate, + 'file.code_signature.trusted': schemaBoolean, + 'file.code_signature.valid': schemaBoolean, + 'file.created': schemaDate, + 'file.ctime': schemaDate, + 'file.device': schemaString, + 'file.directory': schemaString, + 'file.drive_letter': schemaString, + 'file.elf.architecture': schemaString, + 'file.elf.byte_order': schemaString, + 'file.elf.cpu_type': schemaString, + 'file.elf.creation_date': schemaDate, + 'file.elf.exports': schemaUnknownArray, + 'file.elf.header.abi_version': schemaString, + 'file.elf.header.class': schemaString, + 'file.elf.header.data': schemaString, + 'file.elf.header.entrypoint': schemaStringOrNumber, + 'file.elf.header.object_version': schemaString, + 'file.elf.header.os_abi': schemaString, + 'file.elf.header.type': schemaString, + 'file.elf.header.version': schemaString, + 'file.elf.imports': schemaUnknownArray, + 'file.elf.sections': rt.array( + rt.partial({ + chi2: schemaStringOrNumber, + entropy: schemaStringOrNumber, + flags: schemaString, name: schemaString, - postal_code: schemaString, - region_iso_code: schemaString, - region_name: schemaString, - timezone: schemaString, - }), - hostname: schemaString, - id: schemaString, - ip: schemaStringArray, - mac: schemaStringArray, - name: schemaString, - network: rt.partial({ - egress: rt.partial({ - bytes: schemaStringOrNumber, - packets: schemaStringOrNumber, - }), - ingress: rt.partial({ - bytes: schemaStringOrNumber, - packets: schemaStringOrNumber, - }), - }), - os: rt.partial({ - family: schemaString, - full: schemaString, - kernel: schemaString, - name: schemaString, - platform: schemaString, + physical_offset: schemaString, + physical_size: schemaStringOrNumber, type: schemaString, - version: schemaString, - }), - pid_ns_ino: schemaString, - risk: rt.partial({ - calculated_level: schemaString, - calculated_score: schemaNumber, - calculated_score_norm: schemaNumber, - static_level: schemaString, - static_score: schemaNumber, - static_score_norm: schemaNumber, - }), - type: schemaString, - uptime: schemaStringOrNumber, - }), - http: rt.partial({ - request: rt.partial({ - body: rt.partial({ - bytes: schemaStringOrNumber, - content: schemaString, - }), - bytes: schemaStringOrNumber, - id: schemaString, - method: schemaString, - mime_type: schemaString, - referrer: schemaString, - }), - response: rt.partial({ - body: rt.partial({ - bytes: schemaStringOrNumber, - content: schemaString, - }), - bytes: schemaStringOrNumber, - mime_type: schemaString, - status_code: schemaStringOrNumber, - }), - version: schemaString, - }), - log: rt.partial({ - file: rt.partial({ - path: schemaString, - }), - level: schemaString, - logger: schemaString, - origin: rt.partial({ - file: rt.partial({ - line: schemaStringOrNumber, - name: schemaString, - }), - function: schemaString, - }), - }), - message: schemaString, - network: rt.partial({ - application: schemaString, - bytes: schemaStringOrNumber, - community_id: schemaString, - direction: schemaString, - forwarded_ip: schemaString, - iana_number: schemaString, - name: schemaString, - packets: schemaStringOrNumber, - protocol: schemaString, - transport: schemaString, - type: schemaString, - vlan: rt.partial({ - id: schemaString, - name: schemaString, - }), - }), - observer: rt.partial({ - geo: rt.partial({ - city_name: schemaString, - continent_code: schemaString, - continent_name: schemaString, - country_iso_code: schemaString, - country_name: schemaString, - location: schemaGeoPoint, - name: schemaString, - postal_code: schemaString, - region_iso_code: schemaString, - region_name: schemaString, - timezone: schemaString, - }), - hostname: schemaString, - ip: schemaStringArray, - mac: schemaStringArray, - name: schemaString, - os: rt.partial({ - family: schemaString, - full: schemaString, - kernel: schemaString, - name: schemaString, - platform: schemaString, + virtual_address: schemaStringOrNumber, + virtual_size: schemaStringOrNumber, + }) + ), + 'file.elf.segments': rt.array( + rt.partial({ + sections: schemaString, type: schemaString, - version: schemaString, - }), - product: schemaString, - serial_number: schemaString, - type: schemaString, - vendor: schemaString, - version: schemaString, - }), - orchestrator: rt.partial({ - api_version: schemaString, - cluster: rt.partial({ - id: schemaString, - name: schemaString, - url: schemaString, - version: schemaString, - }), - namespace: schemaString, - organization: schemaString, - resource: rt.partial({ - id: schemaString, - ip: schemaStringArray, + }) + ), + 'file.elf.shared_libraries': schemaStringArray, + 'file.elf.telfhash': schemaString, + 'file.extension': schemaString, + 'file.fork_name': schemaString, + 'file.gid': schemaString, + 'file.group': schemaString, + 'file.hash.md5': schemaString, + 'file.hash.sha1': schemaString, + 'file.hash.sha256': schemaString, + 'file.hash.sha384': schemaString, + 'file.hash.sha512': schemaString, + 'file.hash.ssdeep': schemaString, + 'file.hash.tlsh': schemaString, + 'file.inode': schemaString, + 'file.mime_type': schemaString, + 'file.mode': schemaString, + 'file.mtime': schemaDate, + 'file.name': schemaString, + 'file.owner': schemaString, + 'file.path': schemaString, + 'file.pe.architecture': schemaString, + 'file.pe.company': schemaString, + 'file.pe.description': schemaString, + 'file.pe.file_version': schemaString, + 'file.pe.imphash': schemaString, + 'file.pe.original_file_name': schemaString, + 'file.pe.pehash': schemaString, + 'file.pe.product': schemaString, + 'file.size': schemaStringOrNumber, + 'file.target_path': schemaString, + 'file.type': schemaString, + 'file.uid': schemaString, + 'file.x509.alternative_names': schemaStringArray, + 'file.x509.issuer.common_name': schemaStringArray, + 'file.x509.issuer.country': schemaStringArray, + 'file.x509.issuer.distinguished_name': schemaString, + 'file.x509.issuer.locality': schemaStringArray, + 'file.x509.issuer.organization': schemaStringArray, + 'file.x509.issuer.organizational_unit': schemaStringArray, + 'file.x509.issuer.state_or_province': schemaStringArray, + 'file.x509.not_after': schemaDate, + 'file.x509.not_before': schemaDate, + 'file.x509.public_key_algorithm': schemaString, + 'file.x509.public_key_curve': schemaString, + 'file.x509.public_key_exponent': schemaStringOrNumber, + 'file.x509.public_key_size': schemaStringOrNumber, + 'file.x509.serial_number': schemaString, + 'file.x509.signature_algorithm': schemaString, + 'file.x509.subject.common_name': schemaStringArray, + 'file.x509.subject.country': schemaStringArray, + 'file.x509.subject.distinguished_name': schemaString, + 'file.x509.subject.locality': schemaStringArray, + 'file.x509.subject.organization': schemaStringArray, + 'file.x509.subject.organizational_unit': schemaStringArray, + 'file.x509.subject.state_or_province': schemaStringArray, + 'file.x509.version_number': schemaString, + 'group.domain': schemaString, + 'group.id': schemaString, + 'group.name': schemaString, + 'host.architecture': schemaString, + 'host.boot.id': schemaString, + 'host.cpu.usage': schemaStringOrNumber, + 'host.disk.read.bytes': schemaStringOrNumber, + 'host.disk.write.bytes': schemaStringOrNumber, + 'host.domain': schemaString, + 'host.geo.city_name': schemaString, + 'host.geo.continent_code': schemaString, + 'host.geo.continent_name': schemaString, + 'host.geo.country_iso_code': schemaString, + 'host.geo.country_name': schemaString, + 'host.geo.location': schemaGeoPoint, + 'host.geo.name': schemaString, + 'host.geo.postal_code': schemaString, + 'host.geo.region_iso_code': schemaString, + 'host.geo.region_name': schemaString, + 'host.geo.timezone': schemaString, + 'host.hostname': schemaString, + 'host.id': schemaString, + 'host.ip': schemaStringArray, + 'host.mac': schemaStringArray, + 'host.name': schemaString, + 'host.network.egress.bytes': schemaStringOrNumber, + 'host.network.egress.packets': schemaStringOrNumber, + 'host.network.ingress.bytes': schemaStringOrNumber, + 'host.network.ingress.packets': schemaStringOrNumber, + 'host.os.family': schemaString, + 'host.os.full': schemaString, + 'host.os.kernel': schemaString, + 'host.os.name': schemaString, + 'host.os.platform': schemaString, + 'host.os.type': schemaString, + 'host.os.version': schemaString, + 'host.pid_ns_ino': schemaString, + 'host.risk.calculated_level': schemaString, + 'host.risk.calculated_score': schemaNumber, + 'host.risk.calculated_score_norm': schemaNumber, + 'host.risk.static_level': schemaString, + 'host.risk.static_score': schemaNumber, + 'host.risk.static_score_norm': schemaNumber, + 'host.type': schemaString, + 'host.uptime': schemaStringOrNumber, + 'http.request.body.bytes': schemaStringOrNumber, + 'http.request.body.content': schemaString, + 'http.request.bytes': schemaStringOrNumber, + 'http.request.id': schemaString, + 'http.request.method': schemaString, + 'http.request.mime_type': schemaString, + 'http.request.referrer': schemaString, + 'http.response.body.bytes': schemaStringOrNumber, + 'http.response.body.content': schemaString, + 'http.response.bytes': schemaStringOrNumber, + 'http.response.mime_type': schemaString, + 'http.response.status_code': schemaStringOrNumber, + 'http.version': schemaString, + 'log.file.path': schemaString, + 'log.level': schemaString, + 'log.logger': schemaString, + 'log.origin.file.line': schemaStringOrNumber, + 'log.origin.file.name': schemaString, + 'log.origin.function': schemaString, + message: schemaString, + 'network.application': schemaString, + 'network.bytes': schemaStringOrNumber, + 'network.community_id': schemaString, + 'network.direction': schemaString, + 'network.forwarded_ip': schemaString, + 'network.iana_number': schemaString, + 'network.name': schemaString, + 'network.packets': schemaStringOrNumber, + 'network.protocol': schemaString, + 'network.transport': schemaString, + 'network.type': schemaString, + 'network.vlan.id': schemaString, + 'network.vlan.name': schemaString, + 'observer.geo.city_name': schemaString, + 'observer.geo.continent_code': schemaString, + 'observer.geo.continent_name': schemaString, + 'observer.geo.country_iso_code': schemaString, + 'observer.geo.country_name': schemaString, + 'observer.geo.location': schemaGeoPoint, + 'observer.geo.name': schemaString, + 'observer.geo.postal_code': schemaString, + 'observer.geo.region_iso_code': schemaString, + 'observer.geo.region_name': schemaString, + 'observer.geo.timezone': schemaString, + 'observer.hostname': schemaString, + 'observer.ip': schemaStringArray, + 'observer.mac': schemaStringArray, + 'observer.name': schemaString, + 'observer.os.family': schemaString, + 'observer.os.full': schemaString, + 'observer.os.kernel': schemaString, + 'observer.os.name': schemaString, + 'observer.os.platform': schemaString, + 'observer.os.type': schemaString, + 'observer.os.version': schemaString, + 'observer.product': schemaString, + 'observer.serial_number': schemaString, + 'observer.type': schemaString, + 'observer.vendor': schemaString, + 'observer.version': schemaString, + 'orchestrator.api_version': schemaString, + 'orchestrator.cluster.id': schemaString, + 'orchestrator.cluster.name': schemaString, + 'orchestrator.cluster.url': schemaString, + 'orchestrator.cluster.version': schemaString, + 'orchestrator.namespace': schemaString, + 'orchestrator.organization': schemaString, + 'orchestrator.resource.id': schemaString, + 'orchestrator.resource.ip': schemaStringArray, + 'orchestrator.resource.name': schemaString, + 'orchestrator.resource.parent.type': schemaString, + 'orchestrator.resource.type': schemaString, + 'orchestrator.type': schemaString, + 'organization.id': schemaString, + 'organization.name': schemaString, + 'package.architecture': schemaString, + 'package.build_version': schemaString, + 'package.checksum': schemaString, + 'package.description': schemaString, + 'package.install_scope': schemaString, + 'package.installed': schemaDate, + 'package.license': schemaString, + 'package.name': schemaString, + 'package.path': schemaString, + 'package.reference': schemaString, + 'package.size': schemaStringOrNumber, + 'package.type': schemaString, + 'package.version': schemaString, + 'process.args': schemaStringArray, + 'process.args_count': schemaStringOrNumber, + 'process.code_signature.digest_algorithm': schemaString, + 'process.code_signature.exists': schemaBoolean, + 'process.code_signature.signing_id': schemaString, + 'process.code_signature.status': schemaString, + 'process.code_signature.subject_name': schemaString, + 'process.code_signature.team_id': schemaString, + 'process.code_signature.timestamp': schemaDate, + 'process.code_signature.trusted': schemaBoolean, + 'process.code_signature.valid': schemaBoolean, + 'process.command_line': schemaString, + 'process.elf.architecture': schemaString, + 'process.elf.byte_order': schemaString, + 'process.elf.cpu_type': schemaString, + 'process.elf.creation_date': schemaDate, + 'process.elf.exports': schemaUnknownArray, + 'process.elf.header.abi_version': schemaString, + 'process.elf.header.class': schemaString, + 'process.elf.header.data': schemaString, + 'process.elf.header.entrypoint': schemaStringOrNumber, + 'process.elf.header.object_version': schemaString, + 'process.elf.header.os_abi': schemaString, + 'process.elf.header.type': schemaString, + 'process.elf.header.version': schemaString, + 'process.elf.imports': schemaUnknownArray, + 'process.elf.sections': rt.array( + rt.partial({ + chi2: schemaStringOrNumber, + entropy: schemaStringOrNumber, + flags: schemaString, name: schemaString, - parent: rt.partial({ - type: schemaString, - }), + physical_offset: schemaString, + physical_size: schemaStringOrNumber, type: schemaString, - }), - type: schemaString, - }), - organization: rt.partial({ - id: schemaString, - name: schemaString, - }), - package: rt.partial({ - architecture: schemaString, - build_version: schemaString, - checksum: schemaString, - description: schemaString, - install_scope: schemaString, - installed: schemaDate, - license: schemaString, - name: schemaString, - path: schemaString, - reference: schemaString, - size: schemaStringOrNumber, - type: schemaString, - version: schemaString, - }), - process: rt.partial({ - args: schemaStringArray, - args_count: schemaStringOrNumber, - code_signature: rt.partial({ - digest_algorithm: schemaString, - exists: schemaBoolean, - signing_id: schemaString, - status: schemaString, - subject_name: schemaString, - team_id: schemaString, - timestamp: schemaDate, - trusted: schemaBoolean, - valid: schemaBoolean, - }), - command_line: schemaString, - elf: rt.partial({ - architecture: schemaString, - byte_order: schemaString, - cpu_type: schemaString, - creation_date: schemaDate, - exports: schemaUnknownArray, - header: rt.partial({ - abi_version: schemaString, - class: schemaString, - data: schemaString, - entrypoint: schemaStringOrNumber, - object_version: schemaString, - os_abi: schemaString, - type: schemaString, - version: schemaString, - }), - imports: schemaUnknownArray, - sections: rt.array( - rt.partial({ - chi2: schemaStringOrNumber, - entropy: schemaStringOrNumber, - flags: schemaString, - name: schemaString, - physical_offset: schemaString, - physical_size: schemaStringOrNumber, - type: schemaString, - virtual_address: schemaStringOrNumber, - virtual_size: schemaStringOrNumber, - }) - ), - segments: rt.array( - rt.partial({ - sections: schemaString, - type: schemaString, - }) - ), - shared_libraries: schemaStringArray, - telfhash: schemaString, - }), - end: schemaDate, - entity_id: schemaString, - entry_leader: rt.partial({ - args: schemaStringArray, - args_count: schemaStringOrNumber, - attested_groups: rt.partial({ - name: schemaString, - }), - attested_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - command_line: schemaString, - entity_id: schemaString, - entry_meta: rt.partial({ - source: rt.partial({ - ip: schemaString, - }), - type: schemaString, - }), - executable: schemaString, - group: rt.partial({ - id: schemaString, - name: schemaString, - }), - interactive: schemaBoolean, - name: schemaString, - parent: rt.partial({ - entity_id: schemaString, - pid: schemaStringOrNumber, - session_leader: rt.partial({ - entity_id: schemaString, - pid: schemaStringOrNumber, - start: schemaDate, - }), - start: schemaDate, - }), - pid: schemaStringOrNumber, - real_group: rt.partial({ - id: schemaString, - name: schemaString, - }), - real_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - same_as_process: schemaBoolean, - saved_group: rt.partial({ - id: schemaString, - name: schemaString, - }), - saved_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - start: schemaDate, - supplemental_groups: rt.partial({ - id: schemaString, - name: schemaString, - }), - user: rt.partial({ - id: schemaString, - name: schemaString, - }), - working_directory: schemaString, - }), - env_vars: schemaStringArray, - executable: schemaString, - exit_code: schemaStringOrNumber, - group_leader: rt.partial({ - args: schemaStringArray, - args_count: schemaStringOrNumber, - command_line: schemaString, - entity_id: schemaString, - executable: schemaString, - group: rt.partial({ - id: schemaString, - name: schemaString, - }), - interactive: schemaBoolean, - name: schemaString, - pid: schemaStringOrNumber, - real_group: rt.partial({ - id: schemaString, - name: schemaString, - }), - real_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - same_as_process: schemaBoolean, - saved_group: rt.partial({ - id: schemaString, - name: schemaString, - }), - saved_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - start: schemaDate, - supplemental_groups: rt.partial({ - id: schemaString, - name: schemaString, - }), - user: rt.partial({ - id: schemaString, - name: schemaString, - }), - working_directory: schemaString, - }), - hash: rt.partial({ - md5: schemaString, - sha1: schemaString, - sha256: schemaString, - sha384: schemaString, - sha512: schemaString, - ssdeep: schemaString, - tlsh: schemaString, - }), - interactive: schemaBoolean, - name: schemaString, - parent: rt.partial({ - args: schemaStringArray, - args_count: schemaStringOrNumber, - code_signature: rt.partial({ - digest_algorithm: schemaString, - exists: schemaBoolean, - signing_id: schemaString, - status: schemaString, - subject_name: schemaString, - team_id: schemaString, - timestamp: schemaDate, - trusted: schemaBoolean, - valid: schemaBoolean, - }), - command_line: schemaString, - elf: rt.partial({ - architecture: schemaString, - byte_order: schemaString, - cpu_type: schemaString, - creation_date: schemaDate, - exports: schemaUnknownArray, - header: rt.partial({ - abi_version: schemaString, - class: schemaString, - data: schemaString, - entrypoint: schemaStringOrNumber, - object_version: schemaString, - os_abi: schemaString, - type: schemaString, - version: schemaString, - }), - imports: schemaUnknownArray, - sections: rt.array( - rt.partial({ - chi2: schemaStringOrNumber, - entropy: schemaStringOrNumber, - flags: schemaString, - name: schemaString, - physical_offset: schemaString, - physical_size: schemaStringOrNumber, - type: schemaString, - virtual_address: schemaStringOrNumber, - virtual_size: schemaStringOrNumber, - }) - ), - segments: rt.array( - rt.partial({ - sections: schemaString, - type: schemaString, - }) - ), - shared_libraries: schemaStringArray, - telfhash: schemaString, - }), - end: schemaDate, - entity_id: schemaString, - executable: schemaString, - exit_code: schemaStringOrNumber, - group: rt.partial({ - id: schemaString, - name: schemaString, - }), - group_leader: rt.partial({ - entity_id: schemaString, - pid: schemaStringOrNumber, - start: schemaDate, - }), - hash: rt.partial({ - md5: schemaString, - sha1: schemaString, - sha256: schemaString, - sha384: schemaString, - sha512: schemaString, - ssdeep: schemaString, - tlsh: schemaString, - }), - interactive: schemaBoolean, - name: schemaString, - pe: rt.partial({ - architecture: schemaString, - company: schemaString, - description: schemaString, - file_version: schemaString, - imphash: schemaString, - original_file_name: schemaString, - pehash: schemaString, - product: schemaString, - }), - pgid: schemaStringOrNumber, - pid: schemaStringOrNumber, - real_group: rt.partial({ - id: schemaString, - name: schemaString, - }), - real_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - saved_group: rt.partial({ - id: schemaString, - name: schemaString, - }), - saved_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - start: schemaDate, - supplemental_groups: rt.partial({ - id: schemaString, - name: schemaString, - }), - thread: rt.partial({ - id: schemaStringOrNumber, - name: schemaString, - }), - title: schemaString, - uptime: schemaStringOrNumber, - user: rt.partial({ - id: schemaString, - name: schemaString, - }), - working_directory: schemaString, - }), - pe: rt.partial({ - architecture: schemaString, - company: schemaString, - description: schemaString, - file_version: schemaString, - imphash: schemaString, - original_file_name: schemaString, - pehash: schemaString, - product: schemaString, - }), - pgid: schemaStringOrNumber, - pid: schemaStringOrNumber, - previous: rt.partial({ - args: schemaStringArray, - args_count: schemaStringOrNumber, - executable: schemaString, - }), - real_group: rt.partial({ - id: schemaString, - name: schemaString, - }), - real_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - saved_group: rt.partial({ - id: schemaString, - name: schemaString, - }), - saved_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - session_leader: rt.partial({ - args: schemaStringArray, - args_count: schemaStringOrNumber, - command_line: schemaString, - entity_id: schemaString, - executable: schemaString, - group: rt.partial({ - id: schemaString, - name: schemaString, - }), - interactive: schemaBoolean, - name: schemaString, - parent: rt.partial({ - entity_id: schemaString, - pid: schemaStringOrNumber, - session_leader: rt.partial({ - entity_id: schemaString, - pid: schemaStringOrNumber, - start: schemaDate, - }), - start: schemaDate, - }), - pid: schemaStringOrNumber, - real_group: rt.partial({ - id: schemaString, - name: schemaString, - }), - real_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - same_as_process: schemaBoolean, - saved_group: rt.partial({ - id: schemaString, - name: schemaString, - }), - saved_user: rt.partial({ - id: schemaString, - name: schemaString, - }), - start: schemaDate, - supplemental_groups: rt.partial({ - id: schemaString, - name: schemaString, - }), - user: rt.partial({ - id: schemaString, - name: schemaString, - }), - working_directory: schemaString, - }), - start: schemaDate, - supplemental_groups: rt.partial({ - id: schemaString, - name: schemaString, - }), - thread: rt.partial({ - id: schemaStringOrNumber, - name: schemaString, - }), - title: schemaString, - uptime: schemaStringOrNumber, - user: rt.partial({ - id: schemaString, - name: schemaString, - }), - working_directory: schemaString, - }), - registry: rt.partial({ - data: rt.partial({ - bytes: schemaString, - strings: schemaStringArray, + virtual_address: schemaStringOrNumber, + virtual_size: schemaStringOrNumber, + }) + ), + 'process.elf.segments': rt.array( + rt.partial({ + sections: schemaString, type: schemaString, - }), - hive: schemaString, - key: schemaString, - path: schemaString, - value: schemaString, - }), - related: rt.partial({ - hash: schemaStringArray, - hosts: schemaStringArray, - ip: schemaStringArray, - user: schemaStringArray, - }), - rule: rt.partial({ - author: schemaStringArray, - category: schemaString, - description: schemaString, - id: schemaString, - license: schemaString, - name: schemaString, - reference: schemaString, - ruleset: schemaString, - uuid: schemaString, - version: schemaString, - }), - server: rt.partial({ - address: schemaString, - as: rt.partial({ - number: schemaStringOrNumber, - organization: rt.partial({ - name: schemaString, - }), - }), - bytes: schemaStringOrNumber, - domain: schemaString, - geo: rt.partial({ - city_name: schemaString, - continent_code: schemaString, - continent_name: schemaString, - country_iso_code: schemaString, - country_name: schemaString, - location: schemaGeoPoint, - name: schemaString, - postal_code: schemaString, - region_iso_code: schemaString, - region_name: schemaString, - timezone: schemaString, - }), - ip: schemaString, - mac: schemaString, - nat: rt.partial({ - ip: schemaString, - port: schemaStringOrNumber, - }), - packets: schemaStringOrNumber, - port: schemaStringOrNumber, - registered_domain: schemaString, - subdomain: schemaString, - top_level_domain: schemaString, - user: rt.partial({ - domain: schemaString, - email: schemaString, - full_name: schemaString, - group: rt.partial({ - domain: schemaString, - id: schemaString, - name: schemaString, - }), - hash: schemaString, - id: schemaString, - name: schemaString, - roles: schemaStringArray, - }), - }), - service: rt.partial({ - address: schemaString, - environment: schemaString, - ephemeral_id: schemaString, - id: schemaString, - name: schemaString, - node: rt.partial({ + }) + ), + 'process.elf.shared_libraries': schemaStringArray, + 'process.elf.telfhash': schemaString, + 'process.end': schemaDate, + 'process.entity_id': schemaString, + 'process.entry_leader.args': schemaStringArray, + 'process.entry_leader.args_count': schemaStringOrNumber, + 'process.entry_leader.attested_groups.name': schemaString, + 'process.entry_leader.attested_user.id': schemaString, + 'process.entry_leader.attested_user.name': schemaString, + 'process.entry_leader.command_line': schemaString, + 'process.entry_leader.entity_id': schemaString, + 'process.entry_leader.entry_meta.source.ip': schemaString, + 'process.entry_leader.entry_meta.type': schemaString, + 'process.entry_leader.executable': schemaString, + 'process.entry_leader.group.id': schemaString, + 'process.entry_leader.group.name': schemaString, + 'process.entry_leader.interactive': schemaBoolean, + 'process.entry_leader.name': schemaString, + 'process.entry_leader.parent.entity_id': schemaString, + 'process.entry_leader.parent.pid': schemaStringOrNumber, + 'process.entry_leader.parent.session_leader.entity_id': schemaString, + 'process.entry_leader.parent.session_leader.pid': schemaStringOrNumber, + 'process.entry_leader.parent.session_leader.start': schemaDate, + 'process.entry_leader.parent.start': schemaDate, + 'process.entry_leader.pid': schemaStringOrNumber, + 'process.entry_leader.real_group.id': schemaString, + 'process.entry_leader.real_group.name': schemaString, + 'process.entry_leader.real_user.id': schemaString, + 'process.entry_leader.real_user.name': schemaString, + 'process.entry_leader.same_as_process': schemaBoolean, + 'process.entry_leader.saved_group.id': schemaString, + 'process.entry_leader.saved_group.name': schemaString, + 'process.entry_leader.saved_user.id': schemaString, + 'process.entry_leader.saved_user.name': schemaString, + 'process.entry_leader.start': schemaDate, + 'process.entry_leader.supplemental_groups.id': schemaString, + 'process.entry_leader.supplemental_groups.name': schemaString, + 'process.entry_leader.user.id': schemaString, + 'process.entry_leader.user.name': schemaString, + 'process.entry_leader.working_directory': schemaString, + 'process.env_vars': schemaStringArray, + 'process.executable': schemaString, + 'process.exit_code': schemaStringOrNumber, + 'process.group_leader.args': schemaStringArray, + 'process.group_leader.args_count': schemaStringOrNumber, + 'process.group_leader.command_line': schemaString, + 'process.group_leader.entity_id': schemaString, + 'process.group_leader.executable': schemaString, + 'process.group_leader.group.id': schemaString, + 'process.group_leader.group.name': schemaString, + 'process.group_leader.interactive': schemaBoolean, + 'process.group_leader.name': schemaString, + 'process.group_leader.pid': schemaStringOrNumber, + 'process.group_leader.real_group.id': schemaString, + 'process.group_leader.real_group.name': schemaString, + 'process.group_leader.real_user.id': schemaString, + 'process.group_leader.real_user.name': schemaString, + 'process.group_leader.same_as_process': schemaBoolean, + 'process.group_leader.saved_group.id': schemaString, + 'process.group_leader.saved_group.name': schemaString, + 'process.group_leader.saved_user.id': schemaString, + 'process.group_leader.saved_user.name': schemaString, + 'process.group_leader.start': schemaDate, + 'process.group_leader.supplemental_groups.id': schemaString, + 'process.group_leader.supplemental_groups.name': schemaString, + 'process.group_leader.user.id': schemaString, + 'process.group_leader.user.name': schemaString, + 'process.group_leader.working_directory': schemaString, + 'process.hash.md5': schemaString, + 'process.hash.sha1': schemaString, + 'process.hash.sha256': schemaString, + 'process.hash.sha384': schemaString, + 'process.hash.sha512': schemaString, + 'process.hash.ssdeep': schemaString, + 'process.hash.tlsh': schemaString, + 'process.interactive': schemaBoolean, + 'process.name': schemaString, + 'process.parent.args': schemaStringArray, + 'process.parent.args_count': schemaStringOrNumber, + 'process.parent.code_signature.digest_algorithm': schemaString, + 'process.parent.code_signature.exists': schemaBoolean, + 'process.parent.code_signature.signing_id': schemaString, + 'process.parent.code_signature.status': schemaString, + 'process.parent.code_signature.subject_name': schemaString, + 'process.parent.code_signature.team_id': schemaString, + 'process.parent.code_signature.timestamp': schemaDate, + 'process.parent.code_signature.trusted': schemaBoolean, + 'process.parent.code_signature.valid': schemaBoolean, + 'process.parent.command_line': schemaString, + 'process.parent.elf.architecture': schemaString, + 'process.parent.elf.byte_order': schemaString, + 'process.parent.elf.cpu_type': schemaString, + 'process.parent.elf.creation_date': schemaDate, + 'process.parent.elf.exports': schemaUnknownArray, + 'process.parent.elf.header.abi_version': schemaString, + 'process.parent.elf.header.class': schemaString, + 'process.parent.elf.header.data': schemaString, + 'process.parent.elf.header.entrypoint': schemaStringOrNumber, + 'process.parent.elf.header.object_version': schemaString, + 'process.parent.elf.header.os_abi': schemaString, + 'process.parent.elf.header.type': schemaString, + 'process.parent.elf.header.version': schemaString, + 'process.parent.elf.imports': schemaUnknownArray, + 'process.parent.elf.sections': rt.array( + rt.partial({ + chi2: schemaStringOrNumber, + entropy: schemaStringOrNumber, + flags: schemaString, name: schemaString, - role: schemaString, - roles: schemaStringArray, - }), - origin: rt.partial({ - address: schemaString, - environment: schemaString, - ephemeral_id: schemaString, - id: schemaString, - name: schemaString, - node: rt.partial({ - name: schemaString, - role: schemaString, - roles: schemaStringArray, - }), - state: schemaString, + physical_offset: schemaString, + physical_size: schemaStringOrNumber, type: schemaString, - version: schemaString, - }), - state: schemaString, - target: rt.partial({ - address: schemaString, - environment: schemaString, - ephemeral_id: schemaString, - id: schemaString, - name: schemaString, - node: rt.partial({ - name: schemaString, - role: schemaString, - roles: schemaStringArray, - }), - state: schemaString, + virtual_address: schemaStringOrNumber, + virtual_size: schemaStringOrNumber, + }) + ), + 'process.parent.elf.segments': rt.array( + rt.partial({ + sections: schemaString, type: schemaString, - version: schemaString, - }), - type: schemaString, - version: schemaString, - }), - source: rt.partial({ - address: schemaString, - as: rt.partial({ - number: schemaStringOrNumber, - organization: rt.partial({ - name: schemaString, - }), - }), - bytes: schemaStringOrNumber, - domain: schemaString, - geo: rt.partial({ - city_name: schemaString, - continent_code: schemaString, - continent_name: schemaString, - country_iso_code: schemaString, - country_name: schemaString, - location: schemaGeoPoint, - name: schemaString, - postal_code: schemaString, - region_iso_code: schemaString, - region_name: schemaString, - timezone: schemaString, - }), - ip: schemaString, - mac: schemaString, - nat: rt.partial({ - ip: schemaString, - port: schemaStringOrNumber, - }), - packets: schemaStringOrNumber, - port: schemaStringOrNumber, - registered_domain: schemaString, - subdomain: schemaString, - top_level_domain: schemaString, - user: rt.partial({ - domain: schemaString, - email: schemaString, - full_name: schemaString, - group: rt.partial({ - domain: schemaString, - id: schemaString, - name: schemaString, - }), - hash: schemaString, - id: schemaString, - name: schemaString, - roles: schemaStringArray, - }), - }), - span: rt.partial({ - id: schemaString, - }), + }) + ), + 'process.parent.elf.shared_libraries': schemaStringArray, + 'process.parent.elf.telfhash': schemaString, + 'process.parent.end': schemaDate, + 'process.parent.entity_id': schemaString, + 'process.parent.executable': schemaString, + 'process.parent.exit_code': schemaStringOrNumber, + 'process.parent.group.id': schemaString, + 'process.parent.group.name': schemaString, + 'process.parent.group_leader.entity_id': schemaString, + 'process.parent.group_leader.pid': schemaStringOrNumber, + 'process.parent.group_leader.start': schemaDate, + 'process.parent.hash.md5': schemaString, + 'process.parent.hash.sha1': schemaString, + 'process.parent.hash.sha256': schemaString, + 'process.parent.hash.sha384': schemaString, + 'process.parent.hash.sha512': schemaString, + 'process.parent.hash.ssdeep': schemaString, + 'process.parent.hash.tlsh': schemaString, + 'process.parent.interactive': schemaBoolean, + 'process.parent.name': schemaString, + 'process.parent.pe.architecture': schemaString, + 'process.parent.pe.company': schemaString, + 'process.parent.pe.description': schemaString, + 'process.parent.pe.file_version': schemaString, + 'process.parent.pe.imphash': schemaString, + 'process.parent.pe.original_file_name': schemaString, + 'process.parent.pe.pehash': schemaString, + 'process.parent.pe.product': schemaString, + 'process.parent.pgid': schemaStringOrNumber, + 'process.parent.pid': schemaStringOrNumber, + 'process.parent.real_group.id': schemaString, + 'process.parent.real_group.name': schemaString, + 'process.parent.real_user.id': schemaString, + 'process.parent.real_user.name': schemaString, + 'process.parent.saved_group.id': schemaString, + 'process.parent.saved_group.name': schemaString, + 'process.parent.saved_user.id': schemaString, + 'process.parent.saved_user.name': schemaString, + 'process.parent.start': schemaDate, + 'process.parent.supplemental_groups.id': schemaString, + 'process.parent.supplemental_groups.name': schemaString, + 'process.parent.thread.id': schemaStringOrNumber, + 'process.parent.thread.name': schemaString, + 'process.parent.title': schemaString, + 'process.parent.uptime': schemaStringOrNumber, + 'process.parent.user.id': schemaString, + 'process.parent.user.name': schemaString, + 'process.parent.working_directory': schemaString, + 'process.pe.architecture': schemaString, + 'process.pe.company': schemaString, + 'process.pe.description': schemaString, + 'process.pe.file_version': schemaString, + 'process.pe.imphash': schemaString, + 'process.pe.original_file_name': schemaString, + 'process.pe.pehash': schemaString, + 'process.pe.product': schemaString, + 'process.pgid': schemaStringOrNumber, + 'process.pid': schemaStringOrNumber, + 'process.previous.args': schemaStringArray, + 'process.previous.args_count': schemaStringOrNumber, + 'process.previous.executable': schemaString, + 'process.real_group.id': schemaString, + 'process.real_group.name': schemaString, + 'process.real_user.id': schemaString, + 'process.real_user.name': schemaString, + 'process.saved_group.id': schemaString, + 'process.saved_group.name': schemaString, + 'process.saved_user.id': schemaString, + 'process.saved_user.name': schemaString, + 'process.session_leader.args': schemaStringArray, + 'process.session_leader.args_count': schemaStringOrNumber, + 'process.session_leader.command_line': schemaString, + 'process.session_leader.entity_id': schemaString, + 'process.session_leader.executable': schemaString, + 'process.session_leader.group.id': schemaString, + 'process.session_leader.group.name': schemaString, + 'process.session_leader.interactive': schemaBoolean, + 'process.session_leader.name': schemaString, + 'process.session_leader.parent.entity_id': schemaString, + 'process.session_leader.parent.pid': schemaStringOrNumber, + 'process.session_leader.parent.session_leader.entity_id': schemaString, + 'process.session_leader.parent.session_leader.pid': schemaStringOrNumber, + 'process.session_leader.parent.session_leader.start': schemaDate, + 'process.session_leader.parent.start': schemaDate, + 'process.session_leader.pid': schemaStringOrNumber, + 'process.session_leader.real_group.id': schemaString, + 'process.session_leader.real_group.name': schemaString, + 'process.session_leader.real_user.id': schemaString, + 'process.session_leader.real_user.name': schemaString, + 'process.session_leader.same_as_process': schemaBoolean, + 'process.session_leader.saved_group.id': schemaString, + 'process.session_leader.saved_group.name': schemaString, + 'process.session_leader.saved_user.id': schemaString, + 'process.session_leader.saved_user.name': schemaString, + 'process.session_leader.start': schemaDate, + 'process.session_leader.supplemental_groups.id': schemaString, + 'process.session_leader.supplemental_groups.name': schemaString, + 'process.session_leader.user.id': schemaString, + 'process.session_leader.user.name': schemaString, + 'process.session_leader.working_directory': schemaString, + 'process.start': schemaDate, + 'process.supplemental_groups.id': schemaString, + 'process.supplemental_groups.name': schemaString, + 'process.thread.id': schemaStringOrNumber, + 'process.thread.name': schemaString, + 'process.title': schemaString, + 'process.uptime': schemaStringOrNumber, + 'process.user.id': schemaString, + 'process.user.name': schemaString, + 'process.working_directory': schemaString, + 'registry.data.bytes': schemaString, + 'registry.data.strings': schemaStringArray, + 'registry.data.type': schemaString, + 'registry.hive': schemaString, + 'registry.key': schemaString, + 'registry.path': schemaString, + 'registry.value': schemaString, + 'related.hash': schemaStringArray, + 'related.hosts': schemaStringArray, + 'related.ip': schemaStringArray, + 'related.user': schemaStringArray, + 'rule.author': schemaStringArray, + 'rule.category': schemaString, + 'rule.description': schemaString, + 'rule.id': schemaString, + 'rule.license': schemaString, + 'rule.name': schemaString, + 'rule.reference': schemaString, + 'rule.ruleset': schemaString, + 'rule.uuid': schemaString, + 'rule.version': schemaString, + 'server.address': schemaString, + 'server.as.number': schemaStringOrNumber, + 'server.as.organization.name': schemaString, + 'server.bytes': schemaStringOrNumber, + 'server.domain': schemaString, + 'server.geo.city_name': schemaString, + 'server.geo.continent_code': schemaString, + 'server.geo.continent_name': schemaString, + 'server.geo.country_iso_code': schemaString, + 'server.geo.country_name': schemaString, + 'server.geo.location': schemaGeoPoint, + 'server.geo.name': schemaString, + 'server.geo.postal_code': schemaString, + 'server.geo.region_iso_code': schemaString, + 'server.geo.region_name': schemaString, + 'server.geo.timezone': schemaString, + 'server.ip': schemaString, + 'server.mac': schemaString, + 'server.nat.ip': schemaString, + 'server.nat.port': schemaStringOrNumber, + 'server.packets': schemaStringOrNumber, + 'server.port': schemaStringOrNumber, + 'server.registered_domain': schemaString, + 'server.subdomain': schemaString, + 'server.top_level_domain': schemaString, + 'server.user.domain': schemaString, + 'server.user.email': schemaString, + 'server.user.full_name': schemaString, + 'server.user.group.domain': schemaString, + 'server.user.group.id': schemaString, + 'server.user.group.name': schemaString, + 'server.user.hash': schemaString, + 'server.user.id': schemaString, + 'server.user.name': schemaString, + 'server.user.roles': schemaStringArray, + 'service.address': schemaString, + 'service.environment': schemaString, + 'service.ephemeral_id': schemaString, + 'service.id': schemaString, + 'service.name': schemaString, + 'service.node.name': schemaString, + 'service.node.role': schemaString, + 'service.node.roles': schemaStringArray, + 'service.origin.address': schemaString, + 'service.origin.environment': schemaString, + 'service.origin.ephemeral_id': schemaString, + 'service.origin.id': schemaString, + 'service.origin.name': schemaString, + 'service.origin.node.name': schemaString, + 'service.origin.node.role': schemaString, + 'service.origin.node.roles': schemaStringArray, + 'service.origin.state': schemaString, + 'service.origin.type': schemaString, + 'service.origin.version': schemaString, + 'service.state': schemaString, + 'service.target.address': schemaString, + 'service.target.environment': schemaString, + 'service.target.ephemeral_id': schemaString, + 'service.target.id': schemaString, + 'service.target.name': schemaString, + 'service.target.node.name': schemaString, + 'service.target.node.role': schemaString, + 'service.target.node.roles': schemaStringArray, + 'service.target.state': schemaString, + 'service.target.type': schemaString, + 'service.target.version': schemaString, + 'service.type': schemaString, + 'service.version': schemaString, + 'source.address': schemaString, + 'source.as.number': schemaStringOrNumber, + 'source.as.organization.name': schemaString, + 'source.bytes': schemaStringOrNumber, + 'source.domain': schemaString, + 'source.geo.city_name': schemaString, + 'source.geo.continent_code': schemaString, + 'source.geo.continent_name': schemaString, + 'source.geo.country_iso_code': schemaString, + 'source.geo.country_name': schemaString, + 'source.geo.location': schemaGeoPoint, + 'source.geo.name': schemaString, + 'source.geo.postal_code': schemaString, + 'source.geo.region_iso_code': schemaString, + 'source.geo.region_name': schemaString, + 'source.geo.timezone': schemaString, + 'source.ip': schemaString, + 'source.mac': schemaString, + 'source.nat.ip': schemaString, + 'source.nat.port': schemaStringOrNumber, + 'source.packets': schemaStringOrNumber, + 'source.port': schemaStringOrNumber, + 'source.registered_domain': schemaString, + 'source.subdomain': schemaString, + 'source.top_level_domain': schemaString, + 'source.user.domain': schemaString, + 'source.user.email': schemaString, + 'source.user.full_name': schemaString, + 'source.user.group.domain': schemaString, + 'source.user.group.id': schemaString, + 'source.user.group.name': schemaString, + 'source.user.hash': schemaString, + 'source.user.id': schemaString, + 'source.user.name': schemaString, + 'source.user.roles': schemaStringArray, + 'span.id': schemaString, tags: schemaStringArray, - threat: rt.partial({ - enrichments: rt.array( - rt.partial({ - matched: rt.partial({ - atomic: schemaString, - field: schemaString, - id: schemaString, - index: schemaString, - occurred: schemaDate, - type: schemaString, - }), - }) - ), - feed: rt.partial({ - dashboard_id: schemaString, - description: schemaString, - name: schemaString, - reference: schemaString, - }), - framework: schemaString, - group: rt.partial({ - alias: schemaStringArray, - id: schemaString, + 'threat.enrichments': rt.array( + rt.partial({ + 'matched.atomic': schemaString, + 'matched.field': schemaString, + 'matched.id': schemaString, + 'matched.index': schemaString, + 'matched.occurred': schemaDate, + 'matched.type': schemaString, + }) + ), + 'threat.feed.dashboard_id': schemaString, + 'threat.feed.description': schemaString, + 'threat.feed.name': schemaString, + 'threat.feed.reference': schemaString, + 'threat.framework': schemaString, + 'threat.group.alias': schemaStringArray, + 'threat.group.id': schemaString, + 'threat.group.name': schemaString, + 'threat.group.reference': schemaString, + 'threat.indicator.as.number': schemaStringOrNumber, + 'threat.indicator.as.organization.name': schemaString, + 'threat.indicator.confidence': schemaString, + 'threat.indicator.description': schemaString, + 'threat.indicator.email.address': schemaString, + 'threat.indicator.file.accessed': schemaDate, + 'threat.indicator.file.attributes': schemaStringArray, + 'threat.indicator.file.code_signature.digest_algorithm': schemaString, + 'threat.indicator.file.code_signature.exists': schemaBoolean, + 'threat.indicator.file.code_signature.signing_id': schemaString, + 'threat.indicator.file.code_signature.status': schemaString, + 'threat.indicator.file.code_signature.subject_name': schemaString, + 'threat.indicator.file.code_signature.team_id': schemaString, + 'threat.indicator.file.code_signature.timestamp': schemaDate, + 'threat.indicator.file.code_signature.trusted': schemaBoolean, + 'threat.indicator.file.code_signature.valid': schemaBoolean, + 'threat.indicator.file.created': schemaDate, + 'threat.indicator.file.ctime': schemaDate, + 'threat.indicator.file.device': schemaString, + 'threat.indicator.file.directory': schemaString, + 'threat.indicator.file.drive_letter': schemaString, + 'threat.indicator.file.elf.architecture': schemaString, + 'threat.indicator.file.elf.byte_order': schemaString, + 'threat.indicator.file.elf.cpu_type': schemaString, + 'threat.indicator.file.elf.creation_date': schemaDate, + 'threat.indicator.file.elf.exports': schemaUnknownArray, + 'threat.indicator.file.elf.header.abi_version': schemaString, + 'threat.indicator.file.elf.header.class': schemaString, + 'threat.indicator.file.elf.header.data': schemaString, + 'threat.indicator.file.elf.header.entrypoint': schemaStringOrNumber, + 'threat.indicator.file.elf.header.object_version': schemaString, + 'threat.indicator.file.elf.header.os_abi': schemaString, + 'threat.indicator.file.elf.header.type': schemaString, + 'threat.indicator.file.elf.header.version': schemaString, + 'threat.indicator.file.elf.imports': schemaUnknownArray, + 'threat.indicator.file.elf.sections': rt.array( + rt.partial({ + chi2: schemaStringOrNumber, + entropy: schemaStringOrNumber, + flags: schemaString, name: schemaString, - reference: schemaString, - }), - indicator: rt.partial({ - as: rt.partial({ - number: schemaStringOrNumber, - organization: rt.partial({ - name: schemaString, - }), - }), - confidence: schemaString, - description: schemaString, - email: rt.partial({ - address: schemaString, - }), - file: rt.partial({ - accessed: schemaDate, - attributes: schemaStringArray, - code_signature: rt.partial({ - digest_algorithm: schemaString, - exists: schemaBoolean, - signing_id: schemaString, - status: schemaString, - subject_name: schemaString, - team_id: schemaString, - timestamp: schemaDate, - trusted: schemaBoolean, - valid: schemaBoolean, - }), - created: schemaDate, - ctime: schemaDate, - device: schemaString, - directory: schemaString, - drive_letter: schemaString, - elf: rt.partial({ - architecture: schemaString, - byte_order: schemaString, - cpu_type: schemaString, - creation_date: schemaDate, - exports: schemaUnknownArray, - header: rt.partial({ - abi_version: schemaString, - class: schemaString, - data: schemaString, - entrypoint: schemaStringOrNumber, - object_version: schemaString, - os_abi: schemaString, - type: schemaString, - version: schemaString, - }), - imports: schemaUnknownArray, - sections: rt.array( - rt.partial({ - chi2: schemaStringOrNumber, - entropy: schemaStringOrNumber, - flags: schemaString, - name: schemaString, - physical_offset: schemaString, - physical_size: schemaStringOrNumber, - type: schemaString, - virtual_address: schemaStringOrNumber, - virtual_size: schemaStringOrNumber, - }) - ), - segments: rt.array( - rt.partial({ - sections: schemaString, - type: schemaString, - }) - ), - shared_libraries: schemaStringArray, - telfhash: schemaString, - }), - extension: schemaString, - fork_name: schemaString, - gid: schemaString, - group: schemaString, - hash: rt.partial({ - md5: schemaString, - sha1: schemaString, - sha256: schemaString, - sha384: schemaString, - sha512: schemaString, - ssdeep: schemaString, - tlsh: schemaString, - }), - inode: schemaString, - mime_type: schemaString, - mode: schemaString, - mtime: schemaDate, - name: schemaString, - owner: schemaString, - path: schemaString, - pe: rt.partial({ - architecture: schemaString, - company: schemaString, - description: schemaString, - file_version: schemaString, - imphash: schemaString, - original_file_name: schemaString, - pehash: schemaString, - product: schemaString, - }), - size: schemaStringOrNumber, - target_path: schemaString, - type: schemaString, - uid: schemaString, - x509: rt.partial({ - alternative_names: schemaStringArray, - issuer: rt.partial({ - common_name: schemaStringArray, - country: schemaStringArray, - distinguished_name: schemaString, - locality: schemaStringArray, - organization: schemaStringArray, - organizational_unit: schemaStringArray, - state_or_province: schemaStringArray, - }), - not_after: schemaDate, - not_before: schemaDate, - public_key_algorithm: schemaString, - public_key_curve: schemaString, - public_key_exponent: schemaStringOrNumber, - public_key_size: schemaStringOrNumber, - serial_number: schemaString, - signature_algorithm: schemaString, - subject: rt.partial({ - common_name: schemaStringArray, - country: schemaStringArray, - distinguished_name: schemaString, - locality: schemaStringArray, - organization: schemaStringArray, - organizational_unit: schemaStringArray, - state_or_province: schemaStringArray, - }), - version_number: schemaString, - }), - }), - first_seen: schemaDate, - geo: rt.partial({ - city_name: schemaString, - continent_code: schemaString, - continent_name: schemaString, - country_iso_code: schemaString, - country_name: schemaString, - location: schemaGeoPoint, - name: schemaString, - postal_code: schemaString, - region_iso_code: schemaString, - region_name: schemaString, - timezone: schemaString, - }), - ip: schemaString, - last_seen: schemaDate, - marking: rt.partial({ - tlp: schemaString, - tlp_version: schemaString, - }), - modified_at: schemaDate, - port: schemaStringOrNumber, - provider: schemaString, - reference: schemaString, - registry: rt.partial({ - data: rt.partial({ - bytes: schemaString, - strings: schemaStringArray, - type: schemaString, - }), - hive: schemaString, - key: schemaString, - path: schemaString, - value: schemaString, - }), - scanner_stats: schemaStringOrNumber, - sightings: schemaStringOrNumber, + physical_offset: schemaString, + physical_size: schemaStringOrNumber, type: schemaString, - url: rt.partial({ - domain: schemaString, - extension: schemaString, - fragment: schemaString, - full: schemaString, - original: schemaString, - password: schemaString, - path: schemaString, - port: schemaStringOrNumber, - query: schemaString, - registered_domain: schemaString, - scheme: schemaString, - subdomain: schemaString, - top_level_domain: schemaString, - username: schemaString, - }), - x509: rt.partial({ - alternative_names: schemaStringArray, - issuer: rt.partial({ - common_name: schemaStringArray, - country: schemaStringArray, - distinguished_name: schemaString, - locality: schemaStringArray, - organization: schemaStringArray, - organizational_unit: schemaStringArray, - state_or_province: schemaStringArray, - }), - not_after: schemaDate, - not_before: schemaDate, - public_key_algorithm: schemaString, - public_key_curve: schemaString, - public_key_exponent: schemaStringOrNumber, - public_key_size: schemaStringOrNumber, - serial_number: schemaString, - signature_algorithm: schemaString, - subject: rt.partial({ - common_name: schemaStringArray, - country: schemaStringArray, - distinguished_name: schemaString, - locality: schemaStringArray, - organization: schemaStringArray, - organizational_unit: schemaStringArray, - state_or_province: schemaStringArray, - }), - version_number: schemaString, - }), - }), - software: rt.partial({ - alias: schemaStringArray, - id: schemaString, - name: schemaString, - platforms: schemaStringArray, - reference: schemaString, - type: schemaString, - }), - tactic: rt.partial({ - id: schemaStringArray, - name: schemaStringArray, - reference: schemaStringArray, - }), - technique: rt.partial({ - id: schemaStringArray, - name: schemaStringArray, - reference: schemaStringArray, - subtechnique: rt.partial({ - id: schemaStringArray, - name: schemaStringArray, - reference: schemaStringArray, - }), - }), - }), - tls: rt.partial({ - cipher: schemaString, - client: rt.partial({ - certificate: schemaString, - certificate_chain: schemaStringArray, - hash: rt.partial({ - md5: schemaString, - sha1: schemaString, - sha256: schemaString, - }), - issuer: schemaString, - ja3: schemaString, - not_after: schemaDate, - not_before: schemaDate, - server_name: schemaString, - subject: schemaString, - supported_ciphers: schemaStringArray, - x509: rt.partial({ - alternative_names: schemaStringArray, - issuer: rt.partial({ - common_name: schemaStringArray, - country: schemaStringArray, - distinguished_name: schemaString, - locality: schemaStringArray, - organization: schemaStringArray, - organizational_unit: schemaStringArray, - state_or_province: schemaStringArray, - }), - not_after: schemaDate, - not_before: schemaDate, - public_key_algorithm: schemaString, - public_key_curve: schemaString, - public_key_exponent: schemaStringOrNumber, - public_key_size: schemaStringOrNumber, - serial_number: schemaString, - signature_algorithm: schemaString, - subject: rt.partial({ - common_name: schemaStringArray, - country: schemaStringArray, - distinguished_name: schemaString, - locality: schemaStringArray, - organization: schemaStringArray, - organizational_unit: schemaStringArray, - state_or_province: schemaStringArray, - }), - version_number: schemaString, - }), - }), - curve: schemaString, - established: schemaBoolean, - next_protocol: schemaString, - resumed: schemaBoolean, - server: rt.partial({ - certificate: schemaString, - certificate_chain: schemaStringArray, - hash: rt.partial({ - md5: schemaString, - sha1: schemaString, - sha256: schemaString, - }), - issuer: schemaString, - ja3s: schemaString, - not_after: schemaDate, - not_before: schemaDate, - subject: schemaString, - x509: rt.partial({ - alternative_names: schemaStringArray, - issuer: rt.partial({ - common_name: schemaStringArray, - country: schemaStringArray, - distinguished_name: schemaString, - locality: schemaStringArray, - organization: schemaStringArray, - organizational_unit: schemaStringArray, - state_or_province: schemaStringArray, - }), - not_after: schemaDate, - not_before: schemaDate, - public_key_algorithm: schemaString, - public_key_curve: schemaString, - public_key_exponent: schemaStringOrNumber, - public_key_size: schemaStringOrNumber, - serial_number: schemaString, - signature_algorithm: schemaString, - subject: rt.partial({ - common_name: schemaStringArray, - country: schemaStringArray, - distinguished_name: schemaString, - locality: schemaStringArray, - organization: schemaStringArray, - organizational_unit: schemaStringArray, - state_or_province: schemaStringArray, - }), - version_number: schemaString, - }), - }), - version: schemaString, - version_protocol: schemaString, - }), - trace: rt.partial({ - id: schemaString, - }), - transaction: rt.partial({ - id: schemaString, - }), - url: rt.partial({ - domain: schemaString, - extension: schemaString, - fragment: schemaString, - full: schemaString, - original: schemaString, - password: schemaString, - path: schemaString, - port: schemaStringOrNumber, - query: schemaString, - registered_domain: schemaString, - scheme: schemaString, - subdomain: schemaString, - top_level_domain: schemaString, - username: schemaString, - }), - user: rt.partial({ - changes: rt.partial({ - domain: schemaString, - email: schemaString, - full_name: schemaString, - group: rt.partial({ - domain: schemaString, - id: schemaString, - name: schemaString, - }), - hash: schemaString, - id: schemaString, - name: schemaString, - roles: schemaStringArray, - }), - domain: schemaString, - effective: rt.partial({ - domain: schemaString, - email: schemaString, - full_name: schemaString, - group: rt.partial({ - domain: schemaString, - id: schemaString, - name: schemaString, - }), - hash: schemaString, - id: schemaString, - name: schemaString, - roles: schemaStringArray, - }), - email: schemaString, - full_name: schemaString, - group: rt.partial({ - domain: schemaString, - id: schemaString, - name: schemaString, - }), - hash: schemaString, - id: schemaString, - name: schemaString, - risk: rt.partial({ - calculated_level: schemaString, - calculated_score: schemaNumber, - calculated_score_norm: schemaNumber, - static_level: schemaString, - static_score: schemaNumber, - static_score_norm: schemaNumber, - }), - roles: schemaStringArray, - target: rt.partial({ - domain: schemaString, - email: schemaString, - full_name: schemaString, - group: rt.partial({ - domain: schemaString, - id: schemaString, - name: schemaString, - }), - hash: schemaString, - id: schemaString, - name: schemaString, - roles: schemaStringArray, - }), - }), - user_agent: rt.partial({ - device: rt.partial({ - name: schemaString, - }), - name: schemaString, - original: schemaString, - os: rt.partial({ - family: schemaString, - full: schemaString, - kernel: schemaString, - name: schemaString, - platform: schemaString, + virtual_address: schemaStringOrNumber, + virtual_size: schemaStringOrNumber, + }) + ), + 'threat.indicator.file.elf.segments': rt.array( + rt.partial({ + sections: schemaString, type: schemaString, - version: schemaString, - }), - version: schemaString, - }), - vulnerability: rt.partial({ - category: schemaStringArray, - classification: schemaString, - description: schemaString, - enumeration: schemaString, - id: schemaString, - reference: schemaString, - report_id: schemaString, - scanner: rt.partial({ - vendor: schemaString, - }), - score: rt.partial({ - base: schemaNumber, - environmental: schemaNumber, - temporal: schemaNumber, - version: schemaString, - }), - severity: schemaString, - }), + }) + ), + 'threat.indicator.file.elf.shared_libraries': schemaStringArray, + 'threat.indicator.file.elf.telfhash': schemaString, + 'threat.indicator.file.extension': schemaString, + 'threat.indicator.file.fork_name': schemaString, + 'threat.indicator.file.gid': schemaString, + 'threat.indicator.file.group': schemaString, + 'threat.indicator.file.hash.md5': schemaString, + 'threat.indicator.file.hash.sha1': schemaString, + 'threat.indicator.file.hash.sha256': schemaString, + 'threat.indicator.file.hash.sha384': schemaString, + 'threat.indicator.file.hash.sha512': schemaString, + 'threat.indicator.file.hash.ssdeep': schemaString, + 'threat.indicator.file.hash.tlsh': schemaString, + 'threat.indicator.file.inode': schemaString, + 'threat.indicator.file.mime_type': schemaString, + 'threat.indicator.file.mode': schemaString, + 'threat.indicator.file.mtime': schemaDate, + 'threat.indicator.file.name': schemaString, + 'threat.indicator.file.owner': schemaString, + 'threat.indicator.file.path': schemaString, + 'threat.indicator.file.pe.architecture': schemaString, + 'threat.indicator.file.pe.company': schemaString, + 'threat.indicator.file.pe.description': schemaString, + 'threat.indicator.file.pe.file_version': schemaString, + 'threat.indicator.file.pe.imphash': schemaString, + 'threat.indicator.file.pe.original_file_name': schemaString, + 'threat.indicator.file.pe.pehash': schemaString, + 'threat.indicator.file.pe.product': schemaString, + 'threat.indicator.file.size': schemaStringOrNumber, + 'threat.indicator.file.target_path': schemaString, + 'threat.indicator.file.type': schemaString, + 'threat.indicator.file.uid': schemaString, + 'threat.indicator.file.x509.alternative_names': schemaStringArray, + 'threat.indicator.file.x509.issuer.common_name': schemaStringArray, + 'threat.indicator.file.x509.issuer.country': schemaStringArray, + 'threat.indicator.file.x509.issuer.distinguished_name': schemaString, + 'threat.indicator.file.x509.issuer.locality': schemaStringArray, + 'threat.indicator.file.x509.issuer.organization': schemaStringArray, + 'threat.indicator.file.x509.issuer.organizational_unit': schemaStringArray, + 'threat.indicator.file.x509.issuer.state_or_province': schemaStringArray, + 'threat.indicator.file.x509.not_after': schemaDate, + 'threat.indicator.file.x509.not_before': schemaDate, + 'threat.indicator.file.x509.public_key_algorithm': schemaString, + 'threat.indicator.file.x509.public_key_curve': schemaString, + 'threat.indicator.file.x509.public_key_exponent': schemaStringOrNumber, + 'threat.indicator.file.x509.public_key_size': schemaStringOrNumber, + 'threat.indicator.file.x509.serial_number': schemaString, + 'threat.indicator.file.x509.signature_algorithm': schemaString, + 'threat.indicator.file.x509.subject.common_name': schemaStringArray, + 'threat.indicator.file.x509.subject.country': schemaStringArray, + 'threat.indicator.file.x509.subject.distinguished_name': schemaString, + 'threat.indicator.file.x509.subject.locality': schemaStringArray, + 'threat.indicator.file.x509.subject.organization': schemaStringArray, + 'threat.indicator.file.x509.subject.organizational_unit': schemaStringArray, + 'threat.indicator.file.x509.subject.state_or_province': schemaStringArray, + 'threat.indicator.file.x509.version_number': schemaString, + 'threat.indicator.first_seen': schemaDate, + 'threat.indicator.geo.city_name': schemaString, + 'threat.indicator.geo.continent_code': schemaString, + 'threat.indicator.geo.continent_name': schemaString, + 'threat.indicator.geo.country_iso_code': schemaString, + 'threat.indicator.geo.country_name': schemaString, + 'threat.indicator.geo.location': schemaGeoPoint, + 'threat.indicator.geo.name': schemaString, + 'threat.indicator.geo.postal_code': schemaString, + 'threat.indicator.geo.region_iso_code': schemaString, + 'threat.indicator.geo.region_name': schemaString, + 'threat.indicator.geo.timezone': schemaString, + 'threat.indicator.ip': schemaString, + 'threat.indicator.last_seen': schemaDate, + 'threat.indicator.marking.tlp': schemaString, + 'threat.indicator.marking.tlp_version': schemaString, + 'threat.indicator.modified_at': schemaDate, + 'threat.indicator.port': schemaStringOrNumber, + 'threat.indicator.provider': schemaString, + 'threat.indicator.reference': schemaString, + 'threat.indicator.registry.data.bytes': schemaString, + 'threat.indicator.registry.data.strings': schemaStringArray, + 'threat.indicator.registry.data.type': schemaString, + 'threat.indicator.registry.hive': schemaString, + 'threat.indicator.registry.key': schemaString, + 'threat.indicator.registry.path': schemaString, + 'threat.indicator.registry.value': schemaString, + 'threat.indicator.scanner_stats': schemaStringOrNumber, + 'threat.indicator.sightings': schemaStringOrNumber, + 'threat.indicator.type': schemaString, + 'threat.indicator.url.domain': schemaString, + 'threat.indicator.url.extension': schemaString, + 'threat.indicator.url.fragment': schemaString, + 'threat.indicator.url.full': schemaString, + 'threat.indicator.url.original': schemaString, + 'threat.indicator.url.password': schemaString, + 'threat.indicator.url.path': schemaString, + 'threat.indicator.url.port': schemaStringOrNumber, + 'threat.indicator.url.query': schemaString, + 'threat.indicator.url.registered_domain': schemaString, + 'threat.indicator.url.scheme': schemaString, + 'threat.indicator.url.subdomain': schemaString, + 'threat.indicator.url.top_level_domain': schemaString, + 'threat.indicator.url.username': schemaString, + 'threat.indicator.x509.alternative_names': schemaStringArray, + 'threat.indicator.x509.issuer.common_name': schemaStringArray, + 'threat.indicator.x509.issuer.country': schemaStringArray, + 'threat.indicator.x509.issuer.distinguished_name': schemaString, + 'threat.indicator.x509.issuer.locality': schemaStringArray, + 'threat.indicator.x509.issuer.organization': schemaStringArray, + 'threat.indicator.x509.issuer.organizational_unit': schemaStringArray, + 'threat.indicator.x509.issuer.state_or_province': schemaStringArray, + 'threat.indicator.x509.not_after': schemaDate, + 'threat.indicator.x509.not_before': schemaDate, + 'threat.indicator.x509.public_key_algorithm': schemaString, + 'threat.indicator.x509.public_key_curve': schemaString, + 'threat.indicator.x509.public_key_exponent': schemaStringOrNumber, + 'threat.indicator.x509.public_key_size': schemaStringOrNumber, + 'threat.indicator.x509.serial_number': schemaString, + 'threat.indicator.x509.signature_algorithm': schemaString, + 'threat.indicator.x509.subject.common_name': schemaStringArray, + 'threat.indicator.x509.subject.country': schemaStringArray, + 'threat.indicator.x509.subject.distinguished_name': schemaString, + 'threat.indicator.x509.subject.locality': schemaStringArray, + 'threat.indicator.x509.subject.organization': schemaStringArray, + 'threat.indicator.x509.subject.organizational_unit': schemaStringArray, + 'threat.indicator.x509.subject.state_or_province': schemaStringArray, + 'threat.indicator.x509.version_number': schemaString, + 'threat.software.alias': schemaStringArray, + 'threat.software.id': schemaString, + 'threat.software.name': schemaString, + 'threat.software.platforms': schemaStringArray, + 'threat.software.reference': schemaString, + 'threat.software.type': schemaString, + 'threat.tactic.id': schemaStringArray, + 'threat.tactic.name': schemaStringArray, + 'threat.tactic.reference': schemaStringArray, + 'threat.technique.id': schemaStringArray, + 'threat.technique.name': schemaStringArray, + 'threat.technique.reference': schemaStringArray, + 'threat.technique.subtechnique.id': schemaStringArray, + 'threat.technique.subtechnique.name': schemaStringArray, + 'threat.technique.subtechnique.reference': schemaStringArray, + 'tls.cipher': schemaString, + 'tls.client.certificate': schemaString, + 'tls.client.certificate_chain': schemaStringArray, + 'tls.client.hash.md5': schemaString, + 'tls.client.hash.sha1': schemaString, + 'tls.client.hash.sha256': schemaString, + 'tls.client.issuer': schemaString, + 'tls.client.ja3': schemaString, + 'tls.client.not_after': schemaDate, + 'tls.client.not_before': schemaDate, + 'tls.client.server_name': schemaString, + 'tls.client.subject': schemaString, + 'tls.client.supported_ciphers': schemaStringArray, + 'tls.client.x509.alternative_names': schemaStringArray, + 'tls.client.x509.issuer.common_name': schemaStringArray, + 'tls.client.x509.issuer.country': schemaStringArray, + 'tls.client.x509.issuer.distinguished_name': schemaString, + 'tls.client.x509.issuer.locality': schemaStringArray, + 'tls.client.x509.issuer.organization': schemaStringArray, + 'tls.client.x509.issuer.organizational_unit': schemaStringArray, + 'tls.client.x509.issuer.state_or_province': schemaStringArray, + 'tls.client.x509.not_after': schemaDate, + 'tls.client.x509.not_before': schemaDate, + 'tls.client.x509.public_key_algorithm': schemaString, + 'tls.client.x509.public_key_curve': schemaString, + 'tls.client.x509.public_key_exponent': schemaStringOrNumber, + 'tls.client.x509.public_key_size': schemaStringOrNumber, + 'tls.client.x509.serial_number': schemaString, + 'tls.client.x509.signature_algorithm': schemaString, + 'tls.client.x509.subject.common_name': schemaStringArray, + 'tls.client.x509.subject.country': schemaStringArray, + 'tls.client.x509.subject.distinguished_name': schemaString, + 'tls.client.x509.subject.locality': schemaStringArray, + 'tls.client.x509.subject.organization': schemaStringArray, + 'tls.client.x509.subject.organizational_unit': schemaStringArray, + 'tls.client.x509.subject.state_or_province': schemaStringArray, + 'tls.client.x509.version_number': schemaString, + 'tls.curve': schemaString, + 'tls.established': schemaBoolean, + 'tls.next_protocol': schemaString, + 'tls.resumed': schemaBoolean, + 'tls.server.certificate': schemaString, + 'tls.server.certificate_chain': schemaStringArray, + 'tls.server.hash.md5': schemaString, + 'tls.server.hash.sha1': schemaString, + 'tls.server.hash.sha256': schemaString, + 'tls.server.issuer': schemaString, + 'tls.server.ja3s': schemaString, + 'tls.server.not_after': schemaDate, + 'tls.server.not_before': schemaDate, + 'tls.server.subject': schemaString, + 'tls.server.x509.alternative_names': schemaStringArray, + 'tls.server.x509.issuer.common_name': schemaStringArray, + 'tls.server.x509.issuer.country': schemaStringArray, + 'tls.server.x509.issuer.distinguished_name': schemaString, + 'tls.server.x509.issuer.locality': schemaStringArray, + 'tls.server.x509.issuer.organization': schemaStringArray, + 'tls.server.x509.issuer.organizational_unit': schemaStringArray, + 'tls.server.x509.issuer.state_or_province': schemaStringArray, + 'tls.server.x509.not_after': schemaDate, + 'tls.server.x509.not_before': schemaDate, + 'tls.server.x509.public_key_algorithm': schemaString, + 'tls.server.x509.public_key_curve': schemaString, + 'tls.server.x509.public_key_exponent': schemaStringOrNumber, + 'tls.server.x509.public_key_size': schemaStringOrNumber, + 'tls.server.x509.serial_number': schemaString, + 'tls.server.x509.signature_algorithm': schemaString, + 'tls.server.x509.subject.common_name': schemaStringArray, + 'tls.server.x509.subject.country': schemaStringArray, + 'tls.server.x509.subject.distinguished_name': schemaString, + 'tls.server.x509.subject.locality': schemaStringArray, + 'tls.server.x509.subject.organization': schemaStringArray, + 'tls.server.x509.subject.organizational_unit': schemaStringArray, + 'tls.server.x509.subject.state_or_province': schemaStringArray, + 'tls.server.x509.version_number': schemaString, + 'tls.version': schemaString, + 'tls.version_protocol': schemaString, + 'trace.id': schemaString, + 'transaction.id': schemaString, + 'url.domain': schemaString, + 'url.extension': schemaString, + 'url.fragment': schemaString, + 'url.full': schemaString, + 'url.original': schemaString, + 'url.password': schemaString, + 'url.path': schemaString, + 'url.port': schemaStringOrNumber, + 'url.query': schemaString, + 'url.registered_domain': schemaString, + 'url.scheme': schemaString, + 'url.subdomain': schemaString, + 'url.top_level_domain': schemaString, + 'url.username': schemaString, + 'user.changes.domain': schemaString, + 'user.changes.email': schemaString, + 'user.changes.full_name': schemaString, + 'user.changes.group.domain': schemaString, + 'user.changes.group.id': schemaString, + 'user.changes.group.name': schemaString, + 'user.changes.hash': schemaString, + 'user.changes.id': schemaString, + 'user.changes.name': schemaString, + 'user.changes.roles': schemaStringArray, + 'user.domain': schemaString, + 'user.effective.domain': schemaString, + 'user.effective.email': schemaString, + 'user.effective.full_name': schemaString, + 'user.effective.group.domain': schemaString, + 'user.effective.group.id': schemaString, + 'user.effective.group.name': schemaString, + 'user.effective.hash': schemaString, + 'user.effective.id': schemaString, + 'user.effective.name': schemaString, + 'user.effective.roles': schemaStringArray, + 'user.email': schemaString, + 'user.full_name': schemaString, + 'user.group.domain': schemaString, + 'user.group.id': schemaString, + 'user.group.name': schemaString, + 'user.hash': schemaString, + 'user.id': schemaString, + 'user.name': schemaString, + 'user.risk.calculated_level': schemaString, + 'user.risk.calculated_score': schemaNumber, + 'user.risk.calculated_score_norm': schemaNumber, + 'user.risk.static_level': schemaString, + 'user.risk.static_score': schemaNumber, + 'user.risk.static_score_norm': schemaNumber, + 'user.roles': schemaStringArray, + 'user.target.domain': schemaString, + 'user.target.email': schemaString, + 'user.target.full_name': schemaString, + 'user.target.group.domain': schemaString, + 'user.target.group.id': schemaString, + 'user.target.group.name': schemaString, + 'user.target.hash': schemaString, + 'user.target.id': schemaString, + 'user.target.name': schemaString, + 'user.target.roles': schemaStringArray, + 'user_agent.device.name': schemaString, + 'user_agent.name': schemaString, + 'user_agent.original': schemaString, + 'user_agent.os.family': schemaString, + 'user_agent.os.full': schemaString, + 'user_agent.os.kernel': schemaString, + 'user_agent.os.name': schemaString, + 'user_agent.os.platform': schemaString, + 'user_agent.os.type': schemaString, + 'user_agent.os.version': schemaString, + 'user_agent.version': schemaString, + 'vulnerability.category': schemaStringArray, + 'vulnerability.classification': schemaString, + 'vulnerability.description': schemaString, + 'vulnerability.enumeration': schemaString, + 'vulnerability.id': schemaString, + 'vulnerability.reference': schemaString, + 'vulnerability.report_id': schemaString, + 'vulnerability.scanner.vendor': schemaString, + 'vulnerability.score.base': schemaNumber, + 'vulnerability.score.environmental': schemaNumber, + 'vulnerability.score.temporal': schemaNumber, + 'vulnerability.score.version': schemaString, + 'vulnerability.severity': schemaString, }); // prettier-ignore diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/legacy_alert_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/legacy_alert_schema.ts index 107cdd65464bc..54298bacc919b 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/legacy_alert_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/legacy_alert_schema.ts @@ -69,46 +69,34 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint); const LegacyAlertRequired = rt.type({ }); const LegacyAlertOptional = rt.partial({ - ecs: rt.partial({ - version: schemaString, - }), - kibana: rt.partial({ - alert: rt.partial({ - risk_score: schemaNumber, - rule: rt.partial({ - author: schemaString, - created_at: schemaDate, - created_by: schemaString, - description: schemaString, - enabled: schemaString, - from: schemaString, - interval: schemaString, - license: schemaString, - note: schemaString, - references: schemaStringArray, - rule_id: schemaString, - rule_name_override: schemaString, - to: schemaString, - type: schemaString, - updated_at: schemaDate, - updated_by: schemaString, - version: schemaString, - }), - severity: schemaString, - suppression: rt.partial({ - docs_count: schemaStringOrNumber, - end: schemaDate, - start: schemaDate, - terms: rt.partial({ - field: schemaStringArray, - value: schemaStringArray, - }), - }), - system_status: schemaString, - workflow_reason: schemaString, - workflow_user: schemaString, - }), - }), + 'ecs.version': schemaString, + 'kibana.alert.risk_score': schemaNumber, + 'kibana.alert.rule.author': schemaString, + 'kibana.alert.rule.created_at': schemaDate, + 'kibana.alert.rule.created_by': schemaString, + 'kibana.alert.rule.description': schemaString, + 'kibana.alert.rule.enabled': schemaString, + 'kibana.alert.rule.from': schemaString, + 'kibana.alert.rule.interval': schemaString, + 'kibana.alert.rule.license': schemaString, + 'kibana.alert.rule.note': schemaString, + 'kibana.alert.rule.references': schemaStringArray, + 'kibana.alert.rule.rule_id': schemaString, + 'kibana.alert.rule.rule_name_override': schemaString, + 'kibana.alert.rule.to': schemaString, + 'kibana.alert.rule.type': schemaString, + 'kibana.alert.rule.updated_at': schemaDate, + 'kibana.alert.rule.updated_by': schemaString, + 'kibana.alert.rule.version': schemaString, + 'kibana.alert.severity': schemaString, + 'kibana.alert.suppression.docs_count': schemaStringOrNumber, + 'kibana.alert.suppression.end': schemaDate, + 'kibana.alert.suppression.start': schemaDate, + 'kibana.alert.suppression.terms.field': schemaStringArray, + 'kibana.alert.suppression.terms.value': schemaStringArray, + 'kibana.alert.system_status': schemaString, + 'kibana.alert.workflow_reason': schemaString, + 'kibana.alert.workflow_user': schemaString, }); // prettier-ignore diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/ml_anomaly_detection_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/ml_anomaly_detection_schema.ts index 2e5912bca84c2..0c80cef15237f 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/ml_anomaly_detection_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/ml_anomaly_detection_schema.ts @@ -67,51 +67,43 @@ export const schemaGeoPoint = rt.union([ export const schemaGeoPointArray = rt.array(schemaGeoPoint); // prettier-ignore const MlAnomalyDetectionAlertRequired = rt.type({ - kibana: rt.type({ - alert: rt.type({ - job_id: schemaString, - }), - }), + 'kibana.alert.job_id': schemaString, }); const MlAnomalyDetectionAlertOptional = rt.partial({ - kibana: rt.partial({ - alert: rt.partial({ - anomaly_score: schemaNumber, - anomaly_timestamp: schemaDate, + 'kibana.alert.anomaly_score': schemaNumber, + 'kibana.alert.anomaly_timestamp': schemaDate, + 'kibana.alert.is_interim': schemaBoolean, + 'kibana.alert.top_influencers': rt.array( + rt.partial({ + influencer_field_name: schemaString, + influencer_field_value: schemaString, + influencer_score: schemaNumber, + initial_influencer_score: schemaNumber, + is_interim: schemaBoolean, + job_id: schemaString, + timestamp: schemaDate, + }) + ), + 'kibana.alert.top_records': rt.array( + rt.partial({ + actual: schemaNumber, + by_field_name: schemaString, + by_field_value: schemaString, + detector_index: schemaNumber, + field_name: schemaString, + function: schemaString, + initial_record_score: schemaNumber, is_interim: schemaBoolean, - top_influencers: rt.array( - rt.partial({ - influencer_field_name: schemaString, - influencer_field_value: schemaString, - influencer_score: schemaNumber, - initial_influencer_score: schemaNumber, - is_interim: schemaBoolean, - job_id: schemaString, - timestamp: schemaDate, - }) - ), - top_records: rt.array( - rt.partial({ - actual: schemaNumber, - by_field_name: schemaString, - by_field_value: schemaString, - detector_index: schemaNumber, - field_name: schemaString, - function: schemaString, - initial_record_score: schemaNumber, - is_interim: schemaBoolean, - job_id: schemaString, - over_field_name: schemaString, - over_field_value: schemaString, - partition_field_name: schemaString, - partition_field_value: schemaString, - record_score: schemaNumber, - timestamp: schemaDate, - typical: schemaNumber, - }) - ), - }), - }), + job_id: schemaString, + over_field_name: schemaString, + over_field_value: schemaString, + partition_field_name: schemaString, + partition_field_value: schemaString, + record_score: schemaNumber, + timestamp: schemaDate, + typical: schemaNumber, + }) + ), }); // prettier-ignore diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_apm_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_apm_schema.ts index 813ce72f84505..73a0f3c100c20 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_apm_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_apm_schema.ts @@ -70,36 +70,18 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint); const ObservabilityApmAlertRequired = rt.type({ }); const ObservabilityApmAlertOptional = rt.partial({ - agent: rt.partial({ - name: schemaString, - }), - error: rt.partial({ - grouping_key: schemaString, - grouping_name: schemaString, - }), - kibana: rt.partial({ - alert: rt.partial({ - evaluation: rt.partial({ - threshold: schemaStringOrNumber, - value: schemaStringOrNumber, - values: schemaStringOrNumberArray, - }), - }), - }), - processor: rt.partial({ - event: schemaString, - }), - service: rt.partial({ - environment: schemaString, - language: rt.partial({ - name: schemaString, - }), - name: schemaString, - }), - transaction: rt.partial({ - name: schemaString, - type: schemaString, - }), + 'agent.name': schemaString, + 'error.grouping_key': schemaString, + 'error.grouping_name': schemaString, + 'kibana.alert.evaluation.threshold': schemaStringOrNumber, + 'kibana.alert.evaluation.value': schemaStringOrNumber, + 'kibana.alert.evaluation.values': schemaStringOrNumberArray, + 'processor.event': schemaString, + 'service.environment': schemaString, + 'service.language.name': schemaString, + 'service.name': schemaString, + 'transaction.name': schemaString, + 'transaction.type': schemaString, }); // prettier-ignore diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_logs_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_logs_schema.ts index 1b824c7c41d24..1cd10f1367d69 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_logs_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_logs_schema.ts @@ -71,15 +71,9 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint); const ObservabilityLogsAlertRequired = rt.type({ }); const ObservabilityLogsAlertOptional = rt.partial({ - kibana: rt.partial({ - alert: rt.partial({ - evaluation: rt.partial({ - threshold: schemaStringOrNumber, - value: schemaStringOrNumber, - values: schemaStringOrNumberArray, - }), - }), - }), + 'kibana.alert.evaluation.threshold': schemaStringOrNumber, + 'kibana.alert.evaluation.value': schemaStringOrNumber, + 'kibana.alert.evaluation.values': schemaStringOrNumberArray, }); // prettier-ignore diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_metrics_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_metrics_schema.ts index d2b887ff6a845..ec5feb7caf445 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_metrics_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_metrics_schema.ts @@ -71,15 +71,9 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint); const ObservabilityMetricsAlertRequired = rt.type({ }); const ObservabilityMetricsAlertOptional = rt.partial({ - kibana: rt.partial({ - alert: rt.partial({ - evaluation: rt.partial({ - threshold: schemaStringOrNumber, - value: schemaStringOrNumber, - values: schemaStringOrNumberArray, - }), - }), - }), + 'kibana.alert.evaluation.threshold': schemaStringOrNumber, + 'kibana.alert.evaluation.value': schemaStringOrNumber, + 'kibana.alert.evaluation.values': schemaStringOrNumberArray, }); // prettier-ignore diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_slo_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_slo_schema.ts index 82ce866631583..ea27af5f613d9 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_slo_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_slo_schema.ts @@ -70,20 +70,12 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint); const ObservabilitySloAlertRequired = rt.type({ }); const ObservabilitySloAlertOptional = rt.partial({ - kibana: rt.partial({ - alert: rt.partial({ - evaluation: rt.partial({ - threshold: schemaStringOrNumber, - value: schemaStringOrNumber, - values: schemaStringOrNumberArray, - }), - }), - }), - slo: rt.partial({ - id: schemaString, - instanceId: schemaString, - revision: schemaStringOrNumber, - }), + 'kibana.alert.evaluation.threshold': schemaStringOrNumber, + 'kibana.alert.evaluation.value': schemaStringOrNumber, + 'kibana.alert.evaluation.values': schemaStringOrNumberArray, + 'slo.id': schemaString, + 'slo.instanceId': schemaString, + 'slo.revision': schemaStringOrNumber, }); // prettier-ignore diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_uptime_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_uptime_schema.ts index e2bc5b755ad23..59d04ea38479b 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_uptime_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_uptime_schema.ts @@ -70,57 +70,23 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint); const ObservabilityUptimeAlertRequired = rt.type({ }); const ObservabilityUptimeAlertOptional = rt.partial({ - agent: rt.partial({ - name: schemaString, - }), - anomaly: rt.partial({ - bucket_span: rt.partial({ - minutes: schemaString, - }), - start: schemaDate, - }), - error: rt.partial({ - message: schemaString, - }), - kibana: rt.partial({ - alert: rt.partial({ - evaluation: rt.partial({ - threshold: schemaStringOrNumber, - value: schemaStringOrNumber, - values: schemaStringOrNumberArray, - }), - }), - }), - monitor: rt.partial({ - id: schemaString, - name: schemaString, - type: schemaString, - }), - observer: rt.partial({ - geo: rt.partial({ - name: schemaString, - }), - }), - tls: rt.partial({ - server: rt.partial({ - hash: rt.partial({ - sha256: schemaString, - }), - x509: rt.partial({ - issuer: rt.partial({ - common_name: schemaString, - }), - not_after: schemaDate, - not_before: schemaDate, - subject: rt.partial({ - common_name: schemaString, - }), - }), - }), - }), - url: rt.partial({ - full: schemaString, - }), + 'agent.name': schemaString, + 'anomaly.bucket_span.minutes': schemaString, + 'anomaly.start': schemaDate, + 'error.message': schemaString, + 'kibana.alert.evaluation.threshold': schemaStringOrNumber, + 'kibana.alert.evaluation.value': schemaStringOrNumber, + 'kibana.alert.evaluation.values': schemaStringOrNumberArray, + 'monitor.id': schemaString, + 'monitor.name': schemaString, + 'monitor.type': schemaString, + 'observer.geo.name': schemaString, + 'tls.server.hash.sha256': schemaString, + 'tls.server.x509.issuer.common_name': schemaString, + 'tls.server.x509.not_after': schemaDate, + 'tls.server.x509.not_before': schemaDate, + 'tls.server.x509.subject.common_name': schemaString, + 'url.full': schemaString, }); // prettier-ignore diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/security_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/security_schema.ts index 03124f6bef160..28bb73fb99643 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/security_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/security_schema.ts @@ -70,277 +70,133 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint); // prettier-ignore const SecurityAlertRequired = rt.type({ '@timestamp': schemaDate, - kibana: rt.type({ - alert: rt.type({ - ancestors: rt.array( - rt.type({ - depth: schemaStringOrNumber, - id: schemaString, - index: schemaString, - type: schemaString, - }) - ), + 'kibana.alert.ancestors': rt.array( + rt.type({ depth: schemaStringOrNumber, - instance: rt.type({ - id: schemaString, - }), - original_event: rt.type({ - action: schemaString, - category: schemaStringArray, - created: schemaDate, - dataset: schemaString, - id: schemaString, - ingested: schemaDate, - kind: schemaString, - module: schemaString, - original: schemaString, - outcome: schemaString, - provider: schemaString, - sequence: schemaStringOrNumber, - type: schemaStringArray, - }), - original_time: schemaDate, - rule: rt.type({ - category: schemaString, - consumer: schemaString, - false_positives: schemaStringArray, - max_signals: schemaStringOrNumberArray, - name: schemaString, - producer: schemaString, - revision: schemaStringOrNumber, - rule_type_id: schemaString, - threat: rt.type({ - framework: schemaString, - tactic: rt.type({ - id: schemaString, - name: schemaString, - reference: schemaString, - }), - technique: rt.type({ - id: schemaString, - name: schemaString, - reference: schemaString, - subtechnique: rt.type({ - id: schemaString, - name: schemaString, - reference: schemaString, - }), - }), - }), - uuid: schemaString, - }), - status: schemaString, - uuid: schemaString, - }), - space_ids: schemaStringArray, - }), + id: schemaString, + index: schemaString, + type: schemaString, + }) + ), + 'kibana.alert.depth': schemaStringOrNumber, + 'kibana.alert.instance.id': schemaString, + 'kibana.alert.original_event.action': schemaString, + 'kibana.alert.original_event.category': schemaStringArray, + 'kibana.alert.original_event.created': schemaDate, + 'kibana.alert.original_event.dataset': schemaString, + 'kibana.alert.original_event.id': schemaString, + 'kibana.alert.original_event.ingested': schemaDate, + 'kibana.alert.original_event.kind': schemaString, + 'kibana.alert.original_event.module': schemaString, + 'kibana.alert.original_event.original': schemaString, + 'kibana.alert.original_event.outcome': schemaString, + 'kibana.alert.original_event.provider': schemaString, + 'kibana.alert.original_event.sequence': schemaStringOrNumber, + 'kibana.alert.original_event.type': schemaStringArray, + 'kibana.alert.original_time': schemaDate, + 'kibana.alert.rule.category': schemaString, + 'kibana.alert.rule.consumer': schemaString, + 'kibana.alert.rule.false_positives': schemaStringArray, + 'kibana.alert.rule.max_signals': schemaStringOrNumberArray, + 'kibana.alert.rule.name': schemaString, + 'kibana.alert.rule.producer': schemaString, + 'kibana.alert.rule.revision': schemaStringOrNumber, + 'kibana.alert.rule.rule_type_id': schemaString, + 'kibana.alert.rule.threat.framework': schemaString, + 'kibana.alert.rule.threat.tactic.id': schemaString, + 'kibana.alert.rule.threat.tactic.name': schemaString, + 'kibana.alert.rule.threat.tactic.reference': schemaString, + 'kibana.alert.rule.threat.technique.id': schemaString, + 'kibana.alert.rule.threat.technique.name': schemaString, + 'kibana.alert.rule.threat.technique.reference': schemaString, + 'kibana.alert.rule.threat.technique.subtechnique.id': schemaString, + 'kibana.alert.rule.threat.technique.subtechnique.name': schemaString, + 'kibana.alert.rule.threat.technique.subtechnique.reference': schemaString, + 'kibana.alert.rule.uuid': schemaString, + 'kibana.alert.status': schemaString, + 'kibana.alert.uuid': schemaString, + 'kibana.space_ids': schemaStringArray, }); const SecurityAlertOptional = rt.partial({ - ecs: rt.partial({ - version: schemaString, - }), - event: rt.partial({ - action: schemaString, - kind: schemaString, - }), - kibana: rt.partial({ - alert: rt.partial({ - action_group: schemaString, - ancestors: rt.partial({ - rule: schemaString, - }), - building_block_type: schemaString, - case_ids: schemaStringArray, - duration: rt.partial({ - us: schemaStringOrNumber, - }), - end: schemaDate, - flapping: schemaBoolean, - flapping_history: schemaBooleanArray, - group: rt.partial({ - id: schemaString, - index: schemaNumber, - }), - last_detected: schemaDate, - maintenance_window_ids: schemaStringArray, - new_terms: schemaStringArray, - original_event: rt.partial({ - agent_id_status: schemaString, - code: schemaString, - duration: schemaString, - end: schemaDate, - hash: schemaString, - reason: schemaString, - reference: schemaString, - risk_score: schemaNumber, - risk_score_norm: schemaNumber, - severity: schemaStringOrNumber, - start: schemaDate, - timezone: schemaString, - url: schemaString, - }), - reason: schemaString, - risk_score: schemaNumber, - rule: rt.partial({ - author: schemaString, - building_block_type: schemaString, - created_at: schemaDate, - created_by: schemaString, - description: schemaString, - enabled: schemaString, - execution: rt.partial({ - uuid: schemaString, - }), - from: schemaString, - immutable: schemaStringArray, - interval: schemaString, - license: schemaString, - note: schemaString, - parameters: schemaUnknown, - references: schemaStringArray, - rule_id: schemaString, - rule_name_override: schemaString, - tags: schemaStringArray, - timeline_id: schemaStringArray, - timeline_title: schemaStringArray, - timestamp_override: schemaString, - to: schemaString, - type: schemaString, - updated_at: schemaDate, - updated_by: schemaString, - version: schemaString, - }), - severity: schemaString, - start: schemaDate, - suppression: rt.partial({ - docs_count: schemaStringOrNumber, - end: schemaDate, - start: schemaDate, - terms: rt.partial({ - field: schemaStringArray, - value: schemaStringArray, - }), - }), - system_status: schemaString, - threshold_result: rt.partial({ - count: schemaStringOrNumber, - from: schemaDate, - terms: rt.array( - rt.partial({ - field: schemaString, - value: schemaString, - }) - ), - }), - time_range: schemaDateRange, - url: schemaString, - workflow_reason: schemaString, - workflow_status: schemaString, - workflow_tags: schemaStringArray, - workflow_user: schemaString, - }), - version: schemaString, - }), - signal: rt.partial({ - ancestors: rt.partial({ - depth: schemaUnknown, - id: schemaUnknown, - index: schemaUnknown, - type: schemaUnknown, - }), - depth: schemaUnknown, - group: rt.partial({ - id: schemaUnknown, - index: schemaUnknown, - }), - original_event: rt.partial({ - action: schemaUnknown, - category: schemaUnknown, - code: schemaUnknown, - created: schemaUnknown, - dataset: schemaUnknown, - duration: schemaUnknown, - end: schemaUnknown, - hash: schemaUnknown, - id: schemaUnknown, - kind: schemaUnknown, - module: schemaUnknown, - outcome: schemaUnknown, - provider: schemaUnknown, - reason: schemaUnknown, - risk_score: schemaUnknown, - risk_score_norm: schemaUnknown, - sequence: schemaUnknown, - severity: schemaUnknown, - start: schemaUnknown, - timezone: schemaUnknown, - type: schemaUnknown, - }), - original_time: schemaUnknown, - reason: schemaUnknown, - rule: rt.partial({ - author: schemaUnknown, - building_block_type: schemaUnknown, - created_at: schemaUnknown, - created_by: schemaUnknown, - description: schemaUnknown, - enabled: schemaUnknown, - false_positives: schemaUnknown, - from: schemaUnknown, - id: schemaUnknown, - immutable: schemaUnknown, - interval: schemaUnknown, - license: schemaUnknown, - max_signals: schemaUnknown, - name: schemaUnknown, - note: schemaUnknown, - references: schemaUnknown, - risk_score: schemaUnknown, - rule_id: schemaUnknown, - rule_name_override: schemaUnknown, - severity: schemaUnknown, - tags: schemaUnknown, - threat: rt.partial({ - framework: schemaUnknown, - tactic: rt.partial({ - id: schemaUnknown, - name: schemaUnknown, - reference: schemaUnknown, - }), - technique: rt.partial({ - id: schemaUnknown, - name: schemaUnknown, - reference: schemaUnknown, - subtechnique: rt.partial({ - id: schemaUnknown, - name: schemaUnknown, - reference: schemaUnknown, - }), - }), - }), - timeline_id: schemaUnknown, - timeline_title: schemaUnknown, - timestamp_override: schemaUnknown, - to: schemaUnknown, - type: schemaUnknown, - updated_at: schemaUnknown, - updated_by: schemaUnknown, - version: schemaUnknown, - }), - status: schemaUnknown, - threshold_result: rt.partial({ - cardinality: rt.partial({ - field: schemaUnknown, - value: schemaUnknown, - }), - count: schemaUnknown, - from: schemaUnknown, - terms: rt.partial({ - field: schemaUnknown, - value: schemaUnknown, - }), - }), - }), + 'ecs.version': schemaString, + 'event.action': schemaString, + 'event.kind': schemaString, + 'kibana.alert.action_group': schemaString, + 'kibana.alert.ancestors.rule': schemaString, + 'kibana.alert.building_block_type': schemaString, + 'kibana.alert.case_ids': schemaStringArray, + 'kibana.alert.duration.us': schemaStringOrNumber, + 'kibana.alert.end': schemaDate, + 'kibana.alert.flapping': schemaBoolean, + 'kibana.alert.flapping_history': schemaBooleanArray, + 'kibana.alert.group.id': schemaString, + 'kibana.alert.group.index': schemaNumber, + 'kibana.alert.last_detected': schemaDate, + 'kibana.alert.maintenance_window_ids': schemaStringArray, + 'kibana.alert.new_terms': schemaStringArray, + 'kibana.alert.original_event.agent_id_status': schemaString, + 'kibana.alert.original_event.code': schemaString, + 'kibana.alert.original_event.duration': schemaString, + 'kibana.alert.original_event.end': schemaDate, + 'kibana.alert.original_event.hash': schemaString, + 'kibana.alert.original_event.reason': schemaString, + 'kibana.alert.original_event.reference': schemaString, + 'kibana.alert.original_event.risk_score': schemaNumber, + 'kibana.alert.original_event.risk_score_norm': schemaNumber, + 'kibana.alert.original_event.severity': schemaStringOrNumber, + 'kibana.alert.original_event.start': schemaDate, + 'kibana.alert.original_event.timezone': schemaString, + 'kibana.alert.original_event.url': schemaString, + 'kibana.alert.reason': schemaString, + 'kibana.alert.risk_score': schemaNumber, + 'kibana.alert.rule.author': schemaString, + 'kibana.alert.rule.building_block_type': schemaString, + 'kibana.alert.rule.created_at': schemaDate, + 'kibana.alert.rule.created_by': schemaString, + 'kibana.alert.rule.description': schemaString, + 'kibana.alert.rule.enabled': schemaString, + 'kibana.alert.rule.execution.uuid': schemaString, + 'kibana.alert.rule.from': schemaString, + 'kibana.alert.rule.immutable': schemaStringArray, + 'kibana.alert.rule.interval': schemaString, + 'kibana.alert.rule.license': schemaString, + 'kibana.alert.rule.note': schemaString, + 'kibana.alert.rule.parameters': schemaUnknown, + 'kibana.alert.rule.references': schemaStringArray, + 'kibana.alert.rule.rule_id': schemaString, + 'kibana.alert.rule.rule_name_override': schemaString, + 'kibana.alert.rule.tags': schemaStringArray, + 'kibana.alert.rule.timeline_id': schemaStringArray, + 'kibana.alert.rule.timeline_title': schemaStringArray, + 'kibana.alert.rule.timestamp_override': schemaString, + 'kibana.alert.rule.to': schemaString, + 'kibana.alert.rule.type': schemaString, + 'kibana.alert.rule.updated_at': schemaDate, + 'kibana.alert.rule.updated_by': schemaString, + 'kibana.alert.rule.version': schemaString, + 'kibana.alert.severity': schemaString, + 'kibana.alert.start': schemaDate, + 'kibana.alert.suppression.docs_count': schemaStringOrNumber, + 'kibana.alert.suppression.end': schemaDate, + 'kibana.alert.suppression.start': schemaDate, + 'kibana.alert.suppression.terms.field': schemaStringArray, + 'kibana.alert.suppression.terms.value': schemaStringArray, + 'kibana.alert.system_status': schemaString, + 'kibana.alert.threshold_result.count': schemaStringOrNumber, + 'kibana.alert.threshold_result.from': schemaDate, + 'kibana.alert.threshold_result.terms': rt.array( + rt.partial({ + field: schemaString, + value: schemaString, + }) + ), + 'kibana.alert.time_range': schemaDateRange, + 'kibana.alert.url': schemaString, + 'kibana.alert.workflow_reason': schemaString, + 'kibana.alert.workflow_status': schemaString, + 'kibana.alert.workflow_tags': schemaStringArray, + 'kibana.alert.workflow_user': schemaString, + 'kibana.version': schemaString, tags: schemaStringArray, }); diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/stack_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/stack_schema.ts index 362d64de05d98..9c62e6094f82c 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/stack_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/stack_schema.ts @@ -69,15 +69,9 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint); const StackAlertRequired = rt.type({ }); const StackAlertOptional = rt.partial({ - kibana: rt.partial({ - alert: rt.partial({ - evaluation: rt.partial({ - conditions: schemaString, - value: schemaString, - }), - title: schemaString, - }), - }), + 'kibana.alert.evaluation.conditions': schemaString, + 'kibana.alert.evaluation.value': schemaString, + 'kibana.alert.title': schemaString, }); // prettier-ignore diff --git a/x-pack/plugins/alerting/server/alert/alert.test.ts b/x-pack/plugins/alerting/server/alert/alert.test.ts index c4db2189e6d26..a0d0ef25f9a86 100644 --- a/x-pack/plugins/alerting/server/alert/alert.test.ts +++ b/x-pack/plugins/alerting/server/alert/alert.test.ts @@ -695,6 +695,7 @@ describe('isFilteredOut', () => { _id: '1', _index: '.alerts', '@timestamp': '', + // @ts-expect-error kibana: { alert: { instance: { id: 'a' }, diff --git a/x-pack/plugins/alerting/server/alert/alert.ts b/x-pack/plugins/alerting/server/alert/alert.ts index b05c3bea22cc3..ee8c48a18447b 100644 --- a/x-pack/plugins/alerting/server/alert/alert.ts +++ b/x-pack/plugins/alerting/server/alert/alert.ts @@ -6,8 +6,9 @@ */ import { v4 as uuidV4 } from 'uuid'; -import { isEmpty } from 'lodash'; +import { get, isEmpty } from 'lodash'; import { MutableAlertInstanceMeta } from '@kbn/alerting-state-types'; +import { ALERT_UUID } from '@kbn/rule-data-utils'; import { AlertHit, CombinedSummarizedAlerts } from '../types'; import { AlertInstanceMeta, @@ -298,10 +299,10 @@ export class Alert< // // Related issue: https://github.com/elastic/kibana/issues/144862 - return !summarizedAlerts.all.data.some( - (alert: AlertHit) => - alert?.kibana?.alert?.uuid === this.getId() || alert?.kibana?.alert?.uuid === this.getUuid() - ); + return !summarizedAlerts.all.data.some((alert: AlertHit) => { + const alertUuid = get(alert, ALERT_UUID); + return alertUuid === this.getId() || alertUuid === this.getUuid(); + }); } setMaintenanceWindowIds(maintenanceWindowIds: string[] = []) { diff --git a/x-pack/plugins/alerting/server/alerts_client/alerts_client.test.ts b/x-pack/plugins/alerting/server/alerts_client/alerts_client.test.ts index 6fc742e344758..18d4a7bc019b6 100644 --- a/x-pack/plugins/alerting/server/alerts_client/alerts_client.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/alerts_client.test.ts @@ -12,6 +12,36 @@ import { RecoveredActionGroup, RuleAlertData, } from '../types'; +import { + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_END, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_INSTANCE_ID, + ALERT_MAINTENANCE_WINDOW_IDS, + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + ALERT_START, + ALERT_STATUS, + ALERT_TIME_RANGE, + ALERT_UUID, + ALERT_WORKFLOW_STATUS, + EVENT_ACTION, + EVENT_KIND, + SPACE_IDS, + TAGS, + TIMESTAMP, + VERSION, +} from '@kbn/rule-data-utils'; import * as LegacyAlertsClientModule from './legacy_alerts_client'; import { LegacyAlertsClient } from './legacy_alerts_client'; import { Alert } from '../alert/alert'; @@ -21,7 +51,7 @@ import { legacyAlertsClientMock } from './legacy_alerts_client.mock'; import { keys, range } from 'lodash'; import { alertingEventLoggerMock } from '../lib/alerting_event_logger/alerting_event_logger.mock'; import { ruleRunMetricsStoreMock } from '../lib/rule_run_metrics_store.mock'; -import { expandFlattenedAlert } from './lib/get_summarized_alerts_query'; +import { expandFlattenedAlert } from './lib'; import { alertRuleData, getExpectedQueryByExecutionUuid, @@ -384,102 +414,66 @@ describe('Alerts Client', () => { }, // new alert doc { - '@timestamp': date, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '1', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: date, - status: 'active', - time_range: { - gte: date, - }, - uuid: uuid1, - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: date, + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: date, + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: date }, + [ALERT_UUID]: uuid1, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, { create: { _id: uuid2, ...(useDataStreamForAlerts ? {} : { require_alias: true }) }, }, // new alert doc { - '@timestamp': date, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '2', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: date, - status: 'active', - time_range: { - gte: date, - }, - uuid: uuid2, - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: date, + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '2', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: date, + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: date }, + [ALERT_UUID]: uuid2, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, ], }); @@ -502,50 +496,33 @@ describe('Alerts Client', () => { _seq_no: 41, _primary_term: 665, _source: { - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '1', - }, - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_UUID]: 'abc', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.0', + [TAGS]: ['rule-', '-tags'], }, }, ], @@ -602,102 +579,66 @@ describe('Alerts Client', () => { }, // ongoing alert doc { - '@timestamp': date, - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '36000000000000', - }, - flapping: false, - flapping_history: [true, false], - instance: { - id: '1', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: date, + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '36000000000000', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, false], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_UUID]: 'abc', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, { create: { _id: uuid2, ...(useDataStreamForAlerts ? {} : { require_alias: true }) }, }, // new alert doc { - '@timestamp': date, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '2', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: date, - status: 'active', - time_range: { - gte: date, - }, - uuid: uuid2, - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: date, + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '2', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: date, + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: date }, + [ALERT_UUID]: uuid2, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, ], }); @@ -738,50 +679,33 @@ describe('Alerts Client', () => { _id: 'abc', _index: '.internal.alerts-test.alerts-default-000001', _source: { - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '1', - }, - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_UUID]: 'abc', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.0', + [TAGS]: ['rule-', '-tags'], }, }, ], @@ -832,51 +756,33 @@ describe('Alerts Client', () => { }, // ongoing alert doc { - '@timestamp': date, - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true, false], - instance: { - id: '1', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: date, + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, false], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_UUID]: 'abc', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, ], }); @@ -899,50 +805,33 @@ describe('Alerts Client', () => { _seq_no: 41, _primary_term: 665, _source: { - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '1', - }, - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_UUID]: 'abc', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.0', + [TAGS]: ['rule-', '-tags'], }, }, { @@ -951,50 +840,33 @@ describe('Alerts Client', () => { _seq_no: 42, _primary_term: 666, _source: { - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '36000000000000', - }, - flapping: false, - flapping_history: [true, false], - instance: { - id: '2', - }, - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T02:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T02:27:28.159Z', - }, - uuid: 'def', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '36000000000000', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, false], + [ALERT_INSTANCE_ID]: '2', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_UUID]: 'def', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.0', + [TAGS]: ['rule-', '-tags'], }, }, ], @@ -1061,102 +933,66 @@ describe('Alerts Client', () => { }, // ongoing alert doc { - '@timestamp': date, - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '72000000000000', - }, - flapping: false, - flapping_history: [true, false, false], - instance: { - id: '2', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T02:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T02:27:28.159Z', - }, - uuid: 'def', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: date, + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '72000000000000', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, false, false], + [ALERT_INSTANCE_ID]: '2', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_UUID]: 'def', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, { create: { _id: uuid3, ...(useDataStreamForAlerts ? {} : { require_alias: true }) }, }, // new alert doc { - '@timestamp': date, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '3', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: date, - status: 'active', - time_range: { - gte: date, - }, - uuid: uuid3, - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: date, + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '3', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: date, + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: date }, + [ALERT_UUID]: uuid3, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, { index: { @@ -1169,53 +1005,34 @@ describe('Alerts Client', () => { }, // recovered alert doc { - '@timestamp': date, - event: { - action: 'close', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'recovered', - duration: { - us: '36000000000000', - }, - end: date, - flapping: false, - flapping_history: [true, true], - instance: { - id: '1', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'recovered', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - lte: date, - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: date, + [EVENT_ACTION]: 'close', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'recovered', + [ALERT_DURATION]: '36000000000000', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_END]: date, + [ALERT_STATUS]: 'recovered', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z', lte: date }, + [ALERT_UUID]: 'abc', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, ], }); @@ -1320,50 +1137,33 @@ describe('Alerts Client', () => { _seq_no: 41, _primary_term: 665, _source: { - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '1', - }, - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_UUID]: 'abc', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.0', + [TAGS]: ['rule-', '-tags'], }, }, { @@ -1372,50 +1172,33 @@ describe('Alerts Client', () => { _seq_no: 41, _primary_term: 665, _source: { - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '2', - }, - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'xyz', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '2', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_UUID]: 'xyz', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.0', + [TAGS]: ['rule-', '-tags'], }, }, ], @@ -1479,51 +1262,33 @@ describe('Alerts Client', () => { }, // ongoing alert doc { - '@timestamp': date, - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '36000000000000', - }, - flapping: false, - flapping_history: [true, false], - instance: { - id: '2', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'xyz', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + [TIMESTAMP]: date, + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '36000000000000', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, false], + [ALERT_INSTANCE_ID]: '2', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_UUID]: 'xyz', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, ], }); @@ -2136,106 +1901,70 @@ describe('Alerts Client', () => { }, // new alert doc { - '@timestamp': date, + [TIMESTAMP]: date, count: 1, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '1', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: date, - status: 'active', - time_range: { - gte: date, - }, - uuid: uuid1, - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], url: `https://url1`, + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: date, + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: date }, + [ALERT_UUID]: uuid1, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, { create: { _id: uuid2, ...(useDataStreamForAlerts ? {} : { require_alias: true }) }, }, // new alert doc { - '@timestamp': date, + [TIMESTAMP]: date, count: 2, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '2', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: date, - status: 'active', - time_range: { - gte: date, - }, - uuid: uuid2, - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], url: `https://url2`, + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '2', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: date, + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: date }, + [ALERT_UUID]: uuid2, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, ], }); @@ -2405,53 +2134,35 @@ describe('Alerts Client', () => { }, }, { - '@timestamp': date, + [TIMESTAMP]: date, count: 100, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '1', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: date, - status: 'active', - time_range: { - gte: date, - }, - uuid: expect.any(String), - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], url: 'https://elastic.co', + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: date, + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: date }, + [ALERT_UUID]: expect.any(String), + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, ], }); @@ -2472,52 +2183,35 @@ describe('Alerts Client', () => { _id: 'abc', _index: '.internal.alerts-test.alerts-default-000001', _source: { - '@timestamp': '2023-03-28T12:27:28.159Z', + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', count: 1, url: 'https://localhost:5601/abc', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '1', - }, - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.0', - }, - tags: ['rule-', '-tags'], + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_UUID]: 'abc', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.0', + [TAGS]: ['rule-', '-tags'], }, }, ], @@ -2581,53 +2275,35 @@ describe('Alerts Client', () => { }, }, { - '@timestamp': date, + [TIMESTAMP]: date, count: 100, - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '36000000000000', - }, - flapping: false, - flapping_history: [true, false], - instance: { - id: '1', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T12:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], url: 'https://elastic.co', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '36000000000000', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, false], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_UUID]: 'abc', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, ], }); @@ -2650,52 +2326,35 @@ describe('Alerts Client', () => { _seq_no: 42, _primary_term: 666, _source: { - '@timestamp': '2023-03-28T12:27:28.159Z', + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', count: 1, url: 'https://localhost:5601/abc', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '1', - }, - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T11:27:28.159Z', - status: 'active', - time_range: { - gte: '2023-03-28T11:27:28.159Z', - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.0', - }, - tags: ['rule-', '-tags'], + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_UUID]: 'abc', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.0', + [TAGS]: ['rule-', '-tags'], }, }, ], @@ -2756,55 +2415,36 @@ describe('Alerts Client', () => { }, }, { - '@timestamp': date, + [TIMESTAMP]: date, count: 100, - event: { - action: 'close', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'recovered', - duration: { - us: '39600000000000', - }, - end: date, - flapping: false, - flapping_history: [true, true], - instance: { - id: '1', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: '2023-03-28T11:27:28.159Z', - status: 'recovered', - time_range: { - gte: '2023-03-28T11:27:28.159Z', - lte: date, - }, - uuid: 'abc', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], url: 'https://elastic.co', + [EVENT_ACTION]: 'close', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'recovered', + [ALERT_DURATION]: '39600000000000', + [ALERT_END]: date, + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_UUID]: 'abc', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_STATUS]: 'recovered', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z', lte: date }, + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }, ], }); diff --git a/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts b/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts index eec5d3c5595bd..34d4e994cfe8b 100644 --- a/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts +++ b/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts @@ -7,13 +7,14 @@ import { ElasticsearchClient } from '@kbn/core/server'; import { + ALERT_INSTANCE_ID, ALERT_RULE_UUID, ALERT_STATUS, ALERT_STATUS_UNTRACKED, ALERT_STATUS_ACTIVE, ALERT_UUID, } from '@kbn/rule-data-utils'; -import { chunk, flatMap, isEmpty, keys } from 'lodash'; +import { chunk, flatMap, get, isEmpty, keys } from 'lodash'; import { SearchRequest } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { Alert } from '@kbn/alerts-as-data-utils'; import { DEFAULT_NAMESPACE_STRING } from '@kbn/core-saved-objects-utils-server'; @@ -92,7 +93,7 @@ export class AlertsClient< primaryTerm: Record; }; - private rule: AlertRule = {}; + private rule: AlertRule; private ruleType: UntypedNormalizedRuleType; private indexTemplateAndPattern: IIndexPatternString; @@ -173,8 +174,8 @@ export class AlertsClient< for (const hit of results.flat()) { const alertHit: Alert & AlertData = hit._source as Alert & AlertData; - const alertUuid = alertHit.kibana.alert.uuid; - const alertId = alertHit.kibana.alert.instance.id; + const alertUuid = get(alertHit, ALERT_UUID); + const alertId = get(alertHit, ALERT_INSTANCE_ID); // Keep track of existing alert document so we can copy over data if alert is ongoing this.fetchedAlerts.data[alertId] = alertHit; @@ -350,7 +351,7 @@ export class AlertsClient< if (!!activeAlerts[id]) { if ( this.fetchedAlerts.data.hasOwnProperty(id) && - this.fetchedAlerts.data[id].kibana.alert.status === 'active' + get(this.fetchedAlerts.data[id], ALERT_STATUS) === 'active' ) { activeAlertsToIndex.push( buildOngoingAlert< @@ -432,12 +433,13 @@ export class AlertsClient< const alertsToIndex = [...activeAlertsToIndex, ...recoveredAlertsToIndex].filter( (alert: Alert & AlertData) => { - const alertIndex = this.fetchedAlerts.indices[alert.kibana.alert.uuid]; + const alertUuid = get(alert, ALERT_UUID); + const alertIndex = this.fetchedAlerts.indices[alertUuid]; if (!alertIndex) { return true; } else if (!isValidAlertIndexName(alertIndex)) { this.options.logger.warn( - `Could not update alert ${alert.kibana.alert.uuid} in ${alertIndex}. Partial and restored alert indices are not supported.` + `Could not update alert ${alertUuid} in ${alertIndex}. Partial and restored alert indices are not supported.` ); return false; } @@ -446,16 +448,19 @@ export class AlertsClient< ); if (alertsToIndex.length > 0) { const bulkBody = flatMap( - alertsToIndex.map((alert: Alert & AlertData) => [ - getBulkMeta( - alert.kibana.alert.uuid, - this.fetchedAlerts.indices[alert.kibana.alert.uuid], - this.fetchedAlerts.seqNo[alert.kibana.alert.uuid], - this.fetchedAlerts.primaryTerm[alert.kibana.alert.uuid], - this.isUsingDataStreams() - ), - alert, - ]) + alertsToIndex.map((alert: Alert & AlertData) => { + const alertUuid = get(alert, ALERT_UUID); + return [ + getBulkMeta( + alertUuid, + this.fetchedAlerts.indices[alertUuid], + this.fetchedAlerts.seqNo[alertUuid], + this.fetchedAlerts.primaryTerm[alertUuid], + this.isUsingDataStreams() + ), + alert, + ]; + }) ); try { diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/alert_conflict_resolver.test.ts b/x-pack/plugins/alerting/server/alerts_client/lib/alert_conflict_resolver.test.ts index ffa2adc96f54f..281b358854be9 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/alert_conflict_resolver.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/alert_conflict_resolver.test.ts @@ -7,6 +7,13 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; +import { + ALERT_CASE_IDS, + ALERT_STATUS, + ALERT_WORKFLOW_STATUS, + ALERT_WORKFLOW_TAGS, + EVENT_ACTION, +} from '@kbn/rule-data-utils'; import { BulkRequest, BulkResponse, @@ -20,15 +27,11 @@ const logger = loggingSystemMock.create().get(); const esClient = elasticsearchServiceMock.createElasticsearchClient(); const alertDoc = { - event: { action: 'active' }, - kibana: { - alert: { - status: 'untracked', - workflow_status: 'a-ok!', - workflow_tags: ['fee', 'fi', 'fo', 'fum'], - case_ids: ['123', '456', '789'], - }, - }, + [EVENT_ACTION]: 'active', + [ALERT_STATUS]: 'untracked', + [ALERT_WORKFLOW_STATUS]: 'a-ok!', + [ALERT_WORKFLOW_TAGS]: ['fee', 'fi', 'fo', 'fum'], + [ALERT_CASE_IDS]: ['123', '456', '789'], }; describe('alert_conflict_resolver', () => { diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/alert_conflict_resolver.ts b/x-pack/plugins/alerting/server/alerts_client/lib/alert_conflict_resolver.ts index 223070c0e7245..ed81c76b7987e 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/alert_conflict_resolver.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/alert_conflict_resolver.ts @@ -22,7 +22,6 @@ import { ALERT_CASE_IDS, } from '@kbn/rule-data-utils'; -import { set } from '@kbn/safer-lodash-set'; import { zip, get } from 'lodash'; // these fields are the one's we'll refresh from the fresh mget'd docs @@ -147,7 +146,7 @@ async function refreshFieldsInDocs( for (const refreshField of REFRESH_FIELDS_ALWAYS) { const val = get(freshDoc, refreshField); - set(conflictDoc, refreshField, val); + conflictDoc[refreshField] = val; } // structured this way to make sure all conditional refresh @@ -160,7 +159,7 @@ async function refreshFieldsInDocs( const freshStatus = get(freshDoc, ALERT_STATUS); if (freshStatus !== ALERT_STATUS_ACTIVE && freshStatus !== ALERT_STATUS_RECOVERED) { - set(conflictDoc, ALERT_STATUS, freshStatus); + conflictDoc[ALERT_STATUS] = freshStatus; } break; } diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/build_new_alert.test.ts b/x-pack/plugins/alerting/server/alerts_client/lib/build_new_alert.test.ts index d31d506854f49..88c63a2a3dd6a 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/build_new_alert.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/build_new_alert.test.ts @@ -8,6 +8,35 @@ import { Alert as LegacyAlert } from '../../alert/alert'; import { buildNewAlert } from './build_new_alert'; import type { AlertRule } from '../types'; import { Alert } from '@kbn/alerts-as-data-utils'; +import { + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + SPACE_IDS, + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_INSTANCE_ID, + ALERT_MAINTENANCE_WINDOW_IDS, + ALERT_START, + ALERT_STATUS, + ALERT_UUID, + ALERT_WORKFLOW_STATUS, + EVENT_ACTION, + EVENT_KIND, + TAGS, + TIMESTAMP, + VERSION, + ALERT_TIME_RANGE, +} from '@kbn/rule-data-utils'; const rule = { category: 'My test rule', @@ -26,12 +55,17 @@ const rule = { uuid: '1', }; const alertRule: AlertRule = { - kibana: { - alert: { - rule, - }, - space_ids: ['default'], - }, + [ALERT_RULE_CATEGORY]: rule.category, + [ALERT_RULE_CONSUMER]: rule.consumer, + [ALERT_RULE_EXECUTION_UUID]: rule.execution.uuid, + [ALERT_RULE_NAME]: rule.name, + [ALERT_RULE_PARAMETERS]: rule.parameters, + [ALERT_RULE_PRODUCER]: rule.producer, + [ALERT_RULE_REVISION]: rule.revision, + [ALERT_RULE_TYPE_ID]: rule.rule_type_id, + [ALERT_RULE_TAGS]: rule.tags, + [ALERT_RULE_UUID]: rule.uuid, + [SPACE_IDS]: ['default'], }; describe('buildNewAlert', () => { @@ -47,29 +81,21 @@ describe('buildNewAlert', () => { kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - rule, - status: 'active', - uuid: legacyAlert.getUuid(), - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + ...alertRule, + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: legacyAlert.getUuid(), + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -86,36 +112,24 @@ describe('buildNewAlert', () => { kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - start: now, - rule, - status: 'active', - time_range: { - gte: now, - }, - uuid: legacyAlert.getUuid(), - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + ...alertRule, + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: legacyAlert.getUuid(), + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '0', + [ALERT_START]: now, + [ALERT_TIME_RANGE]: { gte: now }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -133,29 +147,21 @@ describe('buildNewAlert', () => { kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - flapping: false, - flapping_history: [true, false, false, false, true, true], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: ['maint-1', 'maint-321'], - rule, - status: 'active', - uuid: legacyAlert.getUuid(), - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + ...alertRule, + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, false, false, false, true, true], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: ['maint-1', 'maint-321'], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: legacyAlert.getUuid(), + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -165,7 +171,7 @@ describe('buildNewAlert', () => { expect( buildNewAlert< - { count: number; url: string; kibana: { alert: { nested_field: number } } }, + { count: number; url: string; 'kibana.alert.nested_field': number }, {}, {}, 'default', @@ -174,36 +180,28 @@ describe('buildNewAlert', () => { legacyAlert, rule: alertRule, timestamp: '2023-03-28T12:27:28.159Z', - payload: { count: 1, url: `https://url1`, kibana: { alert: { nested_field: 2 } } }, + payload: { count: 1, url: `https://url1`, 'kibana.alert.nested_field': 2 }, kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-28T12:27:28.159Z', + ...alertRule, count: 1, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - nested_field: 2, - rule, - status: 'active', - uuid: legacyAlert.getUuid(), - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], url: `https://url1`, + 'kibana.alert.nested_field': 2, + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: legacyAlert.getUuid(), + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -213,7 +211,7 @@ describe('buildNewAlert', () => { expect( buildNewAlert< - Alert & { count: number; url: string; kibana: { alert: { nested_field: number } } }, + Alert & { count: number; url: string; 'kibana.alert.nested_field': number }, {}, {}, 'default', @@ -225,37 +223,30 @@ describe('buildNewAlert', () => { payload: { count: 1, url: `https://url1`, - kibana: { alert: { nested_field: 2, workflow_status: 'custom_workflow' } }, + 'kibana.alert.nested_field': 2, + [ALERT_WORKFLOW_STATUS]: 'custom_workflow', }, kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-28T12:27:28.159Z', + ...alertRule, count: 1, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - nested_field: 2, - rule, - status: 'active', - uuid: legacyAlert.getUuid(), - workflow_status: 'custom_workflow', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], url: `https://url1`, + 'kibana.alert.nested_field': 2, + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: legacyAlert.getUuid(), + [ALERT_WORKFLOW_STATUS]: 'custom_workflow', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -268,7 +259,8 @@ describe('buildNewAlert', () => { { count: number; url: string; - kibana: { alert: { action_group: string; nested_field: number } }; + [ALERT_ACTION_GROUP]: string; + 'kibana.alert.nested_field': number; }, {}, {}, @@ -281,37 +273,30 @@ describe('buildNewAlert', () => { payload: { count: 1, url: `https://url1`, - kibana: { alert: { action_group: 'bad action group', nested_field: 2 } }, + [ALERT_ACTION_GROUP]: 'bad action group', + 'kibana.alert.nested_field': 2, }, kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-28T12:27:28.159Z', + ...alertRule, count: 1, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - nested_field: 2, - rule, - status: 'active', - uuid: legacyAlert.getUuid(), - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], url: `https://url1`, + 'kibana.alert.nested_field': 2, + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: legacyAlert.getUuid(), + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -324,7 +309,8 @@ describe('buildNewAlert', () => { { count: number; url: string; - kibana: { alert: { action_group: string; nested_field: number } }; + [ALERT_ACTION_GROUP]: string; + 'kibana.alert.nested_field': number; tags: string[]; }, {}, @@ -338,38 +324,31 @@ describe('buildNewAlert', () => { payload: { count: 1, url: `https://url1`, - kibana: { alert: { action_group: 'bad action group', nested_field: 2 } }, + [ALERT_ACTION_GROUP]: 'bad action group', + 'kibana.alert.nested_field': 2, tags: ['custom-tag1', '-tags'], }, kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-28T12:27:28.159Z', + ...alertRule, count: 1, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - nested_field: 2, - rule, - status: 'active', - uuid: legacyAlert.getUuid(), - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['custom-tag1', '-tags', 'rule-'], url: `https://url1`, + 'kibana.alert.nested_field': 2, + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: legacyAlert.getUuid(), + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['custom-tag1', '-tags', 'rule-'], }); }); }); diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/build_new_alert.ts b/x-pack/plugins/alerting/server/alerts_client/lib/build_new_alert.ts index 5d163504a9606..9c4c4bb6c095c 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/build_new_alert.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/build_new_alert.ts @@ -7,7 +7,26 @@ import deepmerge from 'deepmerge'; import { get } from 'lodash'; import type { Alert } from '@kbn/alerts-as-data-utils'; -import { ALERT_WORKFLOW_STATUS } from '@kbn/rule-data-utils'; +import { + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_INSTANCE_ID, + ALERT_MAINTENANCE_WINDOW_IDS, + ALERT_RULE_TAGS, + ALERT_START, + ALERT_STATUS, + ALERT_TIME_RANGE, + ALERT_UUID, + ALERT_WORKFLOW_STATUS, + EVENT_ACTION, + EVENT_KIND, + SPACE_IDS, + TAGS, + TIMESTAMP, + VERSION, +} from '@kbn/rule-data-utils'; import { DeepPartial } from '@kbn/utility-types'; import { Alert as LegacyAlert } from '../../alert/alert'; import { AlertInstanceContext, AlertInstanceState, RuleAlertData } from '../../types'; @@ -56,45 +75,32 @@ export const buildNewAlert = < return deepmerge.all( [ cleanedPayload, + rule, { - '@timestamp': timestamp, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: legacyAlert.getScheduledActionOptions()?.actionGroup, - flapping: legacyAlert.getFlapping(), - flapping_history: legacyAlert.getFlappingHistory(), - instance: { - id: legacyAlert.getId(), - }, - maintenance_window_ids: legacyAlert.getMaintenanceWindowIds(), - rule: rule.kibana?.alert.rule, - status: 'active', - uuid: legacyAlert.getUuid(), - workflow_status: get(cleanedPayload, ALERT_WORKFLOW_STATUS, 'open'), - ...(legacyAlert.getState().duration - ? { duration: { us: legacyAlert.getState().duration } } - : {}), - ...(legacyAlert.getState().start - ? { - start: legacyAlert.getState().start, - time_range: { - gte: legacyAlert.getState().start, - }, - } - : {}), - }, - space_ids: rule.kibana?.space_ids, - version: kibanaVersion, - }, - tags: Array.from( - new Set([ - ...((cleanedPayload?.tags as string[]) ?? []), - ...(rule.kibana?.alert.rule.tags ?? []), - ]) + [TIMESTAMP]: timestamp, + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: legacyAlert.getScheduledActionOptions()?.actionGroup, + [ALERT_FLAPPING]: legacyAlert.getFlapping(), + [ALERT_FLAPPING_HISTORY]: legacyAlert.getFlappingHistory(), + [ALERT_INSTANCE_ID]: legacyAlert.getId(), + [ALERT_MAINTENANCE_WINDOW_IDS]: legacyAlert.getMaintenanceWindowIds(), + [ALERT_STATUS]: 'active', + [ALERT_UUID]: legacyAlert.getUuid(), + [ALERT_WORKFLOW_STATUS]: get(cleanedPayload, ALERT_WORKFLOW_STATUS, 'open'), + ...(legacyAlert.getState().duration + ? { [ALERT_DURATION]: legacyAlert.getState().duration } + : {}), + ...(legacyAlert.getState().start + ? { + [ALERT_START]: legacyAlert.getState().start, + [ALERT_TIME_RANGE]: { gte: legacyAlert.getState().start }, + } + : {}), + [SPACE_IDS]: rule[SPACE_IDS], + [VERSION]: kibanaVersion, + [TAGS]: Array.from( + new Set([...((cleanedPayload?.tags as string[]) ?? []), ...(rule[ALERT_RULE_TAGS] ?? [])]) ), }, ], diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/build_ongoing_alert.test.ts b/x-pack/plugins/alerting/server/alerts_client/lib/build_ongoing_alert.test.ts index 078d16602ac84..201153d41a096 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/build_ongoing_alert.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/build_ongoing_alert.test.ts @@ -7,6 +7,35 @@ import { Alert as LegacyAlert } from '../../alert/alert'; import { buildOngoingAlert } from './build_ongoing_alert'; import type { AlertRule } from '../types'; +import { + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + SPACE_IDS, + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_INSTANCE_ID, + ALERT_MAINTENANCE_WINDOW_IDS, + ALERT_START, + ALERT_STATUS, + ALERT_UUID, + ALERT_WORKFLOW_STATUS, + EVENT_ACTION, + EVENT_KIND, + TAGS, + TIMESTAMP, + VERSION, + ALERT_TIME_RANGE, +} from '@kbn/rule-data-utils'; const rule = { category: 'My test rule', @@ -25,43 +54,38 @@ const rule = { uuid: '1', }; const alertRule: AlertRule = { - kibana: { - alert: { - rule, - }, - space_ids: ['default'], - }, + [ALERT_RULE_CATEGORY]: rule.category, + [ALERT_RULE_CONSUMER]: rule.consumer, + [ALERT_RULE_EXECUTION_UUID]: rule.execution.uuid, + [ALERT_RULE_NAME]: rule.name, + [ALERT_RULE_PARAMETERS]: rule.parameters, + [ALERT_RULE_PRODUCER]: rule.producer, + [ALERT_RULE_REVISION]: rule.revision, + [ALERT_RULE_TYPE_ID]: rule.rule_type_id, + [ALERT_RULE_TAGS]: rule.tags, + [ALERT_RULE_UUID]: rule.uuid, + [SPACE_IDS]: ['default'], }; + const existingAlert = { - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'error', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: 'alert-A', - }, - start: '2023-03-28T12:27:28.159Z', - rule, - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.1', - }, - tags: ['rule-', '-tags'], + ...alertRule, + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'error', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.1', + [TAGS]: ['rule-', '-tags'], }; describe('buildOngoingAlert', () => { @@ -80,36 +104,24 @@ describe('buildOngoingAlert', () => { kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'warning', - duration: { - us: '36000000', - }, - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - start: '2023-03-28T12:27:28.159Z', - rule, - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + ...alertRule, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'warning', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -119,64 +131,38 @@ describe('buildOngoingAlert', () => { .scheduleActions('warning') .replaceState({ start: '0000-00-00T00:00:00.000Z', duration: '36000000' }); + const updatedRule = { + ...alertRule, + [ALERT_RULE_NAME]: 'updated-rule-name', + [ALERT_RULE_PARAMETERS]: { bar: false }, + }; expect( buildOngoingAlert<{}, {}, {}, 'error' | 'warning', 'recovered'>({ alert: existingAlert, legacyAlert, - rule: { - kibana: { - alert: { - rule: { - ...rule, - name: 'updated-rule-name', - parameters: { - bar: false, - }, - }, - }, - space_ids: ['default'], - }, - }, + rule: updatedRule, timestamp: '2023-03-29T12:27:28.159Z', kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'warning', - duration: { - us: '36000000', - }, - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - start: '2023-03-28T12:27:28.159Z', - rule: { - ...rule, - name: 'updated-rule-name', - parameters: { - bar: false, - }, - }, - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + ...updatedRule, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'warning', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -190,14 +176,8 @@ describe('buildOngoingAlert', () => { buildOngoingAlert<{}, {}, {}, 'error' | 'warning', 'recovered'>({ alert: { ...existingAlert, - kibana: { - ...existingAlert.kibana, - alert: { - ...existingAlert.kibana.alert, - flapping_history: [true, false, false, false, true, true], - maintenance_window_ids: ['maint-1', 'maint-321'], - }, - }, + [ALERT_FLAPPING_HISTORY]: [true, false, false, false, true, true], + [ALERT_MAINTENANCE_WINDOW_IDS]: ['maint-1', 'maint-321'], }, legacyAlert, rule: alertRule, @@ -205,36 +185,24 @@ describe('buildOngoingAlert', () => { kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'error', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [false, false, true, true], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: ['maint-xyz'], - start: '2023-03-28T12:27:28.159Z', - rule, - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + ...alertRule, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'error', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [false, false, true, true], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: ['maint-xyz'], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '0', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -246,7 +214,7 @@ describe('buildOngoingAlert', () => { expect( buildOngoingAlert< - { count: number; url: string; kibana?: { alert?: { nested_field?: number } } }, + { count: number; url: string; 'kibana.alert.nested_field'?: number }, {}, {}, 'error' | 'warning', @@ -263,44 +231,32 @@ describe('buildOngoingAlert', () => { payload: { count: 2, url: `https://url2`, - kibana: { alert: { nested_field: 2 } }, + 'kibana.alert.nested_field': 2, }, kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', + ...alertRule, count: 2, - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'warning', - duration: { - us: '36000000', - }, - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - nested_field: 2, - start: '2023-03-28T12:27:28.159Z', - rule, - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, url: `https://url2`, - tags: ['rule-', '-tags'], + 'kibana.alert.nested_field': 2, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'warning', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -315,7 +271,8 @@ describe('buildOngoingAlert', () => { { count: number; url: string; - kibana?: { alert?: { action_group: string; nested_field?: number } }; + [ALERT_ACTION_GROUP]: string; + 'kibana.alert.nested_field'?: number; }, {}, {}, @@ -333,44 +290,33 @@ describe('buildOngoingAlert', () => { payload: { count: 2, url: `https://url2`, - kibana: { alert: { action_group: 'bad action group', nested_field: 2 } }, + [ALERT_ACTION_GROUP]: 'bad action group', + 'kibana.alert.nested_field': 2, }, kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', + ...alertRule, count: 2, - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'warning', - duration: { - us: '36000000', - }, - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - nested_field: 2, - start: '2023-03-28T12:27:28.159Z', - rule, - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, url: `https://url2`, - tags: ['rule-', '-tags'], + 'kibana.alert.nested_field': 2, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'warning', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -385,7 +331,8 @@ describe('buildOngoingAlert', () => { { count: number; url: string; - kibana?: { alert?: { action_group: string; nested_field?: number } }; + [ALERT_ACTION_GROUP]: string; + 'kibana.alert.nested_field'?: number; tags?: string[]; }, {}, @@ -405,45 +352,34 @@ describe('buildOngoingAlert', () => { payload: { count: 2, url: `https://url2`, - kibana: { alert: { action_group: 'bad action group', nested_field: 2 } }, + [ALERT_ACTION_GROUP]: 'bad action group', + 'kibana.alert.nested_field': 2, tags: ['-tags', 'custom-tag2'], }, kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', + ...alertRule, count: 2, - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'warning', - duration: { - us: '36000000', - }, - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - nested_field: 2, - start: '2023-03-28T12:27:28.159Z', - rule, - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, url: `https://url2`, - tags: ['-tags', 'custom-tag2', 'old-tag1', 'rule-'], + 'kibana.alert.nested_field': 2, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'warning', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['-tags', 'custom-tag2', 'old-tag1', 'rule-'], }); }); @@ -466,38 +402,26 @@ describe('buildOngoingAlert', () => { kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', + ...alertRule, count: 1, - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'warning', - duration: { - us: '36000000', - }, - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - start: '2023-03-28T12:27:28.159Z', - rule, - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, url: `https://url1`, - tags: ['rule-', '-tags'], + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'warning', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'active', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); }); diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/build_ongoing_alert.ts b/x-pack/plugins/alerting/server/alerts_client/lib/build_ongoing_alert.ts index 491c4dfe7cca7..ed0e193aed508 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/build_ongoing_alert.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/build_ongoing_alert.ts @@ -7,6 +7,19 @@ import deepmerge from 'deepmerge'; import type { Alert } from '@kbn/alerts-as-data-utils'; +import { + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_MAINTENANCE_WINDOW_IDS, + ALERT_RULE_TAGS, + EVENT_ACTION, + SPACE_IDS, + TAGS, + TIMESTAMP, + VERSION, +} from '@kbn/rule-data-utils'; import { DeepPartial } from '@kbn/utility-types'; import { Alert as LegacyAlert } from '../../alert/alert'; import { AlertInstanceContext, AlertInstanceState, RuleAlertData } from '../../types'; @@ -58,51 +71,44 @@ export const buildOngoingAlert = < [ alert, cleanedPayload, + // Set the latest rule configuration + rule, { // Update the timestamp to reflect latest update time - '@timestamp': timestamp, - event: { - action: 'active', - }, - kibana: { - alert: { - // Because we're building this alert after the action execution handler has been - // run, the scheduledExecutionOptions for the alert has been cleared and - // the lastScheduledActions has been set. If we ever change the order of operations - // to build and persist the alert before action execution handler, we will need to - // update where we pull the action group from. - // Set latest action group as this may have changed during execution (ex: error -> warning) - action_group: legacyAlert.getScheduledActionOptions()?.actionGroup, - // Set latest flapping state - flapping: legacyAlert.getFlapping(), - // Set latest flapping_history - flapping_history: legacyAlert.getFlappingHistory(), - // Set latest maintenance window IDs - maintenance_window_ids: legacyAlert.getMaintenanceWindowIds(), - // Set latest rule configuration - rule: rule.kibana?.alert.rule, - // Set latest duration as ongoing alerts should have updated duration - ...(legacyAlert.getState().duration - ? { duration: { us: legacyAlert.getState().duration } } - : {}), - // Fields that are explicitly not updated: - // event.kind - // instance.id - // status - ongoing alerts should maintain 'active' status - // uuid - ongoing alerts should carry over previous UUID - // start - ongoing alerts should keep the initial start time - // time_range - ongoing alerts should keep the initial time_range - // workflow_status - ongoing alerts should keep the initial workflow status - }, - space_ids: rule.kibana?.space_ids, - // Set latest kibana version - version: kibanaVersion, - }, - tags: Array.from( + [TIMESTAMP]: timestamp, + [EVENT_ACTION]: 'active', + // Because we're building this alert after the action execution handler has been + // run, the scheduledExecutionOptions for the alert has been cleared and + // the lastScheduledActions has been set. If we ever change the order of operations + // to build and persist the alert before action execution handler, we will need to + // update where we pull the action group from. + // Set latest action group as this may have changed during execution (ex: error -> warning) + [ALERT_ACTION_GROUP]: legacyAlert.getScheduledActionOptions()?.actionGroup, + // Set latest flapping state + [ALERT_FLAPPING]: legacyAlert.getFlapping(), + // Set latest flapping_history + [ALERT_FLAPPING_HISTORY]: legacyAlert.getFlappingHistory(), + // Set latest maintenance window IDs + [ALERT_MAINTENANCE_WINDOW_IDS]: legacyAlert.getMaintenanceWindowIds(), + // Set latest duration as ongoing alerts should have updated duration + ...(legacyAlert.getState().duration + ? { [ALERT_DURATION]: legacyAlert.getState().duration } + : {}), + // Fields that are explicitly not updated: + // event.kind + // instance.id + // status - ongoing alerts should maintain 'active' status + // uuid - ongoing alerts should carry over previous UUID + // start - ongoing alerts should keep the initial start time + // time_range - ongoing alerts should keep the initial time_range + // workflow_status - ongoing alerts should keep the initial workflow status + [SPACE_IDS]: rule[SPACE_IDS], + [VERSION]: kibanaVersion, + [TAGS]: Array.from( new Set([ ...((cleanedPayload?.tags as string[]) ?? []), ...(alert.tags ?? []), - ...(rule.kibana?.alert.rule.tags ?? []), + ...(rule[ALERT_RULE_TAGS] ?? []), ]) ), }, diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/build_recovered_alert.test.ts b/x-pack/plugins/alerting/server/alerts_client/lib/build_recovered_alert.test.ts index 03f538dc07ef3..ec499cb921deb 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/build_recovered_alert.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/build_recovered_alert.test.ts @@ -7,6 +7,36 @@ import { Alert as LegacyAlert } from '../../alert/alert'; import { buildRecoveredAlert } from './build_recovered_alert'; import type { AlertRule } from '../types'; +import { + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + SPACE_IDS, + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_INSTANCE_ID, + ALERT_MAINTENANCE_WINDOW_IDS, + ALERT_START, + ALERT_STATUS, + ALERT_UUID, + ALERT_WORKFLOW_STATUS, + EVENT_ACTION, + EVENT_KIND, + TAGS, + TIMESTAMP, + VERSION, + ALERT_TIME_RANGE, + ALERT_END, +} from '@kbn/rule-data-utils'; const rule = { category: 'My test rule', @@ -25,44 +55,38 @@ const rule = { uuid: '1', }; const alertRule: AlertRule = { - kibana: { - alert: { - rule, - }, - space_ids: ['default'], - }, + [ALERT_RULE_CATEGORY]: rule.category, + [ALERT_RULE_CONSUMER]: rule.consumer, + [ALERT_RULE_EXECUTION_UUID]: rule.execution.uuid, + [ALERT_RULE_NAME]: rule.name, + [ALERT_RULE_PARAMETERS]: rule.parameters, + [ALERT_RULE_PRODUCER]: rule.producer, + [ALERT_RULE_REVISION]: rule.revision, + [ALERT_RULE_TYPE_ID]: rule.rule_type_id, + [ALERT_RULE_TAGS]: rule.tags, + [ALERT_RULE_UUID]: rule.uuid, + [SPACE_IDS]: ['default'], }; + const existingActiveAlert = { - '@timestamp': '2023-03-28T12:27:28.159Z', - event: { - action: 'active', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true, false], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: ['maint-x'], - start: '2023-03-28T12:27:28.159Z', - rule, - status: 'active', - time_range: { - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.1', - }, - tags: ['rule-', '-tags'], + ...alertRule, + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'active', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, false], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: ['maint-x'], + [ALERT_STATUS]: 'active', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z' }, + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.1', + [TAGS]: ['rule-', '-tags'], }; describe('buildRecoveredAlert', () => { @@ -82,38 +106,25 @@ describe('buildRecoveredAlert', () => { kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', - event: { - action: 'close', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'recovered', - duration: { - us: '36000000', - }, - end: '2023-03-30T12:27:28.159Z', - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: [], - start: '2023-03-28T12:27:28.159Z', - rule, - status: 'recovered', - time_range: { - lte: '2023-03-30T12:27:28.159Z', - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + ...alertRule, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'close', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'recovered', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_STATUS]: 'recovered', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_END]: '2023-03-30T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z', lte: '2023-03-30T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -124,67 +135,41 @@ describe('buildRecoveredAlert', () => { .replaceState({ end: '2023-03-30T12:27:28.159Z', duration: '36000000' }); legacyAlert.setMaintenanceWindowIds(['maint-1', 'maint-321']); + const updatedRule = { + ...alertRule, + [ALERT_RULE_NAME]: 'updated-rule-name', + [ALERT_RULE_PARAMETERS]: { bar: false }, + }; + expect( buildRecoveredAlert<{}, {}, {}, 'default', 'recovered'>({ alert: existingActiveAlert, legacyAlert, recoveryActionGroup: 'NoLongerActive', - rule: { - kibana: { - alert: { - rule: { - ...rule, - name: 'updated-rule-name', - parameters: { - bar: false, - }, - }, - }, - space_ids: ['default'], - }, - }, + rule: updatedRule, timestamp: '2023-03-29T12:27:28.159Z', kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', - event: { - action: 'close', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'NoLongerActive', - duration: { - us: '36000000', - }, - end: '2023-03-30T12:27:28.159Z', - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: ['maint-1', 'maint-321'], - start: '2023-03-28T12:27:28.159Z', - rule: { - ...rule, - name: 'updated-rule-name', - parameters: { - bar: false, - }, - }, - status: 'recovered', - time_range: { - lte: '2023-03-30T12:27:28.159Z', - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, - tags: ['rule-', '-tags'], + ...updatedRule, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'close', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'NoLongerActive', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: ['maint-1', 'maint-321'], + [ALERT_STATUS]: 'recovered', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_END]: '2023-03-30T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z', lte: '2023-03-30T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -195,9 +180,15 @@ describe('buildRecoveredAlert', () => { .replaceState({ end: '2023-03-30T12:27:28.159Z', duration: '36000000' }); legacyAlert.setMaintenanceWindowIds(['maint-1', 'maint-321']); + const updatedRule = { + ...alertRule, + [ALERT_RULE_NAME]: 'updated-rule-name', + [ALERT_RULE_PARAMETERS]: { bar: false }, + }; + expect( buildRecoveredAlert< - { count: number; url: string; kibana?: { alert?: { nested_field?: number } } }, + { count: number; url: string; 'kibana.alert.nested_field'?: number }, {}, {}, 'default', @@ -213,67 +204,35 @@ describe('buildRecoveredAlert', () => { payload: { count: 2, url: `https://url2`, - kibana: { alert: { nested_field: 2 } }, - }, - rule: { - kibana: { - alert: { - rule: { - ...rule, - name: 'updated-rule-name', - parameters: { - bar: false, - }, - }, - }, - space_ids: ['default'], - }, + 'kibana.alert.nested_field': 2, }, + rule: updatedRule, timestamp: '2023-03-29T12:27:28.159Z', kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', + ...updatedRule, count: 2, - event: { - action: 'close', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'NoLongerActive', - duration: { - us: '36000000', - }, - end: '2023-03-30T12:27:28.159Z', - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: ['maint-1', 'maint-321'], - nested_field: 2, - start: '2023-03-28T12:27:28.159Z', - rule: { - ...rule, - name: 'updated-rule-name', - parameters: { - bar: false, - }, - }, - status: 'recovered', - time_range: { - lte: '2023-03-30T12:27:28.159Z', - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, url: `https://url2`, - tags: ['rule-', '-tags'], + 'kibana.alert.nested_field': 2, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'close', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'NoLongerActive', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: ['maint-1', 'maint-321'], + [ALERT_STATUS]: 'recovered', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_END]: '2023-03-30T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z', lte: '2023-03-30T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); @@ -284,12 +243,18 @@ describe('buildRecoveredAlert', () => { .replaceState({ end: '2023-03-30T12:27:28.159Z', duration: '36000000' }); legacyAlert.setMaintenanceWindowIds(['maint-1', 'maint-321']); + const updatedRule = { + ...alertRule, + [ALERT_RULE_NAME]: 'updated-rule-name', + [ALERT_RULE_PARAMETERS]: { bar: false }, + }; + expect( buildRecoveredAlert< { count: number; url: string; - kibana?: { alert?: { nested_field?: number } }; + 'kibana.alert.nested_field'?: number; tags?: string[]; }, {}, @@ -308,68 +273,36 @@ describe('buildRecoveredAlert', () => { payload: { count: 2, url: `https://url2`, - kibana: { alert: { nested_field: 2 } }, + 'kibana.alert.nested_field': 2, tags: ['-tags', 'reported-recovery-tag'], }, - rule: { - kibana: { - alert: { - rule: { - ...rule, - name: 'updated-rule-name', - parameters: { - bar: false, - }, - }, - }, - space_ids: ['default'], - }, - }, + rule: updatedRule, timestamp: '2023-03-29T12:27:28.159Z', kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', + ...updatedRule, count: 2, - event: { - action: 'close', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'NoLongerActive', - duration: { - us: '36000000', - }, - end: '2023-03-30T12:27:28.159Z', - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: ['maint-1', 'maint-321'], - nested_field: 2, - start: '2023-03-28T12:27:28.159Z', - rule: { - ...rule, - name: 'updated-rule-name', - parameters: { - bar: false, - }, - }, - status: 'recovered', - time_range: { - lte: '2023-03-30T12:27:28.159Z', - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, url: `https://url2`, - tags: ['-tags', 'reported-recovery-tag', 'active-alert-tag', 'rule-'], + 'kibana.alert.nested_field': 2, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'close', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'NoLongerActive', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: ['maint-1', 'maint-321'], + [ALERT_STATUS]: 'recovered', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_END]: '2023-03-30T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z', lte: '2023-03-30T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['-tags', 'reported-recovery-tag', 'active-alert-tag', 'rule-'], }); }); @@ -380,12 +313,19 @@ describe('buildRecoveredAlert', () => { .replaceState({ end: '2023-03-30T12:27:28.159Z', duration: '36000000' }); legacyAlert.setMaintenanceWindowIds(['maint-1', 'maint-321']); + const updatedRule = { + ...alertRule, + [ALERT_RULE_NAME]: 'updated-rule-name', + [ALERT_RULE_PARAMETERS]: { bar: false }, + }; + expect( buildRecoveredAlert< { count: number; url: string; - kibana?: { alert?: { action_group: string; nested_field?: number } }; + [ALERT_ACTION_GROUP]: string; + 'kibana.alert.nested_field'?: number; }, {}, {}, @@ -402,67 +342,36 @@ describe('buildRecoveredAlert', () => { payload: { count: 2, url: `https://url2`, - kibana: { alert: { action_group: 'bad action group', nested_field: 2 } }, - }, - rule: { - kibana: { - alert: { - rule: { - ...rule, - name: 'updated-rule-name', - parameters: { - bar: false, - }, - }, - }, - space_ids: ['default'], - }, + [ALERT_ACTION_GROUP]: 'bad action group', + 'kibana.alert.nested_field': 2, }, + rule: updatedRule, timestamp: '2023-03-29T12:27:28.159Z', kibanaVersion: '8.9.0', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', + ...updatedRule, count: 2, - event: { - action: 'close', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'NoLongerActive', - duration: { - us: '36000000', - }, - end: '2023-03-30T12:27:28.159Z', - flapping: false, - flapping_history: [], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: ['maint-1', 'maint-321'], - nested_field: 2, - start: '2023-03-28T12:27:28.159Z', - rule: { - ...rule, - name: 'updated-rule-name', - parameters: { - bar: false, - }, - }, - status: 'recovered', - time_range: { - lte: '2023-03-30T12:27:28.159Z', - gte: '2023-03-28T12:27:28.159Z', - }, - uuid: 'abcdefg', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.9.0', - }, url: `https://url2`, - tags: ['rule-', '-tags'], + 'kibana.alert.nested_field': 2, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'close', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'NoLongerActive', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: ['maint-1', 'maint-321'], + [ALERT_STATUS]: 'recovered', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_END]: '2023-03-30T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z', lte: '2023-03-30T12:27:28.159Z' }, + [SPACE_IDS]: ['default'], + [VERSION]: '8.9.0', + [TAGS]: ['rule-', '-tags'], }); }); }); diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/build_recovered_alert.ts b/x-pack/plugins/alerting/server/alerts_client/lib/build_recovered_alert.ts index b283844acbc63..d05f2e2ae1cec 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/build_recovered_alert.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/build_recovered_alert.ts @@ -6,6 +6,22 @@ */ import deepmerge from 'deepmerge'; import type { Alert } from '@kbn/alerts-as-data-utils'; +import { + ALERT_RULE_TAGS, + SPACE_IDS, + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_MAINTENANCE_WINDOW_IDS, + ALERT_STATUS, + EVENT_ACTION, + TAGS, + TIMESTAMP, + VERSION, + ALERT_END, + ALERT_TIME_RANGE, +} from '@kbn/rule-data-utils'; import { DeepPartial } from '@kbn/utility-types'; import { Alert as LegacyAlert } from '../../alert/alert'; import { AlertInstanceContext, AlertInstanceState, RuleAlertData } from '../../types'; @@ -59,57 +75,48 @@ export const buildRecoveredAlert = < [ alert, cleanedPayload, + // Set latest rule configuration + rule, { // Update the timestamp to reflect latest update time - '@timestamp': timestamp, - event: { - action: 'close', - }, - kibana: { - alert: { - // Set the recovery action group - action_group: recoveryActionGroup, - // Set latest flapping state - flapping: legacyAlert.getFlapping(), - // Set latest flapping_history - flapping_history: legacyAlert.getFlappingHistory(), - // Set latest maintenance window IDs - maintenance_window_ids: legacyAlert.getMaintenanceWindowIds(), - // Set latest rule configuration - rule: rule.kibana?.alert.rule, - // Set status to 'recovered' - status: 'recovered', - // Set latest duration as recovered alerts should have updated duration - ...(legacyAlert.getState().duration - ? { duration: { us: legacyAlert.getState().duration } } - : {}), - // Set end time - ...(legacyAlert.getState().end - ? { - end: legacyAlert.getState().end, - time_range: { - // this should get merged with a time_range.gte - lte: legacyAlert.getState().end, - }, - } - : {}), - - // Fields that are explicitly not updated: - // instance.id - // action_group - // uuid - recovered alerts should carry over previous UUID - // start - recovered alerts should keep the initial start time - // workflow_status - recovered alerts should keep the initial workflow_status - }, - space_ids: rule.kibana?.space_ids, - // Set latest kibana version - version: kibanaVersion, - }, - tags: Array.from( + [TIMESTAMP]: timestamp, + [EVENT_ACTION]: 'close', + // Set the recovery action group + [ALERT_ACTION_GROUP]: recoveryActionGroup, + // Set latest flapping state + [ALERT_FLAPPING]: legacyAlert.getFlapping(), + // Set latest flapping_history + [ALERT_FLAPPING_HISTORY]: legacyAlert.getFlappingHistory(), + // Set latest maintenance window IDs + [ALERT_MAINTENANCE_WINDOW_IDS]: legacyAlert.getMaintenanceWindowIds(), + // Set status to 'recovered' + [ALERT_STATUS]: 'recovered', + // Set latest duration as recovered alerts should have updated duration + ...(legacyAlert.getState().duration + ? { [ALERT_DURATION]: legacyAlert.getState().duration } + : {}), + // Set end time + ...(legacyAlert.getState().end + ? { + [ALERT_END]: legacyAlert.getState().end, + // this should get merged with a ALERT_TIME_RANGE_GTE + [ALERT_TIME_RANGE]: { lte: legacyAlert.getState().end }, + } + : {}), + // Fields that are explicitly not updated: + // instance.id + // action_group + // uuid - recovered alerts should carry over previous UUID + // start - recovered alerts should keep the initial start time + // workflow_status - recovered alerts should keep the initial workflow_status + [SPACE_IDS]: rule[SPACE_IDS], + // Set latest kibana version + [VERSION]: kibanaVersion, + [TAGS]: Array.from( new Set([ ...((cleanedPayload?.tags as string[]) ?? []), ...(alert.tags ?? []), - ...(rule.kibana?.alert.rule.tags ?? []), + ...(rule[ALERT_RULE_TAGS] ?? []), ]) ), }, diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/build_updated_recovered_alert.test.ts b/x-pack/plugins/alerting/server/alerts_client/lib/build_updated_recovered_alert.test.ts index e4793cecc71d3..458a9f6c7a7b3 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/build_updated_recovered_alert.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/build_updated_recovered_alert.test.ts @@ -7,6 +7,36 @@ import { Alert as LegacyAlert } from '../../alert/alert'; import { AlertRule } from '../types'; import { buildUpdatedRecoveredAlert } from './build_updated_recovered_alert'; +import { + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + SPACE_IDS, + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_INSTANCE_ID, + ALERT_MAINTENANCE_WINDOW_IDS, + ALERT_START, + ALERT_STATUS, + ALERT_UUID, + ALERT_WORKFLOW_STATUS, + EVENT_ACTION, + EVENT_KIND, + TAGS, + TIMESTAMP, + VERSION, + ALERT_TIME_RANGE, + ALERT_END, +} from '@kbn/rule-data-utils'; const rule = { category: 'My test rule', @@ -26,36 +56,40 @@ const rule = { }; const alertRule: AlertRule = { - kibana: { - alert: { - rule, - }, - space_ids: ['default'], - }, + [ALERT_RULE_CATEGORY]: rule.category, + [ALERT_RULE_CONSUMER]: rule.consumer, + [ALERT_RULE_EXECUTION_UUID]: rule.execution.uuid, + [ALERT_RULE_NAME]: rule.name, + [ALERT_RULE_PARAMETERS]: rule.parameters, + [ALERT_RULE_PRODUCER]: rule.producer, + [ALERT_RULE_REVISION]: rule.revision, + [ALERT_RULE_TYPE_ID]: rule.rule_type_id, + [ALERT_RULE_TAGS]: rule.tags, + [ALERT_RULE_UUID]: rule.uuid, + [SPACE_IDS]: ['default'], }; const existingRecoveredAlert = { - '@timestamp': '2023-03-28T12:27:28.159Z', - kibana: { - alert: { - action_group: 'recovered', - duration: { - us: '0', - }, - end: '2023-03-28T12:27:28.159Z', - flapping: false, - flapping_history: [true, false, false], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: ['maint-x'], - start: '2023-03-27T12:27:28.159Z', - rule, - status: 'recovered', - uuid: 'abcdefg', - }, - space_ids: ['default'], - }, + ...alertRule, + [TIMESTAMP]: '2023-03-28T12:27:28.159Z', + [EVENT_ACTION]: 'close', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'recovered', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-27T12:27:28.159Z', + [ALERT_END]: '2023-03-30T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z', lte: '2023-03-30T12:27:28.159Z' }, + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true, false, false], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: ['maint-x'], + [ALERT_STATUS]: 'recovered', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.1', + [TAGS]: ['rule-', '-tags'], }; describe('buildUpdatedRecoveredAlert', () => { @@ -82,27 +116,26 @@ describe('buildUpdatedRecoveredAlert', () => { timestamp: '2023-03-29T12:27:28.159Z', }) ).toEqual({ - '@timestamp': '2023-03-29T12:27:28.159Z', - kibana: { - alert: { - action_group: 'recovered', - duration: { - us: '0', - }, - end: '2023-03-28T12:27:28.159Z', - flapping: true, - flapping_history: [false, false, true, true], - instance: { - id: 'alert-A', - }, - maintenance_window_ids: ['maint-x'], - start: '2023-03-27T12:27:28.159Z', - rule, - status: 'recovered', - uuid: 'abcdefg', - }, - space_ids: ['default'], - }, + ...alertRule, + [TIMESTAMP]: '2023-03-29T12:27:28.159Z', + [EVENT_ACTION]: 'close', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'recovered', + [ALERT_DURATION]: '36000000', + [ALERT_START]: '2023-03-27T12:27:28.159Z', + [ALERT_END]: '2023-03-30T12:27:28.159Z', + [ALERT_TIME_RANGE]: { gte: '2023-03-28T12:27:28.159Z', lte: '2023-03-30T12:27:28.159Z' }, + [ALERT_FLAPPING]: true, + [ALERT_FLAPPING_HISTORY]: [false, false, true, true], + [ALERT_INSTANCE_ID]: 'alert-A', + [ALERT_MAINTENANCE_WINDOW_IDS]: ['maint-x'], + [ALERT_STATUS]: 'recovered', + [ALERT_START]: '2023-03-28T12:27:28.159Z', + [ALERT_UUID]: 'abcdefg', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.1', + [TAGS]: ['rule-', '-tags'], }); }); }); diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/build_updated_recovered_alert.ts b/x-pack/plugins/alerting/server/alerts_client/lib/build_updated_recovered_alert.ts index 8954bba332fc6..e8910d75040d3 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/build_updated_recovered_alert.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/build_updated_recovered_alert.ts @@ -7,6 +7,7 @@ import deepmerge from 'deepmerge'; import type { Alert } from '@kbn/alerts-as-data-utils'; +import { ALERT_FLAPPING, ALERT_FLAPPING_HISTORY, TIMESTAMP } from '@kbn/rule-data-utils'; import { RawAlertInstance } from '@kbn/alerting-state-types'; import { RuleAlertData } from '../../types'; import { AlertRule } from '../types'; @@ -32,19 +33,15 @@ export const buildUpdatedRecoveredAlert = ({ return deepmerge.all( [ alert, + // Set latest rule configuration + rule, { // Update the timestamp to reflect latest update time - '@timestamp': timestamp, - kibana: { - alert: { - // Set latest flapping state - flapping: legacyRawAlert.meta?.flapping, - // Set latest flapping history - flapping_history: legacyRawAlert.meta?.flappingHistory, - // Set latest rule configuration - rule: rule.kibana?.alert.rule, - }, - }, + [TIMESTAMP]: timestamp, + // Set latest flapping state + [ALERT_FLAPPING]: legacyRawAlert.meta?.flapping, + // Set latest flapping history + [ALERT_FLAPPING_HISTORY]: legacyRawAlert.meta?.flappingHistory, }, ], { arrayMerge: (_, sourceArray) => sourceArray } diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.test.ts b/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.test.ts index 6e8d28de01753..86e8176423a20 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.test.ts @@ -7,6 +7,19 @@ import { formatRule } from './format_rule'; import { UntypedNormalizedRuleType } from '../../rule_type_registry'; import { RecoveredActionGroup } from '../../types'; +import { + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + SPACE_IDS, +} from '@kbn/rule-data-utils'; const ruleType: jest.Mocked = { id: 'test.rule-type', @@ -51,27 +64,17 @@ describe('formatRule', () => { ruleType, }) ).toEqual({ - kibana: { - alert: { - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test.rule-type', - tags: ['rule-', '-tags'], - uuid: '1', - }, - }, - space_ids: ['default'], - }, + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test.rule-type', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [SPACE_IDS]: ['default'], }); }); }); diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.ts b/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.ts index 70588fc4cb665..33281b918c2a9 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.ts @@ -4,6 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + SPACE_IDS, +} from '@kbn/rule-data-utils'; import type { AlertRule, AlertRuleData } from '../types'; import { UntypedNormalizedRuleType } from '../../rule_type_registry'; @@ -14,24 +27,16 @@ interface FormatRuleOpts { export const formatRule = ({ rule, ruleType }: FormatRuleOpts): AlertRule => { return { - kibana: { - alert: { - rule: { - category: ruleType.name, - consumer: rule.consumer, - execution: { - uuid: rule.executionId, - }, - name: rule.name, - parameters: rule.parameters, - producer: ruleType.producer, - revision: rule.revision, - rule_type_id: ruleType.id, - tags: rule.tags, - uuid: rule.id, - }, - }, - space_ids: [rule.spaceId], - }, + [ALERT_RULE_CATEGORY]: ruleType.name, + [ALERT_RULE_CONSUMER]: rule.consumer, + [ALERT_RULE_EXECUTION_UUID]: rule.executionId, + [ALERT_RULE_NAME]: rule.name, + [ALERT_RULE_PARAMETERS]: rule.parameters, + [ALERT_RULE_PRODUCER]: ruleType.producer, + [ALERT_RULE_REVISION]: rule.revision, + [ALERT_RULE_TYPE_ID]: ruleType.id, + [ALERT_RULE_TAGS]: rule.tags, + [ALERT_RULE_UUID]: rule.id, + [SPACE_IDS]: [rule.spaceId], }; }; diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/strip_framework_fields.test.ts b/x-pack/plugins/alerting/server/alerts_client/lib/strip_framework_fields.test.ts index 5e61cbda2ac92..42e377d870ac3 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/strip_framework_fields.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/strip_framework_fields.test.ts @@ -16,6 +16,11 @@ describe('stripFrameworkFields', () => { expect(stripFrameworkFields(payload)).toEqual(payload); }); + test('should do nothing if flattened payload has no framework fields', () => { + const payload = { field1: 'test', 'kibana.alert.not_a_framework_field': 2 }; + expect(stripFrameworkFields(payload)).toEqual(payload); + }); + test(`should allow fields from the allowlist`, () => { const payload = { field1: 'test', @@ -27,6 +32,17 @@ describe('stripFrameworkFields', () => { expect(stripFrameworkFields(payload)).toEqual(payload); }); + test(`should allow fields from the allowlist in flattened payload`, () => { + const payload = { + field1: 'test', + 'kibana.alert.not_a_framework_field': 2, + 'kibana.alert.reason': 'because i said so', + 'kibana.alert.workflow_status': 'custom', + tags: ['taggity-tag'], + }; + expect(stripFrameworkFields(payload)).toEqual(payload); + }); + test(`should strip fields that the framework controls`, () => { const payload = { field1: 'test', @@ -95,4 +111,44 @@ describe('stripFrameworkFields', () => { }, }); }); + + test(`should strip flattened fields that the framework controls`, () => { + const payload = { + field1: 'test', + field2: [], + 'kibana.alert.action_group': 'invalid action group', + 'kibana.alert.not_a_framework_field1': 2, + 'kibana.alert.not_a_framework_field2': [], + 'kibana.alert.not_a_framework_field3.abc': 'xyz', + 'kibana.alert.instance.id': 'A', + 'kibana.alert.duration.us': '23543543534', + 'kibana.alert.case_ids': ['abcdefg'], + 'kibana.alert.start': 'datestring', + 'kibana.alert.status': 'bad', + 'kibana.alert.end': 'datestring', + 'kibana.alert.flapping': true, + 'kibana.alert.flapping_history': [true], + 'kibana.alert.maintenance_window_ids': ['xyz'], + 'kibana.alert.rule.category': 'My test rule', + 'kibana.alert.rule.consumer': 'bar', + 'kibana.alert.rule.execution.uuid': '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + 'kibana.alert.rule.name': 'rule-name', + 'kibana.alert.rule.parameters': { + bar: true, + }, + 'kibana.alert.rule.producer': 'alerts', + 'kibana.alert.rule.revision': 0, + 'kibana.alert.rule.rule_type_id': 'test.rule-type', + 'kibana.alert.rule.tags': ['rule-', '-tags'], + 'kibana.alert.rule.uuid': '1', + 'kibana.alert.uuid': 'uuid', + }; + expect(stripFrameworkFields(payload)).toEqual({ + field1: 'test', + field2: [], + 'kibana.alert.not_a_framework_field1': 2, + 'kibana.alert.not_a_framework_field2': [], + 'kibana.alert.not_a_framework_field3.abc': 'xyz', + }); + }); }); diff --git a/x-pack/plugins/alerting/server/alerts_client/types.ts b/x-pack/plugins/alerting/server/alerts_client/types.ts index 94adde2892623..0c48138615e43 100644 --- a/x-pack/plugins/alerting/server/alerts_client/types.ts +++ b/x-pack/plugins/alerting/server/alerts_client/types.ts @@ -8,6 +8,19 @@ import type { Alert } from '@kbn/alerts-as-data-utils'; import { DeepPartial } from '@kbn/utility-types'; import { SearchResponseBody } from '@elastic/elasticsearch/lib/api/types'; +import { + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + SPACE_IDS, +} from '@kbn/rule-data-utils'; import { Alert as LegacyAlert } from '../alert/alert'; import { AlertInstanceContext, @@ -35,12 +48,17 @@ export interface AlertRuleData { } export interface AlertRule { - kibana?: { - alert: { - rule: Alert['kibana']['alert']['rule']; - }; - space_ids: Alert['kibana']['space_ids']; - }; + [ALERT_RULE_CATEGORY]: string; + [ALERT_RULE_CONSUMER]: string; + [ALERT_RULE_EXECUTION_UUID]: string; + [ALERT_RULE_NAME]: string; + [ALERT_RULE_PARAMETERS]: unknown; + [ALERT_RULE_PRODUCER]: string; + [ALERT_RULE_REVISION]: number; + [ALERT_RULE_TYPE_ID]: string; + [ALERT_RULE_TAGS]: string[]; + [ALERT_RULE_UUID]: string; + [SPACE_IDS]: string[]; } export interface IAlertsClient< diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts index 24a47357aa0be..b8c587f18e22e 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts @@ -68,6 +68,35 @@ import { AlertsService } from '../alerts_service'; import { ReplaySubject } from 'rxjs'; import { IAlertsClient } from '../alerts_client/types'; import { getDataStreamAdapter } from '../alerts_service/lib/data_stream_adapter'; +import { + TIMESTAMP, + EVENT_ACTION, + EVENT_KIND, + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_INSTANCE_ID, + ALERT_MAINTENANCE_WINDOW_IDS, + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TYPE_ID, + ALERT_RULE_TAGS, + ALERT_RULE_UUID, + ALERT_START, + ALERT_STATUS, + ALERT_TIME_RANGE, + ALERT_UUID, + ALERT_WORKFLOW_STATUS, + SPACE_IDS, + TAGS, + VERSION, +} from '@kbn/rule-data-utils'; jest.mock('uuid', () => ({ v4: () => '5f6aa57d-3e22-484e-bae8-cbed868f4d28', @@ -494,53 +523,35 @@ describe('Task Runner', () => { }, // new alert doc { - '@timestamp': DATE_1970, - event: { - action: 'open', - kind: 'signal', - }, - kibana: { - alert: { - action_group: 'default', - duration: { - us: '0', - }, - flapping: false, - flapping_history: [true], - instance: { - id: '1', - }, - maintenance_window_ids: [], - rule: { - category: 'My test rule', - consumer: 'bar', - execution: { - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - }, - name: 'rule-name', - parameters: { - bar: true, - }, - producer: 'alerts', - revision: 0, - rule_type_id: 'test', - tags: ['rule-', '-tags'], - uuid: '1', - }, - start: DATE_1970, - status: 'active', - time_range: { - gte: DATE_1970, - }, - uuid: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', - workflow_status: 'open', - }, - space_ids: ['default'], - version: '8.8.0', - }, + [TIMESTAMP]: DATE_1970, numericField: 27, textField: 'foo', - tags: ['rule-', '-tags'], + [EVENT_ACTION]: 'open', + [EVENT_KIND]: 'signal', + [ALERT_ACTION_GROUP]: 'default', + [ALERT_DURATION]: '0', + [ALERT_FLAPPING]: false, + [ALERT_FLAPPING_HISTORY]: [true], + [ALERT_INSTANCE_ID]: '1', + [ALERT_MAINTENANCE_WINDOW_IDS]: [], + [ALERT_RULE_CATEGORY]: 'My test rule', + [ALERT_RULE_CONSUMER]: 'bar', + [ALERT_RULE_EXECUTION_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_RULE_NAME]: 'rule-name', + [ALERT_RULE_PARAMETERS]: { bar: true }, + [ALERT_RULE_PRODUCER]: 'alerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: 'test', + [ALERT_RULE_TAGS]: ['rule-', '-tags'], + [ALERT_RULE_UUID]: '1', + [ALERT_START]: DATE_1970, + [ALERT_STATUS]: 'active', + [ALERT_TIME_RANGE]: { gte: DATE_1970 }, + [ALERT_UUID]: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['default'], + [VERSION]: '8.8.0', + [TAGS]: ['rule-', '-tags'], }, ], }); diff --git a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts index 2935643348f76..2b7fd39847ce1 100644 --- a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts +++ b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts @@ -19,7 +19,6 @@ import { IRuleTypeAlerts, RuleExecutorOptions } from '@kbn/alerting-plugin/serve import { ALERT_NAMESPACE, ALERT_REASON, ALERT_URL } from '@kbn/rule-data-utils'; import { MlAnomalyDetectionAlert } from '@kbn/alerts-as-data-utils'; import { ES_FIELD_TYPES } from '@kbn/field-types'; -import { expandFlattenedAlert } from '@kbn/alerting-plugin/server/alerts_client/lib'; import { ML_ALERT_TYPES } from '../../../common/constants/alerts'; import { PLUGIN_ID } from '../../../common/constants/app'; import { MINIMUM_FULL_LICENSE } from '../../../common/license'; @@ -48,7 +47,7 @@ export type AnomalyDetectionAlertPayload = { job_id: string; anomaly_score?: number; is_interim?: boolean; - anomaly_timestamp?: number; + anomaly_timestamp?: string; top_records?: any; top_influencers?: any; } & { @@ -265,7 +264,7 @@ export function registerAnomalyDetectionAlertType({ id: name, actionGroup: ANOMALY_SCORE_MATCH_GROUP_ID, context, - payload: expandFlattenedAlert({ + payload: { [ALERT_URL]: payload[ALERT_URL], [ALERT_REASON]: payload[ALERT_REASON], [ALERT_ANOMALY_DETECTION_JOB_ID]: payload.job_id, @@ -274,7 +273,7 @@ export function registerAnomalyDetectionAlertType({ [ALERT_ANOMALY_TIMESTAMP]: payload.anomaly_timestamp, [ALERT_TOP_RECORDS]: payload.top_records, [ALERT_TOP_INFLUENCERS]: payload.top_influencers, - }), + }, }); } @@ -285,11 +284,11 @@ export function registerAnomalyDetectionAlertType({ alertsClient.setAlertData({ id: alertId, context, - payload: expandFlattenedAlert({ + payload: { [ALERT_URL]: payload[ALERT_URL], [ALERT_REASON]: payload[ALERT_REASON], [ALERT_ANOMALY_DETECTION_JOB_ID]: payload.job_id, - }), + }, }); } } diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.test.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.test.ts index 43f84acf65e78..63f5024067cea 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.test.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.test.ts @@ -303,22 +303,18 @@ describe('es_query executor', () => { latestTimestamp: undefined, }, payload: { - kibana: { - alert: { - url: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', - reason: `rule 'test-rule-name' is active: + 'kibana.alert.evaluation.conditions': + 'Number of matching documents is greater than or equal to 200', + 'kibana.alert.evaluation.value': '491', + 'kibana.alert.reason': `rule 'test-rule-name' is active: - Value: 491 - Conditions Met: Number of matching documents is greater than or equal to 200 over 5m - Timestamp: ${new Date(mockNow).toISOString()} - Link: https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id`, - title: "rule 'test-rule-name' matched query", - evaluation: { - conditions: 'Number of matching documents is greater than or equal to 200', - value: 491, - }, - }, - }, + 'kibana.alert.title': "rule 'test-rule-name' matched query", + 'kibana.alert.url': + 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', }, }); expect(mockSetLimitReached).toHaveBeenCalledTimes(1); @@ -389,23 +385,18 @@ describe('es_query executor', () => { latestTimestamp: undefined, }, payload: { - kibana: { - alert: { - url: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', - reason: `rule 'test-rule-name' is active: + 'kibana.alert.evaluation.conditions': + 'Number of matching documents for group "host-1" is greater than or equal to 200', + 'kibana.alert.evaluation.value': '291', + 'kibana.alert.reason': `rule 'test-rule-name' is active: - Value: 291 - Conditions Met: Number of matching documents for group "host-1" is greater than or equal to 200 over 5m - Timestamp: ${new Date(mockNow).toISOString()} - Link: https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id`, - title: "rule 'test-rule-name' matched query for group host-1", - evaluation: { - conditions: - 'Number of matching documents for group "host-1" is greater than or equal to 200', - value: 291, - }, - }, - }, + 'kibana.alert.title': "rule 'test-rule-name' matched query for group host-1", + 'kibana.alert.url': + 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', }, }); expect(mockReport).toHaveBeenNthCalledWith(2, { @@ -432,23 +423,18 @@ describe('es_query executor', () => { latestTimestamp: undefined, }, payload: { - kibana: { - alert: { - url: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', - reason: `rule 'test-rule-name' is active: + 'kibana.alert.evaluation.conditions': + 'Number of matching documents for group "host-2" is greater than or equal to 200', + 'kibana.alert.evaluation.value': '477', + 'kibana.alert.reason': `rule 'test-rule-name' is active: - Value: 477 - Conditions Met: Number of matching documents for group "host-2" is greater than or equal to 200 over 5m - Timestamp: ${new Date(mockNow).toISOString()} - Link: https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id`, - title: "rule 'test-rule-name' matched query for group host-2", - evaluation: { - conditions: - 'Number of matching documents for group "host-2" is greater than or equal to 200', - value: 477, - }, - }, - }, + 'kibana.alert.title': "rule 'test-rule-name' matched query for group host-2", + 'kibana.alert.url': + 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', }, }); expect(mockReport).toHaveBeenNthCalledWith(3, { @@ -475,23 +461,18 @@ describe('es_query executor', () => { latestTimestamp: undefined, }, payload: { - kibana: { - alert: { - url: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', - reason: `rule 'test-rule-name' is active: + 'kibana.alert.evaluation.conditions': + 'Number of matching documents for group "host-3" is greater than or equal to 200', + 'kibana.alert.evaluation.value': '999', + 'kibana.alert.reason': `rule 'test-rule-name' is active: - Value: 999 -- Conditions Met: Number of matching documents for group \"host-3\" is greater than or equal to 200 over 5m +- Conditions Met: Number of matching documents for group "host-3" is greater than or equal to 200 over 5m - Timestamp: ${new Date(mockNow).toISOString()} - Link: https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id`, - title: "rule 'test-rule-name' matched query for group host-3", - evaluation: { - conditions: - 'Number of matching documents for group "host-3" is greater than or equal to 200', - value: 999, - }, - }, - }, + 'kibana.alert.title': "rule 'test-rule-name' matched query for group host-3", + 'kibana.alert.url': + 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', }, }); expect(mockSetLimitReached).toHaveBeenCalledTimes(1); @@ -543,22 +524,17 @@ describe('es_query executor', () => { }, id: 'query matched', payload: { - kibana: { - alert: { - evaluation: { - conditions: 'Query matched documents', - value: 198, - }, - reason: `rule 'test-rule-name' is active: + 'kibana.alert.evaluation.conditions': 'Query matched documents', + 'kibana.alert.evaluation.value': '198', + 'kibana.alert.reason': `rule 'test-rule-name' is active: - Value: 198 - Conditions Met: Query matched documents over 5m - Timestamp: ${new Date(mockNow).toISOString()} - Link: https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id`, - title: "rule 'test-rule-name' matched query", - url: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', - }, - }, + 'kibana.alert.title': "rule 'test-rule-name' matched query", + 'kibana.alert.url': + 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', }, state: { dateEnd: new Date(mockNow).toISOString(), @@ -664,22 +640,18 @@ describe('es_query executor', () => { value: 0, }, payload: { - kibana: { - alert: { - evaluation: { - conditions: 'Number of matching documents is NOT greater than or equal to 500', - value: 0, - }, - reason: `rule 'test-rule-name' is recovered: + 'kibana.alert.evaluation.conditions': + 'Number of matching documents is NOT greater than or equal to 500', + 'kibana.alert.evaluation.value': '0', + 'kibana.alert.reason': `rule 'test-rule-name' is recovered: - Value: 0 - Conditions Met: Number of matching documents is NOT greater than or equal to 500 over 5m - Timestamp: ${new Date(mockNow).toISOString()} - Link: https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id`, - title: "rule 'test-rule-name' recovered", - url: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', - }, - }, + 'kibana.alert.title': "rule 'test-rule-name' recovered", + 'kibana.alert.url': + 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', }, }); expect(mockSetLimitReached).toHaveBeenCalledTimes(1); @@ -737,23 +709,18 @@ describe('es_query executor', () => { value: 0, }, payload: { - kibana: { - alert: { - evaluation: { - conditions: - 'Number of matching documents for group "host-1" is NOT greater than or equal to 200', - value: 0, - }, - reason: `rule 'test-rule-name' is recovered: + 'kibana.alert.evaluation.conditions': + 'Number of matching documents for group "host-1" is NOT greater than or equal to 200', + 'kibana.alert.evaluation.value': '0', + 'kibana.alert.reason': `rule 'test-rule-name' is recovered: - Value: 0 - Conditions Met: Number of matching documents for group \"host-1\" is NOT greater than or equal to 200 over 5m - Timestamp: ${new Date(mockNow).toISOString()} - Link: https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id`, - title: "rule 'test-rule-name' recovered", - url: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', - }, - }, + 'kibana.alert.title': "rule 'test-rule-name' recovered", + 'kibana.alert.url': + 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', }, }); expect(mockSetAlertData).toHaveBeenNthCalledWith(2, { @@ -773,23 +740,18 @@ describe('es_query executor', () => { value: 0, }, payload: { - kibana: { - alert: { - evaluation: { - conditions: - 'Number of matching documents for group "host-2" is NOT greater than or equal to 200', - value: 0, - }, - reason: `rule 'test-rule-name' is recovered: + 'kibana.alert.evaluation.conditions': + 'Number of matching documents for group "host-2" is NOT greater than or equal to 200', + 'kibana.alert.evaluation.value': '0', + 'kibana.alert.reason': `rule 'test-rule-name' is recovered: - Value: 0 - Conditions Met: Number of matching documents for group \"host-2\" is NOT greater than or equal to 200 over 5m - Timestamp: ${new Date(mockNow).toISOString()} - Link: https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id`, - title: "rule 'test-rule-name' recovered", - url: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', - }, - }, + 'kibana.alert.title': "rule 'test-rule-name' recovered", + 'kibana.alert.url': + 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', }, }); expect(mockSetLimitReached).toHaveBeenCalledTimes(1); @@ -842,22 +804,17 @@ describe('es_query executor', () => { value: 0, }, payload: { - kibana: { - alert: { - evaluation: { - conditions: 'Query did NOT match documents', - value: 0, - }, - reason: `rule 'test-rule-name' is recovered: + 'kibana.alert.evaluation.conditions': 'Query did NOT match documents', + 'kibana.alert.evaluation.value': '0', + 'kibana.alert.reason': `rule 'test-rule-name' is recovered: - Value: 0 - Conditions Met: Query did NOT match documents over 5m - Timestamp: ${new Date(mockNow).toISOString()} - Link: https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id`, - title: "rule 'test-rule-name' recovered", - url: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', - }, - }, + 'kibana.alert.title': "rule 'test-rule-name' recovered", + 'kibana.alert.url': + 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', }, }); expect(mockSetLimitReached).toHaveBeenCalledTimes(1); diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts index c048bfd36cefb..e6366caf53130 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts @@ -11,7 +11,6 @@ import { parseDuration } from '@kbn/alerting-plugin/server'; import { isGroupAggregation, UngroupedGroupId } from '@kbn/triggers-actions-ui-plugin/common'; import { ALERT_EVALUATION_VALUE, ALERT_REASON, ALERT_URL } from '@kbn/rule-data-utils'; -import { expandFlattenedAlert } from '@kbn/alerting-plugin/server/alerts_client/lib'; import { ComparatorFns } from '../../../common'; import { addMessages, @@ -148,13 +147,13 @@ export async function executor(core: CoreSetup, options: ExecutorOptions { actionGroup: 'query matched', id: 'query matched', payload: expect.objectContaining({ - kibana: { - alert: { - url: expect.any(String), - reason: expect.any(String), - title: "rule 'rule-name' matched query", - evaluation: { - conditions: 'Number of matching documents is greater than or equal to 3', - value: 3, - }, - }, - }, + 'kibana.alert.evaluation.conditions': + 'Number of matching documents is greater than or equal to 3', + 'kibana.alert.evaluation.value': '3', + 'kibana.alert.reason': expect.any(String), + 'kibana.alert.title': "rule 'rule-name' matched query", + 'kibana.alert.url': expect.any(String), }), }) ); @@ -836,17 +831,11 @@ describe('ruleType', () => { actionGroup: 'query matched', id: 'query matched', payload: expect.objectContaining({ - kibana: { - alert: { - url: expect.any(String), - reason: expect.any(String), - title: "rule 'rule-name' matched query", - evaluation: { - conditions: 'Query matched documents', - value: 3, - }, - }, - }, + 'kibana.alert.evaluation.conditions': 'Query matched documents', + 'kibana.alert.evaluation.value': '3', + 'kibana.alert.reason': expect.any(String), + 'kibana.alert.title': "rule 'rule-name' matched query", + 'kibana.alert.url': expect.any(String), }), }) ); diff --git a/x-pack/plugins/stack_alerts/server/rule_types/index_threshold/rule_type.test.ts b/x-pack/plugins/stack_alerts/server/rule_types/index_threshold/rule_type.test.ts index 1e0aab0bb7930..0d0c7a9f49b33 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/index_threshold/rule_type.test.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/index_threshold/rule_type.test.ts @@ -242,17 +242,14 @@ describe('ruleType', () => { }, id: 'all documents', payload: { - kibana: { - alert: { - evaluation: { conditions: 'foo is less than 1', value: 0 }, - reason: `alert '${ruleName}' is active for group 'all documents': + 'kibana.alert.evaluation.conditions': 'foo is less than 1', + 'kibana.alert.evaluation.value': '0', + 'kibana.alert.reason': `alert '${ruleName}' is active for group 'all documents': - Value: 0 - Conditions Met: foo is less than 1 over 5m - Timestamp: 1970-01-01T00:00:00.000Z`, - title: `alert ${ruleName} group all documents met threshold`, - }, - }, + 'kibana.alert.title': `alert ${ruleName} group all documents met threshold`, }, state: {}, }); diff --git a/x-pack/plugins/stack_alerts/server/rule_types/index_threshold/rule_type.ts b/x-pack/plugins/stack_alerts/server/rule_types/index_threshold/rule_type.ts index a2e27231c76f9..c55e727c01bbf 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/index_threshold/rule_type.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/index_threshold/rule_type.ts @@ -17,7 +17,6 @@ import { ALERT_REASON, STACK_ALERTS_FEATURE_ID, } from '@kbn/rule-data-utils'; -import { expandFlattenedAlert } from '@kbn/alerting-plugin/server/alerts_client/lib'; import { ALERT_EVALUATION_CONDITIONS, ALERT_TITLE, STACK_ALERTS_AAD_CONFIG } from '..'; import { ComparatorFns, getComparatorScript, getHumanReadableComparator } from '../../../common'; import { ActionContext, BaseActionContext, addMessages } from './action_context'; @@ -320,12 +319,12 @@ export function getRuleType( actionGroup: ActionGroupId, state: {}, context: actionContext, - payload: expandFlattenedAlert({ + payload: { [ALERT_REASON]: actionContext.message, [ALERT_TITLE]: actionContext.title, [ALERT_EVALUATION_CONDITIONS]: actionContext.conditions, - [ALERT_EVALUATION_VALUE]: actionContext.value, - }), + [ALERT_EVALUATION_VALUE]: `${actionContext.value}`, + }, }); logger.debug(`scheduled actionGroup: ${JSON.stringify(actionContext)}`); } @@ -348,12 +347,12 @@ export function getRuleType( alertsClient?.setAlertData({ id: alertId, context: recoveryContext, - payload: expandFlattenedAlert({ + payload: { [ALERT_REASON]: recoveryContext.message, [ALERT_TITLE]: recoveryContext.title, [ALERT_EVALUATION_CONDITIONS]: recoveryContext.conditions, - [ALERT_EVALUATION_VALUE]: recoveryContext.value, - }), + [ALERT_EVALUATION_VALUE]: `${recoveryContext.value}`, + }, }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts index 941f663bb6284..e36d22a6c85af 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts @@ -152,9 +152,8 @@ export default function alertTests({ getService }: FtrProviderContext) { const aadDocs = await waitForAAD(1); for (const doc of aadDocs) { - const { job_id: jobId, url } = doc._source.kibana.alert; - expect(jobId).to.be(AD_JOB_ID); - expect(url).to.contain( + expect(doc._source['kibana.alert.job_id']).to.be(AD_JOB_ID); + expect(doc._source['kibana.alert.url']).to.contain( '/s/space1/app/ml/explorer/?_g=(ml%3A(jobIds%3A!(rt-anomaly-mean-value))' ); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts index eee79e38a2dac..fc548df7a3426 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; +import { ALERT_REASON, ALERT_URL } from '@kbn/rule-data-utils'; import { Spaces } from '../../../../../scenarios'; import { FtrProviderContext } from '../../../../../../common/ftr_provider_context'; import { getUrlPrefix, ObjectRemover } from '../../../../../../common/lib'; @@ -97,12 +98,13 @@ export default function ruleTests({ getService }: FtrProviderContext) { const aadDocs = await getAllAADDocs(1); - const alertDoc = aadDocs.body.hits.hits[0]._source.kibana.alert; - expect(alertDoc.reason).to.match(messagePattern); - expect(alertDoc.title).to.be("rule 'always fire' matched query"); - expect(alertDoc.evaluation.conditions).to.be('Query matched documents'); - expect(alertDoc.evaluation.value).greaterThan(0); - expect(alertDoc.url).to.contain('/s/space1/app/'); + const alertDoc = aadDocs.body.hits.hits[0]._source; + expect(alertDoc[ALERT_REASON]).to.match(messagePattern); + expect(alertDoc['kibana.alert.title']).to.be("rule 'always fire' matched query"); + expect(alertDoc['kibana.alert.evaluation.conditions']).to.be('Query matched documents'); + const value = parseInt(alertDoc['kibana.alert.evaluation.value'], 10); + expect(value).greaterThan(0); + expect(alertDoc[ALERT_URL]).to.contain('/s/space1/app/'); }); it('runs correctly: use epoch millis - threshold on hit count < >', async () => { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts index 25ca53c52e429..0e0ad5cc9bb68 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts @@ -9,6 +9,7 @@ import expect from '@kbn/expect'; import { ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; +import { ALERT_REASON, ALERT_URL } from '@kbn/rule-data-utils'; import { Spaces } from '../../../../../scenarios'; import { FtrProviderContext } from '../../../../../../common/ftr_provider_context'; import { getUrlPrefix, ObjectRemover } from '../../../../../../common/lib'; @@ -162,14 +163,15 @@ export default function ruleTests({ getService }: FtrProviderContext) { const aadDocs = await getAllAADDocs(1); - const alertDoc = aadDocs.body.hits.hits[0]._source.kibana.alert; - expect(alertDoc.reason).to.match(messagePattern); - expect(alertDoc.title).to.be("rule 'always fire' matched query"); - expect(alertDoc.evaluation.conditions).to.be( + const alertDoc = aadDocs.body.hits.hits[0]._source; + expect(alertDoc[ALERT_REASON]).to.match(messagePattern); + expect(alertDoc['kibana.alert.title']).to.be("rule 'always fire' matched query"); + expect(alertDoc['kibana.alert.evaluation.conditions']).to.be( 'Number of matching documents is greater than -1' ); - expect(alertDoc.evaluation.value).greaterThan(0); - expect(alertDoc.url).to.contain('/s/space1/app/'); + const value = parseInt(alertDoc['kibana.alert.evaluation.value'], 10); + expect(value).greaterThan(0); + expect(alertDoc[ALERT_URL]).to.contain('/s/space1/app/'); }) ); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/index_threshold/alert.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/index_threshold/alert.ts index 3de5e761b2622..f7e2dd9ec983c 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/index_threshold/alert.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/index_threshold/alert.ts @@ -10,6 +10,7 @@ import expect from '@kbn/expect'; import { ESTestIndexTool, ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; import { STACK_AAD_INDEX_NAME } from '@kbn/stack-alerts-plugin/server/rule_types'; +import { ALERT_REASON } from '@kbn/rule-data-utils'; import { Spaces } from '../../../../../scenarios'; import { FtrProviderContext } from '../../../../../../common/ftr_provider_context'; import { getUrlPrefix, ObjectRemover, getEventLog } from '../../../../../../common/lib'; @@ -111,12 +112,17 @@ export default function ruleTests({ getService }: FtrProviderContext) { const aadDocs = await esTestIndexToolAAD.getAll(1); + const alertDoc = aadDocs.body.hits.hits[0]._source; // @ts-ignore - const alertDoc = aadDocs.body.hits.hits[0]._source.kibana.alert; - expect(alertDoc.reason).to.match(messagePattern); - expect(alertDoc.title).to.be('alert always fire group all documents met threshold'); - expect(alertDoc.evaluation.conditions).to.be('count is greater than -1'); - expect(alertDoc.evaluation.value).greaterThan(0); + expect(alertDoc[ALERT_REASON]).to.match(messagePattern); + // @ts-ignore + expect(alertDoc['kibana.alert.title']).to.be( + 'alert always fire group all documents met threshold' + ); + // @ts-ignore + expect(alertDoc['kibana.alert.evaluation.conditions']).to.be('count is greater than -1'); + // @ts-ignore + expect(alertDoc['kibana.alert.evaluation.value']).greaterThan(0); }); it('runs correctly: count grouped <= =>', async () => { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data.ts index 13f3c5d445916..83dfff9c08d08 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data.ts @@ -10,6 +10,31 @@ import { SearchHit } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { IValidatedEvent } from '@kbn/event-log-plugin/server'; import type { Alert } from '@kbn/alerts-as-data-utils'; import { omit } from 'lodash'; +import { + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_END, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_INSTANCE_ID, + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + ALERT_START, + ALERT_STATUS, + ALERT_TIME_RANGE, + ALERT_UUID, + ALERT_WORKFLOW_STATUS, + EVENT_ACTION, + EVENT_KIND, + SPACE_IDS, +} from '@kbn/rule-data-utils'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { Spaces } from '../../../../scenarios'; import { @@ -97,57 +122,57 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F const source: PatternFiringAlert = alertDocsRun1[i]._source!; // Each doc should have active status and default action group id - expect(source.kibana.alert.action_group).to.equal('default'); + expect(source[ALERT_ACTION_GROUP]).to.equal('default'); // patternIndex should be 0 for the first run expect(source.patternIndex).to.equal(0); // alert UUID should equal doc id - expect(source.kibana.alert.uuid).to.equal(alertDocsRun1[i]._id); + expect(source[ALERT_UUID]).to.equal(alertDocsRun1[i]._id); // duration should be '0' since this is a new alert - expect(source.kibana.alert.duration?.us).to.equal('0'); + expect(source[ALERT_DURATION]).to.equal('0'); // start should be defined - expect(source.kibana.alert.start).to.match(timestampPattern); + expect(source[ALERT_START]).to.match(timestampPattern); // time_range.gte should be same as start - expect(source.kibana.alert.time_range?.gte).to.equal(source.kibana.alert.start); + expect(source[ALERT_TIME_RANGE]?.gte).to.equal(source[ALERT_START]); // timestamp should be defined expect(source['@timestamp']).to.match(timestampPattern); // status should be active - expect(source.kibana.alert.status).to.equal('active'); + expect(source[ALERT_STATUS]).to.equal('active'); // flapping information for new alert - expect(source.kibana.alert.flapping).to.equal(false); - expect(source.kibana.alert.flapping_history).to.eql([true]); + expect(source[ALERT_FLAPPING]).to.equal(false); + expect(source[ALERT_FLAPPING_HISTORY]).to.eql([true]); // workflow status should be 'open' - expect(source.kibana.alert.workflow_status).to.equal('open'); + expect(source[ALERT_WORKFLOW_STATUS]).to.equal('open'); // event.action should be 'open' - expect(source.event?.action).to.equal('open'); + expect(source[EVENT_ACTION]).to.equal('open'); // event.kind should be 'signal' - expect(source.event?.kind).to.equal('signal'); + expect(source[EVENT_KIND]).to.equal('signal'); // tags should equal rule tags because rule type doesn't set any tags expect(source.tags).to.eql(['foo']); } let alertDoc: SearchHit | undefined = alertDocsRun1.find( - (doc) => doc._source!.kibana.alert.instance.id === 'alertA' + (doc) => doc._source![ALERT_INSTANCE_ID] === 'alertA' ); const alertADocRun1 = alertDoc!._source!; expect(alertADocRun1.instancePattern).to.eql(pattern.alertA); - alertDoc = alertDocsRun1.find((doc) => doc._source!.kibana.alert.instance.id === 'alertB'); + alertDoc = alertDocsRun1.find((doc) => doc._source![ALERT_INSTANCE_ID] === 'alertB'); const alertBDocRun1 = alertDoc!._source!; expect(alertBDocRun1.instancePattern).to.eql(pattern.alertB); - alertDoc = alertDocsRun1.find((doc) => doc._source!.kibana.alert.instance.id === 'alertC'); + alertDoc = alertDocsRun1.find((doc) => doc._source![ALERT_INSTANCE_ID] === 'alertC'); const alertCDocRun1 = alertDoc!._source!; expect(alertCDocRun1.instancePattern).to.eql(pattern.alertC); @@ -182,130 +207,118 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F const source: PatternFiringAlert = alertDocsRun2[i]._source!; // alert UUID should equal doc id - expect(source.kibana.alert.uuid).to.equal(alertDocsRun2[i]._id); + expect(source[ALERT_UUID]).to.equal(alertDocsRun2[i]._id); // duration should be greater than 0 since these are not new alerts - const durationAsNumber = Number(source.kibana.alert.duration?.us); + const durationAsNumber = Number(source[ALERT_DURATION]); expect(durationAsNumber).to.be.greaterThan(0); } // alertA, run2 // status is still active; duration is updated; no end time - alertDoc = alertDocsRun2.find((doc) => doc._source!.kibana.alert.instance.id === 'alertA'); + alertDoc = alertDocsRun2.find((doc) => doc._source![ALERT_INSTANCE_ID] === 'alertA'); const alertADocRun2 = alertDoc!._source!; expect(alertADocRun2.instancePattern).to.eql(pattern.alertA); // uuid is the same - expect(alertADocRun2.kibana.alert.uuid).to.equal(alertADocRun1.kibana.alert.uuid); + expect(alertADocRun2[ALERT_UUID]).to.equal(alertADocRun1[ALERT_UUID]); // patternIndex should be 1 for the second run expect(alertADocRun2.patternIndex).to.equal(1); - expect(alertADocRun2.kibana.alert.action_group).to.equal('default'); + expect(alertADocRun2[ALERT_ACTION_GROUP]).to.equal('default'); // start time should be defined and the same as prior run - expect(alertADocRun2.kibana.alert.start).to.match(timestampPattern); - expect(alertADocRun2.kibana.alert.start).to.equal(alertADocRun1.kibana.alert.start); + expect(alertADocRun2[ALERT_START]).to.match(timestampPattern); + expect(alertADocRun2[ALERT_START]).to.equal(alertADocRun1[ALERT_START]); // timestamp should be defined and not the same as prior run expect(alertADocRun2['@timestamp']).to.match(timestampPattern); expect(alertADocRun2['@timestamp']).not.to.equal(alertADocRun1['@timestamp']); // status should still be active - expect(alertADocRun2.kibana.alert.status).to.equal('active'); + expect(alertADocRun2[ALERT_STATUS]).to.equal('active'); // flapping false, flapping history updated with additional entry - expect(alertADocRun2.kibana.alert.flapping).to.equal(false); - expect(alertADocRun2.kibana.alert.flapping_history).to.eql([ - ...alertADocRun1.kibana.alert.flapping_history!, + expect(alertADocRun2[ALERT_FLAPPING]).to.equal(false); + expect(alertADocRun2[ALERT_FLAPPING_HISTORY]).to.eql([ + ...alertADocRun1[ALERT_FLAPPING_HISTORY]!, false, ]); // event.action set to active - expect(alertADocRun2.event?.action).to.eql('active'); + expect(alertADocRun2[EVENT_ACTION]).to.eql('active'); expect(alertADocRun2.tags).to.eql(['foo']); // these values should be the same as previous run - expect(alertADocRun2.event?.kind).to.eql(alertADocRun1.event?.kind); - expect(alertADocRun2.kibana.alert.workflow_status).to.eql( - alertADocRun1.kibana.alert.workflow_status - ); - expect(alertADocRun2.kibana.alert.time_range?.gte).to.equal( - alertADocRun1.kibana.alert.time_range?.gte - ); + expect(alertADocRun2[EVENT_KIND]).to.eql(alertADocRun1[EVENT_KIND]); + expect(alertADocRun2[ALERT_WORKFLOW_STATUS]).to.eql(alertADocRun1[ALERT_WORKFLOW_STATUS]); + expect(alertADocRun2[ALERT_TIME_RANGE]?.gte).to.equal(alertADocRun1[ALERT_TIME_RANGE]?.gte); // alertB, run 2 // status is updated to recovered, duration is updated, end time is set - alertDoc = alertDocsRun2.find((doc) => doc._source!.kibana.alert.instance.id === 'alertB'); + alertDoc = alertDocsRun2.find((doc) => doc._source![ALERT_INSTANCE_ID] === 'alertB'); const alertBDocRun2 = alertDoc!._source!; // action group should be set to recovered - expect(alertBDocRun2.kibana.alert.action_group).to.be('recovered'); + expect(alertBDocRun2[ALERT_ACTION_GROUP]).to.be('recovered'); // rule type AAD payload should be set to recovery values expect(alertBDocRun2.instancePattern).to.eql([]); expect(alertBDocRun2.patternIndex).to.eql(-1); // uuid is the same - expect(alertBDocRun2.kibana.alert.uuid).to.equal(alertBDocRun1.kibana.alert.uuid); + expect(alertBDocRun2[ALERT_UUID]).to.equal(alertBDocRun1[ALERT_UUID]); // start time should be defined and the same as before - expect(alertBDocRun2.kibana.alert.start).to.match(timestampPattern); - expect(alertBDocRun2.kibana.alert.start).to.equal(alertBDocRun1.kibana.alert.start); + expect(alertBDocRun2[ALERT_START]).to.match(timestampPattern); + expect(alertBDocRun2[ALERT_START]).to.equal(alertBDocRun1[ALERT_START]); // timestamp should be defined and not the same as prior run expect(alertBDocRun2['@timestamp']).to.match(timestampPattern); expect(alertBDocRun2['@timestamp']).not.to.equal(alertBDocRun1['@timestamp']); // end time should be defined - expect(alertBDocRun2.kibana.alert.end).to.match(timestampPattern); + expect(alertBDocRun2[ALERT_END]).to.match(timestampPattern); // status should be set to recovered - expect(alertBDocRun2.kibana.alert.status).to.equal('recovered'); + expect(alertBDocRun2[ALERT_STATUS]).to.equal('recovered'); // flapping false, flapping history updated with additional entry - expect(alertBDocRun2.kibana.alert.flapping).to.equal(false); - expect(alertBDocRun2.kibana.alert.flapping_history).to.eql([ - ...alertBDocRun1.kibana.alert.flapping_history!, + expect(alertBDocRun2[ALERT_FLAPPING]).to.equal(false); + expect(alertBDocRun2[ALERT_FLAPPING_HISTORY]).to.eql([ + ...alertBDocRun1[ALERT_FLAPPING_HISTORY]!, true, ]); // event.action set to close - expect(alertBDocRun2.event?.action).to.eql('close'); + expect(alertBDocRun2[EVENT_ACTION]).to.eql('close'); expect(alertBDocRun2.tags).to.eql(['foo']); // these values should be the same as previous run - expect(alertBDocRun2.event?.kind).to.eql(alertBDocRun1.event?.kind); - expect(alertBDocRun2.kibana.alert.workflow_status).to.eql( - alertBDocRun1.kibana.alert.workflow_status - ); - expect(alertBDocRun2.kibana.alert.time_range?.gte).to.equal( - alertBDocRun1.kibana.alert.time_range?.gte - ); + expect(alertBDocRun2[EVENT_KIND]).to.eql(alertBDocRun1[EVENT_KIND]); + expect(alertBDocRun2[ALERT_WORKFLOW_STATUS]).to.eql(alertBDocRun1[ALERT_WORKFLOW_STATUS]); + expect(alertBDocRun2[ALERT_TIME_RANGE]?.gte).to.equal(alertBDocRun1[ALERT_TIME_RANGE]?.gte); // time_range.lte should be set to end time - expect(alertBDocRun2.kibana.alert.time_range?.lte).to.equal(alertBDocRun2.kibana.alert.end); + expect(alertBDocRun2[ALERT_TIME_RANGE]?.lte).to.equal(alertBDocRun2[ALERT_END]); // alertC, run 2 // status is updated to recovered, duration is updated, end time is set - alertDoc = alertDocsRun2.find((doc) => doc._source!.kibana.alert.instance.id === 'alertC'); + alertDoc = alertDocsRun2.find((doc) => doc._source![ALERT_INSTANCE_ID] === 'alertC'); const alertCDocRun2 = alertDoc!._source!; // action group should be set to recovered - expect(alertCDocRun2.kibana.alert.action_group).to.be('recovered'); + expect(alertCDocRun2[ALERT_ACTION_GROUP]).to.be('recovered'); // rule type AAD payload should be set to recovery values expect(alertCDocRun2.instancePattern).to.eql([]); expect(alertCDocRun2.patternIndex).to.eql(-1); // uuid is the same - expect(alertCDocRun2.kibana.alert.uuid).to.equal(alertCDocRun1.kibana.alert.uuid); + expect(alertCDocRun2[ALERT_UUID]).to.equal(alertCDocRun1[ALERT_UUID]); // start time should be defined and the same as before - expect(alertCDocRun2.kibana.alert.start).to.match(timestampPattern); - expect(alertCDocRun2.kibana.alert.start).to.equal(alertCDocRun1.kibana.alert.start); + expect(alertCDocRun2[ALERT_START]).to.match(timestampPattern); + expect(alertCDocRun2[ALERT_START]).to.equal(alertCDocRun1[ALERT_START]); // timestamp should be defined and not the same as prior run expect(alertCDocRun2['@timestamp']).to.match(timestampPattern); expect(alertCDocRun2['@timestamp']).not.to.equal(alertCDocRun1['@timestamp']); // end time should be defined - expect(alertCDocRun2.kibana.alert.end).to.match(timestampPattern); + expect(alertCDocRun2[ALERT_END]).to.match(timestampPattern); // status should be set to recovered - expect(alertCDocRun2.kibana.alert.status).to.equal('recovered'); + expect(alertCDocRun2[ALERT_STATUS]).to.equal('recovered'); // flapping false, flapping history updated with additional entry - expect(alertCDocRun2.kibana.alert.flapping).to.equal(false); - expect(alertCDocRun2.kibana.alert.flapping_history).to.eql([ - ...alertCDocRun1.kibana.alert.flapping_history!, + expect(alertCDocRun2[ALERT_FLAPPING]).to.equal(false); + expect(alertCDocRun2[ALERT_FLAPPING_HISTORY]).to.eql([ + ...alertCDocRun1[ALERT_FLAPPING_HISTORY]!, true, ]); // event.action set to close - expect(alertCDocRun2.event?.action).to.eql('close'); + expect(alertCDocRun2[EVENT_ACTION]).to.eql('close'); expect(alertCDocRun2.tags).to.eql(['foo']); // these values should be the same as previous run - expect(alertCDocRun2.event?.kind).to.eql(alertADocRun1.event?.kind); - expect(alertCDocRun2.kibana.alert.workflow_status).to.eql( - alertCDocRun1.kibana.alert.workflow_status - ); - expect(alertCDocRun2.kibana.alert.time_range?.gte).to.equal( - alertCDocRun1.kibana.alert.time_range?.gte - ); + expect(alertCDocRun2[EVENT_KIND]).to.eql(alertADocRun1[EVENT_KIND]); + expect(alertCDocRun2[ALERT_WORKFLOW_STATUS]).to.eql(alertCDocRun1[ALERT_WORKFLOW_STATUS]); + expect(alertCDocRun2[ALERT_TIME_RANGE]?.gte).to.equal(alertCDocRun1[ALERT_TIME_RANGE]?.gte); // time_range.lte should be set to end time - expect(alertCDocRun2.kibana.alert.time_range?.lte).to.equal(alertCDocRun2.kibana.alert.end); + expect(alertCDocRun2[ALERT_TIME_RANGE]?.lte).to.equal(alertCDocRun2[ALERT_END]); // -------------------------- // RUN 3 - 1 re-active (alertC), 1 still recovered (alertB), 1 ongoing (alertA) @@ -340,97 +353,93 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // alertA, run3 // status is still active; duration is updated; no end time - alertDoc = alertDocsRun3.find((doc) => doc._source!.kibana.alert.instance.id === 'alertA'); + alertDoc = alertDocsRun3.find((doc) => doc._source![ALERT_INSTANCE_ID] === 'alertA'); const alertADocRun3 = alertDoc!._source!; expect(alertADocRun3.instancePattern).to.eql(pattern.alertA); // uuid is the same as previous runs - expect(alertADocRun3.kibana.alert.uuid).to.equal(alertADocRun2.kibana.alert.uuid); - expect(alertADocRun3.kibana.alert.uuid).to.equal(alertADocRun1.kibana.alert.uuid); + expect(alertADocRun3[ALERT_UUID]).to.equal(alertADocRun2[ALERT_UUID]); + expect(alertADocRun3[ALERT_UUID]).to.equal(alertADocRun1[ALERT_UUID]); // patternIndex should be 2 for the third run expect(alertADocRun3.patternIndex).to.equal(2); - expect(alertADocRun3.kibana.alert.action_group).to.equal('default'); + expect(alertADocRun3[ALERT_ACTION_GROUP]).to.equal('default'); // start time should be defined and the same as prior runs - expect(alertADocRun3.kibana.alert.start).to.match(timestampPattern); - expect(alertADocRun3.kibana.alert.start).to.equal(alertADocRun2.kibana.alert.start); - expect(alertADocRun3.kibana.alert.start).to.equal(alertADocRun1.kibana.alert.start); + expect(alertADocRun3[ALERT_START]).to.match(timestampPattern); + expect(alertADocRun3[ALERT_START]).to.equal(alertADocRun2[ALERT_START]); + expect(alertADocRun3[ALERT_START]).to.equal(alertADocRun1[ALERT_START]); // timestamp should be defined and not the same as prior run expect(alertADocRun3['@timestamp']).to.match(timestampPattern); expect(alertADocRun3['@timestamp']).not.to.equal(alertADocRun2['@timestamp']); // status should still be active - expect(alertADocRun3.kibana.alert.status).to.equal('active'); + expect(alertADocRun3[ALERT_STATUS]).to.equal('active'); // flapping false, flapping history updated with additional entry - expect(alertADocRun3.kibana.alert.flapping).to.equal(false); - expect(alertADocRun3.kibana.alert.flapping_history).to.eql([ - ...alertADocRun2.kibana.alert.flapping_history!, + expect(alertADocRun3[ALERT_FLAPPING]).to.equal(false); + expect(alertADocRun3[ALERT_FLAPPING_HISTORY]).to.eql([ + ...alertADocRun2[ALERT_FLAPPING_HISTORY]!, false, ]); // event.action should still to active - expect(alertADocRun3.event?.action).to.eql('active'); + expect(alertADocRun3[EVENT_ACTION]).to.eql('active'); expect(alertADocRun3.tags).to.eql(['foo']); // these values should be the same as previous run - expect(alertADocRun3.event?.kind).to.eql(alertADocRun2.event?.kind); - expect(alertADocRun3.kibana.alert.workflow_status).to.eql( - alertADocRun2.kibana.alert.workflow_status - ); - expect(alertADocRun3.kibana.alert.time_range?.gte).to.equal( - alertADocRun2.kibana.alert.time_range?.gte - ); + expect(alertADocRun3[EVENT_KIND]).to.eql(alertADocRun2[EVENT_KIND]); + expect(alertADocRun3[ALERT_WORKFLOW_STATUS]).to.eql(alertADocRun2[ALERT_WORKFLOW_STATUS]); + expect(alertADocRun3[ALERT_TIME_RANGE]?.gte).to.equal(alertADocRun2[ALERT_TIME_RANGE]?.gte); // alertB doc should be unchanged from prior run because it is still recovered // but its flapping history should be updated - alertDoc = alertDocsRun3.find((doc) => doc._source!.kibana.alert.instance.id === 'alertB'); + alertDoc = alertDocsRun3.find((doc) => doc._source![ALERT_INSTANCE_ID] === 'alertB'); const alertBDocRun3 = alertDoc!._source!; expect(omit(alertBDocRun3, fieldsToOmitInComparison)).to.eql( omit(alertBDocRun2, fieldsToOmitInComparison) ); // execution uuid should be current one - expect(alertBDocRun3.kibana.alert.rule.execution?.uuid).to.equal(executionUuid); + expect(alertBDocRun3[ALERT_RULE_EXECUTION_UUID]).to.equal(executionUuid); // flapping history should be history from prior run with additional entry - expect(alertBDocRun3.kibana.alert.flapping_history).to.eql([ - ...alertBDocRun2.kibana.alert.flapping_history!, + expect(alertBDocRun3[ALERT_FLAPPING_HISTORY]).to.eql([ + ...alertBDocRun2[ALERT_FLAPPING_HISTORY]!, false, ]); // alertC should have 2 docs const alertCDocs = alertDocsRun3.filter( - (doc) => doc._source!.kibana.alert.instance.id === 'alertC' + (doc) => doc._source![ALERT_INSTANCE_ID] === 'alertC' ); // alertC recovered doc should be exactly the same as the alertC doc from prior run const recoveredAlertCDoc = alertCDocs.find( - (doc) => doc._source!.kibana.alert.rule.execution?.uuid !== executionUuid + (doc) => doc._source![ALERT_RULE_EXECUTION_UUID] !== executionUuid )!._source!; expect(recoveredAlertCDoc).to.eql(alertCDocRun2); // alertC doc from current execution const alertCDocRun3 = alertCDocs.find( - (doc) => doc._source!.kibana.alert.rule.execution?.uuid === executionUuid + (doc) => doc._source![ALERT_RULE_EXECUTION_UUID] === executionUuid )!._source!; expect(alertCDocRun3.instancePattern).to.eql(pattern.alertC); // uuid is the different from prior run] - expect(alertCDocRun3.kibana.alert.uuid).not.to.equal(alertCDocRun2.kibana.alert.uuid); - expect(alertCDocRun3.kibana.alert.action_group).to.equal('default'); + expect(alertCDocRun3[ALERT_UUID]).not.to.equal(alertCDocRun2[ALERT_UUID]); + expect(alertCDocRun3[ALERT_ACTION_GROUP]).to.equal('default'); // patternIndex should be 2 for the third run expect(alertCDocRun3.patternIndex).to.equal(2); // start time should be defined and different from the prior run - expect(alertCDocRun3.kibana.alert.start).to.match(timestampPattern); - expect(alertCDocRun3.kibana.alert.start).not.to.equal(alertCDocRun2.kibana.alert.start); + expect(alertCDocRun3[ALERT_START]).to.match(timestampPattern); + expect(alertCDocRun3[ALERT_START]).not.to.equal(alertCDocRun2[ALERT_START]); // timestamp should be defined and not the same as prior run expect(alertCDocRun3['@timestamp']).to.match(timestampPattern); // duration should be '0' since this is a new alert - expect(alertCDocRun3.kibana.alert.duration?.us).to.equal('0'); + expect(alertCDocRun3[ALERT_DURATION]).to.equal('0'); // flapping false, flapping history should be history from prior run with additional entry - expect(alertCDocRun3.kibana.alert.flapping).to.equal(false); - expect(alertCDocRun3.kibana.alert.flapping_history).to.eql([ - ...alertCDocRun2.kibana.alert.flapping_history!, + expect(alertCDocRun3[ALERT_FLAPPING]).to.equal(false); + expect(alertCDocRun3[ALERT_FLAPPING_HISTORY]).to.eql([ + ...alertCDocRun2[ALERT_FLAPPING_HISTORY]!, true, ]); // event.action should be 'open' - expect(alertCDocRun3.event?.action).to.eql('open'); + expect(alertCDocRun3[EVENT_ACTION]).to.eql('open'); expect(alertCDocRun3.tags).to.eql(['foo']); // these values should be the same as previous run - expect(alertCDocRun3.event?.kind).to.eql('signal'); - expect(alertCDocRun3.kibana.alert.workflow_status).to.eql('open'); - expect(alertCDocRun3.kibana.alert.time_range?.gte).to.equal(alertCDocRun3.kibana.alert.start); + expect(alertCDocRun3[EVENT_KIND]).to.eql('signal'); + expect(alertCDocRun3[ALERT_WORKFLOW_STATUS]).to.eql('open'); + expect(alertCDocRun3[ALERT_TIME_RANGE]?.gte).to.equal(alertCDocRun3[ALERT_START]); }); }); @@ -444,20 +453,20 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F const source: PatternFiringAlert = alertDocs[i]._source!; // Each doc should have a copy of the rule data - expect(source.kibana.alert.rule.category).to.equal( + expect(source[ALERT_RULE_CATEGORY]).to.equal( 'Test: Firing on a Pattern and writing Alerts as Data' ); - expect(source.kibana.alert.rule.consumer).to.equal('alertsFixture'); - expect(source.kibana.alert.rule.name).to.equal('abc'); - expect(source.kibana.alert.rule.producer).to.equal('alertsFixture'); - expect(source.kibana.alert.rule.tags).to.eql(['foo']); - expect(source.kibana.alert.rule.rule_type_id).to.equal('test.patternFiringAad'); - expect(source.kibana.alert.rule.uuid).to.equal(ruleId); - expect(source.kibana.alert.rule.parameters).to.eql(ruleParameters); - expect(source.kibana.space_ids).to.eql(['space1']); + expect(source[ALERT_RULE_CONSUMER]).to.equal('alertsFixture'); + expect(source[ALERT_RULE_NAME]).to.equal('abc'); + expect(source[ALERT_RULE_PRODUCER]).to.equal('alertsFixture'); + expect(source[ALERT_RULE_TAGS]).to.eql(['foo']); + expect(source[ALERT_RULE_TYPE_ID]).to.equal('test.patternFiringAad'); + expect(source[ALERT_RULE_UUID]).to.equal(ruleId); + expect(source[ALERT_RULE_PARAMETERS]).to.eql(ruleParameters); + expect(source[SPACE_IDS]).to.eql(['space1']); if (executionUuid) { - expect(source.kibana.alert.rule.execution?.uuid).to.equal(executionUuid); + expect(source[ALERT_RULE_EXECUTION_UUID]).to.equal(executionUuid); } } } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_conflicts.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_conflicts.ts index c0243dbd482fd..ea53cbe33c98f 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_conflicts.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_conflicts.ts @@ -13,6 +13,14 @@ import { ESTestIndexTool } from '@kbn/alerting-api-integration-helpers'; import { basename } from 'node:path'; import { v4 as uuidv4 } from 'uuid'; import { get, omit } from 'lodash'; +import { + ALERT_ACTION_GROUP, + ALERT_CASE_IDS, + ALERT_INSTANCE_ID, + ALERT_STATUS, + ALERT_WORKFLOW_STATUS, + ALERT_WORKFLOW_TAGS, +} from '@kbn/rule-data-utils'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { Spaces } from '../../../../scenarios'; import { getTestRuleData, getUrlPrefix, ObjectRemover } from '../../../../../common/lib'; @@ -21,7 +29,7 @@ type AlertDoc = Alert & { runCount: number }; // sort results of a search of alert docs by alert instance id function sortAlertDocsByInstanceId(a: SearchHit, b: SearchHit) { - return a._source!.kibana.alert.instance.id.localeCompare(b._source!.kibana.alert.instance.id); + return a._source![ALERT_INSTANCE_ID].localeCompare(b._source![ALERT_INSTANCE_ID]); } // eslint-disable-next-line import/no-default-export @@ -250,16 +258,12 @@ async function adHocUpdate(es: Client, index: string, id: string) { // we'll do the adhoc updates with this data const DocUpdate = { runCount: -1, // rule-specific field, will be overwritten by rule execution - kibana: { - alert: { - action_group: 'not-the-default', // will be overwritten by rule execution - // below are all fields that will NOT be overwritten by rule execution - workflow_status: 'a-ok!', - workflow_tags: ['fee', 'fi', 'fo', 'fum'], - case_ids: ['123', '456', '789'], - status: 'untracked', - }, - }, + [ALERT_ACTION_GROUP]: 'not-the-default', // will be overwritten by rule execution + // below are all fields that will NOT be overwritten by rule execution + [ALERT_WORKFLOW_STATUS]: 'a-ok!', + [ALERT_WORKFLOW_TAGS]: ['fee', 'fi', 'fo', 'fum'], + [ALERT_CASE_IDS]: ['123', '456', '789'], + [ALERT_STATUS]: 'untracked', }; const SkipFields = [ diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts index 3bff92d2470c9..f10047e8a25b2 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts @@ -9,6 +9,7 @@ import expect from '@kbn/expect'; import { SearchHit } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { Alert } from '@kbn/alerts-as-data-utils'; import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; +import { ALERT_FLAPPING, ALERT_FLAPPING_HISTORY } from '@kbn/rule-data-utils'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { Spaces } from '../../../../scenarios'; import { @@ -102,14 +103,14 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // Newest alert doc is first // Flapping history for newest alert doc should match flapping history in state - expect(alertDocs[0]._source!.kibana.alert.flapping_history).to.eql( + expect(alertDocs[0]._source![ALERT_FLAPPING_HISTORY]).to.eql( state.alertRecoveredInstances.alertA.meta.flappingHistory ); // Flapping value for alert doc should be false while flapping value for state should be true // This is because we write out the alert doc BEFORE calculating the latest flapping state and // persisting into task state - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(false); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(false); expect(state.alertRecoveredInstances.alertA.meta.flapping).to.equal(true); // Run the rule 6 more times @@ -132,12 +133,12 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // Newest alert doc is first // Flapping history for newest alert doc should match flapping history in state - expect(alertDocs[0]._source!.kibana.alert.flapping_history).to.eql( + expect(alertDocs[0]._source![ALERT_FLAPPING_HISTORY]).to.eql( state.alertInstances.alertA.meta.flappingHistory ); // Flapping value for alert doc and task state should be true because alert is flapping - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(true); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(true); expect(state.alertInstances.alertA.meta.flapping).to.equal(true); // Run the rule 7 more times @@ -160,13 +161,13 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // Newest alert doc is first // Flapping history for newest alert doc should match flapping history in state - expect(alertDocs[0]._source!.kibana.alert.flapping_history).to.eql( + expect(alertDocs[0]._source![ALERT_FLAPPING_HISTORY]).to.eql( state.alertRecoveredInstances.alertA.meta.flappingHistory ); // Flapping value for alert doc and task state should be false because alert was active for long // enough to reset the flapping state - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(false); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(false); expect(state.alertRecoveredInstances.alertA.meta.flapping).to.equal(false); }); @@ -231,14 +232,14 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // Newest alert doc is first // Flapping history for newest alert doc should match flapping history in state - expect(alertDocs[0]._source!.kibana.alert.flapping_history).to.eql( + expect(alertDocs[0]._source![ALERT_FLAPPING_HISTORY]).to.eql( state.alertRecoveredInstances.alertA.meta.flappingHistory ); // Flapping value for alert doc should be false while flapping value for state should be true // This is because we write out the alert doc BEFORE calculating the latest flapping state and // persisting into task state - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(false); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(false); expect(state.alertRecoveredInstances.alertA.meta.flapping).to.equal(true); // Run the rule 6 more times @@ -261,12 +262,12 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // Newest alert doc is first // Flapping history for newest alert doc should match flapping history in state - expect(alertDocs[0]._source!.kibana.alert.flapping_history).to.eql( + expect(alertDocs[0]._source![ALERT_FLAPPING_HISTORY]).to.eql( state.alertInstances.alertA.meta.flappingHistory ); // Flapping value for alert doc and task state should be true because alert is flapping - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(true); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(true); expect(state.alertInstances.alertA.meta.flapping).to.equal(true); // Run the rule 3 more times @@ -289,12 +290,12 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // Newest alert doc is first // Flapping history for newest alert doc should match flapping history in state - expect(alertDocs[0]._source!.kibana.alert.flapping_history).to.eql( + expect(alertDocs[0]._source![ALERT_FLAPPING_HISTORY]).to.eql( state.alertRecoveredInstances.alertA.meta.flappingHistory ); // Flapping value for alert doc and task state should be true because alert recovered while flapping - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(true); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(true); expect(state.alertRecoveredInstances.alertA.meta.flapping).to.equal(true); }); @@ -351,7 +352,7 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F expect(alertDocs.length).to.equal(2); // Alert is recovered and flapping - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(true); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(true); expect(state.alertRecoveredInstances.alertA.meta.flapping).to.equal(true); }); @@ -417,12 +418,12 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // Newest alert doc is first // Flapping history for newest alert doc should match flapping history in state - expect(alertDocs[0]._source!.kibana.alert.flapping_history).to.eql( + expect(alertDocs[0]._source![ALERT_FLAPPING_HISTORY]).to.eql( state.alertRecoveredInstances.alertA.meta.flappingHistory ); // Alert shouldn't be flapping because the status change threshold hasn't been exceeded - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(false); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(false); expect(state.alertRecoveredInstances.alertA.meta.flapping).to.equal(false); // Run the rule 1 more time @@ -445,14 +446,14 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // Newest alert doc is first // Flapping history for newest alert doc should match flapping history in state - expect(alertDocs[0]._source!.kibana.alert.flapping_history).to.eql( + expect(alertDocs[0]._source![ALERT_FLAPPING_HISTORY]).to.eql( state.alertInstances.alertA.meta.flappingHistory ); // Flapping value for alert doc should be false while flapping value for state should be true // This is because we write out the alert doc BEFORE calculating the latest flapping state and // persisting into task state - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(false); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(false); expect(state.alertInstances.alertA.meta.flapping).to.equal(true); // Run the rule 6 more times @@ -475,14 +476,14 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // Newest alert doc is first // Flapping history for newest alert doc should match flapping history in state - expect(alertDocs[0]._source!.kibana.alert.flapping_history).to.eql( + expect(alertDocs[0]._source![ALERT_FLAPPING_HISTORY]).to.eql( state.alertInstances.alertA.meta.flappingHistory ); // Flapping value for alert doc should be true while flapping value for state should be false // This is because we write out the alert doc BEFORE calculating the latest flapping state and // persisting into task state - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(true); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(true); expect(state.alertInstances.alertA.meta.flapping).to.equal(false); // Run the rule 3 more times @@ -505,12 +506,12 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F // Newest alert doc is first // Flapping history for newest alert doc should match flapping history in state - expect(alertDocs[0]._source!.kibana.alert.flapping_history).to.eql( + expect(alertDocs[0]._source![ALERT_FLAPPING_HISTORY]).to.eql( state.alertInstances.alertA.meta.flappingHistory ); // Flapping value for alert doc and task state should be true because lookback threshold exceeded - expect(alertDocs[0]._source!.kibana.alert.flapping).to.equal(false); + expect(alertDocs[0]._source![ALERT_FLAPPING]).to.equal(false); expect(state.alertInstances.alertA.meta.flapping).to.equal(false); }); }); diff --git a/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts b/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts index 799d87f65e10f..10e5e4d0c88e1 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts @@ -7,6 +7,36 @@ import expect from '@kbn/expect'; import { unset } from 'lodash'; +import { + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_FLAPPING, + ALERT_FLAPPING_HISTORY, + ALERT_INSTANCE_ID, + ALERT_MAINTENANCE_WINDOW_IDS, + ALERT_REASON, + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + ALERT_START, + ALERT_STATUS, + ALERT_TIME_RANGE, + ALERT_URL, + ALERT_UUID, + ALERT_WORKFLOW_STATUS, + EVENT_ACTION, + EVENT_KIND, + SPACE_IDS, + TAGS, + VERSION, +} from '@kbn/rule-data-utils'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { createEsQueryRule } from './helpers/alerting_api_helper'; import { waitForAlertInIndex, waitForNumRuleRuns } from './helpers/alerting_wait_for_helpers'; @@ -70,18 +100,17 @@ export default function ({ getService }: FtrProviderContext) { expect(new Date(hits1['@timestamp'])).to.be.a(Date); // should be open, first time, but also seen sometimes active; timing? - expect(OPEN_OR_ACTIVE.has(hits1.event.action)).to.be(true); - expect(hits1.kibana.alert.flapping_history).to.be.an(Array); - expect(hits1.kibana.alert.maintenance_window_ids).to.be.an(Array); - expect(typeof hits1.kibana.alert.reason).to.be('string'); - expect(typeof hits1.kibana.alert.rule.execution.uuid).to.be('string'); - expect(typeof hits1.kibana.alert.duration).to.be('object'); - expect(new Date(hits1.kibana.alert.start)).to.be.a(Date); - expect(typeof hits1.kibana.alert.time_range).to.be('object'); - expect(typeof hits1.kibana.alert.uuid).to.be('string'); - expect(typeof hits1.kibana.alert.url).to.be('string'); - expect(typeof hits1.kibana.alert.duration.us).to.be('string'); - expect(typeof hits1.kibana.version).to.be('string'); + expect(OPEN_OR_ACTIVE.has(hits1[EVENT_ACTION])).to.be(true); + expect(hits1[ALERT_FLAPPING_HISTORY]).to.be.an(Array); + expect(hits1[ALERT_MAINTENANCE_WINDOW_IDS]).to.be.an(Array); + expect(typeof hits1[ALERT_REASON]).to.be('string'); + expect(typeof hits1[ALERT_RULE_EXECUTION_UUID]).to.be('string'); + expect(typeof hits1[ALERT_DURATION]).to.be('string'); + expect(new Date(hits1[ALERT_START])).to.be.a(Date); + expect(typeof hits1[ALERT_TIME_RANGE]).to.be('object'); + expect(typeof hits1[ALERT_UUID]).to.be('string'); + expect(typeof hits1[ALERT_URL]).to.be('string'); + expect(typeof hits1[VERSION]).to.be('string'); // remove fields we aren't going to compare directly const fields = [ @@ -105,51 +134,39 @@ export default function ({ getService }: FtrProviderContext) { } const expected = { - event: { - kind: 'signal', - }, - tags: [], - kibana: { - space_ids: ['default'], - alert: { - title: "rule 'always fire' matched query", - evaluation: { - conditions: 'Number of matching documents is greater than -1', - value: 0, - }, - action_group: 'query matched', - flapping: false, - duration: {}, - instance: { id: 'query matched' }, - status: 'active', - workflow_status: 'open', - rule: { - category: 'Elasticsearch query', - consumer: 'alerts', - name: 'always fire', - execution: {}, - parameters: { - size: 100, - thresholdComparator: '>', - threshold: [-1], - index: ['alert-test-data'], - timeField: 'date', - esQuery: '{"query":{"match_all":{}}}', - timeWindowSize: 20, - timeWindowUnit: 's', - excludeHitsFromPreviousRun: true, - aggType: 'count', - groupBy: 'all', - searchType: 'esQuery', - }, - producer: 'stackAlerts', - revision: 0, - rule_type_id: '.es-query', - tags: [], - uuid: ruleId, - }, - }, + [EVENT_KIND]: 'signal', + [TAGS]: [], + [SPACE_IDS]: ['default'], + ['kibana.alert.title']: "rule 'always fire' matched query", + ['kibana.alert.evaluation.conditions']: 'Number of matching documents is greater than -1', + ['kibana.alert.evaluation.value']: '0', + [ALERT_ACTION_GROUP]: 'query matched', + [ALERT_FLAPPING]: false, + [ALERT_INSTANCE_ID]: 'query matched', + [ALERT_STATUS]: 'active', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_RULE_CATEGORY]: 'Elasticsearch query', + [ALERT_RULE_CONSUMER]: 'alerts', + [ALERT_RULE_NAME]: 'always fire', + [ALERT_RULE_PARAMETERS]: { + size: 100, + thresholdComparator: '>', + threshold: [-1], + index: ['alert-test-data'], + timeField: 'date', + esQuery: '{"query":{"match_all":{}}}', + timeWindowSize: 20, + timeWindowUnit: 's', + excludeHitsFromPreviousRun: true, + aggType: 'count', + groupBy: 'all', + searchType: 'esQuery', }, + [ALERT_RULE_PRODUCER]: 'stackAlerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: '.es-query', + [ALERT_RULE_TAGS]: [], + [ALERT_RULE_UUID]: ruleId, }; expect(hits1).to.eql(expected); @@ -216,10 +233,10 @@ export default function ({ getService }: FtrProviderContext) { const hits2 = alResp2.hits.hits[0]._source as Record; expect(hits2['@timestamp']).to.be.greaterThan(hits1['@timestamp']); - expect(OPEN_OR_ACTIVE.has(hits1?.event?.action)).to.be(true); - expect(hits2?.event?.action).to.be('active'); - expect(parseInt(hits1?.kibana?.alert?.duration?.us, 10)).to.not.be.lessThan(0); - expect(hits2?.kibana?.alert?.duration?.us).not.to.be('0'); + expect(OPEN_OR_ACTIVE.has(hits1[EVENT_ACTION])).to.be(true); + expect(hits2[EVENT_ACTION]).to.be('active'); + expect(parseInt(hits1[ALERT_DURATION], 10)).to.not.be.lessThan(0); + expect(hits2[ALERT_DURATION]).not.to.be('0'); // remove fields we know will be different const fields = [ diff --git a/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts b/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts index 63e34eefae79d..7daddff58ce76 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts @@ -6,6 +6,25 @@ */ import expect from '@kbn/expect'; +import { + EVENT_KIND, + ALERT_ACTION_GROUP, + ALERT_FLAPPING, + ALERT_INSTANCE_ID, + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_REVISION, + ALERT_RULE_TYPE_ID, + ALERT_RULE_TAGS, + ALERT_RULE_UUID, + ALERT_STATUS, + ALERT_WORKFLOW_STATUS, + SPACE_IDS, + TAGS, +} from '@kbn/rule-data-utils'; import { omit, padStart } from 'lodash'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { createIndexConnector, createEsQueryRule } from './helpers/alerting_api_helper'; @@ -141,51 +160,39 @@ export default function ({ getService }: FtrProviderContext) { const alertDocument = resp2.hits.hits[0]._source as Record; expect(omit(alertDocument, fields)).to.eql({ - event: { - kind: 'signal', - }, - tags: [], - kibana: { - space_ids: ['default'], - alert: { - title: "rule 'always fire' matched query", - evaluation: { - conditions: 'Number of matching documents is greater than -1', - value: 0, - }, - action_group: 'query matched', - flapping: false, - duration: {}, - instance: { id: 'query matched' }, - status: 'active', - workflow_status: 'open', - rule: { - category: 'Elasticsearch query', - consumer: 'alerts', - name: 'always fire', - execution: {}, - parameters: { - size: 100, - thresholdComparator: '>', - threshold: [-1], - index: ['alert-test-data'], - timeField: 'date', - esQuery: '{\n "query":{\n "match_all" : {}\n }\n}', - timeWindowSize: 20, - timeWindowUnit: 's', - excludeHitsFromPreviousRun: true, - aggType: 'count', - groupBy: 'all', - searchType: 'esQuery', - }, - producer: 'stackAlerts', - revision: 0, - rule_type_id: '.es-query', - tags: [], - uuid: ruleId, - }, - }, + [EVENT_KIND]: 'signal', + ['kibana.alert.title']: "rule 'always fire' matched query", + ['kibana.alert.evaluation.conditions']: 'Number of matching documents is greater than -1', + ['kibana.alert.evaluation.value']: '0', + [ALERT_ACTION_GROUP]: 'query matched', + [ALERT_FLAPPING]: false, + [ALERT_INSTANCE_ID]: 'query matched', + [ALERT_STATUS]: 'active', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_RULE_CATEGORY]: 'Elasticsearch query', + [ALERT_RULE_CONSUMER]: 'alerts', + [ALERT_RULE_NAME]: 'always fire', + [ALERT_RULE_PARAMETERS]: { + size: 100, + thresholdComparator: '>', + threshold: [-1], + index: ['alert-test-data'], + timeField: 'date', + esQuery: '{\n "query":{\n "match_all" : {}\n }\n}', + timeWindowSize: 20, + timeWindowUnit: 's', + excludeHitsFromPreviousRun: true, + aggType: 'count', + groupBy: 'all', + searchType: 'esQuery', }, + [ALERT_RULE_PRODUCER]: 'stackAlerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: '.es-query', + [ALERT_RULE_TAGS]: [], + [ALERT_RULE_UUID]: ruleId, + [SPACE_IDS]: ['default'], + [TAGS]: [], }); }); @@ -273,51 +280,39 @@ export default function ({ getService }: FtrProviderContext) { const alertDocument = resp2.hits.hits[0]._source as Record; expect(omit(alertDocument, fields)).to.eql({ - event: { - kind: 'signal', - }, - tags: [], - kibana: { - space_ids: ['default'], - alert: { - title: "rule 'always fire' matched query", - evaluation: { - conditions: 'Number of matching documents is greater than -1', - value: 0, - }, - action_group: 'query matched', - flapping: false, - duration: {}, - instance: { id: 'query matched' }, - status: 'active', - workflow_status: 'open', - rule: { - category: 'Elasticsearch query', - consumer: 'alerts', - name: 'always fire', - execution: {}, - parameters: { - size: 100, - thresholdComparator: '>', - threshold: [-1], - index: ['alert-test-data'], - timeField: 'date', - esQuery: '{\n "query":{\n "match_all" : {}\n }\n}', - timeWindowSize: 20, - timeWindowUnit: 's', - excludeHitsFromPreviousRun: true, - aggType: 'count', - groupBy: 'all', - searchType: 'esQuery', - }, - producer: 'stackAlerts', - revision: 0, - rule_type_id: '.es-query', - tags: [], - uuid: ruleId, - }, - }, + [EVENT_KIND]: 'signal', + ['kibana.alert.title']: "rule 'always fire' matched query", + ['kibana.alert.evaluation.conditions']: 'Number of matching documents is greater than -1', + ['kibana.alert.evaluation.value']: '0', + [ALERT_ACTION_GROUP]: 'query matched', + [ALERT_FLAPPING]: false, + [ALERT_INSTANCE_ID]: 'query matched', + [ALERT_STATUS]: 'active', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_RULE_CATEGORY]: 'Elasticsearch query', + [ALERT_RULE_CONSUMER]: 'alerts', + [ALERT_RULE_NAME]: 'always fire', + [ALERT_RULE_PARAMETERS]: { + size: 100, + thresholdComparator: '>', + threshold: [-1], + index: ['alert-test-data'], + timeField: 'date', + esQuery: '{\n "query":{\n "match_all" : {}\n }\n}', + timeWindowSize: 20, + timeWindowUnit: 's', + excludeHitsFromPreviousRun: true, + aggType: 'count', + groupBy: 'all', + searchType: 'esQuery', }, + [ALERT_RULE_PRODUCER]: 'stackAlerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: '.es-query', + [ALERT_RULE_TAGS]: [], + [ALERT_RULE_UUID]: ruleId, + [SPACE_IDS]: ['default'], + [TAGS]: [], }); }); @@ -492,51 +487,39 @@ export default function ({ getService }: FtrProviderContext) { const alertDocument = resp2.hits.hits[0]._source as Record; expect(omit(alertDocument, fields)).to.eql({ - event: { - kind: 'signal', - }, - tags: [], - kibana: { - space_ids: ['default'], - alert: { - title: "rule 'always fire' matched query", - evaluation: { - conditions: 'Number of matching documents is greater than -1', - value: 0, - }, - action_group: 'query matched', - flapping: false, - duration: {}, - instance: { id: 'query matched' }, - status: 'active', - workflow_status: 'open', - rule: { - category: 'Elasticsearch query', - consumer: 'alerts', - name: 'always fire', - execution: {}, - parameters: { - size: 100, - thresholdComparator: '>', - threshold: [-1], - index: ['alert-test-data'], - timeField: 'date', - esQuery: '{\n "query":{\n "match_all" : {}\n }\n}', - timeWindowSize: 20, - timeWindowUnit: 's', - excludeHitsFromPreviousRun: true, - aggType: 'count', - groupBy: 'all', - searchType: 'esQuery', - }, - producer: 'stackAlerts', - revision: 0, - rule_type_id: '.es-query', - tags: [], - uuid: ruleId, - }, - }, + [EVENT_KIND]: 'signal', + ['kibana.alert.title']: "rule 'always fire' matched query", + ['kibana.alert.evaluation.conditions']: 'Number of matching documents is greater than -1', + ['kibana.alert.evaluation.value']: '0', + [ALERT_ACTION_GROUP]: 'query matched', + [ALERT_FLAPPING]: false, + [ALERT_INSTANCE_ID]: 'query matched', + [ALERT_STATUS]: 'active', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_RULE_CATEGORY]: 'Elasticsearch query', + [ALERT_RULE_CONSUMER]: 'alerts', + [ALERT_RULE_NAME]: 'always fire', + [ALERT_RULE_PARAMETERS]: { + size: 100, + thresholdComparator: '>', + threshold: [-1], + index: ['alert-test-data'], + timeField: 'date', + esQuery: '{\n "query":{\n "match_all" : {}\n }\n}', + timeWindowSize: 20, + timeWindowUnit: 's', + excludeHitsFromPreviousRun: true, + aggType: 'count', + groupBy: 'all', + searchType: 'esQuery', }, + [ALERT_RULE_PRODUCER]: 'stackAlerts', + [ALERT_RULE_REVISION]: 0, + [ALERT_RULE_TYPE_ID]: '.es-query', + [ALERT_RULE_TAGS]: [], + [ALERT_RULE_UUID]: ruleId, + [SPACE_IDS]: ['default'], + [TAGS]: [], }); }); });