mirror of
https://github.com/goharbor/harbor.git
synced 2024-10-02 07:18:01 +02:00
Enhancements to configuration sharable component
This commit is contained in:
parent
f50a125d61
commit
c3dd5e6d12
@ -100,7 +100,7 @@ export class Configuration {
|
|||||||
this.verify_remote_cert = new BoolValueItem(false, true);
|
this.verify_remote_cert = new BoolValueItem(false, true);
|
||||||
this.scan_all_policy = new ComplexValueItem({
|
this.scan_all_policy = new ComplexValueItem({
|
||||||
type: "daily",
|
type: "daily",
|
||||||
parameters: {
|
parameter: {
|
||||||
daily_time: 0
|
daily_time: 0
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
export const REGISTRY_CONFIG_HTML: string = `
|
export const REGISTRY_CONFIG_HTML: string = `
|
||||||
<div>
|
<div>
|
||||||
<replication-config [(replicationConfig)]="config"></replication-config>
|
<replication-config #replicationConfig [(replicationConfig)]="config"></replication-config>
|
||||||
<system-settings [(systemSettings)]="config"></system-settings>
|
<system-settings #systemSettings [(systemSettings)]="config"></system-settings>
|
||||||
<vulnerability-config [(vulnerabilityConfig)]="config"></vulnerability-config>
|
<vulnerability-config #vulnerabilityConfig [(vulnerabilityConfig)]="config"></vulnerability-config>
|
||||||
|
<div>
|
||||||
|
<button type="button" class="btn btn-primary" (click)="save()" [disabled]="shouldDisable">{{'BUTTON.SAVE' | translate}}</button>
|
||||||
|
<button type="button" class="btn btn-outline" (click)="cancel()" [disabled]="shouldDisable">{{'BUTTON.CANCEL' | translate}}</button>
|
||||||
|
</div>
|
||||||
|
<confirmation-dialog #cfgConfirmationDialog (confirmAction)="confirmCancel($event)"></confirmation-dialog>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
@ -8,6 +8,7 @@ import { ReplicationConfigComponent } from './replication/replication-config.com
|
|||||||
import { SystemSettingsComponent } from './system/system-settings.component';
|
import { SystemSettingsComponent } from './system/system-settings.component';
|
||||||
import { VulnerabilityConfigComponent } from './vulnerability/vulnerability-config.component';
|
import { VulnerabilityConfigComponent } from './vulnerability/vulnerability-config.component';
|
||||||
import { RegistryConfigComponent } from './registry-config.component';
|
import { RegistryConfigComponent } from './registry-config.component';
|
||||||
|
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ConfigurationService,
|
ConfigurationService,
|
||||||
@ -29,7 +30,7 @@ describe('RegistryConfigComponent (inline template)', () => {
|
|||||||
mockConfig.verify_remote_cert.value = true;
|
mockConfig.verify_remote_cert.value = true;
|
||||||
mockConfig.scan_all_policy.value = {
|
mockConfig.scan_all_policy.value = {
|
||||||
type: "daily",
|
type: "daily",
|
||||||
parameters: {
|
parameter: {
|
||||||
daily_time: 0
|
daily_time: 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -46,7 +47,8 @@ describe('RegistryConfigComponent (inline template)', () => {
|
|||||||
ReplicationConfigComponent,
|
ReplicationConfigComponent,
|
||||||
SystemSettingsComponent,
|
SystemSettingsComponent,
|
||||||
VulnerabilityConfigComponent,
|
VulnerabilityConfigComponent,
|
||||||
RegistryConfigComponent
|
RegistryConfigComponent,
|
||||||
|
ConfirmationDialogComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
ErrorHandler,
|
ErrorHandler,
|
||||||
|
@ -1,10 +1,22 @@
|
|||||||
import { Component, OnInit, EventEmitter, Output } from '@angular/core';
|
import { Component, OnInit, EventEmitter, Output, ViewChild } from '@angular/core';
|
||||||
|
|
||||||
import { Configuration, ComplexValueItem } from './config';
|
import { Configuration, ComplexValueItem } from './config';
|
||||||
import { REGISTRY_CONFIG_HTML } from './registry-config.component.html';
|
import { REGISTRY_CONFIG_HTML } from './registry-config.component.html';
|
||||||
import { ConfigurationService } from '../service/index';
|
import { ConfigurationService } from '../service/index';
|
||||||
import { toPromise } from '../utils';
|
import { toPromise } from '../utils';
|
||||||
import { ErrorHandler } from '../error-handler';
|
import { ErrorHandler } from '../error-handler';
|
||||||
|
import {
|
||||||
|
ReplicationConfigComponent,
|
||||||
|
SystemSettingsComponent,
|
||||||
|
VulnerabilityConfigComponent
|
||||||
|
} from './index';
|
||||||
|
|
||||||
|
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const';
|
||||||
|
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
||||||
|
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
|
||||||
|
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hbr-registry-config',
|
selector: 'hbr-registry-config',
|
||||||
@ -13,27 +25,56 @@ import { ErrorHandler } from '../error-handler';
|
|||||||
export class RegistryConfigComponent implements OnInit {
|
export class RegistryConfigComponent implements OnInit {
|
||||||
config: Configuration = new Configuration();
|
config: Configuration = new Configuration();
|
||||||
configCopy: Configuration;
|
configCopy: Configuration;
|
||||||
|
onGoing: boolean = false;
|
||||||
|
|
||||||
@Output() configChanged: EventEmitter<any> = new EventEmitter<any>();
|
@ViewChild("replicationConfig") replicationCfg: ReplicationConfigComponent;
|
||||||
|
@ViewChild("systemSettings") systemSettings: SystemSettingsComponent;
|
||||||
|
@ViewChild("vulnerabilityConfig") vulnerabilityCfg: VulnerabilityConfigComponent;
|
||||||
|
@ViewChild("cfgConfirmationDialog") confirmationDlg: ConfirmationDialogComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private configService: ConfigurationService,
|
private configService: ConfigurationService,
|
||||||
private errorHandler: ErrorHandler
|
private errorHandler: ErrorHandler,
|
||||||
|
private translate: TranslateService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
get shouldDisable(): boolean {
|
||||||
|
return !this.isValid() || !this.hasChanges() || this.onGoing;
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
//Initialize
|
//Initialize
|
||||||
this.load();
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isValid(): boolean {
|
||||||
|
return this.replicationCfg &&
|
||||||
|
this.replicationCfg.isValid &&
|
||||||
|
this.systemSettings &&
|
||||||
|
this.systemSettings.isValid &&
|
||||||
|
this.vulnerabilityCfg &&
|
||||||
|
this.vulnerabilityCfg.isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasChanges(): boolean {
|
||||||
|
return !this._isEmptyObject(this.getChanges());
|
||||||
|
}
|
||||||
|
|
||||||
//Load configurations
|
//Load configurations
|
||||||
load(): void {
|
load(): void {
|
||||||
|
this.onGoing = true;
|
||||||
toPromise<Configuration>(this.configService.getConfigurations())
|
toPromise<Configuration>(this.configService.getConfigurations())
|
||||||
.then((config: Configuration) => {
|
.then((config: Configuration) => {
|
||||||
this.configCopy = Object.assign({}, config);
|
this.onGoing = false;
|
||||||
|
|
||||||
|
this.configCopy = this._clone(config);
|
||||||
this.config = config;
|
this.config = config;
|
||||||
})
|
})
|
||||||
.catch(error => this.errorHandler.error(error));
|
.catch(error => {
|
||||||
|
this.onGoing = false;
|
||||||
|
|
||||||
|
this.errorHandler.error(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//Save configuration changes
|
//Save configuration changes
|
||||||
@ -45,26 +86,48 @@ export class RegistryConfigComponent implements OnInit {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Fix policy parameters issue
|
this.onGoing = true;
|
||||||
let scanningAllPolicy = changes["scan_all_policy"];
|
|
||||||
if (scanningAllPolicy &&
|
|
||||||
scanningAllPolicy.type !== "daily" &&
|
|
||||||
scanningAllPolicy.parameters) {
|
|
||||||
delete (scanningAllPolicy.parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
toPromise<any>(this.configService.saveConfigurations(changes))
|
toPromise<any>(this.configService.saveConfigurations(changes))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.configChanged.emit(changes);
|
this.onGoing = false;
|
||||||
|
|
||||||
|
this.translate.get("CONFIG.SAVE_SUCCESS").subscribe((res: string) => {
|
||||||
|
this.errorHandler.info(res);
|
||||||
|
});
|
||||||
|
//Reload to fetch all the updates
|
||||||
|
this.load();
|
||||||
})
|
})
|
||||||
.catch(error => this.errorHandler.error(error));
|
.catch(error => {
|
||||||
|
this.onGoing = false;
|
||||||
|
this.errorHandler.error(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Cancel the changes if have
|
||||||
|
cancel(): void {
|
||||||
|
let msg = new ConfirmationMessage(
|
||||||
|
"CONFIG.CONFIRM_TITLE",
|
||||||
|
"CONFIG.CONFIRM_SUMMARY",
|
||||||
|
"",
|
||||||
|
{},
|
||||||
|
ConfirmationTargets.CONFIG
|
||||||
|
);
|
||||||
|
this.confirmationDlg.open(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Confirm cancel
|
||||||
|
confirmCancel(ack: ConfirmationAcknowledgement): void {
|
||||||
|
if (ack && ack.source === ConfirmationTargets.CONFIG &&
|
||||||
|
ack.state === ConfirmationState.CONFIRMED) {
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reset(): void {
|
reset(): void {
|
||||||
//Reset to the values of copy
|
//Reset to the values of copy
|
||||||
let changes: { [key: string]: any | any[] } = this.getChanges();
|
let changes: { [key: string]: any | any[] } = this.getChanges();
|
||||||
for (let prop in changes) {
|
for (let prop in changes) {
|
||||||
this.config[prop] = Object.assign({}, this.configCopy[prop]);
|
this.config[prop] = this._clone(this.configCopy[prop]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,4 +170,10 @@ export class RegistryConfigComponent implements OnInit {
|
|||||||
_isEmptyObject(obj: any): boolean {
|
_isEmptyObject(obj: any): boolean {
|
||||||
return !obj || JSON.stringify(obj) === "{}";
|
return !obj || JSON.stringify(obj) === "{}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Deeper clone all
|
||||||
|
_clone(srcObj: any): any {
|
||||||
|
if (!srcObj) return null;
|
||||||
|
return JSON.parse(JSON.stringify(srcObj));
|
||||||
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ export const VULNERABILITY_CONFIG_HTML: string = `
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="scanAllPolicy">{{ 'CONFIG.SCANNING.SCAN_ALL' | translate }}</label>
|
<label for="scanAllPolicy">{{ 'CONFIG.SCANNING.SCAN_ALL' | translate }}</label>
|
||||||
<div class="select">
|
<div class="select">
|
||||||
<select id="scanAllPolicy" name="scanAllPolicy" [disabled]="!editable" [(ngModel)]="vulnerabilityConfig.scan_all_policy.value.type">
|
<select id="scanAllPolicy" name="scanAllPolicy" [disabled]="!editable" [(ngModel)]="scanningType">
|
||||||
<option value="none">{{ 'CONFIG.SCANNING.NONE_POLICY' | translate }}</option>
|
<option value="none">{{ 'CONFIG.SCANNING.NONE_POLICY' | translate }}</option>
|
||||||
<option value="daily">{{ 'CONFIG.SCANNING.DAILY_POLICY' | translate }}</option>
|
<option value="daily">{{ 'CONFIG.SCANNING.DAILY_POLICY' | translate }}</option>
|
||||||
<option value="on_refresh">{{ 'CONFIG.SCANNING.REFRESH_POLICY' | translate }}</option>
|
<option value="on_refresh">{{ 'CONFIG.SCANNING.REFRESH_POLICY' | translate }}</option>
|
||||||
|
@ -30,13 +30,13 @@ export class VulnerabilityConfigComponent {
|
|||||||
this.config = cfg;
|
this.config = cfg;
|
||||||
if (this.config.scan_all_policy &&
|
if (this.config.scan_all_policy &&
|
||||||
this.config.scan_all_policy.value) {
|
this.config.scan_all_policy.value) {
|
||||||
if (this.config.scan_all_policy.value.type === "daily"){
|
if (this.config.scan_all_policy.value.type === "daily") {
|
||||||
if(!this.config.scan_all_policy.value.parameters){
|
if (!this.config.scan_all_policy.value.parameter) {
|
||||||
this.config.scan_all_policy.value.parameters = {
|
this.config.scan_all_policy.value.parameter = {
|
||||||
daily_time: 0
|
daily_time: 0
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.configChange.emit(this.config);
|
this.configChange.emit(this.config);
|
||||||
}
|
}
|
||||||
@ -51,8 +51,8 @@ export class VulnerabilityConfigComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let timeOffset: number = 0;//seconds
|
let timeOffset: number = 0;//seconds
|
||||||
if (this.config.scan_all_policy.value.parameters) {
|
if (this.config.scan_all_policy.value.parameter) {
|
||||||
let daily_time = this.config.scan_all_policy.value.parameters.daily_time;
|
let daily_time = this.config.scan_all_policy.value.parameter.daily_time;
|
||||||
if (daily_time && typeof daily_time === "number") {
|
if (daily_time && typeof daily_time === "number") {
|
||||||
timeOffset = +daily_time;
|
timeOffset = +daily_time;
|
||||||
}
|
}
|
||||||
@ -99,8 +99,9 @@ export class VulnerabilityConfigComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.config.scan_all_policy.value.parameters) {
|
//Double confirm inner parameter existing.
|
||||||
this.config.scan_all_policy.value.parameters = {
|
if (!this.config.scan_all_policy.value.parameter) {
|
||||||
|
this.config.scan_all_policy.value.parameter = {
|
||||||
daily_time: 0
|
daily_time: 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -124,7 +125,41 @@ export class VulnerabilityConfigComponent {
|
|||||||
utcTimes -= ONE_DAY_SECONDS;
|
utcTimes -= ONE_DAY_SECONDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.config.scan_all_policy.value.parameters.daily_time = utcTimes;
|
this.config.scan_all_policy.value.parameter.daily_time = utcTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Scanning type
|
||||||
|
get scanningType(): string {
|
||||||
|
if (this.config &&
|
||||||
|
this.config.scan_all_policy &&
|
||||||
|
this.config.scan_all_policy.value) {
|
||||||
|
return this.config.scan_all_policy.value.type;
|
||||||
|
} else {
|
||||||
|
//default
|
||||||
|
return "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set scanningType(v: string) {
|
||||||
|
if (this.config &&
|
||||||
|
this.config.scan_all_policy &&
|
||||||
|
this.config.scan_all_policy.value) {
|
||||||
|
let type: string = (v && v.trim() !== "") ? v : "none";
|
||||||
|
this.config.scan_all_policy.value.type = type;
|
||||||
|
if (type !== "daily") {
|
||||||
|
//No parameter
|
||||||
|
if (this.config.scan_all_policy.value.parameter) {
|
||||||
|
delete (this.config.scan_all_policy.value.parameter);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Has parameter
|
||||||
|
if (!this.config.scan_all_policy.value.parameter) {
|
||||||
|
this.config.scan_all_policy.value.parameter = {
|
||||||
|
daily_time: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewChild("systemConfigFrom") systemSettingsForm: NgForm;
|
@ViewChild("systemConfigFrom") systemSettingsForm: NgForm;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
"clarity-icons": "^0.9.8",
|
"clarity-icons": "^0.9.8",
|
||||||
"clarity-ui": "^0.9.8",
|
"clarity-ui": "^0.9.8",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "^2.4.1",
|
||||||
"harbor-ui": "^0.2.40",
|
"harbor-ui": "^0.2.52",
|
||||||
"intl": "^1.2.5",
|
"intl": "^1.2.5",
|
||||||
"mutationobserver-shim": "^0.3.2",
|
"mutationobserver-shim": "^0.3.2",
|
||||||
"ngx-cookie": "^1.0.0",
|
"ngx-cookie": "^1.0.0",
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<button id="config-system" class="btn btn-link nav-link" aria-controls="system_settings" [class.active]='isCurrentTabLink("config-system")' type="button" (click)='tabLinkClick("config-system")'>{{'CONFIG.SYSTEM' | translate }}</button>
|
<button id="config-system" class="btn btn-link nav-link" aria-controls="system_settings" [class.active]='isCurrentTabLink("config-system")' type="button" (click)='tabLinkClick("config-system")'>{{'CONFIG.SYSTEM' | translate }}</button>
|
||||||
</li>
|
</li>
|
||||||
<li role="presentation" class="nav-item">
|
<li role="presentation" class="nav-item">
|
||||||
<button id="config-vulnerability" class="btn btn-link nav-link" aria-controls="vulnerability" [class.active]='isCurrentTabLink("config-vulnerability")' type="button" (click)='tabLinkClick("config-vulnerability")'>Vulnerability</button>
|
<button id="config-vulnerability" class="btn btn-link nav-link" aria-controls="vulnerability" [class.active]='isCurrentTabLink("config-vulnerability")' type="button" (click)='tabLinkClick("config-vulnerability")'>{{'VULNERABILITY.SINGULAR' | translate}}</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<section id="authentication" role="tabpanel" aria-labelledby="config-auth" [hidden]='!isCurrentTabContent("authentication")'>
|
<section id="authentication" role="tabpanel" aria-labelledby="config-auth" [hidden]='!isCurrentTabContent("authentication")'>
|
||||||
@ -41,7 +41,6 @@
|
|||||||
<button type="button" class="btn btn-outline" (click)="testLDAPServer()" *ngIf="showLdapServerBtn" [disabled]="!isLDAPConfigValid()">{{'BUTTON.TEST_LDAP' | translate}}</button>
|
<button type="button" class="btn btn-outline" (click)="testLDAPServer()" *ngIf="showLdapServerBtn" [disabled]="!isLDAPConfigValid()">{{'BUTTON.TEST_LDAP' | translate}}</button>
|
||||||
<span id="forTestingMail" class="spinner spinner-inline" [hidden]="hideMailTestingSpinner"></span>
|
<span id="forTestingMail" class="spinner spinner-inline" [hidden]="hideMailTestingSpinner"></span>
|
||||||
<span id="forTestingLDAP" class="spinner spinner-inline" [hidden]="hideLDAPTestingSpinner"></span>
|
<span id="forTestingLDAP" class="spinner spinner-inline" [hidden]="hideLDAPTestingSpinner"></span>
|
||||||
<button type="button" class="btn btn-primary" (click)="consoleTest()">CONSOLE</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -71,11 +71,6 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
private appConfigService: AppConfigService,
|
private appConfigService: AppConfigService,
|
||||||
private session: SessionService) { }
|
private session: SessionService) { }
|
||||||
|
|
||||||
consoleTest(): void {
|
|
||||||
console.log(this.allConfig, this.originalCopy);
|
|
||||||
console.log("-------------");
|
|
||||||
console.log(this.getChanges());
|
|
||||||
}
|
|
||||||
isCurrentTabLink(tabId: string): boolean {
|
isCurrentTabLink(tabId: string): boolean {
|
||||||
return this.currentTabId === tabId;
|
return this.currentTabId === tabId;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user