-
-
-
@@ -159,9 +157,7 @@
\ No newline at end of file
diff --git a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.scss b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.scss
index c1163e44f..a62f0e1a0 100644
--- a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.scss
+++ b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.scss
@@ -146,12 +146,19 @@ h4 {
}
.form-group-override {
- padding-left: 170px !important;
+ padding-left: 200px;
}
-.form-group>label:first-child {
- font-size: 14px;
- width: 6.5rem;
+.form-group {
+ >label:first-child{
+ font-size: 14px;
+ width: 7rem;
+ }
+ .radio {
+ label {
+ margin-right:10px;
+ }
+ }
}
.form-select {
@@ -199,7 +206,7 @@ clr-modal {
margin-left: -15px;
}
-.plus-position {
+.mr-t-11{
margin-top: 11px;
}
@@ -214,4 +221,14 @@ clr-modal {
.loading-center {
display: block;
text-align: center;
+}
+
+.width-315 {
+ display: flex;
+ align-items: center;
+ width:315px;
+}
+
+.mr-t-15 {
+ margin-top: 15px;
}
\ No newline at end of file
diff --git a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.spec.ts b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.spec.ts
index b78496707..c2b80308b 100644
--- a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.spec.ts
+++ b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.spec.ts
@@ -48,48 +48,14 @@ describe("CreateEditRuleComponent (inline template)", () => {
id: 1,
name: "sync_01",
description: "",
- projects: [
- {
- project_id: 1,
- owner_id: 0,
- name: "project_01",
- creation_time: "",
- deleted: 0,
- owner_name: "",
- togglable: false,
- update_time: "",
- current_user_role_id: 0,
- repo_count: 0,
- has_project_admin_role: false,
- is_member: false,
- role_name: "",
- metadata: {
- public: "",
- enable_content_trust: "",
- prevent_vul: "",
- severity: "",
- auto_scan: ""
- }
- }
- ],
- targets: [
- {
- id: 1,
- endpoint: "https://10.117.4.151",
- name: "target_01",
- username: "admin",
- password: "",
- insecure: false,
- type: 0
- }
- ],
+ src_registry_id: 2,
+ src_namespaces: ["name1", "name2"],
trigger: {
kind: "Manual",
schedule_param: null
},
filters: [],
- replicate_existing_image_now: false,
- replicate_deletion: false
+ deletion: false
}
];
let mockJobs: ReplicationJobItem[] = [
@@ -127,39 +93,55 @@ describe("CreateEditRuleComponent (inline template)", () => {
let mockEndpoints: Endpoint[] = [
{
id: 1,
- endpoint: "https://10.117.4.151",
- name: "target_01",
- username: "admin",
- password: "",
+ credential: {
+ access_key: "admin",
+ access_secret: "",
+ type: "basic"
+ },
+ description: "test",
insecure: false,
- type: 0
+ name: "target_01",
+ type: "Harbor",
+ url: "https://10.117.4.151"
},
{
id: 2,
- endpoint: "https://10.117.5.142",
- name: "target_02",
- username: "AAA",
- password: "",
+ credential: {
+ access_key: "AAA",
+ access_secret: "",
+ type: "basic"
+ },
+ description: "test",
insecure: false,
- type: 0
+ name: "target_02",
+ type: "Harbor",
+ url: "https://10.117.5.142"
},
{
id: 3,
- endpoint: "https://101.1.11.111",
- name: "target_03",
- username: "admin",
- password: "",
+ credential: {
+ access_key: "admin",
+ access_secret: "",
+ type: "basic"
+ },
+ description: "test",
insecure: false,
- type: 0
+ name: "target_03",
+ type: "Harbor",
+ url: "https://101.1.11.111"
},
{
id: 4,
- endpoint: "http://4.4.4.4",
- name: "target_04",
- username: "",
- password: "",
+ credential: {
+ access_key: "admin",
+ access_secret: "",
+ type: "basic"
+ },
+ description: "test",
insecure: true,
- type: 0
+ name: "target_04",
+ type: "Harbor",
+ url: "https://4.4.4.4"
}
];
@@ -167,48 +149,14 @@ describe("CreateEditRuleComponent (inline template)", () => {
id: 1,
name: "sync_01",
description: "",
- projects: [
- {
- project_id: 1,
- owner_id: 0,
- name: "project_01",
- creation_time: "",
- deleted: 0,
- owner_name: "",
- togglable: false,
- update_time: "",
- current_user_role_id: 0,
- repo_count: 0,
- has_project_admin_role: false,
- is_member: false,
- role_name: "",
- metadata: {
- public: "",
- enable_content_trust: "",
- prevent_vul: "",
- severity: "",
- auto_scan: ""
- }
- }
- ],
- targets: [
- {
- id: 1,
- endpoint: "https://10.117.4.151",
- name: "target_01",
- username: "admin",
- password: "",
- insecure: false,
- type: 0
- }
- ],
+ src_namespaces: ["namespace1", "namespace2"],
+ src_registry_id: 10,
trigger: {
kind: "Manual",
schedule_param: null
},
filters: [],
- replicate_existing_image_now: false,
- replicate_deletion: false
+ deletion: false
};
let fixture: ComponentFixture
;
diff --git a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.ts b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.ts
index 912b3c0d8..d7e3e6e80 100644
--- a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.ts
+++ b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.ts
@@ -24,7 +24,7 @@ import {
import { Filter, ReplicationRule, Endpoint, Label } from "../service/interface";
import { Subject , Subscription } from "rxjs";
import {debounceTime, distinctUntilChanged} from "rxjs/operators";
-import { FormArray, FormBuilder, FormGroup, Validators } from "@angular/forms";
+import { FormArray, FormBuilder, FormGroup, Validators, FormControl } from "@angular/forms";
import { clone, compareValue, isEmptyObject, toPromise } from "../utils";
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
import { ReplicationService } from "../service/replication.service";
@@ -45,6 +45,7 @@ const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
})
export class CreateEditRuleComponent implements OnInit, OnDestroy {
_localTime: Date = new Date();
+ sourceList: Endpoint[] = [];
targetList: Endpoint[] = [];
projectList: Project[] = [];
selectedProjectList: Project[] = [];
@@ -54,22 +55,13 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
isImmediate = false;
noProjectInfo = "";
noEndpointInfo = "";
+ isPushMode = true;
noSelectedProject = true;
noSelectedEndpoint = true;
filterCount = 0;
alertClosed = false;
triggerNames: string[] = ["Manual", "Immediate", "Scheduled"];
- scheduleNames: string[] = ["Daily", "Weekly"];
- weekly: string[] = [
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday",
- "Sunday"
- ];
- filterSelect: string[] = ["repository", "tag", "label"];
+ filterSelect: string[] = ["type", "repository", "tag", "label"];
ruleNameTooltip = "REPLICATION.NAME_TOOLTIP";
headerTitle = "REPLICATION.ADD_POLICY";
@@ -87,10 +79,16 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
deletedLabelCount = 0;
deletedLabelInfo: string;
+ namespaceList: [any] = [{
+ id: 1,
+ name: "namespace1"
+ }];
+
confirmSub: Subscription;
ruleForm: FormGroup;
formArrayLabel: FormArray;
copyUpdateForm: ReplicationRule;
+ cronString: string;
@Input() projectId: number;
@Input() projectName: string;
@@ -138,23 +136,16 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
ngOnInit(): void {
if (this.withAdmiral) {
- this.filterSelect = ["repository", "tag"];
+ this.filterSelect = ["type", "repository", "tag"];
}
toPromise(this.endpointService.getEndpoints())
- .then(targets => {
- this.targetList = targets || [];
+ .then(endPoints => {
+ this.targetList = endPoints || [];
+ this.sourceList = endPoints || [];
})
.catch((error: any) => this.errorHandler.error(error));
- if (!this.projectId) {
- toPromise(this.proService.listProjects("", undefined))
- .then(targets => {
- this.projectList = targets || [];
- })
- .catch(error => this.errorHandler.error(error));
- }
-
this.nameChecker
.pipe(debounceTime(300))
.pipe(distinctUntilChanged())
@@ -182,39 +173,19 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
}
}
});
+ }
- this.proNameChecker
- .pipe(debounceTime(500))
- .pipe(distinctUntilChanged())
- .subscribe((resp: string) => {
- let name = this.ruleForm.controls["projects"].value[0].name;
- this.noProjectInfo = "";
- this.selectedProjectList = [];
- toPromise(this.proService.listProjects(name, undefined))
- .then((res: any) => {
- if (res) {
- this.selectedProjectList = res.slice(0, 10);
- // if input value exit in project list
- let pro = res.find((data: any) => data.name === name);
- if (!pro) {
- this.noProjectInfo = "REPLICATION.NO_PROJECT_INFO";
- this.noSelectedProject = true;
- } else {
- this.noProjectInfo = "";
- this.noSelectedProject = false;
- this.setProject([pro]);
- }
- } else {
- this.noProjectInfo = "REPLICATION.NO_PROJECT_INFO";
- this.noSelectedProject = true;
- }
- })
- .catch((error: any) => {
- this.errorHandler.error(error);
- this.noProjectInfo = "REPLICATION.NO_PROJECT_INFO";
- this.noSelectedProject = true;
- });
- });
+ sourceChange($event): void {
+ if ($event && $event.target) {
+ if ($event.target["value"] === "-1") {
+ this.noSelectedEndpoint = true;
+ return;
+ }
+ let selecedTarget: Endpoint = this.sourceList.find(
+ source => source.id === +$event.target["value"]
+ );
+ this.noSelectedEndpoint = false;
+ }
}
ngOnDestroy(): void {
@@ -228,11 +199,11 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
this.proNameChecker.unsubscribe();
}
}
+ get src_namespaces(): FormArray { return this.ruleForm.get('src_namespaces') as FormArray; }
get isValid() {
return !(
!this.isRuleNameValid ||
- this.noSelectedProject ||
this.noSelectedEndpoint ||
this.inProgress
);
@@ -240,23 +211,21 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
createForm() {
this.formArrayLabel = this.fb.array([]);
-
this.ruleForm = this.fb.group({
name: ["", Validators.required],
description: "",
- projects: this.fb.array([]),
- targets: this.fb.array([]),
+ src_registry_id: new FormControl(),
+ src_namespaces: new FormArray([new FormControl('')], Validators.required),
+ dest_registry_id: new FormControl(),
+ dest_namespace: "",
trigger: this.fb.group({
kind: this.triggerNames[0],
schedule_param: this.fb.group({
- type: this.scheduleNames[0],
- weekday: 1,
- offtime: "08:00"
+ cron: ""
})
}),
filters: this.fb.array([]),
- replicate_existing_image_now: true,
- replicate_deletion: false
+ deletion: false
});
}
@@ -267,33 +236,27 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
trigger: {
kind: this.triggerNames[0],
schedule_param: {
- type: this.scheduleNames[0],
- weekday: 1,
- offtime: "08:00"
+ cron: ""
}
},
- replicate_existing_image_now: true,
- replicate_deletion: false
+ deletion: false
});
- this.setProject([this.emptyProject]);
- this.setTarget([this.emptyEndpoint]);
this.setFilter([]);
this.copyUpdateForm = clone(this.ruleForm.value);
}
updateForm(rule: ReplicationRule): void {
- rule.trigger = this.updateTrigger(rule.trigger);
this.ruleForm.reset({
name: rule.name,
description: rule.description,
+ src_namespaces: rule.src_namespaces,
+ dest_namespace: rule.dest_namespace,
trigger: rule.trigger,
- replicate_existing_image_now: rule.replicate_existing_image_now,
- replicate_deletion: rule.replicate_deletion
+ deletion: rule.deletion
});
- this.setProject(rule.projects);
+
this.noSelectedProject = false;
- this.setTarget(rule.targets);
this.noSelectedEndpoint = false;
if (rule.filters) {
@@ -315,7 +278,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
let delLabel = '';
filterLabels.forEach((data: any) => {
- if (data.kind === this.filterSelect[2]) {
+ if (data.kind === this.filterSelect[3]) {
if (!data.value.deleted) {
count++;
this.filterLabelInfo.push(data.value);
@@ -337,7 +300,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
if (delLabel || count) {
let len = filterLabels.length;
for (let i = 0; i < len; i++) {
- let lab = filterLabels.find(data => data.kind === this.filterSelect[2]);
+ let lab = filterLabels.find(data => data.kind === this.filterSelect[3]);
if (lab) { filterLabels.splice(filterLabels.indexOf(lab), 1); }
}
filterLabels.push({ kind: 'label', value: count + ' labels' });
@@ -364,19 +327,12 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
this.ruleForm.setControl("filters", filterFormArray);
}
- get targets(): FormArray {
- return this.ruleForm.get("targets") as FormArray;
- }
- setTarget(targets: Endpoint[]) {
- const targetFGs = targets.map(target => this.fb.group(target));
- const targetFormArray = this.fb.array(targetFGs);
- this.ruleForm.setControl("targets", targetFormArray);
- }
+
initFilter(name: string) {
return this.fb.group({
kind: name,
- value: ['', Validators.required]
+ value: ''
});
}
@@ -398,7 +354,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
}
// if before select, $event is label
- if (!this.withAdmiral && name === this.filterSelect[2] && data.name === value) {
+ if (!this.withAdmiral && name === this.filterSelect[3] && data.name === value) {
this.labelInputVal = controlArray.controls[index].get('value').value.split(' ')[0];
data.isOpen = false;
controlArray.controls[index].get('value').setValue('');
@@ -421,7 +377,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
// when input value is label, then open label panel
openLabelList(labelTag: string, indexId: number, $event: any) {
- if (!this.withAdmiral && labelTag === this.filterSelect[2]) {
+ if (!this.withAdmiral && labelTag === this.filterSelect[3]) {
this.filterListData.forEach((data, index) => {
if (index === indexId) {
data.isOpen = true;
@@ -438,10 +394,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
this.noSelectedEndpoint = true;
return;
}
- let selecedTarget: Endpoint = this.targetList.find(
- target => target.id === +$event.target["value"]
- );
- this.setTarget([selecedTarget]);
this.noSelectedEndpoint = false;
}
}
@@ -486,6 +438,14 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
}
}
+ addNewNamespace(): void {
+ this.src_namespaces.push(new FormControl());
+ }
+
+ deleteNamespace(index: number): void {
+ this.src_namespaces.removeAt(index);
+ }
+
addNewFilter(): void {
const controlArray = this.ruleForm.get('filters');
if (this.filterCount === 0) {
@@ -513,7 +473,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
if (this.filterCount >= this.filterSelect.length) {
this.isFilterHide = true;
}
- if (controlArray.controls[this.filterCount - 1].get('kind').value === this.filterSelect[2] && this.labelInputVal) {
+ if (controlArray.controls[this.filterCount - 1].get('kind').value === this.filterSelect[3] && this.labelInputVal) {
controlArray.controls[this.filterCount - 1].get('value').setValue(this.labelInputVal + ' labels');
}
@@ -565,23 +525,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
// Replication Schedule select value exchange
selectSchedule($event: any): void {
- if ($event && $event.target && $event.target["value"]) {
- switch ($event.target["value"]) {
- case this.scheduleNames[1]:
- this.weeklySchedule = true;
- this.ruleForm.patchValue({
- trigger: {
- schedule_param: {
- weekday: 1
- }
- }
- });
- break;
- case this.scheduleNames[0]:
- this.weeklySchedule = false;
- break;
- }
- }
}
checkRuleName(): void {
@@ -634,54 +577,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
});
}
- updateTrigger(trigger: any) {
- if (trigger["schedule_param"]) {
- this.isScheduleOpt = true;
- this.isImmediate = false;
- trigger["schedule_param"]["offtime"] = this.getOfftime(
- trigger["schedule_param"]["offtime"]
- );
- if (trigger["schedule_param"]["weekday"]) {
- this.weeklySchedule = true;
- } else {
- // set default
- trigger["schedule_param"]["weekday"] = 1;
- }
- } else {
- if (trigger["kind"] === this.triggerNames[0]) {
- this.isImmediate = false;
- }
- if (trigger["kind"] === this.triggerNames[1]) {
- this.isImmediate = true;
- }
- trigger["schedule_param"] = {
- type: this.scheduleNames[0],
- weekday: this.weekly[0],
- offtime: "08:00"
- };
- }
- return trigger;
- }
-
- setTriggerVaule(trigger: any) {
- if (!this.isScheduleOpt) {
- delete trigger["schedule_param"];
- return trigger;
- } else {
- if (!this.weeklySchedule) {
- delete trigger["schedule_param"]["weekday"];
- } else {
- trigger["schedule_param"]["weekday"] = +trigger["schedule_param"][
- "weekday"
- ];
- }
- trigger["schedule_param"]["offtime"] = this.setOfftime(
- trigger["schedule_param"]["offtime"]
- );
- return trigger;
- }
- }
-
setFilterLabelVal(filters: any[]) {
let labels: any = filters.find(data => data.kind === this.filterSelect[2]);
@@ -703,7 +598,12 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
// add new Replication rule
this.inProgress = true;
let copyRuleForm: ReplicationRule = this.ruleForm.value;
- copyRuleForm.trigger = this.setTriggerVaule(copyRuleForm.trigger);
+ copyRuleForm.trigger = null;
+ if (this.isPushMode) {
+ copyRuleForm.src_registry_id = null;
+ } else {
+ copyRuleForm.dest_registry_id = null;
+ }
// rewrite key name of label when filer contain labels.
if (copyRuleForm.filters) { this.setFilterLabelVal(copyRuleForm.filters); }
@@ -787,12 +687,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
});
} else {
this.headerTitle = "REPLICATION.ADD_POLICY";
- if (this.projectId) {
- this.setProject([
- { project_id: this.projectId, name: this.projectName }
- ]);
- this.noSelectedProject = false;
- }
this.copyUpdateForm = clone(this.ruleForm.value);
}
}
@@ -820,71 +714,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
this.goToRegistry.emit();
}
- // UTC time
- public getOfftime(daily_time: any): string {
- let timeOffset = 0; // seconds
- if (daily_time && typeof daily_time === "number") {
- timeOffset = +daily_time;
- }
-
- // Convert to current time
- let timezoneOffset: number = this._localTime.getTimezoneOffset();
- // Local time
- timeOffset = timeOffset - timezoneOffset * 60;
- if (timeOffset < 0) {
- timeOffset = timeOffset + ONE_DAY_SECONDS;
- }
-
- if (timeOffset >= ONE_DAY_SECONDS) {
- timeOffset -= ONE_DAY_SECONDS;
- }
-
- // To time string
- let hours: number = Math.floor(timeOffset / ONE_HOUR_SECONDS);
- let minutes: number = Math.floor(
- (timeOffset - hours * ONE_HOUR_SECONDS) / 60
- );
-
- let timeStr: string = "" + hours;
- if (hours < 10) {
- timeStr = "0" + timeStr;
- }
- if (minutes < 10) {
- timeStr += ":0";
- } else {
- timeStr += ":";
- }
- timeStr += minutes;
-
- return timeStr;
- }
- public setOfftime(v: string) {
- if (!v || v === "") {
- return;
- }
-
- let values: string[] = v.split(":");
- if (!values || values.length !== 2) {
- return;
- }
-
- let hours: number = +values[0];
- let minutes: number = +values[1];
- // Convert to UTC time
- let timezoneOffset: number = this._localTime.getTimezoneOffset();
- let utcTimes: number = hours * ONE_HOUR_SECONDS + minutes * 60;
- utcTimes += timezoneOffset * 60;
- if (utcTimes < 0) {
- utcTimes += ONE_DAY_SECONDS;
- }
-
- if (utcTimes >= ONE_DAY_SECONDS) {
- utcTimes -= ONE_DAY_SECONDS;
- }
-
- return utcTimes;
- }
-
hasChanges(): boolean {
let formValue = clone(this.ruleForm.value);
let initValue = clone(this.copyUpdateForm);
diff --git a/src/portal/lib/src/endpoint/endpoint.component.spec.ts b/src/portal/lib/src/endpoint/endpoint.component.spec.ts
index 3cbe0feca..1c04cfbf2 100644
--- a/src/portal/lib/src/endpoint/endpoint.component.spec.ts
+++ b/src/portal/lib/src/endpoint/endpoint.component.spec.ts
@@ -24,51 +24,51 @@ describe("EndpointComponent (inline template)", () => {
let mockData: Endpoint[] = [
{
id: 1,
- endpoint: "https://10.117.4.151",
+ url: "https://10.117.4.151",
name: "target_01",
username: "admin",
password: "",
insecure: true,
- type: 0
+ type: "Harbor"
},
{
id: 2,
- endpoint: "https://10.117.5.142",
+ url: "https://10.117.5.142",
name: "target_02",
username: "AAA",
password: "",
insecure: false,
- type: 0
+ type: "Harbor"
},
{
id: 3,
- endpoint: "https://101.1.11.111",
+ url: "https://101.1.11.111",
name: "target_03",
username: "admin",
password: "",
insecure: false,
- type: 0
+ type: "Harbor"
},
{
id: 4,
- endpoint: "http://4.4.4.4",
+ url: "http://4.4.4.4",
name: "target_04",
username: "",
password: "",
insecure: false,
- type: 0
+ type: "Harbor"
}
];
let mockOne: Endpoint[] = [
{
id: 1,
- endpoint: "https://10.117.4.151",
+ url: "https://10.117.4.151",
name: "target_01",
username: "admin",
password: "",
insecure: false,
- type: 0
+ type: "Harbor"
}
];
diff --git a/src/portal/lib/src/endpoint/endpoint.component.ts b/src/portal/lib/src/endpoint/endpoint.component.ts
index fd77076ff..6c92e06cb 100644
--- a/src/portal/lib/src/endpoint/endpoint.component.ts
+++ b/src/portal/lib/src/endpoint/endpoint.component.ts
@@ -77,12 +77,12 @@ export class EndpointComponent implements OnInit, OnDestroy {
get initEndpoint(): Endpoint {
return {
- endpoint: "",
+ url: "",
name: "",
username: "",
password: "",
insecure: false,
- type: 0
+ type: ""
};
}
diff --git a/src/portal/lib/src/list-replication-rule/list-replication-rule.component.spec.ts b/src/portal/lib/src/list-replication-rule/list-replication-rule.component.spec.ts
index 32b49d198..6f11bb3d5 100644
--- a/src/portal/lib/src/list-replication-rule/list-replication-rule.component.spec.ts
+++ b/src/portal/lib/src/list-replication-rule/list-replication-rule.component.spec.ts
@@ -20,83 +20,25 @@ describe('ListReplicationRuleComponent (inline template)', () => {
let mockRules: ReplicationRule[] = [
{
"id": 1,
- "projects": [{
- "project_id": 33,
- "owner_id": 1,
- "name": "aeas",
- "deleted": 0,
- "togglable": false,
- "current_user_role_id": 0,
- "repo_count": 0,
- "metadata": {
- "public": false,
- "enable_content_trust": "",
- "prevent_vul": "",
- "severity": "",
- "auto_scan": ""},
- "owner_name": "",
- "creation_time": null,
- "update_time": null,
- "has_project_admin_role": true,
- "is_member": true,
- "role_name": ""
- }],
- "targets": [{
- "endpoint": "",
- "id": 0,
- "insecure": false,
- "name": "khans3",
- "username": "",
- "password": "",
- "type": 0,
- }],
"name": "sync_01",
"description": "",
"filters": null,
"trigger": {"kind": "Manual", "schedule_param": null},
"error_job_count": 2,
- "replicate_deletion": false,
- "replicate_existing_image_now": false,
+ "deletion": false,
+ "src_namespaces": ["name1", "name2"],
+ "src_registry_id": 3
},
{
"id": 2,
- "projects": [{
- "project_id": 33,
- "owner_id": 1,
- "name": "aeas",
- "deleted": 0,
- "togglable": false,
- "current_user_role_id": 0,
- "repo_count": 0,
- "metadata": {
- "public": false,
- "enable_content_trust": "",
- "prevent_vul": "",
- "severity": "",
- "auto_scan": ""},
- "owner_name": "",
- "creation_time": null,
- "update_time": null,
- "has_project_admin_role": true,
- "is_member": true,
- "role_name": ""
- }],
- "targets": [{
- "endpoint": "",
- "id": 0,
- "insecure": false,
- "name": "khans3",
- "username": "",
- "password": "",
- "type": 0,
- }],
"name": "sync_02",
"description": "",
"filters": null,
"trigger": {"kind": "Manual", "schedule_param": null},
"error_job_count": 2,
- "replicate_deletion": false,
- "replicate_existing_image_now": false,
+ "deletion": false,
+ "src_namespaces": ["name1", "name2"],
+ "dest_registry_id": 3
},
];
diff --git a/src/portal/lib/src/replication/replication.component.spec.ts b/src/portal/lib/src/replication/replication.component.spec.ts
index 25a32bbfd..f185cd044 100644
--- a/src/portal/lib/src/replication/replication.component.spec.ts
+++ b/src/portal/lib/src/replication/replication.component.spec.ts
@@ -29,83 +29,25 @@ describe('Replication Component (inline template)', () => {
let mockRules: ReplicationRule[] = [
{
"id": 1,
- "projects": [{
- "project_id": 33,
- "owner_id": 1,
- "name": "aeas",
- "deleted": 0,
- "togglable": false,
- "current_user_role_id": 0,
- "repo_count": 0,
- "metadata": {
- "public": false,
- "enable_content_trust": "",
- "prevent_vul": "",
- "severity": "",
- "auto_scan": ""},
- "owner_name": "",
- "creation_time": null,
- "update_time": null,
- "has_project_admin_role": true,
- "is_member": true,
- "role_name": ""
- }],
- "targets": [{
- "id": 1,
- "endpoint": "https://10.117.4.151",
- "name": "target_01",
- "username": "admin",
- "password": "",
- "insecure": false,
- "type": 0
- }],
"name": "sync_01",
"description": "",
"filters": null,
"trigger": {"kind": "Manual", "schedule_param": null},
"error_job_count": 2,
- "replicate_deletion": false,
- "replicate_existing_image_now": false,
+ "deletion": false,
+ "src_registry_id": 3,
+ "src_namespaces": ["name1"]
},
{
"id": 2,
- "projects": [{
- "project_id": 33,
- "owner_id": 1,
- "name": "aeas",
- "deleted": 0,
- "togglable": false,
- "current_user_role_id": 0,
- "repo_count": 0,
- "metadata": {
- "public": false,
- "enable_content_trust": "",
- "prevent_vul": "",
- "severity": "",
- "auto_scan": ""},
- "owner_name": "",
- "creation_time": null,
- "update_time": null,
- "has_project_admin_role": true,
- "is_member": true,
- "role_name": ""
- }],
- "targets": [{
- "id": 1,
- "endpoint": "https://10.117.4.151",
- "name": "target_01",
- "username": "admin",
- "password": "",
- "insecure": false,
- "type": 0
- }],
"name": "sync_02",
"description": "",
"filters": null,
"trigger": {"kind": "Manual", "schedule_param": null},
"error_job_count": 2,
- "replicate_deletion": false,
- "replicate_existing_image_now": false,
+ "deletion": false,
+ "dest_registry_id": 5,
+ "src_namespaces": ["name1"]
}
];
@@ -142,47 +84,24 @@ describe('Replication Component (inline template)', () => {
let mockEndpoints: Endpoint[] = [
{
"id": 1,
- "endpoint": "https://10.117.4.151",
+ "url": "https://10.117.4.151",
"name": "target_01",
"username": "admin",
"password": "",
"insecure": false,
- "type": 0
+ "type": "Harbor"
},
{
"id": 2,
- "endpoint": "https://10.117.5.142",
+ "url": "https://10.117.5.142",
"name": "target_02",
"username": "AAA",
"password": "",
"insecure": false,
- "type": 0
+ "type": "Harbor"
},
];
- // let mockProjects: Project[] = [
- // { "project_id": 1,
- // "owner_id": 0,
- // "name": 'project_01',
- // "creation_time": '',
- // "deleted": 0,
- // "owner_name": '',
- // "togglable": false,
- // "update_time": '',
- // "current_user_role_id": 0,
- // "repo_count": 0,
- // "has_project_admin_role": false,
- // "is_member": false,
- // "role_name": '',
- // "metadata": {
- // "public": '',
- // "enable_content_trust": '',
- // "prevent_vul": '',
- // "severity": '',
- // "auto_scan": '',
- // }
- // }];
-
let mockJob: ReplicationJob = {
metadata: {xTotalCount: 3},
data: mockJobs
diff --git a/src/portal/lib/src/service/interface.ts b/src/portal/lib/src/service/interface.ts
index eb1fc802c..bf9e56bc0 100644
--- a/src/portal/lib/src/service/interface.ts
+++ b/src/portal/lib/src/service/interface.ts
@@ -75,12 +75,12 @@ export interface Tag extends Base {
* extends {Base}
*/
export interface Endpoint extends Base {
- endpoint: string;
+ url: string;
name: string;
username?: string;
password?: string;
insecure: boolean;
- type: number;
+ type: string;
[key: string]: any;
}
@@ -97,24 +97,13 @@ export interface ReplicationRule extends Base {
id?: number;
name: string;
description: string;
- projects: Project[];
- targets: Endpoint[];
trigger: Trigger;
filters: Filter[];
- replicate_existing_image_now?: boolean;
- replicate_deletion?: boolean;
- // id?: number;
- // name: string;
- // description: string;
- // src_registry_id: number;
- // src_namespaces: [];
- // dest_registry_id: number;
- // dest_namespace: string;
- // trigger: Trigger;
- // filter: Filter[];
- // deletion: boolean;
- // override: boolean;
- // enabled: boolean;
+ deletion?: boolean;
+ src_registry_id?: number;
+ dest_registry_id?: number;
+ src_namespaces: string [];
+ dest_namespace?: string;
}
export class Filter {
diff --git a/src/portal/lib/src/service/replication.service.ts b/src/portal/lib/src/service/replication.service.ts
index 9303d9354..cf5547da1 100644
--- a/src/portal/lib/src/service/replication.service.ts
+++ b/src/portal/lib/src/service/replication.service.ts
@@ -216,7 +216,8 @@ export class ReplicationDefaultService extends ReplicationService {
rule != null &&
rule.name !== undefined &&
rule.name.trim() !== "" &&
- rule.targets.length !== 0
+ rule.src_namespaces && rule.src_namespaces.length > 0 &&
+ (!!rule.dest_registry_id || !! rule.src_registry_id)
);
}
diff --git a/src/portal/src/i18n/lang/en-us-lang.json b/src/portal/src/i18n/lang/en-us-lang.json
index 4eafd0c3f..5ee287542 100644
--- a/src/portal/src/i18n/lang/en-us-lang.json
+++ b/src/portal/src/i18n/lang/en-us-lang.json
@@ -447,7 +447,12 @@
"NAME_TOOLTIP": "replication rule name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
"DELETED_LABEL_INFO": "Deleted label(s) '{{param}}' referenced in the filter, click 'SAVE' to update the filter to enable this rule.",
"ACKNOWLEDGE": "Acknowledge",
- "RULE_DISABLED": "This rule has been disabled because a label used in its filter has been deleted. \n Edit the rule and update its filter to enable it."
+ "RULE_DISABLED": "This rule has been disabled because a label used in its filter has been deleted. \n Edit the rule and update its filter to enable it.",
+ "REPLI_MODE": "Replication mode",
+ "SOURCE_REGISTRY":"Source registry",
+ "SOURCE_NAMESPACES":"Source namespaces",
+ "DEST_REGISTRY":"Destination registry",
+ "DEST_NAMESPACE":"Destination namespace"
},
"DESTINATION": {
"NEW_ENDPOINT": "New Endpoint",
diff --git a/src/portal/src/i18n/lang/es-es-lang.json b/src/portal/src/i18n/lang/es-es-lang.json
index a789b0b43..c1a0f62b9 100644
--- a/src/portal/src/i18n/lang/es-es-lang.json
+++ b/src/portal/src/i18n/lang/es-es-lang.json
@@ -448,7 +448,12 @@
"NAME_TOOLTIP": "replication rule name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
"DELETED_LABEL_INFO": "Deleted label(s) '{{param}}' referenced in the filter, click 'SAVE' to update the filter to enable this rule.",
"ACKNOWLEDGE": "Acknowledge",
- "RULE_DISABLED": "This rule has been disabled because a label used in its filter has been deleted. \n Edit the rule and update its filter to enable it."
+ "RULE_DISABLED": "This rule has been disabled because a label used in its filter has been deleted. \n Edit the rule and update its filter to enable it.",
+ "REPLI_MODE": "Replication mode",
+ "SOURCE_REGISTRY":"Source registry",
+ "SOURCE_NAMESPACES":"Source namespaces",
+ "DEST_REGISTRY":"Destination registry",
+ "DEST_NAMESPACE":"Destination namespace"
},
"DESTINATION": {
"NEW_ENDPOINT": "Nuevo Endpoint",
diff --git a/src/portal/src/i18n/lang/fr-fr-lang.json b/src/portal/src/i18n/lang/fr-fr-lang.json
index bcc7ecf0d..96ceb436d 100644
--- a/src/portal/src/i18n/lang/fr-fr-lang.json
+++ b/src/portal/src/i18n/lang/fr-fr-lang.json
@@ -429,7 +429,12 @@
"NAME_TOOLTIP": "replication rule name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
"DELETED_LABEL_INFO": "Deleted label(s) '{{param}}' referenced in the filter, click 'SAVE' to update the filter to enable this rule.",
"ACKNOWLEDGE": "Acknowledge",
- "RULE_DISABLED": "This rule has been disabled because a label used in its filter has been deleted. \n Edit the rule and update its filter to enable it."
+ "RULE_DISABLED": "This rule has been disabled because a label used in its filter has been deleted. \n Edit the rule and update its filter to enable it.",
+ "REPLI_MODE": "Replication mode",
+ "SOURCE_REGISTRY":"Source registry",
+ "SOURCE_NAMESPACES":"Source namespaces",
+ "DEST_REGISTRY":"Destination registry",
+ "DEST_NAMESPACE":"Destination namespace"
},
"DESTINATION": {
"NEW_ENDPOINT": "Nouveau Point Final",
diff --git a/src/portal/src/i18n/lang/pt-br-lang.json b/src/portal/src/i18n/lang/pt-br-lang.json
index f1fc885f2..abd21cccc 100644
--- a/src/portal/src/i18n/lang/pt-br-lang.json
+++ b/src/portal/src/i18n/lang/pt-br-lang.json
@@ -447,7 +447,12 @@
"NAME_TOOLTIP": "nome da regra de replicação deve conter ao menos 2 caracteres sendo caracteres minusculos, números e ._- e devem iniciar com letras e números.",
"DELETED_LABEL_INFO": "Removidas as label(s) '{{param}}' referenciadas no filtro, clique 'SALVAR' para atualizar o filtro e habilitar essa regra.",
"ACKNOWLEDGE": "Reconhecer",
- "RULE_DISABLED": "Essa regra foi desabilitada pois uma label usada no seu filtro foi removida. \n Edite a regra e atualize seu filtro para habilitá-la."
+ "RULE_DISABLED": "Essa regra foi desabilitada pois uma label usada no seu filtro foi removida. \n Edite a regra e atualize seu filtro para habilitá-la.",
+ "REPLI_MODE": "Replication mode",
+ "SOURCE_REGISTRY":"Source registry",
+ "SOURCE_NAMESPACES":"Source namespaces",
+ "DEST_REGISTRY":"Destination registry",
+ "DEST_NAMESPACE":"Destination namespace"
},
"DESTINATION": {
"NEW_ENDPOINT": "Novo Endpoint",
diff --git a/src/portal/src/i18n/lang/zh-cn-lang.json b/src/portal/src/i18n/lang/zh-cn-lang.json
index 18a784fc0..10a46a7a2 100644
--- a/src/portal/src/i18n/lang/zh-cn-lang.json
+++ b/src/portal/src/i18n/lang/zh-cn-lang.json
@@ -448,7 +448,12 @@
"NAME_TOOLTIP": "项目名称由小写字符、数字和._-组成且至少2个字符并以字符或者数字开头。",
"DELETED_LABEL_INFO": "过滤项有被删除的标签 {{param}} , 点击保存按钮更新过滤项使规则可用。",
"ACKNOWLEDGE": "确认",
- "RULE_DISABLED": "这个规则因为过滤选项中的标签被删除已经不能用了,更新过滤项以便重新启用规则。"
+ "RULE_DISABLED": "这个规则因为过滤选项中的标签被删除已经不能用了,更新过滤项以便重新启用规则。",
+ "REPLI_MODE": "复制模式",
+ "SOURCE_REGISTRY":"源Registry",
+ "SOURCE_NAMESPACES":"源Namespace",
+ "DEST_REGISTRY":"目的Registry",
+ "DEST_NAMESPACE":"目的Namespace"
},
"DESTINATION": {
"NEW_ENDPOINT": "新建目标",