diff --git a/src/portal/src/lib/components/config/config.ts b/src/portal/src/lib/components/config/config.ts index 81958967b..652c3480c 100644 --- a/src/portal/src/lib/components/config/config.ts +++ b/src/portal/src/lib/components/config/config.ts @@ -179,6 +179,11 @@ export class ScanningMetrics { [key: string]: number; }; requester?: string; - isScheduled?: boolean; + trigger?: string; ongoing: boolean; } +export enum Triggers { + MANUAL= 'Manual', + SCHEDULE = 'Schedule', + EVENT = 'Event' +} diff --git a/src/portal/src/lib/components/config/vulnerability/scanAll.service.ts b/src/portal/src/lib/components/config/vulnerability/scanAll.service.ts index 1946f66bd..1baf7ee15 100644 --- a/src/portal/src/lib/components/config/vulnerability/scanAll.service.ts +++ b/src/portal/src/lib/components/config/vulnerability/scanAll.service.ts @@ -51,12 +51,7 @@ export class ScanAllRepoService { return this.scanApiRepository.putSchedule(param); } - getScheduleMetrics(): Observable { - return this.http.get(CURRENT_BASE_HREF + '/scans/schedule/metrics') - .pipe(catchError(error => observableThrowError(error))) - .pipe(map(response => response as ScanningMetrics)); - } - getManualMetrics(): Observable { + getMetrics(): Observable { return this.http.get(CURRENT_BASE_HREF + '/scans/all/metrics') .pipe(catchError(error => observableThrowError(error))) .pipe(map(response => response as ScanningMetrics)); diff --git a/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.html b/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.html index 7f17a23c2..bf2368c55 100644 --- a/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.html +++ b/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.html @@ -23,8 +23,8 @@
- {{ 'CONFIG.SCANNING.MANUAL' | translate }} - {{ 'CONFIG.SCANNING.SCHEDULED' | translate }} + {{ 'CONFIG.SCANNING.MANUAL' | translate }} + {{ 'CONFIG.SCANNING.SCHEDULED' | translate }} {{ 'SCANNER.TOTAL' | translate }} {{scanningMetrics?.total}}
@@ -32,13 +32,15 @@
+
{{item?.value}} + 'in-progress': isInProgress(item?.key), + abort: isAborted(item?.key)}">{{item?.value}}
{{getI18nKey(item?.key)|translate}}
diff --git a/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.scss b/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.scss index c27eecd8a..c41c45d90 100644 --- a/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.scss +++ b/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.scss @@ -103,6 +103,9 @@ .in-progress { background-color: #0079b8; } +.abort { + background-color: #cccc15; +} .badge { min-width: 30px; } diff --git a/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.spec.ts b/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.spec.ts index e3fb7c489..837ad5fbd 100644 --- a/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.spec.ts +++ b/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.spec.ts @@ -4,7 +4,7 @@ import { ScanAllRepoService } from "./scanAll.service"; import { of } from "rxjs"; import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; import { IServiceConfig, SERVICE_CONFIG } from "../../../entities/service.config"; -import { ScanningMetrics } from "../config"; +import { ScanningMetrics, Triggers } from "../config"; import { SharedModule } from "../../../utils/shared/shared.module"; import { ErrorHandler } from "../../../utils/error-handler"; import { CURRENT_BASE_HREF } from "../../../utils/utils"; @@ -23,17 +23,8 @@ let mockedScheduledMetrics: ScanningMetrics = { "Success": 20, "Error": 30, }, - ongoing: false -}; -let mockedManualMetrics: ScanningMetrics = { - total: 100, - completed: 20, - metrics: { - "Error": 10, - "Success": 20, - "Running": 70 - }, - ongoing: true + ongoing: false, + trigger: Triggers.SCHEDULE }; const mockedScanner: Scanner = { "uuid": "ca3c27f3-72f3-11ea-9e46-0242ac170004", @@ -52,12 +43,9 @@ let fakedScanAllRepoService = { getSchedule() { return of(mockedSchedule); }, - getScheduleMetrics() { + getMetrics() { return of(mockedScheduledMetrics); }, - getManualMetrics() { - return of(mockedManualMetrics); - }, manualScan() { return of(true); }, @@ -105,10 +93,9 @@ describe('VulnerabilityConfigComponent', () => { it('should create', () => { expect(component).toBeTruthy(); const ele = fixture.nativeElement.querySelector('.finished'); - expect(ele.style.width).toEqual('40px'); + expect(ele.style.width).toEqual('80px'); }); - it('should loop scheduled metrics if scheduled scanning is on going', () => { - component.scanningMetrics.isScheduled = true; + it('should loop metrics if scheduled scanning is on going', () => { component.scanningMetrics.ongoing = true; expect(component.scanAvailable).toBeFalsy(); }); @@ -116,10 +103,10 @@ describe('VulnerabilityConfigComponent', () => { const button = fixture.nativeElement.querySelector('#scan-now'); button.click(); const ele = fixture.nativeElement.querySelector('.finished'); - expect(ele.style.width).toEqual('40px'); + expect(ele.style.width).toEqual('80px'); }); it('should stop looping manual metrics if manual scanning is finished', () => { - component.scanningMetrics.isScheduled = false; + component.scanningMetrics.trigger = Triggers.MANUAL; component.scanningMetrics.ongoing = false; component.hasDefaultScanner = true; expect(component.scanAvailable).toBeTruthy(); diff --git a/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.ts b/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.ts index 4ad3bfe7a..8d8c011d8 100644 --- a/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.ts +++ b/src/portal/src/lib/components/config/vulnerability/vulnerability-config.component.ts @@ -1,11 +1,11 @@ import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; import { finalize } from "rxjs/operators"; -import { ScanningMetrics } from '../config'; +import { ScanningMetrics, Triggers } from '../config'; import { ErrorHandler } from '../../../utils/error-handler'; import { TranslateService } from '@ngx-translate/core'; import { ScanAllRepoService } from './scanAll.service'; -import { OriginCron } from '../../../services/interface'; -import { CronScheduleComponent } from "../../cron-schedule/cron-schedule.component"; +import { OriginCron } from '../../../services'; +import { CronScheduleComponent } from "../../cron-schedule"; import { DATABASE_UPDATED_PROPERTY, VULNERABILITY_SCAN_STATUS } from "../../../utils/utils"; import { errorHandler as errorHandFn} from "../../../utils/shared/shared.utils"; import { DatePipe } from "@angular/common"; @@ -37,8 +37,7 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy { "Success": "CONFIG.SCANNING.STATUS.SUCCESS", "Scheduled": "CONFIG.SCANNING.STATUS.SCHEDULED" }; - private _loopScheduleInterval; - private _loopManualInterval; + private _loopInterval; updatedTimeStr: string; onGettingUpdatedTimeStr: boolean; hasDefaultScanner: boolean = false; @@ -52,34 +51,19 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy { return this._scanningMetrics; } set scanningMetrics(metrics: ScanningMetrics) { - // start looping scheduled metrics - if (metrics && metrics.ongoing && metrics.isScheduled) { - if (!this._loopScheduleInterval) { - this._loopScheduleInterval = setInterval(() => { - this.getScheduleMetrics(); + // start looping metrics + if (metrics && metrics.ongoing) { + if (!this._loopInterval) { + this._loopInterval = setInterval(() => { + this.getMetrics(); }, 5000); } } - // stop looping scheduled metrics - if (metrics && !metrics.ongoing && metrics.isScheduled) { - if (this._loopScheduleInterval) { - clearInterval(this._loopScheduleInterval); - this._loopScheduleInterval = null; - } - } - // start looping manual metrics - if (metrics && metrics.ongoing && !metrics.isScheduled) { - if (!this._loopManualInterval) { - this._loopManualInterval = setInterval(() => { - this.getManualMetrics(); - }, 5000); - } - } - // stop looping manual metrics - if (metrics && !metrics.ongoing && !metrics.isScheduled) { - if (this._loopManualInterval) { - clearInterval(this._loopManualInterval); - this._loopManualInterval = null; + // stop looping metrics + if (metrics && !metrics.ongoing) { + if (this._loopInterval) { + clearInterval(this._loopInterval); + this._loopInterval = null; } } this._scanningMetrics = metrics; @@ -117,7 +101,7 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy { scanners.forEach(scanner => { if (scanner.is_default) { flag = true; - this.initMetrics(); + this.getMetrics(); this.getSchedule(); this.getScannerMetadata(scanner.uuid); } @@ -169,60 +153,25 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy { } ngOnDestroy() { - if (this._loopScheduleInterval) { - clearInterval(this._loopScheduleInterval); - this._loopScheduleInterval = null; - } - if (this._loopManualInterval) { - clearInterval(this._loopManualInterval); - this._loopManualInterval = null; + if (this._loopInterval) { + clearInterval(this._loopInterval); + this._loopInterval = null; } } isOnScanning(): boolean { return this.scanningMetrics && this.scanningMetrics.ongoing; } - getScheduleMetrics() { + getMetrics() { this.gettingMetrics = true; - this.scanningService.getScheduleMetrics() + this.scanningService.getMetrics() .pipe(finalize(() => this.gettingMetrics = false)) .subscribe(response => { if (response) { - response.isScheduled = true; this.scanningMetrics = response; } }); } - getManualMetrics() { - this.gettingMetrics = true; - this.scanningService.getManualMetrics() - .pipe(finalize(() => this.gettingMetrics = false)) - .subscribe(response => { - if (response) { - response.isScheduled = false; - this.scanningMetrics = response; - } - }); - } - initMetrics() { - // get scheduled metrics first - this.scanningService.getScheduleMetrics() - .pipe(finalize(() => this.gettingMetrics = false)) - .subscribe(response => { - // if scheduled scanning is on going - if (response && response.ongoing) { - response.isScheduled = true; - this.scanningMetrics = response; - } else { - this.getManualMetrics(); - } - }, - error => { - this.errorHandler.error(error); - // if error, get manual metrics - this.getManualMetrics(); - }); - } getI18nKey(str: string): string { if (str && this.i18nKeyMap[str]) { return this.i18nKeyMap[str]; @@ -259,6 +208,16 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy { } return '0'; } + abortWidth() { + if (this.scanningMetrics + && this.scanningMetrics.metrics + && this.scanningMetrics.total + && this.scanningMetrics.metrics[VULNERABILITY_SCAN_STATUS.STOPPED]) { + return this.scanningMetrics.metrics[VULNERABILITY_SCAN_STATUS.STOPPED] / + this.scanningMetrics.total * this.totalWidth + 'px'; + } + return '0'; + } scanNow(): void { if (this.onSubmitting) { return; // Aoid duplicated submitting @@ -277,7 +236,7 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy { }); // reset metrics and then get new metrics this.scanningMetrics = null; - this.getManualMetrics(); + this.getMetrics(); } , error => { if (error && error.status && error.status === 412) { @@ -341,4 +300,13 @@ export class VulnerabilityConfigComponent implements OnInit, OnDestroy { isInProgress(status: string): boolean { return status === VULNERABILITY_SCAN_STATUS.RUNNING; } + isAborted(status: string): boolean { + return status === VULNERABILITY_SCAN_STATUS.STOPPED; + } + isManual() { + return this.scanningMetrics && this.scanningMetrics.trigger === Triggers.MANUAL; + } + isSchedule() { + return this.scanningMetrics && this.scanningMetrics.trigger === Triggers.SCHEDULE; + } }