diff --git a/x-pack/packages/kbn-cloud-security-posture-common/README.md b/x-pack/packages/kbn-cloud-security-posture-common/README.md index bafaa51be0d82c..2fc159d9c4cac5 100644 --- a/x-pack/packages/kbn-cloud-security-posture-common/README.md +++ b/x-pack/packages/kbn-cloud-security-posture-common/README.md @@ -1 +1,9 @@ -FILL THIS IN LATER \ No newline at end of file +# @kbn/cloud-security-posture-common + +This package provides common code consumed in both the browser, i.e. the +`packages/cloud-security-posture` package and `plugins/cloud_security_posture` plugin, and on the server, i.e. the +`plugins/cloud_security_posture` plugin. + +## Maintainers + +Maintained by the Cloud Security Posture Team \ No newline at end of file diff --git a/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts b/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts index e64d281a447754..be97ef8947b8f0 100644 --- a/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts @@ -5,13 +5,16 @@ * 2.0. */ import { QueryDslQueryContainer } from '@kbn/data-views-plugin/common/types'; +import { i18n } from '@kbn/i18n'; import { CspBenchmarkRulesStates } from '../types/latest'; export const extractErrorMessage = (e: unknown, defaultMessage = 'Unknown Error'): string => { if (e instanceof Error) return e.message; if (typeof e === 'string') return e; - return defaultMessage; // TODO: i18n + return i18n.translate('xpack.csp.findings.errorMessage.default', { + defaultMessage, + }); }; export const buildMutedRulesFilter = ( diff --git a/x-pack/packages/kbn-cloud-security-posture/README.md b/x-pack/packages/kbn-cloud-security-posture/README.md index bafaa51be0d82c..38a875dda54abf 100644 --- a/x-pack/packages/kbn-cloud-security-posture/README.md +++ b/x-pack/packages/kbn-cloud-security-posture/README.md @@ -1 +1,9 @@ -FILL THIS IN LATER \ No newline at end of file +# @kbn/cloud-security-posture + +This package includes +- Hooks that's used on Flyout component that's used in Alerts page on Security Solution Plugins as well as components on CSP plugin +- Utilities and types thats used for the Hooks above as well as in CSP plugins + +## Maintainers + +Maintained by the Cloud Security Posture Team \ No newline at end of file diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/insight_entity/misconfigurations_overview.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/insight_entity/misconfigurations_overview.tsx index 7903ccc15e90a5..2c533971fcb75f 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/insight_entity/misconfigurations_overview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/insight_entity/misconfigurations_overview.tsx @@ -5,33 +5,37 @@ * 2.0. */ -import React from 'react'; +import React, { useCallback } from 'react'; import { css } from '@emotion/react'; import { EuiFlexGroup, EuiFlexItem, EuiText, useEuiTheme } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { DistributionBar } from '@kbn/security-solution-distribution-bar'; import { useMisconfigurationPreview } from '@kbn/cloud-security-posture'; import { euiThemeVars } from '@kbn/ui-theme'; +import { i18n } from '@kbn/i18n'; import { ExpandablePanel } from '../../../../shared/components/expandable_panel'; export const MisconfigurationsOverview = ({ hostName }: { hostName: string }) => { - const queryHostName = { - bool: { - must: [], - filter: [ - { - bool: { - should: [{ term: { 'host.name': { value: `${hostName}` } } }], - minimum_should_match: 1, + const queryHostName = useCallback(() => { + return { + bool: { + must: [], + filter: [ + { + bool: { + should: [{ term: { 'host.name': { value: `${hostName}` } } }], + minimum_should_match: 1, + }, }, - }, - ], - should: [], - must_not: [], - }, - }; + ], + should: [], + must_not: [], + }, + }; + }, [hostName]); + const { data } = useMisconfigurationPreview({ - query: queryHostName, + query: queryHostName(), sort: [], enabled: true, pageSize: 1, @@ -44,18 +48,91 @@ export const MisconfigurationsOverview = ({ hostName }: { hostName: string }) => if (passedFindingsStats === 0 && failedFindingsStats === 0) return []; return [ { - key: 'Passed findings', + key: i18n.translate( + 'xpack.securitySolution.flyout.right.insights.misconfigurations.passedFindingsText', + { + defaultMessage: 'Passed findings', + } + ), count: passedFindingsStats, color: euiThemeVars.euiColorSuccess, }, { - key: 'Failed findings', + key: i18n.translate( + 'xpack.securitySolution.flyout.right.insights.misconfigurations.failedFindingsText', + { + defaultMessage: 'Failed findings', + } + ), count: failedFindingsStats, color: euiThemeVars.euiColorVis9, }, ]; }; + const MisconfigurationEmptyState = () => { + return ( + + + + + + + + + + + + + ); + }; + + const MisconfigurationPreviewScore = () => { + return ( + + + + + {`${Math.round((passedFindings / (passedFindings + failedFindings)) * 100)}%`} + + + + + + + + + + ); + }; + return ( /> ), - // Commented this out until we have the expanded flyout + // TODO: Uncomment when we have the expanded flyout // iconType: 'arrowStart', }} data-test-subj={'securitySolutionFlyoutInsightsMisconfigurations'} > {passedFindings === 0 && failedFindings === 0 ? ( - - - - - {'-'} - - - - - - - - - + ) : ( - - - - - {`${Math.round((passedFindings / (passedFindings + failedFindings)) * 100)}%`} - - - - - - - - - + )} diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/rules.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/rules.ts index 008fc92bd02248..be63a66f9a5317 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/rules.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/rules.ts @@ -138,3 +138,16 @@ export const enableRules = ({ names, ids }: EnableRulesParameters): Cypress.Chai failOnStatusCode: false, }); }; + +export const createFindings = ( + rule: RuleCreateProps +): Cypress.Chainable> => { + return cy.currentSpace().then((spaceId) => + rootRequest({ + method: 'POST', + url: spaceId ? getSpaceUrl(spaceId, DETECTION_ENGINE_RULES_URL) : DETECTION_ENGINE_RULES_URL, + body: rule, + failOnStatusCode: false, + }) + ); +};