Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cloud Security Posture][Benchmark Improvements] Rules Page Improvements phase 1 #172424

Draft
wants to merge 57 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
dea42f5
fix for dashboard trendline issue
animehart Jun 22, 2023
1d0101f
removed empty line
animehart Jun 22, 2023
a504ccc
added retention period for KSPM CSPM and CNVM
animehart Jun 22, 2023
0a70547
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine Jun 22, 2023
cf75786
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Jun 22, 2023
caa4d05
Merge branch 'main' into retention-period-issue
animehart Aug 17, 2023
6362d2d
updated query
animehart Aug 18, 2023
38e4709
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine Aug 18, 2023
9f2e328
ftr fix
animehart Aug 18, 2023
14d2908
Merge branch 'retention-period-issue' of github.com:animehart/kibana …
animehart Aug 18, 2023
5b07a6a
attempt to fix failed ftr
animehart Aug 22, 2023
f5a5f24
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine Aug 22, 2023
d3528f8
Merge branch 'main' into retention-period-issue
animehart Aug 22, 2023
7cdff23
Merge branch 'main' into retention-period-issue
animehart Aug 24, 2023
cb836d8
Merge branch 'main' into retention-period-issue
animehart Oct 19, 2023
b80cf71
Merge branch 'main' into retention-period-issue
animehart Nov 2, 2023
414563f
fix FTR + query
animehart Nov 3, 2023
8014b23
update mock
animehart Nov 3, 2023
60f30f2
clean up
animehart Nov 8, 2023
5ed9958
more clean up
animehart Nov 8, 2023
9ceae0c
Merge branch 'main' into retention-period-issue
animehart Nov 9, 2023
7518ad2
added FTR for this fix
animehart Nov 9, 2023
c86986e
clean up
animehart Nov 9, 2023
287a949
pr comments
animehart Nov 13, 2023
c0b4b6b
Merge branch 'main' into retention-period-issue
animehart Nov 14, 2023
b332a5f
Merge branch 'main' into retention-period-issue
animehart Nov 14, 2023
a48aea2
pr comments
animehart Nov 17, 2023
295d331
Merge branch 'main' into retention-period-issue
animehart Nov 17, 2023
4edcaab
dirty-change
animehart Nov 21, 2023
7dda1fd
updated UI
animehart Nov 22, 2023
f65350b
Merge branch 'main' into benchmark-improvement-1
animehart Nov 22, 2023
db4b240
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Nov 22, 2023
693516b
fix UT, a little clean up. TODO: more test fixes and updates + Clean up
animehart Nov 23, 2023
b80dc23
conflict fix
animehart Nov 23, 2023
eb6a297
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Nov 23, 2023
c762649
more clean up
animehart Nov 23, 2023
0d463f6
fix and updates
animehart Nov 23, 2023
13c3caa
fix for same id diff version not showing on different row
animehart Nov 24, 2023
02d5207
UI updates and more clean up
animehart Nov 24, 2023
676ae03
more cleanup
animehart Nov 27, 2023
e03e5f3
added missing imports
animehart Nov 28, 2023
f13636b
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Nov 28, 2023
21a6880
clean up
animehart Nov 29, 2023
ebe59d1
conflict fix
animehart Nov 29, 2023
ecd6d2f
checks fail fix
animehart Nov 29, 2023
7f8cc31
check fix
animehart Nov 29, 2023
276e590
Merge branch 'main' into benchmark-improvement-1
animehart Nov 29, 2023
7d656c6
still dirty code
animehart Dec 1, 2023
860ead4
added empty benchmark page, need clean up and need to learn what spyr…
animehart Dec 2, 2023
e247de4
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Dec 2, 2023
3ca20b5
Merge branch 'main' into rule-page-phase1-dev
animehart Dec 3, 2023
02017f7
fix test
animehart Dec 4, 2023
7f385c2
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Dec 4, 2023
68b36c8
clean up + fix CI failures
animehart Dec 4, 2023
4a56079
fix conflict
animehart Dec 4, 2023
fb4549e
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Dec 4, 2023
4d057b0
attempt
animehart Dec 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion x-pack/plugins/cloud_security_posture/common/types/rules/v3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,25 @@ export const findCspBenchmarkRuleRequestSchema = schema.object({
* benchmark id
*/
benchmarkId: schema.maybe(
schema.oneOf([schema.literal('cis_k8s'), schema.literal('cis_eks'), schema.literal('cis_aws')])
schema.oneOf([
schema.literal('cis_k8s'),
schema.literal('cis_eks'),
schema.literal('cis_aws'),
schema.literal('cis_gcp'),
schema.literal('cis_azure'),
])
),

/**
* policy_id
*/
benchmarkVersion: schema.maybe(schema.string()),

/**
* policy_id
*/
policyId: schema.maybe(schema.string()),

/**
* package_policy_id
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ export const getBenchmarkFilter = (type: BenchmarkId, section?: RuleSection): st
: ''
}`;

export const getBenchmarkFilterQuery = (id: BenchmarkId, version?: string): string =>
`${CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.id:${id} AND ${CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.version:"v${version}"`;

export const isEnabledBenchmarkInputType = (input: PackagePolicyInput | NewPackagePolicyInput) =>
input.enabled;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,12 @@ export const cloudPosturePages: Record<CspPage, CspPageNavigationItem> = {
id: 'cloud_security_posture-benchmarks',
},
};

// CHANGE THIS
export const benchmarksNavigation: Record<CspBenchmarksPage, CspPageNavigationItem> = {
rules: {
name: NAV_ITEMS_NAMES.RULES,
path: `${CLOUD_SECURITY_POSTURE_BASE_PATH}/benchmarks/:packagePolicyId/:policyId/rules`,
// path: `${CLOUD_SECURITY_POSTURE_BASE_PATH}/benchmarks/:packagePolicyId/:policyId/rules`,
path: `${CLOUD_SECURITY_POSTURE_BASE_PATH}/benchmarks/:benchmarkId/:benchmarkVersion/rules`,
id: 'cloud_security_posture-benchmarks-rules',
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ import {
} from './use_csp_benchmark_integrations';
import { extractErrorMessage, getBenchmarkCisName } from '../../../common/utils/helpers';
import * as TEST_SUBJ from './test_subjects';
import { LOCAL_STORAGE_PAGE_SIZE_BENCHMARK_KEY } from '../../common/constants';
import {
LOCAL_STORAGE_PAGE_SIZE_BENCHMARK_KEY,
NO_FINDINGS_STATUS_REFRESH_INTERVAL_MS,
} from '../../common/constants';
import { usePageSize } from '../../common/hooks/use_page_size';
import { useKibana } from '../../common/hooks/use_kibana';
import { NoFindingsStates } from '../../components/no_findings_states';
import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api';

const SEARCH_DEBOUNCE_MS = 300;

Expand Down Expand Up @@ -151,6 +156,14 @@ export const Benchmarks = () => {
[];
const totalItemCount = queryResult.data?.items.length || 0;

// Check if we have any CSP Integration or not
const getSetupStatus = useCspSetupStatusApi({
refetchInterval: NO_FINDINGS_STATUS_REFRESH_INTERVAL_MS,
});
const showConfigurationInstallPrompt =
getSetupStatus.data?.kspm?.status === 'not-installed' &&
getSetupStatus.data?.cspm?.status === 'not-installed';

return (
<CloudPosturePage>
<EuiPageHeader
Expand All @@ -166,44 +179,51 @@ export const Benchmarks = () => {
bottomBorder
/>
<EuiSpacer />
<BenchmarkSearchField
isLoading={queryResult.isFetching}
onSearch={(name) => setQuery((current) => ({ ...current, name }))}
/>
<EuiSpacer />
<TotalIntegrationsCount
pageCount={(queryResult.data?.items || []).length}
totalCount={totalItemCount}
/>
<EuiSpacer size="s" />
<BenchmarksTable
benchmarks={benchmarkResult}
data-test-subj={TEST_SUBJ.BENCHMARKS_TABLE_DATA_TEST_SUBJ}
error={queryResult.error ? extractErrorMessage(queryResult.error) : undefined}
loading={queryResult.isFetching}
pageIndex={query.page}
pageSize={pageSize || query.perPage}
sorting={{
// @ts-expect-error - EUI types currently do not support sorting by nested fields
sort: { field: query.sortField, direction: query.sortOrder },
allowNeutralSort: false,
}}
totalItemCount={totalItemCount}
setQuery={({ page, sort }) => {
setPageSize(page.size);
setQuery((current) => ({
...current,
page: page.index,
perPage: page.size,
sortField:
(sort?.field as UseCspBenchmarkIntegrationsProps['sortField']) || current.sortField,
sortOrder: sort?.direction || current.sortOrder,
}));
}}
noItemsMessage={
queryResult.isSuccess ? <BenchmarkEmptyState name={query.name} /> : undefined
}
/>
{showConfigurationInstallPrompt ? (
// Does not matter what posture value we put here, as we wanted to render the case where both cspm and kspm are both not-installed
<NoFindingsStates posturetype={'cspm'} />
) : (
<>
<BenchmarkSearchField
isLoading={queryResult.isFetching}
onSearch={(name) => setQuery((current) => ({ ...current, name }))}
/>
<EuiSpacer />
<TotalIntegrationsCount
pageCount={(queryResult.data?.items || []).length}
totalCount={totalItemCount}
/>
<EuiSpacer size="s" />
<BenchmarksTable
benchmarks={benchmarkResult || []}
data-test-subj={TEST_SUBJ.BENCHMARKS_TABLE_DATA_TEST_SUBJ}
error={queryResult.error ? extractErrorMessage(queryResult.error) : undefined}
loading={queryResult.isFetching}
pageIndex={query.page}
pageSize={pageSize || query.perPage}
sorting={{
sort: { field: query.sortField, direction: query.sortOrder },
allowNeutralSort: false,
}}
totalItemCount={totalItemCount}
setQuery={({ page, sort }) => {
setPageSize(page.size);
setQuery((current) => ({
...current,
page: page.index,
perPage: page.size,
sortField:
(sort?.field as UseCspBenchmarkIntegrationsProps['sortField']) ||
current.sortField,
sortOrder: sort?.direction || current.sortOrder,
}));
}}
noItemsMessage={
queryResult.isSuccess ? <BenchmarkEmptyState name={query.name} /> : undefined
}
/>
</>
)}
</CloudPosturePage>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,21 @@ import {
EuiEmptyPrompt,
EuiFlexGroup,
EuiFlexItem,
EuiLink,
} from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { generatePath } from 'react-router-dom';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import type { BenchmarkScore, Benchmark, BenchmarksCisId } from '../../../common/types/latest';
import * as TEST_SUBJ from './test_subjects';
import { isCommonError } from '../../components/cloud_posture_page';
import { FullSizeCenteredPage } from '../../components/full_size_centered_page';
import { ComplianceScoreBar } from '../../components/compliance_score_bar';
import { getBenchmarkCisName, getBenchmarkApplicableTo } from '../../../common/utils/helpers';
import { CISBenchmarkIcon } from '../../components/cis_benchmark_icon';
import { benchmarksNavigation } from '../../common/navigation/constants';

export const ERROR_STATE_TEST_SUBJECT = 'benchmark_page_error';

Expand All @@ -36,46 +40,71 @@ interface BenchmarksTableProps
'data-test-subj'?: string;
}

const IntegrationButtonLink = ({
packageName,
benchmarkVersion,
benchmarkId,
}: {
packageName: string;
benchmarkVersion: string;
benchmarkId: string;
}) => {
const { application } = useKibana().services;

return (
<EuiLink
href={application?.getUrlForApp('security', {
path: generatePath(benchmarksNavigation.rules.path, {
benchmarkVersion,
benchmarkId,
}),
})}
>
{packageName}
</EuiLink>
);
};

export const getBenchmarkPlurals = (benchmarkId: string, accountEvaluation: number) => {
switch (benchmarkId) {
case 'cis_k8s':
return (
<FormattedMessage
id="xpack.csp.benchmarks.benchmarksTable.integrationBenchmarkK8sAccountPlural"
defaultMessage="{accountCount, plural, one {# cluster} other {# clusters}}"
values={{ accountCount: accountEvaluation || 0 }}
defaultMessage="{ruleCount, plural, one {# cluster} other {# clusters}}"
values={{ ruleCount: accountEvaluation || 0 }}
/>
);
case 'cis_azure':
return (
<FormattedMessage
id="xpack.csp.benchmarks.benchmarksTable.integrationBenchmarkAzureAccountPlural"
defaultMessage="{accountCount, plural, one {# subscription} other {# subscriptions}}"
values={{ accountCount: accountEvaluation || 0 }}
defaultMessage="{ruleCount, plural, one {# subscription} other {# subscriptions}}"
values={{ ruleCount: accountEvaluation || 0 }}
/>
);
case 'cis_aws':
return (
<FormattedMessage
id="xpack.csp.benchmarks.benchmarksTable.integrationBenchmarkAwsAccountPlural"
defaultMessage="{accountCount, plural, one {# account} other {# accounts}}"
values={{ accountCount: accountEvaluation || 0 }}
defaultMessage="{ruleCount, plural, one {# account} other {# accounts}}"
values={{ ruleCount: accountEvaluation || 0 }}
/>
);
case 'cis_eks':
return (
<FormattedMessage
id="xpack.csp.benchmarks.benchmarksTable.integrationBenchmarkEksAccountPlural"
defaultMessage="{accountCount, plural, one {# cluster} other {# clusters}}"
values={{ accountCount: accountEvaluation || 0 }}
defaultMessage="{ruleCount, plural, one {# cluster} other {# clusters}}"
values={{ ruleCount: accountEvaluation || 0 }}
/>
);
case 'cis_gcp':
return (
<FormattedMessage
id="xpack.csp.benchmarks.benchmarksTable.integrationBenchmarkGcpAccountPlural"
defaultMessage="{accountCount, plural, one {# project} other {# projects}}"
values={{ accountCount: accountEvaluation || 0 }}
defaultMessage="{ruleCount, plural, one {# project} other {# projects}}"
values={{ ruleCount: accountEvaluation || 0 }}
/>
);
}
Expand Down Expand Up @@ -123,9 +152,13 @@ const BENCHMARKS_TABLE_COLUMNS: Array<EuiBasicTableColumn<Benchmark>> = [
truncateText: true,
width: '17.5%',
sortable: true,
render: (benchmarkId: BenchmarksCisId) => {
return getBenchmarkCisName(benchmarkId);
},
render: (complianceScore: Benchmark['id'], benchmarkId) => (
<IntegrationButtonLink
packageName={getBenchmarkCisName(benchmarkId.id) || ''}
benchmarkId={benchmarkId.id || ''}
benchmarkVersion={benchmarkId.version || ''}
/>
),
'data-test-subj': TEST_SUBJ.BENCHMARKS_TABLE_COLUMNS.CIS_NAME,
},
{
Expand Down
Loading