Skip to content

Commit cbb398d

Browse files
authored
Merge pull request #2058 from devtron-labs/feat/security-migration
feat: security migration
2 parents 74f230e + 6ad66d4 commit cbb398d

File tree

12 files changed

+262
-147
lines changed

12 files changed

+262
-147
lines changed

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.5-beta-3",
7+
"@devtron-labs/devtron-fe-common-lib": "0.3.5-beta-6",
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: 51 additions & 10 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, SecurityModal } 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'
@@ -29,7 +39,24 @@ import { ReactComponent as MenuDots } from '../../../assets/icons/appstatus/ic-m
2939
import { NodeType } from '../../v2/appDetails/appDetails.type'
3040

3141
const OpenSecurityModalButton = importComponentFromFELibrary('OpenSecurityModalButton', null, 'function')
32-
const isFELibAvailable = importComponentFromFELibrary('isFELibAvailable', 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
}
@@ -143,15 +186,13 @@ const ResourceBrowserActionMenu: React.FC<ResourceBrowserActionMenuType> = ({
143186

144187
{showVulnerabilityModal && !!isFELibAvailable && (
145188
<SecurityModal
146-
resourceScanPayload={{
147-
name: String(resourceData.name),
148-
namespace: String(resourceData.namespace),
149-
group: selectedResource?.gvk?.Group,
150-
kind: selectedResource?.gvk?.Kind,
151-
version: selectedResource?.gvk?.Version,
152-
clusterId: +clusterId,
153-
}}
189+
isResourceScan
154190
handleModalClose={handleCloseVulnerabilityModal}
191+
Sidebar={SecurityModalSidebar}
192+
isSecurityScanV2Enabled={isSecurityScanV2Enabled}
193+
isLoading={resourceScanLoading}
194+
error={resourceScanError}
195+
responseData={resourceScanResponse?.result}
155196
/>
156197
)}
157198
</>
Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,60 @@
1-
import { getSecurityScan, useAsync } from '@devtron-labs/devtron-fe-common-lib'
2-
import { getLastExecutionMinByAppAndEnv } from '@Services/service'
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'
312
import { UseGetAppSecurityDetailsProps, UseGetAppSecurityDetailsReturnType } from './appDetails.type'
413

14+
const getSecurityScan: ({
15+
appId,
16+
envId,
17+
installedAppId,
18+
}: AppDetailsPayload) => Promise<ResponseType<ApiResponseResultType>> = importComponentFromFELibrary(
19+
'getSecurityScan',
20+
null,
21+
'function',
22+
)
23+
524
export const useGetAppSecurityDetails = ({
625
appId,
726
envId,
27+
installedAppId,
28+
imageScanDeployInfoId,
829
isSecurityScanV2Enabled,
930
}: UseGetAppSecurityDetailsProps): UseGetAppSecurityDetailsReturnType => {
1031
const [scanResultLoading, scanResultResponse, scanResultError, reloadScanResult] = useAsync(
11-
() => getSecurityScan({ appId, envId }),
12-
[appId, envId],
13-
isSecurityScanV2Enabled,
32+
() => getSecurityScan({ appId, envId, installedAppId }),
33+
[appId, envId, installedAppId],
34+
getSecurityScan && isSecurityScanV2Enabled && (!!appId || !!installedAppId),
1435
)
1536

1637
const [executionDetailsLoading, executionDetailsResponse, executionDetailsError, reloadExecutionDetails] = useAsync(
17-
() => getLastExecutionMinByAppAndEnv(appId, envId),
18-
[appId, envId],
19-
!isSecurityScanV2Enabled,
38+
() => getExecutionDetails({ appId, envId, imageScanDeployInfoId }),
39+
[appId, envId, imageScanDeployInfoId],
40+
!isSecurityScanV2Enabled && !!appId,
2041
)
2142

43+
const scanDetailsResponse = isSecurityScanV2Enabled ? scanResultResponse : executionDetailsResponse
44+
45+
const severities = isSecurityScanV2Enabled
46+
? scanResultResponse?.result.imageScan.vulnerability?.summary.severities
47+
: executionDetailsResponse?.result.imageScan.vulnerability?.summary.severities
48+
const severityCount: SeverityCount = getSeverityCountFromSummary(severities)
49+
50+
const totalCount = getTotalSeverityCount(severityCount)
51+
2252
return {
2353
scanDetailsLoading: scanResultLoading || executionDetailsLoading,
24-
scanResultResponse,
25-
executionDetailsResponse,
54+
scanDetailsResponse,
2655
scanDetailsError: scanResultError || executionDetailsError,
2756
reloadScanDetails: isSecurityScanV2Enabled ? reloadScanResult : reloadExecutionDetails,
57+
severityCount,
58+
totalCount,
2859
}
2960
}

src/components/app/details/appDetails/SecurityVulnerabilityCard.tsx

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616

1717
import React, { useState } from 'react'
1818
import Tippy from '@tippyjs/react'
19-
import { getSeverityCountFromSummary, getTotalSeverityCount, SecurityModal, SeverityCount } from '@devtron-labs/devtron-fe-common-lib'
19+
import {
20+
getSeverityCountFromSummary,
21+
getTotalSeverityCount,
22+
SecurityModal,
23+
SeverityCount,
24+
} from '@devtron-labs/devtron-fe-common-lib'
2025
import { ReactComponent as Question } from '../../../../assets/icons/ic-help-outline.svg'
2126
import { ReactComponent as Bug } from '../../../../assets/icons/ic-nav-bug.svg'
2227
import { ReactComponent as Secure } from '../../../../assets/icons/ic-secure.svg'
@@ -26,6 +31,7 @@ import { importComponentFromFELibrary } from '../../../common'
2631
import { useGetAppSecurityDetails } from './AppSecurity'
2732

2833
const isFELibAvailable = importComponentFromFELibrary('isFELibAvailable', null, 'function')
34+
const SecurityModalSidebar = importComponentFromFELibrary('SecurityModalSidebar', null, 'function')
2935

3036
export const SecurityVulnerabilityCard = ({
3137
cardLoading,
@@ -39,11 +45,13 @@ export const SecurityVulnerabilityCard = ({
3945

4046
const handleModalClose = () => setShowScanDetailsModal(false)
4147

42-
const { scanDetailsLoading, scanResultResponse, executionDetailsResponse, scanDetailsError, reloadScanDetails } =
43-
useGetAppSecurityDetails({ appId, envId, isSecurityScanV2Enabled })
48+
const { scanDetailsLoading, scanDetailsResponse, scanDetailsError, reloadScanDetails, severityCount } =
49+
useGetAppSecurityDetails({ appId: +appId, envId: +envId, installedAppId, isSecurityScanV2Enabled })
4450

45-
const imageScanFailed = scanResultResponse?.result.codeScan.status === 'Failed'
46-
const imageScanProgressing = scanResultResponse?.result.codeScan.status === 'Progressing'
51+
// Since we get status in v2 Api only
52+
const imageScanFailed: boolean = isSecurityScanV2Enabled && scanDetailsResponse?.result.codeScan.status === 'Failed'
53+
const imageScanProgressing: boolean =
54+
isSecurityScanV2Enabled && scanDetailsResponse?.result.codeScan.status === 'Progressing'
4755

4856
const handleOnCardClick = () => {
4957
if (!cardLoading && !scanDetailsError && !showScanDetailsModal) {
@@ -52,11 +60,6 @@ export const SecurityVulnerabilityCard = ({
5260
}
5361
}
5462

55-
const scanResultSeverities = scanResultResponse?.result.imageScan.vulnerability?.summary.severities // For scan-result Api
56-
const severityCount: SeverityCount = isSecurityScanV2Enabled
57-
? getSeverityCountFromSummary(scanResultSeverities)
58-
: executionDetailsResponse?.result.severityCount ?? { critical: 0, high: 0, medium: 0, low: 0, unknown: 0 }
59-
6063
const totalCount = getTotalSeverityCount(severityCount)
6164

6265
const getIcon = () => {
@@ -140,10 +143,7 @@ export const SecurityVulnerabilityCard = ({
140143
return <LoadingCard />
141144
}
142145

143-
if (
144-
(scanResultResponse && !scanResultResponse.result.scanned) ||
145-
(executionDetailsResponse && !executionDetailsResponse.result.scanned)
146-
) {
146+
if (scanDetailsResponse && !scanDetailsResponse.result.scanned) {
147147
return null
148148
}
149149

@@ -190,21 +190,12 @@ export const SecurityVulnerabilityCard = ({
190190
<SecurityModal
191191
handleModalClose={handleModalClose}
192192
isExternalCI={isExternalCI}
193-
{...(isSecurityScanV2Enabled
194-
? {
195-
appDetailsPayload: {
196-
appId,
197-
envId,
198-
installedAppId: installedAppId ? String(installedAppId) : null,
199-
},
200-
}
201-
: {
202-
executionDetailsPayload: {
203-
appId,
204-
envId,
205-
imageScanDeployInfoId: executionDetailsResponse?.result.imageScanDeployInfoId,
206-
},
207-
})}
193+
Sidebar={SecurityModalSidebar}
194+
isSecurityScanV2Enabled={isSecurityScanV2Enabled}
195+
isHelmApp={!!installedAppId}
196+
isLoading={scanDetailsLoading}
197+
error={scanDetailsError}
198+
responseData={scanDetailsResponse?.result}
208199
/>
209200
)}
210201
</button>

src/components/app/details/appDetails/appDetails.type.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { ACTION_STATE, getSecurityScan, ResponseType } from '@devtron-labs/devtron-fe-common-lib'
18-
import { getLastExecutionMinByAppAndEnv } from '@Services/service'
17+
import {
18+
ACTION_STATE,
19+
ApiResponseResultType,
20+
ResponseType,
21+
ServerErrors,
22+
SeverityCount,
23+
} from '@devtron-labs/devtron-fe-common-lib'
1924
import { AggregatedNodes, OptionType } from '../../types'
2025
import { SyncErrorType, AppDetails } from '../../../v2/appDetails/appDetails.type'
2126

@@ -260,14 +265,17 @@ export interface LastUpdatedCardType {
260265
}
261266

262267
export interface UseGetAppSecurityDetailsProps {
263-
appId: string
264-
envId: string
268+
appId: number
269+
envId: number
270+
installedAppId?: number
271+
imageScanDeployInfoId?: number
265272
isSecurityScanV2Enabled: boolean
266273
}
267274
export interface UseGetAppSecurityDetailsReturnType {
268275
scanDetailsLoading: boolean
269-
scanResultResponse: Awaited<ReturnType<typeof getSecurityScan>>
270-
executionDetailsResponse: Awaited<ReturnType<typeof getLastExecutionMinByAppAndEnv>>
271-
scanDetailsError: any
276+
scanDetailsResponse: ResponseType<ApiResponseResultType>
277+
scanDetailsError: ServerErrors
272278
reloadScanDetails: () => void
279+
severityCount: SeverityCount
280+
totalCount: number
273281
}

src/components/app/details/cIDetails/CIDetails.tsx

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
ErrorScreenManager,
4949
getTotalSeverityCount,
5050
getSeverityCountFromSummary,
51+
parseExecutionDetailResponse,
5152
} from '@devtron-labs/devtron-fe-common-lib'
5253
import { Switch, Route, Redirect, useRouteMatch, useParams, useHistory, generatePath } from 'react-router-dom'
5354
import {
@@ -71,6 +72,7 @@ import { importComponentFromFELibrary } from '@Components/common'
7172
import { useGetCISecurityDetails } from './CISecurity.utils'
7273

7374
const isFELibAvailable = importComponentFromFELibrary('isFELibAvailable', null, 'function')
75+
const SecurityModalSidebar = importComponentFromFELibrary('SecurityModalSidebar', null, 'function')
7476
const terminalStatus = new Set(['succeeded', 'failed', 'error', 'cancelled', 'nottriggered', 'notbuilt'])
7577
const statusSet = new Set(['starting', 'running', 'pending'])
7678

@@ -640,8 +642,6 @@ const HistoryLogs = ({
640642
artifactId={triggerDetails.artifactId}
641643
status={triggerDetails.status}
642644
appIdFromParent={appIdFromParent}
643-
isJobCI={isJobCI}
644-
isJobView={isJobView}
645645
/>
646646
</Route>
647647
}
@@ -673,19 +673,19 @@ export const NoVulnerabilityViewWithTool = ({ scanToolId }: { scanToolId: number
673673
)
674674
}
675675

676-
const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent, isJobCI, isJobView }: SecurityTabType) => {
676+
const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: SecurityTabType) => {
677677
const { appId } = useParams<{ appId: string }>()
678678
const { push } = useHistory()
679679
const isSecurityScanV2Enabled = window._env_.ENABLE_RESOURCE_SCAN_V2 && !!isFELibAvailable
680680

681681
const computedAppId = appId ?? appIdFromParent
682682

683-
const { scanDetailsLoading, scanResultResponse, executionDetailsResponse, scanDetailsError, reloadScanDetails } = useGetCISecurityDetails({
684-
appId: computedAppId,
685-
artifactId,
686-
isJobCard: isJobCI || isJobView,
687-
isSecurityScanV2Enabled,
688-
})
683+
const { scanDetailsLoading, scanResultResponse, executionDetailsResponse, scanDetailsError, reloadScanDetails, severityCount, totalCount } =
684+
useGetCISecurityDetails({
685+
appId: +computedAppId,
686+
artifactId,
687+
isSecurityScanV2Enabled,
688+
})
689689

690690
const redirectToCreate = () => {
691691
if (!ciPipelineId) {
@@ -727,14 +727,7 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent, isJobC
727727
return <ImageNotScannedView />
728728
}
729729

730-
const scanResultSeverities = scanResultResponse?.result.imageScan.vulnerability?.summary.severities // For scan-result Api
731-
const severityCount: SeverityCount = isSecurityScanV2Enabled
732-
? getSeverityCountFromSummary(scanResultSeverities)
733-
: executionDetailsResponse?.result.severityCount ?? { critical: 0, high: 0, medium: 0, low: 0, unknown: 0 }
734-
735-
const totalSeverities = getTotalSeverityCount(severityCount)
736-
737-
if (artifactId && !totalSeverities) {
730+
if (artifactId && !totalCount) {
738731
return (
739732
<NoVulnerabilityViewWithTool
740733
scanToolId={isSecurityScanV2Enabled ? SCAN_TOOL_ID_TRIVY : executionDetailsResponse.result?.scanToolId} // Since v2 scan is via trivy only
@@ -748,14 +741,9 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent, isJobC
748741
severityCount={severityCount}
749742
scanToolId={executionDetailsResponse?.result.scanToolId ?? SCAN_TOOL_ID_TRIVY}
750743
rootClassName="w-500"
751-
{...(isSecurityScanV2Enabled
752-
? { appDetailsPayload: { appId: computedAppId, artifactId } }
753-
: {
754-
executionDetailsPayload: {
755-
appId: computedAppId,
756-
artifactId,
757-
},
758-
})}
744+
SecurityModalSidebar={SecurityModalSidebar}
745+
isSecurityScanV2Enabled={isSecurityScanV2Enabled}
746+
responseData={isSecurityScanV2Enabled ? scanResultResponse?.result : parseExecutionDetailResponse(executionDetailsResponse?.result)}
759747
/>
760748
</div>
761749
)

0 commit comments

Comments
 (0)