-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(tekton): add CVE summary and signed badge (#1028)
feat(tekton): Add CVE summary and signed badge
- Loading branch information
1 parent
94bda1c
commit effdef0
Showing
17 changed files
with
497 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 8 additions & 1 deletion
9
plugins/tekton/src/components/PipelineRunList/PipelineRunColumnHeader.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
plugins/tekton/src/components/PipelineRunList/PipelineRunVulnerabilities.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import * as React from 'react'; | ||
|
||
import { makeStyles, Theme } from '@material-ui/core'; | ||
import { Tooltip } from '@patternfly/react-core'; | ||
import { | ||
AngleDoubleDownIcon, | ||
AngleDoubleUpIcon, | ||
CriticalRiskIcon, | ||
EqualsIcon, | ||
} from '@patternfly/react-icons'; | ||
import { global_palette_blue_300 as lowColor } from '@patternfly/react-tokens/dist/js/global_palette_blue_300'; | ||
import { global_palette_gold_400 as mediumColor } from '@patternfly/react-tokens/dist/js/global_palette_gold_400'; | ||
import { global_palette_orange_300 as highColor } from '@patternfly/react-tokens/dist/js/global_palette_orange_300'; | ||
import { global_palette_red_200 as criticalColor } from '@patternfly/react-tokens/dist/js/global_palette_red_200'; | ||
|
||
import { PipelineRunKind } from '@janus-idp/shared-react'; | ||
|
||
import { usePipelineRunScanResults } from '../../hooks/usePipelineRunScanResults'; | ||
|
||
const useVStyles = makeStyles((theme: Theme) => ({ | ||
pipelineVulnerabilities: { | ||
display: 'flex', | ||
flexWrap: 'wrap', | ||
gap: theme.spacing(1), | ||
}, | ||
severityContainer: { | ||
alignItems: 'center', | ||
display: 'flex', | ||
flexWrap: 'nowrap', | ||
gap: theme.spacing(0.5), | ||
}, | ||
severityStatus: { | ||
alignItems: 'center', | ||
display: 'flex', | ||
flexWrap: 'nowrap', | ||
gap: theme.spacing(0.5), | ||
}, | ||
severityCount: { | ||
fontWeight: 'bold', | ||
}, | ||
criticalStatus: { | ||
color: criticalColor.value, | ||
}, | ||
highStatus: { | ||
color: highColor.value, | ||
}, | ||
mediumStatus: { | ||
color: mediumColor.value, | ||
}, | ||
lowStatus: { | ||
color: lowColor.value, | ||
}, | ||
})); | ||
|
||
type PipelineRunVulnerabilitiesProps = { | ||
pipelineRun: PipelineRunKind; | ||
condensed?: boolean; | ||
}; | ||
|
||
const PipelineRunVulnerabilities: React.FC<PipelineRunVulnerabilitiesProps> = ({ | ||
pipelineRun, | ||
condensed, | ||
}) => { | ||
const classes = useVStyles(); | ||
const scanResults = usePipelineRunScanResults(pipelineRun); | ||
|
||
return ( | ||
<div className={classes.pipelineVulnerabilities}> | ||
{scanResults?.vulnerabilities ? ( | ||
<> | ||
<div className={classes.severityContainer}> | ||
<span className={classes.severityStatus}> | ||
<Tooltip content="Critical"> | ||
<CriticalRiskIcon | ||
title="Critical" | ||
className={classes.criticalStatus} | ||
/> | ||
</Tooltip> | ||
{!condensed ? 'Critical' : null} | ||
</span> | ||
<span className={classes.severityCount}> | ||
{scanResults.vulnerabilities.critical || 0} | ||
</span> | ||
</div> | ||
<div className={classes.severityContainer}> | ||
<span className={classes.severityStatus}> | ||
<Tooltip content="High"> | ||
<AngleDoubleUpIcon | ||
title="High" | ||
className={classes.highStatus} | ||
/> | ||
</Tooltip> | ||
{!condensed ? 'High' : null} | ||
</span> | ||
<span className={classes.severityCount}> | ||
{scanResults.vulnerabilities.high || 0} | ||
</span> | ||
</div> | ||
<div className={classes.severityContainer}> | ||
<span className={classes.severityStatus}> | ||
<Tooltip content="Medium"> | ||
<EqualsIcon title="Medium" className={classes.mediumStatus} /> | ||
</Tooltip> | ||
{!condensed ? 'Medium' : null} | ||
</span> | ||
<span className={classes.severityCount}> | ||
{scanResults.vulnerabilities.medium || 0} | ||
</span> | ||
</div> | ||
<div className={classes.severityContainer}> | ||
<span className={classes.severityStatus}> | ||
<Tooltip content="medium"> | ||
<AngleDoubleDownIcon | ||
title="Low" | ||
className={classes.lowStatus} | ||
/> | ||
</Tooltip> | ||
{!condensed ? 'Low' : null} | ||
</span> | ||
<span className={classes.severityCount}> | ||
{scanResults.vulnerabilities.low || 0} | ||
</span> | ||
</div> | ||
</> | ||
) : ( | ||
'-' | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default PipelineRunVulnerabilities; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
declare module '*.svg' { | ||
const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>; | ||
export default content; | ||
} |
53 changes: 53 additions & 0 deletions
53
plugins/tekton/src/hooks/usePipelineRunScanResults.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { renderHook } from '@testing-library/react-hooks'; | ||
|
||
import { mockKubernetesPlrResponse } from '../__fixtures__/1-pipelinesData'; | ||
import { usePipelineRunScanResults } from './usePipelineRunScanResults'; | ||
|
||
jest.mock('@backstage/core-plugin-api', () => ({ | ||
...jest.requireActual('@backstage/core-plugin-api'), | ||
useApi: jest.fn(), | ||
})); | ||
|
||
describe('usePipelineRunVulnerabilities', () => { | ||
it('should return vulnerabilities when SCAN_OUTPUT is set', () => { | ||
const { result } = renderHook(() => | ||
usePipelineRunScanResults(mockKubernetesPlrResponse.pipelineruns[1]), | ||
); | ||
|
||
expect(result.current.vulnerabilities?.critical).toEqual(13); | ||
expect(result.current.vulnerabilities?.high).toEqual(29); | ||
expect(result.current.vulnerabilities?.medium).toEqual(32); | ||
expect(result.current.vulnerabilities?.low).toEqual(3); | ||
}); | ||
it('should return vulnerabilities when the suffix SCAN_OUTPUT is set', () => { | ||
const { result } = renderHook(() => | ||
usePipelineRunScanResults(mockKubernetesPlrResponse.pipelineruns[0]), | ||
); | ||
|
||
expect(result.current.vulnerabilities?.critical).toEqual(1); | ||
expect(result.current.vulnerabilities?.high).toEqual(9); | ||
expect(result.current.vulnerabilities?.medium).toEqual(20); | ||
expect(result.current.vulnerabilities?.low).toEqual(1); | ||
}); | ||
it('should accumulate all vulnerabilities', () => { | ||
const { result } = renderHook(() => { | ||
const results0 = | ||
mockKubernetesPlrResponse.pipelineruns[0].status.pipelineResults?.[0]; | ||
const results1 = | ||
mockKubernetesPlrResponse.pipelineruns[1].status.results?.[0]; | ||
const plr = { | ||
...mockKubernetesPlrResponse.pipelineruns[1], | ||
status: { | ||
...mockKubernetesPlrResponse.pipelineruns[1].status, | ||
results: results0 && results1 ? [results0, results1] : [], | ||
}, | ||
}; | ||
return usePipelineRunScanResults(plr); | ||
}); | ||
|
||
expect(result.current.vulnerabilities?.critical).toEqual(14); | ||
expect(result.current.vulnerabilities?.high).toEqual(38); | ||
expect(result.current.vulnerabilities?.medium).toEqual(52); | ||
expect(result.current.vulnerabilities?.low).toEqual(4); | ||
}); | ||
}); |
Oops, something went wrong.