Remove negligible and unknown severities and add none severity

Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
AllForNothing 2021-10-13 16:45:16 +08:00
parent 4d89c845d0
commit b2775292ef
17 changed files with 99 additions and 148 deletions

View File

@ -80,9 +80,7 @@ export const PROJECT_SEVERITY_LEVEL_MAP = {
"high": 4,
"medium": 3,
"low": 2,
"negligible": 1,
"unknown": 0,
"none": 0
"none": 1
};
export const PROJECT_SEVERITY_LEVEL_TO_TEXT_MAP = {
@ -90,8 +88,7 @@ export const PROJECT_SEVERITY_LEVEL_TO_TEXT_MAP = {
4: "high",
3: "medium",
2: "low",
1: "negligible",
0: "none",
1: "none",
};
export enum FILTER_TYPE {

View File

@ -62,8 +62,7 @@
<span *ngSwitchCase="'High'" class="label label-danger no-border">{{severityText(res.severity) | translate}}</span>
<span *ngSwitchCase="'Medium'" class="label label-medium no-border">{{severityText(res.severity) | translate}}</span>
<span *ngSwitchCase="'Low'" class="label label-low no-border">{{severityText(res.severity) | translate}}</span>
<span *ngSwitchCase="'Negligible'" class="label label-negligible no-border">{{severityText(res.severity) | translate}}</span>
<span *ngSwitchCase="'Unknown'" class="label label-unknown no-border">{{severityText(res.severity) | translate}}</span>
<span *ngSwitchCase="'None'" class="label label-none no-border">{{severityText(res.severity) | translate}}</span>
<span *ngSwitchDefault>{{severityText(res.severity) | translate}}</span>
</clr-dg-cell>
<clr-dg-cell>{{res.preferred_cvss?.score_v3}}</clr-dg-cell>

View File

@ -35,11 +35,7 @@
background: #007CBB;
color:#cab6b1;
}
.label-negligible {
background-color: green;
color:#bad7ba;
}
.label-unknown {
.label-none {
background-color: grey;
color:#bad7ba;
}
@ -54,4 +50,4 @@
}
.mt-5px {
margin-top: 5px;
}
}

View File

@ -56,15 +56,16 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
sub: Subscription;
hasViewInitWithDelay: boolean = false;
currentCVEList: Array<{ "cve_id": string; }> = [];
constructor(
private errorHandler: ErrorHandler,
private additionsService: AdditionsService,
private userPermissionService: UserPermissionService,
private scanningService: ScanningResultService,
private eventService: EventService,
private session: SessionService,
private projectService: ProjectService,
private systemInfoService: SystemInfoService,
private errorHandler: ErrorHandler,
private additionsService: AdditionsService,
private userPermissionService: UserPermissionService,
private scanningService: ScanningResultService,
private eventService: EventService,
private session: SessionService,
private projectService: ProjectService,
private systemInfoService: SystemInfoService,
) {
const that = this;
this.severitySort = {
@ -101,74 +102,80 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
this.getCurrentCVEAllowList();
}
}
ngOnDestroy() {
if (this.sub) {
this.sub.unsubscribe();
this.sub = null;
}
}
getVulnerabilities() {
if (this.vulnerabilitiesLink
&& !this.vulnerabilitiesLink.absolute
&& this.vulnerabilitiesLink.href) {
&& !this.vulnerabilitiesLink.absolute
&& this.vulnerabilitiesLink.href) {
if (!this.hasShowLoading) {
this.loading = true;
this.hasShowLoading = true;
}
this.additionsService.getDetailByLink(this.vulnerabilitiesLink.href, true, false)
.pipe(finalize(() => {
this.loading = false;
this.hasShowLoading = false;
}))
.subscribe(
res => {
this.scan_overview = res;
if (this.scan_overview && Object.values(this.scan_overview)[0]) {
this.scanningResults = (Object.values(this.scan_overview)[0] as any).vulnerabilities || [];
// sort
if (this.scanningResults) {
this.scanningResults.sort(((a, b) => this.getLevel(b) - this.getLevel(a)));
.pipe(finalize(() => {
this.loading = false;
this.hasShowLoading = false;
}))
.subscribe(
res => {
this.scan_overview = res;
if (this.scan_overview && Object.values(this.scan_overview)[0]) {
this.scanningResults = (Object.values(this.scan_overview)[0] as any).vulnerabilities || [];
// sort
if (this.scanningResults) {
this.scanningResults.sort(((a, b) => this.getLevel(b) - this.getLevel(a)));
}
this.scanner = (Object.values(this.scan_overview)[0] as any).scanner;
}
}, error => {
this.errorHandler.error(error);
}
this.scanner = (Object.values(this.scan_overview)[0] as any).scanner;
}
}, error => {
this.errorHandler.error(error);
}
);
);
}
}
getScanningPermission(): void {
const permissions = [
{ resource: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.VALUE.CREATE },
{resource: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.KEY, action: USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.VALUE.CREATE},
];
this.userPermissionService.hasProjectPermissions(this.projectId, permissions).subscribe((results: Array<boolean>) => {
this.hasScanningPermission = results[0];
// only has label permission
}, error => this.errorHandler.error(error));
}
getProjectScanner(): void {
this.hasEnabledScanner = false;
this.scanBtnState = ClrLoadingState.LOADING;
this.scanningService.getProjectScanner(this.projectId)
.subscribe(response => {
if (response && "{}" !== JSON.stringify(response) && !response.disabled
&& response.health === "healthy") {
this.scanBtnState = ClrLoadingState.SUCCESS;
this.hasEnabledScanner = true;
} else {
.subscribe(response => {
if (response && "{}" !== JSON.stringify(response) && !response.disabled
&& response.health === "healthy") {
this.scanBtnState = ClrLoadingState.SUCCESS;
this.hasEnabledScanner = true;
} else {
this.scanBtnState = ClrLoadingState.ERROR;
}
this.projectScanner = response;
}, error => {
this.scanBtnState = ClrLoadingState.ERROR;
}
this.projectScanner = response;
}, error => {
this.scanBtnState = ClrLoadingState.ERROR;
});
});
}
getLevel(v: VulnerabilityItem): number {
if (v && v.severity && SEVERITY_LEVEL_MAP[v.severity]) {
return SEVERITY_LEVEL_MAP[v.severity];
}
return 0;
}
refresh(): void {
this.getVulnerabilities();
}
@ -183,49 +190,55 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
return 'VULNERABILITY.SEVERITY.MEDIUM';
case VULNERABILITY_SEVERITY.LOW:
return 'VULNERABILITY.SEVERITY.LOW';
case VULNERABILITY_SEVERITY.NEGLIGIBLE:
return 'VULNERABILITY.SEVERITY.NEGLIGIBLE';
case VULNERABILITY_SEVERITY.UNKNOWN:
return 'VULNERABILITY.SEVERITY.UNKNOWN';
case VULNERABILITY_SEVERITY.NONE:
return 'VULNERABILITY.SEVERITY.NONE';
default:
return 'UNKNOWN';
}
}
scanNow() {
this.onSendingScanCommand = true;
this.eventService.publish(HarborEvent.START_SCAN_ARTIFACT, this.repoName + "/" + this.digest);
}
submitFinish(e: boolean) {
this.onSendingScanCommand = e;
}
submitStopFinish(e: boolean) {
this.onSendingStopCommand = e;
}
shouldShowBar(): boolean {
return this.hasViewInitWithDelay && this.resultBarChartComponent
&& (this.resultBarChartComponent.queued
&& (this.resultBarChartComponent.queued
|| this.resultBarChartComponent.scanning
|| this.resultBarChartComponent.error
|| this.resultBarChartComponent.stopped);
}
hasScanned(): boolean {
return this.hasViewInitWithDelay && this.resultBarChartComponent
&& !(this.resultBarChartComponent.completed
|| this.resultBarChartComponent.error
|| this.resultBarChartComponent.queued
|| this.resultBarChartComponent.stopped
|| this.resultBarChartComponent.scanning);
&& !(this.resultBarChartComponent.completed
|| this.resultBarChartComponent.error
|| this.resultBarChartComponent.queued
|| this.resultBarChartComponent.stopped
|| this.resultBarChartComponent.scanning);
}
handleScanOverview(scanOverview: any): any {
if (scanOverview) {
return Object.values(scanOverview)[0];
}
return null;
}
isSystemAdmin(): boolean {
const account = this.session.getCurrentUser();
return account && account.has_admin_role;
}
getCurrentCVEAllowList() {
this.projectService.getProject(this.projectId).subscribe(
projectRes => {
@ -245,6 +258,7 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
}
);
}
isInAllowList(CVEId: string): boolean {
if (this.currentCVEList && this.currentCVEList.length) {
for (let i = 0; i < this.currentCVEList.length; i++) {
@ -255,6 +269,7 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
}
return false;
}
getScannerInfo(scanner: ScannerVo): string {
if (scanner) {
if (scanner.name && scanner.version) {
@ -266,9 +281,10 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
}
return "";
}
isRunningState(): boolean {
return this.hasViewInitWithDelay && this.resultBarChartComponent
&& (this.resultBarChartComponent.queued || this.resultBarChartComponent.scanning);
&& (this.resultBarChartComponent.queued || this.resultBarChartComponent.scanning);
}
scanOrStop() {
@ -278,6 +294,7 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
this.scanNow();
}
}
stopNow() {
this.onSendingStopCommand = true;
this.eventService.publish(HarborEvent.STOP_SCAN_ARTIFACT, this.repoName + "/" + this.digest);

View File

@ -1,5 +1,5 @@
<div class="tip-wrapper width-215">
<clr-tooltip *ngIf="!isNone">
<clr-tooltip *ngIf="!noVulnerability">
<div clrTooltipTrigger class="level-border">
<div [className]="getClass()">
<div class="inner">
@ -14,7 +14,7 @@
</clr-tooltip>
<clr-tooltip>
<div clrTooltipTrigger class="tip-block">
<div *ngIf="!isNone" class="circle-block">
<div *ngIf="!noVulnerability" class="circle-block">
<div class="black-point-container margin-left-10"></div>
<span class="margin-left-10 font-weight-800 font-size-14">{{total}}</span>
<span class="margin-left-5 font-size-14">{{'SCANNER.TOTAL' | translate}}</span>
@ -22,11 +22,11 @@
<span class="margin-left-10 font-weight-800 font-size-12">{{fixableCount}}</span>
<span class="margin-left-5 font-size-12">{{'SCANNER.FIXABLE' | translate}}</span>
</div>
<div *ngIf="isNone" class="pl-1 margin-left-5 tip-wrapper bar-block-none shadow-none width-150">{{'VULNERABILITY.NO_VULNERABILITY' | translate }}</div>
<div *ngIf="noVulnerability" class="pl-1 margin-left-5 tip-wrapper bar-block-none shadow-none width-150">{{'VULNERABILITY.NO_VULNERABILITY' | translate }}</div>
</div>
<clr-tooltip-content class="w-800" [clrPosition]="'right'" [clrSize]="'lg'" *clrIfOpen>
<div class="bar-tooltip-font-larger">
<div *ngIf="!isNone" class="level-border clr-display-inline-block margin-right-5">
<div *ngIf="!noVulnerability" class="level-border clr-display-inline-block margin-right-5">
<div [className]="getClass()">
<div class="inner" [ngClass]="{'is-white': !isThemeLight(), 'is-dark': isThemeLight()}">
{{vulnerabilitySummary?.severity | slice:0:1}}
@ -45,19 +45,16 @@
<ng-container *ngIf="isLow">
<span>{{'VULNERABILITY.OVERALL_SEVERITY' | translate }} <span class="font-weight-600">{{'VULNERABILITY.SEVERITY.LOW' | translate | titlecase }}</span></span>
</ng-container>
<ng-container *ngIf="isUnknown">
<span>{{'VULNERABILITY.OVERALL_SEVERITY' | translate }} <span class="font-weight-600">{{'VULNERABILITY.SEVERITY.UNKNOWN' | translate | titlecase }}</span></span>
</ng-container>
<ng-container *ngIf="isNegligible">
<span>{{'VULNERABILITY.OVERALL_SEVERITY' | translate }} <span class="font-weight-600">{{'VULNERABILITY.SEVERITY.NEGLIGIBLE' | translate | titlecase }}</span></span>
</ng-container>
<ng-container *ngIf="isNone">
<span>{{'VULNERABILITY.OVERALL_SEVERITY' | translate }} <span class="font-weight-600">{{'VULNERABILITY.SEVERITY.NONE' | translate | titlecase }}</span></span>
</ng-container>
<ng-container *ngIf="noVulnerability">
<clr-icon shape="check-circle" class="is-success" size="32"></clr-icon>
<span>{{'VULNERABILITY.NO_VULNERABILITY' | translate }}</span>
</ng-container>
</div>
<hr>
<div class="bar-summary bar-tooltip-fon" *ngIf="!isNone">
<div class="bar-summary bar-tooltip-fon" *ngIf="!noVulnerability">
<histogram-chart [isWhiteBackground]="!isThemeLight()" [metadata]="passMetadataToChart()"></histogram-chart>
</div>
<div *ngIf="scanner">

View File

@ -257,11 +257,7 @@ hr {
background: #007CBB;
color:#007CBB;
}
.level-negligible {
background-color: green;
color:green;
}
.level-unknown {
.level-none {
background-color: grey;
color:grey;
}

View File

@ -13,8 +13,7 @@ const CLASS_MAP = {
"HIGH": "level-high",
"MEDIUM": "level-medium",
"LOW": "level-low",
"NEGLIGIBLE": "level-negligible",
"UNKNOWN": "level-unknown"
"NONE": "level-none",
};
@Component({
@ -46,12 +45,6 @@ export class ResultTipHistogramComponent implements OnInit {
case VULNERABILITY_SEVERITY.LOW:
key = "VULNERABILITY.SEVERITY.LOW";
break;
case VULNERABILITY_SEVERITY.NEGLIGIBLE:
key = "VULNERABILITY.SEVERITY.NEGLIGIBLE";
break;
case VULNERABILITY_SEVERITY.UNKNOWN:
key = "VULNERABILITY.SEVERITY.UNKNOWN";
break;
default:
break;
}
@ -136,18 +129,10 @@ export class ResultTipHistogramComponent implements OnInit {
return 0;
}
get unknownCount(): number {
get noneCount(): number {
if (this.vulnerabilitySummary && this.vulnerabilitySummary.summary
&& this.vulnerabilitySummary.summary.summary) {
return this.vulnerabilitySummary.summary.summary[VULNERABILITY_SEVERITY.UNKNOWN];
}
return 0;
}
get negligibleCount(): number {
if (this.sevSummary) {
return this.sevSummary[VULNERABILITY_SEVERITY.NEGLIGIBLE];
return this.vulnerabilitySummary.summary.summary[VULNERABILITY_SEVERITY.NONE];
}
return 0;
@ -173,16 +158,12 @@ export class ResultTipHistogramComponent implements OnInit {
get isLow(): boolean {
return this.vulnerabilitySummary && VULNERABILITY_SEVERITY.LOW === this.vulnerabilitySummary.severity;
}
get isUnknown(): boolean {
return this.vulnerabilitySummary && VULNERABILITY_SEVERITY.UNKNOWN === this.vulnerabilitySummary.severity;
}
get isNegligible(): boolean {
return this.vulnerabilitySummary && VULNERABILITY_SEVERITY.NEGLIGIBLE === this.vulnerabilitySummary.severity;
}
get isNone(): boolean {
return this.vulnerabilitySummary && VULNERABILITY_SEVERITY.NONE === this.vulnerabilitySummary.severity;
}
get noVulnerability(): boolean {
return this.total === 0;
}
getClass(): string {
if (this.vulnerabilitySummary && this.vulnerabilitySummary.severity) {
if (this.isCritical) {
@ -197,11 +178,8 @@ export class ResultTipHistogramComponent implements OnInit {
if (this.isLow) {
return CLASS_MAP.LOW;
}
if (this.isNegligible) {
return CLASS_MAP.NEGLIGIBLE;
}
if (this.isUnknown) {
return CLASS_MAP.UNKNOWN;
if (this.isNone) {
return CLASS_MAP.NONE;
}
}
return null;
@ -229,13 +207,8 @@ export class ResultTipHistogramComponent implements OnInit {
color: '#007CBB'
},
{
text: 'VULNERABILITY.SEVERITY.NEGLIGIBLE',
value: this.negligibleCount ? this.negligibleCount : 0,
color: 'green'
},
{
text: 'VULNERABILITY.SEVERITY.UNKNOWN',
value: this.unknownCount ? this.unknownCount : 0,
text: 'VULNERABILITY.SEVERITY.NONE',
value: this.noneCount ? this.noneCount : 0,
color: 'grey'
},
];

View File

@ -152,11 +152,7 @@ hr{
background: #007CBB;
color:#cab6b1;
}
.label-negligible {
background-color: green;
color:#bad7ba;
}
.label-unknown {
.label-none {
background-color: grey;
color:#bad7ba;
}

View File

@ -257,8 +257,6 @@ export const VULNERABILITY_SCAN_STATUS = {
* The severity of vulnerability scanning
*/
export const VULNERABILITY_SEVERITY = {
NEGLIGIBLE: "Negligible",
UNKNOWN: "Unknown",
LOW: "Low",
MEDIUM: "Medium",
HIGH: "High",
@ -269,13 +267,11 @@ export const VULNERABILITY_SEVERITY = {
* The level of vulnerability severity for comparing
*/
export const SEVERITY_LEVEL_MAP = {
"Critical": 6,
"High": 5,
"Medium": 4,
"Low": 3,
"Negligible": 2,
"Unknown": 1,
"None": 0
"Critical": 5,
"High": 4,
"Medium": 3,
"Low": 2,
"None": 1
};
/**

View File

@ -1066,8 +1066,6 @@
"HIGH": "Hoch",
"MEDIUM": "Mittel",
"LOW": "Niedrig",
"NEGLIGIBLE": "Geringfügig",
"UNKNOWN": "Unbekannt",
"NONE": "Keine"
},
"SINGULAR": "Schwachstelle",

View File

@ -1066,8 +1066,6 @@
"HIGH": "High",
"MEDIUM": "Medium",
"LOW": "Low",
"NEGLIGIBLE": "Negligible",
"UNKNOWN": "Unknown",
"NONE": "None"
},
"SINGULAR": "vulnerability",

View File

@ -1067,8 +1067,6 @@
"HIGH": "High",
"MEDIUM": "Medium",
"LOW": "Low",
"NEGLIGIBLE": "Negligible",
"UNKNOWN": "Unknown",
"NONE": "None"
},
"SINGULAR": "vulnerability",

View File

@ -1039,8 +1039,6 @@
"HIGH": "Haut",
"MEDIUM": "Moyen",
"LOW": "Bas",
"NEGLIGIBLE": "Négligeable",
"UNKNOWN": "Inconnu",
"NONE": "Aucune"
},
"SINGULAR": "vulnérabilitée",

View File

@ -1062,8 +1062,6 @@
"HIGH": "Alta",
"MEDIUM": "Média",
"LOW": "Baixa",
"NEGLIGIBLE": "Negligenciável",
"UNKNOWN": "Desconhecida",
"NONE": "Nenhum"
},
"SINGULAR": "vulnerabilidade",

View File

@ -1066,8 +1066,6 @@
"HIGH": "Yüksek",
"MEDIUM": "Orta",
"LOW": "Düşük",
"NEGLIGIBLE": "Önemsiz",
"UNKNOWN": "Bilinmiyor",
"NONE": "Hiç"
},
"SINGULAR": "güvenlik açığı",

View File

@ -1067,9 +1067,7 @@
"HIGH": "严重",
"MEDIUM": "中等",
"LOW": "较低",
"NEGLIGIBLE": "可忽略",
"UNKNOWN": "未知",
"NONE": "无"
"NONE": "无评分"
},
"SINGULAR": "漏洞",
"OVERALL_SEVERITY": "漏洞严重度:",

View File

@ -1062,8 +1062,6 @@
"HIGH": "嚴重",
"MEDIUM": "中等",
"LOW": "較低",
"NEGLIGIBLE": "可忽略",
"UNKNOWN":"未知",
"NONE":"無"
},
"SINGULAR": "漏洞",