mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Cloud Security] [Telemetry] Add Alerts Telemetry (#163907)
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
cfe7cabf86
commit
ff2e7a8c8f
6 changed files with 285 additions and 18 deletions
|
@ -136,3 +136,5 @@ export const AWS_CREDENTIALS_TYPE_TO_FIELDS_MAP: AwsCredentialsTypeFieldMap = {
|
|||
|
||||
export const SETUP_ACCESS_CLOUD_SHELL = 'google_cloud_shell';
|
||||
export const SETUP_ACCESS_MANUAL = 'manual';
|
||||
|
||||
export const DETECTION_ENGINE_ALERTS_INDEX_DEFAULT = '.alerts-security.alerts-default';
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* 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 { Logger } from '@kbn/core/server';
|
||||
import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
|
||||
import type { CloudSecurityAlertsStats } from './types';
|
||||
import { DETECTION_ENGINE_ALERTS_INDEX_DEFAULT } from '../../../../common/constants';
|
||||
|
||||
interface AlertsStats {
|
||||
aggregations: {
|
||||
cspm: {
|
||||
rules_count: {
|
||||
value: number;
|
||||
};
|
||||
alerts_open: {
|
||||
doc_count: number;
|
||||
};
|
||||
alerts_acknowledged: {
|
||||
doc_count: number;
|
||||
};
|
||||
alerts_closed: {
|
||||
doc_count: number;
|
||||
};
|
||||
};
|
||||
kspm: {
|
||||
rules_count: {
|
||||
value: number;
|
||||
};
|
||||
alerts_open: {
|
||||
doc_count: number;
|
||||
};
|
||||
alerts_acknowledged: {
|
||||
doc_count: number;
|
||||
};
|
||||
alerts_closed: {
|
||||
doc_count: number;
|
||||
};
|
||||
};
|
||||
vuln_mgmt: {
|
||||
rules_count: {
|
||||
value: number;
|
||||
};
|
||||
alerts_open: {
|
||||
doc_count: number;
|
||||
};
|
||||
alerts_acknowledged: {
|
||||
doc_count: number;
|
||||
};
|
||||
alerts_closed: {
|
||||
doc_count: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const getAlertsStatsQuery = (index: string) => ({
|
||||
size: 0,
|
||||
query: {
|
||||
bool: {
|
||||
filter: [{ term: { 'kibana.alert.rule.tags': 'Cloud Security' } }],
|
||||
},
|
||||
},
|
||||
sort: '@timestamp:desc',
|
||||
index,
|
||||
aggs: {
|
||||
cspm: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.rule.tags': 'CSPM',
|
||||
},
|
||||
},
|
||||
aggs: {
|
||||
rules_count: {
|
||||
cardinality: {
|
||||
field: 'kibana.alert.rule.uuid',
|
||||
},
|
||||
},
|
||||
alerts_open: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.workflow_status': 'open',
|
||||
},
|
||||
},
|
||||
},
|
||||
alerts_acknowledged: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.workflow_status': 'acknowledged',
|
||||
},
|
||||
},
|
||||
},
|
||||
alerts_closed: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.workflow_status': 'closed',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
kspm: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.rule.tags': 'KSPM',
|
||||
},
|
||||
},
|
||||
aggs: {
|
||||
rules_count: {
|
||||
cardinality: {
|
||||
field: 'kibana.alert.rule.uuid',
|
||||
},
|
||||
},
|
||||
alerts_open: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.workflow_status': 'open',
|
||||
},
|
||||
},
|
||||
},
|
||||
alerts_acknowledged: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.workflow_status': 'acknowledged',
|
||||
},
|
||||
},
|
||||
},
|
||||
alerts_closed: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.workflow_status': 'closed',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
vuln_mgmt: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.rule.tags': 'CNVM',
|
||||
},
|
||||
},
|
||||
aggs: {
|
||||
rules_count: {
|
||||
cardinality: {
|
||||
field: 'kibana.alert.rule.uuid',
|
||||
},
|
||||
},
|
||||
alerts_open: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.workflow_status': 'open',
|
||||
},
|
||||
},
|
||||
},
|
||||
alerts_acknowledged: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.workflow_status': 'acknowledged',
|
||||
},
|
||||
},
|
||||
},
|
||||
alerts_closed: {
|
||||
filter: {
|
||||
term: {
|
||||
'kibana.alert.workflow_status': 'closed',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const getAlertsStats = async (
|
||||
esClient: ElasticsearchClient,
|
||||
logger: Logger
|
||||
): Promise<CloudSecurityAlertsStats[]> => {
|
||||
const index = DETECTION_ENGINE_ALERTS_INDEX_DEFAULT;
|
||||
|
||||
try {
|
||||
const isIndexExists = await esClient.indices.exists({
|
||||
index,
|
||||
});
|
||||
|
||||
if (isIndexExists) {
|
||||
const alertsStats = await esClient.search<unknown, AlertsStats>(getAlertsStatsQuery(index));
|
||||
|
||||
const postureTypes = ['cspm', 'kspm', 'vuln_mgmt'] as const;
|
||||
|
||||
return postureTypes.map((postureType) => ({
|
||||
posture_type: postureType,
|
||||
rules_count: alertsStats.aggregations?.aggregations[postureType].rules_count.value,
|
||||
alerts_count: alertsStats.aggregations?.aggregations[postureType].alerts_open.doc_count,
|
||||
alerts_open_count:
|
||||
alertsStats.aggregations?.aggregations[postureType].alerts_open.doc_count,
|
||||
alerts_acknowledged_count:
|
||||
alertsStats.aggregations?.aggregations[postureType].alerts_acknowledged.doc_count,
|
||||
alerts_closed_count:
|
||||
alertsStats.aggregations?.aggregations[postureType].alerts_closed.doc_count,
|
||||
})) as CloudSecurityAlertsStats[];
|
||||
}
|
||||
return [];
|
||||
} catch (e) {
|
||||
logger.error(`Failed to get index stats for ${index}: ${e}`);
|
||||
return [];
|
||||
}
|
||||
};
|
|
@ -15,6 +15,7 @@ import { CspmUsage } from './types';
|
|||
import { getAccountsStats } from './accounts_stats_collector';
|
||||
import { getRulesStats } from './rules_stats_collector';
|
||||
import { getInstallationStats } from './installation_stats_collector';
|
||||
import { getAlertsStats } from './alert_stats_collector';
|
||||
|
||||
export function registerCspmUsageCollector(
|
||||
logger: Logger,
|
||||
|
@ -34,24 +35,31 @@ export function registerCspmUsageCollector(
|
|||
return true;
|
||||
},
|
||||
fetch: async (collectorFetchContext: CollectorFetchContext) => {
|
||||
const [indicesStats, accountsStats, resourcesStats, rulesStats, installationStats] =
|
||||
await Promise.all([
|
||||
getIndicesStats(
|
||||
collectorFetchContext.esClient,
|
||||
collectorFetchContext.soClient,
|
||||
coreServices,
|
||||
logger
|
||||
),
|
||||
getAccountsStats(collectorFetchContext.esClient, logger),
|
||||
getResourcesStats(collectorFetchContext.esClient, logger),
|
||||
getRulesStats(collectorFetchContext.esClient, logger),
|
||||
getInstallationStats(
|
||||
collectorFetchContext.esClient,
|
||||
collectorFetchContext.soClient,
|
||||
coreServices,
|
||||
logger
|
||||
),
|
||||
]);
|
||||
const [
|
||||
indicesStats,
|
||||
accountsStats,
|
||||
resourcesStats,
|
||||
rulesStats,
|
||||
installationStats,
|
||||
alertsStats,
|
||||
] = await Promise.all([
|
||||
getIndicesStats(
|
||||
collectorFetchContext.esClient,
|
||||
collectorFetchContext.soClient,
|
||||
coreServices,
|
||||
logger
|
||||
),
|
||||
getAccountsStats(collectorFetchContext.esClient, logger),
|
||||
getResourcesStats(collectorFetchContext.esClient, logger),
|
||||
getRulesStats(collectorFetchContext.esClient, logger),
|
||||
getInstallationStats(
|
||||
collectorFetchContext.esClient,
|
||||
collectorFetchContext.soClient,
|
||||
coreServices,
|
||||
logger
|
||||
),
|
||||
getAlertsStats(collectorFetchContext.esClient, logger),
|
||||
]);
|
||||
|
||||
return {
|
||||
indices: indicesStats,
|
||||
|
@ -59,6 +67,7 @@ export function registerCspmUsageCollector(
|
|||
resources_stats: resourcesStats,
|
||||
rules_stats: rulesStats,
|
||||
installation_stats: installationStats,
|
||||
alerts_stats: alertsStats,
|
||||
};
|
||||
},
|
||||
schema: cspmUsageSchema,
|
||||
|
|
|
@ -156,4 +156,15 @@ export const cspmUsageSchema: MakeSchemaFrom<CspmUsage> = {
|
|||
account_type: { type: 'keyword' },
|
||||
},
|
||||
},
|
||||
alerts_stats: {
|
||||
type: 'array',
|
||||
items: {
|
||||
posture_type: { type: 'keyword' },
|
||||
rules_count: { type: 'long' },
|
||||
alerts_count: { type: 'long' },
|
||||
alerts_open_count: { type: 'long' },
|
||||
alerts_closed_count: { type: 'long' },
|
||||
alerts_acknowledged_count: { type: 'long' },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@ export interface CspmUsage {
|
|||
accounts_stats: CspmAccountsStats[];
|
||||
rules_stats: CspmRulesStats[];
|
||||
installation_stats: CloudSecurityInstallationStats[];
|
||||
alerts_stats: CloudSecurityAlertsStats[];
|
||||
}
|
||||
|
||||
export interface PackageSetupStatus {
|
||||
|
@ -88,3 +89,12 @@ export interface CloudSecurityInstallationStats {
|
|||
agent_count: number;
|
||||
account_type?: 'single-account' | 'organization-account';
|
||||
}
|
||||
|
||||
export interface CloudSecurityAlertsStats {
|
||||
posture_type: string;
|
||||
rules_count: number;
|
||||
alerts_count: number;
|
||||
alerts_open_count: number;
|
||||
alerts_closed_count: number;
|
||||
alerts_acknowledged_count: number;
|
||||
}
|
||||
|
|
|
@ -6613,6 +6613,31 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"alerts_stats": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"properties": {
|
||||
"posture_type": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"rules_count": {
|
||||
"type": "long"
|
||||
},
|
||||
"alerts_count": {
|
||||
"type": "long"
|
||||
},
|
||||
"alerts_open_count": {
|
||||
"type": "long"
|
||||
},
|
||||
"alerts_closed_count": {
|
||||
"type": "long"
|
||||
},
|
||||
"alerts_acknowledged_count": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue