Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
04435aa
Trivy Image scanning module Integration
Shivam-nagar23 May 16, 2023
43880b8
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 May 16, 2023
89bd6d1
minor changes
Shivam-nagar23 May 17, 2023
ae3e64b
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 May 17, 2023
f720d34
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 May 18, 2023
c66362b
Scanning Changes
Shivam-nagar23 May 20, 2023
92989c9
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 May 20, 2023
dc62b98
Tesing
Shivam-nagar23 May 21, 2023
c716b81
minor changes
Shivam-nagar23 May 22, 2023
8716dce
Final Changes
Shivam-nagar23 May 22, 2023
651385e
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 May 22, 2023
9c0aec8
Changes final
Shivam-nagar23 May 22, 2023
f592cd3
Final Changes
Shivam-nagar23 May 23, 2023
974afe3
Enabling Chnages
Shivam-nagar23 May 24, 2023
ad980e1
Enabling tool option
Shivam-nagar23 May 28, 2023
d1c9088
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 May 28, 2023
a368abc
Minor changes
Shivam-nagar23 May 29, 2023
6b8dc81
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 May 29, 2023
9444f82
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 May 29, 2023
4bf1f97
margin-fix
Shivam-nagar23 May 29, 2023
3287975
Review changes
Shivam-nagar23 May 30, 2023
9eedba3
review Changes
Shivam-nagar23 May 30, 2023
3b913a4
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 May 30, 2023
cd362fe
uat fixes
Shivam-nagar23 May 30, 2023
aa386c9
Review Changes
Shivam-nagar23 May 31, 2023
eaa577d
Review changes
Shivam-nagar23 May 31, 2023
d6f2d29
Final Changes
Shivam-nagar23 May 31, 2023
44802bd
Final Changes
Shivam-nagar23 May 31, 2023
9f9c4c3
reverting demo url
Shivam-nagar23 May 31, 2023
edd64b3
minor changes
Shivam-nagar23 May 31, 2023
1d845b8
Data-testids changes
Shivam-nagar23 May 31, 2023
682c304
minor changes
Shivam-nagar23 May 31, 2023
977bc61
uat Changes
Shivam-nagar23 Jun 1, 2023
ed43003
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 Jun 1, 2023
7e29d5d
Testing change
Shivam-nagar23 Jun 1, 2023
bb98bad
Testing Change
Shivam-nagar23 Jun 1, 2023
f8eaa5f
Version changes
Shivam-nagar23 Jun 1, 2023
eb4326b
fixes minor
Shivam-nagar23 Jun 2, 2023
4d85725
Merge branch 'main' into trivy-image-scanning
Shivam-nagar23 Jun 3, 2023
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
3 changes: 2 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ CLUSTER_TERMINAL_CONNECTION_RETRY_COUNT=7
ENABLE_CHART_SEARCH_IN_HELM_DEPLOY=false
HIDE_EXCLUDE_INCLUDE_GIT_COMMITS=true
ENABLE_BUILD_CONTEXT=false
ENABLE_RESTART_WORKLOAD=false
CLAIR_TOOL_VERSION=
ENABLE_RESTART_WORKLOAD=false
20 changes: 20 additions & 0 deletions src/assets/icons/ic-clair-to-trivy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/assets/icons/ic-clair.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions src/assets/icons/ic-trivy-to-clair.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/assets/icons/ic-trivy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions src/components/ApplicationGroup/AppGroup.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,11 @@ export const getCIConfigList = (envID: string, appIds: string): Promise<CIConfig
getCIConfigMin(envID, appIds),
getModuleInfo(ModuleNameMap.SECURITY),
getModuleConfigured(ModuleNameMap.BLOB_STORAGE),
]).then(([ciConfig, securityInfo, moduleConfig]) => {
getModuleInfo(ModuleNameMap.SECURITY_TRIVY),
]).then(([ciConfig, securityInfo, moduleConfig,trivysecurityInfo]) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trivySecurityInfo fix camel casing

return {
pipelineList: ciConfig.result,
securityModuleInstalled: securityInfo?.result?.status === ModuleStatus.INSTALLED,
securityModuleInstalled: (securityInfo?.result?.status === ModuleStatus.INSTALLED || trivysecurityInfo?.result?.status === ModuleStatus.INSTALLED),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create a const above

blobStorageConfigured: moduleConfig?.result?.enabled,
}
})
Expand Down
3 changes: 2 additions & 1 deletion src/components/CIPipelineN/CIPipeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ export default function CIPipeline({
const getSecurityModuleStatus = async (): Promise<void> => {
try {
const { result } = await getModuleInfo(ModuleNameMap.SECURITY)
if (result?.status === ModuleStatus.INSTALLED) {
const { result:result2 } =await getModuleInfo(ModuleNameMap.SECURITY_TRIVY)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you need both calls data use Promise.all

if (result?.status === ModuleStatus.INSTALLED || result2?.status === ModuleStatus.INSTALLED ) {
setSecurityModuleInstalled(true)
}
} catch (error) {}
Expand Down
28 changes: 22 additions & 6 deletions src/components/app/details/cIDetails/CIDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import React, { useState, useEffect, useMemo } from 'react'
import { showError, Progressing, Reload, GenericEmptyState } from '@devtron-labs/devtron-fe-common-lib'
import { getCIPipelines, getCIHistoricalStatus, getTriggerHistory, getArtifact } from '../../service'
import { useScrollable, useAsync, useInterval, mapByKey, asyncWrap } from '../../../common'
import { URLS, ModuleNameMap } from '../../../../config'
import { URLS, ModuleNameMap, SCAN_TOOL_ID_TRIVY } from '../../../../config'
import { NavLink, Switch, Route, Redirect } from 'react-router-dom'
import { useRouteMatch, useParams, useHistory, generatePath } from 'react-router'
import { BuildDetails, CIPipeline, HistoryLogsType, SecurityTabType } from './types'
import { ReactComponent as Down } from '../../../../assets/icons/ic-dropdown-filled.svg'
import { getLastExecutionByArtifactId } from '../../../../services/service'
import { ScanDisabledView, ImageNotScannedView, NoVulnerabilityView, CIRunningView } from './cIDetails.util'
import { ScanDisabledView, ImageNotScannedView, CIRunningView } from './cIDetails.util'
import './ciDetails.scss'
import { getModuleInfo } from '../../../v2/devtronStackManager/DevtronStackManager.service'
import { ModuleStatus } from '../../../v2/devtronStackManager/DevtronStackManager.type'
Expand All @@ -20,6 +20,9 @@ import Artifacts from '../cicdHistory/Artifacts'
import { CICDSidebarFilterOptionType, History, HistoryComponentType } from '../cicdHistory/types'
import LogsRenderer from '../cicdHistory/LogsRenderer'
import { EMPTY_STATE_STATUS } from '../../../../config/constantMessaging'
import { ReactComponent as Clair } from '../../../../assets/icons/ic-clair.svg'
import { ReactComponent as Trivy } from '../../../../assets/icons/ic-trivy.svg'
import novulnerability from '../../../../assets/img/ic-vulnerability-not-found.svg';

const terminalStatus = new Set(['succeeded', 'failed', 'error', 'cancelled', 'nottriggered', 'notbuilt'])
let statusSet = new Set(['starting', 'running', 'pending'])
Expand All @@ -41,6 +44,7 @@ export default function CIDetails({ isJobView }: { isJobView?: boolean }) {
getCIPipelines(+appId),
getModuleInfo(ModuleNameMap.SECURITY),
getModuleConfigured(ModuleNameMap.BLOB_STORAGE),
getModuleInfo(ModuleNameMap.SECURITY_TRIVY)
]),
[appId],
)
Expand Down Expand Up @@ -162,8 +166,9 @@ export default function CIDetails({ isJobView }: { isJobView?: boolean }) {
synchroniseState={synchroniseState}
triggerHistory={triggerHistory}
isSecurityModuleInstalled={
initDataResults[1]?.['value']?.['result']?.status ===
ModuleStatus.INSTALLED || false
(initDataResults[1]?.['value']?.['result']?.status ===
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move it to top

ModuleStatus.INSTALLED|| initDataResults[3]?.['value']?.['result']?.status ===
ModuleStatus.INSTALLED )|| false
}
isBlobStorageConfigured={
initDataResults[2]?.['value']?.['result']?.enabled || false
Expand Down Expand Up @@ -405,6 +410,7 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: Secu
scanned: false,
isLoading: !!artifactId,
isError: false,
ScanToolId:0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 can be an Id use null instead if you want intial state & format the code

})
const { appId } = useParams<{ appId: string }>()
const { push } = useHistory()
Expand All @@ -419,6 +425,7 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: Secu
scanned: result.scanned,
isLoading: false,
isError: false,
ScanToolId:result.scanToolId
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format the code

})
} catch (error) {
// showError(error);
Expand Down Expand Up @@ -472,7 +479,13 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: Secu
return <ImageNotScannedView />
}
} else if (artifactId && securityData.scanned && !securityData.vulnerabilities.length) {
return <NoVulnerabilityView />
return (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move into a function & format

<div className='flex h-100'>
<GenericEmptyState image={novulnerability} title={EMPTY_STATE_STATUS.CI_DEATILS_NO_VULNERABILITY_FOUND} children={<span className="flex workflow__header dc__border-radius-24 bcn-0">
Scanned By {securityData.ScanToolId===SCAN_TOOL_ID_TRIVY ? 'Trivy ' : 'Clair '} {securityData.ScanToolId===SCAN_TOOL_ID_TRIVY ? <Trivy className="h-20 w-20" /> : <Clair className="h-20 w-20" />}
</span>} />
</div>
)
}

return (
Expand All @@ -497,7 +510,10 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: Secu
{severityCount.critical === 0 && severityCount.moderate === 0 && severityCount.low !== 0 ? (
<span className="dc__fill-low">{severityCount.low} Low</span>
) : null}
<div className="security-scan__type">post build execution</div>
<div className="security-scan__type flex">
Scanned By {securityData.ScanToolId=== SCAN_TOOL_ID_TRIVY? 'Trivy' : 'Clair'}
{securityData.ScanToolId===SCAN_TOOL_ID_TRIVY ? <Trivy /> : <Clair/>}
</div>
</div>
{isCollapsed ? (
''
Expand Down
1 change: 1 addition & 0 deletions src/components/app/details/triggerView/TriggerView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,7 @@ class TriggerView extends Component<TriggerViewProps, TriggerViewState> {
node[this.state.materialType][materialIndex]['lastExecution'] =
response.result.lastExecution
node[this.state.materialType][materialIndex]['vulnerabilitiesLoading'] = false
node[this.state.materialType][materialIndex]['scanToolId']=response.result.scanToolId
}
return node
})
Expand Down
18 changes: 13 additions & 5 deletions src/components/app/details/triggerView/cdMaterial.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { ReactComponent as WarningIcon } from '../../../../assets/icons/ic-warni
import { ReactComponent as BackIcon } from '../../../../assets/icons/ic-arrow-backward.svg'
import { ReactComponent as BotIcon } from '../../../../assets/icons/ic-bot.svg'
import { ReactComponent as World } from '../../../../assets/icons/ic-world.svg'
import { ReactComponent as Clair } from '../../../../assets/icons/ic-clair.svg'
import { ReactComponent as Trivy } from '../../../../assets/icons/ic-trivy.svg'
import { ReactComponent as Failed } from '../../../../assets/icons/ic-rocket-fail.svg'
import { ReactComponent as InfoIcon } from '../../../../assets/icons/info-filled.svg'
import play from '../../../../assets/icons/misc/arrow-solid-right.svg'
Expand All @@ -42,7 +44,7 @@ import { CDButtonLabelMap, getCommonConfigSelectStyles, TriggerViewContext } fro
import { getLatestDeploymentConfig, getRecentDeploymentConfig, getSpecificDeploymentConfig } from '../../service'
import GitCommitInfoGeneric from '../../../common/GitCommitInfoGeneric'
import { getModuleInfo } from '../../../v2/devtronStackManager/DevtronStackManager.service'
import { ModuleNameMap } from '../../../../config'
import { ModuleNameMap, SCAN_TOOL_ID_TRIVY } from '../../../../config'
import { ModuleStatus } from '../../../v2/devtronStackManager/DevtronStackManager.type'
import { DropdownIndicator, Option } from '../../../v2/common/ReactSelect.utils'
import {
Expand Down Expand Up @@ -153,7 +155,8 @@ export class CDMaterial extends Component<CDMaterialProps, CDMaterialState> {
async getSecurityModuleStatus(): Promise<void> {
try {
const { result } = await getModuleInfo(ModuleNameMap.SECURITY)
if (result?.status === ModuleStatus.INSTALLED) {
const {result:result2} =await getModuleInfo(ModuleNameMap.SECURITY_TRIVY)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing as before

if (result?.status === ModuleStatus.INSTALLED|| result2?.status === ModuleStatus.INSTALLED) {
this.setState({ isSecurityModuleInstalled: true })
}
} catch (error) {}
Expand Down Expand Up @@ -221,15 +224,20 @@ export class CDMaterial extends Component<CDMaterialProps, CDMaterialState> {
)
} else if (!mat.vulnerabilitiesLoading && mat.vulnerabilities.length === 0) {
return (
<div className="security-tab-empty">
<p className="security-tab-empty__title">No vulnerabilities Found</p>
<div className="security-tab-empty summary-view__card">
<p className="security-tab-empty__title">You’re secure!</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move texts to constants

<p className="">No security vulnerability found for this image.</p>
<p className="security-tab-empty__subtitle">{mat.lastExecution}</p>
<p className='workflow__header dc__border-radius-24 bcn-0'>Scanned By {mat.scanToolId===SCAN_TOOL_ID_TRIVY ?'Trivy':'Clair'}{mat.scanToolId===SCAN_TOOL_ID_TRIVY? <Trivy className='h-20 w-20'/>:<Clair className='h-20 w-20'/>} </p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format code

</div>
)
} else
return (
<div className="security-tab">
<p className="security-tab__last-scanned">Scanned on {mat.lastExecution} </p>
<div className='flexbox dc__content-space'>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format

<span className="flex left security-tab__last-scanned ">Scanned on {mat.lastExecution} </span>
<span className='flex right'>Scanned By {mat.scanToolId===SCAN_TOOL_ID_TRIVY?'Trivy':'Clair'}{mat.scanToolId===SCAN_TOOL_ID_TRIVY? <Trivy className='h-20 w-20'/>:<Clair className='h-20 w-20'/>} </span>
</div>
<ScanVulnerabilitiesTable vulnerabilities={mat.vulnerabilities} />
</div>
)
Expand Down
22 changes: 19 additions & 3 deletions src/components/common/navigation/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ const NavigationList = [
iconClass: 'nav-security',
icon: SecurityIcon,
moduleName: ModuleNameMap.SECURITY,
moduleNameTrivy: ModuleNameMap.SECURITY_TRIVY,
},
{
title: 'Bulk Edit',
Expand Down Expand Up @@ -181,18 +182,19 @@ export default class Navigation extends Component<
componentDidUpdate(prevProps) {
if (
this.props.moduleInInstallingState !== prevProps.moduleInInstallingState &&
this.props.moduleInInstallingState === ModuleNameMap.SECURITY
(this.props.moduleInInstallingState === ModuleNameMap.SECURITY || ModuleNameMap.SECURITY_TRIVY)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no comparison of constant with variable. Please fix this

) {
this.getSecurityModuleStatus(MODULE_STATUS_RETRY_COUNT)
}
}

async getSecurityModuleStatus(retryOnError: number): Promise<void> {
if (this.props.installedModuleMap.current?.[ModuleNameMap.SECURITY] || window._env_.K8S_CLIENT) {
if (this.props.installedModuleMap.current?.[ModuleNameMap.SECURITY] || window._env_.K8S_CLIENT || this.props.installedModuleMap.current?.[ModuleNameMap.SECURITY_TRIVY]) {
return
}
try {
const { result } = await getModuleInfo(ModuleNameMap.SECURITY)
const { result:result2 } = await getModuleInfo(ModuleNameMap.SECURITY_TRIVY)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Promise.all

if (result?.status === ModuleStatus.INSTALLED) {
this.props.installedModuleMap.current = {
...this.props.installedModuleMap.current,
Expand All @@ -204,6 +206,19 @@ export default class Navigation extends Component<
this.getSecurityModuleStatus(MODULE_STATUS_RETRY_COUNT)
}, MODULE_STATUS_POLLING_INTERVAL)
}
if (result2?.status === ModuleStatus.INSTALLED) {
this.props.installedModuleMap.current = {
...this.props.installedModuleMap.current,
[ModuleNameMap.SECURITY_TRIVY]: true,
}
this.setState({ forceUpdateTime: Date.now() })
} else if (result2?.status === ModuleStatus.INSTALLING) {
this.securityModuleStatusTimer = setTimeout(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats the purpose of this condition

this.getSecurityModuleStatus(MODULE_STATUS_RETRY_COUNT)
}, MODULE_STATUS_POLLING_INTERVAL)
}


} catch (error) {
if (retryOnError >= 0) {
this.getSecurityModuleStatus(retryOnError--)
Expand Down Expand Up @@ -301,7 +316,8 @@ export default class Navigation extends Component<
return (
(this.props.serverMode === SERVER_MODE.FULL && !item.moduleName) ||
(this.props.serverMode === SERVER_MODE.EA_ONLY && item.isAvailableInEA) ||
this.props.installedModuleMap.current?.[item.moduleName]
(this.props.installedModuleMap.current?.[item.moduleName]) ||
(this.props.installedModuleMap.current?.[item.moduleNameTrivy])
)
}
}
Expand Down
1 change: 1 addition & 0 deletions src/components/common/navigation/NavigationRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ export default function NavigationRoutes() {
<DevtronStackManager
serverInfo={currentServerInfo.serverInfo}
getCurrentServerInfo={getCurrentServerInfo}
isSuperAdmin={isSuperAdmin}
/>
</Route>,
<Route key={URLS.GETTING_STARTED} exact path={`/${URLS.GETTING_STARTED}`}>
Expand Down
Loading