mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 11:05:39 -04:00
[Security Solution][Endpoint] script to load data into an environment for testing or development (#175132)
## Summary - New script to load data to an environment for testing - currently supports loading Endpoint policies and endpoint artifacts (Trusted Apps, Blocklists, Event filters, Host Isolation Exceptions and Endpoint Exceptions
This commit is contained in:
parent
851df6906b
commit
9666b19644
20 changed files with 2387 additions and 23 deletions
|
@ -15,6 +15,15 @@ export enum ListOperatorEnum {
|
||||||
EXCLUDED = 'excluded',
|
EXCLUDED = 'excluded',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const listOperatorType = t.keyof({
|
||||||
|
nested: null,
|
||||||
|
match: null,
|
||||||
|
match_any: null,
|
||||||
|
wildcard: null,
|
||||||
|
exists: null,
|
||||||
|
list: null,
|
||||||
|
});
|
||||||
|
export type ListOperatorType = t.TypeOf<typeof listOperatorType>;
|
||||||
export enum ListOperatorTypeEnum {
|
export enum ListOperatorTypeEnum {
|
||||||
NESTED = 'nested',
|
NESTED = 'nested',
|
||||||
MATCH = 'match',
|
MATCH = 'match',
|
||||||
|
|
|
@ -0,0 +1,926 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of ECS fields that can appear on the `logs-endpoint.events.*` index.
|
||||||
|
* Used to defined Event Filters and Endpoint Exceptions
|
||||||
|
*/
|
||||||
|
export const ENDPOINT_EVENTS_LOG_INDEX_FIELDS: readonly string[] = [
|
||||||
|
'@timestamp',
|
||||||
|
'Effective_process.entity_id',
|
||||||
|
'Effective_process.executable',
|
||||||
|
'Effective_process.name',
|
||||||
|
'Effective_process.pid',
|
||||||
|
'Persistence.args',
|
||||||
|
'Persistence.executable',
|
||||||
|
'Persistence.keepalive',
|
||||||
|
'Persistence.name',
|
||||||
|
'Persistence.path',
|
||||||
|
'Persistence.runatload',
|
||||||
|
'Target.process.Ext.memory_region.allocation_base',
|
||||||
|
'Target.process.Ext.memory_region.allocation_protection',
|
||||||
|
'Target.process.Ext.memory_region.allocation_size',
|
||||||
|
'Target.process.Ext.memory_region.allocation_type',
|
||||||
|
'Target.process.Ext.memory_region.bytes_address',
|
||||||
|
'Target.process.Ext.memory_region.bytes_allocation_offset',
|
||||||
|
'Target.process.Ext.memory_region.bytes_compressed',
|
||||||
|
'Target.process.Ext.memory_region.bytes_compressed_present',
|
||||||
|
'Target.process.Ext.memory_region.hash.sha256',
|
||||||
|
'Target.process.Ext.memory_region.malware_signature.all_names',
|
||||||
|
'Target.process.Ext.memory_region.malware_signature.identifier',
|
||||||
|
'Target.process.Ext.memory_region.malware_signature.primary.matches',
|
||||||
|
'Target.process.Ext.memory_region.malware_signature.primary.signature.hash.sha256',
|
||||||
|
'Target.process.Ext.memory_region.malware_signature.primary.signature.id',
|
||||||
|
'Target.process.Ext.memory_region.malware_signature.primary.signature.name',
|
||||||
|
'Target.process.Ext.memory_region.malware_signature.version',
|
||||||
|
'Target.process.Ext.memory_region.mapped_path',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.dotnet',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.sections.hash.md5',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.sections.hash.sha1',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.sections.hash.sha256',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.sections.hash.sha384',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.sections.hash.sha512',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.sections.hash.ssdeep',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.sections.hash.tlsh',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.sections.name',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.streams.hash.md5',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.streams.hash.sha1',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.streams.hash.sha256',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.streams.hash.sha384',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.streams.hash.sha512',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.streams.hash.ssdeep',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.streams.hash.tlsh',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.Ext.streams.name',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.architecture',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.company',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.description',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.file_version',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.go_import_hash',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.go_imports',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.go_imports_names_entropy',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.go_imports_names_var_entropy',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.go_stripped',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.imphash',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.import_hash',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.imports',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.imports_names_entropy',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.imports_names_var_entropy',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.original_file_name',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.pehash',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.product',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.sections.entropy',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.sections.name',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.sections.physical_size',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.sections.var_entropy',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe.sections.virtual_size',
|
||||||
|
'Target.process.Ext.memory_region.mapped_pe_detected',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.dotnet',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.sections.hash.md5',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.sections.hash.sha1',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.sections.hash.sha256',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.sections.hash.sha384',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.sections.hash.sha512',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.sections.hash.ssdeep',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.sections.hash.tlsh',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.sections.name',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.streams.hash.md5',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.streams.hash.sha1',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.streams.hash.sha256',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.streams.hash.sha384',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.streams.hash.sha512',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.streams.hash.ssdeep',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.streams.hash.tlsh',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.Ext.streams.name',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.architecture',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.company',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.description',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.file_version',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.go_import_hash',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.go_imports',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.go_imports_names_entropy',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.go_imports_names_var_entropy',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.go_stripped',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.imphash',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.import_hash',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.imports',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.imports_names_entropy',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.imports_names_var_entropy',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.original_file_name',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.pehash',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.product',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.sections.entropy',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.sections.name',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.sections.physical_size',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.sections.var_entropy',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe.sections.virtual_size',
|
||||||
|
'Target.process.Ext.memory_region.memory_pe_detected',
|
||||||
|
'Target.process.Ext.memory_region.region_base',
|
||||||
|
'Target.process.Ext.memory_region.region_protection',
|
||||||
|
'Target.process.Ext.memory_region.region_size',
|
||||||
|
'Target.process.Ext.memory_region.region_state',
|
||||||
|
'Target.process.Ext.memory_region.strings',
|
||||||
|
'Target.process.Ext.token.integrity_level_name',
|
||||||
|
'Target.process.entity_id',
|
||||||
|
'Target.process.executable',
|
||||||
|
'Target.process.executable.caseless',
|
||||||
|
'Target.process.executable.text',
|
||||||
|
'Target.process.name',
|
||||||
|
'Target.process.name.caseless',
|
||||||
|
'Target.process.name.text',
|
||||||
|
'Target.process.pid',
|
||||||
|
'_id',
|
||||||
|
'_index',
|
||||||
|
'_score',
|
||||||
|
'_source',
|
||||||
|
'agent.ephemeral_id',
|
||||||
|
'agent.id',
|
||||||
|
'agent.name',
|
||||||
|
'agent.type',
|
||||||
|
'agent.version',
|
||||||
|
'cloud.account.id',
|
||||||
|
'cloud.instance.name',
|
||||||
|
'cloud.project.id',
|
||||||
|
'cloud.provider',
|
||||||
|
'cloud.region',
|
||||||
|
'container.id',
|
||||||
|
'container.image.hash.all',
|
||||||
|
'container.image.name',
|
||||||
|
'container.image.tag',
|
||||||
|
'container.name',
|
||||||
|
'data_stream.dataset',
|
||||||
|
'data_stream.namespace',
|
||||||
|
'data_stream.type',
|
||||||
|
'destination.address',
|
||||||
|
'destination.as.number',
|
||||||
|
'destination.as.organization.name',
|
||||||
|
'destination.as.organization.name.text',
|
||||||
|
'destination.bytes',
|
||||||
|
'destination.domain',
|
||||||
|
'destination.geo.city_name',
|
||||||
|
'destination.geo.continent_code',
|
||||||
|
'destination.geo.continent_name',
|
||||||
|
'destination.geo.country_iso_code',
|
||||||
|
'destination.geo.country_name',
|
||||||
|
'destination.geo.location',
|
||||||
|
'destination.geo.name',
|
||||||
|
'destination.geo.postal_code',
|
||||||
|
'destination.geo.region_iso_code',
|
||||||
|
'destination.geo.region_name',
|
||||||
|
'destination.geo.timezone',
|
||||||
|
'destination.ip',
|
||||||
|
'destination.packets',
|
||||||
|
'destination.port',
|
||||||
|
'destination.registered_domain',
|
||||||
|
'destination.top_level_domain',
|
||||||
|
'dll.Ext.code_signature.exists',
|
||||||
|
'dll.Ext.code_signature.status',
|
||||||
|
'dll.Ext.code_signature.subject_name',
|
||||||
|
'dll.Ext.code_signature.trusted',
|
||||||
|
'dll.Ext.code_signature.valid',
|
||||||
|
'dll.Ext.defense_evasions',
|
||||||
|
'dll.Ext.device.bus_type',
|
||||||
|
'dll.Ext.device.dos_name',
|
||||||
|
'dll.Ext.device.file_system_type',
|
||||||
|
'dll.Ext.device.nt_name',
|
||||||
|
'dll.Ext.device.product_id',
|
||||||
|
'dll.Ext.device.serial_number',
|
||||||
|
'dll.Ext.device.vendor_id',
|
||||||
|
'dll.Ext.device.volume_device_type',
|
||||||
|
'dll.Ext.load_index',
|
||||||
|
'dll.Ext.relative_file_creation_time',
|
||||||
|
'dll.Ext.relative_file_name_modify_time',
|
||||||
|
'dll.Ext.size',
|
||||||
|
'dll.code_signature.exists',
|
||||||
|
'dll.code_signature.signing_id',
|
||||||
|
'dll.code_signature.status',
|
||||||
|
'dll.code_signature.subject_name',
|
||||||
|
'dll.code_signature.team_id',
|
||||||
|
'dll.code_signature.trusted',
|
||||||
|
'dll.code_signature.valid',
|
||||||
|
'dll.hash.md5',
|
||||||
|
'dll.hash.sha1',
|
||||||
|
'dll.hash.sha256',
|
||||||
|
'dll.hash.sha512',
|
||||||
|
'dll.name',
|
||||||
|
'dll.path',
|
||||||
|
'dll.pe.company',
|
||||||
|
'dll.pe.description',
|
||||||
|
'dll.pe.file_version',
|
||||||
|
'dll.pe.imphash',
|
||||||
|
'dll.pe.original_file_name',
|
||||||
|
'dll.pe.product',
|
||||||
|
'dns.Ext.options',
|
||||||
|
'dns.Ext.status',
|
||||||
|
'dns.question.name',
|
||||||
|
'dns.question.registered_domain',
|
||||||
|
'dns.question.subdomain',
|
||||||
|
'dns.question.top_level_domain',
|
||||||
|
'dns.question.type',
|
||||||
|
'dns.resolved_ip',
|
||||||
|
'ecs.version',
|
||||||
|
'event.Ext.correlation.id',
|
||||||
|
'event.action',
|
||||||
|
'event.agent_id_status',
|
||||||
|
'event.category',
|
||||||
|
'event.code',
|
||||||
|
'event.created',
|
||||||
|
'event.dataset',
|
||||||
|
'event.end',
|
||||||
|
'event.hash',
|
||||||
|
'event.id',
|
||||||
|
'event.ingested',
|
||||||
|
'event.kind',
|
||||||
|
'event.module',
|
||||||
|
'event.outcome',
|
||||||
|
'event.provider',
|
||||||
|
'event.sequence',
|
||||||
|
'event.severity',
|
||||||
|
'event.start',
|
||||||
|
'event.type',
|
||||||
|
'file.Ext.code_signature.exists',
|
||||||
|
'file.Ext.code_signature.status',
|
||||||
|
'file.Ext.code_signature.subject_name',
|
||||||
|
'file.Ext.code_signature.trusted',
|
||||||
|
'file.Ext.code_signature.valid',
|
||||||
|
'file.Ext.device.bus_type',
|
||||||
|
'file.Ext.device.dos_name',
|
||||||
|
'file.Ext.device.file_system_type',
|
||||||
|
'file.Ext.device.nt_name',
|
||||||
|
'file.Ext.device.product_id',
|
||||||
|
'file.Ext.device.serial_number',
|
||||||
|
'file.Ext.device.vendor_id',
|
||||||
|
'file.Ext.device.volume_device_type',
|
||||||
|
'file.Ext.entropy',
|
||||||
|
'file.Ext.header_bytes',
|
||||||
|
'file.Ext.header_data',
|
||||||
|
'file.Ext.malware_signature.all_names',
|
||||||
|
'file.Ext.malware_signature.identifier',
|
||||||
|
'file.Ext.malware_signature.primary.signature.hash.sha256',
|
||||||
|
'file.Ext.malware_signature.primary.signature.id',
|
||||||
|
'file.Ext.malware_signature.primary.signature.name',
|
||||||
|
'file.Ext.malware_signature.version',
|
||||||
|
'file.Ext.monotonic_id',
|
||||||
|
'file.Ext.original.extension',
|
||||||
|
'file.Ext.original.gid',
|
||||||
|
'file.Ext.original.group',
|
||||||
|
'file.Ext.original.mode',
|
||||||
|
'file.Ext.original.name',
|
||||||
|
'file.Ext.original.owner',
|
||||||
|
'file.Ext.original.path',
|
||||||
|
'file.Ext.original.uid',
|
||||||
|
'file.Ext.windows.zone_identifier',
|
||||||
|
'file.accessed',
|
||||||
|
'file.attributes',
|
||||||
|
'file.code_signature.exists',
|
||||||
|
'file.code_signature.signing_id',
|
||||||
|
'file.code_signature.status',
|
||||||
|
'file.code_signature.subject_name',
|
||||||
|
'file.code_signature.team_id',
|
||||||
|
'file.code_signature.trusted',
|
||||||
|
'file.code_signature.valid',
|
||||||
|
'file.created',
|
||||||
|
'file.ctime',
|
||||||
|
'file.device',
|
||||||
|
'file.directory',
|
||||||
|
'file.drive_letter',
|
||||||
|
'file.extension',
|
||||||
|
'file.gid',
|
||||||
|
'file.group',
|
||||||
|
'file.hash.md5',
|
||||||
|
'file.hash.sha1',
|
||||||
|
'file.hash.sha256',
|
||||||
|
'file.hash.sha512',
|
||||||
|
'file.inode',
|
||||||
|
'file.mime_type',
|
||||||
|
'file.mode',
|
||||||
|
'file.mtime',
|
||||||
|
'file.name',
|
||||||
|
'file.owner',
|
||||||
|
'file.path',
|
||||||
|
'file.path.caseless',
|
||||||
|
'file.path.text',
|
||||||
|
'file.pe.company',
|
||||||
|
'file.pe.description',
|
||||||
|
'file.pe.file_version',
|
||||||
|
'file.pe.imphash',
|
||||||
|
'file.pe.original_file_name',
|
||||||
|
'file.pe.product',
|
||||||
|
'file.size',
|
||||||
|
'file.target_path',
|
||||||
|
'file.target_path.caseless',
|
||||||
|
'file.target_path.text',
|
||||||
|
'file.type',
|
||||||
|
'file.uid',
|
||||||
|
'group.Ext.real.id',
|
||||||
|
'group.Ext.real.name',
|
||||||
|
'group.domain',
|
||||||
|
'group.id',
|
||||||
|
'group.name',
|
||||||
|
'host.architecture',
|
||||||
|
'host.boot.id',
|
||||||
|
'host.domain',
|
||||||
|
'host.hostname',
|
||||||
|
'host.id',
|
||||||
|
'host.ip',
|
||||||
|
'host.mac',
|
||||||
|
'host.name',
|
||||||
|
'host.os.Ext.variant',
|
||||||
|
'host.os.family',
|
||||||
|
'host.os.full',
|
||||||
|
'host.os.full.caseless',
|
||||||
|
'host.os.full.text',
|
||||||
|
'host.os.kernel',
|
||||||
|
'host.os.name',
|
||||||
|
'host.os.name.caseless',
|
||||||
|
'host.os.name.text',
|
||||||
|
'host.os.platform',
|
||||||
|
'host.os.type',
|
||||||
|
'host.os.version',
|
||||||
|
'host.pid_ns_ino',
|
||||||
|
'host.type',
|
||||||
|
'host.uptime',
|
||||||
|
'http.request.body.bytes',
|
||||||
|
'http.request.body.content',
|
||||||
|
'http.request.body.content.text',
|
||||||
|
'http.request.bytes',
|
||||||
|
'http.response.Ext.version',
|
||||||
|
'http.response.body.bytes',
|
||||||
|
'http.response.body.content',
|
||||||
|
'http.response.body.content.text',
|
||||||
|
'http.response.bytes',
|
||||||
|
'http.response.status_code',
|
||||||
|
'message',
|
||||||
|
'network.bytes',
|
||||||
|
'network.community_id',
|
||||||
|
'network.direction',
|
||||||
|
'network.iana_number',
|
||||||
|
'network.packets',
|
||||||
|
'network.protocol',
|
||||||
|
'network.transport',
|
||||||
|
'network.type',
|
||||||
|
'orchestrator.cluster.id',
|
||||||
|
'orchestrator.cluster.name',
|
||||||
|
'orchestrator.namespace',
|
||||||
|
'orchestrator.resource.ip',
|
||||||
|
'orchestrator.resource.name',
|
||||||
|
'orchestrator.resource.parent.type',
|
||||||
|
'orchestrator.resource.type',
|
||||||
|
'package.name',
|
||||||
|
'process.Ext.ancestry',
|
||||||
|
'process.Ext.api.behaviors',
|
||||||
|
'process.Ext.api.metadata.background_callcount',
|
||||||
|
'process.Ext.api.metadata.ms_since_last_keyevent',
|
||||||
|
'process.Ext.api.metadata.procedure_symbol',
|
||||||
|
'process.Ext.api.metadata.return_value',
|
||||||
|
'process.Ext.api.metadata.start_address_allocation_protection',
|
||||||
|
'process.Ext.api.metadata.start_address_module',
|
||||||
|
'process.Ext.api.metadata.target_address_name',
|
||||||
|
'process.Ext.api.metadata.target_address_path',
|
||||||
|
'process.Ext.api.metadata.thread_info_flags',
|
||||||
|
'process.Ext.api.metadata.visible_windows_count',
|
||||||
|
'process.Ext.api.metadata.windows_count',
|
||||||
|
'process.Ext.api.name',
|
||||||
|
'process.Ext.api.parameters.address',
|
||||||
|
'process.Ext.api.parameters.allocation_type',
|
||||||
|
'process.Ext.api.parameters.argument1',
|
||||||
|
'process.Ext.api.parameters.argument2',
|
||||||
|
'process.Ext.api.parameters.argument3',
|
||||||
|
'process.Ext.api.parameters.context_flags',
|
||||||
|
'process.Ext.api.parameters.desired_access',
|
||||||
|
'process.Ext.api.parameters.desired_access_numeric',
|
||||||
|
'process.Ext.api.parameters.device',
|
||||||
|
'process.Ext.api.parameters.driver',
|
||||||
|
'process.Ext.api.parameters.eax',
|
||||||
|
'process.Ext.api.parameters.ebp',
|
||||||
|
'process.Ext.api.parameters.ebx',
|
||||||
|
'process.Ext.api.parameters.ecx',
|
||||||
|
'process.Ext.api.parameters.edi',
|
||||||
|
'process.Ext.api.parameters.edx',
|
||||||
|
'process.Ext.api.parameters.eip',
|
||||||
|
'process.Ext.api.parameters.esi',
|
||||||
|
'process.Ext.api.parameters.esp',
|
||||||
|
'process.Ext.api.parameters.flags',
|
||||||
|
'process.Ext.api.parameters.handle_type',
|
||||||
|
'process.Ext.api.parameters.hook_module',
|
||||||
|
'process.Ext.api.parameters.hook_type',
|
||||||
|
'process.Ext.api.parameters.procedure',
|
||||||
|
'process.Ext.api.parameters.protection',
|
||||||
|
'process.Ext.api.parameters.protection_old',
|
||||||
|
'process.Ext.api.parameters.r8',
|
||||||
|
'process.Ext.api.parameters.r9',
|
||||||
|
'process.Ext.api.parameters.rax',
|
||||||
|
'process.Ext.api.parameters.rbp',
|
||||||
|
'process.Ext.api.parameters.rbx',
|
||||||
|
'process.Ext.api.parameters.rcx',
|
||||||
|
'process.Ext.api.parameters.rdi',
|
||||||
|
'process.Ext.api.parameters.rdx',
|
||||||
|
'process.Ext.api.parameters.rip',
|
||||||
|
'process.Ext.api.parameters.rsi',
|
||||||
|
'process.Ext.api.parameters.rsp',
|
||||||
|
'process.Ext.api.parameters.size',
|
||||||
|
'process.Ext.api.parameters.usage',
|
||||||
|
'process.Ext.api.parameters.usage_page',
|
||||||
|
'process.Ext.api.summary',
|
||||||
|
'process.Ext.architecture',
|
||||||
|
'process.Ext.authentication_id',
|
||||||
|
'process.Ext.code_signature.exists',
|
||||||
|
'process.Ext.code_signature.status',
|
||||||
|
'process.Ext.code_signature.subject_name',
|
||||||
|
'process.Ext.code_signature.trusted',
|
||||||
|
'process.Ext.code_signature.valid',
|
||||||
|
'process.Ext.defense_evasions',
|
||||||
|
'process.Ext.device.bus_type',
|
||||||
|
'process.Ext.device.dos_name',
|
||||||
|
'process.Ext.device.file_system_type',
|
||||||
|
'process.Ext.device.nt_name',
|
||||||
|
'process.Ext.device.product_id',
|
||||||
|
'process.Ext.device.serial_number',
|
||||||
|
'process.Ext.device.vendor_id',
|
||||||
|
'process.Ext.device.volume_device_type',
|
||||||
|
'process.Ext.dll.Ext.mapped_address',
|
||||||
|
'process.Ext.dll.Ext.mapped_size',
|
||||||
|
'process.Ext.dll.name',
|
||||||
|
'process.Ext.dll.path',
|
||||||
|
'process.Ext.effective_parent.entity_id',
|
||||||
|
'process.Ext.effective_parent.executable',
|
||||||
|
'process.Ext.effective_parent.name',
|
||||||
|
'process.Ext.effective_parent.pid',
|
||||||
|
'process.Ext.memory_region.allocation_base',
|
||||||
|
'process.Ext.memory_region.allocation_protection',
|
||||||
|
'process.Ext.memory_region.allocation_size',
|
||||||
|
'process.Ext.memory_region.allocation_type',
|
||||||
|
'process.Ext.memory_region.bytes_address',
|
||||||
|
'process.Ext.memory_region.bytes_allocation_offset',
|
||||||
|
'process.Ext.memory_region.bytes_compressed',
|
||||||
|
'process.Ext.memory_region.bytes_compressed_present',
|
||||||
|
'process.Ext.memory_region.hash.sha256',
|
||||||
|
'process.Ext.memory_region.malware_signature.all_names',
|
||||||
|
'process.Ext.memory_region.malware_signature.identifier',
|
||||||
|
'process.Ext.memory_region.malware_signature.primary.matches',
|
||||||
|
'process.Ext.memory_region.malware_signature.primary.signature.hash.sha256',
|
||||||
|
'process.Ext.memory_region.malware_signature.primary.signature.id',
|
||||||
|
'process.Ext.memory_region.malware_signature.primary.signature.name',
|
||||||
|
'process.Ext.memory_region.malware_signature.version',
|
||||||
|
'process.Ext.memory_region.mapped_path',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.dotnet',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.sections.hash.md5',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.sections.hash.sha1',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.sections.hash.sha256',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.sections.hash.sha384',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.sections.hash.sha512',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.sections.hash.ssdeep',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.sections.hash.tlsh',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.sections.name',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.streams.hash.md5',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.streams.hash.sha1',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.streams.hash.sha256',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.streams.hash.sha384',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.streams.hash.sha512',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.streams.hash.ssdeep',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.streams.hash.tlsh',
|
||||||
|
'process.Ext.memory_region.mapped_pe.Ext.streams.name',
|
||||||
|
'process.Ext.memory_region.mapped_pe.architecture',
|
||||||
|
'process.Ext.memory_region.mapped_pe.company',
|
||||||
|
'process.Ext.memory_region.mapped_pe.description',
|
||||||
|
'process.Ext.memory_region.mapped_pe.file_version',
|
||||||
|
'process.Ext.memory_region.mapped_pe.go_import_hash',
|
||||||
|
'process.Ext.memory_region.mapped_pe.go_imports',
|
||||||
|
'process.Ext.memory_region.mapped_pe.go_imports_names_entropy',
|
||||||
|
'process.Ext.memory_region.mapped_pe.go_imports_names_var_entropy',
|
||||||
|
'process.Ext.memory_region.mapped_pe.go_stripped',
|
||||||
|
'process.Ext.memory_region.mapped_pe.imphash',
|
||||||
|
'process.Ext.memory_region.mapped_pe.import_hash',
|
||||||
|
'process.Ext.memory_region.mapped_pe.imports',
|
||||||
|
'process.Ext.memory_region.mapped_pe.imports_names_entropy',
|
||||||
|
'process.Ext.memory_region.mapped_pe.imports_names_var_entropy',
|
||||||
|
'process.Ext.memory_region.mapped_pe.original_file_name',
|
||||||
|
'process.Ext.memory_region.mapped_pe.pehash',
|
||||||
|
'process.Ext.memory_region.mapped_pe.product',
|
||||||
|
'process.Ext.memory_region.mapped_pe.sections.entropy',
|
||||||
|
'process.Ext.memory_region.mapped_pe.sections.name',
|
||||||
|
'process.Ext.memory_region.mapped_pe.sections.physical_size',
|
||||||
|
'process.Ext.memory_region.mapped_pe.sections.var_entropy',
|
||||||
|
'process.Ext.memory_region.mapped_pe.sections.virtual_size',
|
||||||
|
'process.Ext.memory_region.mapped_pe_detected',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.dotnet',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.sections.hash.md5',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.sections.hash.sha1',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.sections.hash.sha256',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.sections.hash.sha384',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.sections.hash.sha512',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.sections.hash.ssdeep',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.sections.hash.tlsh',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.sections.name',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.streams.hash.md5',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.streams.hash.sha1',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.streams.hash.sha256',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.streams.hash.sha384',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.streams.hash.sha512',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.streams.hash.ssdeep',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.streams.hash.tlsh',
|
||||||
|
'process.Ext.memory_region.memory_pe.Ext.streams.name',
|
||||||
|
'process.Ext.memory_region.memory_pe.architecture',
|
||||||
|
'process.Ext.memory_region.memory_pe.company',
|
||||||
|
'process.Ext.memory_region.memory_pe.description',
|
||||||
|
'process.Ext.memory_region.memory_pe.file_version',
|
||||||
|
'process.Ext.memory_region.memory_pe.go_import_hash',
|
||||||
|
'process.Ext.memory_region.memory_pe.go_imports',
|
||||||
|
'process.Ext.memory_region.memory_pe.go_imports_names_entropy',
|
||||||
|
'process.Ext.memory_region.memory_pe.go_imports_names_var_entropy',
|
||||||
|
'process.Ext.memory_region.memory_pe.go_stripped',
|
||||||
|
'process.Ext.memory_region.memory_pe.imphash',
|
||||||
|
'process.Ext.memory_region.memory_pe.import_hash',
|
||||||
|
'process.Ext.memory_region.memory_pe.imports',
|
||||||
|
'process.Ext.memory_region.memory_pe.imports_names_entropy',
|
||||||
|
'process.Ext.memory_region.memory_pe.imports_names_var_entropy',
|
||||||
|
'process.Ext.memory_region.memory_pe.original_file_name',
|
||||||
|
'process.Ext.memory_region.memory_pe.pehash',
|
||||||
|
'process.Ext.memory_region.memory_pe.product',
|
||||||
|
'process.Ext.memory_region.memory_pe.sections.entropy',
|
||||||
|
'process.Ext.memory_region.memory_pe.sections.name',
|
||||||
|
'process.Ext.memory_region.memory_pe.sections.physical_size',
|
||||||
|
'process.Ext.memory_region.memory_pe.sections.var_entropy',
|
||||||
|
'process.Ext.memory_region.memory_pe.sections.virtual_size',
|
||||||
|
'process.Ext.memory_region.memory_pe_detected',
|
||||||
|
'process.Ext.memory_region.region_base',
|
||||||
|
'process.Ext.memory_region.region_protection',
|
||||||
|
'process.Ext.memory_region.region_size',
|
||||||
|
'process.Ext.memory_region.region_state',
|
||||||
|
'process.Ext.memory_region.strings',
|
||||||
|
'process.Ext.mitigation_policies',
|
||||||
|
'process.Ext.protection',
|
||||||
|
'process.Ext.relative_file_creation_time',
|
||||||
|
'process.Ext.relative_file_name_modify_time',
|
||||||
|
'process.Ext.session',
|
||||||
|
'process.Ext.session_info.authentication_package',
|
||||||
|
'process.Ext.session_info.client_address',
|
||||||
|
'process.Ext.session_info.id',
|
||||||
|
'process.Ext.session_info.logon_type',
|
||||||
|
'process.Ext.session_info.relative_logon_time',
|
||||||
|
'process.Ext.session_info.relative_password_age',
|
||||||
|
'process.Ext.session_info.user_flags',
|
||||||
|
'process.Ext.token.elevation',
|
||||||
|
'process.Ext.token.elevation_level',
|
||||||
|
'process.Ext.token.elevation_type',
|
||||||
|
'process.Ext.token.integrity_level_name',
|
||||||
|
'process.Ext.token.security_attributes',
|
||||||
|
'process.Ext.trusted',
|
||||||
|
'process.Ext.trusted_descendant',
|
||||||
|
'process.args',
|
||||||
|
'process.args_count',
|
||||||
|
'process.code_signature.exists',
|
||||||
|
'process.code_signature.signing_id',
|
||||||
|
'process.code_signature.status',
|
||||||
|
'process.code_signature.subject_name',
|
||||||
|
'process.code_signature.team_id',
|
||||||
|
'process.code_signature.trusted',
|
||||||
|
'process.code_signature.valid',
|
||||||
|
'process.command_line',
|
||||||
|
'process.command_line.caseless',
|
||||||
|
'process.command_line.text',
|
||||||
|
'process.end',
|
||||||
|
'process.entity_id',
|
||||||
|
'process.entry_leader.args',
|
||||||
|
'process.entry_leader.args_count',
|
||||||
|
'process.entry_leader.attested_groups.name',
|
||||||
|
'process.entry_leader.attested_user.id',
|
||||||
|
'process.entry_leader.attested_user.name',
|
||||||
|
'process.entry_leader.attested_user.name.text',
|
||||||
|
'process.entry_leader.command_line',
|
||||||
|
'process.entry_leader.command_line.caseless',
|
||||||
|
'process.entry_leader.command_line.text',
|
||||||
|
'process.entry_leader.entity_id',
|
||||||
|
'process.entry_leader.entry_meta.source.ip',
|
||||||
|
'process.entry_leader.entry_meta.type',
|
||||||
|
'process.entry_leader.executable',
|
||||||
|
'process.entry_leader.executable.caseless',
|
||||||
|
'process.entry_leader.executable.text',
|
||||||
|
'process.entry_leader.group.id',
|
||||||
|
'process.entry_leader.group.name',
|
||||||
|
'process.entry_leader.interactive',
|
||||||
|
'process.entry_leader.name',
|
||||||
|
'process.entry_leader.name.caseless',
|
||||||
|
'process.entry_leader.name.text',
|
||||||
|
'process.entry_leader.parent.entity_id',
|
||||||
|
'process.entry_leader.parent.pid',
|
||||||
|
'process.entry_leader.parent.session_leader.entity_id',
|
||||||
|
'process.entry_leader.parent.session_leader.pid',
|
||||||
|
'process.entry_leader.parent.session_leader.start',
|
||||||
|
'process.entry_leader.parent.start',
|
||||||
|
'process.entry_leader.pid',
|
||||||
|
'process.entry_leader.real_group.id',
|
||||||
|
'process.entry_leader.real_group.name',
|
||||||
|
'process.entry_leader.real_user.id',
|
||||||
|
'process.entry_leader.real_user.name',
|
||||||
|
'process.entry_leader.real_user.name.text',
|
||||||
|
'process.entry_leader.same_as_process',
|
||||||
|
'process.entry_leader.saved_group.id',
|
||||||
|
'process.entry_leader.saved_group.name',
|
||||||
|
'process.entry_leader.saved_user.id',
|
||||||
|
'process.entry_leader.saved_user.name',
|
||||||
|
'process.entry_leader.saved_user.name.text',
|
||||||
|
'process.entry_leader.start',
|
||||||
|
'process.entry_leader.supplemental_groups.id',
|
||||||
|
'process.entry_leader.supplemental_groups.name',
|
||||||
|
'process.entry_leader.tty.char_device.major',
|
||||||
|
'process.entry_leader.tty.char_device.minor',
|
||||||
|
'process.entry_leader.user.id',
|
||||||
|
'process.entry_leader.user.name',
|
||||||
|
'process.entry_leader.user.name.text',
|
||||||
|
'process.entry_leader.working_directory',
|
||||||
|
'process.entry_leader.working_directory.caseless',
|
||||||
|
'process.entry_leader.working_directory.text',
|
||||||
|
'process.env_vars',
|
||||||
|
'process.executable',
|
||||||
|
'process.executable.caseless',
|
||||||
|
'process.executable.text',
|
||||||
|
'process.exit_code',
|
||||||
|
'process.group.id',
|
||||||
|
'process.group.name',
|
||||||
|
'process.group_leader.args',
|
||||||
|
'process.group_leader.args_count',
|
||||||
|
'process.group_leader.command_line',
|
||||||
|
'process.group_leader.command_line.caseless',
|
||||||
|
'process.group_leader.command_line.text',
|
||||||
|
'process.group_leader.entity_id',
|
||||||
|
'process.group_leader.executable',
|
||||||
|
'process.group_leader.executable.caseless',
|
||||||
|
'process.group_leader.executable.text',
|
||||||
|
'process.group_leader.group.id',
|
||||||
|
'process.group_leader.group.name',
|
||||||
|
'process.group_leader.interactive',
|
||||||
|
'process.group_leader.name',
|
||||||
|
'process.group_leader.name.caseless',
|
||||||
|
'process.group_leader.name.text',
|
||||||
|
'process.group_leader.pid',
|
||||||
|
'process.group_leader.real_group.id',
|
||||||
|
'process.group_leader.real_group.name',
|
||||||
|
'process.group_leader.real_user.id',
|
||||||
|
'process.group_leader.real_user.name',
|
||||||
|
'process.group_leader.real_user.name.text',
|
||||||
|
'process.group_leader.same_as_process',
|
||||||
|
'process.group_leader.saved_group.id',
|
||||||
|
'process.group_leader.saved_group.name',
|
||||||
|
'process.group_leader.saved_user.id',
|
||||||
|
'process.group_leader.saved_user.name',
|
||||||
|
'process.group_leader.saved_user.name.text',
|
||||||
|
'process.group_leader.start',
|
||||||
|
'process.group_leader.supplemental_groups.id',
|
||||||
|
'process.group_leader.supplemental_groups.name',
|
||||||
|
'process.group_leader.tty.char_device.major',
|
||||||
|
'process.group_leader.tty.char_device.minor',
|
||||||
|
'process.group_leader.user.id',
|
||||||
|
'process.group_leader.user.name',
|
||||||
|
'process.group_leader.user.name.text',
|
||||||
|
'process.group_leader.working_directory',
|
||||||
|
'process.group_leader.working_directory.caseless',
|
||||||
|
'process.group_leader.working_directory.text',
|
||||||
|
'process.hash.md5',
|
||||||
|
'process.hash.sha1',
|
||||||
|
'process.hash.sha256',
|
||||||
|
'process.hash.sha512',
|
||||||
|
'process.interactive',
|
||||||
|
'process.io.max_bytes_per_process_exceeded',
|
||||||
|
'process.io.text',
|
||||||
|
'process.io.total_bytes_captured',
|
||||||
|
'process.io.total_bytes_skipped',
|
||||||
|
'process.name',
|
||||||
|
'process.name.caseless',
|
||||||
|
'process.name.text',
|
||||||
|
'process.parent.Ext.architecture',
|
||||||
|
'process.parent.Ext.code_signature.exists',
|
||||||
|
'process.parent.Ext.code_signature.status',
|
||||||
|
'process.parent.Ext.code_signature.subject_name',
|
||||||
|
'process.parent.Ext.code_signature.trusted',
|
||||||
|
'process.parent.Ext.code_signature.valid',
|
||||||
|
'process.parent.Ext.protection',
|
||||||
|
'process.parent.Ext.real.pid',
|
||||||
|
'process.parent.Ext.user',
|
||||||
|
'process.parent.args',
|
||||||
|
'process.parent.args_count',
|
||||||
|
'process.parent.code_signature.exists',
|
||||||
|
'process.parent.code_signature.signing_id',
|
||||||
|
'process.parent.code_signature.status',
|
||||||
|
'process.parent.code_signature.subject_name',
|
||||||
|
'process.parent.code_signature.team_id',
|
||||||
|
'process.parent.code_signature.trusted',
|
||||||
|
'process.parent.code_signature.valid',
|
||||||
|
'process.parent.command_line',
|
||||||
|
'process.parent.command_line.caseless',
|
||||||
|
'process.parent.command_line.text',
|
||||||
|
'process.parent.entity_id',
|
||||||
|
'process.parent.executable',
|
||||||
|
'process.parent.executable.caseless',
|
||||||
|
'process.parent.executable.text',
|
||||||
|
'process.parent.exit_code',
|
||||||
|
'process.parent.group.id',
|
||||||
|
'process.parent.group.name',
|
||||||
|
'process.parent.group_leader.entity_id',
|
||||||
|
'process.parent.group_leader.pid',
|
||||||
|
'process.parent.group_leader.start',
|
||||||
|
'process.parent.hash.md5',
|
||||||
|
'process.parent.hash.sha1',
|
||||||
|
'process.parent.hash.sha256',
|
||||||
|
'process.parent.hash.sha512',
|
||||||
|
'process.parent.interactive',
|
||||||
|
'process.parent.name',
|
||||||
|
'process.parent.name.caseless',
|
||||||
|
'process.parent.name.text',
|
||||||
|
'process.parent.pe.company',
|
||||||
|
'process.parent.pe.description',
|
||||||
|
'process.parent.pe.file_version',
|
||||||
|
'process.parent.pe.imphash',
|
||||||
|
'process.parent.pe.original_file_name',
|
||||||
|
'process.parent.pe.product',
|
||||||
|
'process.parent.pgid',
|
||||||
|
'process.parent.pid',
|
||||||
|
'process.parent.ppid',
|
||||||
|
'process.parent.real_group.id',
|
||||||
|
'process.parent.real_group.name',
|
||||||
|
'process.parent.real_user.id',
|
||||||
|
'process.parent.real_user.name',
|
||||||
|
'process.parent.real_user.name.text',
|
||||||
|
'process.parent.saved_group.id',
|
||||||
|
'process.parent.saved_group.name',
|
||||||
|
'process.parent.saved_user.id',
|
||||||
|
'process.parent.saved_user.name',
|
||||||
|
'process.parent.saved_user.name.text',
|
||||||
|
'process.parent.start',
|
||||||
|
'process.parent.supplemental_groups.id',
|
||||||
|
'process.parent.supplemental_groups.name',
|
||||||
|
'process.parent.thread.Ext.call_stack.allocation_private_bytes',
|
||||||
|
'process.parent.thread.Ext.call_stack.callsite_leading_bytes',
|
||||||
|
'process.parent.thread.Ext.call_stack.callsite_trailing_bytes',
|
||||||
|
'process.parent.thread.Ext.call_stack.protection',
|
||||||
|
'process.parent.thread.Ext.call_stack.symbol_info',
|
||||||
|
'process.parent.thread.Ext.call_stack_contains_unbacked',
|
||||||
|
'process.parent.thread.Ext.call_stack_summary',
|
||||||
|
'process.parent.thread.id',
|
||||||
|
'process.parent.thread.name',
|
||||||
|
'process.parent.title',
|
||||||
|
'process.parent.title.text',
|
||||||
|
'process.parent.tty.char_device.major',
|
||||||
|
'process.parent.tty.char_device.minor',
|
||||||
|
'process.parent.uptime',
|
||||||
|
'process.parent.user.id',
|
||||||
|
'process.parent.user.name',
|
||||||
|
'process.parent.user.name.text',
|
||||||
|
'process.parent.working_directory',
|
||||||
|
'process.parent.working_directory.caseless',
|
||||||
|
'process.parent.working_directory.text',
|
||||||
|
'process.pe.company',
|
||||||
|
'process.pe.description',
|
||||||
|
'process.pe.file_version',
|
||||||
|
'process.pe.imphash',
|
||||||
|
'process.pe.original_file_name',
|
||||||
|
'process.pe.product',
|
||||||
|
'process.pgid',
|
||||||
|
'process.pid',
|
||||||
|
'process.ppid',
|
||||||
|
'process.previous.args',
|
||||||
|
'process.previous.args_count',
|
||||||
|
'process.previous.executable',
|
||||||
|
'process.previous.executable.caseless',
|
||||||
|
'process.previous.executable.text',
|
||||||
|
'process.real_group.id',
|
||||||
|
'process.real_group.name',
|
||||||
|
'process.real_user.id',
|
||||||
|
'process.real_user.name',
|
||||||
|
'process.real_user.name.text',
|
||||||
|
'process.saved_group.id',
|
||||||
|
'process.saved_group.name',
|
||||||
|
'process.saved_user.id',
|
||||||
|
'process.saved_user.name',
|
||||||
|
'process.saved_user.name.text',
|
||||||
|
'process.session_leader.args',
|
||||||
|
'process.session_leader.args_count',
|
||||||
|
'process.session_leader.command_line',
|
||||||
|
'process.session_leader.command_line.caseless',
|
||||||
|
'process.session_leader.command_line.text',
|
||||||
|
'process.session_leader.entity_id',
|
||||||
|
'process.session_leader.executable',
|
||||||
|
'process.session_leader.executable.caseless',
|
||||||
|
'process.session_leader.executable.text',
|
||||||
|
'process.session_leader.group.id',
|
||||||
|
'process.session_leader.group.name',
|
||||||
|
'process.session_leader.interactive',
|
||||||
|
'process.session_leader.name',
|
||||||
|
'process.session_leader.name.caseless',
|
||||||
|
'process.session_leader.name.text',
|
||||||
|
'process.session_leader.parent.entity_id',
|
||||||
|
'process.session_leader.parent.pid',
|
||||||
|
'process.session_leader.parent.session_leader.entity_id',
|
||||||
|
'process.session_leader.parent.session_leader.pid',
|
||||||
|
'process.session_leader.parent.session_leader.start',
|
||||||
|
'process.session_leader.parent.start',
|
||||||
|
'process.session_leader.pid',
|
||||||
|
'process.session_leader.real_group.id',
|
||||||
|
'process.session_leader.real_group.name',
|
||||||
|
'process.session_leader.real_user.id',
|
||||||
|
'process.session_leader.real_user.name',
|
||||||
|
'process.session_leader.real_user.name.text',
|
||||||
|
'process.session_leader.same_as_process',
|
||||||
|
'process.session_leader.saved_group.id',
|
||||||
|
'process.session_leader.saved_group.name',
|
||||||
|
'process.session_leader.saved_user.id',
|
||||||
|
'process.session_leader.saved_user.name',
|
||||||
|
'process.session_leader.saved_user.name.text',
|
||||||
|
'process.session_leader.start',
|
||||||
|
'process.session_leader.supplemental_groups.id',
|
||||||
|
'process.session_leader.supplemental_groups.name',
|
||||||
|
'process.session_leader.tty.char_device.major',
|
||||||
|
'process.session_leader.tty.char_device.minor',
|
||||||
|
'process.session_leader.user.id',
|
||||||
|
'process.session_leader.user.name',
|
||||||
|
'process.session_leader.user.name.text',
|
||||||
|
'process.session_leader.working_directory',
|
||||||
|
'process.session_leader.working_directory.caseless',
|
||||||
|
'process.session_leader.working_directory.text',
|
||||||
|
'process.start',
|
||||||
|
'process.supplemental_groups.id',
|
||||||
|
'process.supplemental_groups.name',
|
||||||
|
'process.thread.Ext.call_stack.allocation_private_bytes',
|
||||||
|
'process.thread.Ext.call_stack.callsite_leading_bytes',
|
||||||
|
'process.thread.Ext.call_stack.callsite_trailing_bytes',
|
||||||
|
'process.thread.Ext.call_stack.instruction_pointer',
|
||||||
|
'process.thread.Ext.call_stack.module_path',
|
||||||
|
'process.thread.Ext.call_stack.protection',
|
||||||
|
'process.thread.Ext.call_stack.protection_provenance',
|
||||||
|
'process.thread.Ext.call_stack.symbol_info',
|
||||||
|
'process.thread.Ext.call_stack_contains_unbacked',
|
||||||
|
'process.thread.Ext.call_stack_final_user_module.code_signature.exists',
|
||||||
|
'process.thread.Ext.call_stack_final_user_module.code_signature.status',
|
||||||
|
'process.thread.Ext.call_stack_final_user_module.code_signature.subject_name',
|
||||||
|
'process.thread.Ext.call_stack_final_user_module.code_signature.trusted',
|
||||||
|
'process.thread.Ext.call_stack_final_user_module.code_signature.valid',
|
||||||
|
'process.thread.Ext.call_stack_final_user_module.hash.sha256',
|
||||||
|
'process.thread.Ext.call_stack_final_user_module.name',
|
||||||
|
'process.thread.Ext.call_stack_final_user_module.path',
|
||||||
|
'process.thread.Ext.call_stack_final_user_module.protection_provenance',
|
||||||
|
'process.thread.Ext.call_stack_summary',
|
||||||
|
'process.thread.capabilities.effective',
|
||||||
|
'process.thread.capabilities.permitted',
|
||||||
|
'process.thread.id',
|
||||||
|
'process.thread.name',
|
||||||
|
'process.title',
|
||||||
|
'process.title.text',
|
||||||
|
'process.tty.char_device.major',
|
||||||
|
'process.tty.char_device.minor',
|
||||||
|
'process.tty.columns',
|
||||||
|
'process.tty.rows',
|
||||||
|
'process.uptime',
|
||||||
|
'process.user.id',
|
||||||
|
'process.user.name',
|
||||||
|
'process.user.name.text',
|
||||||
|
'process.working_directory',
|
||||||
|
'process.working_directory.caseless',
|
||||||
|
'process.working_directory.text',
|
||||||
|
'registry.data.bytes',
|
||||||
|
'registry.data.strings',
|
||||||
|
'registry.data.type',
|
||||||
|
'registry.hive',
|
||||||
|
'registry.key',
|
||||||
|
'registry.path',
|
||||||
|
'registry.value',
|
||||||
|
'source.address',
|
||||||
|
'source.as.number',
|
||||||
|
'source.as.organization.name',
|
||||||
|
'source.as.organization.name.text',
|
||||||
|
'source.bytes',
|
||||||
|
'source.domain',
|
||||||
|
'source.geo.city_name',
|
||||||
|
'source.geo.continent_code',
|
||||||
|
'source.geo.continent_name',
|
||||||
|
'source.geo.country_iso_code',
|
||||||
|
'source.geo.country_name',
|
||||||
|
'source.geo.location',
|
||||||
|
'source.geo.name',
|
||||||
|
'source.geo.postal_code',
|
||||||
|
'source.geo.region_iso_code',
|
||||||
|
'source.geo.region_name',
|
||||||
|
'source.geo.timezone',
|
||||||
|
'source.ip',
|
||||||
|
'source.packets',
|
||||||
|
'source.port',
|
||||||
|
'source.registered_domain',
|
||||||
|
'source.top_level_domain',
|
||||||
|
'user.Ext.real.id',
|
||||||
|
'user.Ext.real.name',
|
||||||
|
'user.domain',
|
||||||
|
'user.email',
|
||||||
|
'user.full_name',
|
||||||
|
'user.full_name.text',
|
||||||
|
'user.group.Ext.real.id',
|
||||||
|
'user.group.Ext.real.name',
|
||||||
|
'user.group.domain',
|
||||||
|
'user.group.id',
|
||||||
|
'user.group.name',
|
||||||
|
'user.hash',
|
||||||
|
'user.id',
|
||||||
|
'user.name',
|
||||||
|
'user.name.text',
|
||||||
|
];
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ListOperator, ListOperatorType } from '@kbn/securitysolution-io-ts-list-types';
|
||||||
|
import { ListOperatorEnum, ListOperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
|
||||||
|
|
||||||
|
export const LIST_ITEM_ENTRY_OPERATOR_TYPES: readonly ListOperatorType[] = Object.freeze([
|
||||||
|
ListOperatorTypeEnum.NESTED,
|
||||||
|
ListOperatorTypeEnum.MATCH,
|
||||||
|
ListOperatorTypeEnum.MATCH_ANY,
|
||||||
|
ListOperatorTypeEnum.WILDCARD,
|
||||||
|
ListOperatorTypeEnum.EXISTS,
|
||||||
|
ListOperatorTypeEnum.LIST,
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const LIST_ITEM_ENTRY_OPERATOR: readonly ListOperator[] = Object.freeze([
|
||||||
|
ListOperatorEnum.INCLUDED,
|
||||||
|
ListOperatorEnum.EXCLUDED,
|
||||||
|
]);
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type {
|
||||||
|
CreateExceptionListItemSchema,
|
||||||
|
ExceptionListItemSchema,
|
||||||
|
ListOperatorType,
|
||||||
|
} from '@kbn/securitysolution-io-ts-list-types';
|
||||||
|
import { ListOperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
|
||||||
|
import { ENDPOINT_LIST_ID } from '@kbn/securitysolution-list-constants';
|
||||||
|
import { LIST_ITEM_ENTRY_OPERATOR_TYPES } from './common/artifact_list_item_entry_values';
|
||||||
|
import { exceptionItemToCreateExceptionItem } from './exceptions_list_item_generator';
|
||||||
|
import { BaseDataGenerator } from './base_data_generator';
|
||||||
|
import { GLOBAL_ARTIFACT_TAG } from '../service/artifacts';
|
||||||
|
import { ENDPOINT_EVENTS_LOG_INDEX_FIELDS } from './common/alerts_ecs_fields';
|
||||||
|
|
||||||
|
export class EndpointExceptionsGenerator extends BaseDataGenerator<ExceptionListItemSchema> {
|
||||||
|
generate(overrides: Partial<ExceptionListItemSchema> = {}): ExceptionListItemSchema {
|
||||||
|
return {
|
||||||
|
name: `Generated Exception (${this.randomString(5)})`,
|
||||||
|
comments: [],
|
||||||
|
description: 'created by EndpointExceptionsGenerator',
|
||||||
|
id: this.seededUUIDv4(),
|
||||||
|
item_id: this.seededUUIDv4(),
|
||||||
|
list_id: ENDPOINT_LIST_ID,
|
||||||
|
tags: [GLOBAL_ARTIFACT_TAG],
|
||||||
|
entries: this.randomEndpointExceptionEntries(1),
|
||||||
|
meta: undefined,
|
||||||
|
namespace_type: 'agnostic',
|
||||||
|
os_types: [this.randomOSFamily()] as ExceptionListItemSchema['os_types'],
|
||||||
|
created_at: this.randomPastDate(),
|
||||||
|
created_by: this.randomUser(),
|
||||||
|
updated_at: '2020-04-20T15:25:31.830Z',
|
||||||
|
expire_time: undefined,
|
||||||
|
updated_by: this.randomUser(),
|
||||||
|
_version: this.randomString(5),
|
||||||
|
type: 'simple',
|
||||||
|
tie_breaker_id: this.seededUUIDv4(),
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
generateEndpointExceptionForCreate(
|
||||||
|
overrides: Partial<CreateExceptionListItemSchema> = {}
|
||||||
|
): CreateExceptionListItemSchema {
|
||||||
|
return {
|
||||||
|
...exceptionItemToCreateExceptionItem(this.generate()),
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected randomEndpointExceptionEntries(
|
||||||
|
count: number = this.randomN(5)
|
||||||
|
): ExceptionListItemSchema['entries'] {
|
||||||
|
const operatorTypes = LIST_ITEM_ENTRY_OPERATOR_TYPES.filter(
|
||||||
|
(item) =>
|
||||||
|
!(
|
||||||
|
[
|
||||||
|
ListOperatorTypeEnum.LIST,
|
||||||
|
ListOperatorTypeEnum.NESTED,
|
||||||
|
ListOperatorTypeEnum.EXISTS,
|
||||||
|
] as ListOperatorType[]
|
||||||
|
).includes(item)
|
||||||
|
);
|
||||||
|
const fieldList = ENDPOINT_EVENTS_LOG_INDEX_FIELDS.filter((field) => field.endsWith('.text'));
|
||||||
|
|
||||||
|
return Array.from({ length: count || 1 }, () => {
|
||||||
|
const operatorType = this.randomChoice(operatorTypes);
|
||||||
|
|
||||||
|
return {
|
||||||
|
field: this.randomChoice(fieldList),
|
||||||
|
operator: 'included',
|
||||||
|
type: operatorType,
|
||||||
|
value:
|
||||||
|
operatorType === ListOperatorTypeEnum.MATCH_ANY
|
||||||
|
? [this.randomString(10), this.randomString(10)]
|
||||||
|
: this.randomString(10),
|
||||||
|
};
|
||||||
|
}) as ExceptionListItemSchema['entries'];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type {
|
||||||
|
ExceptionListItemSchema,
|
||||||
|
CreateExceptionListItemSchema,
|
||||||
|
ListOperator,
|
||||||
|
} from '@kbn/securitysolution-io-ts-list-types';
|
||||||
|
import { ENDPOINT_ARTIFACT_LISTS } from '@kbn/securitysolution-list-constants';
|
||||||
|
import { exceptionItemToCreateExceptionItem } from './exceptions_list_item_generator';
|
||||||
|
import { GLOBAL_ARTIFACT_TAG } from '../service/artifacts';
|
||||||
|
import { BaseDataGenerator } from './base_data_generator';
|
||||||
|
import { ENDPOINT_EVENTS_LOG_INDEX_FIELDS } from './common/alerts_ecs_fields';
|
||||||
|
|
||||||
|
const ENTRY_OPERATORS: readonly ListOperator[] = ['included', 'excluded'];
|
||||||
|
|
||||||
|
export class EventFiltersGenerator extends BaseDataGenerator<ExceptionListItemSchema> {
|
||||||
|
generate(overrides: Partial<ExceptionListItemSchema> = {}): ExceptionListItemSchema {
|
||||||
|
return {
|
||||||
|
id: this.seededUUIDv4(),
|
||||||
|
item_id: this.seededUUIDv4(),
|
||||||
|
list_id: ENDPOINT_ARTIFACT_LISTS.eventFilters.id,
|
||||||
|
meta: undefined,
|
||||||
|
name: `Event filter (${this.randomString(5)})`,
|
||||||
|
description: `created by ${this.constructor.name}`,
|
||||||
|
tags: [GLOBAL_ARTIFACT_TAG],
|
||||||
|
entries: this.randomEventFilterEntries(),
|
||||||
|
expire_time: undefined,
|
||||||
|
namespace_type: 'agnostic',
|
||||||
|
type: 'simple',
|
||||||
|
os_types: [this.randomOSFamily()] as ExceptionListItemSchema['os_types'],
|
||||||
|
tie_breaker_id: this.seededUUIDv4(),
|
||||||
|
_version: this.randomString(5),
|
||||||
|
comments: [],
|
||||||
|
created_at: this.randomPastDate(),
|
||||||
|
created_by: this.randomUser(),
|
||||||
|
updated_at: '2020-04-20T15:25:31.830Z',
|
||||||
|
updated_by: this.randomUser(),
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
generateEventFilterForCreate(
|
||||||
|
overrides: Partial<CreateExceptionListItemSchema> = {}
|
||||||
|
): CreateExceptionListItemSchema {
|
||||||
|
return {
|
||||||
|
...exceptionItemToCreateExceptionItem(this.generate()),
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected randomEventFilterEntries(
|
||||||
|
count: number = this.randomN(5)
|
||||||
|
): ExceptionListItemSchema['entries'] {
|
||||||
|
return Array.from({ length: count || 1 }, () => {
|
||||||
|
if (this.randomBoolean()) {
|
||||||
|
// single entry
|
||||||
|
return {
|
||||||
|
field: this.randomChoice(ENDPOINT_EVENTS_LOG_INDEX_FIELDS),
|
||||||
|
operator: this.randomChoice(ENTRY_OPERATORS),
|
||||||
|
type: 'match',
|
||||||
|
value: this.randomString(10),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// nested entry
|
||||||
|
return {
|
||||||
|
field: this.randomChoice(ENDPOINT_EVENTS_LOG_INDEX_FIELDS),
|
||||||
|
type: 'nested',
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
field: this.randomChoice(ENDPOINT_EVENTS_LOG_INDEX_FIELDS),
|
||||||
|
operator: this.randomChoice(ENTRY_OPERATORS),
|
||||||
|
type: 'match',
|
||||||
|
value: this.randomString(10),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ type UpdateExceptionListItemSchemaWithNonNullProps = NonNullableTypeProperties<
|
||||||
> &
|
> &
|
||||||
Pick<UpdateExceptionListItemSchema, 'meta' | 'expire_time'>;
|
Pick<UpdateExceptionListItemSchema, 'meta' | 'expire_time'>;
|
||||||
|
|
||||||
const exceptionItemToCreateExceptionItem = (
|
export const exceptionItemToCreateExceptionItem = (
|
||||||
exceptionItem: ExceptionListItemSchema
|
exceptionItem: ExceptionListItemSchema
|
||||||
): CreateExceptionListItemSchemaWithNonNullProps => {
|
): CreateExceptionListItemSchemaWithNonNullProps => {
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -247,4 +247,8 @@ export class FleetAgentGenerator extends BaseDataGenerator<Agent> {
|
||||||
public randomAgentStatus() {
|
public randomAgentStatus() {
|
||||||
return this.randomChoice(agentStatusList);
|
return this.randomChoice(agentStatusList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public randomString(length: number = 5) {
|
||||||
|
return super.randomString(length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ export const setupFleetForEndpoint = usageTracker.track(
|
||||||
export const installOrUpgradeEndpointFleetPackage = usageTracker.track(
|
export const installOrUpgradeEndpointFleetPackage = usageTracker.track(
|
||||||
'installOrUpgradeEndpointFleetPackage',
|
'installOrUpgradeEndpointFleetPackage',
|
||||||
async (kbnClient: KbnClient, logger: ToolingLog): Promise<BulkInstallPackageInfo> => {
|
async (kbnClient: KbnClient, logger: ToolingLog): Promise<BulkInstallPackageInfo> => {
|
||||||
logger.info(`installOrUpgradeEndpointFleetPackage(): starting`);
|
logger.debug(`installOrUpgradeEndpointFleetPackage(): starting`);
|
||||||
|
|
||||||
const updatePackages = async () => {
|
const updatePackages = async () => {
|
||||||
const installEndpointPackageResp = (await kbnClient
|
const installEndpointPackageResp = (await kbnClient
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { mergeWith } from 'lodash';
|
||||||
import type { ToolingLogTextWriterConfig } from '@kbn/tooling-log';
|
import type { ToolingLogTextWriterConfig } from '@kbn/tooling-log';
|
||||||
import { ToolingLog } from '@kbn/tooling-log';
|
import { ToolingLog } from '@kbn/tooling-log';
|
||||||
import type { Flags } from '@kbn/dev-cli-runner';
|
import type { Flags } from '@kbn/dev-cli-runner';
|
||||||
|
import moment from 'moment/moment';
|
||||||
|
|
||||||
export const RETRYABLE_TRANSIENT_ERRORS: Readonly<Array<string | RegExp>> = [
|
export const RETRYABLE_TRANSIENT_ERRORS: Readonly<Array<string | RegExp>> = [
|
||||||
'no_shard_available_action_exception',
|
'no_shard_available_action_exception',
|
||||||
|
@ -76,18 +77,18 @@ export const retryOnError = async <T>(
|
||||||
const thisAttempt = attempt;
|
const thisAttempt = attempt;
|
||||||
attempt++;
|
attempt++;
|
||||||
|
|
||||||
log.info(msg(`attempt ${thisAttempt} started at: ${new Date().toISOString()}`));
|
log.debug(msg(`attempt ${thisAttempt} started at: ${new Date().toISOString()}`));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
responsePromise = callback(); // store promise so that if it fails and no more attempts, we return the last failure
|
responsePromise = callback(); // store promise so that if it fails and no more attempts, we return the last failure
|
||||||
const result = await responsePromise;
|
const result = await responsePromise;
|
||||||
|
|
||||||
log.info(msg(`attempt ${thisAttempt} was successful. Exiting retry`));
|
log.debug(msg(`attempt ${thisAttempt} was successful. Exiting retry`));
|
||||||
log.indent(-4);
|
log.indent(-4);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.info(msg(`attempt ${thisAttempt} failed with: ${err.message}`), err);
|
log.warning(msg(`attempt ${thisAttempt} failed with: ${err.message}`), err);
|
||||||
|
|
||||||
// If not an error that is retryable, then end loop here and return that error;
|
// If not an error that is retryable, then end loop here and return that error;
|
||||||
if (!isRetryableError(err)) {
|
if (!isRetryableError(err)) {
|
||||||
|
@ -157,3 +158,26 @@ createToolingLogger.setDefaultLogLevelFromCliFlags = (flags) => {
|
||||||
? 'error'
|
? 'error'
|
||||||
: 'info';
|
: 'info';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get human readable string of time elapsed between to dates. Return value will be in the format
|
||||||
|
* of `hh:mm:ss.ms`
|
||||||
|
* @param startDate
|
||||||
|
* @param endTime
|
||||||
|
*/
|
||||||
|
export const getElapsedTime = (
|
||||||
|
startDate: string | Date,
|
||||||
|
endTime: string | Date = new Date()
|
||||||
|
): string => {
|
||||||
|
const durationObj = moment.duration(moment(endTime).diff(startDate));
|
||||||
|
const pad = (num: number, max = 2): string => {
|
||||||
|
return String(num).padStart(max, '0');
|
||||||
|
};
|
||||||
|
|
||||||
|
const hours = pad(durationObj.hours());
|
||||||
|
const minutes = pad(durationObj.minutes());
|
||||||
|
const seconds = pad(durationObj.seconds());
|
||||||
|
const milliseconds = pad(durationObj.milliseconds(), 3);
|
||||||
|
|
||||||
|
return `${hours}:${minutes}:${seconds}.${milliseconds}`;
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ENDPOINT_ARTIFACT_LISTS } from '@kbn/securitysolution-list-constants';
|
||||||
|
import {
|
||||||
|
ENDPOINT_LIST_DESCRIPTION,
|
||||||
|
ENDPOINT_LIST_ID,
|
||||||
|
ENDPOINT_LIST_NAME,
|
||||||
|
EXCEPTION_LIST_ITEM_URL,
|
||||||
|
INTERNAL_EXCEPTIONS_LIST_ENSURE_CREATED_URL,
|
||||||
|
} from '@kbn/securitysolution-list-constants';
|
||||||
|
import type { KbnClient } from '@kbn/test';
|
||||||
|
import type {
|
||||||
|
CreateExceptionListSchema,
|
||||||
|
ExceptionListItemSchema,
|
||||||
|
CreateExceptionListItemSchema,
|
||||||
|
} from '@kbn/securitysolution-io-ts-list-types';
|
||||||
|
import { memoize } from 'lodash';
|
||||||
|
import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
|
||||||
|
import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error';
|
||||||
|
import { TRUSTED_APPS_EXCEPTION_LIST_DEFINITION } from '../../../public/management/pages/trusted_apps/constants';
|
||||||
|
import { EVENT_FILTER_LIST_DEFINITION } from '../../../public/management/pages/event_filters/constants';
|
||||||
|
import { BLOCKLISTS_LIST_DEFINITION } from '../../../public/management/pages/blocklist/constants';
|
||||||
|
import { HOST_ISOLATION_EXCEPTIONS_LIST_DEFINITION } from '../../../public/management/pages/host_isolation_exceptions/constants';
|
||||||
|
import type { NewTrustedApp } from '../../../common/endpoint/types';
|
||||||
|
import { newTrustedAppToCreateExceptionListItem } from '../../../public/management/pages/trusted_apps/service/mappers';
|
||||||
|
|
||||||
|
const ensureArtifactListExists = memoize(
|
||||||
|
async (
|
||||||
|
kbnClient: KbnClient,
|
||||||
|
artifactType: keyof typeof ENDPOINT_ARTIFACT_LISTS | 'endpointExceptions'
|
||||||
|
) => {
|
||||||
|
let listDefinition: CreateExceptionListSchema;
|
||||||
|
|
||||||
|
switch (artifactType) {
|
||||||
|
case 'blocklists':
|
||||||
|
listDefinition = BLOCKLISTS_LIST_DEFINITION;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'eventFilters':
|
||||||
|
listDefinition = EVENT_FILTER_LIST_DEFINITION;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'hostIsolationExceptions':
|
||||||
|
listDefinition = HOST_ISOLATION_EXCEPTIONS_LIST_DEFINITION;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'trustedApps':
|
||||||
|
listDefinition = TRUSTED_APPS_EXCEPTION_LIST_DEFINITION;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'endpointExceptions':
|
||||||
|
listDefinition = {
|
||||||
|
name: ENDPOINT_LIST_NAME,
|
||||||
|
namespace_type: 'agnostic',
|
||||||
|
description: ENDPOINT_LIST_DESCRIPTION,
|
||||||
|
list_id: ENDPOINT_LIST_ID,
|
||||||
|
type: ExceptionListTypeEnum.ENDPOINT,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown Artifact list: ${artifactType}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await kbnClient
|
||||||
|
.request({
|
||||||
|
method: 'POST',
|
||||||
|
path: INTERNAL_EXCEPTIONS_LIST_ENSURE_CREATED_URL,
|
||||||
|
body: listDefinition,
|
||||||
|
headers: {
|
||||||
|
'elastic-api-version': '1',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch(catchAxiosErrorFormatAndThrow);
|
||||||
|
},
|
||||||
|
(kbnClient: KbnClient, artifactType: string) => {
|
||||||
|
return `${artifactType}@[${kbnClient.resolveUrl('')}`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an exception list item.
|
||||||
|
* NOTE: this method does NOT create the list itself.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*
|
||||||
|
* @param kbnClient
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
const createExceptionListItem = async (
|
||||||
|
kbnClient: KbnClient,
|
||||||
|
data: CreateExceptionListItemSchema
|
||||||
|
): Promise<ExceptionListItemSchema> => {
|
||||||
|
return kbnClient
|
||||||
|
.request<ExceptionListItemSchema>({
|
||||||
|
method: 'POST',
|
||||||
|
path: EXCEPTION_LIST_ITEM_URL,
|
||||||
|
body: data,
|
||||||
|
headers: {
|
||||||
|
'elastic-api-version': '2023-10-31',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch(catchAxiosErrorFormatAndThrow)
|
||||||
|
.then((response) => response.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createTrustedApp = async (
|
||||||
|
kbnClient: KbnClient,
|
||||||
|
data: NewTrustedApp
|
||||||
|
): Promise<ExceptionListItemSchema> => {
|
||||||
|
await ensureArtifactListExists(kbnClient, 'trustedApps');
|
||||||
|
return createExceptionListItem(kbnClient, newTrustedAppToCreateExceptionListItem(data));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createEventFilter = async (
|
||||||
|
kbnClient: KbnClient,
|
||||||
|
data: CreateExceptionListItemSchema
|
||||||
|
): Promise<ExceptionListItemSchema> => {
|
||||||
|
await ensureArtifactListExists(kbnClient, 'eventFilters');
|
||||||
|
return createExceptionListItem(kbnClient, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createBlocklist = async (
|
||||||
|
kbnClient: KbnClient,
|
||||||
|
data: CreateExceptionListItemSchema
|
||||||
|
): Promise<ExceptionListItemSchema> => {
|
||||||
|
await ensureArtifactListExists(kbnClient, 'blocklists');
|
||||||
|
return createExceptionListItem(kbnClient, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createHostIsolationException = async (
|
||||||
|
kbnClient: KbnClient,
|
||||||
|
data: CreateExceptionListItemSchema
|
||||||
|
): Promise<ExceptionListItemSchema> => {
|
||||||
|
await ensureArtifactListExists(kbnClient, 'hostIsolationExceptions');
|
||||||
|
return createExceptionListItem(kbnClient, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createEndpointException = async (
|
||||||
|
kbnClient: KbnClient,
|
||||||
|
data: CreateExceptionListItemSchema
|
||||||
|
): Promise<ExceptionListItemSchema> => {
|
||||||
|
await ensureArtifactListExists(kbnClient, 'hostIsolationExceptions');
|
||||||
|
return createExceptionListItem(kbnClient, data);
|
||||||
|
};
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type { ToolingLog } from '@kbn/tooling-log';
|
||||||
|
import { createToolingLogger } from '../../../common/endpoint/data_loaders/utils';
|
||||||
|
|
||||||
|
export interface ExecutionThrottlerOptions {
|
||||||
|
concurrency?: number;
|
||||||
|
log?: ToolingLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue callback functions and execute them in parallel using the defined concurrency number. Execution of
|
||||||
|
* callbacks starts as soon as functions start to be added to the queue (ex. Does not wait for a "batch"
|
||||||
|
* size to be reached) and continues to process the queue until it is flushed out.
|
||||||
|
*/
|
||||||
|
export class ExecutionThrottler {
|
||||||
|
private readonly options: Required<ExecutionThrottlerOptions>;
|
||||||
|
private readonly queue: Array<() => Promise<any>> = [];
|
||||||
|
private readonly executing = new Set<Promise<any>>();
|
||||||
|
|
||||||
|
constructor({ concurrency = 10, log = createToolingLogger() }: ExecutionThrottlerOptions = {}) {
|
||||||
|
this.options = {
|
||||||
|
concurrency,
|
||||||
|
log,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private logCurrentState() {
|
||||||
|
this.options.log.debug(
|
||||||
|
`Executing count: [${this.executing.size}], Queue count: [${this.queue.length}]`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async execute(): Promise<void> {
|
||||||
|
if (this.queue.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (this.executing.size < this.options.concurrency && this.queue.length) {
|
||||||
|
const callbackFn = this.queue.shift();
|
||||||
|
|
||||||
|
if (callbackFn) {
|
||||||
|
const callbackPromise = callbackFn();
|
||||||
|
this.executing.add(callbackPromise);
|
||||||
|
|
||||||
|
callbackPromise.finally(() => {
|
||||||
|
this.executing.delete(callbackPromise);
|
||||||
|
this.execute();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logCurrentState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public addToQueue(fn: () => Promise<any>): void {
|
||||||
|
this.queue.push(fn);
|
||||||
|
this.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async complete(): Promise<void> {
|
||||||
|
while (this.executing.size > 0) {
|
||||||
|
this.logCurrentState();
|
||||||
|
await Promise.all(Array.from(this.executing)).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getStats(): { pending: number } {
|
||||||
|
return {
|
||||||
|
pending: this.queue.length,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ import type {
|
||||||
GetPackagePoliciesResponse,
|
GetPackagePoliciesResponse,
|
||||||
PackagePolicy,
|
PackagePolicy,
|
||||||
PostFleetSetupResponse,
|
PostFleetSetupResponse,
|
||||||
|
CopyAgentPolicyResponse,
|
||||||
} from '@kbn/fleet-plugin/common';
|
} from '@kbn/fleet-plugin/common';
|
||||||
import {
|
import {
|
||||||
AGENT_API_ROUTES,
|
AGENT_API_ROUTES,
|
||||||
|
@ -37,6 +38,7 @@ import {
|
||||||
epmRouteService,
|
epmRouteService,
|
||||||
PACKAGE_POLICY_API_ROUTES,
|
PACKAGE_POLICY_API_ROUTES,
|
||||||
SETUP_API_ROUTE,
|
SETUP_API_ROUTE,
|
||||||
|
PACKAGE_POLICY_SAVED_OBJECT_TYPE,
|
||||||
} from '@kbn/fleet-plugin/common';
|
} from '@kbn/fleet-plugin/common';
|
||||||
import type { ToolingLog } from '@kbn/tooling-log';
|
import type { ToolingLog } from '@kbn/tooling-log';
|
||||||
import type { KbnClient } from '@kbn/test';
|
import type { KbnClient } from '@kbn/test';
|
||||||
|
@ -54,6 +56,7 @@ import type {
|
||||||
GetEnrollmentAPIKeysResponse,
|
GetEnrollmentAPIKeysResponse,
|
||||||
GetOutputsResponse,
|
GetOutputsResponse,
|
||||||
PostAgentUnenrollResponse,
|
PostAgentUnenrollResponse,
|
||||||
|
CopyAgentPolicyRequest,
|
||||||
} from '@kbn/fleet-plugin/common/types';
|
} from '@kbn/fleet-plugin/common/types';
|
||||||
import nodeFetch from 'node-fetch';
|
import nodeFetch from 'node-fetch';
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
|
@ -79,6 +82,14 @@ const DEFAULT_AGENT_POLICY_NAME = `${CURRENT_USERNAME} test policy`;
|
||||||
/** A Fleet agent policy that includes integrations that don't actually require an agent to run on a host. Example: SenttinelOne */
|
/** A Fleet agent policy that includes integrations that don't actually require an agent to run on a host. Example: SenttinelOne */
|
||||||
export const DEFAULT_AGENTLESS_INTEGRATIONS_AGENT_POLICY_NAME = `${CURRENT_USERNAME} - agentless integrations`;
|
export const DEFAULT_AGENTLESS_INTEGRATIONS_AGENT_POLICY_NAME = `${CURRENT_USERNAME} - agentless integrations`;
|
||||||
|
|
||||||
|
const randomAgentPolicyName = (() => {
|
||||||
|
let counter = fleetGenerator.randomN(100);
|
||||||
|
|
||||||
|
return (): string => {
|
||||||
|
return `agent policy - ${fleetGenerator.randomString(10)}_${counter++}`;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
export const checkInFleetAgent = async (
|
export const checkInFleetAgent = async (
|
||||||
esClient: Client,
|
esClient: Client,
|
||||||
agentId: string,
|
agentId: string,
|
||||||
|
@ -753,6 +764,41 @@ export const enrollHostVmWithFleet = async ({
|
||||||
return waitForHostToEnroll(kbnClient, log, hostVm.name, timeoutMs);
|
return waitForHostToEnroll(kbnClient, log, hostVm.name, timeoutMs);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface CreateAgentPolicyOptions {
|
||||||
|
kbnClient: KbnClient;
|
||||||
|
policy?: CreateAgentPolicyRequest['body'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Agent Policy in fleet
|
||||||
|
* @param kbnClient
|
||||||
|
* @param log
|
||||||
|
* @param policy
|
||||||
|
*/
|
||||||
|
export const createAgentPolicy = async ({
|
||||||
|
kbnClient,
|
||||||
|
policy,
|
||||||
|
}: CreateAgentPolicyOptions): Promise<AgentPolicy> => {
|
||||||
|
const body: CreateAgentPolicyRequest['body'] = policy ?? {
|
||||||
|
name: randomAgentPolicyName(),
|
||||||
|
description: `Policy created by security solution tooling: ${__filename}`,
|
||||||
|
namespace: 'default',
|
||||||
|
monitoring_enabled: ['logs', 'metrics'],
|
||||||
|
};
|
||||||
|
|
||||||
|
return kbnClient
|
||||||
|
.request<CreateAgentPolicyResponse>({
|
||||||
|
path: AGENT_POLICY_API_ROUTES.CREATE_PATTERN,
|
||||||
|
headers: {
|
||||||
|
'elastic-api-version': API_VERSIONS.public.v1,
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
body,
|
||||||
|
})
|
||||||
|
.then((response) => response.data.item)
|
||||||
|
.catch(catchAxiosErrorFormatAndThrow);
|
||||||
|
};
|
||||||
|
|
||||||
interface GetOrCreateDefaultAgentPolicyOptions {
|
interface GetOrCreateDefaultAgentPolicyOptions {
|
||||||
kbnClient: KbnClient;
|
kbnClient: KbnClient;
|
||||||
log: ToolingLog;
|
log: ToolingLog;
|
||||||
|
@ -784,24 +830,15 @@ export const getOrCreateDefaultAgentPolicy = async ({
|
||||||
|
|
||||||
log.info(`Creating default test/dev Fleet agent policy with name: [${policyName}]`);
|
log.info(`Creating default test/dev Fleet agent policy with name: [${policyName}]`);
|
||||||
|
|
||||||
const newAgentPolicyData: CreateAgentPolicyRequest['body'] = {
|
const newAgentPolicy = await createAgentPolicy({
|
||||||
|
kbnClient,
|
||||||
|
policy: {
|
||||||
name: policyName,
|
name: policyName,
|
||||||
description: `Policy created by security solution tooling: ${__filename}`,
|
description: `Policy created by security solution tooling: ${__filename}`,
|
||||||
namespace: 'default',
|
namespace: 'default',
|
||||||
monitoring_enabled: ['logs', 'metrics'],
|
monitoring_enabled: ['logs', 'metrics'],
|
||||||
};
|
|
||||||
|
|
||||||
const newAgentPolicy = await kbnClient
|
|
||||||
.request<CreateAgentPolicyResponse>({
|
|
||||||
path: AGENT_POLICY_API_ROUTES.CREATE_PATTERN,
|
|
||||||
headers: {
|
|
||||||
'elastic-api-version': API_VERSIONS.public.v1,
|
|
||||||
},
|
},
|
||||||
method: 'POST',
|
});
|
||||||
body: newAgentPolicyData,
|
|
||||||
})
|
|
||||||
.then((response) => response.data.item)
|
|
||||||
.catch(catchAxiosErrorFormatAndThrow);
|
|
||||||
|
|
||||||
log.verbose(newAgentPolicy);
|
log.verbose(newAgentPolicy);
|
||||||
|
|
||||||
|
@ -1182,6 +1219,40 @@ export const addEndpointIntegrationToAgentPolicy = async ({
|
||||||
return newIntegrationPolicy;
|
return newIntegrationPolicy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type CopyAgentPolicyOptions = Partial<CopyAgentPolicyRequest['body']> & {
|
||||||
|
kbnClient: KbnClient;
|
||||||
|
agentPolicyId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy (clone) a Fleet Agent Policy
|
||||||
|
* @param kbnClient
|
||||||
|
* @param agentPolicyId
|
||||||
|
* @param name
|
||||||
|
* @param description
|
||||||
|
*/
|
||||||
|
export const copyAgentPolicy = async ({
|
||||||
|
kbnClient,
|
||||||
|
agentPolicyId,
|
||||||
|
name = randomAgentPolicyName(),
|
||||||
|
description,
|
||||||
|
}: CopyAgentPolicyOptions) => {
|
||||||
|
return kbnClient
|
||||||
|
.request<CopyAgentPolicyResponse>({
|
||||||
|
path: agentPolicyRouteService.getCopyPath(agentPolicyId),
|
||||||
|
headers: {
|
||||||
|
'elastic-api-version': API_VERSIONS.public.v1,
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
body: {
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => response.data.item)
|
||||||
|
.catch(catchAxiosErrorFormatAndThrow);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the fleet setup API to ensure fleet configured with default settings
|
* Calls the fleet setup API to ensure fleet configured with default settings
|
||||||
* @param kbnClient
|
* @param kbnClient
|
||||||
|
@ -1205,3 +1276,45 @@ export const ensureFleetSetup = memoize(
|
||||||
return setupResponse.data;
|
return setupResponse.data;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a list of Endpoint Integration policies from fleet
|
||||||
|
* @param kbnClient
|
||||||
|
* @param kuery
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
export const fetchEndpointIntegrationPolicyList = async (
|
||||||
|
kbnClient: KbnClient,
|
||||||
|
{ kuery, ...options }: GetPackagePoliciesRequest['query'] = {}
|
||||||
|
) => {
|
||||||
|
const endpointPackageMatchValue = `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`;
|
||||||
|
|
||||||
|
return fetchIntegrationPolicyList(kbnClient, {
|
||||||
|
...options,
|
||||||
|
kuery: kuery ? `${kuery} AND ${endpointPackageMatchValue}` : endpointPackageMatchValue,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all Endpoint Integration policy IDs - but only up to 10k
|
||||||
|
* @param kbnClient
|
||||||
|
*/
|
||||||
|
export const fetchAllEndpointIntegrationPolicyListIds = async (
|
||||||
|
kbnClient: KbnClient
|
||||||
|
): Promise<string[]> => {
|
||||||
|
const perPage = 1000;
|
||||||
|
const policyIds = [];
|
||||||
|
let hasMoreData = true;
|
||||||
|
|
||||||
|
do {
|
||||||
|
const result = await fetchEndpointIntegrationPolicyList(kbnClient, { perPage });
|
||||||
|
policyIds.push(...result.items.map((policy) => policy.id));
|
||||||
|
|
||||||
|
// If no more results or the next page of content goes over 10k, then end loop here.
|
||||||
|
if (!result.items.length || policyIds.length + perPage < 10000) {
|
||||||
|
hasMoreData = false;
|
||||||
|
}
|
||||||
|
} while (hasMoreData);
|
||||||
|
|
||||||
|
return policyIds;
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { run } from '@kbn/dev-cli-runner';
|
||||||
|
import { HORIZONTAL_LINE } from '../common/constants';
|
||||||
|
import { createKbnClient } from '../common/stack_services';
|
||||||
|
import { load } from './src/load';
|
||||||
|
import { createToolingLogger } from '../../../common/endpoint/data_loaders/utils';
|
||||||
|
|
||||||
|
export const cli = () => {
|
||||||
|
run(
|
||||||
|
async (cliContext) => {
|
||||||
|
createToolingLogger.setDefaultLogLevelFromCliFlags(cliContext.flags);
|
||||||
|
|
||||||
|
const log = cliContext.log;
|
||||||
|
const kbnClient = createKbnClient({
|
||||||
|
log,
|
||||||
|
url: cliContext.flags.kibana as string,
|
||||||
|
username: cliContext.flags.username as string,
|
||||||
|
password: cliContext.flags.password as string,
|
||||||
|
noCertForSsl: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
policyCount: Number(cliContext.flags.policyCount),
|
||||||
|
trustedAppsCount: Number(cliContext.flags.trustedAppsCount),
|
||||||
|
eventFiltersCount: Number(cliContext.flags.eventFiltersCount),
|
||||||
|
blocklistsCount: Number(cliContext.flags.blocklistsCount),
|
||||||
|
hostIsolationExceptionsCount: Number(cliContext.flags.hostIsolationExceptionsCount),
|
||||||
|
endpointExceptionsCount: Number(cliContext.flags.endpointExceptionsCount),
|
||||||
|
globalArtifactRatio: Number(cliContext.flags.globalArtifactRatio),
|
||||||
|
concurrency: Number(cliContext.flags.concurrency),
|
||||||
|
};
|
||||||
|
|
||||||
|
log.info(`${HORIZONTAL_LINE}
|
||||||
|
Environment Data Loader
|
||||||
|
${HORIZONTAL_LINE}
|
||||||
|
`);
|
||||||
|
log.info(`Loading data to: ${kbnClient.resolveUrl('')}`);
|
||||||
|
|
||||||
|
await load({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Options
|
||||||
|
{
|
||||||
|
description: `Loads data into a environment for testing/development`,
|
||||||
|
flags: {
|
||||||
|
string: ['kibana', 'username', 'password'],
|
||||||
|
default: {
|
||||||
|
kibana: 'http://127.0.0.1:5601',
|
||||||
|
username: 'elastic',
|
||||||
|
password: 'changeme',
|
||||||
|
policyCount: 10,
|
||||||
|
trustedAppsCount: 10,
|
||||||
|
eventFiltersCount: 10,
|
||||||
|
blocklistsCount: 10,
|
||||||
|
hostIsolationExceptionsCount: 10,
|
||||||
|
endpointExceptionsCount: 10,
|
||||||
|
globalArtifactRatio: 50,
|
||||||
|
concurrency: 10,
|
||||||
|
},
|
||||||
|
allowUnexpected: false,
|
||||||
|
help: `
|
||||||
|
--username User name to be used for auth against elasticsearch and
|
||||||
|
kibana (Default: elastic).
|
||||||
|
--password User name Password (Default: changeme)
|
||||||
|
--kibana The url to Kibana (Default: http://127.0.0.1:5601)
|
||||||
|
--policyCount How many policies to create (Default: 10)
|
||||||
|
--trustedAppsCount How many Trusted Applications to create (Default: 10)
|
||||||
|
--eventFiltersCount How many Event Filters to create (Default: 10)
|
||||||
|
--blocklistsCount How many Blocklists to create (Default: 10)
|
||||||
|
--hostIsolationExceptionsCount How many Host Isolation Exceptions to create (Default: 10)
|
||||||
|
--endpointExceptionsCount How many Endpoint Exceptions to create (Default: 10)
|
||||||
|
--globalArtifactRatio The percentage ratio of all artifacts that should be global
|
||||||
|
rather than per-policy. (Default: 50)
|
||||||
|
--concurrency The max number of request to process in parallel. (Default: 10)
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,296 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { KbnClient } from '@kbn/test';
|
||||||
|
import type { ToolingLog } from '@kbn/tooling-log';
|
||||||
|
import { BaseDataGenerator } from '../../../../common/endpoint/data_generators/base_data_generator';
|
||||||
|
import type { NewTrustedApp } from '../../../../common/endpoint/types';
|
||||||
|
import { stringify } from '../../../../server/endpoint/utils/stringify';
|
||||||
|
import { EndpointExceptionsGenerator } from '../../../../common/endpoint/data_generators/endpoint_exceptions_generator';
|
||||||
|
import {
|
||||||
|
BY_POLICY_ARTIFACT_TAG_PREFIX,
|
||||||
|
GLOBAL_ARTIFACT_TAG,
|
||||||
|
} from '../../../../common/endpoint/service/artifacts';
|
||||||
|
import { ExceptionsListItemGenerator } from '../../../../common/endpoint/data_generators/exceptions_list_item_generator';
|
||||||
|
import type { ExecutionThrottler } from '../../common/execution_throttler';
|
||||||
|
import { EventFiltersGenerator } from '../../../../common/endpoint/data_generators/event_filters_generator';
|
||||||
|
import { TrustedAppGenerator } from '../../../../common/endpoint/data_generators/trusted_app_generator';
|
||||||
|
import {
|
||||||
|
createBlocklist,
|
||||||
|
createEventFilter,
|
||||||
|
createHostIsolationException,
|
||||||
|
createTrustedApp,
|
||||||
|
} from '../../common/endpoint_artifact_services';
|
||||||
|
import type { ReportProgressCallback } from './types';
|
||||||
|
import { loop } from './utils';
|
||||||
|
|
||||||
|
interface ArtifactCreationOptions {
|
||||||
|
kbnClient: KbnClient;
|
||||||
|
log: ToolingLog;
|
||||||
|
count: number;
|
||||||
|
policyIds: string[];
|
||||||
|
reportProgress: ReportProgressCallback;
|
||||||
|
globalArtifactRatio: number;
|
||||||
|
throttler: ExecutionThrottler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class instance that exposes protected methods for use locally in this module
|
||||||
|
const gen = new (class extends BaseDataGenerator {
|
||||||
|
public randomArray<T>(lengthLimit: number, generator: () => T): T[] {
|
||||||
|
return super.randomArray(lengthLimit, generator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public randomChoice<T>(choices: T[] | readonly T[]): T {
|
||||||
|
return super.randomChoice(choices);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
const generatePerPolicyEffectiveScope = (policyIds: string[]): string[] => {
|
||||||
|
return gen.randomArray(
|
||||||
|
gen.randomN(Math.min(100, policyIds.length)),
|
||||||
|
() => `${BY_POLICY_ARTIFACT_TAG_PREFIX}${gen.randomChoice(policyIds)}`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const logError = (log: ToolingLog, artifactType: string, error: Error) => {
|
||||||
|
log.error(`[${artifactType}] error: ${error.message}`);
|
||||||
|
log.verbose(stringify(error));
|
||||||
|
};
|
||||||
|
|
||||||
|
const calculateGlobalAndPerPolicyCounts = (
|
||||||
|
total: number,
|
||||||
|
globalRatio: number
|
||||||
|
): { global: number; perPolicy: number } => {
|
||||||
|
const response = {
|
||||||
|
global: 0,
|
||||||
|
perPolicy: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
response.global = Math.floor(total * (globalRatio / 100));
|
||||||
|
|
||||||
|
// If a ratio was defined, then ensure at least one is created
|
||||||
|
if (globalRatio > 0 && response.global === 0) {
|
||||||
|
response.global = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.perPolicy = total - response.global;
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createTrustedApps = async ({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
count,
|
||||||
|
reportProgress,
|
||||||
|
throttler,
|
||||||
|
globalArtifactRatio,
|
||||||
|
policyIds,
|
||||||
|
}: ArtifactCreationOptions): Promise<void> => {
|
||||||
|
const generator = new TrustedAppGenerator();
|
||||||
|
const { global: globalCount, perPolicy } = calculateGlobalAndPerPolicyCounts(
|
||||||
|
count,
|
||||||
|
globalArtifactRatio
|
||||||
|
);
|
||||||
|
let globalDone = 0;
|
||||||
|
let doneCount = 0;
|
||||||
|
let errorCount = 0;
|
||||||
|
|
||||||
|
log.info(`Trusted Apps: Creating ${globalCount} global and ${perPolicy} per-policy artifacts`);
|
||||||
|
|
||||||
|
loop(count, () => {
|
||||||
|
throttler.addToQueue(async () => {
|
||||||
|
let effectScope: NewTrustedApp['effectScope'] = { type: 'global' };
|
||||||
|
|
||||||
|
if (globalDone < globalCount) {
|
||||||
|
globalDone++;
|
||||||
|
} else {
|
||||||
|
effectScope = {
|
||||||
|
type: 'policy',
|
||||||
|
policies: gen.randomArray(gen.randomN(Math.min(100, policyIds.length)), () =>
|
||||||
|
gen.randomChoice(policyIds)
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
await createTrustedApp(
|
||||||
|
kbnClient,
|
||||||
|
generator.generateTrustedAppForCreate({
|
||||||
|
effectScope,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.catch((e) => {
|
||||||
|
errorCount++;
|
||||||
|
logError(log, 'Trusted Application', e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
doneCount++;
|
||||||
|
reportProgress({ doneCount, errorCount });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createEventFilters = async ({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
count,
|
||||||
|
reportProgress,
|
||||||
|
throttler,
|
||||||
|
globalArtifactRatio,
|
||||||
|
policyIds,
|
||||||
|
}: ArtifactCreationOptions): Promise<void> => {
|
||||||
|
const eventGenerator = new EventFiltersGenerator();
|
||||||
|
const { global: globalCount, perPolicy } = calculateGlobalAndPerPolicyCounts(
|
||||||
|
count,
|
||||||
|
globalArtifactRatio
|
||||||
|
);
|
||||||
|
let globalDone = 0;
|
||||||
|
let doneCount = 0;
|
||||||
|
let errorCount = 0;
|
||||||
|
|
||||||
|
log.info(`Event Filters: Creating ${globalCount} global and ${perPolicy} per-policy artifacts`);
|
||||||
|
|
||||||
|
loop(count, () => {
|
||||||
|
throttler.addToQueue(async () => {
|
||||||
|
let tags = [GLOBAL_ARTIFACT_TAG];
|
||||||
|
|
||||||
|
if (globalDone < globalCount) {
|
||||||
|
globalDone++;
|
||||||
|
} else {
|
||||||
|
tags = generatePerPolicyEffectiveScope(policyIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
await createEventFilter(kbnClient, eventGenerator.generateEventFilterForCreate({ tags }))
|
||||||
|
.catch((e) => {
|
||||||
|
errorCount++;
|
||||||
|
logError(log, 'Event Filter', e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
doneCount++;
|
||||||
|
reportProgress({ doneCount, errorCount });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createBlocklists = async ({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
count,
|
||||||
|
reportProgress,
|
||||||
|
throttler,
|
||||||
|
policyIds,
|
||||||
|
globalArtifactRatio,
|
||||||
|
}: ArtifactCreationOptions): Promise<void> => {
|
||||||
|
const generate = new ExceptionsListItemGenerator();
|
||||||
|
const { global: globalCount, perPolicy } = calculateGlobalAndPerPolicyCounts(
|
||||||
|
count,
|
||||||
|
globalArtifactRatio
|
||||||
|
);
|
||||||
|
let globalDone = 0;
|
||||||
|
let doneCount = 0;
|
||||||
|
let errorCount = 0;
|
||||||
|
|
||||||
|
log.info(`Blocklists: Creating ${globalCount} global and ${perPolicy} per-policy artifacts`);
|
||||||
|
|
||||||
|
loop(count, () => {
|
||||||
|
throttler.addToQueue(async () => {
|
||||||
|
let tags = [GLOBAL_ARTIFACT_TAG];
|
||||||
|
|
||||||
|
if (globalDone < globalCount) {
|
||||||
|
globalDone++;
|
||||||
|
} else {
|
||||||
|
tags = generatePerPolicyEffectiveScope(policyIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
await createBlocklist(kbnClient, generate.generateBlocklistForCreate({ tags }))
|
||||||
|
.catch((e) => {
|
||||||
|
errorCount++;
|
||||||
|
logError(log, 'BLocklist', e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
doneCount++;
|
||||||
|
reportProgress({ doneCount, errorCount });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createHostIsolationExceptions = async ({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
count,
|
||||||
|
reportProgress,
|
||||||
|
throttler,
|
||||||
|
globalArtifactRatio,
|
||||||
|
policyIds,
|
||||||
|
}: ArtifactCreationOptions): Promise<void> => {
|
||||||
|
const generate = new ExceptionsListItemGenerator();
|
||||||
|
const { global: globalCount, perPolicy } = calculateGlobalAndPerPolicyCounts(
|
||||||
|
count,
|
||||||
|
globalArtifactRatio
|
||||||
|
);
|
||||||
|
let globalDone = 0;
|
||||||
|
let doneCount = 0;
|
||||||
|
let errorCount = 0;
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
`Host Isolation Exceptions: Creating ${globalCount} global and ${perPolicy} per-policy artifacts`
|
||||||
|
);
|
||||||
|
|
||||||
|
loop(count, () => {
|
||||||
|
throttler.addToQueue(async () => {
|
||||||
|
let tags = [GLOBAL_ARTIFACT_TAG];
|
||||||
|
|
||||||
|
if (globalDone < globalCount) {
|
||||||
|
globalDone++;
|
||||||
|
} else {
|
||||||
|
tags = generatePerPolicyEffectiveScope(policyIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
await createHostIsolationException(
|
||||||
|
kbnClient,
|
||||||
|
generate.generateHostIsolationExceptionForCreate({ tags })
|
||||||
|
)
|
||||||
|
.catch((e) => {
|
||||||
|
errorCount++;
|
||||||
|
logError(log, 'Host Isolation Exception', e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
doneCount++;
|
||||||
|
reportProgress({ doneCount, errorCount });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createEndpointExceptions = async ({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
count,
|
||||||
|
reportProgress,
|
||||||
|
throttler,
|
||||||
|
}: ArtifactCreationOptions): Promise<void> => {
|
||||||
|
const generate = new EndpointExceptionsGenerator();
|
||||||
|
let doneCount = 0;
|
||||||
|
let errorCount = 0;
|
||||||
|
|
||||||
|
loop(count, () => {
|
||||||
|
throttler.addToQueue(async () => {
|
||||||
|
await createHostIsolationException(kbnClient, generate.generateEndpointExceptionForCreate())
|
||||||
|
.catch((e) => {
|
||||||
|
errorCount++;
|
||||||
|
logError(log, 'Endpoint Exception', e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
doneCount++;
|
||||||
|
reportProgress({ doneCount, errorCount });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { KbnClient } from '@kbn/test';
|
||||||
|
import type { ToolingLog } from '@kbn/tooling-log';
|
||||||
|
import { loop } from './utils';
|
||||||
|
import type { ExecutionThrottler } from '../../common/execution_throttler';
|
||||||
|
import {
|
||||||
|
addEndpointIntegrationToAgentPolicy,
|
||||||
|
copyAgentPolicy,
|
||||||
|
createAgentPolicy,
|
||||||
|
} from '../../common/fleet_services';
|
||||||
|
import type { ReportProgressCallback } from './types';
|
||||||
|
|
||||||
|
interface CreatePoliciesOptions {
|
||||||
|
kbnClient: KbnClient;
|
||||||
|
log: ToolingLog;
|
||||||
|
count: number;
|
||||||
|
reportProgress: ReportProgressCallback;
|
||||||
|
throttler: ExecutionThrottler;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createPolicies = async ({
|
||||||
|
kbnClient,
|
||||||
|
count,
|
||||||
|
reportProgress,
|
||||||
|
log,
|
||||||
|
throttler,
|
||||||
|
}: CreatePoliciesOptions): Promise<string[]> => {
|
||||||
|
const endpointIntegrationPolicyIds: string[] = [];
|
||||||
|
const errors: Error[] = [];
|
||||||
|
let doneCount = 0;
|
||||||
|
|
||||||
|
log.verbose(`creating [${count}] policies in fleet`);
|
||||||
|
|
||||||
|
// Create first policy with endpoint
|
||||||
|
const agentPolicyId = (await createAgentPolicy({ kbnClient })).id;
|
||||||
|
const endpointPolicy = await addEndpointIntegrationToAgentPolicy({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
agentPolicyId,
|
||||||
|
name: `endpoint protect policy (${Math.random().toString(32).substring(2)})`,
|
||||||
|
});
|
||||||
|
|
||||||
|
endpointIntegrationPolicyIds.push(endpointPolicy.id);
|
||||||
|
doneCount++;
|
||||||
|
reportProgress({ doneCount, errorCount: errors.length });
|
||||||
|
|
||||||
|
// TODO:PT maybe use ES bulk create and bypass fleet so that we speed this up?
|
||||||
|
|
||||||
|
loop(count - 1, () => {
|
||||||
|
throttler.addToQueue(async () => {
|
||||||
|
await copyAgentPolicy({ kbnClient, agentPolicyId })
|
||||||
|
.then((response) => {
|
||||||
|
if (response.package_policies?.[0]) {
|
||||||
|
endpointIntegrationPolicyIds.push(response.package_policies[0].id);
|
||||||
|
} else {
|
||||||
|
errors.push(
|
||||||
|
new Error(
|
||||||
|
`Copy of agent policy [${agentPolicyId}] did not copy the Endpoint Integration!`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
errors.push(e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
doneCount++;
|
||||||
|
reportProgress({ doneCount, errorCount: errors.length });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await throttler.complete();
|
||||||
|
|
||||||
|
if (errors.length) {
|
||||||
|
log.error(
|
||||||
|
`${errors.length} errors encountered while trying to create policies. First error: ${errors[0].message}`
|
||||||
|
);
|
||||||
|
log.verbose(...errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpointIntegrationPolicyIds;
|
||||||
|
};
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ToolingLog } from '@kbn/tooling-log';
|
||||||
|
import type { KbnClient } from '@kbn/test';
|
||||||
|
import { fetchAllEndpointIntegrationPolicyListIds } from '../../common/fleet_services';
|
||||||
|
import { ExecutionThrottler } from '../../common/execution_throttler';
|
||||||
|
import {
|
||||||
|
createBlocklists,
|
||||||
|
createEndpointExceptions,
|
||||||
|
createEventFilters,
|
||||||
|
createHostIsolationExceptions,
|
||||||
|
createTrustedApps,
|
||||||
|
} from './create_artifacts';
|
||||||
|
import { installOrUpgradeEndpointFleetPackage } from '../../../../common/endpoint/data_loaders/setup_fleet_for_endpoint';
|
||||||
|
import { ProgressReporter } from './progress_reporter';
|
||||||
|
import type { ProgressReporterInterface } from './types';
|
||||||
|
import { createPolicies } from './create_policies';
|
||||||
|
import { createToolingLogger } from '../../../../common/endpoint/data_loaders/utils';
|
||||||
|
|
||||||
|
interface LoadOptions {
|
||||||
|
kbnClient: KbnClient;
|
||||||
|
log?: ToolingLog;
|
||||||
|
policyCount: number;
|
||||||
|
trustedAppsCount: number;
|
||||||
|
eventFiltersCount: number;
|
||||||
|
blocklistsCount: number;
|
||||||
|
hostIsolationExceptionsCount: number;
|
||||||
|
endpointExceptionsCount: number;
|
||||||
|
globalArtifactRatio: number;
|
||||||
|
concurrency: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const load = async ({
|
||||||
|
kbnClient,
|
||||||
|
log = createToolingLogger(),
|
||||||
|
policyCount,
|
||||||
|
trustedAppsCount,
|
||||||
|
eventFiltersCount,
|
||||||
|
blocklistsCount,
|
||||||
|
hostIsolationExceptionsCount,
|
||||||
|
endpointExceptionsCount,
|
||||||
|
globalArtifactRatio,
|
||||||
|
concurrency,
|
||||||
|
}: LoadOptions) => {
|
||||||
|
const throttler = new ExecutionThrottler({ log, concurrency });
|
||||||
|
const reportProgress: ProgressReporterInterface = new ProgressReporter({
|
||||||
|
reportStatus: (status) => {
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
log.info(`__
|
||||||
|
Status at: ${now.toString()}
|
||||||
|
${status}\nRequests pending: ${throttler.getStats().pending}
|
||||||
|
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const policyReporter = reportProgress.addCategory('policies', policyCount);
|
||||||
|
const trustedAppsReporter = reportProgress.addCategory('trusted apps', trustedAppsCount);
|
||||||
|
const eventFiltersReporter = reportProgress.addCategory('event filters', eventFiltersCount);
|
||||||
|
const blocklistsReporter = reportProgress.addCategory('blocklists', blocklistsCount);
|
||||||
|
const hostIsolationExceptionsReporter = reportProgress.addCategory(
|
||||||
|
'host isolation exceptions',
|
||||||
|
hostIsolationExceptionsCount
|
||||||
|
);
|
||||||
|
const endpointExceptionsReporter = reportProgress.addCategory(
|
||||||
|
'endpoint exceptions',
|
||||||
|
endpointExceptionsCount
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ensure fleet is setup with endpoint (which also creates the DS/Transforms, etc)
|
||||||
|
await installOrUpgradeEndpointFleetPackage(kbnClient, log);
|
||||||
|
|
||||||
|
const endpointPolicyIds = policyCount
|
||||||
|
? await createPolicies({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
count: policyCount,
|
||||||
|
reportProgress: policyReporter,
|
||||||
|
throttler,
|
||||||
|
})
|
||||||
|
: await fetchAllEndpointIntegrationPolicyListIds(kbnClient);
|
||||||
|
|
||||||
|
log?.verbose(`Policy IDs:\n${endpointPolicyIds.join('\n')}`);
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
trustedAppsCount &&
|
||||||
|
createTrustedApps({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
reportProgress: trustedAppsReporter,
|
||||||
|
count: trustedAppsCount,
|
||||||
|
policyIds: endpointPolicyIds,
|
||||||
|
globalArtifactRatio,
|
||||||
|
throttler,
|
||||||
|
}),
|
||||||
|
|
||||||
|
eventFiltersCount &&
|
||||||
|
createEventFilters({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
reportProgress: eventFiltersReporter,
|
||||||
|
count: eventFiltersCount,
|
||||||
|
policyIds: endpointPolicyIds,
|
||||||
|
globalArtifactRatio,
|
||||||
|
throttler,
|
||||||
|
}),
|
||||||
|
|
||||||
|
blocklistsCount &&
|
||||||
|
createBlocklists({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
reportProgress: blocklistsReporter,
|
||||||
|
count: blocklistsCount,
|
||||||
|
policyIds: endpointPolicyIds,
|
||||||
|
globalArtifactRatio,
|
||||||
|
throttler,
|
||||||
|
}),
|
||||||
|
|
||||||
|
hostIsolationExceptionsCount &&
|
||||||
|
createHostIsolationExceptions({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
reportProgress: hostIsolationExceptionsReporter,
|
||||||
|
count: hostIsolationExceptionsCount,
|
||||||
|
policyIds: endpointPolicyIds,
|
||||||
|
globalArtifactRatio,
|
||||||
|
throttler,
|
||||||
|
}),
|
||||||
|
|
||||||
|
endpointExceptionsCount &&
|
||||||
|
createEndpointExceptions({
|
||||||
|
kbnClient,
|
||||||
|
log,
|
||||||
|
reportProgress: endpointExceptionsReporter,
|
||||||
|
count: endpointExceptionsCount,
|
||||||
|
policyIds: endpointPolicyIds,
|
||||||
|
globalArtifactRatio,
|
||||||
|
throttler,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await throttler.complete();
|
||||||
|
reportProgress.stopReporting();
|
||||||
|
};
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { once } from 'lodash';
|
||||||
|
import { HORIZONTAL_LINE } from '../../common/constants';
|
||||||
|
import { getElapsedTime } from '../../../../common/endpoint/data_loaders/utils';
|
||||||
|
import type {
|
||||||
|
ProgressReporterInterface,
|
||||||
|
ProgressReporterState,
|
||||||
|
ReportProgressCallback,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
const NOOP = () => {};
|
||||||
|
|
||||||
|
interface ProgressReporterOptions {
|
||||||
|
/**
|
||||||
|
* If defined, this callback to be used in reporting status on an interval until
|
||||||
|
* the `doneCount` reaches the `totalCount` of all categories
|
||||||
|
* @param status
|
||||||
|
*/
|
||||||
|
reportStatus?: (status: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ProgressReporter implements ProgressReporterInterface {
|
||||||
|
private readonly reportIntervalMs = 20000;
|
||||||
|
private readonly startedAt: Date = new Date();
|
||||||
|
private categories: Record<
|
||||||
|
string,
|
||||||
|
{ totalCount: number; doneCount: number; errorCount: number }
|
||||||
|
> = {};
|
||||||
|
private stopReportingLoop: () => void = NOOP;
|
||||||
|
|
||||||
|
constructor(private readonly options: ProgressReporterOptions = {}) {
|
||||||
|
if (options.reportStatus) {
|
||||||
|
this.startReporting();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public startReporting() {
|
||||||
|
this.stopReportingLoop();
|
||||||
|
|
||||||
|
if (!this.options.reportStatus) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const setIntId = setInterval(() => {
|
||||||
|
if (this.options.reportStatus) {
|
||||||
|
this.options.reportStatus(this.getStatus());
|
||||||
|
|
||||||
|
if (this.getState().prctDone === 100) {
|
||||||
|
this.stopReportingLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, this.reportIntervalMs);
|
||||||
|
|
||||||
|
const exitEvCallback = () => this.stopReportingLoop();
|
||||||
|
|
||||||
|
this.stopReportingLoop = once(() => {
|
||||||
|
clearInterval(setIntId);
|
||||||
|
process.off('exit', exitEvCallback);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('exit', exitEvCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
stopReporting() {
|
||||||
|
this.stopReportingLoop();
|
||||||
|
|
||||||
|
if (this.options.reportStatus) {
|
||||||
|
this.options.reportStatus(this.getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addCategory(name: string, totalCount: number): ReportProgressCallback {
|
||||||
|
this.categories[name] = {
|
||||||
|
totalCount,
|
||||||
|
doneCount: 0,
|
||||||
|
errorCount: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.startReporting();
|
||||||
|
return this.getReporter(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
getReporter(categoryName: string): ReportProgressCallback {
|
||||||
|
if (!this.categories[categoryName]) {
|
||||||
|
throw new Error(`category name [${categoryName}] has not known`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (options) => {
|
||||||
|
this.categories[categoryName].doneCount = options.doneCount;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getState(): ProgressReporterState {
|
||||||
|
const state: ProgressReporterState = {
|
||||||
|
prctDone: 0,
|
||||||
|
totalCount: 0,
|
||||||
|
doneCount: 0,
|
||||||
|
errorCount: 0,
|
||||||
|
categories: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(this.categories).forEach(
|
||||||
|
([
|
||||||
|
categoryName,
|
||||||
|
{
|
||||||
|
totalCount: thisCategoryTotalCount,
|
||||||
|
doneCount: thisCategoryDoneCount,
|
||||||
|
errorCount: thisCategoryErrorCount,
|
||||||
|
},
|
||||||
|
]) => {
|
||||||
|
state.totalCount += thisCategoryTotalCount;
|
||||||
|
state.doneCount += thisCategoryDoneCount;
|
||||||
|
state.errorCount += thisCategoryErrorCount;
|
||||||
|
|
||||||
|
state.categories[categoryName] = {
|
||||||
|
totalCount: thisCategoryTotalCount,
|
||||||
|
doneCount: thisCategoryDoneCount,
|
||||||
|
errorCount: thisCategoryErrorCount,
|
||||||
|
prctDone: calculatePercentage(thisCategoryTotalCount, thisCategoryDoneCount),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
state.prctDone = calculatePercentage(state.totalCount, state.doneCount);
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStatus(): string {
|
||||||
|
const state = this.getState();
|
||||||
|
const categoryNamesMaxChr =
|
||||||
|
Object.keys(state.categories).reduce((acc, categoryName) => {
|
||||||
|
return Math.max(acc, categoryName.length);
|
||||||
|
}, 10) + 4;
|
||||||
|
|
||||||
|
return `${HORIZONTAL_LINE}
|
||||||
|
${'Overall Progress: '.padEnd(categoryNamesMaxChr + 4)}${state.prctDone}%
|
||||||
|
${HORIZONTAL_LINE}
|
||||||
|
${
|
||||||
|
'Elapsed Time (hh:mm:ss.ms):'.padEnd(categoryNamesMaxChr + 4) +
|
||||||
|
getElapsedTime(this.getStartedTime())
|
||||||
|
}
|
||||||
|
${'Error Count:'.padEnd(categoryNamesMaxChr + 4) + state.errorCount}
|
||||||
|
Details:
|
||||||
|
${Object.entries(state.categories).reduce((acc, [categoryName, categoryState]) => {
|
||||||
|
let updatedOutput = acc;
|
||||||
|
|
||||||
|
if (updatedOutput.length) {
|
||||||
|
updatedOutput += `\n `;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedOutput += `${`${`${categoryName}:`
|
||||||
|
.concat(' '.repeat(categoryNamesMaxChr))
|
||||||
|
.substring(0, categoryNamesMaxChr)} ${categoryState.prctDone}%`.padEnd(
|
||||||
|
categoryNamesMaxChr + 10
|
||||||
|
)}(${categoryState.doneCount} / ${categoryState.totalCount}, ${
|
||||||
|
categoryState.errorCount
|
||||||
|
} errors)`;
|
||||||
|
|
||||||
|
return updatedOutput;
|
||||||
|
}, '')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStartedTime(): Date {
|
||||||
|
return new Date(this.startedAt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const calculatePercentage = (totalCount: number, doneCount: number): number => {
|
||||||
|
if (totalCount <= 0 || doneCount <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.min(100, Number(((doneCount / totalCount) * 100).toPrecision(3)));
|
||||||
|
};
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type ReportProgressCallback = (options: { doneCount: number; errorCount: number }) => void;
|
||||||
|
|
||||||
|
interface ProgressReporterStateProperties {
|
||||||
|
prctDone: number;
|
||||||
|
totalCount: number;
|
||||||
|
doneCount: number;
|
||||||
|
errorCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProgressReporterState extends ProgressReporterStateProperties {
|
||||||
|
categories: Record<string, ProgressReporterStateProperties>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProgressReporterInterface {
|
||||||
|
addCategory(name: string, totalCount: number): ReportProgressCallback;
|
||||||
|
|
||||||
|
getReporter(categoryName: string): ReportProgressCallback;
|
||||||
|
|
||||||
|
getState(): ProgressReporterState;
|
||||||
|
|
||||||
|
getStatus(): string;
|
||||||
|
|
||||||
|
getStartedTime(): Date;
|
||||||
|
|
||||||
|
startReporting(): void;
|
||||||
|
|
||||||
|
stopReporting(): void;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
export const loop = (count: number, callback: (instance: number) => any): void => {
|
||||||
|
let done = 1;
|
||||||
|
|
||||||
|
while (done <= count) {
|
||||||
|
try {
|
||||||
|
callback(done++);
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
require('../../../../../src/setup_node_env');
|
||||||
|
require('./env_data_loader').cli();
|
Loading…
Add table
Add a link
Reference in a new issue