Merge pull request #8834 from AllForNothing/tag-imp

Improvement for rule validator of tag-retention
This commit is contained in:
Will Sun 2019-08-27 10:45:10 +08:00 committed by GitHub
commit c4baa75c9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 109 additions and 17 deletions

View File

@ -3,6 +3,7 @@
<h3 class="modal-title" *ngIf="isAdd">{{'TAG_RETENTION.ADD_TITLE' | translate}}</h3>
<h3 class="modal-title" *ngIf="!isAdd">{{'TAG_RETENTION.EDIT_TITLE' | translate}}</h3>
<div class="modal-body no-scrolling">
<inline-alert class="modal-title"></inline-alert>
<p class="color-97">{{'TAG_RETENTION.ADD_SUBTITLE' | translate}}</p>
<div class="height-72">
<div class="clr-row mt-1">
@ -40,6 +41,7 @@
<div class="over-line"></div>
<div class="clr-select-wrapper w-100">
<select [(ngModel)]="template" class="clr-select w-100">
<option class="display-none" value=""></option>
<option *ngFor="let t of metadata?.templates"
value="{{t?.rule_template}}">{{getI18nKey(t?.action)|translate}}{{getI18nKey(t?.display_text)|translate}}</option>
</select>

View File

@ -10,4 +10,8 @@
.height-72 {
height: 72px;
}
.display-none {
display: none
}

View File

@ -16,12 +16,17 @@ import {
OnInit,
OnDestroy,
Output,
EventEmitter,
EventEmitter, ViewChild, Input,
} from "@angular/core";
import { Rule, RuleMetadate } from "../retention";
import { Retention, Rule, RuleMetadate } from "../retention";
import { compareValue } from "@harbor/ui";
import { TagRetentionService } from "../tag-retention.service";
import { InlineAlertComponent } from "../../../shared/inline-alert/inline-alert.component";
const EXISTING_RULE = "TAG_RETENTION.EXISTING_RULE";
const ILLEGAL_RULE = "TAG_RETENTION.ILLEGAL_RULE";
const INVALID_RULE = "TAG_RETENTION.INVALID_RULE";
const MAX = 2100000000;
@Component({
selector: "add-rule",
templateUrl: "./add-rule.component.html",
@ -30,11 +35,13 @@ import { TagRetentionService } from "../tag-retention.service";
export class AddRuleComponent implements OnInit, OnDestroy {
addRuleOpened: boolean = false;
@Output() clickAdd = new EventEmitter<Rule>();
@Input() retention: Retention;
metadata: RuleMetadate = new RuleMetadate();
rule: Rule = new Rule();
isAdd: boolean = true;
editRuleOrigin: Rule;
onGoing: boolean = false;
@ViewChild(InlineAlertComponent) inlineAlert: InlineAlertComponent;
constructor(private tagRetentionService: TagRetentionService) {
}
@ -134,24 +141,33 @@ export class AddRuleComponent implements OnInit, OnDestroy {
}
canNotAdd(): boolean {
if (this.onGoing) {
return true;
}
if (!this.isAdd && compareValue(this.editRuleOrigin, this.rule)) {
return true;
}
if (!this.hasParam()) {
return !(this.rule.template
&& this.rule.scope_selectors.repository[0].pattern
&& this.rule.tag_selectors[0].pattern);
&& this.rule.scope_selectors.repository[0].pattern.replace(/[{}]/g, "")
&& this.rule.tag_selectors[0].pattern
&& this.rule.tag_selectors[0].pattern.replace(/[{}]/g, ""));
} else {
return !(this.rule.template
&& this.rule.params[this.template]
&& parseInt(this.rule.params[this.template], 10) >= 0
&& this.rule.scope_selectors.repository[0].pattern
&& this.rule.tag_selectors[0].pattern);
&& this.rule.scope_selectors.repository[0].pattern.replace(/[{}]/g, "")
&& this.rule.tag_selectors[0].pattern
&& this.rule.tag_selectors[0].pattern.replace(/[{}]/g, ""));
}
}
open() {
this.addRuleOpened = true;
this.inlineAlert.alertClose = true;
this.onGoing = false;
}
close() {
@ -163,9 +179,50 @@ export class AddRuleComponent implements OnInit, OnDestroy {
}
add() {
this.close();
if (this.rule.scope_selectors.repository[0].decoration !== "repoMatches"
&& this.rule.scope_selectors.repository[0].pattern.indexOf("**") !== -1) {
this.inlineAlert.showInlineError(INVALID_RULE);
return;
}
if (this.hasParam()
&& (this.rule.params[this.template] <= 0 || this.rule.params[this.template] > MAX)) {
this.inlineAlert.showInlineError(ILLEGAL_RULE);
return;
}
if (this.isExistingRule()) {
this.inlineAlert.showInlineError(EXISTING_RULE);
return;
}
this.clickAdd.emit(this.rule);
}
isExistingRule(): boolean {
if (this.retention && this.retention.rules && this.retention.rules.length > 0) {
for (let i = 0; i < this.retention.rules.length; i++) {
if (this.isSameRule(this.retention.rules[i])) {
return true;
}
}
}
return false;
}
isSameRule(rule: Rule): boolean {
if (this.rule.scope_selectors.repository[0].decoration !== rule.scope_selectors.repository[0].decoration) {
return false;
}
if (this.rule.scope_selectors.repository[0].pattern !== rule.scope_selectors.repository[0].pattern) {
return false;
}
if (this.rule.template !== rule.template) {
return false;
}
if (this.hasParam() && JSON.stringify(this.rule.params) !== JSON.stringify(rule.params)) {
return false;
}
if (this.rule.tag_selectors[0].decoration !== rule.tag_selectors[0].decoration) {
return false;
}
return this.rule.tag_selectors[0].pattern === rule.tag_selectors[0].pattern;
}
getI18nKey(str: string) {
return this.tagRetentionService.getI18nKey(str);

View File

@ -158,7 +158,7 @@
</clr-datagrid>
</div>
</div>
<add-rule #addRule (clickAdd)="clickAdd($event)"></add-rule>
<add-rule #addRule [retention]="retention" (clickAdd)="clickAdd($event)"></add-rule>
<clr-modal [(clrModalOpen)]="isRetentionRunOpened"
[clrModalStaticBackdrop]="true" [clrModalClosable]="true">
<h3 class="modal-title">{{'TAG_RETENTION.RETENTION_RUN' | translate}}</h3>

View File

@ -342,6 +342,7 @@ export class TagRetentionComponent implements OnInit {
clickAdd(rule) {
this.loadingRule = true;
this.addRuleComponent.onGoing = true;
if (this.addRuleComponent.isAdd) {
let retention: Retention = clone(this.retention);
retention.rules.push(rule);
@ -349,17 +350,23 @@ export class TagRetentionComponent implements OnInit {
this.tagRetentionService.createRetention(retention).subscribe(
response => {
this.refreshAfterCreatRetention();
this.addRuleComponent.close();
this.addRuleComponent.onGoing = false;
}, error => {
this.errorHandler.error(error);
this.addRuleComponent.inlineAlert.showInlineError(error);
this.loadingRule = false;
this.addRuleComponent.onGoing = false;
});
} else {
this.tagRetentionService.updateRetention(this.retentionId, retention).subscribe(
response => {
this.getRetention();
this.addRuleComponent.close();
this.addRuleComponent.onGoing = false;
}, error => {
this.loadingRule = false;
this.errorHandler.error(error);
this.addRuleComponent.onGoing = false;
this.addRuleComponent.inlineAlert.showInlineError(error);
});
}
} else {
@ -368,9 +375,12 @@ export class TagRetentionComponent implements OnInit {
this.tagRetentionService.updateRetention(this.retentionId, retention).subscribe(
response => {
this.getRetention();
this.addRuleComponent.close();
this.addRuleComponent.onGoing = false;
}, error => {
this.errorHandler.error(error);
this.addRuleComponent.inlineAlert.showInlineError(error);
this.loadingRule = false;
this.addRuleComponent.onGoing = false;
});
}
}

View File

@ -1210,7 +1210,10 @@
"RULE_TEMPLATE_6": " the images pulled within the last # days",
"RULE_TEMPLATE_7": " the images pushed within the last # days",
"SCHEDULE": "Schedule",
"SCHEDULE_WARNING": "Executing the retention policy can have adverse effects to the images in this project and affected image tags will be deleted."
"SCHEDULE_WARNING": "Executing the retention policy can have adverse effects to the images in this project and affected image tags will be deleted.",
"EXISTING_RULE": "Existing rule",
"ILLEGAL_RULE": "Illegal rule",
"INVALID_RULE": "Invalid rule"
}
}

View File

@ -1207,7 +1207,10 @@
"RULE_TEMPLATE_6": " the images pulled within the last # days",
"RULE_TEMPLATE_7": " the images pushed within the last # days",
"SCHEDULE": "Schedule",
"SCHEDULE_WARNING": "Executing the retention policy can have adverse effects to the images in this project and affected image tags will be deleted."
"SCHEDULE_WARNING": "Executing the retention policy can have adverse effects to the images in this project and affected image tags will be deleted.",
"EXISTING_RULE": "Existing rule",
"ILLEGAL_RULE": "Illegal rule",
"INVALID_RULE": "Invalid rule"
}
}

View File

@ -1179,7 +1179,10 @@
"RULE_TEMPLATE_6": " the images pulled within the last # days",
"RULE_TEMPLATE_7": " the images pushed within the last # days",
"SCHEDULE": "Schedule",
"SCHEDULE_WARNING": "Executing the retention policy can have adverse effects to the images in this project and affected image tags will be deleted."
"SCHEDULE_WARNING": "Executing the retention policy can have adverse effects to the images in this project and affected image tags will be deleted.",
"EXISTING_RULE": "Existing rule",
"ILLEGAL_RULE": "Illegal rule",
"INVALID_RULE": "Invalid rule"
}
}

View File

@ -1204,7 +1204,10 @@
"RULE_TEMPLATE_6": " the images pulled within the last # days",
"RULE_TEMPLATE_7": " the images pushed within the last # days",
"SCHEDULE": "Schedule",
"SCHEDULE_WARNING": "Executing the retention policy can have adverse effects to the images in this project and affected image tags will be deleted."
"SCHEDULE_WARNING": "Executing the retention policy can have adverse effects to the images in this project and affected image tags will be deleted.",
"EXISTING_RULE": "Existing rule",
"ILLEGAL_RULE": "Illegal rule",
"INVALID_RULE": "Invalid rule"
}

View File

@ -1210,7 +1210,10 @@
"RULE_TEMPLATE_6": " imajlar son # gün içinde imdirilmiş",
"RULE_TEMPLATE_7": " imajlar son # gün içinde yüklendi.",
"SCHEDULE": "Program",
"SCHEDULE_WARNING": "Tutma ilkesinin yürütülmesinin bu projedeki görüntüler üzerinde olumsuz etkileri olabilir ve etkilenen imajların etiketleri silinecektir."
"SCHEDULE_WARNING": "Tutma ilkesinin yürütülmesinin bu projedeki görüntüler üzerinde olumsuz etkileri olabilir ve etkilenen imajların etiketleri silinecektir.",
"EXISTING_RULE": "Existing rule",
"ILLEGAL_RULE": "Illegal rule",
"INVALID_RULE": "Invalid rule"
}
}

View File

@ -804,7 +804,8 @@
"ROOT_CERT_DOWNLOAD": "下载镜像库根证书。",
"SCANNING_POLICY": "基于不同需求设置镜像扫描策略。‘无’:不设置任何策略;‘每日定时’:每天在设置的时间定时执行扫描。",
"VERIFY_CERT": "检查来自LDAP服务端的证书",
"REPO_TOOLTIP": "用户在此模式下无法对镜像执行任何操作。",
"READONLY_TOOLTIP": "选中,表示正在维护状态,不可删除仓库及标签,也不可以推送镜像。",
"REPO_TOOLTIP": "用户在此模式下无法对图像执行任何操作。",
"WEBHOOK_TOOLTIP": "当执行推送,拉动,删除,扫描图像或图表等特定操作时,启用 webhooks 以在指定端点接收回调",
"HOURLY_CRON":"每小时运行一次。相当于 0 0 * * * *",
"WEEKLY_CRON":"每周一次,周六/周日午夜之间开始。相当于 0 0 * * * *",
@ -1205,7 +1206,10 @@
"RULE_TEMPLATE_6": "最近#天被拉取过的镜像",
"RULE_TEMPLATE_7": "最近#天被推送过的镜像",
"SCHEDULE": "定时任务",
"SCHEDULE_WARNING": "执行保留策略将对该项目中的镜像产生反向影响受影响的镜像tags将会被删除。"
"SCHEDULE_WARNING": "执行保留策略将对该项目中的镜像产生反向影响受影响的镜像tags将会被删除。",
"EXISTING_RULE": "规则已存在",
"ILLEGAL_RULE": "规则不合法",
"INVALID_RULE": "无效规则"
}
}