-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Cloud Security] Misconfiguration preview & Refactor CSP Plugin to in…
…clude new package PHASE 4 (#191677) The previous #190105 was way too big and made it hard to review without missing any bugs or potential bugs, Thus we decided we are going to make series of smaller PR to make things more manageable We will be splitting it into 4 PR Phase 1: Creating empty packages for csp and csp-common Phase 2: Move Types from CSP plugin to the Package + Deleting duplicates in the CSP plugin where possible Phase 3: Move Functions, Utils or Helpers, Hooks to Package Phase 4: Misconfiguration Preview feature (with Cypress test and other required test) <img width="681" alt="353329193-5ad22c4e-81c2-4a8b-89f7-fdbc2a686c2d" src="https://github.com/user-attachments/assets/b369625a-efc5-4292-a690-2c5dffb5483d"> This is Phase 4 of the Process, --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
- Loading branch information
1 parent
f6807f9
commit 8b7d965
Showing
12 changed files
with
484 additions
and
2 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
149 changes: 149 additions & 0 deletions
149
x-pack/packages/kbn-cloud-security-posture/src/hooks/use_misconfiguration_preview.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 { useQuery } from '@tanstack/react-query'; | ||
import { lastValueFrom } from 'rxjs'; | ||
import type { IKibanaSearchResponse, IKibanaSearchRequest } from '@kbn/search-types'; | ||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; | ||
import { | ||
CDR_MISCONFIGURATIONS_INDEX_PATTERN, | ||
LATEST_FINDINGS_RETENTION_POLICY, | ||
CspFinding, | ||
} from '@kbn/cloud-security-posture-common'; | ||
import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common/schema/rules/latest'; | ||
import { buildMutedRulesFilter } from '@kbn/cloud-security-posture-common'; | ||
import { useKibana } from '@kbn/kibana-react-plugin/public'; | ||
import type { CoreStart } from '@kbn/core/public'; | ||
import { showErrorToast } from '../..'; | ||
import type { CspClientPluginStartDeps } from '../../type'; | ||
import { useGetCspBenchmarkRulesStatesApi } from './use_get_benchmark_rules_state_api'; | ||
|
||
interface MisconfigurationPreviewBaseEsQuery { | ||
query?: { | ||
bool: { | ||
filter: estypes.QueryDslQueryContainer[]; | ||
}; | ||
}; | ||
} | ||
|
||
interface UseMisconfigurationPreviewOptions extends MisconfigurationPreviewBaseEsQuery { | ||
sort: string[][]; | ||
enabled: boolean; | ||
pageSize: number; | ||
} | ||
|
||
type LatestFindingsRequest = IKibanaSearchRequest<estypes.SearchRequest>; | ||
type LatestFindingsResponse = IKibanaSearchResponse< | ||
estypes.SearchResponse<CspFinding, FindingsAggs> | ||
>; | ||
|
||
interface FindingsAggs { | ||
count: estypes.AggregationsMultiBucketAggregateBase<estypes.AggregationsStringRareTermsBucketKeys>; | ||
} | ||
|
||
const RESULT_EVALUATION = { | ||
PASSED: 'passed', | ||
FAILED: 'failed', | ||
UNKNOWN: 'unknown', | ||
}; | ||
|
||
export const getFindingsCountAggQueryMisconfigurationPreview = () => ({ | ||
count: { | ||
filters: { | ||
other_bucket_key: RESULT_EVALUATION.UNKNOWN, | ||
filters: { | ||
[RESULT_EVALUATION.PASSED]: { match: { 'result.evaluation': RESULT_EVALUATION.PASSED } }, | ||
[RESULT_EVALUATION.FAILED]: { match: { 'result.evaluation': RESULT_EVALUATION.FAILED } }, | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
export const getMisconfigurationAggregationCount = ( | ||
buckets: estypes.AggregationsBuckets<estypes.AggregationsStringRareTermsBucketKeys> | ||
) => { | ||
return Object.entries(buckets).reduce( | ||
(evaluation, [key, value]) => { | ||
evaluation[key] = (evaluation[key] || 0) + (value.doc_count || 0); | ||
return evaluation; | ||
}, | ||
{ | ||
[RESULT_EVALUATION.PASSED]: 0, | ||
[RESULT_EVALUATION.FAILED]: 0, | ||
[RESULT_EVALUATION.UNKNOWN]: 0, | ||
} | ||
); | ||
}; | ||
|
||
export const buildMisconfigurationsFindingsQuery = ( | ||
{ query }: UseMisconfigurationPreviewOptions, | ||
rulesStates: CspBenchmarkRulesStates | ||
) => { | ||
const mutedRulesFilterQuery = buildMutedRulesFilter(rulesStates); | ||
|
||
return { | ||
index: CDR_MISCONFIGURATIONS_INDEX_PATTERN, | ||
size: 0, | ||
aggs: getFindingsCountAggQueryMisconfigurationPreview(), | ||
ignore_unavailable: false, | ||
query: buildMisconfigurationsFindingsQueryWithFilters(query, mutedRulesFilterQuery), | ||
}; | ||
}; | ||
|
||
const buildMisconfigurationsFindingsQueryWithFilters = ( | ||
query: UseMisconfigurationPreviewOptions['query'], | ||
mutedRulesFilterQuery: estypes.QueryDslQueryContainer[] | ||
) => { | ||
return { | ||
...query, | ||
bool: { | ||
...query?.bool, | ||
filter: [ | ||
...(query?.bool?.filter ?? []), | ||
{ | ||
range: { | ||
'@timestamp': { | ||
gte: `now-${LATEST_FINDINGS_RETENTION_POLICY}`, | ||
lte: 'now', | ||
}, | ||
}, | ||
}, | ||
], | ||
must_not: [...mutedRulesFilterQuery], | ||
}, | ||
}; | ||
}; | ||
|
||
export const useMisconfigurationPreview = (options: UseMisconfigurationPreviewOptions) => { | ||
const { | ||
data, | ||
notifications: { toasts }, | ||
} = useKibana<CoreStart & CspClientPluginStartDeps>().services; | ||
const { data: rulesStates } = useGetCspBenchmarkRulesStatesApi(); | ||
|
||
return useQuery( | ||
['csp_misconfiguration_preview', { params: options }, rulesStates], | ||
async () => { | ||
const { | ||
rawResponse: { aggregations }, | ||
} = await lastValueFrom( | ||
data.search.search<LatestFindingsRequest, LatestFindingsResponse>({ | ||
params: buildMisconfigurationsFindingsQuery(options, rulesStates!), | ||
}) | ||
); | ||
if (!aggregations) throw new Error('expected aggregations to be defined'); | ||
|
||
return { | ||
count: getMisconfigurationAggregationCount(aggregations.count.buckets), | ||
}; | ||
}, | ||
{ | ||
enabled: options.enabled && !!rulesStates, | ||
keepPreviousData: true, | ||
onError: (err: Error) => showErrorToast(toasts, err), | ||
} | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,5 +36,6 @@ | |
"@kbn/kibana-react-plugin", | ||
"@kbn/cloud-security-posture-common", | ||
"@kbn/i18n", | ||
"@kbn/search-types", | ||
] | ||
} |
52 changes: 52 additions & 0 deletions
52
x-pack/plugins/security_solution/public/cloud_security_posture/components/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 { EuiAccordion, EuiSpacer, EuiTitle, useEuiTheme } from '@elastic/eui'; | ||
|
||
import React from 'react'; | ||
import { css } from '@emotion/react'; | ||
import { FormattedMessage } from '@kbn/i18n-react'; | ||
import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; | ||
import { MisconfigurationsPreview } from './misconfiguration/misconfiguration_preview'; | ||
|
||
export const EntityInsight = <T,>({ hostName }: { hostName: string }) => { | ||
const { euiTheme } = useEuiTheme(); | ||
const getSetupStatus = useCspSetupStatusApi(); | ||
const hasMisconfigurationFindings = getSetupStatus.data?.hasMisconfigurationsFindings; | ||
|
||
return ( | ||
<> | ||
{hasMisconfigurationFindings && ( | ||
<EuiAccordion | ||
initialIsOpen={true} | ||
id="entityInsight-accordion" | ||
data-test-subj="entityInsightTestSubj" | ||
buttonProps={{ | ||
'data-test-subj': 'entityInsight-accordion-button', | ||
css: css` | ||
color: ${euiTheme.colors.primary}; | ||
`, | ||
}} | ||
buttonContent={ | ||
<EuiTitle size="xs"> | ||
<h3> | ||
<FormattedMessage | ||
id="xpack.securitySolution.flyout.entityDetails.insightsTitle" | ||
defaultMessage="Insights" | ||
/> | ||
</h3> | ||
</EuiTitle> | ||
} | ||
> | ||
<EuiSpacer size="m" /> | ||
<MisconfigurationsPreview hostName={hostName} /> | ||
<EuiSpacer size="m" /> | ||
</EuiAccordion> | ||
)} | ||
</> | ||
); | ||
}; |
28 changes: 28 additions & 0 deletions
28
...blic/cloud_security_posture/components/misconfiguration/misconfiguration_preview.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
// Add stuff here | ||
import { TestProviders } from '../../../common/mock'; | ||
import { render } from '@testing-library/react'; | ||
import React from 'react'; | ||
import { MisconfigurationsPreview } from './misconfiguration_preview'; | ||
|
||
const mockProps = { | ||
hostName: 'testContextID', | ||
}; | ||
|
||
describe('MisconfigurationsPreview', () => { | ||
it('renders', () => { | ||
const { queryByTestId } = render(<MisconfigurationsPreview {...mockProps} />, { | ||
wrapper: TestProviders, | ||
}); | ||
expect( | ||
queryByTestId('securitySolutionFlyoutInsightsMisconfigurationsContent') | ||
).toBeInTheDocument(); | ||
expect(queryByTestId('noFindingsDataTestSubj')).toBeInTheDocument(); | ||
}); | ||
}); |
Oops, something went wrong.