[Cloud Security][CNVM] Initial CNVM dashboard links and placeholder (#158188)

This commit is contained in:
Jordan 2023-05-30 16:05:40 +03:00 committed by GitHub
parent 13806c8c8e
commit f89537909c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 115 additions and 7 deletions

View file

@ -17,6 +17,9 @@ import { QueryClientProviderProps } from '@tanstack/react-query';
jest.mock('../pages', () => ({
Findings: () => <div data-test-subj="Findings">Findings</div>,
ComplianceDashboard: () => <div data-test-subj="ComplianceDashboard">ComplianceDashboard</div>,
VulnerabilityDashboard: () => (
<div data-test-subj="VulnerabilityDashboard">VulnerabilityDashboard</div>
),
Rules: () => <div data-test-subj="Rules">Rules</div>,
Benchmarks: () => <div data-test-subj="Benchmarks">Benchmarks</div>,
}));
@ -57,6 +60,7 @@ describe('CspRouter', () => {
expect(result.queryByTestId('Findings')).toBeInTheDocument();
expect(result.queryByTestId('ComplianceDashboard')).not.toBeInTheDocument();
expect(result.queryByTestId('VulnerabilityDashboard')).not.toBeInTheDocument();
expect(result.queryByTestId('Benchmarks')).not.toBeInTheDocument();
expect(result.queryByTestId('Rules')).not.toBeInTheDocument();
});
@ -66,6 +70,18 @@ describe('CspRouter', () => {
const result = renderCspRouter();
expect(result.queryByTestId('ComplianceDashboard')).toBeInTheDocument();
expect(result.queryByTestId('VulnerabilityDashboard')).not.toBeInTheDocument();
expect(result.queryByTestId('Findings')).not.toBeInTheDocument();
expect(result.queryByTestId('Benchmarks')).not.toBeInTheDocument();
expect(result.queryByTestId('Rules')).not.toBeInTheDocument();
});
it('should render the Vulnerability Dashboard', () => {
history.push('/cloud_security_posture/vulnerability_dashboard');
const result = renderCspRouter();
expect(result.queryByTestId('VulnerabilityDashboard')).toBeInTheDocument();
expect(result.queryByTestId('ComplianceDashboard')).not.toBeInTheDocument();
expect(result.queryByTestId('Findings')).not.toBeInTheDocument();
expect(result.queryByTestId('Benchmarks')).not.toBeInTheDocument();
expect(result.queryByTestId('Rules')).not.toBeInTheDocument();
@ -78,6 +94,7 @@ describe('CspRouter', () => {
expect(result.queryByTestId('Benchmarks')).toBeInTheDocument();
expect(result.queryByTestId('Findings')).not.toBeInTheDocument();
expect(result.queryByTestId('ComplianceDashboard')).not.toBeInTheDocument();
expect(result.queryByTestId('VulnerabilityDashboard')).not.toBeInTheDocument();
expect(result.queryByTestId('Rules')).not.toBeInTheDocument();
});
@ -88,6 +105,7 @@ describe('CspRouter', () => {
expect(result.queryByTestId('Rules')).toBeInTheDocument();
expect(result.queryByTestId('Findings')).not.toBeInTheDocument();
expect(result.queryByTestId('ComplianceDashboard')).not.toBeInTheDocument();
expect(result.queryByTestId('VulnerabilityDashboard')).not.toBeInTheDocument();
expect(result.queryByTestId('Benchmarks')).not.toBeInTheDocument();
});
});

View file

@ -30,6 +30,10 @@ export const CspRouter = ({ securitySolutionContext }: CspRouterProps) => {
<Switch>
<CspRoute {...cloudPosturePages.findings} component={pages.Findings} />
<CspRoute {...cloudPosturePages.dashboard} component={pages.ComplianceDashboard} />
<CspRoute
{...cloudPosturePages.vulnerability_dashboard}
component={pages.VulnerabilityDashboard}
/>
<CspRoute {...cloudPosturePages.benchmarks}>
<Switch>

View file

@ -19,6 +19,10 @@ const NAV_ITEMS_NAMES = {
DASHBOARD: i18n.translate('xpack.csp.navigation.dashboardNavItemLabel', {
defaultMessage: 'Cloud Security Posture',
}),
VULNERABILITY_DASHBOARD: i18n.translate(
'xpack.csp.navigation.vulnerabilityDashboardNavItemLabel',
{ defaultMessage: 'Cloud Native Vulnerability Management' }
),
FINDINGS: i18n.translate('xpack.csp.navigation.findingsNavItemLabel', {
defaultMessage: 'Findings',
}),
@ -39,6 +43,11 @@ export const cloudPosturePages: Record<CspPage, CspPageNavigationItem> = {
path: `${CLOUD_SECURITY_POSTURE_BASE_PATH}/dashboard`,
id: 'cloud_security_posture-dashboard',
},
vulnerability_dashboard: {
name: NAV_ITEMS_NAMES.VULNERABILITY_DASHBOARD,
path: `${CLOUD_SECURITY_POSTURE_BASE_PATH}/vulnerability_dashboard`,
id: 'cloud_security_posture-vulnerability_dashboard',
},
findings: {
name: NAV_ITEMS_NAMES.FINDINGS,
path: `${CLOUD_SECURITY_POSTURE_BASE_PATH}/findings`,

View file

@ -14,7 +14,12 @@ const chance = new Chance();
describe('getSecuritySolutionLink', () => {
it('gets the correct link properties', () => {
const cspPage = chance.pickone<CspPage>(['dashboard', 'findings', 'benchmarks']);
const cspPage = chance.pickone<CspPage>([
'dashboard',
'findings',
'benchmarks',
'vulnerability_dashboard',
]);
const link = getSecuritySolutionLink(cspPage);
@ -26,7 +31,12 @@ describe('getSecuritySolutionLink', () => {
describe('getSecuritySolutionNavTab', () => {
it('gets the correct nav tab properties', () => {
const cspPage = chance.pickone<CspPage>(['dashboard', 'findings', 'benchmarks']);
const cspPage = chance.pickone<CspPage>([
'dashboard',
'findings',
'benchmarks',
'vulnerability_dashboard',
]);
const basePath = chance.word();
const navTab = getSecuritySolutionNavTab(cspPage, basePath);

View file

@ -14,7 +14,7 @@ export interface CspPageNavigationItem extends CspNavigationItem {
id: CloudSecurityPosturePageId;
}
export type CspPage = 'dashboard' | 'findings' | 'benchmarks';
export type CspPage = 'dashboard' | 'vulnerability_dashboard' | 'findings' | 'benchmarks';
export type CspBenchmarksPage = 'rules';
/**
@ -23,6 +23,7 @@ export type CspBenchmarksPage = 'rules';
*/
export type CloudSecurityPosturePageId =
| 'cloud_security_posture-dashboard'
| 'cloud_security_posture-vulnerability_dashboard'
| 'cloud_security_posture-findings'
| 'cloud_security_posture-benchmarks'
| 'cloud_security_posture-benchmarks-rules';

View file

@ -6,14 +6,29 @@
*/
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui';
import { EuiBetaBadge, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
export const CloudPosturePageTitle = ({ title }: { title: string }) => (
export const CloudPosturePageTitle = ({ title, isBeta }: { title: string; isBeta?: boolean }) => (
<EuiFlexGroup alignItems="center" gutterSize="s">
<EuiFlexItem grow={false}>
<EuiTitle>
<h1>{title}</h1>
</EuiTitle>
</EuiFlexItem>
{isBeta && (
<EuiFlexItem grow={false}>
<EuiBetaBadge
label="Beta"
tooltipContent={
<FormattedMessage
id="xpack.csp.cloudPosturePage.betaLabel"
defaultMessage="This functionality is in beta and is subject to change. The design and code is less mature than official generally available features and is being provided as-is with no warranties. Beta features are not subject to the support service level agreement of official generally available features."
/>
}
tooltipPosition="bottom"
/>
</EuiFlexItem>
)}
</EuiFlexGroup>
);

View file

@ -11,6 +11,7 @@ export const DASHBOARD_SUMMARY_CONTAINER = 'dashboard-summary-section';
export const KUBERNETES_DASHBOARD_CONTAINER = 'kubernetes-dashboard-container';
export const CLOUD_DASHBOARD_CONTAINER = 'cloud-dashboard-container';
export const CLOUD_POSTURE_DASHBOARD_PAGE_HEADER = 'cloud-posture-dashboard-page-header';
export const VULNERABILITY_DASHBOARD_PAGE_HEADER = 'vulnerability-dashboard-page-header';
export const DASHBOARD_COUNTER_CARDS = {
CLUSTERS_EVALUATED: 'dashboard-counter-card-clusters-evaluated',

View file

@ -7,6 +7,7 @@
export { Findings } from './findings';
export { Configurations } from './configurations';
export * from './compliance_dashboard';
export { ComplianceDashboard } from './compliance_dashboard';
export { Benchmarks } from './benchmarks';
export { Rules } from './rules';
export { VulnerabilityDashboard } from './vulnerability_dashboard/vulnerability_dashboard';

View file

@ -0,0 +1,33 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { EuiPageHeader } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { VULNERABILITY_DASHBOARD_PAGE_HEADER } from '../compliance_dashboard/test_subjects';
import { CloudPosturePageTitle } from '../../components/cloud_posture_page_title';
import { CloudPosturePage } from '../../components/cloud_posture_page';
export const VulnerabilityDashboard = () => {
return (
<CloudPosturePage>
<EuiPageHeader
data-test-subj={VULNERABILITY_DASHBOARD_PAGE_HEADER}
bottomBorder
pageTitle={
<div style={{ display: 'flex', justifyContent: 'flex-start', gap: 10 }}>
<CloudPosturePageTitle
isBeta
title={i18n.translate('xpack.csp.vulnerability_dashboard.cspPageTemplate.pageTitle', {
defaultMessage: 'Cloud Native Vulnerability Management',
})}
/>
</div>
}
/>
</CloudPosturePage>
);
};

View file

@ -8,6 +8,7 @@ import { getSecuritySolutionLink } from '@kbn/cloud-security-posture-plugin/publ
import { i18n } from '@kbn/i18n';
import { SecurityPageName, SERVER_APP_ID } from '../../common/constants';
import cloudSecurityPostureDashboardImage from '../common/images/cloud_security_posture_dashboard_page.png';
import cloudNativeVulnerabilityManagementDashboardImage from '../common/images/cloud_native_vulnerability_management_dashboard_page.png';
import type { LinkCategories, LinkItem } from '../common/links/types';
import { IconExceptionLists } from '../management/icons/exception_lists';
@ -34,6 +35,17 @@ export const dashboardLinks: LinkItem = {
...commonLinkProperties,
};
export const vulnerabilityDashboardLink: LinkItem = {
isBeta: true,
...getSecuritySolutionLink<SecurityPageName>('vulnerability_dashboard'),
description: i18n.translate('xpack.securitySolution.appLinks.vulnerabilityDashboardDescription', {
defaultMessage:
'Cloud Native Vulnerability Management (CNVM) allows you to identify vulnerabilities in your cloud workloads.',
}),
landingImage: cloudNativeVulnerabilityManagementDashboardImage,
...commonLinkProperties,
};
export const manageLinks: LinkItem = {
...getSecuritySolutionLink<SecurityPageName>('benchmarks'),
description: i18n.translate(

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View file

@ -9,7 +9,10 @@ import { DASHBOARDS_PATH, SecurityPageName, SERVER_APP_ID } from '../../common/c
import { DASHBOARDS } from '../app/translations';
import type { LinkItem } from '../common/links/types';
import { links as kubernetesLinks } from '../kubernetes/links';
import { dashboardLinks as cloudSecurityPostureLinks } from '../cloud_security_posture/links';
import {
dashboardLinks as cloudSecurityPostureLinks,
vulnerabilityDashboardLink,
} from '../cloud_security_posture/links';
import {
ecsDataQualityDashboardLinks,
detectionResponseLinks,
@ -33,6 +36,7 @@ export const dashboardsLandingLinks: LinkItem = {
detectionResponseLinks,
kubernetesLinks,
cloudSecurityPostureLinks,
vulnerabilityDashboardLink,
entityAnalyticsLinks,
ecsDataQualityDashboardLinks,
],