Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: integrate scanning for v1 and v2 APIs #2317

Merged
merged 31 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bfcf197
fix: sentry source map upload action
eshankvaish Dec 23, 2024
76fab4c
test: add test changes
eshankvaish Dec 23, 2024
2b71610
Revert "test: add test changes"
eshankvaish Dec 23, 2024
7254a7f
fix: name for step
eshankvaish Dec 23, 2024
f899302
Merge pull request #2309 from devtron-labs/fix/source-map-upload
eshankvaish Dec 23, 2024
3c8ae86
feat: integrate sacanning for v1 and v2 APIs
arunjaindev Dec 24, 2024
3465ac8
feat: remove falg for resource scan from dashbaord
arunjaindev Dec 26, 2024
aafd80e
feat: add check for progressing in security card
arunjaindev Dec 26, 2024
8dced5f
feat: remove name from scan details state
arunjaindev Dec 26, 2024
dadfb89
feat: add isManifestScanningEnabled in main context
arunjaindev Dec 26, 2024
bc66839
feat: add checks on security card
arunjaindev Dec 26, 2024
8498112
feat: use common util for scan tool, severity count and total count
arunjaindev Dec 26, 2024
952b97e
fix: update devtron-fe-common-lib to version 1.3.0-patch-3
AbhishekA1509 Dec 26, 2024
0f2bfc8
feat: uplife return statements
arunjaindev Dec 26, 2024
4affde2
Merge pull request #2321 from devtron-labs/fix/rjsf-checkbox-null-check
AbhishekA1509 Dec 26, 2024
86d471a
chore: remove image scan enabled check
arunjaindev Dec 27, 2024
5816258
Merge branch 'develop' of https://github.com/devtron-labs/dashboard i…
arunjaindev Dec 27, 2024
2b8691b
Merge branch 'develop' of https://github.com/devtron-labs/dashboard i…
arunjaindev Dec 27, 2024
644a01d
feat: use app security hook in ci detials
arunjaindev Dec 27, 2024
8032ddc
chore: update check for security-scan app security
arunjaindev Dec 27, 2024
60b1f88
chore: revert yarnlock
arunjaindev Dec 27, 2024
a90eeff
fix: loading state for global scans list
arunjaindev Dec 27, 2024
7cea9ea
chore: version bump
arunjaindev Dec 27, 2024
d04e471
feat: remove isManifestScanningEnabled flag from helm apps
arunjaindev Dec 27, 2024
6c5d202
fix: hide security card in app details and ci if image scan is null
arunjaindev Dec 27, 2024
0386a49
fix: update check for security card
arunjaindev Dec 27, 2024
d58325a
chore: version bump
arunjaindev Dec 28, 2024
2b72f6d
fix: use computedAppId for api call in security tab
arunjaindev Dec 28, 2024
7c33b24
Merge pull request #2322 from devtron-labs/fix/integrate-scans
arunjaindev Dec 30, 2024
cd941c8
Merge branch 'develop' into feat/integrate-scan
arunjaindev Dec 30, 2024
8e08c01
Merge branch 'main' of https://github.com/devtron-labs/dashboard into…
arunjaindev Dec 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions src/components/app/details/appDetails/AppSecurity.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
getSeverityCountFromSummary,
getTotalSeverityCount,
SeverityCount,
useAsync,
getSecurityScan,
} from '@devtron-labs/devtron-fe-common-lib'
import { useAsync, getSecurityScan } from '@devtron-labs/devtron-fe-common-lib'
import { UseGetAppSecurityDetailsProps, UseGetAppSecurityDetailsReturnType } from './appDetails.type'

export const useGetAppSecurityDetails = ({
Expand All @@ -18,17 +12,10 @@ export const useGetAppSecurityDetails = ({
(!!appId && !!envId) || !!installedAppId,
)

const severities = scanResultResponse?.result.imageScan?.vulnerability?.summary.severities
const severityCount: SeverityCount = getSeverityCountFromSummary(severities)

const totalCount = getTotalSeverityCount(severityCount)

return {
scanResultLoading,
scanResultResponse,
scanResultError,
reloadScanResult,
severityCount,
totalCount,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import React, { useState } from 'react'
import Tippy from '@tippyjs/react'
import { getTotalSeverityCount, SecurityModal } from '@devtron-labs/devtron-fe-common-lib'
import { getScanToolAndSeverityCount, SecurityModal } from '@devtron-labs/devtron-fe-common-lib'
import { ReactComponent as Question } from '../../../../assets/icons/ic-help-outline.svg'
import { ReactComponent as Bug } from '../../../../assets/icons/ic-nav-bug.svg'
import { ReactComponent as Secure } from '../../../../assets/icons/ic-secure.svg'
Expand All @@ -37,13 +37,28 @@ export const SecurityVulnerabilityCard = ({

const handleModalClose = () => setShowScanDetailsModal(false)

const { scanResultLoading, scanResultResponse, scanResultError, reloadScanResult, severityCount } =
useGetAppSecurityDetails({ appId: +appId, envId: +envId, installedAppId })
const { scanResultLoading, scanResultResponse, scanResultError, reloadScanResult } = useGetAppSecurityDetails({
appId: +appId,
envId: +envId,
installedAppId,
})

const imageScanProgressing: boolean = scanResultResponse?.result.imageScan?.vulnerability?.list.some(
if (cardLoading || scanResultLoading) {
return <LoadingCard />
}

if (scanResultResponse && (!scanResultResponse.result.scanned || !scanResultResponse.result.isImageScanEnabled)) {
return null
}

const { severityCount, totalCount } = getScanToolAndSeverityCount(scanResultResponse?.result)

const imageScanVulnerabilities = scanResultResponse?.result.imageScan?.vulnerability
const imageScanList = imageScanVulnerabilities?.list ?? []
const imageScanProgressing: boolean = imageScanList.some(
(image) => image.status === 'Running' || image.status === 'Progressing',
)
const imageScanFailed: boolean = scanResultResponse?.result.imageScan?.vulnerability?.list[0].status === 'Failed'
const imageScanFailed: boolean = imageScanList[0]?.status === 'Failed'

const handleOnCardClick = () => {
if (!cardLoading && !scanResultLoading && !scanResultError && !showScanDetailsModal) {
Expand All @@ -52,8 +67,6 @@ export const SecurityVulnerabilityCard = ({
}
}

const totalCount = getTotalSeverityCount(severityCount)

const getIcon = () => {
if (scanResultError || imageScanFailed || imageScanProgressing || totalCount) {
return <Bug className="scy-7" />
Expand Down Expand Up @@ -132,14 +145,6 @@ export const SecurityVulnerabilityCard = ({
)
}

if (cardLoading || scanResultLoading) {
return <LoadingCard />
}

if (scanResultResponse && !scanResultResponse.result.scanned) {
return null
}

return (
<button type="button" className="dc__unset-button-styles" onClick={handleOnCardClick}>
<div
Expand Down
10 changes: 1 addition & 9 deletions src/components/app/details/appDetails/appDetails.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@
* limitations under the License.
*/

import {
ACTION_STATE,
ResponseType,
ScanResultDTO,
ServerErrors,
SeverityCount,
} from '@devtron-labs/devtron-fe-common-lib'
import { ACTION_STATE, ResponseType, ScanResultDTO, ServerErrors } from '@devtron-labs/devtron-fe-common-lib'
import { fetchAppDetailsInTime } from '@Components/app/service'
import { AggregatedNodes, OptionType } from '../../types'
import { SyncErrorType, AppDetails } from '../../../v2/appDetails/appDetails.type'
Expand Down Expand Up @@ -274,6 +268,4 @@ export interface UseGetAppSecurityDetailsReturnType {
scanResultResponse: ResponseType<ScanResultDTO>
scanResultError: ServerErrors
reloadScanResult: () => void
severityCount: SeverityCount
totalCount: number
}
19 changes: 3 additions & 16 deletions src/components/app/details/cIDetails/CIDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,9 @@ import {
SecuritySummaryCard,
TabGroup,
TRIGGER_STATUS_PROGRESSING,
SCAN_TOOL_ID_TRIVY,
ErrorScreenManager,
getSecurityScan,
SeverityCount,
getSeverityCountFromSummary,
getTotalSeverityCount,
SCAN_TOOL_ID_CLAIR,
getScanToolAndSeverityCount,
} from '@devtron-labs/devtron-fe-common-lib'
import { Switch, Route, Redirect, useRouteMatch, useParams, useHistory, generatePath } from 'react-router-dom'
import {
Expand Down Expand Up @@ -703,29 +699,20 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: Secu
)
}

const severityCount: SeverityCount = getSeverityCountFromSummary(
scanResultResponse?.result.imageScan?.vulnerability?.summary.severities,
)

const totalCount = getTotalSeverityCount(severityCount)

if (scanResultLoading) {
return <Progressing pageLoader />
}
if (scanResultError) {
return <ErrorScreenManager code={scanResultError.code} reload={reloadScanResult} />
}
if (scanResultResponse && !scanResultResponse.result.scanned) {
if (!scanResultResponse?.result.isImageScanEnabled) {
if (!scanResultResponse.result.isImageScanEnabled) {
return <ScanDisabledView redirectToCreate={redirectToCreate} />
}
return <ImageNotScannedView />
}

const scanToolId =
scanResultResponse?.result.imageScan?.vulnerability?.list[0].scanToolName === 'TRIVY'
? SCAN_TOOL_ID_TRIVY
: SCAN_TOOL_ID_CLAIR
const {scanToolId, severityCount, totalCount } = getScanToolAndSeverityCount(scanResultResponse?.result)

if (artifactId && !totalCount) {
return <NoVulnerabilityViewWithTool scanToolId={scanToolId} />
Expand Down
9 changes: 2 additions & 7 deletions src/components/common/helpers/Helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ import {
PluginDetailServiceParamsType,
PipelineBuildStageType,
SeverityCount,
useAsync,
ResponseType,
useMainContext,
} from '@devtron-labs/devtron-fe-common-lib'
import YAML from 'yaml'
import { Link, PromptProps } from 'react-router-dom'
Expand Down Expand Up @@ -1119,12 +1118,8 @@ export const getAPIOptionsWithTriggerTimeout = (options?: APIOptions): APIOption
return _options
}

const getEnvironmentData: () => Promise<ResponseType<{isManifestScanningEnabled: boolean}>> = importComponentFromFELibrary('getEnvironmentData', null, 'function')

export const getShowResourceScanModal = (selectedResourceKind: NodeType, isTrivyInstalled: boolean): boolean => {
const [, envVariablesResponse] = useAsync(getEnvironmentData, [], !!getEnvironmentData)

const isManifestScanningEnabled: boolean = envVariablesResponse?.result.isManifestScanningEnabled || false
const { isManifestScanningEnabled } = useMainContext()
const fromWorkloadOrRollout =
getAppDetailsAggregator(selectedResourceKind) === AggregationKeys.Workloads ||
selectedResourceKind === NodeType.Rollout
Expand Down
12 changes: 12 additions & 0 deletions src/components/common/navigation/NavigationRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export default function NavigationRoutes() {
const [environmentId, setEnvironmentId] = useState(null)
const contextValue = useMemo(() => ({ environmentId, setEnvironmentId }), [environmentId])
const [isAirgapped, setIsAirGapped] = useState(false)
const [isManifestScanningEnabled, setIsManifestScanningEnabled] = useState<boolean>(false)

const getInit = async (_serverMode: string) => {
setLoginLoader(true)
Expand Down Expand Up @@ -267,6 +268,15 @@ export default function NavigationRoutes() {
}
}

async function getManifestScanningEnabled() {
try {
const { result } = await getEnvironmentData()
setIsManifestScanningEnabled(result.isManifestScanningEnabled)
} catch (err) {
setIsManifestScanningEnabled(false)
}
}

async function getAirGapEnvironmentValue() {
if (typeof Storage === 'undefined' || !localStorage.getItem('isAirGapped')) {
try {
Expand All @@ -293,6 +303,7 @@ export default function NavigationRoutes() {
getServerMode()
if (getEnvironmentData) {
getAirGapEnvironmentValue()
getManifestScanningEnabled()
}
getCurrentServerInfo()
}
Expand Down Expand Up @@ -379,6 +390,7 @@ export default function NavigationRoutes() {
currentServerInfo,
isAirgapped,
isSuperAdmin,
isManifestScanningEnabled,
}}
>
<main className={_isOnboardingPage ? 'no-nav' : ''} id={DEVTRON_BASE_MAIN_ID}>
Expand Down
1 change: 1 addition & 0 deletions src/components/common/navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ export interface MainContext {
}
isAirgapped: boolean
isSuperAdmin: boolean
isManifestScanningEnabled: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { useRouteMatch, useHistory, useParams } from 'react-router-dom'
import NotesDrawer from './NotesDrawer'
import { getInstalledChartNotesDetail } from '../../appDetails.api'
import { importComponentFromFELibrary } from '../../../../common'
import { DeploymentAppTypes, useAsync } from '@devtron-labs/devtron-fe-common-lib'
import { DeploymentAppTypes, useAsync, useMainContext } from '@devtron-labs/devtron-fe-common-lib'
import { EnvironmentStatusComponentType } from '../environment.type'
import HelmAppConfigApplyStatusCard from './HelmAppConfigApplyStatusCard'
import AppStatusCard from '../../../../app/details/appDetails/AppStatusCard'
Expand All @@ -39,7 +39,6 @@ import IssuesListingModal from '../../../../app/details/appDetails/IssuesListing
import SecurityVulnerabilityCard from '../../../../app/details/appDetails/SecurityVulnerabilityCard'

const AppDetailsDownloadCard = importComponentFromFELibrary('AppDetailsDownloadCard')
const isFELibAvailable = importComponentFromFELibrary('isFELibAvailable', null, 'function')

const EnvironmentStatusComponent = ({
loadingDetails,
Expand All @@ -48,6 +47,7 @@ const EnvironmentStatusComponent = ({
isVirtualEnvironment,
refetchDeploymentStatus,
}: EnvironmentStatusComponentType) => {
const { isManifestScanningEnabled } = useMainContext()
const [appDetails] = useSharedState(IndexStore.getAppDetails(), IndexStore.getAppDetailsObservable())
const [showAppStatusDetail, setShowAppStatusDetail] = useState(false)
const [showNotes, setShowNotes] = useState(false)
Expand Down Expand Up @@ -183,7 +183,7 @@ const EnvironmentStatusComponent = ({
{renderHelmConfigApplyStatusBlock()}
{renderLastUpdatedBlock()}
{renderChartUsedBlock()}
{isFELibAvailable && appDetails?.appType === AppType.DEVTRON_HELM_CHART && (
{isManifestScanningEnabled && appDetails?.appType === AppType.DEVTRON_HELM_CHART && (
<SecurityVulnerabilityCard
cardLoading={cardLoading}
installedAppId={appDetails?.installedAppId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ import {
ShowMoreText,
DEPLOYMENT_STATUS,
EMPTY_STATE_STATUS,
useAsync,
ResponseType,
useMainContext,
} from '@devtron-labs/devtron-fe-common-lib'
import moment from 'moment'
import Tippy from '@tippyjs/react'
Expand Down Expand Up @@ -70,7 +69,6 @@ import {ReactComponent as ICLines } from '@Icons/ic-lines.svg'

const VirtualHistoryArtifact = importComponentFromFELibrary('VirtualHistoryArtifact')
const ChartSecurityTab = importComponentFromFELibrary('ChartSecurityTab', null, 'function')
const getEnvironmentData: () => Promise<ResponseType<{isManifestScanningEnabled: boolean}>> = importComponentFromFELibrary('getEnvironmentData', null, 'function')

interface DeploymentManifestDetail extends ChartDeploymentManifestDetail {
loading?: boolean
Expand Down Expand Up @@ -112,15 +110,14 @@ const ChartDeploymentHistory = ({
let initTimer = null
// Checking if deployment app type is argocd only then show steps tab

const [, envVariablesResponse] = useAsync(getEnvironmentData, [], !!getEnvironmentData)
const isScanV2Enabled = envVariablesResponse?.result.isManifestScanningEnabled ?? false
const { isManifestScanningEnabled } = useMainContext()

const deploymentTabs = () => {
const tabs = [
DEPLOYMENT_HISTORY_TAB.SOURCE,
DEPLOYMENT_HISTORY_TAB.VALUES_YAML,
DEPLOYMENT_HISTORY_TAB.HELM_GENERATED_MANIFEST,
(ChartSecurityTab && isScanV2Enabled && !isExternal && DEPLOYMENT_HISTORY_TAB.SECURITY),
(ChartSecurityTab && isManifestScanningEnabled && !isExternal && DEPLOYMENT_HISTORY_TAB.SECURITY),
]
if (installedAppInfo?.deploymentType === DeploymentAppTypes.GITOPS) {
tabs.unshift(DEPLOYMENT_HISTORY_TAB.STEPS)
Expand Down Expand Up @@ -599,7 +596,7 @@ const ChartDeploymentHistory = ({
status={deployment.status}
/>
)}
{selectedDeploymentTabName === DEPLOYMENT_HISTORY_TAB.SECURITY && !isExternal && isScanV2Enabled && ChartSecurityTab && (
{selectedDeploymentTabName === DEPLOYMENT_HISTORY_TAB.SECURITY && !isExternal && isManifestScanningEnabled && ChartSecurityTab && (
<ChartSecurityTab installedAppVersionHistoryId={deploymentHistoryArr[selectedDeploymentHistoryIndex].version} />
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { DeploymentAppTypes } from '@devtron-labs/devtron-fe-common-lib'
import { DeploymentAppTypes, useMainContext } from '@devtron-labs/devtron-fe-common-lib'
import { ChartValuesType, ChartVersionType } from '../../../charts/charts.types'
import { ChartValuesViewAction, ChartValuesViewActionTypes, ChartValuesViewState } from './ChartValuesView.type'

Expand All @@ -24,8 +24,10 @@ export const initState = (
installedConfigFromParent: any,
chartVersionsDataFromParent: ChartVersionType[],
deploymentAppType: DeploymentAppTypes,
isManifestScanningEnabled: boolean,
): ChartValuesViewState => {

const {isManifestScanningEnabled} = useMainContext()

return {
isLoading: true,
isLodingGUIForm: false,
Expand Down
10 changes: 1 addition & 9 deletions src/components/v2/values/chartValuesDiff/ChartValuesView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import {
ConfigurationType,
ToastManager,
ToastVariantType,
useAsync,
} from '@devtron-labs/devtron-fe-common-lib'
import YAML from 'yaml'
import Tippy from '@tippyjs/react'
Expand Down Expand Up @@ -144,8 +143,6 @@ import { AUTO_GENERATE_GITOPS_REPO, CHART_VALUE_ID } from './constant'
const GeneratedHelmDownload = importComponentFromFELibrary('GeneratedHelmDownload')
const getDownloadManifestUrl = importComponentFromFELibrary('getDownloadManifestUrl', null, 'function')
const ToggleSecurityScan = importComponentFromFELibrary('ToggleSecurityScan', null, 'function')
const getEnvironmentData: () => Promise<ResponseType<{ isManifestScanningEnabled: boolean }>> =
importComponentFromFELibrary('getEnvironmentData', null, 'function')

const ChartValuesView = ({
appId,
Expand All @@ -167,7 +164,7 @@ const ChartValuesView = ({
presetValueId: string
envId: string
}>()
const { serverMode } = useMainContext()
const { serverMode, isManifestScanningEnabled } = useMainContext()
const { handleDownload } = useDownload()
const chartValuesAbortRef = useRef<AbortController>(new AbortController())
const [chartValuesList, setChartValuesList] = useState<ChartValuesType[]>(chartValuesListFromParent || [])
Expand All @@ -186,10 +183,6 @@ const ChartValuesView = ({
const [showRepoSelector, setShowRepoSelector] = useState<boolean>(false)
const [shouldShowPrompt, setShouldShowPrompt] = useState<boolean>(true)

const [, envVariablesResponse] = useAsync(getEnvironmentData, [], !!getEnvironmentData)

const isManifestScanningEnabled: boolean = envVariablesResponse?.result.isManifestScanningEnabled || false

const [commonState, dispatch] = useReducer(
chartValuesReducer,
initState(
Expand All @@ -204,7 +197,6 @@ const ChartValuesView = ({
installedConfigFromParent,
chartVersionsDataFromParent,
appDetails?.deploymentAppType,
isManifestScanningEnabled,
),
)

Expand Down
Loading