mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Cloud Security] 3P findings page and flyout support (#187874)
This commit is contained in:
parent
381ea546e0
commit
a98a8ab101
28 changed files with 2007 additions and 849 deletions
|
@ -7,7 +7,7 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
|
||||
## Directory: x-pack/plugins/cloud_security_posture
|
||||
|
||||
**Total Tests:** 458 | **Skipped:** 5 (1.09%) | **Todo:** 0 (0.00%)
|
||||
**Total Tests:** 473 | **Skipped:** 5 (1.06%) | **Todo:** 0 (0.00%)
|
||||
|
||||
 
|
||||
|
||||
|
@ -121,6 +121,8 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
| [renders loading state](x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.test.tsx) | it | | |
|
||||
| [renders empty state when no rows are present](x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.test.tsx) | it | | |
|
||||
| [renders data table with rows](x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.test.tsx) | it | | |
|
||||
| [renders data table with actions button](x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.test.tsx) | it | | |
|
||||
| [renders data table without actions button](x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.test.tsx) | it | | |
|
||||
| [FieldsSelectorTable](x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/fields_selector/fields_selector_table.test.tsx) | describe | | |
|
||||
| [renders the table with data correctly](x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/fields_selector/fields_selector_table.test.tsx) | it | | |
|
||||
| [calls onAddColumn when a checkbox is checked](x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/fields_selector/fields_selector_table.test.tsx) | it | | |
|
||||
|
@ -209,6 +211,7 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
| [renders ${CLOUDBEAT_AZURE} Service Principal with Client Secret fields](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx) | it | | |
|
||||
| [updates ${CLOUDBEAT_AZURE} Service Principal with Client Secret fields](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx) | it | | |
|
||||
| [Agentless](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx) | describe | | |
|
||||
| [should not render setup technology selector if agentless is not available and CSPM integration supports agentless](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx) | it | | |
|
||||
| [should render setup technology selector for AWS and allow to select agent-based](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx) | it | | |
|
||||
| [should render setup technology selector for GCP for organisation account type](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx) | it | | |
|
||||
| [should render setup technology selector for GCP for single-account](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx) | it | | |
|
||||
|
@ -228,11 +231,11 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
| [sets to AGENTLESS when agentless is available and GCP cloud](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [sets to AGENTLESS when agentless is available and Azure cloud](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [sets to AGENT_BASED when agentless is available but input is not supported for agentless](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [sets to AGENT_BASED when agentPolicyId differs from agentlessPolicyId](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [sets to AGENT_BASED when isAgentlessEnabled is false](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [calls handleSetupTechnologyChange when setupTechnology changes](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [edit page flow](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | describe | | |
|
||||
| [initializes with AGENT_BASED technology](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [initializes with AGENTLESS technology if the agent policy id is "agentless"](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [initializes with AGENTLESS technology if isAgentlessEnable is true](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [should not call handleSetupTechnologyChange when setupTechnology changes](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [should not update setupTechnology when agentlessPolicyId becomes available](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.test.ts) | it | | |
|
||||
| [getPosturePolicy](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/utils.test.ts) | describe | | |
|
||||
|
@ -265,14 +268,14 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
| [Should return undefined when datastream is undefined](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/utils.test.ts) | it | | |
|
||||
| [Should return undefined when stream is undefined](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/utils.test.ts) | it | | |
|
||||
| [Should return undefined when stream.var is invalid](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/utils.test.ts) | it | | |
|
||||
| [NoFindingsStates](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | describe | | |
|
||||
| [should show the indexing notification when CSPM is not installed and KSPM is indexing](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | |
|
||||
| [should show the indexing notification when KSPM is not installed and CSPM is indexing](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | |
|
||||
| [should show the indexing timout notification when CSPM is status is index-timeout](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | |
|
||||
| [should show the indexing timout notification when KSPM is status is index-timeout](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | |
|
||||
| [should show the unprivileged notification when CSPM is status is index-timeout](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | |
|
||||
| [should show the unprivileged notification when KSPM is status is index-timeout](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | |
|
||||
| [should show the not-installed notification when CSPM and KSPM status is not-installed](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | |
|
||||
| [NoFindingsStates](x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.test.tsx) | describe | | |
|
||||
| [shows integrations installation prompt with installation links when integration is not-installed](x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.test.tsx) | it | | |
|
||||
| [shows install agent prompt with install agent link when status is not-deployed](x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.test.tsx) | it | | |
|
||||
| [shows install agent prompt with install agent link when status is not-deployed and postureType is KSPM](x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.test.tsx) | it | | |
|
||||
| [shows indexing message when status is indexing](x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.test.tsx) | it | | |
|
||||
| [shows timeout message when status is index-timeout](x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.test.tsx) | it | | |
|
||||
| [shows unprivileged message when status is unprivileged](x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.test.tsx) | it | | |
|
||||
| [renders empty container when the status does not match a no finding status](x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.test.tsx) | it | | |
|
||||
| [<BenchmarksTable />](x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx) | describe | | |
|
||||
| [renders cis integration name](x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx) | it | | |
|
||||
| [renders benchmark version](x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx) | it | | |
|
||||
|
@ -320,19 +323,31 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
| [renders counters content according to mock](x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/summary_section.test.tsx) | it | | |
|
||||
| [renders counters value in compact abbreviation if its above one million](x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/summary_section.test.tsx) | it | | |
|
||||
| [<Findings />](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | describe | | |
|
||||
| [no findings state: not-deployed - shows NotDeployed instead of findings](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [no findings state: indexing - shows Indexing instead of findings](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [no findings state: index-timeout - shows IndexTimeout instead of findings](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [no findings state: unprivileged - shows Unprivileged instead of findings](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [renders integrations installation prompt if integration is not installed](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [SearchBar](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | describe | | |
|
||||
| [set search query](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [renders no results message and reset button when search query does not match](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [add filter](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [remove filter](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [DistributionBar](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | describe | | |
|
||||
| [renders the distribution bar](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [filters by passed findings when clicking on the passed findings button](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [filters by failed findings when clicking on the failed findings button](x-pack/plugins/cloud_security_posture/public/pages/configurations/configurations.test.tsx) | it | | |
|
||||
| [<FindingsFlyout/>](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | describe | | |
|
||||
| [Overview Tab](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | describe | | |
|
||||
| [details and remediation accordions are open](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [displays text details summary info](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [displays missing info callout when data source is not CSP](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [does not display missing info callout when data source is CSP](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [Rule Tab](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | describe | | |
|
||||
| [displays rule text details](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [displays missing info callout when data source is not CSP](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [does not display missing info callout when data source is CSP](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [Table Tab](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | describe | | |
|
||||
| [displays resource name and id](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [does not display missing info callout for 3Ps](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [JSON Tab](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | describe | | |
|
||||
| [does not display missing info callout for 3Ps](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [should allow pagination with next](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [should allow pagination with previous](x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.test.tsx) | it | | |
|
||||
| [Get Filters](x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/get_filters.test.ts) | describe | | |
|
||||
|
@ -528,7 +543,7 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
|
||||
## Directory: x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture
|
||||
|
||||
**Total Tests:** 4 | **Skipped:** 0 (0.00%) | **Todo:** 0 (0.00%)
|
||||
**Total Tests:** 23 | **Skipped:** 0 (0.00%) | **Todo:** 0 (0.00%)
|
||||
|
||||
 
|
||||
|
||||
|
@ -537,9 +552,28 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
|
||||
| Test Label | Type | Skipped | Todo |
|
||||
|------------|------|---------|------|
|
||||
| [Agentless CIS Integration Page](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts) | describe | | |
|
||||
| [Agentless CIS_AWS Single Account Launch Cloud formation](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts) | describe | | |
|
||||
| [should show CIS_AWS Launch Cloud formation button when credentials selector is direct access keys and package version is ${CLOUD_CREDENTIALS_PACKAGE_VERSION}](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts) | it | | |
|
||||
| [should hide CIS_AWS Launch Cloud formation button when credentials selector is temporary keys and package version is less than ${previousPackageVersion}](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts) | it | | |
|
||||
| [Agentless CIS_AWS ORG Account Launch Cloud formation](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts) | describe | | |
|
||||
| [should show CIS_AWS Launch Cloud formation button when credentials selector is direct access keys and package version is ${CLOUD_CREDENTIALS_PACKAGE_VERSION}](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts) | it | | |
|
||||
| [should hide CIS_AWS Launch Cloud formation button when credentials selector is temporary keys and package version is less than ${previousPackageVersion}](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts) | it | | |
|
||||
| [Agentless CIS Integration Page](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts) | describe | | |
|
||||
| [Agentless CIS_GCP Single Account Launch Cloud shell](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts) | describe | | |
|
||||
| [should show CIS_GCP Launch Cloud Shell button when package version is ${agentlessPreReleaseVersion}](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts) | it | | |
|
||||
| [should hide CIS_GCP Launch Cloud Shell button when package version is less than ${agentlessPreReleaseVersion}](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts) | it | | |
|
||||
| [Agentless CIS_GCP ORG Account Launch Cloud Shell](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts) | describe | | |
|
||||
| [should show CIS_GCP Launch Cloud Shell button when package version is ${agentlessPreReleaseVersion}](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts) | it | | |
|
||||
| [should hide CIS_GCP Launch Cloud shell button when package version is ${previousPackageVersion}](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts) | it | | |
|
||||
| [cloud_security_posture](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/index.ts) | describe | | |
|
||||
| [Cloud Posture Dashboard Page](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/compliance_dashboard.ts) | describe | | |
|
||||
| [Kubernetes Dashboard](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/compliance_dashboard.ts) | describe | | |
|
||||
| [displays accurate summary compliance score](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/compliance_dashboard.ts) | it | | |
|
||||
| [[Essentials PLI] Test Cloud Security Posture Integrations on Serverless](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/csp_integrations_form.essentials.ts) | describe | | |
|
||||
| [[Essentials PLI] Integration installation form should be available with Essentials or Complete PLI](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/csp_integrations_form.essentials.ts) | it | | |
|
||||
| [Test Cloud Security Posture Integrations on Serverless](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/csp_integrations_form.ts) | describe | | |
|
||||
| [Integration installation form should not be available without required PLI](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/csp_integrations_form.ts) | it | | |
|
||||
| [cloud_security_posture](x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/index.ts) | describe | | |
|
||||
</details>
|
||||
|
||||
|
@ -620,19 +654,19 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
|
||||
## Directory: x-pack/test/cloud_security_posture_api
|
||||
|
||||
**Total Tests:** 35 | **Skipped:** 4 (11.43%) | **Todo:** 0 (0.00%)
|
||||
**Total Tests:** 35 | **Skipped:** 0 (0.00%) | **Todo:** 0 (0.00%)
|
||||
|
||||
  
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>Test Details</summary>
|
||||
|
||||
| Test Label | Type | Skipped | Todo |
|
||||
|------------|------|---------|------|
|
||||
| [GET /internal/cloud_security_posture/benchmarks](x-pack/test/cloud_security_posture_api/routes/benchmarks.ts) | describe |  | |
|
||||
| [Get Benchmark API](x-pack/test/cloud_security_posture_api/routes/benchmarks.ts) | describe |  | |
|
||||
| [Verify cspm benchmark score is updated when muting rules](x-pack/test/cloud_security_posture_api/routes/benchmarks.ts) | it |  | |
|
||||
| [Verify kspm benchmark score is updated when muting rules](x-pack/test/cloud_security_posture_api/routes/benchmarks.ts) | it |  | |
|
||||
| [GET /internal/cloud_security_posture/benchmarks](x-pack/test/cloud_security_posture_api/routes/benchmarks.ts) | describe | | |
|
||||
| [Get Benchmark API](x-pack/test/cloud_security_posture_api/routes/benchmarks.ts) | describe | | |
|
||||
| [Verify cspm benchmark score is updated when muting rules](x-pack/test/cloud_security_posture_api/routes/benchmarks.ts) | it | | |
|
||||
| [Verify kspm benchmark score is updated when muting rules](x-pack/test/cloud_security_posture_api/routes/benchmarks.ts) | it | | |
|
||||
| [Verify update csp rules states API](x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts) | describe | | |
|
||||
| [mute benchmark rules successfully](x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts) | it | | |
|
||||
| [unmute rules successfully](x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts) | it | | |
|
||||
|
@ -668,7 +702,7 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
|
||||
## Directory: x-pack/test/cloud_security_posture_functional
|
||||
|
||||
**Total Tests:** 202 | **Skipped:** 41 (20.30%) | **Todo:** 3 (1.49%)
|
||||
**Total Tests:** 201 | **Skipped:** 71 (35.32%) | **Todo:** 3 (1.49%)
|
||||
|
||||
  
|
||||
|
||||
|
@ -677,6 +711,15 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
|
||||
| Test Label | Type | Skipped | Todo |
|
||||
|------------|------|---------|------|
|
||||
| [Cloud Posture Dashboard Page](x-pack/test/cloud_security_posture_functional/cloud_tests/basic_ui_sanity.ts) | describe | | |
|
||||
| [Cloud Dashboard](x-pack/test/cloud_security_posture_functional/cloud_tests/basic_ui_sanity.ts) | describe | | |
|
||||
| [displays compliance score greater than 40](x-pack/test/cloud_security_posture_functional/cloud_tests/basic_ui_sanity.ts) | it | | |
|
||||
| [displays all compliance scores](x-pack/test/cloud_security_posture_functional/cloud_tests/basic_ui_sanity.ts) | it | | |
|
||||
| [displays a number of resources evaluated greater than 3000](x-pack/test/cloud_security_posture_functional/cloud_tests/basic_ui_sanity.ts) | it | | |
|
||||
| [Kubernetes Dashboard](x-pack/test/cloud_security_posture_functional/cloud_tests/basic_ui_sanity.ts) | describe | | |
|
||||
| [displays compliance score greater than 80](x-pack/test/cloud_security_posture_functional/cloud_tests/basic_ui_sanity.ts) | it | | |
|
||||
| [displays a number of resources evaluated greater than 150](x-pack/test/cloud_security_posture_functional/cloud_tests/basic_ui_sanity.ts) | it | | |
|
||||
| [Cloud Security Posture](x-pack/test/cloud_security_posture_functional/cloud_tests/index.ts) | describe | | |
|
||||
| [Access with custom roles](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | describe | | |
|
||||
| [Access with valid user role](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | it |  | |
|
||||
| [Access with invalid user role](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | it |  | |
|
||||
|
@ -684,16 +727,16 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
| [Access with valid user role](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | it | | |
|
||||
| [Access with invalid user role](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | it |  | |
|
||||
| [Test adding Cloud Security Posture Integrations CNVM](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | describe | | |
|
||||
| [CNVM AWS](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | describe | | |
|
||||
| [Hyperlink on PostInstallation Modal should have the correct URL](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | it | | |
|
||||
| [On Add Agent modal there should be modal that has Cloud Formation details as well as button that redirects user to Cloud formation page on AWS upon clicking them ](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | it | | |
|
||||
| [Clicking on Launch CloudFormation on post intall modal should lead user to Cloud Formation page](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | it | | |
|
||||
| [CNVM AWS](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | describe |  | |
|
||||
| [Hyperlink on PostInstallation Modal should have the correct URL](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | it |  | |
|
||||
| [On Add Agent modal there should be modal that has Cloud Formation details as well as button that redirects user to Cloud formation page on AWS upon clicking them ](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | it |  | |
|
||||
| [Clicking on Launch CloudFormation on post intall modal should lead user to Cloud Formation page](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | it |  | |
|
||||
| [Test adding Cloud Security Posture Integrations CSPM AWS](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | describe | | |
|
||||
| [CIS_AWS Organization Cloud Formation](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | describe | | |
|
||||
| [Initial form state, AWS Org account, and CloudFormation should be selected by default](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | it | | |
|
||||
| [Hyperlink on PostInstallation Modal should have the correct URL](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | it | | |
|
||||
| [On Add Agent modal there should be modal that has Cloud Formation details as well as button that redirects user to Cloud formation page on AWS upon clicking them ](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | it | | |
|
||||
| [Clicking on Launch CloudFormation on post intall modal should lead user to Cloud Formation page](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | it | | |
|
||||
| [CIS_AWS Organization Cloud Formation](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | describe |  | |
|
||||
| [Initial form state, AWS Org account, and CloudFormation should be selected by default](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | it |  | |
|
||||
| [Hyperlink on PostInstallation Modal should have the correct URL](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | it |  | |
|
||||
| [On Add Agent modal there should be modal that has Cloud Formation details as well as button that redirects user to Cloud formation page on AWS upon clicking them ](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | it |  | |
|
||||
| [Clicking on Launch CloudFormation on post intall modal should lead user to Cloud Formation page](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | it |  | |
|
||||
| [CIS_AWS Organization Manual Assume Role](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | describe | | |
|
||||
| [CIS_AWS Organization Manual Assume Role Workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | it | | |
|
||||
| [CIS_AWS Organization Manual Direct Access](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_aws.ts) | describe | | |
|
||||
|
@ -729,37 +772,37 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
| [Azure Single Manual Service Principle with Client Secret Workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_azure.ts) | it | | |
|
||||
| [Azure Single Manual Service Principle with Client Certificate](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_azure.ts) | describe | | |
|
||||
| [Azure Single Manual Service Principle with Client Certificate Workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_azure.ts) | it | | |
|
||||
| [Test adding Cloud Security Posture Integrations CSPM GCP](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | describe | | |
|
||||
| [CIS_GCP Organization](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | describe | | |
|
||||
| [Switch between Manual and Google cloud shell](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Post Installation Google Cloud Shell modal pops up after user clicks on Save button when adding integration, when there are no Project ID or Organization ID provided, it should use default value](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Post Installation Google Cloud Shell modal pops up after user clicks on Save button when adding integration, when there are Project ID or Organization ID provided, it should use that value](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Add Agent FLyout - Post Installation Google Cloud Shell modal pops up after user clicks on Save button when adding integration, when there are Project ID or Organization ID provided, it should use that value](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Organization ID field on cloud shell command should only be shown if user chose Google Cloud Shell, if user chose Single Account it shouldn not show up](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Hyperlink on PostInstallation Modal should have the correct URL](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Clicking on Launch CloudShell on post intall modal should lead user to CloudShell page](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [CIS_GCP Organization Credentials File](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | describe | | |
|
||||
| [CIS_GCP Organization Credentials File workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [CIS_GCP Organization Credentials JSON](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | describe | | |
|
||||
| [CIS_GCP Organization Credentials JSON workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [CIS_GCP Single](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | describe | | |
|
||||
| [Post Installation Google Cloud Shell modal pops up after user clicks on Save button when adding integration, when there are no Project ID, it should use default value](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Post Installation Google Cloud Shell modal pops up after user clicks on Save button when adding integration, when there are Project ID, it should use that value](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Add Agent FLyout - Organization ID field on cloud shell command should only be shown if user chose Google Cloud Shell, if user chose Single Account it shouldn not show up](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [On add agent modal, if user chose Google Cloud Shell as their setup access; a google cloud shell modal should show up and clicking on the launch button will redirect user to Google cloud shell page](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Users are able to add CIS_GCP Integration with Manual settings using Credentials File](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Users are able to switch credentials_type from/to Credential JSON fields ](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Users are able to add CIS_GCP Integration with Manual settings using Credentials JSON](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Users are able to switch credentials_type from/to Credential File fields ](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it | | |
|
||||
| [Test adding Cloud Security Posture Integrations CSPM GCP](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | describe |  | |
|
||||
| [CIS_GCP Organization](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | describe |  | |
|
||||
| [Switch between Manual and Google cloud shell](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Post Installation Google Cloud Shell modal pops up after user clicks on Save button when adding integration, when there are no Project ID or Organization ID provided, it should use default value](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Post Installation Google Cloud Shell modal pops up after user clicks on Save button when adding integration, when there are Project ID or Organization ID provided, it should use that value](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Add Agent FLyout - Post Installation Google Cloud Shell modal pops up after user clicks on Save button when adding integration, when there are Project ID or Organization ID provided, it should use that value](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Organization ID field on cloud shell command should only be shown if user chose Google Cloud Shell, if user chose Single Account it shouldn not show up](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Hyperlink on PostInstallation Modal should have the correct URL](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Clicking on Launch CloudShell on post intall modal should lead user to CloudShell page](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [CIS_GCP Organization Credentials File](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | describe |  | |
|
||||
| [CIS_GCP Organization Credentials File workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [CIS_GCP Organization Credentials JSON](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | describe |  | |
|
||||
| [CIS_GCP Organization Credentials JSON workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [CIS_GCP Single](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | describe |  | |
|
||||
| [Post Installation Google Cloud Shell modal pops up after user clicks on Save button when adding integration, when there are no Project ID, it should use default value](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Post Installation Google Cloud Shell modal pops up after user clicks on Save button when adding integration, when there are Project ID, it should use that value](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Add Agent FLyout - Organization ID field on cloud shell command should only be shown if user chose Google Cloud Shell, if user chose Single Account it shouldn not show up](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [On add agent modal, if user chose Google Cloud Shell as their setup access; a google cloud shell modal should show up and clicking on the launch button will redirect user to Google cloud shell page](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Users are able to add CIS_GCP Integration with Manual settings using Credentials File](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Users are able to switch credentials_type from/to Credential JSON fields ](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Users are able to add CIS_GCP Integration with Manual settings using Credentials JSON](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Users are able to switch credentials_type from/to Credential File fields ](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cspm/cis_integration_gcp.ts) | it |  | |
|
||||
| [Test adding Cloud Security Posture Integrations KSPM EKS](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | describe | | |
|
||||
| [KSPM EKS Assume Role](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | describe | | |
|
||||
| [KSPM EKS Assume Role workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | it | | |
|
||||
| [KSPM EKS Direct Access](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | describe | | |
|
||||
| [KSPM EKS Direct Access Workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | it | | |
|
||||
| [KSPM EKS Temporary Keys](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | describe | | |
|
||||
| [KSPM EKS Temporary Keys Workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | it | | |
|
||||
| [KSPM EKS Shared Credentials](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | describe | | |
|
||||
| [KSPM EKS Shared Credentials Workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | it | | |
|
||||
| [KSPM EKS Assume Role](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | describe |  | |
|
||||
| [KSPM EKS Assume Role workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | it |  | |
|
||||
| [KSPM EKS Direct Access](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | describe |  | |
|
||||
| [KSPM EKS Direct Access Workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | it |  | |
|
||||
| [KSPM EKS Temporary Keys](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | describe |  | |
|
||||
| [KSPM EKS Temporary Keys Workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | it |  | |
|
||||
| [KSPM EKS Shared Credentials](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | describe |  | |
|
||||
| [KSPM EKS Shared Credentials Workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_eks.ts) | it |  | |
|
||||
| [Test adding Cloud Security Posture Integrations KSPM K8S](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_k8s.ts) | describe | | |
|
||||
| [KSPM K8S](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_k8s.ts) | describe | | |
|
||||
| [KSPM K8S Workflow](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/kspm/cis_integration_k8s.ts) | it | | |
|
||||
|
@ -772,9 +815,9 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
| [Access with valid user role](x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts) | it | | |
|
||||
| [todo - Access with invalid user role](x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts) | it |  |  |
|
||||
| [Findings Page - Alerts](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | describe | | |
|
||||
| [Create detection rule](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | describe |  | |
|
||||
| [Creates a detection rule from the Take Action button and navigates to rule page](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | it |  | |
|
||||
| [Creates a detection rule from the Alerts section and navigates to rule page](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | it |  | |
|
||||
| [Create detection rule](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | describe | | |
|
||||
| [Creates a detection rule from the Take Action button and navigates to rule page](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | it | | |
|
||||
| [Creates a detection rule from the Alerts section and navigates to rule page](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | it | | |
|
||||
| [Rule details](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | describe | | |
|
||||
| [The rule page contains the expected matching data](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | it | | |
|
||||
| [Navigation](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | describe | | |
|
||||
|
@ -803,16 +846,8 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
| [clicking on the ](x-pack/test/cloud_security_posture_functional/pages/findings_onboarding.ts) | it | | |
|
||||
| [clicking on the ](x-pack/test/cloud_security_posture_functional/pages/findings_onboarding.ts) | it | | |
|
||||
| [Findings Page - DataTable](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | describe | | |
|
||||
| [SearchBar](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | describe |  | |
|
||||
| [add filter](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it |  | |
|
||||
| [remove filter](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it |  | |
|
||||
| [set search query](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it |  | |
|
||||
| [Table Sort](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | describe |  | |
|
||||
| [sorts by a column, should be case sensitive/insensitive depending on the column](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it |  | |
|
||||
| [DistributionBar](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | describe | | |
|
||||
| [filters by ${type} findings](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it | | |
|
||||
| [DataTable features](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | describe | | |
|
||||
| [Edit data view field option is Enabled](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it | | |
|
||||
| [Table Sort](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | describe | | |
|
||||
| [sorts by a column, should be case sensitive/insensitive depending on the column](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it | | |
|
||||
| [Findings - Fields selector](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | describe | | |
|
||||
| [Add fields to the Findings DataTable](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it | | |
|
||||
| [Remove fields from the Findings DataTable](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it | | |
|
||||
|
@ -867,8 +902,6 @@ You can also check out the dedicated app view, which enables easier search and f
|
|||
| [add filter](x-pack/test/cloud_security_posture_functional/pages/vulnerabilities.ts) | it | | |
|
||||
| [remove filter](x-pack/test/cloud_security_posture_functional/pages/vulnerabilities.ts) | it | | |
|
||||
| [set search query](x-pack/test/cloud_security_posture_functional/pages/vulnerabilities.ts) | it | | |
|
||||
| [DataTable features](x-pack/test/cloud_security_posture_functional/pages/vulnerabilities.ts) | describe | | |
|
||||
| [Edit data view field option is Enabled](x-pack/test/cloud_security_posture_functional/pages/vulnerabilities.ts) | it | | |
|
||||
| [Vulnerabilities - Fields selector](x-pack/test/cloud_security_posture_functional/pages/vulnerabilities.ts) | describe | | |
|
||||
| [Add fields to the Vulnerabilities DataTable](x-pack/test/cloud_security_posture_functional/pages/vulnerabilities.ts) | it | | |
|
||||
| [Remove fields from the Vulnerabilities DataTable](x-pack/test/cloud_security_posture_functional/pages/vulnerabilities.ts) | it | | |
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
// TODO: this needs to be defined in a versioned schema
|
||||
import type { EcsEvent } from '@elastic/ecs';
|
||||
import type { EcsDataStream, EcsEvent } from '@elastic/ecs';
|
||||
import { CspBenchmarkRuleMetadata } from '../types/latest';
|
||||
|
||||
export interface CspFinding {
|
||||
|
@ -19,6 +19,7 @@ export interface CspFinding {
|
|||
rule: CspBenchmarkRuleMetadata;
|
||||
host: CspFindingHost;
|
||||
event: EcsEvent;
|
||||
data_stream: EcsDataStream;
|
||||
agent: CspFindingAgent;
|
||||
ecs: {
|
||||
version: string;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -29,7 +29,7 @@ export const convertRuleTagsToMatchAnyKQL = (tags: string[]): string => {
|
|||
export const getFindingsDetectionRuleSearchTags = (
|
||||
cspBenchmarkRule: CspBenchmarkRuleMetadata
|
||||
): string[] => {
|
||||
if (!cspBenchmarkRule.benchmark || !cspBenchmarkRule.benchmark.id) {
|
||||
if (!cspBenchmarkRule?.benchmark || !cspBenchmarkRule?.benchmark?.id) {
|
||||
// Return an empty array if benchmark ID is undefined
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -27,10 +27,12 @@ export const useFetchDetectionRulesAlertsStatus = (tags: string[]) => {
|
|||
throw new Error('Kibana http service is not available');
|
||||
}
|
||||
|
||||
return useQuery<AlertStatus, Error>([DETECTION_ENGINE_ALERTS_KEY, tags], () =>
|
||||
http.get<AlertStatus>(GET_DETECTION_RULE_ALERTS_STATUS_PATH, {
|
||||
version: DETECTION_RULE_ALERTS_STATUS_API_CURRENT_VERSION,
|
||||
query: { tags },
|
||||
})
|
||||
);
|
||||
return useQuery<AlertStatus, Error>({
|
||||
queryKey: [DETECTION_ENGINE_ALERTS_KEY, tags],
|
||||
queryFn: () =>
|
||||
http.get<AlertStatus>(GET_DETECTION_RULE_ALERTS_STATUS_PATH, {
|
||||
version: DETECTION_RULE_ALERTS_STATUS_API_CURRENT_VERSION,
|
||||
query: { tags },
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
type Dataset = 'wiz.cloud_configuration_finding' | 'cloud_security_posture.findings';
|
||||
|
||||
export const WIZ_DATASET = 'wiz.cloud_configuration_finding';
|
||||
export const CSP_DATASET = 'cloud_security_posture.findings';
|
||||
|
||||
export const getDatasetDisplayName = (dataset?: Dataset | string) => {
|
||||
if (dataset === WIZ_DATASET) return 'Wiz';
|
||||
if (dataset === CSP_DATASET) return 'Elastic CSP';
|
||||
};
|
|
@ -19,8 +19,8 @@ interface Props {
|
|||
size?: IconSize;
|
||||
}
|
||||
|
||||
const getBenchmarkIdIconType = (props: Props): string => {
|
||||
switch (props.type) {
|
||||
const getBenchmarkIdIconType = (type: BenchmarkId): string | undefined => {
|
||||
switch (type) {
|
||||
case 'cis_eks':
|
||||
return cisEksIcon;
|
||||
case 'cis_azure':
|
||||
|
@ -30,13 +30,17 @@ const getBenchmarkIdIconType = (props: Props): string => {
|
|||
case 'cis_gcp':
|
||||
return googleCloudLogo;
|
||||
case 'cis_k8s':
|
||||
default:
|
||||
return 'logoKubernetes';
|
||||
}
|
||||
};
|
||||
|
||||
export const CISBenchmarkIcon = (props: Props) => (
|
||||
<EuiToolTip content={props.name}>
|
||||
<EuiIcon type={getBenchmarkIdIconType(props)} size={props.size || 'xl'} css={props.style} />
|
||||
</EuiToolTip>
|
||||
);
|
||||
export const CISBenchmarkIcon = (props: Props) => {
|
||||
const iconType = getBenchmarkIdIconType(props.type);
|
||||
if (!iconType) return <></>;
|
||||
|
||||
return (
|
||||
<EuiToolTip content={props.name}>
|
||||
<EuiIcon type={iconType} size={props.size || 'xl'} css={props.style} />
|
||||
</EuiToolTip>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ import { css } from '@emotion/react';
|
|||
import { statusColors } from '../common/constants';
|
||||
|
||||
interface Props {
|
||||
type: 'passed' | 'failed';
|
||||
type?: 'passed' | 'failed';
|
||||
}
|
||||
|
||||
// 'fail' / 'pass' are same chars length, but not same width size.
|
||||
|
@ -37,8 +37,10 @@ export const CspEvaluationBadge = ({ type }: Props) => (
|
|||
>
|
||||
{type === 'failed' ? (
|
||||
<FormattedMessage id="xpack.csp.cspEvaluationBadge.failLabel" defaultMessage="Fail" />
|
||||
) : (
|
||||
) : type === 'passed' ? (
|
||||
<FormattedMessage id="xpack.csp.cspEvaluationBadge.passLabel" defaultMessage="Pass" />
|
||||
) : (
|
||||
<FormattedMessage id="xpack.csp.cspEvaluationBadge.naLabel" defaultMessage="N/A" />
|
||||
)}
|
||||
</EuiBadge>
|
||||
);
|
||||
|
|
|
@ -31,7 +31,11 @@ interface DetectionRuleCounterProps {
|
|||
|
||||
export const DetectionRuleCounter = ({ tags, createRuleFn }: DetectionRuleCounterProps) => {
|
||||
const { data: rulesData, isLoading: ruleIsLoading } = useFetchDetectionRulesByTags(tags);
|
||||
const { data: alertsData, isLoading: alertsIsLoading } = useFetchDetectionRulesAlertsStatus(tags);
|
||||
const {
|
||||
data: alertsData,
|
||||
isLoading: alertsIsLoading,
|
||||
isError: alertsIsError,
|
||||
} = useFetchDetectionRulesAlertsStatus(tags);
|
||||
|
||||
const [isCreateRuleLoading, setIsCreateRuleLoading] = useState(false);
|
||||
|
||||
|
@ -68,6 +72,8 @@ export const DetectionRuleCounter = ({ tags, createRuleFn }: DetectionRuleCounte
|
|||
queryClient.invalidateQueries([DETECTION_ENGINE_ALERTS_KEY]);
|
||||
}, [createRuleFn, http, analytics, notifications, i18n, theme, queryClient]);
|
||||
|
||||
if (alertsIsError) return <>{'-'}</>;
|
||||
|
||||
return (
|
||||
<EuiSkeletonText
|
||||
data-test-subj="csp:detection-rule-counter-loading"
|
||||
|
|
|
@ -115,4 +115,84 @@ export const mockFindingsHit: CspFinding = {
|
|||
category: ['configuration'],
|
||||
outcome: 'success',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
};
|
||||
|
||||
export const mockWizFinding = {
|
||||
agent: {
|
||||
name: 'ip-172-31-29-186.eu-west-1.compute.internal',
|
||||
id: 'd66400e6-6224-489a-aae5-0dd529e7b61a',
|
||||
ephemeral_id: '3159ed3a-8517-4289-9c4c-ab15abc7f938',
|
||||
type: 'filebeat',
|
||||
version: '8.14.1',
|
||||
},
|
||||
resource: {
|
||||
name: 'annam-instance-group-61wh',
|
||||
id: '45860879-12db-5fce-838d-eb4deac2a544',
|
||||
},
|
||||
elastic_agent: {
|
||||
id: 'd66400e6-6224-489a-aae5-0dd529e7b61a',
|
||||
version: '8.14.1',
|
||||
snapshot: false,
|
||||
},
|
||||
wiz: {
|
||||
cloud_configuration_finding: {
|
||||
rule: {
|
||||
id: '02fde46d-ba1c-405e-b20f-a3742a8d2f41',
|
||||
},
|
||||
},
|
||||
},
|
||||
rule: {
|
||||
name: 'Unattached volume for more than 7 days',
|
||||
id: '02fde46d-ba1c-405e-b20f-a3742a8d2f41',
|
||||
},
|
||||
message:
|
||||
"This rule checks if Compute Disks have been unattached for more than 7 days. \nThis rule fails if a disk's status is `READY`, it has no users attached, and the `lastDetachTimestamp` is more than 7 days ago. \nUnattached disks can incur costs without providing any benefits and may also pose a security risk if they contain sensitive data that is not being used. It is recommended to either delete unattached disks that are no longer needed or reattach them to a relevant instance.",
|
||||
tags: ['preserve_original_event', 'forwarded', 'wiz-cloud_configuration_finding'],
|
||||
cloud: {
|
||||
availability_zone: 'eu-west-1b',
|
||||
image: {
|
||||
id: 'ami-0551ce4d67096d606',
|
||||
},
|
||||
instance: {
|
||||
id: 'i-0d3beee17a99bf575',
|
||||
},
|
||||
provider: 'GCP',
|
||||
service: {
|
||||
name: 'EC2',
|
||||
},
|
||||
machine: {
|
||||
type: 't2.micro',
|
||||
},
|
||||
region: 'us-central1',
|
||||
account: {
|
||||
id: '704479110758',
|
||||
},
|
||||
},
|
||||
input: {
|
||||
type: 'cel',
|
||||
},
|
||||
'@timestamp': '2024-07-15T10:00:16.283Z',
|
||||
ecs: {
|
||||
version: '8.11.0',
|
||||
},
|
||||
data_stream: {
|
||||
namespace: 'default',
|
||||
type: 'logs',
|
||||
dataset: 'wiz.cloud_configuration_finding',
|
||||
},
|
||||
event: {
|
||||
agent_id_status: 'auth_metadata_missing',
|
||||
ingested: '2024-07-15T10:49:45Z',
|
||||
original:
|
||||
'{"analyzedAt":"2024-07-15T10:00:16.283504Z","firstSeenAt":"2024-07-15T10:00:22.271901Z","id":"fd5b53a4-d85c-5d3a-b0bf-2eb270582db5","ignoreRules":null,"remediation":null,"resource":{"id":"45860879-12db-5fce-838d-eb4deac2a544","name":"annam-instance-group-61wh","nativeType":"compute#disk","projects":[{"id":"0f19bcc4-c17b-57d0-a187-db3a6b1a5100","name":"Project 3","riskProfile":{"businessImpact":"MBI"}}],"providerId":"https://www.googleapis.com/compute/v1/projects/my-walla-website/zones/us-central1-c/disks/annam-instance-group-61wh","region":"us-central1","subscription":{"cloudProvider":"GCP","externalId":"my-walla-website","id":"64982819-64ed-5c02-8a73-93d25fef8d89","name":"Product Integration"},"tags":[],"type":"VOLUME"},"result":"PASS","rule":{"description":"This rule checks if Compute Disks have been unattached for more than 7 days. \\nThis rule fails if a disk\'s status is `READY`, it has no users attached, and the `lastDetachTimestamp` is more than 7 days ago. \\nUnattached disks can incur costs without providing any benefits and may also pose a security risk if they contain sensitive data that is not being used. It is recommended to either delete unattached disks that are no longer needed or reattach them to a relevant instance.","functionAsControl":false,"graphId":"60db4cc3-d5c8-5e76-8dc9-77dde142ba98","id":"02fde46d-ba1c-405e-b20f-a3742a8d2f41","name":"Unattached volume for more than 7 days","remediationInstructions":"Perform the following step in order to delete a disk via GCP CLI: \\n``` \\ngcloud compute disks delete {{DiskName}} --zone={{Zone}}\\n``` \\n\\u003e**Note** \\n\\u003eA disk can only be deleted if it is not attached to any virtual machine instances."},"securitySubCategories":[{"category":{"framework":{"id":"wf-id-120","name":"NIS2 Directive (Article 21)"},"id":"wct-id-2418","name":"Article 21 Cybersecurity risk-management measures"},"id":"wsct-id-18827","title":"21.2.1 The measures to protect network and information systems shall include policies on risk analysis and information system security"},{"category":{"framework":{"id":"wf-id-105","name":"Wiz (Legacy)"},"id":"wct-id-2136","name":"Operationalization"},"id":"wsct-id-5540","title":"Operationalization"},{"category":{"framework":{"id":"wf-id-1","name":"Wiz for Risk Assessment"},"id":"wct-id-940","name":"Operationalization"},"id":"wsct-id-6548","title":"Operationalization"},{"category":{"framework":{"id":"wf-id-78","name":"Wiz for Cost Optimization"},"id":"wct-id-1796","name":"Waste"},"id":"wsct-id-10216","title":"Storage"}],"severity":"NONE","status":"RESOLVED","targetExternalId":"1404039754344376914","targetObjectProviderUniqueId":"https://www.googleapis.com/compute/v1/projects/my-walla-website/zones/us-central1-c/disks/annam-instance-group-61wh"}',
|
||||
created: '2024-07-15T10:00:22.271Z',
|
||||
kind: 'event',
|
||||
id: 'fd5b53a4-d85c-5d3a-b0bf-2eb270582db5',
|
||||
category: ['configuration'],
|
||||
type: ['info'],
|
||||
dataset: 'wiz.cloud_configuration_finding',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -132,6 +132,9 @@ export const generateCspFinding = (
|
|||
dataset: 'cloud_security_posture.findings',
|
||||
outcome: 'success',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import userEvent from '@testing-library/user-event';
|
|||
import { FindingsRuleFlyout } from './findings_flyout';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { TestProvider } from '../../../test/test_provider';
|
||||
import { mockFindingsHit } from '../__mocks__/findings';
|
||||
import { mockFindingsHit, mockWizFinding } from '../__mocks__/findings';
|
||||
import { LATEST_FINDINGS_INDEX_DEFAULT_NS } from '../../../../common/constants';
|
||||
|
||||
const onPaginate = jest.fn();
|
||||
|
@ -21,7 +21,7 @@ const TestComponent = ({ ...overrideProps }) => (
|
|||
flyoutIndex={0}
|
||||
findingsCount={2}
|
||||
onPaginate={onPaginate}
|
||||
findings={mockFindingsHit}
|
||||
finding={mockFindingsHit}
|
||||
{...overrideProps}
|
||||
/>
|
||||
</TestProvider>
|
||||
|
@ -48,12 +48,22 @@ describe('<FindingsFlyout/>', () => {
|
|||
getAllByText(tag);
|
||||
});
|
||||
});
|
||||
|
||||
it('displays missing info callout when data source is not CSP', () => {
|
||||
const { getByText } = render(<TestComponent finding={mockWizFinding} />);
|
||||
getByText('Some fields not provided by Wiz');
|
||||
});
|
||||
|
||||
it('does not display missing info callout when data source is CSP', () => {
|
||||
const { queryByText } = render(<TestComponent finding={mockFindingsHit} />);
|
||||
const missingInfoCallout = queryByText('Some fields not provided by Wiz');
|
||||
expect(missingInfoCallout).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Rule Tab', () => {
|
||||
it('displays rule text details', () => {
|
||||
const { getByText, getAllByText } = render(<TestComponent />);
|
||||
|
||||
userEvent.click(screen.getByTestId('findings_flyout_tab_rule'));
|
||||
|
||||
getAllByText(mockFindingsHit.rule.name);
|
||||
|
@ -63,17 +73,49 @@ describe('<FindingsFlyout/>', () => {
|
|||
getAllByText(tag);
|
||||
});
|
||||
});
|
||||
|
||||
it('displays missing info callout when data source is not CSP', () => {
|
||||
const { getByText } = render(<TestComponent finding={mockWizFinding} />);
|
||||
userEvent.click(screen.getByTestId('findings_flyout_tab_rule'));
|
||||
|
||||
getByText('Some fields not provided by Wiz');
|
||||
});
|
||||
|
||||
it('does not display missing info callout when data source is CSP', () => {
|
||||
const { queryByText } = render(<TestComponent finding={mockFindingsHit} />);
|
||||
userEvent.click(screen.getByTestId('findings_flyout_tab_rule'));
|
||||
|
||||
const missingInfoCallout = queryByText('Some fields not provided by Wiz');
|
||||
expect(missingInfoCallout).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Table Tab', () => {
|
||||
it('displays resource name and id', () => {
|
||||
const { getAllByText } = render(<TestComponent />);
|
||||
|
||||
userEvent.click(screen.getByTestId('findings_flyout_tab_table'));
|
||||
|
||||
getAllByText(mockFindingsHit.resource.name);
|
||||
getAllByText(mockFindingsHit.resource.id);
|
||||
});
|
||||
|
||||
it('does not display missing info callout for 3Ps', () => {
|
||||
const { queryByText } = render(<TestComponent finding={mockWizFinding} />);
|
||||
userEvent.click(screen.getByTestId('findings_flyout_tab_table'));
|
||||
|
||||
const missingInfoCallout = queryByText('Some fields not provided by Wiz');
|
||||
expect(missingInfoCallout).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('JSON Tab', () => {
|
||||
it('does not display missing info callout for 3Ps', () => {
|
||||
const { queryByText } = render(<TestComponent finding={mockWizFinding} />);
|
||||
userEvent.click(screen.getByTestId('findings_flyout_tab_json'));
|
||||
|
||||
const missingInfoCallout = queryByText('Some fields not provided by Wiz');
|
||||
expect(missingInfoCallout).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow pagination with next', async () => {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
useEuiTheme,
|
||||
EuiFlexItem,
|
||||
EuiSpacer,
|
||||
EuiTextColor,
|
||||
|
@ -24,13 +25,17 @@ import {
|
|||
EuiFlyoutFooter,
|
||||
EuiToolTip,
|
||||
EuiDescriptionListProps,
|
||||
EuiCallOut,
|
||||
EuiLink,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { assertNever } from '@kbn/std';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { HttpSetup } from '@kbn/core/public';
|
||||
import { generatePath } from 'react-router-dom';
|
||||
import { css } from '@emotion/react';
|
||||
import { euiThemeVars } from '@kbn/ui-theme';
|
||||
import { CSP_DATASET, getDatasetDisplayName } from '../../../common/utils/get_dataset_display_name';
|
||||
import { truthy } from '../../../../common/utils/helpers';
|
||||
import { benchmarksNavigation } from '../../../common/navigation/constants';
|
||||
import cisLogoIcon from '../../../assets/icons/cis_logo.svg';
|
||||
|
@ -82,9 +87,11 @@ const PAGINATION_LABEL = i18n.translate('xpack.csp.findings.findingsFlyout.pagin
|
|||
|
||||
type FindingsTab = (typeof tabs)[number];
|
||||
|
||||
export const EMPTY_VALUE = '-';
|
||||
|
||||
interface FindingFlyoutProps {
|
||||
onClose(): void;
|
||||
findings: CspFinding;
|
||||
finding: CspFinding;
|
||||
flyoutIndex?: number;
|
||||
findingsCount?: number;
|
||||
onPaginate?: (pageIndex: number) => void;
|
||||
|
@ -98,7 +105,7 @@ export const CspFlyoutMarkdown: React.FC<PropsOf<typeof EuiMarkdownFormat>> = (p
|
|||
<EuiMarkdownFormat textSize="s" {...props} />
|
||||
);
|
||||
|
||||
export const CisKubernetesIcons = ({
|
||||
export const BenchmarkIcons = ({
|
||||
benchmarkId,
|
||||
benchmarkName,
|
||||
}: {
|
||||
|
@ -106,17 +113,41 @@ export const CisKubernetesIcons = ({
|
|||
benchmarkName: BenchmarkName;
|
||||
}) => (
|
||||
<EuiFlexGroup gutterSize="s" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiToolTip content="Center for Internet Security">
|
||||
<EuiIcon type={cisLogoIcon} size="xl" />
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
{benchmarkId.startsWith('cis') && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiToolTip content="Center for Internet Security">
|
||||
<EuiIcon type={cisLogoIcon} size="xl" />
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
<EuiFlexItem grow={false}>
|
||||
<CISBenchmarkIcon type={benchmarkId} name={benchmarkName} />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
||||
export const RuleNameLink = ({
|
||||
ruleFlyoutLink,
|
||||
ruleName,
|
||||
}: {
|
||||
ruleFlyoutLink?: string;
|
||||
ruleName: string;
|
||||
}) => {
|
||||
return ruleFlyoutLink && ruleName ? (
|
||||
<EuiToolTip
|
||||
position="top"
|
||||
content={i18n.translate(
|
||||
'xpack.csp.findings.findingsFlyout.ruleNameTabField.ruleNameTooltip',
|
||||
{ defaultMessage: 'Manage Rule' }
|
||||
)}
|
||||
>
|
||||
<EuiLink href={ruleFlyoutLink}>{ruleName}</EuiLink>
|
||||
</EuiToolTip>
|
||||
) : (
|
||||
<>{ruleName}</>
|
||||
);
|
||||
};
|
||||
|
||||
const getFlyoutDescriptionList = (finding: CspFinding): EuiDescriptionListProps['listItems'] =>
|
||||
[
|
||||
finding.resource?.id && {
|
||||
|
@ -134,34 +165,71 @@ const getFlyoutDescriptionList = (finding: CspFinding): EuiDescriptionListProps[
|
|||
},
|
||||
].filter(truthy);
|
||||
|
||||
const FindingsTab = ({ tab, findings }: { findings: CspFinding; tab: FindingsTab }) => {
|
||||
const FindingsTab = ({ tab, finding }: { finding: CspFinding; tab: FindingsTab }) => {
|
||||
const { application } = useKibana().services;
|
||||
|
||||
const ruleFlyoutLink = application.getUrlForApp('security', {
|
||||
path: generatePath(benchmarksNavigation.rules.path, {
|
||||
benchmarkVersion: findings.rule.benchmark.version.split('v')[1], // removing the v from the version
|
||||
benchmarkId: findings.rule.benchmark.id,
|
||||
ruleId: findings.rule.id,
|
||||
}),
|
||||
});
|
||||
const ruleFlyoutLink =
|
||||
// currently we only support rule linking for native CSP findings
|
||||
finding.data_stream.dataset === CSP_DATASET &&
|
||||
finding.rule?.benchmark?.version &&
|
||||
finding.rule?.benchmark?.id &&
|
||||
finding.rule?.id
|
||||
? application.getUrlForApp('security', {
|
||||
path: generatePath(benchmarksNavigation.rules.path, {
|
||||
benchmarkVersion: finding.rule.benchmark.version.split('v')[1], // removing the v from the version
|
||||
benchmarkId: finding.rule.benchmark.id,
|
||||
ruleId: finding.rule.id,
|
||||
}),
|
||||
})
|
||||
: undefined;
|
||||
|
||||
switch (tab.id) {
|
||||
case 'overview':
|
||||
return <OverviewTab data={findings} ruleFlyoutLink={ruleFlyoutLink} />;
|
||||
return <OverviewTab data={finding} ruleFlyoutLink={ruleFlyoutLink} />;
|
||||
case 'rule':
|
||||
return <RuleTab data={findings} ruleFlyoutLink={ruleFlyoutLink} />;
|
||||
return <RuleTab data={finding} ruleFlyoutLink={ruleFlyoutLink} />;
|
||||
case 'table':
|
||||
return <TableTab data={findings} />;
|
||||
return <TableTab data={finding} />;
|
||||
case 'json':
|
||||
return <JsonTab data={findings} />;
|
||||
return <JsonTab data={finding} />;
|
||||
default:
|
||||
assertNever(tab);
|
||||
}
|
||||
};
|
||||
|
||||
const isNativeCspFinding = (finding: CspFinding) => finding.data_stream.dataset === CSP_DATASET;
|
||||
|
||||
const MissingFieldsCallout = ({ finding }: { finding: CspFinding }) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const datasetDisplayName =
|
||||
getDatasetDisplayName(finding.data_stream.dataset) || finding.data_stream.dataset;
|
||||
|
||||
return (
|
||||
<EuiCallOut
|
||||
style={{
|
||||
borderRadius: 4,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
size="s"
|
||||
iconType="iInCircle"
|
||||
title={
|
||||
<span style={{ color: euiTheme.colors.text }}>
|
||||
<FormattedMessage
|
||||
id="xpack.csp.findings.findingsFlyout.calloutTitle"
|
||||
defaultMessage="Some fields not provided by {datasource}"
|
||||
values={{
|
||||
datasource: datasetDisplayName || 'the data source',
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const FindingsRuleFlyout = ({
|
||||
onClose,
|
||||
findings,
|
||||
finding,
|
||||
flyoutIndex,
|
||||
findingsCount,
|
||||
onPaginate,
|
||||
|
@ -169,19 +237,19 @@ export const FindingsRuleFlyout = ({
|
|||
const [tab, setTab] = useState<FindingsTab>(tabs[0]);
|
||||
|
||||
const createMisconfigurationRuleFn = async (http: HttpSetup) =>
|
||||
await createDetectionRuleFromBenchmarkRule(http, findings.rule);
|
||||
await createDetectionRuleFromBenchmarkRule(http, finding.rule);
|
||||
|
||||
return (
|
||||
<EuiFlyout onClose={onClose} data-test-subj={FINDINGS_FLYOUT}>
|
||||
<EuiFlyoutHeader>
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<CspEvaluationBadge type={findings.result.evaluation} />
|
||||
<CspEvaluationBadge type={finding.result?.evaluation} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow style={{ minWidth: 0 }}>
|
||||
<EuiTitle size="m" className="eui-textTruncate">
|
||||
<EuiTextColor color="primary" title={findings.rule.name}>
|
||||
{findings.rule.name}
|
||||
<EuiTextColor color="primary" title={finding.rule?.name}>
|
||||
{finding.rule?.name}
|
||||
</EuiTextColor>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
|
@ -194,7 +262,7 @@ export const FindingsRuleFlyout = ({
|
|||
>
|
||||
<CspInlineDescriptionList
|
||||
testId={FINDINGS_MISCONFIGS_FLYOUT_DESCRIPTION_LIST}
|
||||
listItems={getFlyoutDescriptionList(findings)}
|
||||
listItems={getFlyoutDescriptionList(finding)}
|
||||
/>
|
||||
</div>
|
||||
<EuiSpacer />
|
||||
|
@ -212,7 +280,12 @@ export const FindingsRuleFlyout = ({
|
|||
</EuiTabs>
|
||||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody key={tab.id}>
|
||||
<FindingsTab tab={tab} findings={findings} />
|
||||
{!isNativeCspFinding(finding) && ['overview', 'rule'].includes(tab.id) && (
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
<MissingFieldsCallout finding={finding} />
|
||||
</div>
|
||||
)}
|
||||
<FindingsTab tab={tab} finding={finding} />
|
||||
</EuiFlyoutBody>
|
||||
<EuiFlyoutFooter>
|
||||
<EuiFlexGroup
|
||||
|
|
|
@ -10,14 +10,12 @@ import { CodeEditor } from '@kbn/code-editor';
|
|||
import { XJsonLang } from '@kbn/monaco';
|
||||
import { CspFinding } from '../../../../common/schemas/csp_finding';
|
||||
|
||||
const offsetTopHeight = 120;
|
||||
const offsetBottomHeight = 72;
|
||||
|
||||
export const JsonTab = ({ data }: { data: CspFinding }) => (
|
||||
<div style={{ position: 'absolute', inset: 0, top: offsetTopHeight, bottom: offsetBottomHeight }}>
|
||||
<div style={{ position: 'absolute', inset: 0 }}>
|
||||
<CodeEditor
|
||||
isCopyable
|
||||
allowFullScreen
|
||||
enableFindAction
|
||||
languageId={XJsonLang.ID}
|
||||
value={JSON.stringify(data, null, 2)}
|
||||
options={{
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
EuiPanel,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import React, { useMemo } from 'react';
|
||||
import moment from 'moment';
|
||||
|
@ -21,6 +20,7 @@ import type { EuiDescriptionListProps, EuiAccordionProps } from '@elastic/eui';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { getDatasetDisplayName } from '../../../common/utils/get_dataset_display_name';
|
||||
import { truthy } from '../../../../common/utils/helpers';
|
||||
import { CSP_MOMENT_FORMAT } from '../../../common/constants';
|
||||
import {
|
||||
|
@ -31,26 +31,31 @@ import {
|
|||
import { useDataView } from '../../../common/api/use_data_view';
|
||||
import { useKibana } from '../../../common/hooks/use_kibana';
|
||||
import { CspFinding } from '../../../../common/schemas/csp_finding';
|
||||
import { CisKubernetesIcons, CodeBlock, CspFlyoutMarkdown } from './findings_flyout';
|
||||
import {
|
||||
BenchmarkIcons,
|
||||
CodeBlock,
|
||||
CspFlyoutMarkdown,
|
||||
EMPTY_VALUE,
|
||||
RuleNameLink,
|
||||
} from './findings_flyout';
|
||||
import { FindingsDetectionRuleCounter } from './findings_detection_rule_counter';
|
||||
|
||||
type Accordion = Pick<EuiAccordionProps, 'title' | 'id' | 'initialIsOpen'> &
|
||||
Pick<EuiDescriptionListProps, 'listItems'>;
|
||||
|
||||
const getDetailsList = (data: CspFinding, ruleFlyoutLink: string, discoverIndexLink?: string) => [
|
||||
const getDetailsList = (
|
||||
data: CspFinding,
|
||||
ruleFlyoutLink?: string,
|
||||
discoverDataViewLink?: string
|
||||
) => [
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.ruleNameTitle', {
|
||||
defaultMessage: 'Rule Name',
|
||||
}),
|
||||
description: (
|
||||
<EuiToolTip
|
||||
position="top"
|
||||
content={i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.ruleNameTooltip', {
|
||||
defaultMessage: 'Manage Rule',
|
||||
})}
|
||||
>
|
||||
<EuiLink href={ruleFlyoutLink}>{data.rule.name}</EuiLink>
|
||||
</EuiToolTip>
|
||||
description: data.rule?.name ? (
|
||||
<RuleNameLink ruleFlyoutLink={ruleFlyoutLink} ruleName={data.rule.name} />
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
{
|
||||
|
@ -63,43 +68,57 @@ const getDetailsList = (data: CspFinding, ruleFlyoutLink: string, discoverIndexL
|
|||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.ruleTagsTitle', {
|
||||
defaultMessage: 'Rule Tags',
|
||||
}),
|
||||
description: (
|
||||
description: data.rule?.tags?.length ? (
|
||||
<>
|
||||
{data.rule.tags.map((tag) => (
|
||||
<EuiBadge key={tag}>{tag}</EuiBadge>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.evaluatedAtTitle', {
|
||||
defaultMessage: 'Evaluated at',
|
||||
}),
|
||||
description: moment(data['@timestamp']).format(CSP_MOMENT_FORMAT),
|
||||
description: data['@timestamp']
|
||||
? moment(data['@timestamp']).format(CSP_MOMENT_FORMAT)
|
||||
: EMPTY_VALUE,
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.frameworkSourcesTitle', {
|
||||
defaultMessage: 'Framework Sources',
|
||||
}),
|
||||
description: (
|
||||
<CisKubernetesIcons
|
||||
benchmarkId={data.rule.benchmark.id}
|
||||
benchmarkName={data.rule.benchmark.name}
|
||||
/>
|
||||
),
|
||||
description:
|
||||
data.rule?.benchmark?.id && data.rule?.benchmark?.name ? (
|
||||
<BenchmarkIcons
|
||||
benchmarkId={data.rule?.benchmark?.id}
|
||||
benchmarkName={data.rule?.benchmark?.name}
|
||||
/>
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.cisSectionTitle', {
|
||||
defaultMessage: 'CIS Section',
|
||||
defaultMessage: 'Framework Section',
|
||||
}),
|
||||
description: data.rule.section,
|
||||
description: data.rule?.section ? data.rule?.section : EMPTY_VALUE,
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.sourceTitle', {
|
||||
defaultMessage: 'Source',
|
||||
}),
|
||||
description:
|
||||
getDatasetDisplayName(data.data_stream?.dataset) || data.data_stream?.dataset || EMPTY_VALUE,
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.indexTitle', {
|
||||
defaultMessage: 'Index',
|
||||
}),
|
||||
description: discoverIndexLink ? (
|
||||
<EuiLink href={discoverIndexLink}>{LATEST_FINDINGS_INDEX_DEFAULT_NS}</EuiLink>
|
||||
description: discoverDataViewLink ? (
|
||||
<EuiLink href={discoverDataViewLink}>{LATEST_FINDINGS_INDEX_DEFAULT_NS}</EuiLink>
|
||||
) : (
|
||||
LATEST_FINDINGS_INDEX_DEFAULT_NS
|
||||
),
|
||||
|
@ -109,33 +128,37 @@ const getDetailsList = (data: CspFinding, ruleFlyoutLink: string, discoverIndexL
|
|||
export const getRemediationList = (rule: CspFinding['rule']) => [
|
||||
{
|
||||
title: '',
|
||||
description: <CspFlyoutMarkdown>{rule.remediation}</CspFlyoutMarkdown>,
|
||||
description: rule?.remediation ? (
|
||||
<CspFlyoutMarkdown>{rule?.remediation}</CspFlyoutMarkdown>
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.impactTitle', {
|
||||
defaultMessage: 'Impact',
|
||||
}),
|
||||
description: rule?.impact ? <CspFlyoutMarkdown>{rule.impact}</CspFlyoutMarkdown> : EMPTY_VALUE,
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.defaultValueTitle', {
|
||||
defaultMessage: 'Default Value',
|
||||
}),
|
||||
description: rule?.default_value ? (
|
||||
<CspFlyoutMarkdown>{rule.default_value}</CspFlyoutMarkdown>
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
...(rule.impact
|
||||
? [
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.impactTitle', {
|
||||
defaultMessage: 'Impact',
|
||||
}),
|
||||
description: <CspFlyoutMarkdown>{rule.impact}</CspFlyoutMarkdown>,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(rule.default_value
|
||||
? [
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.defaultValueTitle', {
|
||||
defaultMessage: 'Default Value',
|
||||
}),
|
||||
description: <CspFlyoutMarkdown>{rule.default_value}</CspFlyoutMarkdown>,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.rationaleTitle', {
|
||||
defaultMessage: 'Rationale',
|
||||
}),
|
||||
description: <CspFlyoutMarkdown>{rule.rationale}</CspFlyoutMarkdown>,
|
||||
description: rule?.rationale ? (
|
||||
<CspFlyoutMarkdown>{rule.rationale}</CspFlyoutMarkdown>
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -152,7 +175,7 @@ const getEvidenceList = ({ result }: CspFinding) =>
|
|||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer size={'s'} />
|
||||
<CodeBlock language="json">{JSON.stringify(result.evidence, null, 2)}</CodeBlock>
|
||||
<CodeBlock language="json">{JSON.stringify(result?.evidence, null, 2)}</CodeBlock>
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
@ -163,20 +186,36 @@ export const OverviewTab = ({
|
|||
ruleFlyoutLink,
|
||||
}: {
|
||||
data: CspFinding;
|
||||
ruleFlyoutLink: string;
|
||||
ruleFlyoutLink?: string;
|
||||
}) => {
|
||||
const { discover } = useKibana().services;
|
||||
const latestFindingsDataView = useDataView(LATEST_FINDINGS_INDEX_PATTERN);
|
||||
|
||||
const discoverIndexLink = useMemo(
|
||||
// link will navigate to our dataview in discover, filtered by the data source of the finding
|
||||
const discoverDataViewLink = useMemo(
|
||||
() =>
|
||||
discover.locator?.getRedirectUrl({
|
||||
indexPatternId: latestFindingsDataView.data?.id,
|
||||
dataViewId: latestFindingsDataView.data?.id,
|
||||
...(data.data_stream?.dataset && {
|
||||
filters: [
|
||||
{
|
||||
meta: {
|
||||
type: 'phrase',
|
||||
key: 'data_stream.dataset',
|
||||
},
|
||||
query: {
|
||||
match_phrase: {
|
||||
'data_stream.dataset': data.data_stream.dataset,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
}),
|
||||
[discover.locator, latestFindingsDataView.data?.id]
|
||||
[data.data_stream?.dataset, discover.locator, latestFindingsDataView.data?.id]
|
||||
);
|
||||
|
||||
const hasEvidence = !isEmpty(data.result.evidence);
|
||||
const hasEvidence = !isEmpty(data.result?.evidence);
|
||||
|
||||
const accordions: Accordion[] = useMemo(
|
||||
() =>
|
||||
|
@ -187,7 +226,7 @@ export const OverviewTab = ({
|
|||
defaultMessage: 'Details',
|
||||
}),
|
||||
id: 'detailsAccordion',
|
||||
listItems: getDetailsList(data, ruleFlyoutLink, discoverIndexLink),
|
||||
listItems: getDetailsList(data, ruleFlyoutLink, discoverDataViewLink),
|
||||
},
|
||||
{
|
||||
initialIsOpen: true,
|
||||
|
@ -208,7 +247,7 @@ export const OverviewTab = ({
|
|||
listItems: getEvidenceList(data),
|
||||
},
|
||||
].filter(truthy),
|
||||
[data, discoverIndexLink, hasEvidence, ruleFlyoutLink]
|
||||
[data, discoverDataViewLink, hasEvidence, ruleFlyoutLink]
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiBadge, EuiDescriptionList, EuiLink, EuiToolTip } from '@elastic/eui';
|
||||
import { EuiBadge, EuiDescriptionList } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { CspFinding } from '../../../../common/schemas/csp_finding';
|
||||
import { RulesDetectionRuleCounter } from '../../rules/rules_detection_rule_counter';
|
||||
import { CisKubernetesIcons, CspFlyoutMarkdown } from './findings_flyout';
|
||||
import { BenchmarkIcons, CspFlyoutMarkdown, EMPTY_VALUE, RuleNameLink } from './findings_flyout';
|
||||
|
||||
export const getRuleList = (
|
||||
rule: CspFinding['rule'],
|
||||
rule?: CspFinding['rule'],
|
||||
ruleState = 'unmuted',
|
||||
ruleFlyoutLink?: string
|
||||
) => [
|
||||
|
@ -22,31 +22,28 @@ export const getRuleList = (
|
|||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.nameTitle', {
|
||||
defaultMessage: 'Name',
|
||||
}),
|
||||
description: ruleFlyoutLink ? (
|
||||
<EuiToolTip
|
||||
position="top"
|
||||
content={i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.nameTooltip', {
|
||||
defaultMessage: 'Manage Rule',
|
||||
})}
|
||||
>
|
||||
<EuiLink href={ruleFlyoutLink}>{rule.name}</EuiLink>
|
||||
</EuiToolTip>
|
||||
description: rule?.name ? (
|
||||
<RuleNameLink ruleFlyoutLink={ruleFlyoutLink} ruleName={rule.name} />
|
||||
) : (
|
||||
rule.name
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.descriptionTitle', {
|
||||
defaultMessage: 'Description',
|
||||
}),
|
||||
description: <CspFlyoutMarkdown>{rule.description}</CspFlyoutMarkdown>,
|
||||
description: rule?.description ? (
|
||||
<CspFlyoutMarkdown>{rule.description}</CspFlyoutMarkdown>
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.AlertsTitle', {
|
||||
defaultMessage: 'Alerts',
|
||||
}),
|
||||
description:
|
||||
ruleState === 'unmuted' ? (
|
||||
ruleState === 'unmuted' && rule?.benchmark?.name ? (
|
||||
<RulesDetectionRuleCounter benchmarkRule={rule} />
|
||||
) : (
|
||||
<FormattedMessage
|
||||
|
@ -59,58 +56,73 @@ export const getRuleList = (
|
|||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.tagsTitle', {
|
||||
defaultMessage: 'Tags',
|
||||
}),
|
||||
description: (
|
||||
description: rule?.tags?.length ? (
|
||||
<>
|
||||
{rule.tags.map((tag) => (
|
||||
<EuiBadge key={tag}>{tag}</EuiBadge>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.frameworkSourcesTitle', {
|
||||
defaultMessage: 'Framework Sources',
|
||||
}),
|
||||
description: (
|
||||
<CisKubernetesIcons benchmarkId={rule.benchmark.id} benchmarkName={rule.benchmark.name} />
|
||||
),
|
||||
description:
|
||||
rule?.benchmark?.id && rule?.benchmark?.name ? (
|
||||
<BenchmarkIcons benchmarkId={rule.benchmark.id} benchmarkName={rule.benchmark.name} />
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.cisSectionTitle', {
|
||||
defaultMessage: 'CIS Section',
|
||||
defaultMessage: 'Framework Section',
|
||||
}),
|
||||
description: rule.section,
|
||||
description: rule?.section || EMPTY_VALUE,
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.profileApplicabilityTitle', {
|
||||
defaultMessage: 'Profile Applicability',
|
||||
}),
|
||||
description: <CspFlyoutMarkdown>{rule.profile_applicability}</CspFlyoutMarkdown>,
|
||||
description: rule?.profile_applicability ? (
|
||||
<CspFlyoutMarkdown>{rule.profile_applicability}</CspFlyoutMarkdown>
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.benchmarkTitle', {
|
||||
defaultMessage: 'Benchmark',
|
||||
}),
|
||||
description: rule.benchmark.name,
|
||||
description: rule?.benchmark?.name || EMPTY_VALUE,
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.auditTitle', {
|
||||
defaultMessage: 'Audit',
|
||||
}),
|
||||
description: <CspFlyoutMarkdown>{rule.audit}</CspFlyoutMarkdown>,
|
||||
description: rule?.audit ? <CspFlyoutMarkdown>{rule.audit}</CspFlyoutMarkdown> : EMPTY_VALUE,
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.referencesTitle', {
|
||||
defaultMessage: 'References',
|
||||
}),
|
||||
description: rule?.references ? (
|
||||
<CspFlyoutMarkdown>{rule.references}</CspFlyoutMarkdown>
|
||||
) : (
|
||||
EMPTY_VALUE
|
||||
),
|
||||
},
|
||||
...(rule.references
|
||||
? [
|
||||
{
|
||||
title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.referencesTitle', {
|
||||
defaultMessage: 'References',
|
||||
}),
|
||||
description: <CspFlyoutMarkdown>{rule.references}</CspFlyoutMarkdown>,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
|
||||
export const RuleTab = ({ data, ruleFlyoutLink }: { data: CspFinding; ruleFlyoutLink: string }) => {
|
||||
export const RuleTab = ({
|
||||
data,
|
||||
ruleFlyoutLink,
|
||||
}: {
|
||||
data: CspFinding;
|
||||
ruleFlyoutLink?: string;
|
||||
}) => {
|
||||
return <EuiDescriptionList listItems={getRuleList(data.rule, ruleFlyoutLink)} />;
|
||||
};
|
||||
|
|
|
@ -126,5 +126,6 @@ export const defaultColumns: CloudSecurityDefaultColumn[] = [
|
|||
{ id: 'rule.benchmark.rule_number' },
|
||||
{ id: 'rule.name' },
|
||||
{ id: 'rule.section' },
|
||||
{ id: 'data_stream.dataset' },
|
||||
{ id: '@timestamp' },
|
||||
];
|
||||
|
|
|
@ -33,7 +33,11 @@ export const findingsTableFieldLabels: Record<string, string> = {
|
|||
),
|
||||
'rule.section': i18n.translate(
|
||||
'xpack.csp.findings.findingsTable.findingsTableColumn.ruleSectionColumnLabel',
|
||||
{ defaultMessage: 'CIS Section' }
|
||||
{ defaultMessage: 'Framework Section' }
|
||||
),
|
||||
'data_stream.dataset': i18n.translate(
|
||||
'xpack.csp.findings.findingsTable.findingsTableColumn.sourceColumnLabel',
|
||||
{ defaultMessage: 'Source' }
|
||||
),
|
||||
'@timestamp': i18n.translate(
|
||||
'xpack.csp.findings.findingsTable.findingsTableColumn.lastCheckedColumnLabel',
|
||||
|
|
|
@ -64,15 +64,15 @@ export const groupPanelRenderer: GroupPanelRenderer<FindingsGroupingAggregation>
|
|||
css={css`
|
||||
word-break: break-all;
|
||||
`}
|
||||
title={bucket.resourceName?.buckets?.[0].key}
|
||||
title={bucket.resourceName?.buckets?.[0]?.key}
|
||||
>
|
||||
<strong>{bucket.key_as_string}</strong> {bucket.resourceName?.buckets?.[0].key}
|
||||
<strong>{bucket.key_as_string}</strong> {bucket.resourceName?.buckets?.[0]?.key}
|
||||
</EuiTextBlockTruncate>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiText size="xs" color="subdued">
|
||||
{bucket.resourceSubType?.buckets?.[0].key}
|
||||
{bucket.resourceSubType?.buckets?.[0]?.key}
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -93,8 +93,8 @@ export const groupPanelRenderer: GroupPanelRenderer<FindingsGroupingAggregation>
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiText size="xs" color="subdued">
|
||||
{firstNonNullValue(bucket.benchmarkName?.buckets?.[0].key)}{' '}
|
||||
{firstNonNullValue(bucket.benchmarkVersion?.buckets?.[0].key)}
|
||||
{firstNonNullValue(bucket.benchmarkName?.buckets?.[0]?.key)}{' '}
|
||||
{firstNonNullValue(bucket.benchmarkVersion?.buckets?.[0]?.key)}
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -11,6 +11,8 @@ import { DataTableRecord } from '@kbn/discover-utils/types';
|
|||
import { HttpSetup } from '@kbn/core-http-browser';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiDataGridCellValueElementProps, EuiFlexItem, EuiSpacer } from '@elastic/eui';
|
||||
import { CspFinding } from '../../../../common/schemas/csp_finding';
|
||||
import { getDatasetDisplayName } from '../../../common/utils/get_dataset_display_name';
|
||||
import * as TEST_SUBJECTS from '../test_subjects';
|
||||
import { FindingsDistributionBar } from '../layout/findings_distribution_bar';
|
||||
import { ErrorCallout } from '../layout/error_callout';
|
||||
|
@ -19,7 +21,6 @@ import { getDefaultQuery, defaultColumns } from './constants';
|
|||
import { useLatestFindingsTable } from './use_latest_findings_table';
|
||||
import { TimestampTableCell } from '../../../components/timestamp_table_cell';
|
||||
import { CspEvaluationBadge } from '../../../components/csp_evaluation_badge';
|
||||
import { CspFinding } from '../../../../common/schemas/csp_finding';
|
||||
import { FindingsRuleFlyout } from '../findings_flyout/findings_flyout';
|
||||
import { createDetectionRuleFromBenchmarkRule } from '../utils/create_detection_rule_from_benchmark';
|
||||
import { findingsTableFieldLabels } from './findings_table_field_labels';
|
||||
|
@ -30,42 +31,26 @@ interface LatestFindingsTableProps {
|
|||
showDistributionBar?: boolean;
|
||||
nonPersistedFilters?: Filter[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Type Guard for checking if the given source is a CspFinding
|
||||
*/
|
||||
const isCspFinding = (source: Record<string, any> | undefined): source is CspFinding => {
|
||||
return source?.result?.evaluation !== undefined;
|
||||
return source?.data_stream?.dataset !== undefined;
|
||||
};
|
||||
|
||||
const getCspFinding = (source: Record<string, any> | undefined): CspFinding | false => {
|
||||
return isCspFinding(source) && (source as CspFinding);
|
||||
};
|
||||
|
||||
/**
|
||||
* This Wrapper component renders the children if the given row is a CspFinding
|
||||
* it uses React's Render Props pattern
|
||||
*/
|
||||
const CspFindingRenderer = ({
|
||||
row,
|
||||
children,
|
||||
}: {
|
||||
row: DataTableRecord;
|
||||
children: ({ finding }: { finding: CspFinding }) => JSX.Element;
|
||||
}) => {
|
||||
const finding = getCspFinding(row.raw._source);
|
||||
if (!finding) return <></>;
|
||||
return children({ finding });
|
||||
const getCspFinding = (source: Record<string, any> | undefined): CspFinding | undefined => {
|
||||
if (isCspFinding(source)) return source as CspFinding;
|
||||
};
|
||||
|
||||
/**
|
||||
* Flyout component for the latest findings table
|
||||
*/
|
||||
const flyoutComponent = (row: DataTableRecord, onCloseFlyout: () => void): JSX.Element => {
|
||||
return (
|
||||
<CspFindingRenderer row={row}>
|
||||
{({ finding }) => <FindingsRuleFlyout findings={finding} onClose={onCloseFlyout} />}
|
||||
</CspFindingRenderer>
|
||||
);
|
||||
const finding = row.raw._source;
|
||||
if (!finding || !isCspFinding(finding)) return <></>;
|
||||
|
||||
return <FindingsRuleFlyout finding={finding} onClose={onCloseFlyout} />;
|
||||
};
|
||||
|
||||
const title = i18n.translate('xpack.csp.findings.latestFindings.tableRowTypeLabel', {
|
||||
|
@ -73,16 +58,23 @@ const title = i18n.translate('xpack.csp.findings.latestFindings.tableRowTypeLabe
|
|||
});
|
||||
|
||||
const customCellRenderer = (rows: DataTableRecord[]) => ({
|
||||
'result.evaluation': ({ rowIndex }: EuiDataGridCellValueElementProps) => (
|
||||
<CspFindingRenderer row={rows[rowIndex]}>
|
||||
{({ finding }) => <CspEvaluationBadge type={finding.result.evaluation} />}
|
||||
</CspFindingRenderer>
|
||||
),
|
||||
'@timestamp': ({ rowIndex }: EuiDataGridCellValueElementProps) => (
|
||||
<CspFindingRenderer row={rows[rowIndex]}>
|
||||
{({ finding }) => <TimestampTableCell timestamp={finding['@timestamp']} />}
|
||||
</CspFindingRenderer>
|
||||
),
|
||||
'result.evaluation': ({ rowIndex }: EuiDataGridCellValueElementProps) => {
|
||||
const finding = getCspFinding(rows[rowIndex].raw._source);
|
||||
|
||||
return <CspEvaluationBadge type={finding?.result?.evaluation} />;
|
||||
},
|
||||
'data_stream.dataset': ({ rowIndex }: EuiDataGridCellValueElementProps) => {
|
||||
const finding = getCspFinding(rows[rowIndex].raw._source);
|
||||
const source = getDatasetDisplayName(finding?.data_stream?.dataset);
|
||||
|
||||
return <>{source || finding?.data_stream?.dataset || ''}</>;
|
||||
},
|
||||
'@timestamp': ({ rowIndex }: EuiDataGridCellValueElementProps) => {
|
||||
const finding = getCspFinding(rows[rowIndex].raw._source);
|
||||
if (!finding?.['@timestamp']) return <></>;
|
||||
|
||||
return <TimestampTableCell timestamp={finding['@timestamp']} />;
|
||||
},
|
||||
});
|
||||
|
||||
export const LatestFindingsTable = ({
|
||||
|
|
|
@ -70,9 +70,9 @@ export const groupPanelRenderer: GroupPanelRenderer<VulnerabilitiesGroupingAggre
|
|||
css={css`
|
||||
word-break: break-all;
|
||||
`}
|
||||
title={bucket.resourceId?.buckets?.[0].key}
|
||||
title={bucket.resourceId?.buckets?.[0]?.key}
|
||||
>
|
||||
<strong>{bucket.key_as_string}</strong> {bucket.resourceId?.buckets?.[0].key}
|
||||
<strong>{bucket.key_as_string}</strong> {bucket.resourceId?.buckets?.[0]?.key}
|
||||
</EuiTextBlockTruncate>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -63,4 +63,7 @@ export const getFindingsFixture = (): CspFinding & { id: string } => ({
|
|||
ecs: {} as any,
|
||||
event: {} as EcsEvent,
|
||||
'@timestamp': new Date().toISOString(),
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
});
|
||||
|
|
|
@ -13237,7 +13237,6 @@
|
|||
"xpack.csp.findings.findingsFlyout.overviewTab.rationaleTitle": "Environnement",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.remediationTitle": "Résolution",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.ruleNameTitle": "Nom de règle",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.ruleNameTooltip": "Gérer la règle",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.ruleTagsTitle": "Balises de règle",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTabTitle": "Aperçu",
|
||||
"xpack.csp.findings.findingsFlyout.paginationLabel": "Navigation de recherche",
|
||||
|
@ -13249,7 +13248,6 @@
|
|||
"xpack.csp.findings.findingsFlyout.ruleTab.disabledRuleText": "Désactivé",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.frameworkSourcesTitle": "Sources du framework",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.nameTitle": "Nom",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.nameTooltip": "Gérer la règle",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.profileApplicabilityTitle": "Applicabilité du profil",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.referencesTitle": "Références",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.tagsTitle": "Balises",
|
||||
|
|
|
@ -13197,7 +13197,6 @@
|
|||
"xpack.csp.findings.findingsFlyout.overviewTab.rationaleTitle": "根拠",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.remediationTitle": "修正",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.ruleNameTitle": "ルール名",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.ruleNameTooltip": "ルールの管理",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.ruleTagsTitle": "ルールタグ",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTabTitle": "概要",
|
||||
"xpack.csp.findings.findingsFlyout.paginationLabel": "ナビゲーションを検索中",
|
||||
|
@ -13209,7 +13208,6 @@
|
|||
"xpack.csp.findings.findingsFlyout.ruleTab.disabledRuleText": "無効",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.frameworkSourcesTitle": "フレームワークソース",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.nameTitle": "名前",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.nameTooltip": "ルールの管理",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.profileApplicabilityTitle": "プロファイル適用性",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.referencesTitle": "基準",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.tagsTitle": "タグ",
|
||||
|
|
|
@ -13257,7 +13257,6 @@
|
|||
"xpack.csp.findings.findingsFlyout.overviewTab.rationaleTitle": "理由",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.remediationTitle": "补救",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.ruleNameTitle": "规则名称",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.ruleNameTooltip": "管理规则",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTab.ruleTagsTitle": "规则标签",
|
||||
"xpack.csp.findings.findingsFlyout.overviewTabTitle": "概览",
|
||||
"xpack.csp.findings.findingsFlyout.paginationLabel": "正在查找导航",
|
||||
|
@ -13269,7 +13268,6 @@
|
|||
"xpack.csp.findings.findingsFlyout.ruleTab.disabledRuleText": "已禁用",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.frameworkSourcesTitle": "框架源",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.nameTitle": "名称",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.nameTooltip": "管理规则",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.profileApplicabilityTitle": "配置文件适用性",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.referencesTitle": "参考",
|
||||
"xpack.csp.findings.findingsFlyout.ruleTab.tagsTitle": "标签",
|
||||
|
|
|
@ -44,6 +44,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
type: 'process',
|
||||
},
|
||||
cluster_id: 'Upper case cluster id',
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
{
|
||||
'@timestamp': timeFiveHoursAgo,
|
||||
|
@ -61,6 +64,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
type: 'process',
|
||||
},
|
||||
cluster_id: 'Another Upper case cluster id',
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
{
|
||||
'@timestamp': timeFiveHoursAgo,
|
||||
|
@ -78,6 +84,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
type: 'process',
|
||||
},
|
||||
cluster_id: 'lower case cluster id',
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
{
|
||||
'@timestamp': timeFiveHoursAgo,
|
||||
|
@ -95,6 +104,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
type: 'process',
|
||||
},
|
||||
cluster_id: 'another lower case cluster id',
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -40,6 +40,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
type: 'process',
|
||||
},
|
||||
cluster_id: 'Upper case cluster id',
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
{
|
||||
'@timestamp': new Date(Date.now() - 60 * 60 * 1000).toISOString(),
|
||||
|
@ -62,6 +65,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
type: 'process',
|
||||
},
|
||||
cluster_id: 'Another Upper case cluster id',
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
{
|
||||
'@timestamp': new Date(Date.now() - 60 * 60 * 1000).toISOString(),
|
||||
|
@ -84,6 +90,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
type: 'process',
|
||||
},
|
||||
cluster_id: 'lower case cluster id',
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
{
|
||||
'@timestamp': new Date(Date.now() - 60 * 60 * 1000).toISOString(),
|
||||
|
@ -106,6 +115,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
type: 'process',
|
||||
},
|
||||
cluster_id: 'another lower case cluster id',
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -53,6 +53,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
},
|
||||
type: 'process',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
{
|
||||
'@timestamp': new Date().toISOString(),
|
||||
|
@ -75,6 +78,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
},
|
||||
type: 'process',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
{
|
||||
'@timestamp': new Date().toISOString(),
|
||||
|
@ -97,6 +103,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
},
|
||||
type: 'process',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
{
|
||||
'@timestamp': new Date().toISOString(),
|
||||
|
@ -119,6 +128,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
},
|
||||
type: 'process',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue