Skip to content
Merged
Show file tree
Hide file tree
Changes from 34 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.
30 changes: 26 additions & 4 deletions src/components/app/details/cIDetails/CIDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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,8 @@ 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 novulnerability from '../../../../assets/img/ic-vulnerability-not-found.svg';
import { ScannedByToolModal } from '../../../common/security/ScannedByToolModal'

const terminalStatus = new Set(['succeeded', 'failed', 'error', 'cancelled', 'nottriggered', 'notbuilt'])
let statusSet = new Set(['starting', 'running', 'pending'])
Expand Down Expand Up @@ -390,6 +392,21 @@ const HistoryLogs = ({ triggerDetails, isBlobStorageConfigured, isJobView, appId
</div>
)
}
export function NoVulnerabilityViewWithTool({scanToolId}:{scanToolId:number}) {
return (
<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">
<ScannedByToolModal scanToolId={scanToolId} />
</span>
}
/>
</div>
)
}

const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: SecurityTabType) => {
const [isCollapsed, setIsCollapsed] = useState(false)
Expand All @@ -405,6 +422,7 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: Secu
scanned: false,
isLoading: !!artifactId,
isError: false,
ScanToolId: null,
})
const { appId } = useParams<{ appId: string }>()
const { push } = useHistory()
Expand All @@ -419,6 +437,7 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: Secu
scanned: result.scanned,
isLoading: false,
isError: false,
ScanToolId: result.scanToolId,
})
} catch (error) {
// showError(error);
Expand All @@ -433,7 +452,7 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: Secu
function toggleCollapse() {
setIsCollapsed(!isCollapsed)
}

useEffect(() => {
if (artifactId) {
callGetSecurityIssues()
Expand Down Expand Up @@ -472,8 +491,9 @@ const SecurityTab = ({ ciPipelineId, artifactId, status, appIdFromParent }: Secu
return <ImageNotScannedView />
}
} else if (artifactId && securityData.scanned && !securityData.vulnerabilities.length) {
return <NoVulnerabilityView />
return <NoVulnerabilityViewWithTool scanToolId={securityData.ScanToolId}/>
}
const scanToolId= securityData.ScanToolId

return (
<>
Expand All @@ -497,7 +517,9 @@ 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">
<ScannedByToolModal scanToolId={scanToolId}/>
</div>
</div>
{isCollapsed ? (
''
Expand Down
18 changes: 14 additions & 4 deletions src/components/app/details/triggerView/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export const CI_MATERIAL_EMPTY_STATE_MESSAGING = {
Retry: 'Retry',
WebhookModalCTA: 'View all incoming webhook payloads',
NoCommitEligibleCommit: 'No eligible commit found in recent commits',
NoCommitEligibleCommitSubtitle: 'Commits that contain changes only in excluded files or folders are not eligible for build.',
NoCommitEligibleCommitSubtitle:
'Commits that contain changes only in excluded files or folders are not eligible for build.',
NoCommitEligibleCommitButtonText: 'Show excluded commits',
}
export const IGNORE_CACHE_INFO = {
Expand All @@ -25,11 +26,11 @@ export const IGNORE_CACHE_INFO = {
},
CacheNotAvailable: {
title: 'Cache will be generated for this pipeline run',
infoText: 'Cache will be used in future runs to reduce build time.'
infoText: 'Cache will be used in future runs to reduce build time.',
},
IgnoreCache: {
title: 'Ignore Cache',
infoText: 'Ignoring cache will lead to longer build time.'
infoText: 'Ignoring cache will lead to longer build time.',
},
}
export const BRANCH_REGEX_MODAL_MESSAGING = {
Expand Down Expand Up @@ -75,11 +76,20 @@ export const TRIGGER_VIEW_GA_EVENTS = {
ApprovalNodeClicked: {
category: 'Trigger View',
action: 'Approval Node Clicked',
}
},
}

export const ARTIFACT_STATUS = {
Progressing: 'Progressing',
Degraded: 'Degraded',
Failed: 'Failed',
}

export const NO_VULNERABILITY_TEXT = {
Secured: 'You’re secure!',
NoVulnerabilityFound: 'No security vulnerability found for this image.',
}
export const IMAGE_SCAN_TOOL = {
Clair: 'Clair',
Trivy: 'Trivy',
}
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
20 changes: 15 additions & 5 deletions src/components/app/details/triggerView/cdMaterial.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ 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 { ModuleStatus } from '../../../v2/devtronStackManager/DevtronStackManager.type'
import { DropdownIndicator, Option } from '../../../v2/common/ReactSelect.utils'
import {
Expand All @@ -54,7 +53,9 @@ import {
} from './TriggerView.utils'
import TriggerViewConfigDiff from './triggerViewConfigDiff/TriggerViewConfigDiff'
import Tippy from '@tippyjs/react'
import { ARTIFACT_STATUS } from './Constants'
import { ARTIFACT_STATUS,NO_VULNERABILITY_TEXT} from './Constants'
import { ScannedByToolModal } from '../../../common/security/ScannedByToolModal'
import { ModuleNameMap } from '../../../../config'

const ApprovalInfoTippy = importComponentFromFELibrary('ApprovalInfoTippy')
const ExpireApproval = importComponentFromFELibrary('ExpireApproval')
Expand Down Expand Up @@ -221,15 +222,24 @@ 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">{NO_VULNERABILITY_TEXT.Secured}</p>
<p>{NO_VULNERABILITY_TEXT.NoVulnerabilityFound}</p>
<p className="security-tab-empty__subtitle">{mat.lastExecution}</p>
<p className="workflow__header dc__border-radius-24 bcn-0">
<ScannedByToolModal scanToolId={mat.scanToolId} />
</p>
</div>
)
} else
return (
<div className="security-tab">
<p className="security-tab__last-scanned">Scanned on {mat.lastExecution} </p>
<div className="flexbox dc__content-space">
<span className="flex left security-tab__last-scanned ">Scanned on {mat.lastExecution} </span>
<span className="flex right">
<ScannedByToolModal scanToolId={mat.scanToolId} />
</span>
</div>
<ScanVulnerabilitiesTable vulnerabilities={mat.vulnerabilities} />
</div>
)
Expand Down
53 changes: 37 additions & 16 deletions src/components/common/navigation/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ const NavigationList = [
href: URLS.SECURITY,
iconClass: 'nav-security',
icon: SecurityIcon,
moduleName: ModuleNameMap.SECURITY,
moduleName: ModuleNameMap.SECURITY_CLAIR,
moduleNameTrivy: ModuleNameMap.SECURITY_TRIVY,
},
{
title: 'Bulk Edit',
Expand Down Expand Up @@ -181,29 +182,48 @@ export default class Navigation extends Component<
componentDidUpdate(prevProps) {
if (
this.props.moduleInInstallingState !== prevProps.moduleInInstallingState &&
this.props.moduleInInstallingState === ModuleNameMap.SECURITY
(this.props.moduleInInstallingState === ModuleNameMap.SECURITY_CLAIR ||
this.props.moduleInInstallingState === ModuleNameMap.SECURITY_TRIVY)
) {
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_CLAIR] ||
window._env_.K8S_CLIENT ||
this.props.installedModuleMap.current?.[ModuleNameMap.SECURITY_TRIVY]
) {
return
}
try {
const { result } = await getModuleInfo(ModuleNameMap.SECURITY)
if (result?.status === ModuleStatus.INSTALLED) {
this.props.installedModuleMap.current = {
...this.props.installedModuleMap.current,
[ModuleNameMap.SECURITY]: true,
}
this.setState({ forceUpdateTime: Date.now() })
} else if (result?.status === ModuleStatus.INSTALLING) {
this.securityModuleStatusTimer = setTimeout(() => {
this.getSecurityModuleStatus(MODULE_STATUS_RETRY_COUNT)
}, MODULE_STATUS_POLLING_INTERVAL)
}
Promise.all([getModuleInfo(ModuleNameMap.SECURITY_CLAIR), getModuleInfo(ModuleNameMap.SECURITY_TRIVY)]).then(
([clairResponse, trivyResponse]) => {
if (clairResponse?.result?.status === ModuleStatus.INSTALLED) {
this.props.installedModuleMap.current = {
...this.props.installedModuleMap.current,
[ModuleNameMap.SECURITY_CLAIR]: true,
}
this.setState({ forceUpdateTime: Date.now() })
} else if (clairResponse?.result?.status === ModuleStatus.INSTALLING) {
this.securityModuleStatusTimer = setTimeout(() => {
this.getSecurityModuleStatus(MODULE_STATUS_RETRY_COUNT)
}, MODULE_STATUS_POLLING_INTERVAL)
}
if (trivyResponse?.result?.status === ModuleStatus.INSTALLED) {
this.props.installedModuleMap.current = {
...this.props.installedModuleMap.current,
[ModuleNameMap.SECURITY_TRIVY]: true,
}
this.setState({ forceUpdateTime: Date.now() })
} else if (trivyResponse?.result?.status === ModuleStatus.INSTALLING) {
this.securityModuleStatusTimer = setTimeout(() => {
this.getSecurityModuleStatus(MODULE_STATUS_RETRY_COUNT)
}, MODULE_STATUS_POLLING_INTERVAL)
}
},
)
} catch (error) {
if (retryOnError >= 0) {
this.getSecurityModuleStatus(retryOnError--)
Expand Down Expand Up @@ -301,7 +321,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