Skip to content

Commit d9b8ed3

Browse files
authored
Merge pull request #1974 from devtron-labs/feat/security-summary-card
feat: add security summary card and merge v1 and v2 security modal
2 parents 04b2af3 + db172e9 commit d9b8ed3

26 files changed

+505
-697
lines changed

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,6 @@ src/components/common/icons/Icons.tsx
293293
src/components/common/lineChart/lineChart.tsx
294294
src/components/common/navigation/Navigation.tsx
295295
src/components/common/navigation/NavigationRoutes.tsx
296-
src/components/common/security/ScanDetailsModal.tsx
297296
src/components/deploymentConfig/ChartSelectorDropdown.tsx
298297
src/components/deploymentConfig/DeploymentConfig.tsx
299298
src/components/deploymentConfig/DeploymentConfig.utils.ts

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"homepage": "/dashboard",
66
"dependencies": {
7-
"@devtron-labs/devtron-fe-common-lib": "0.3.14",
7+
"@devtron-labs/devtron-fe-common-lib": "0.3.15",
88
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
99
"@rjsf/core": "^5.13.3",
1010
"@rjsf/utils": "^5.13.3",

src/components/ResourceBrowser/ResourceList/ResourceBrowserActionMenu.tsx

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,17 @@
1515
*/
1616

1717
import React, { useState } from 'react'
18-
import { PopupMenu, Nodes, useMainContext, ModuleNameMap } from '@devtron-labs/devtron-fe-common-lib'
18+
import {
19+
PopupMenu,
20+
Nodes,
21+
useMainContext,
22+
ModuleNameMap,
23+
SecurityModal,
24+
ResponseType,
25+
ApiResponseResultType,
26+
GetResourceScanDetailsPayloadType,
27+
useAsync,
28+
} from '@devtron-labs/devtron-fe-common-lib'
1929
import DeleteResourcePopup from './DeleteResourcePopup'
2030
import { importComponentFromFELibrary, getShowResourceScanModal } from '../../common'
2131
import { RESOURCE_ACTION_MENU } from '../Constants'
@@ -28,8 +38,25 @@ import { ReactComponent as DeleteIcon } from '../../../assets/icons/ic-delete-in
2838
import { ReactComponent as MenuDots } from '../../../assets/icons/appstatus/ic-menu-dots.svg'
2939
import { NodeType } from '../../v2/appDetails/appDetails.type'
3040

31-
const OpenSecurityModalButton = importComponentFromFELibrary('OpenSecurityModalButton')
32-
const SecurityModal = importComponentFromFELibrary('SecurityModal')
41+
const OpenSecurityModalButton = importComponentFromFELibrary('OpenSecurityModalButton', null, 'function')
42+
const isFELibAvailable = importComponentFromFELibrary('isFELibAvailable', false, 'function')
43+
const SecurityModalSidebar = importComponentFromFELibrary('SecurityModalSidebar', null, 'function')
44+
const getResourceScanDetails: ({
45+
name,
46+
namespace,
47+
clusterId,
48+
group,
49+
version,
50+
kind,
51+
appId,
52+
appType,
53+
deploymentType,
54+
isAppDetailView,
55+
}: GetResourceScanDetailsPayloadType) => Promise<ResponseType<ApiResponseResultType>> = importComponentFromFELibrary(
56+
'getResourceScanDetails',
57+
null,
58+
'function',
59+
)
3360

3461
const ResourceBrowserActionMenu: React.FC<ResourceBrowserActionMenuType> = ({
3562
clusterId,
@@ -41,9 +68,25 @@ const ResourceBrowserActionMenu: React.FC<ResourceBrowserActionMenuType> = ({
4168
}) => {
4269
const { installedModuleMap } = useMainContext()
4370

71+
const isSecurityScanV2Enabled = window._env_.ENABLE_RESOURCE_SCAN_V2 && isFELibAvailable
72+
4473
const [showDeleteDialog, setShowDeleteDialog] = useState(false)
4574
const [showVulnerabilityModal, setShowVulnerabilityModal] = useState(false)
4675

76+
const [resourceScanLoading, resourceScanResponse, resourceScanError] = useAsync(
77+
() =>
78+
getResourceScanDetails({
79+
name: String(resourceData.name),
80+
namespace: String(resourceData.namespace),
81+
group: selectedResource?.gvk?.Group,
82+
kind: selectedResource?.gvk?.Kind,
83+
version: selectedResource?.gvk?.Version,
84+
clusterId: +clusterId,
85+
}),
86+
[],
87+
showVulnerabilityModal && getResourceScanDetails && isSecurityScanV2Enabled,
88+
)
89+
4790
const toggleDeleteDialog = () => {
4891
setShowDeleteDialog((prevState) => !prevState)
4992
}
@@ -56,10 +99,12 @@ const ResourceBrowserActionMenu: React.FC<ResourceBrowserActionMenuType> = ({
5699
setShowVulnerabilityModal(false)
57100
}
58101

59-
const showResourceScanModal = getShowResourceScanModal(
60-
selectedResource?.gvk?.Kind as NodeType,
61-
installedModuleMap.current?.[ModuleNameMap.SECURITY_TRIVY],
62-
)
102+
const showResourceScanModal =
103+
getShowResourceScanModal(
104+
selectedResource?.gvk?.Kind as NodeType,
105+
installedModuleMap.current?.[ModuleNameMap.SECURITY_TRIVY],
106+
) && window._env_.ENABLE_RESOURCE_SCAN_V2
107+
63108
return (
64109
<>
65110
<PopupMenu autoClose>
@@ -141,17 +186,15 @@ const ResourceBrowserActionMenu: React.FC<ResourceBrowserActionMenuType> = ({
141186
/>
142187
)}
143188

144-
{showVulnerabilityModal && SecurityModal && (
189+
{showVulnerabilityModal && !!isFELibAvailable && (
145190
<SecurityModal
146-
resourceScanPayload={{
147-
name: resourceData.name,
148-
namespace: resourceData.namespace,
149-
group: selectedResource?.gvk?.Group,
150-
kind: selectedResource?.gvk?.Kind,
151-
version: selectedResource?.gvk?.Version,
152-
clusterId,
153-
}}
191+
isResourceScan
154192
handleModalClose={handleCloseVulnerabilityModal}
193+
Sidebar={SecurityModalSidebar}
194+
isSecurityScanV2Enabled={isSecurityScanV2Enabled}
195+
isLoading={resourceScanLoading}
196+
error={resourceScanError}
197+
responseData={resourceScanResponse?.result}
155198
/>
156199
)}
157200
</>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import {
2+
ApiResponseResultType,
3+
AppDetailsPayload,
4+
getExecutionDetails,
5+
getSeverityCountFromSummary,
6+
getTotalSeverityCount,
7+
ResponseType,
8+
SeverityCount,
9+
useAsync,
10+
} from '@devtron-labs/devtron-fe-common-lib'
11+
import { importComponentFromFELibrary } from '@Components/common'
12+
import { UseGetAppSecurityDetailsProps, UseGetAppSecurityDetailsReturnType } from './appDetails.type'
13+
14+
const getSecurityScan: ({
15+
appId,
16+
envId,
17+
installedAppId,
18+
}: AppDetailsPayload) => Promise<ResponseType<ApiResponseResultType>> = importComponentFromFELibrary(
19+
'getSecurityScan',
20+
null,
21+
'function',
22+
)
23+
24+
export const useGetAppSecurityDetails = ({
25+
appId,
26+
envId,
27+
installedAppId,
28+
artifactId,
29+
imageScanDeployInfoId,
30+
isSecurityScanV2Enabled,
31+
}: UseGetAppSecurityDetailsProps): UseGetAppSecurityDetailsReturnType => {
32+
const [scanResultLoading, scanResultResponse, scanResultError, reloadScanResult] = useAsync(
33+
() => getSecurityScan({ appId, envId, installedAppId }),
34+
[appId, envId, installedAppId],
35+
getSecurityScan && isSecurityScanV2Enabled && (!!appId || !!installedAppId),
36+
)
37+
38+
const [executionDetailsLoading, executionDetailsResponse, executionDetailsError, reloadExecutionDetails] = useAsync(
39+
() =>
40+
getExecutionDetails(appId && artifactId ? { appId, artifactId } : { appId, envId, imageScanDeployInfoId }),
41+
[appId, envId, imageScanDeployInfoId, artifactId],
42+
!isSecurityScanV2Enabled && !!appId,
43+
)
44+
45+
const scanDetailsResponse = isSecurityScanV2Enabled ? scanResultResponse : executionDetailsResponse
46+
47+
const severities = isSecurityScanV2Enabled
48+
? scanResultResponse?.result.imageScan.vulnerability?.summary.severities
49+
: executionDetailsResponse?.result.imageScan.vulnerability?.summary.severities
50+
const severityCount: SeverityCount = getSeverityCountFromSummary(severities)
51+
52+
const totalCount = getTotalSeverityCount(severityCount)
53+
54+
return {
55+
scanDetailsLoading: scanResultLoading || executionDetailsLoading,
56+
scanDetailsResponse,
57+
scanDetailsError: scanResultError || executionDetailsError,
58+
reloadScanDetails: isSecurityScanV2Enabled ? reloadScanResult : reloadExecutionDetails,
59+
severityCount,
60+
totalCount,
61+
}
62+
}

0 commit comments

Comments
 (0)