diff --git a/src/portal/lib/src/config/vulnerability/scanAll.service.ts b/src/portal/lib/src/config/vulnerability/scanAll.service.ts index 587fad9c3..0dde51524 100644 --- a/src/portal/lib/src/config/vulnerability/scanAll.service.ts +++ b/src/portal/lib/src/config/vulnerability/scanAll.service.ts @@ -60,4 +60,12 @@ export class ScanAllRepoService { .pipe(catchError(error => observableThrowError(error))) .pipe(map(response => response as ScanningMetrics)); } + getScanners(): Observable { + return this.http.get('/api/scanners') + .pipe(catchError(error => observableThrowError(error))); + } + getScannerMetadata(uid: string): Observable { + return this.http.get(`/api/scanners/${uid}/metadata`) + .pipe(catchError(error => observableThrowError(error))); + } } diff --git a/src/portal/lib/src/config/vulnerability/vulnerability-config.component.html b/src/portal/lib/src/config/vulnerability/vulnerability-config.component.html index c6474c3d9..a58021c69 100644 --- a/src/portal/lib/src/config/vulnerability/vulnerability-config.component.html +++ b/src/portal/lib/src/config/vulnerability/vulnerability-config.component.html @@ -1,10 +1,16 @@ -
+ + +
+
+ + {{ updatedTimeStr }} +
-
+
+ + + diff --git a/src/portal/lib/src/config/vulnerability/vulnerability-config.component.scss b/src/portal/lib/src/config/vulnerability/vulnerability-config.component.scss index b33538467..f49995c5f 100644 --- a/src/portal/lib/src/config/vulnerability/vulnerability-config.component.scss +++ b/src/portal/lib/src/config/vulnerability/vulnerability-config.component.scss @@ -97,4 +97,7 @@ } .float-left { float: left; +} +.display-flex { + display: flex; } \ No newline at end of file diff --git a/src/portal/lib/src/config/vulnerability/vulnerability-config.component.spec.ts b/src/portal/lib/src/config/vulnerability/vulnerability-config.component.spec.ts index 9f2517ee9..805a619ea 100644 --- a/src/portal/lib/src/config/vulnerability/vulnerability-config.component.spec.ts +++ b/src/portal/lib/src/config/vulnerability/vulnerability-config.component.spec.ts @@ -42,6 +42,9 @@ let fakedScanAllRepoService = { }, manualScan() { return of(true); + }, + getScanners() { + return of([]); } }; let fakedErrorHandler = { diff --git a/src/portal/lib/src/config/vulnerability/vulnerability-config.component.ts b/src/portal/lib/src/config/vulnerability/vulnerability-config.component.ts index 8fe3c5812..d8f3f256c 100644 --- a/src/portal/lib/src/config/vulnerability/vulnerability-config.component.ts +++ b/src/portal/lib/src/config/vulnerability/vulnerability-config.component.ts @@ -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() { diff --git a/src/portal/lib/src/service/interface.ts b/src/portal/lib/src/service/interface.ts index b709be0ed..fb2cc53e7 100644 --- a/src/portal/lib/src/service/interface.ts +++ b/src/portal/lib/src/service/interface.ts @@ -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; diff --git a/src/portal/lib/src/tag/tag.component.html b/src/portal/lib/src/tag/tag.component.html index 88449dae5..61a3b9580 100644 --- a/src/portal/lib/src/tag/tag.component.html +++ b/src/portal/lib/src/tag/tag.component.html @@ -109,7 +109,7 @@
- +
diff --git a/src/portal/lib/src/utils.ts b/src/portal/lib/src/utils.ts index 3fbe8edb5..1a07dee84 100644 --- a/src/portal/lib/src/utils.ts +++ b/src/portal/lib/src/utils.ts @@ -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 */ diff --git a/src/portal/lib/src/vulnerability-scanning/result-bar-chart-component.html b/src/portal/lib/src/vulnerability-scanning/result-bar-chart-component.html index 3f3795b09..c739158ba 100644 --- a/src/portal/lib/src/vulnerability-scanning/result-bar-chart-component.html +++ b/src/portal/lib/src/vulnerability-scanning/result-bar-chart-component.html @@ -13,7 +13,7 @@
- +
{{'VULNERABILITY.STATE.OTHER_STATUS' | translate}} diff --git a/src/portal/lib/src/vulnerability-scanning/result-bar-chart.component.ts b/src/portal/lib/src/vulnerability-scanning/result-bar-chart.component.ts index 3dbb95e29..fb7717f46 100644 --- a/src/portal/lib/src/vulnerability-scanning/result-bar-chart.component.ts +++ b/src/portal/lib/src/vulnerability-scanning/result-bar-chart.component.ts @@ -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; diff --git a/src/portal/lib/src/vulnerability-scanning/result-tip-histogram/result-tip-histogram.component.html b/src/portal/lib/src/vulnerability-scanning/result-tip-histogram/result-tip-histogram.component.html index ba23c043a..f45139a6a 100644 --- a/src/portal/lib/src/vulnerability-scanning/result-tip-histogram/result-tip-histogram.component.html +++ b/src/portal/lib/src/vulnerability-scanning/result-tip-histogram/result-tip-histogram.component.html @@ -63,6 +63,10 @@
+
+ {{'SCANNER.SCANNED_BY' | translate }} + {{scanner?.name}} +
{{'SCANNER.DURATION' | translate }} {{duration()}} diff --git a/src/portal/lib/src/vulnerability-scanning/result-tip-histogram/result-tip-histogram.component.ts b/src/portal/lib/src/vulnerability-scanning/result-tip-histogram/result-tip-histogram.component.ts index 846477e83..06f34054f 100644 --- a/src/portal/lib/src/vulnerability-scanning/result-tip-histogram/result-tip-histogram.component.ts +++ b/src/portal/lib/src/vulnerability-scanning/result-tip-histogram/result-tip-histogram.component.ts @@ -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, diff --git a/src/portal/src/app/config/scanner/scanner-metadata/scanner-metadata.component.ts b/src/portal/src/app/config/scanner/scanner-metadata/scanner-metadata.component.ts index 2de6873f3..a5d0ec8ae 100644 --- a/src/portal/src/app/config/scanner/scanner-metadata/scanner-metadata.component.ts +++ b/src/portal/src/app/config/scanner/scanner-metadata/scanner-metadata.component.ts @@ -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) { diff --git a/src/portal/src/app/config/scanner/scanner-metadata/scanner-metadata.html b/src/portal/src/app/config/scanner/scanner-metadata/scanner-metadata.html index af1e329e8..55cc33dfb 100644 --- a/src/portal/src/app/config/scanner/scanner-metadata/scanner-metadata.html +++ b/src/portal/src/app/config/scanner/scanner-metadata/scanner-metadata.html @@ -24,7 +24,7 @@
{{'SCANNER.PROPERTIES' | translate}}
{{item?.key}}: - {{parseDate(item?.value)}} + {{parseDate(item)}}
diff --git a/src/portal/src/i18n/lang/en-us-lang.json b/src/portal/src/i18n/lang/en-us-lang.json index b3284f3ff..7e32055d4 100644 --- a/src/portal/src/i18n/lang/en-us-lang.json +++ b/src/portal/src/i18n/lang/en-us-lang.json @@ -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:" } } diff --git a/src/portal/src/i18n/lang/es-es-lang.json b/src/portal/src/i18n/lang/es-es-lang.json index 52bf7b34d..fb3b73beb 100644 --- a/src/portal/src/i18n/lang/es-es-lang.json +++ b/src/portal/src/i18n/lang/es-es-lang.json @@ -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:" } } diff --git a/src/portal/src/i18n/lang/fr-fr-lang.json b/src/portal/src/i18n/lang/fr-fr-lang.json index e655d4f07..26b72c73c 100644 --- a/src/portal/src/i18n/lang/fr-fr-lang.json +++ b/src/portal/src/i18n/lang/fr-fr-lang.json @@ -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:" } } diff --git a/src/portal/src/i18n/lang/pt-br-lang.json b/src/portal/src/i18n/lang/pt-br-lang.json index 67ed7a969..9e185cae3 100644 --- a/src/portal/src/i18n/lang/pt-br-lang.json +++ b/src/portal/src/i18n/lang/pt-br-lang.json @@ -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:" } } diff --git a/src/portal/src/i18n/lang/tr-tr-lang.json b/src/portal/src/i18n/lang/tr-tr-lang.json index b4ce7cd78..3f7bf246d 100644 --- a/src/portal/src/i18n/lang/tr-tr-lang.json +++ b/src/portal/src/i18n/lang/tr-tr-lang.json @@ -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:" } } diff --git a/src/portal/src/i18n/lang/zh-cn-lang.json b/src/portal/src/i18n/lang/zh-cn-lang.json index df14f5fd0..f70da00e3 100644 --- a/src/portal/src/i18n/lang/zh-cn-lang.json +++ b/src/portal/src/i18n/lang/zh-cn-lang.json @@ -1339,6 +1339,7 @@ "VULNERABILITY_SEVERITY": "漏洞严重度:", "CONFIRM_DELETION": "删除扫描器确认", "NO_PROJECT_SCANNER": "无扫描器", - "SET_UNHEALTHY_SCANNER": "选择的扫描器:{{name}}是不健康的" + "SET_UNHEALTHY_SCANNER": "选择的扫描器:{{name}}是不健康的", + "SCANNED_BY": "扫描器:" } }