mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-02 13:01:23 +01:00
new endpoint
Signed-off-by: FangyuanCheng <fangyuanc@vmware.com>
This commit is contained in:
parent
bb76a4d97d
commit
03c9bf8ceb
@ -11,6 +11,18 @@
|
||||
</div>
|
||||
<form #targetForm="ngForm">
|
||||
<section class="form-block">
|
||||
<!-- provider -->
|
||||
<div class="form-group">
|
||||
<label class="form-group-label-override required">{{'DESTINATION.PROVIDER' | translate}}</label>
|
||||
<div class="form-select">
|
||||
<div class="select providerSelect pull-left">
|
||||
<select name="adapter" id="adapter" [(ngModel)]="target.type" [disabled]="testOngoing || controlEnabled">
|
||||
<option *ngFor="let adapter of adapterList" [ngValue]="adapter" value="{{adapter.type}}">{{adapter.type}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Endpoint name -->
|
||||
<div class="form-group">
|
||||
<label for="destination_name" class="col-md-4 form-group-label-override required">{{ 'DESTINATION.NAME' |
|
||||
translate }}</label>
|
||||
@ -23,30 +35,39 @@
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<!--Description-->
|
||||
<div class="form-group">
|
||||
<label class="form-group-label-override">{{'REPLICATION.DESCRIPTION' | translate}}</label>
|
||||
<textarea type="text" class="inputWidth" row=3 name="description" [(ngModel)]="target.description"></textarea>
|
||||
</div>
|
||||
<!-- Endpoint Url -->
|
||||
<div class="form-group">
|
||||
<label for="destination_url" class="col-md-4 form-group-label-override required">{{ 'DESTINATION.URL' |
|
||||
translate }}</label>
|
||||
<label class="col-md-8" for="destination_url" aria-haspopup="true" role="tooltip" [class.invalid]="targetEndpoint.errors && (targetEndpoint.dirty || targetEndpoint.touched)"
|
||||
[class.valid]="targetEndpoint.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
||||
<input type="text" id="destination_url" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.endpoint"
|
||||
<input type="text" id="destination_url" [disabled]="testOngoing || controlEnabled" [readonly]="!editable" [(ngModel)]="target.url"
|
||||
size="20" name="endpointUrl" #targetEndpoint="ngModel" required placeholder="http(s)://192.168.1.1">
|
||||
<span class="tooltip-content" *ngIf="targetEndpoint.errors && targetEndpoint.errors.required && (targetEndpoint.dirty || targetEndpoint.touched)">
|
||||
{{ 'DESTINATION.URL_IS_REQUIRED' | translate }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<!-- access_key -->
|
||||
<div class="form-group">
|
||||
<label for="destination_username" class="col-md-4 form-group-label-override">{{ 'DESTINATION.USERNAME' |
|
||||
<label for="destination_access_key" class="col-md-4 form-group-label-override">{{ 'DESTINATION.ACCESS_ID' |
|
||||
translate }}</label>
|
||||
<input type="text" class="col-md-8" id="destination_username" [disabled]="testOngoing" [readonly]="!editable"
|
||||
[(ngModel)]="target.username" size="20" name="username" #username="ngModel">
|
||||
<input type="text" placeholder="Access ID" class="col-md-8" id="destination_access_key" [disabled]="testOngoing" [readonly]="!editable"
|
||||
[(ngModel)]="target.credential.access_key" size="23" name="access_key" #access_key="ngModel">
|
||||
</div>
|
||||
<!-- access_secret -->
|
||||
<div class="form-group">
|
||||
<label for="destination_password" class="col-md-4 form-group-label-override">{{ 'DESTINATION.PASSWORD' |
|
||||
<label for="destination_password" class="col-md-4 form-group-label-override">{{ 'DESTINATION.ACCESS_SECRET' |
|
||||
translate }}</label>
|
||||
<input type="password" class="col-md-8" id="destination_password" [disabled]="testOngoing" [readonly]="!editable"
|
||||
[(ngModel)]="target.password" size="20" name="password" #password="ngModel">
|
||||
<input type="password" placeholder="Access Secret" class="col-md-8" id="destination_password" [disabled]="testOngoing" [readonly]="!editable"
|
||||
[(ngModel)]="target.credential.access_secret" size="23" name="access_secret" #access_secret="ngModel">
|
||||
</div>
|
||||
<!-- Verify Remote Cert -->
|
||||
<div class="form-group">
|
||||
<label for="destination_insecure" id="destination_insecure_checkbox">{{'CONFIG.VERIFY_REMOTE_CERT' |
|
||||
translate }}</label>
|
||||
|
@ -10,4 +10,12 @@
|
||||
|
||||
.form-height {
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.providerSelect {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.inputWidth {
|
||||
width: 182px;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import { FilterComponent } from "../filter/filter.component";
|
||||
import { CreateEditEndpointComponent } from "../create-edit-endpoint/create-edit-endpoint.component";
|
||||
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
|
||||
import { ErrorHandler } from "../error-handler/error-handler";
|
||||
import { Endpoint } from "../service/interface";
|
||||
import { Endpoint, Adapter } from "../service/interface";
|
||||
import {
|
||||
EndpointService,
|
||||
EndpointDefaultService
|
||||
@ -21,14 +21,27 @@ import { IServiceConfig, SERVICE_CONFIG } from "../service.config";
|
||||
describe("CreateEditEndpointComponent (inline template)", () => {
|
||||
let mockData: Endpoint = {
|
||||
id: 1,
|
||||
url: "https://10.117.4.151",
|
||||
name: "target_01",
|
||||
username: "admin",
|
||||
password: "",
|
||||
credential: {
|
||||
access_key: "admin",
|
||||
access_secret: "",
|
||||
type: "basic"
|
||||
},
|
||||
description: "test",
|
||||
insecure: false,
|
||||
type: "harbor"
|
||||
name: "target_01",
|
||||
type: "Harbor",
|
||||
url: "https://10.117.4.151"
|
||||
};
|
||||
|
||||
let mockAdapter: [Adapter] = [{
|
||||
type: "Harbor",
|
||||
description: "test",
|
||||
supported_resource_types: [
|
||||
"repository"
|
||||
],
|
||||
supported_resource_filters: null
|
||||
}];
|
||||
|
||||
let comp: CreateEditEndpointComponent;
|
||||
let fixture: ComponentFixture<CreateEditEndpointComponent>;
|
||||
|
||||
@ -39,6 +52,7 @@ describe("CreateEditEndpointComponent (inline template)", () => {
|
||||
let endpointService: EndpointService;
|
||||
|
||||
let spy: jasmine.Spy;
|
||||
let spyAdapter: jasmine.Spy;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@ -61,6 +75,10 @@ describe("CreateEditEndpointComponent (inline template)", () => {
|
||||
comp = fixture.componentInstance;
|
||||
|
||||
endpointService = fixture.debugElement.injector.get(EndpointService);
|
||||
spyAdapter = spyOn(endpointService, "getAdapters").and.returnValue(
|
||||
Promise.resolve(mockAdapter)
|
||||
);
|
||||
|
||||
spy = spyOn(endpointService, "getEndpoint").and.returnValue(
|
||||
Promise.resolve(mockData)
|
||||
);
|
||||
|
@ -18,7 +18,8 @@ import {
|
||||
ViewChild,
|
||||
AfterViewChecked,
|
||||
ChangeDetectorRef,
|
||||
OnDestroy
|
||||
OnDestroy,
|
||||
OnInit
|
||||
} from "@angular/core";
|
||||
import { NgForm } from "@angular/forms";
|
||||
import { Subscription } from "rxjs";
|
||||
@ -27,7 +28,7 @@ import { TranslateService } from "@ngx-translate/core";
|
||||
import { EndpointService } from "../service/endpoint.service";
|
||||
import { ErrorHandler } from "../error-handler/index";
|
||||
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
|
||||
import { Endpoint } from "../service/interface";
|
||||
import { Endpoint, Adapter } from "../service/interface";
|
||||
import { toPromise, clone, compareValue, isEmptyObject } from "../utils";
|
||||
|
||||
|
||||
@ -39,16 +40,17 @@ const FAKE_PASSWORD = "rjGcfuRu";
|
||||
styleUrls: ["./create-edit-endpoint.component.scss"]
|
||||
})
|
||||
export class CreateEditEndpointComponent
|
||||
implements AfterViewChecked, OnDestroy {
|
||||
implements AfterViewChecked, OnDestroy, OnInit {
|
||||
modalTitle: string;
|
||||
controlEnabled: boolean = false;
|
||||
createEditDestinationOpened: boolean;
|
||||
staticBackdrop: boolean = true;
|
||||
closable: boolean = false;
|
||||
editable: boolean;
|
||||
|
||||
adapterList: Adapter[] = [];
|
||||
target: Endpoint = this.initEndpoint();
|
||||
selectedType: string;
|
||||
initVal: Endpoint;
|
||||
|
||||
targetForm: NgForm;
|
||||
@ViewChild("targetForm") currentForm: NgForm;
|
||||
|
||||
@ -71,6 +73,14 @@ export class CreateEditEndpointComponent
|
||||
private ref: ChangeDetectorRef
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
toPromise<Adapter[]>(this.endpointService.getAdapters())
|
||||
.then(adapters => {
|
||||
this.adapterList = adapters || [];
|
||||
})
|
||||
.catch((error: any) => this.errorHandler.error(error));
|
||||
}
|
||||
|
||||
public get isValid(): boolean {
|
||||
return (
|
||||
!this.testOngoing &&
|
||||
@ -98,13 +108,17 @@ export class CreateEditEndpointComponent
|
||||
|
||||
initEndpoint(): Endpoint {
|
||||
return {
|
||||
url: "",
|
||||
name: "",
|
||||
username: "",
|
||||
password: "",
|
||||
credential: {
|
||||
access_key: "",
|
||||
access_secret: "",
|
||||
type: "basic"
|
||||
},
|
||||
description: "",
|
||||
insecure: false,
|
||||
type: ""
|
||||
};
|
||||
name: "",
|
||||
type: "Harbor",
|
||||
url: "",
|
||||
};
|
||||
}
|
||||
|
||||
open(): void {
|
||||
@ -125,7 +139,6 @@ export class CreateEditEndpointComponent
|
||||
this.initVal = this.initEndpoint();
|
||||
this.formValues = null;
|
||||
this.endpointId = "";
|
||||
|
||||
this.inlineAlert.close();
|
||||
}
|
||||
|
||||
@ -158,11 +171,12 @@ export class CreateEditEndpointComponent
|
||||
this.target = target;
|
||||
// Keep data cache
|
||||
this.initVal = clone(target);
|
||||
this.initVal.password = FAKE_PASSWORD;
|
||||
this.target.password = FAKE_PASSWORD;
|
||||
this.initVal.credential.access_secret = FAKE_PASSWORD;
|
||||
this.target.credential.access_secret = FAKE_PASSWORD;
|
||||
|
||||
// Open the modal now
|
||||
this.open();
|
||||
this.controlEnabled = true;
|
||||
this.forceRefreshView(2000);
|
||||
})
|
||||
.catch(error => this.errorHandler.error(error));
|
||||
@ -173,15 +187,16 @@ export class CreateEditEndpointComponent
|
||||
.subscribe(res => (this.modalTitle = res));
|
||||
// Directly open the modal
|
||||
this.open();
|
||||
this.controlEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
testConnection() {
|
||||
let payload: Endpoint = this.initEndpoint();
|
||||
if (!this.endpointId) {
|
||||
payload.endpoint = this.target.endpoint;
|
||||
payload.username = this.target.username;
|
||||
payload.password = this.target.password;
|
||||
payload.url = this.target.url;
|
||||
payload.credential.access_key = this.target.credential.access_key;
|
||||
payload.credential.access_secret = this.target.credential.access_secret;
|
||||
payload.insecure = this.target.insecure;
|
||||
} else {
|
||||
let changes: { [key: string]: any } = this.getChanges();
|
||||
@ -225,7 +240,6 @@ export class CreateEditEndpointComponent
|
||||
if (this.onGoing) {
|
||||
return; // Avoid duplicated submitting
|
||||
}
|
||||
|
||||
this.onGoing = true;
|
||||
toPromise<number>(this.endpointService.createEndpoint(this.target))
|
||||
.then(response => {
|
||||
|
@ -176,7 +176,7 @@ describe("CreateEditRuleComponent (inline template)", () => {
|
||||
|
||||
let config: IServiceConfig = {
|
||||
replicationBaseEndpoint: "/api/replication/executions/testing",
|
||||
targetBaseEndpoint: "/api/targets/testing"
|
||||
targetBaseEndpoint: "/api/registries/testing"
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
|
@ -105,12 +105,16 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
emptyEndpoint = {
|
||||
id: -1,
|
||||
endpoint: "",
|
||||
credential: {
|
||||
access_key: "",
|
||||
access_secret: "",
|
||||
type: ""
|
||||
},
|
||||
description: "",
|
||||
insecure: false,
|
||||
name: "",
|
||||
username: "",
|
||||
password: "",
|
||||
insecure: true,
|
||||
type: 0
|
||||
type: "",
|
||||
url: "",
|
||||
};
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
|
@ -17,17 +17,27 @@
|
||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!(selectedRow.length ===1)" (click)="editTargets(selectedRow)" ><clr-icon shape="pencil" size="16"></clr-icon> {{'DESTINATION.EDIT' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!selectedRow.length" (click)="deleteTargets(selectedRow)"><clr-icon shape="times" size="16"></clr-icon> {{'DESTINATION.DELETE' | translate}}</button>
|
||||
</clr-dg-action-bar>
|
||||
<clr-dg-column [clrDgField]="'name'">{{'DESTINATION.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'endpoint'">{{'DESTINATION.URL' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'name'" class="flex-min-width">{{'DESTINATION.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'status'">{{'DESTINATION.STATUS' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'url'" class="flex-min-width">{{'DESTINATION.URL' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'type'" class="flex-min-width">{{'DESTINATION.PROVIDER' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'insecure'">{{'CONFIG.VERIFY_REMOTE_CERT' | translate }}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'credential.type'">{{'DESTINATION.AUTHENTICATION' | translate }}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="creationTimeComparator">{{'DESTINATION.CREATION_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-placeholder>{{'DESTINATION.PLACEHOLDER' | translate }}</clr-dg-placeholder>
|
||||
<clr-dg-row *clrDgItems="let t of targets" [clrDgItem]='t'>
|
||||
<clr-dg-cell>{{t.name}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{t.endpoint}}</clr-dg-cell>
|
||||
<clr-dg-cell class="flex-min-width">{{t.name}}</clr-dg-cell>
|
||||
<clr-dg-cell [ngSwitch]="t.status">
|
||||
<div *ngSwitchCase="'unhealthy'"><clr-icon shape="exclamation-circle" class="is-error text-alignment" size="22"></clr-icon> Unhealthy</div>
|
||||
<div *ngSwitchCase="'healthy'"><clr-icon shape="success-standard" class="is-success text-alignment" size="18"></clr-icon> Healthy</div>
|
||||
<div *ngSwitchCase="'unknown' || ''"><clr-icon shape="exclamation-triangle" class="is-warning text-alignment" size="22"></clr-icon> Unknown</div>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell class="flex-min-width">{{t.url}}</clr-dg-cell>
|
||||
<clr-dg-cell class="flex-min-width">{{t.type}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
{{!t.insecure}}
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>{{t.credential.type}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{t.creation_time | date: 'short'}}</clr-dg-cell>
|
||||
</clr-dg-row>
|
||||
<clr-dg-footer>
|
||||
|
@ -25,4 +25,8 @@
|
||||
|
||||
.endpoint-view {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.flex-min-width {
|
||||
min-width: 180px;
|
||||
}
|
@ -10,7 +10,7 @@ import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation
|
||||
import { CreateEditEndpointComponent } from "../create-edit-endpoint/create-edit-endpoint.component";
|
||||
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
|
||||
import { ErrorHandler } from "../error-handler/error-handler";
|
||||
import { Endpoint } from "../service/interface";
|
||||
import { Endpoint, Adapter } from "../service/interface";
|
||||
import {
|
||||
EndpointService,
|
||||
EndpointDefaultService
|
||||
@ -24,54 +24,83 @@ describe("EndpointComponent (inline template)", () => {
|
||||
let mockData: Endpoint[] = [
|
||||
{
|
||||
id: 1,
|
||||
url: "https://10.117.4.151",
|
||||
credential: {
|
||||
access_key: "admin",
|
||||
access_secret: "",
|
||||
type: "basic"
|
||||
},
|
||||
description: "test",
|
||||
insecure: false,
|
||||
name: "target_01",
|
||||
username: "admin",
|
||||
password: "",
|
||||
insecure: true,
|
||||
type: "Harbor"
|
||||
type: "Harbor",
|
||||
url: "https://10.117.4.151"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
url: "https://10.117.5.142",
|
||||
name: "target_02",
|
||||
username: "AAA",
|
||||
password: "",
|
||||
credential: {
|
||||
access_key: "AAA",
|
||||
access_secret: "",
|
||||
type: "basic"
|
||||
},
|
||||
description: "test",
|
||||
insecure: false,
|
||||
type: "Harbor"
|
||||
name: "target_02",
|
||||
type: "Harbor",
|
||||
url: "https://10.117.5.142"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
url: "https://101.1.11.111",
|
||||
name: "target_03",
|
||||
username: "admin",
|
||||
password: "",
|
||||
credential: {
|
||||
access_key: "admin",
|
||||
access_secret: "",
|
||||
type: "basic"
|
||||
},
|
||||
description: "test",
|
||||
insecure: false,
|
||||
type: "Harbor"
|
||||
name: "target_03",
|
||||
type: "Harbor",
|
||||
url: "https://101.1.11.111"
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
url: "http://4.4.4.4",
|
||||
name: "target_04",
|
||||
username: "",
|
||||
password: "",
|
||||
credential: {
|
||||
access_key: "admin",
|
||||
access_secret: "",
|
||||
type: "basic"
|
||||
},
|
||||
description: "test",
|
||||
insecure: false,
|
||||
type: "Harbor"
|
||||
name: "target_04",
|
||||
type: "Harbor",
|
||||
url: "https://4.4.4.4"
|
||||
}
|
||||
];
|
||||
|
||||
let mockOne: Endpoint[] = [
|
||||
{
|
||||
id: 1,
|
||||
url: "https://10.117.4.151",
|
||||
name: "target_01",
|
||||
username: "admin",
|
||||
password: "",
|
||||
credential: {
|
||||
access_key: "admin",
|
||||
access_secret: "",
|
||||
type: "basic"
|
||||
},
|
||||
description: "test",
|
||||
insecure: false,
|
||||
type: "Harbor"
|
||||
name: "target_01",
|
||||
type: "Harbor",
|
||||
url: "https://10.117.4.151"
|
||||
}
|
||||
];
|
||||
|
||||
let mockAdapter: [Adapter] = [{
|
||||
type: "Harbor",
|
||||
description: "test",
|
||||
supported_resource_types: [
|
||||
"repository"
|
||||
],
|
||||
supported_resource_filters: null
|
||||
}];
|
||||
|
||||
let comp: EndpointComponent;
|
||||
let fixture: ComponentFixture<EndpointComponent>;
|
||||
let config: IServiceConfig = {
|
||||
@ -80,6 +109,7 @@ describe("EndpointComponent (inline template)", () => {
|
||||
|
||||
let endpointService: EndpointService;
|
||||
let spy: jasmine.Spy;
|
||||
let spyAdapter: jasmine.Spy;
|
||||
let spyOnRules: jasmine.Spy;
|
||||
let spyOne: jasmine.Spy;
|
||||
beforeEach(async(() => {
|
||||
@ -110,6 +140,11 @@ describe("EndpointComponent (inline template)", () => {
|
||||
spy = spyOn(endpointService, "getEndpoints").and.returnValues(
|
||||
Promise.resolve(mockData)
|
||||
);
|
||||
|
||||
spyAdapter = spyOn(endpointService, "getAdapters").and.returnValue(
|
||||
Promise.resolve(mockAdapter)
|
||||
);
|
||||
|
||||
spyOnRules = spyOn(
|
||||
endpointService,
|
||||
"getEndpointWithReplicationRules"
|
||||
|
@ -77,12 +77,16 @@ export class EndpointComponent implements OnInit, OnDestroy {
|
||||
|
||||
get initEndpoint(): Endpoint {
|
||||
return {
|
||||
url: "",
|
||||
name: "",
|
||||
username: "",
|
||||
password: "",
|
||||
credential: {
|
||||
access_key: "",
|
||||
access_secret: "",
|
||||
type: ""
|
||||
},
|
||||
description: "",
|
||||
insecure: false,
|
||||
type: ""
|
||||
name: "",
|
||||
type: "",
|
||||
url: "",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,7 @@ export const DefaultServiceConfig: IServiceConfig = {
|
||||
targetBaseEndpoint: "/api/registries",
|
||||
replicationBaseEndpoint: "/api/replication/executions",
|
||||
replicationRuleEndpoint: "/api/replication/policies",
|
||||
adapterEndpoint: "api/replication/adapters",
|
||||
vulnerabilityScanningBaseEndpoint: "/api/repositories",
|
||||
projectPolicyEndpoint: "/api/projects/configs",
|
||||
projectBaseEndpoint: "/api/projects",
|
||||
|
@ -84,21 +84,29 @@ describe('Replication Component (inline template)', () => {
|
||||
let mockEndpoints: Endpoint[] = [
|
||||
{
|
||||
"id": 1,
|
||||
"url": "https://10.117.4.151",
|
||||
"name": "target_01",
|
||||
"username": "admin",
|
||||
"password": "",
|
||||
"credential": {
|
||||
"access_key": "admin",
|
||||
"access_secret": "",
|
||||
"type": "basic"
|
||||
},
|
||||
"description": "test",
|
||||
"insecure": false,
|
||||
"type": "Harbor"
|
||||
"name": "target_01",
|
||||
"type": "Harbor",
|
||||
"url": "https://10.117.4.151"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"url": "https://10.117.5.142",
|
||||
"name": "target_02",
|
||||
"username": "AAA",
|
||||
"password": "",
|
||||
"credential": {
|
||||
"access_key": "admin",
|
||||
"access_secret": "",
|
||||
"type": "basic"
|
||||
},
|
||||
"description": "test",
|
||||
"insecure": false,
|
||||
"type": "Harbor"
|
||||
"name": "target_02",
|
||||
"type": "Harbor",
|
||||
"url": "https://10.117.5.142"
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -54,6 +54,11 @@ export interface IServiceConfig {
|
||||
*/
|
||||
replicationBaseEndpoint?: string;
|
||||
|
||||
/**
|
||||
* The base endpoint of the service used to handle the adapters.
|
||||
*/
|
||||
adapterEndpoint?: string;
|
||||
|
||||
/**
|
||||
* The base endpoint of the service used to handle the replication rules.
|
||||
* Replication rule related endpoints will be built based on this endpoint.
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
HTTP_GET_OPTIONS
|
||||
} from "../utils";
|
||||
import { RequestQueryParams } from "./RequestQueryParams";
|
||||
import { Endpoint, ReplicationRule } from "./interface";
|
||||
import { Endpoint, ReplicationRule, Adapter } from "./interface";
|
||||
|
||||
/**
|
||||
* Define the service methods to handle the endpoint related things.
|
||||
@ -57,6 +57,17 @@ export abstract class EndpointService {
|
||||
*
|
||||
* @memberOf EndpointService
|
||||
*/
|
||||
abstract getAdapters(): Observable<any> | Promise<any> | any;
|
||||
|
||||
/**
|
||||
* Create new endpoint.
|
||||
*
|
||||
* @abstract
|
||||
* ** deprecated param {Adapter} adapter
|
||||
* returns {(Observable<any> | any)}
|
||||
*
|
||||
* @memberOf EndpointService
|
||||
*/
|
||||
abstract createEndpoint(
|
||||
endpoint: Endpoint
|
||||
): Observable<any> | Promise<any> | any;
|
||||
@ -167,6 +178,14 @@ export class EndpointDefaultService extends EndpointService {
|
||||
.catch(error => Promise.reject(error));
|
||||
}
|
||||
|
||||
public getAdapters(): Observable<any> | Promise<any> | any {
|
||||
return this.http
|
||||
.get(`/api/replication/adapters`)
|
||||
.toPromise()
|
||||
.then(response => response.json() as Adapter)
|
||||
.catch(error => Promise.reject(error));
|
||||
}
|
||||
|
||||
public createEndpoint(
|
||||
endpoint: Endpoint
|
||||
): Observable<any> | Promise<any> | any {
|
||||
|
@ -75,13 +75,27 @@ export interface Tag extends Base {
|
||||
* extends {Base}
|
||||
*/
|
||||
export interface Endpoint extends Base {
|
||||
url: string;
|
||||
name: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
credential: {
|
||||
access_key?: string,
|
||||
access_secret?: string,
|
||||
type: string;
|
||||
};
|
||||
description: string;
|
||||
insecure: boolean;
|
||||
name: string;
|
||||
type: string;
|
||||
[key: string]: any;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface Adapter extends Base {
|
||||
type: string;
|
||||
description: string;
|
||||
supported_resource_types: [
|
||||
string
|
||||
];
|
||||
supported_resource_filters: [
|
||||
string
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,6 +65,7 @@ const uiLibConfig: IServiceConfig = {
|
||||
targetBaseEndpoint: "/api/registries",
|
||||
replicationBaseEndpoint: "/api/replication/executions",
|
||||
replicationRuleEndpoint: "/api/replication/policies",
|
||||
adapterEndpoint: "api/replication/adapters",
|
||||
vulnerabilityScanningBaseEndpoint: "/api/repositories",
|
||||
projectPolicyEndpoint: "/api/projects/configs",
|
||||
projectBaseEndpoint: "/api/projects",
|
||||
|
@ -456,22 +456,25 @@
|
||||
},
|
||||
"DESTINATION": {
|
||||
"NEW_ENDPOINT": "New Endpoint",
|
||||
"PROVIDER": "Provider",
|
||||
"ENDPOINT": "Endpoint",
|
||||
"NAME": "Endpoint Name",
|
||||
"NAME": "Name",
|
||||
"NAME_IS_REQUIRED": "Endpoint name is required.",
|
||||
"URL": "Endpoint URL",
|
||||
"URL_IS_REQUIRED": "Endpoint URL is required.",
|
||||
"USERNAME": "Username",
|
||||
"PASSWORD": "Password",
|
||||
"AUTHENTICATION":"Authentication",
|
||||
"ACCESS_ID": "Access ID",
|
||||
"ACCESS_SECRET": "Access Secret",
|
||||
"STATUS": "Status",
|
||||
"TEST_CONNECTION": "Test Connection",
|
||||
"TITLE_EDIT": "Edit Endpoint",
|
||||
"TITLE_ADD": "Create Endpoint",
|
||||
"TITLE_ADD": "New Registry Endpoint",
|
||||
"EDIT": "Edit",
|
||||
"DELETE": "Delete",
|
||||
"TESTING_CONNECTION": "Testing Connection...",
|
||||
"TEST_CONNECTION_SUCCESS": "Connection tested successfully.",
|
||||
"TEST_CONNECTION_FAILURE": "Failed to ping endpoint.",
|
||||
"CONFLICT_NAME": "Endpoint name or URL already exists.",
|
||||
"CONFLICT_NAME": "Endpoint name already exists.",
|
||||
"INVALID_NAME": "Invalid endpoint name.",
|
||||
"FAILED_TO_GET_TARGET": "Failed to get endpoint.",
|
||||
"CREATION_TIME": "Creation Time",
|
||||
|
@ -457,22 +457,25 @@
|
||||
},
|
||||
"DESTINATION": {
|
||||
"NEW_ENDPOINT": "Nuevo Endpoint",
|
||||
"PROVIDER": "Provider",
|
||||
"ENDPOINT": "Endpoint",
|
||||
"NAME": "Nombre del Endpoint",
|
||||
"NAME": "Nombre",
|
||||
"NAME_IS_REQUIRED": "El nombre del endpoint es obligatorio.",
|
||||
"URL": "URL del Endpoint",
|
||||
"URL_IS_REQUIRED": "La URL del endpoint es obligatoria.",
|
||||
"USERNAME": "Nombre de usuario",
|
||||
"PASSWORD": "Contraseña",
|
||||
"AUTHENTICATION":"Autenticación",
|
||||
"ACCESS_ID": "ID de acceso",
|
||||
"ACCESS_SECRET": "Secreto de acceso",
|
||||
"STATUS": "Estado",
|
||||
"TEST_CONNECTION": "Comprobar conexión",
|
||||
"TITLE_EDIT": "Editar Endpoint",
|
||||
"TITLE_ADD": "Crear Endpoint",
|
||||
"TITLE_ADD": "Nuevo punto final de registro",
|
||||
"EDIT": "Editar",
|
||||
"DELETE": "Eliminar",
|
||||
"TESTING_CONNECTION": "Comprobar conexión...",
|
||||
"TEST_CONNECTION_SUCCESS": "Conexión comprobada satisfactoriamente.",
|
||||
"TEST_CONNECTION_FAILURE": "Fallo al comprobar el endpoint.",
|
||||
"CONFLICT_NAME": "El nombre del endpoint ya existe.",
|
||||
"CONFLICT_NAME": "El nombre ya existe.",
|
||||
"INVALID_NAME": "El nombre del endpoint no es válido.",
|
||||
"FAILED_TO_GET_TARGET": "Fallo al obtener el endpoint.",
|
||||
"CREATION_TIME": "Fecha de creación",
|
||||
|
@ -438,21 +438,24 @@
|
||||
},
|
||||
"DESTINATION": {
|
||||
"NEW_ENDPOINT": "Nouveau Point Final",
|
||||
"PROVIDER": "Provider",
|
||||
"ENDPOINT": "Point Final",
|
||||
"NAME": "Nom du Point Final",
|
||||
"NAME": "Alors",
|
||||
"NAME_IS_REQUIRED": "Le nom du Point final est obligatoire.",
|
||||
"URL": "URL du Point Final",
|
||||
"URL_IS_REQUIRED": "L'URL du Point Final est obligatoire.",
|
||||
"USERNAME": "Nom d'utilisateur",
|
||||
"PASSWORD": "Mot de Passe",
|
||||
"AUTHENTICATION":"Authentification",
|
||||
"ACCESS_ID": "ID d'accès",
|
||||
"ACCESS_SECRET": "Secret d'accès",
|
||||
"STATUS": "Statut",
|
||||
"TEST_CONNECTION": "Test de Connexion",
|
||||
"TITLE_EDIT": "Editer le Point Final",
|
||||
"TITLE_ADD": "Créer le Point Final",
|
||||
"TITLE_ADD": "Nouveau point de terminaison de registre",
|
||||
"DELETE": "Supprimer le Point Final",
|
||||
"TESTING_CONNECTION": "En train de tester la Connexion...",
|
||||
"TEST_CONNECTION_SUCCESS": "Connexion testée avec succès.",
|
||||
"TEST_CONNECTION_FAILURE": "Echec du ping du Point Final.",
|
||||
"CONFLICT_NAME": "Le nom ou l'URL du point final existe déjà.",
|
||||
"CONFLICT_NAME": "Le nom du noeud final existe déjà.",
|
||||
"INVALID_NAME": "Nom du point final invalide.",
|
||||
"FAILED_TO_GET_TARGET": "Echec de l'obtention du point final.",
|
||||
"CREATION_TIME": "Temps de Création",
|
||||
|
@ -456,22 +456,25 @@
|
||||
},
|
||||
"DESTINATION": {
|
||||
"NEW_ENDPOINT": "Novo Endpoint",
|
||||
"PROVIDER": "Provider",
|
||||
"ENDPOINT": "Endpoint",
|
||||
"NAME": "Nome do Endpoint",
|
||||
"NAME": "Nome",
|
||||
"NAME_IS_REQUIRED": "Nome do Endpoint é obrigatório.",
|
||||
"URL": "URL do Endpoint",
|
||||
"URL_IS_REQUIRED": "URL do Endpoint URL é obrigatória.",
|
||||
"USERNAME": "Nome de usuário",
|
||||
"PASSWORD": "Senha",
|
||||
"AUTHENTICATION":"Autenticação",
|
||||
"ACCESS_ID": "ID de acesso",
|
||||
"ACCESS_SECRET": "Secreto de acceso",
|
||||
"STATUS": "Segredo de acesso",
|
||||
"TEST_CONNECTION": "Testar Conexão",
|
||||
"TITLE_EDIT": "Editar Endpoint",
|
||||
"TITLE_ADD": "Criar Endpoint",
|
||||
"TITLE_ADD": "Novo ponto final do registro",
|
||||
"EDIT": "Editar",
|
||||
"DELETE": "Remover",
|
||||
"TESTING_CONNECTION": "Testando Conexão...",
|
||||
"TEST_CONNECTION_SUCCESS": "Conexão testada com sucesso.",
|
||||
"TEST_CONNECTION_FAILURE": "Falha ao pingar o endpoint.",
|
||||
"CONFLICT_NAME": "Nome do Endpoint ou URL já existe.",
|
||||
"CONFLICT_NAME": "O nome do terminal já existe.",
|
||||
"INVALID_NAME": "Nome do Endpoint inválido.",
|
||||
"FAILED_TO_GET_TARGET": "Falha ao obter endpoint.",
|
||||
"CREATION_TIME": "Data de criação",
|
||||
|
@ -457,13 +457,16 @@
|
||||
},
|
||||
"DESTINATION": {
|
||||
"NEW_ENDPOINT": "新建目标",
|
||||
"PROVIDER": "提供者",
|
||||
"ENDPOINT": "目标",
|
||||
"NAME": "目标名",
|
||||
"NAME_IS_REQUIRED": "目标名为必填项。",
|
||||
"URL": "目标URL",
|
||||
"URL_IS_REQUIRED": "目标URL为必填项。",
|
||||
"USERNAME": "用户名",
|
||||
"PASSWORD": "密码",
|
||||
"AUTHENTICATION":"认证",
|
||||
"ACCESS_ID": "访问ID",
|
||||
"ACCESS_SECRET": "访问密码",
|
||||
"STATUS": "状态",
|
||||
"TEST_CONNECTION": "测试连接",
|
||||
"TITLE_EDIT": "编辑目标",
|
||||
"TITLE_ADD": "新建目标",
|
||||
@ -472,7 +475,7 @@
|
||||
"TESTING_CONNECTION": "正在测试连接...",
|
||||
"TEST_CONNECTION_SUCCESS": "测试连接成功。",
|
||||
"TEST_CONNECTION_FAILURE": "测试连接失败。",
|
||||
"CONFLICT_NAME": "目标名或目标URL已存在。",
|
||||
"CONFLICT_NAME": "目标名已存在。",
|
||||
"INVALID_NAME": "无效的目标名称。",
|
||||
"FAILED_TO_GET_TARGET": "获取目标失败。",
|
||||
"CREATION_TIME": "创建时间",
|
||||
|
Loading…
Reference in New Issue
Block a user