mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
# Backport This will backport the following commits from `main` to `8.7`: - [[Cloud Security] change `Belongs To` column to use runtime field (#151038)](https://github.com/elastic/kibana/pull/151038) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Jordan","email":"51442161+JordanSh@users.noreply.github.com"},"sourceCommit":{"committedDate":"2023-02-16T10:43:17Z","message":"[Cloud Security] change `Belongs To` column to use runtime field (#151038)","sha":"e974e53b3206031b101de4a843b713bdb349bcdf","branchLabelMapping":{"^v8.8.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Cloud Security","v8.7.0","v8.8.0"],"number":151038,"url":"https://github.com/elastic/kibana/pull/151038","mergeCommit":{"message":"[Cloud Security] change `Belongs To` column to use runtime field (#151038)","sha":"e974e53b3206031b101de4a843b713bdb349bcdf"}},"sourceBranch":"main","suggestedTargetBranches":["8.7"],"targetPullRequestStates":[{"branch":"8.7","label":"v8.7.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.8.0","labelRegex":"^v8.8.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/151038","number":151038,"mergeCommit":{"message":"[Cloud Security] change `Belongs To` column to use runtime field (#151038)","sha":"e974e53b3206031b101de4a843b713bdb349bcdf"}}]}] BACKPORT--> Co-authored-by: Jordan <51442161+JordanSh@users.noreply.github.com>
This commit is contained in:
parent
f53f245f7b
commit
cb1cb236cf
10 changed files with 86 additions and 36 deletions
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/types';
|
||||
|
||||
/**
|
||||
* Creates the `belongs_to` runtime field with the value of either
|
||||
* `account.cloud.name` or `cluster.id` based on the value of `rule.benchmark.posture_type`
|
||||
*/
|
||||
export const getBelongsToRuntimeMapping = (): MappingRuntimeFields => ({
|
||||
belongs_to: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: `
|
||||
if (!doc.containsKey('rule.benchmark.posture_type'))
|
||||
{
|
||||
def identifier = doc["cluster_id"].value;
|
||||
emit(identifier);
|
||||
return
|
||||
}
|
||||
else
|
||||
{
|
||||
if(doc["rule.benchmark.posture_type"].size() > 0)
|
||||
{
|
||||
def policy_template_type = doc["rule.benchmark.posture_type"].value;
|
||||
if (policy_template_type == "cspm")
|
||||
{
|
||||
def identifier = doc["cloud.account.name"].value;
|
||||
emit(identifier);
|
||||
return
|
||||
}
|
||||
|
||||
if (policy_template_type == "kspm")
|
||||
{
|
||||
def identifier = doc["cluster_id"].value;
|
||||
emit(identifier);
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
def identifier = doc["cluster_id"].value;
|
||||
emit(identifier);
|
||||
return
|
||||
}
|
||||
`,
|
||||
},
|
||||
},
|
||||
});
|
|
@ -26,7 +26,7 @@ const getFakeFindingsByResource = (): FindingsByResourcePage => {
|
|||
);
|
||||
|
||||
return {
|
||||
cluster_id: chance.guid(),
|
||||
belongs_to: chance.guid(),
|
||||
resource_id: chance.guid(),
|
||||
'resource.name': resourceName,
|
||||
'resource.sub_type': resourceSubtype,
|
||||
|
|
|
@ -17,6 +17,8 @@ import {
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import numeral from '@elastic/numeral';
|
||||
import { Link, generatePath } from 'react-router-dom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ColumnNameWithTooltip } from '../../../components/column_name_with_tooltip';
|
||||
import { ComplianceScoreBar } from '../../../components/compliance_score_bar';
|
||||
import * as TEST_SUBJECTS from '../test_subjects';
|
||||
import type { FindingsByResourcePage } from './use_findings_by_resource';
|
||||
|
@ -76,7 +78,7 @@ const FindingsByResourceTableComponent = ({
|
|||
getNonSortableColumn(findingsByResourceColumns['rule.benchmark.name']),
|
||||
{ onAddFilter }
|
||||
),
|
||||
createColumnWithFilters(getNonSortableColumn(findingsByResourceColumns.cluster_id), {
|
||||
createColumnWithFilters(getNonSortableColumn(findingsByResourceColumns.belongs_to), {
|
||||
onAddFilter,
|
||||
}),
|
||||
findingsByResourceColumns.compliance_score,
|
||||
|
@ -149,7 +151,22 @@ const baseColumns: Array<EuiTableFieldDataColumnType<FindingsByResourcePage>> =
|
|||
);
|
||||
},
|
||||
},
|
||||
baseFindingsColumns.cluster_id,
|
||||
{
|
||||
field: 'belongs_to',
|
||||
name: (
|
||||
<ColumnNameWithTooltip
|
||||
columnName={i18n.translate(
|
||||
'xpack.csp.findings.findingsTable.findingsTableColumn.clusterIdColumnLabel',
|
||||
{ defaultMessage: 'Belongs To' }
|
||||
)}
|
||||
tooltipContent={i18n.translate(
|
||||
'xpack.csp.findings.findingsTable.findingsTableColumn.clusterIdColumnTooltipLabel',
|
||||
{ defaultMessage: 'Kubernetes Cluster ID or Cloud Account Name' }
|
||||
)}
|
||||
/>
|
||||
),
|
||||
truncateText: true,
|
||||
},
|
||||
{
|
||||
field: 'compliance_score',
|
||||
width: '150px',
|
||||
|
|
|
@ -9,6 +9,7 @@ import { lastValueFrom } from 'rxjs';
|
|||
import { IKibanaSearchRequest, IKibanaSearchResponse } from '@kbn/data-plugin/common';
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { Pagination } from '@elastic/eui';
|
||||
import { getBelongsToRuntimeMapping } from '../../../../common/runtime_mappings/get_belongs_to_runtime_mapping';
|
||||
import { MAX_FINDINGS_TO_LOAD } from '../../../common/constants';
|
||||
import { useKibana } from '../../../common/hooks/use_kibana';
|
||||
import { showErrorToast } from '../latest_findings/use_latest_findings';
|
||||
|
@ -43,7 +44,7 @@ export interface FindingsByResourcePage {
|
|||
};
|
||||
compliance_score: number;
|
||||
resource_id: string;
|
||||
cluster_id: string;
|
||||
belongs_to: string;
|
||||
'resource.name': string;
|
||||
'resource.sub_type': string;
|
||||
'rule.benchmark.name': string;
|
||||
|
@ -62,7 +63,7 @@ interface FindingsAggBucket extends estypes.AggregationsStringRareTermsBucketKey
|
|||
passed_findings: estypes.AggregationsMultiBucketBase;
|
||||
name: estypes.AggregationsMultiBucketAggregateBase<estypes.AggregationsStringTermsBucketKeys>;
|
||||
subtype: estypes.AggregationsMultiBucketAggregateBase<estypes.AggregationsStringTermsBucketKeys>;
|
||||
cluster_id: estypes.AggregationsMultiBucketAggregateBase<estypes.AggregationsStringTermsBucketKeys>;
|
||||
belongs_to: estypes.AggregationsMultiBucketAggregateBase<estypes.AggregationsStringTermsBucketKeys>;
|
||||
benchmarkName: estypes.AggregationsMultiBucketAggregateBase<estypes.AggregationsStringRareTermsBucketKeys>;
|
||||
cis_sections: estypes.AggregationsMultiBucketAggregateBase<estypes.AggregationsStringRareTermsBucketKeys>;
|
||||
}
|
||||
|
@ -75,6 +76,7 @@ export const getFindingsByResourceAggQuery = ({
|
|||
body: {
|
||||
query,
|
||||
size: 0,
|
||||
runtime_mappings: getBelongsToRuntimeMapping(),
|
||||
aggs: {
|
||||
...getFindingsCountAggQuery(),
|
||||
resource_total: { cardinality: { field: 'resource.id' } },
|
||||
|
@ -99,8 +101,9 @@ export const getFindingsByResourceAggQuery = ({
|
|||
passed_findings: {
|
||||
filter: { term: { 'result.evaluation': 'passed' } },
|
||||
},
|
||||
cluster_id: {
|
||||
terms: { field: 'cluster_id', size: 1 },
|
||||
// this field is runtime generated
|
||||
belongs_to: {
|
||||
terms: { field: 'belongs_to', size: 1 },
|
||||
},
|
||||
compliance_score: {
|
||||
bucket_script: {
|
||||
|
@ -177,12 +180,12 @@ const createFindingsByResource = (resource: FindingsAggBucket): FindingsByResour
|
|||
!Array.isArray(resource.cis_sections.buckets) ||
|
||||
!Array.isArray(resource.name.buckets) ||
|
||||
!Array.isArray(resource.subtype.buckets) ||
|
||||
!Array.isArray(resource.cluster_id.buckets) ||
|
||||
!Array.isArray(resource.belongs_to.buckets) ||
|
||||
!resource.benchmarkName.buckets.length ||
|
||||
!resource.cis_sections.buckets.length ||
|
||||
!resource.name.buckets.length ||
|
||||
!resource.subtype.buckets.length ||
|
||||
!resource.cluster_id.buckets.length
|
||||
!resource.belongs_to.buckets.length
|
||||
)
|
||||
throw new Error('expected buckets to be an array');
|
||||
|
||||
|
@ -190,9 +193,9 @@ const createFindingsByResource = (resource: FindingsAggBucket): FindingsByResour
|
|||
resource_id: resource.key,
|
||||
['resource.name']: resource.name.buckets[0]?.key,
|
||||
['resource.sub_type']: resource.subtype.buckets[0]?.key,
|
||||
cluster_id: resource.cluster_id.buckets[0]?.key,
|
||||
['rule.section']: resource.cis_sections.buckets.map((v) => v.key),
|
||||
['rule.benchmark.name']: resource.benchmarkName.buckets[0]?.key,
|
||||
belongs_to: resource.belongs_to.buckets[0]?.key,
|
||||
compliance_score: resource.compliance_score.value,
|
||||
findings: {
|
||||
failed_findings: resource.failed_findings.doc_count,
|
||||
|
|
|
@ -175,28 +175,6 @@ const baseColumns = [
|
|||
</EuiToolTip>
|
||||
),
|
||||
},
|
||||
{
|
||||
field: 'cluster_id',
|
||||
name: (
|
||||
<ColumnNameWithTooltip
|
||||
columnName={i18n.translate(
|
||||
'xpack.csp.findings.findingsTable.findingsTableColumn.clusterIdColumnLabel',
|
||||
{ defaultMessage: 'Belongs To' }
|
||||
)}
|
||||
tooltipContent={i18n.translate(
|
||||
'xpack.csp.findings.findingsTable.findingsTableColumn.clusterIdColumnTooltipLabel',
|
||||
{ defaultMessage: 'Kubernetes Cluster ID or Cloud Account Name' }
|
||||
)}
|
||||
/>
|
||||
),
|
||||
sortable: true,
|
||||
truncateText: true,
|
||||
render: (section: string) => (
|
||||
<EuiToolTip content={section} anchorClassName="eui-textTruncate">
|
||||
<>{section}</>
|
||||
</EuiToolTip>
|
||||
),
|
||||
},
|
||||
{
|
||||
field: '@timestamp',
|
||||
align: 'right',
|
||||
|
|
|
@ -10,7 +10,7 @@ import type {
|
|||
AggregationsMultiBucketBase,
|
||||
SearchRequest,
|
||||
} from '@elastic/elasticsearch/lib/api/types';
|
||||
import { getIdentifierRuntimeMapping } from '../../get_identifier_runtime_mapping';
|
||||
import { getIdentifierRuntimeMapping } from '../../../../common/runtime_mappings/get_identifier_runtime_mapping';
|
||||
import { calculatePostureScore } from '../../../../common/utils/helpers';
|
||||
import type { CspmAccountsStats } from './types';
|
||||
import { LATEST_FINDINGS_INDEX_DEFAULT_NS } from '../../../../common/constants';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
|
||||
import type { Logger } from '@kbn/core/server';
|
||||
import type { SearchRequest } from '@elastic/elasticsearch/lib/api/types';
|
||||
import { getIdentifierRuntimeMapping } from '../../get_identifier_runtime_mapping';
|
||||
import { getIdentifierRuntimeMapping } from '../../../../common/runtime_mappings/get_identifier_runtime_mapping';
|
||||
import type { CspmResourcesStats } from './types';
|
||||
import { LATEST_FINDINGS_INDEX_DEFAULT_NS } from '../../../../common/constants';
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
import type { FailedFindingsQueryResult } from './get_grouped_findings_evaluation';
|
||||
import { findingsEvaluationAggsQuery, getStatsFromFindingsEvaluationsAggs } from './get_stats';
|
||||
import { KeyDocCount } from './compliance_dashboard';
|
||||
import { getIdentifierRuntimeMapping } from '../../lib/get_identifier_runtime_mapping';
|
||||
import { getIdentifierRuntimeMapping } from '../../../common/runtime_mappings/get_identifier_runtime_mapping';
|
||||
|
||||
export interface ClusterBucket extends FailedFindingsQueryResult, KeyDocCount {
|
||||
failed_findings: {
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
import { SearchRequest } from '@kbn/data-plugin/common';
|
||||
import { ElasticsearchClient } from '@kbn/core/server';
|
||||
import type { Logger } from '@kbn/core/server';
|
||||
import { getIdentifierRuntimeMapping } from '../lib/get_identifier_runtime_mapping';
|
||||
import { getIdentifierRuntimeMapping } from '../../common/runtime_mappings/get_identifier_runtime_mapping';
|
||||
import { FindingsStatsTaskResult, TaskHealthStatus, ScoreByPolicyTemplateBucket } from './types';
|
||||
import {
|
||||
BENCHMARK_SCORE_INDEX_DEFAULT_NS,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue