mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-19 23:28:20 +01:00
Add vulnerability database update time and scanner name
Signed-off-by: sshijun <sshijun@vmware.com>
This commit is contained in:
parent
29be93725d
commit
8f3beb3e31
@ -60,4 +60,12 @@ export class ScanAllRepoService {
|
||||
.pipe(catchError(error => observableThrowError(error)))
|
||||
.pipe(map(response => response as ScanningMetrics));
|
||||
}
|
||||
getScanners(): Observable<any> {
|
||||
return this.http.get('/api/scanners')
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
getScannerMetadata(uid: string): Observable<any> {
|
||||
return this.http.get(`/api/scanners/${uid}/metadata`)
|
||||
.pipe(catchError(error => observableThrowError(error)));
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,16 @@
|
||||
<section class="form-block">
|
||||
<span *ngIf="onGettingUpdatedTimeStr || onGoing" class="mt-1 ml-1 spinner spinner-inline"></span>
|
||||
<ng-container *ngIf="!(onGettingUpdatedTimeStr || onGoing)">
|
||||
<section class="form-block">
|
||||
<div *ngIf="updatedTimeStr" class="mt-1 display-flex">
|
||||
<label class="update-time">{{ 'CONFIG.SCANNING.DB_REFRESH_TIME' | translate }}</label>
|
||||
<span>{{ updatedTimeStr }} </span>
|
||||
</div>
|
||||
<div class="button-group">
|
||||
<cron-selection [labelCurrent]="getLabelCurrent" [labelEdit]='getLabelCurrent'
|
||||
[originCron]='originCron' (inputvalue)="saveSchedule($event)"></cron-selection>
|
||||
</div>
|
||||
</section>
|
||||
<div class="clr-row">
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-2 flex-200">
|
||||
<div class="btn-scan-right btn-scan margin-top-16px">
|
||||
<button id="scan-now" class="btn btn-outline btn-sm btn-scan" (click)="scanNow()"
|
||||
@ -35,3 +41,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
|
||||
|
@ -97,4 +97,7 @@
|
||||
}
|
||||
.float-left {
|
||||
float: left;
|
||||
}
|
||||
.display-flex {
|
||||
display: flex;
|
||||
}
|
@ -42,6 +42,9 @@ let fakedScanAllRepoService = {
|
||||
},
|
||||
manualScan() {
|
||||
return of(true);
|
||||
},
|
||||
getScanners() {
|
||||
return of([]);
|
||||
}
|
||||
};
|
||||
let fakedErrorHandler = {
|
||||
|
@ -6,8 +6,9 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { ScanAllRepoService } from './scanAll.service';
|
||||
import { OriginCron } from '../../service/interface';
|
||||
import { CronScheduleComponent } from "../../cron-schedule/cron-schedule.component";
|
||||
import { VULNERABILITY_SCAN_STATUS } from "../../utils";
|
||||
import { DATABASE_UPDATED_PROPERTY, VULNERABILITY_SCAN_STATUS } from "../../utils";
|
||||
import { errorHandler as errorHandFn} from "../../shared/shared.utils";
|
||||
import { DatePipe } from "@angular/common";
|
||||
|
||||
const SCHEDULE_TYPE_NONE = "None";
|
||||
@Component({
|
||||
@ -38,6 +39,8 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
private _loopScheduleInterval;
|
||||
private _loopManualInterval;
|
||||
updatedTimeStr: string;
|
||||
onGettingUpdatedTimeStr: boolean;
|
||||
constructor(
|
||||
private scanningService: ScanAllRepoService,
|
||||
private errorHandler: ErrorHandler,
|
||||
@ -103,6 +106,39 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy {
|
||||
this.errorHandler.error(error);
|
||||
});
|
||||
}
|
||||
getScanners() {
|
||||
this.onGettingUpdatedTimeStr = true;
|
||||
this.scanningService.getScanners()
|
||||
.subscribe(scanners => {
|
||||
let flag = false;
|
||||
if (scanners && scanners.length) {
|
||||
scanners.forEach(scanner => {
|
||||
if (scanner.is_default) {
|
||||
flag = true;
|
||||
this.getScannerMetadata(scanner.uuid);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!flag) {
|
||||
this.onGettingUpdatedTimeStr = false;
|
||||
}
|
||||
}, error => {
|
||||
this.onGettingUpdatedTimeStr = false;
|
||||
});
|
||||
}
|
||||
getScannerMetadata(uid: string) {
|
||||
this.scanningService.getScannerMetadata(uid)
|
||||
.pipe(finalize(() => this.onGettingUpdatedTimeStr = false))
|
||||
.subscribe(metadata => {
|
||||
if (metadata && metadata.properties) {
|
||||
for (let key in metadata.properties) {
|
||||
if (key === DATABASE_UPDATED_PROPERTY && metadata.properties[key]) {
|
||||
this.updatedTimeStr = new DatePipe(this.translate.currentLang).transform(metadata.properties[key], 'short');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public initSchedule(schedule: any) {
|
||||
if (schedule && schedule.schedule !== null) {
|
||||
@ -119,6 +155,7 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy {
|
||||
this.getScanText();
|
||||
this.getSchedule();
|
||||
this.initMetrics();
|
||||
this.getScanners();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
@ -312,6 +312,12 @@ export interface VulnerabilitySummary {
|
||||
summary?: SeveritySummary;
|
||||
start_time?: Date;
|
||||
end_time?: Date;
|
||||
scanner?: ScannerVo;
|
||||
}
|
||||
export interface ScannerVo {
|
||||
name?: string;
|
||||
vendor?: string;
|
||||
version?: string;
|
||||
}
|
||||
export interface SeveritySummary {
|
||||
total: number;
|
||||
|
@ -109,7 +109,7 @@
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
<div class="cell">
|
||||
<hbr-vulnerability-bar (submitFinish)="submitFinish($event)" [repoName]="repoName" [tagId]="t.name" [summary]="handleScanOverview(t.scan_overview)"></hbr-vulnerability-bar>
|
||||
<hbr-vulnerability-bar [scanner]="handleScanOverview(t.scan_overview)?.scanner" (submitFinish)="submitFinish($event)" [repoName]="repoName" [tagId]="t.name" [summary]="handleScanOverview(t.scan_overview)"></hbr-vulnerability-bar>
|
||||
</div>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell *ngIf="withNotary" [ngSwitch]="t.signature !== null">
|
||||
|
@ -230,6 +230,11 @@ export const DEFAULT_PAGE_SIZE: number = 15;
|
||||
*/
|
||||
export const DEFAULT_SUPPORTED_MIME_TYPE = "application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0";
|
||||
|
||||
/**
|
||||
* the property name of vulnerability database updated time
|
||||
*/
|
||||
export const DATABASE_UPDATED_PROPERTY = "harbor.scanner-adapter/vulnerability-database-updated-at";
|
||||
|
||||
/**
|
||||
* The state of vulnerability scanning
|
||||
*/
|
||||
|
@ -13,7 +13,7 @@
|
||||
<div class="progress loop loop-height"><progress></progress></div>
|
||||
</div>
|
||||
<div *ngIf="completed" class="bar-state bar-state-chart">
|
||||
<hbr-result-tip-histogram [vulnerabilitySummary]="summary"></hbr-result-tip-histogram>
|
||||
<hbr-result-tip-histogram [scanner]="scanner" [vulnerabilitySummary]="summary"></hbr-result-tip-histogram>
|
||||
</div>
|
||||
<div *ngIf="otherStatus" class="bar-state">
|
||||
<span class="label">{{'VULNERABILITY.STATE.OTHER_STATUS' | translate}}</span>
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
VulnerabilitySummary,
|
||||
TagService,
|
||||
ScanningResultService,
|
||||
Tag
|
||||
Tag, ScannerVo
|
||||
} from '../service/index';
|
||||
import { ErrorHandler } from '../error-handler/index';
|
||||
import { ChannelService } from '../channel/index';
|
||||
@ -28,6 +28,7 @@ const RETRY_TIMES: number = 3;
|
||||
styleUrls: ['./scanning.scss']
|
||||
})
|
||||
export class ResultBarChartComponent implements OnInit, OnDestroy {
|
||||
@Input() scanner: ScannerVo;
|
||||
@Input() repoName: string = "";
|
||||
@Input() tagId: string = "";
|
||||
@Input() summary: VulnerabilitySummary;
|
||||
|
@ -63,6 +63,10 @@
|
||||
<div class="bar-summary bar-tooltip-fon" *ngIf="!isNone">
|
||||
<histogram-chart [isWhiteBackground]="false" [metadata]="passMetadataToChart()"></histogram-chart>
|
||||
</div>
|
||||
<div *ngIf="scanner">
|
||||
<span class="bar-scanning-time">{{'SCANNER.SCANNED_BY' | translate }}</span>
|
||||
<span class="margin-left-5">{{scanner?.name}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="bar-scanning-time">{{'SCANNER.DURATION' | translate }}</span>
|
||||
<span class="margin-left-5">{{duration()}}</span>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { VulnerabilitySummary } from "../../service";
|
||||
import { ScannerVo, VulnerabilitySummary } from "../../service";
|
||||
import { VULNERABILITY_SCAN_STATUS, VULNERABILITY_SEVERITY } from "../../utils";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
|
||||
@ -21,6 +21,7 @@ const CLASS_MAP = {
|
||||
styleUrls: ['./result-tip-histogram.component.scss']
|
||||
})
|
||||
export class ResultTipHistogramComponent implements OnInit {
|
||||
@Input() scanner: ScannerVo;
|
||||
_tipTitle: string = "";
|
||||
@Input() vulnerabilitySummary: VulnerabilitySummary = {
|
||||
scan_status: VULNERABILITY_SCAN_STATUS.NOT_SCANNED,
|
||||
|
@ -1,12 +1,13 @@
|
||||
import {
|
||||
Component, Inject, Input, LOCALE_ID,
|
||||
Component, Input,
|
||||
OnInit
|
||||
} from "@angular/core";
|
||||
import { ConfigScannerService } from "../config-scanner.service";
|
||||
import { finalize } from "rxjs/operators";
|
||||
import { ErrorHandler } from "@harbor/ui";
|
||||
import { ErrorHandler, DATABASE_UPDATED_PROPERTY } from "@harbor/ui";
|
||||
import { ScannerMetadata } from "../scanner-metadata";
|
||||
import { DatePipe } from "@angular/common";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
|
||||
@Component({
|
||||
selector: 'scanner-metadata',
|
||||
@ -19,7 +20,7 @@ export class ScannerMetadataComponent implements OnInit {
|
||||
scannerMetadata: ScannerMetadata;
|
||||
constructor(private configScannerService: ConfigScannerService,
|
||||
private errorHandler: ErrorHandler,
|
||||
@Inject(LOCALE_ID) private _locale: string) {
|
||||
private translate: TranslateService) {
|
||||
}
|
||||
ngOnInit(): void {
|
||||
this.loading = true;
|
||||
@ -31,15 +32,14 @@ export class ScannerMetadataComponent implements OnInit {
|
||||
this.errorHandler.error(error);
|
||||
});
|
||||
}
|
||||
parseDate(str: string): string {
|
||||
try {
|
||||
if (str === new Date(str).toISOString()) {
|
||||
return new DatePipe(this._locale).transform(str, 'short');
|
||||
}
|
||||
} catch (e) {
|
||||
return str;
|
||||
parseDate(item: any): string {
|
||||
if (item && item.value && item.key === DATABASE_UPDATED_PROPERTY) {
|
||||
return new DatePipe(this.translate.currentLang).transform(item.value, 'short');
|
||||
}
|
||||
return str;
|
||||
if (item && item.value) {
|
||||
return item.value;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
toString(arr: string[]) {
|
||||
if (arr && arr.length > 0) {
|
||||
|
@ -24,7 +24,7 @@
|
||||
<div class="clr-control-label">{{'SCANNER.PROPERTIES' | translate}}</div>
|
||||
<div class="ml-1" *ngFor="let item of scannerMetadata?.properties | keyvalue">
|
||||
<span>{{item?.key}}:</span>
|
||||
<span class="ml-1">{{parseDate(item?.value)}}</span>
|
||||
<span class="ml-1">{{parseDate(item)}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -1343,6 +1343,7 @@
|
||||
"VULNERABILITY_SEVERITY": "Vulnerability severity:",
|
||||
"CONFIRM_DELETION": "Confirm Scanner deletion",
|
||||
"NO_PROJECT_SCANNER": "No Scanner",
|
||||
"SET_UNHEALTHY_SCANNER": "Selected scanner:{{name}} is unhealthy"
|
||||
"SET_UNHEALTHY_SCANNER": "Selected scanner:{{name}} is unhealthy",
|
||||
"SCANNED_BY": "Scanned by:"
|
||||
}
|
||||
}
|
||||
|
@ -1340,6 +1340,7 @@
|
||||
"VULNERABILITY_SEVERITY": "Vulnerability severity:",
|
||||
"CONFIRM_DELETION": "Confirm Scanner deletion",
|
||||
"NO_PROJECT_SCANNER": "No Scanner",
|
||||
"SET_UNHEALTHY_SCANNER": "Selected scanner:{{name}} is unhealthy"
|
||||
"SET_UNHEALTHY_SCANNER": "Selected scanner:{{name}} is unhealthy",
|
||||
"SCANNED_BY": "Scanned by:"
|
||||
}
|
||||
}
|
||||
|
@ -1312,6 +1312,7 @@
|
||||
"VULNERABILITY_SEVERITY": "Vulnerability severity:",
|
||||
"CONFIRM_DELETION": "Confirm Scanner deletion",
|
||||
"NO_PROJECT_SCANNER": "No Scanner",
|
||||
"SET_UNHEALTHY_SCANNER": "Selected scanner:{{name}} is unhealthy"
|
||||
"SET_UNHEALTHY_SCANNER": "Selected scanner:{{name}} is unhealthy",
|
||||
"SCANNED_BY": "Scanned by:"
|
||||
}
|
||||
}
|
||||
|
@ -1337,7 +1337,8 @@
|
||||
"VULNERABILITY_SEVERITY": "Vulnerability severity:",
|
||||
"CONFIRM_DELETION": "Confirm Scanner deletion",
|
||||
"NO_PROJECT_SCANNER": "No Scanner",
|
||||
"SET_UNHEALTHY_SCANNER": "Selected scanner:{{name}} is unhealthy"
|
||||
"SET_UNHEALTHY_SCANNER": "Selected scanner:{{name}} is unhealthy",
|
||||
"SCANNED_BY": "Scanned by:"
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1342,6 +1342,7 @@
|
||||
"VULNERABILITY_SEVERITY": "Vulnerability severity:",
|
||||
"CONFIRM_DELETION": "Confirm Scanner deletion",
|
||||
"NO_PROJECT_SCANNER": "No Scanner",
|
||||
"SET_UNHEALTHY_SCANNER": "Selected scanner:{{name}} is unhealthy"
|
||||
"SET_UNHEALTHY_SCANNER": "Selected scanner:{{name}} is unhealthy",
|
||||
"SCANNED_BY": "Scanned by:"
|
||||
}
|
||||
}
|
||||
|
@ -1339,6 +1339,7 @@
|
||||
"VULNERABILITY_SEVERITY": "漏洞严重度:",
|
||||
"CONFIRM_DELETION": "删除扫描器确认",
|
||||
"NO_PROJECT_SCANNER": "无扫描器",
|
||||
"SET_UNHEALTHY_SCANNER": "选择的扫描器:{{name}}是不健康的"
|
||||
"SET_UNHEALTHY_SCANNER": "选择的扫描器:{{name}}是不健康的",
|
||||
"SCANNED_BY": "扫描器:"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user