mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-14 22:35:36 +01:00
Merge branch 'master' into fix_typo
This commit is contained in:
commit
bc30341a76
@ -1,9 +1,6 @@
|
|||||||
appname = registry
|
appname = Harbor
|
||||||
runmode = dev
|
runmode = dev
|
||||||
|
enablegzip = true
|
||||||
[lang]
|
|
||||||
types = en-US|zh-CN
|
|
||||||
names = en-US|zh-CN
|
|
||||||
|
|
||||||
[dev]
|
[dev]
|
||||||
httpport = 80
|
httpport = 80
|
@ -48,7 +48,7 @@ services:
|
|||||||
- ../common/config/adminserver/env
|
- ../common/config/adminserver/env
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- /data/config/:/etc/adminserver/
|
- /data/config/:/etc/adminserver/config/
|
||||||
- /data/secretkey:/etc/adminserver/key
|
- /data/secretkey:/etc/adminserver/key
|
||||||
- /data/:/data/
|
- /data/:/data/
|
||||||
depends_on:
|
depends_on:
|
||||||
|
@ -54,9 +54,9 @@ services:
|
|||||||
- ./common/config/adminserver/env
|
- ./common/config/adminserver/env
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- /data/config/:/etc/adminserver/
|
- /data/config/:/etc/adminserver/config/:z
|
||||||
- /data/secretkey:/etc/adminserver/key
|
- /data/secretkey:/etc/adminserver/key:z
|
||||||
- /data/:/data/
|
- /data/:/data/:z
|
||||||
networks:
|
networks:
|
||||||
- harbor
|
- harbor
|
||||||
depends_on:
|
depends_on:
|
||||||
|
@ -31,7 +31,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultJSONCfgStorePath string = "/etc/adminserver/config.json"
|
defaultJSONCfgStorePath string = "/etc/adminserver/config/config.json"
|
||||||
defaultKeyPath string = "/etc/adminserver/key"
|
defaultKeyPath string = "/etc/adminserver/key"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -58,7 +58,8 @@ func DeleteProjectMember(projectID int64, userID int) error {
|
|||||||
func GetUserByProject(projectID int64, queryUser models.User) ([]models.User, error) {
|
func GetUserByProject(projectID int64, queryUser models.User) ([]models.User, error) {
|
||||||
o := GetOrmer()
|
o := GetOrmer()
|
||||||
u := []models.User{}
|
u := []models.User{}
|
||||||
sql := `select u.user_id, u.username, r.name rolename, r.role_id as role
|
sql := `select u.user_id, u.username, u.creation_time, u.update_time, r.name as rolename,
|
||||||
|
r.role_id as role
|
||||||
from user u
|
from user u
|
||||||
join project_member pm
|
join project_member pm
|
||||||
on pm.project_id = ? and u.user_id = pm.user_id
|
on pm.project_id = ? and u.user_id = pm.user_id
|
||||||
@ -73,7 +74,7 @@ func GetUserByProject(projectID int64, queryUser models.User) ([]models.User, er
|
|||||||
sql += " and u.username like ? "
|
sql += " and u.username like ? "
|
||||||
queryParam = append(queryParam, "%"+escape(queryUser.Username)+"%")
|
queryParam = append(queryParam, "%"+escape(queryUser.Username)+"%")
|
||||||
}
|
}
|
||||||
sql += ` order by u.user_id `
|
sql += ` order by u.username `
|
||||||
_, err := o.Raw(sql, queryParam).QueryRows(&u)
|
_, err := o.Raw(sql, queryParam).QueryRows(&u)
|
||||||
return u, err
|
return u, err
|
||||||
}
|
}
|
||||||
|
@ -147,17 +147,7 @@ func (t *TargetAPI) Get() {
|
|||||||
t.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound))
|
t.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound))
|
||||||
}
|
}
|
||||||
|
|
||||||
// The reason why the password is returned is that when user just wants to
|
target.Password = ""
|
||||||
// modify other fields of target he does not need to input the password again.
|
|
||||||
// The security issue can be fixed by enable https.
|
|
||||||
if len(target.Password) != 0 {
|
|
||||||
pwd, err := utils.ReversibleDecrypt(target.Password, t.secretKey)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("failed to decrypt password: %v", err)
|
|
||||||
t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
|
||||||
}
|
|
||||||
target.Password = pwd
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Data["json"] = target
|
t.Data["json"] = target
|
||||||
t.ServeJSON()
|
t.ServeJSON()
|
||||||
@ -173,16 +163,7 @@ func (t *TargetAPI) List() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, target := range targets {
|
for _, target := range targets {
|
||||||
if len(target.Password) == 0 {
|
target.Password = ""
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
str, err := utils.ReversibleDecrypt(target.Password, t.secretKey)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("failed to decrypt password: %v", err)
|
|
||||||
t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
|
||||||
}
|
|
||||||
target.Password = str
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Data["json"] = targets
|
t.Data["json"] = targets
|
||||||
|
@ -158,7 +158,7 @@ func (cc *CommonController) SendEmail() {
|
|||||||
60, settings.SSL,
|
60, settings.SSL,
|
||||||
false, settings.From,
|
false, settings.From,
|
||||||
[]string{email},
|
[]string{email},
|
||||||
cc.Tr("reset_email_subject"),
|
"Reset Harbor user password",
|
||||||
message.String())
|
message.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Send email failed: %v", err)
|
log.Errorf("Send email failed: %v", err)
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
required
|
required
|
||||||
email
|
email
|
||||||
id="reset_pwd_email"
|
id="reset_pwd_email"
|
||||||
size="40"
|
size="30"
|
||||||
(input)="handleValidation(true)"
|
(input)="handleValidation(true)"
|
||||||
(blur)="handleValidation(false)">
|
(blur)="handleValidation(false)">
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
required
|
required
|
||||||
name="oldPassword"
|
name="oldPassword"
|
||||||
[(ngModel)]="oldPwd"
|
[(ngModel)]="oldPwd"
|
||||||
#oldPassInput="ngModel" size="42">
|
#oldPassInput="ngModel" size="30">
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
{{'TOOLTIP.CURRENT_PWD' | translate}}
|
{{'TOOLTIP.CURRENT_PWD' | translate}}
|
||||||
</span>
|
</span>
|
||||||
@ -25,7 +25,7 @@
|
|||||||
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
||||||
name="newPassword"
|
name="newPassword"
|
||||||
[(ngModel)]="newPwd"
|
[(ngModel)]="newPwd"
|
||||||
#newPassInput="ngModel" size="42"
|
#newPassInput="ngModel" size="30"
|
||||||
(input)='handleValidation("newPassword", false)'
|
(input)='handleValidation("newPassword", false)'
|
||||||
(blur)='handleValidation("newPassword", true)'>
|
(blur)='handleValidation("newPassword", true)'>
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
@ -42,7 +42,7 @@
|
|||||||
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
||||||
name="reNewPassword"
|
name="reNewPassword"
|
||||||
[(ngModel)]="reNewPwd"
|
[(ngModel)]="reNewPwd"
|
||||||
#reNewPassInput="ngModel" size="42"
|
#reNewPassInput="ngModel" size="30"
|
||||||
(input)='handleValidation("reNewPassword", false)'
|
(input)='handleValidation("reNewPassword", false)'
|
||||||
(blur)='handleValidation("reNewPassword", true)'>
|
(blur)='handleValidation("reNewPassword", true)'>
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_name" class="col-md-4 form-group-label-override">{{ 'DESTINATION.NAME' | translate }}<span style="color: red">*</span></label>
|
<label for="destination_name" class="col-md-4 form-group-label-override">{{ 'DESTINATION.NAME' | translate }}<span style="color: red">*</span></label>
|
||||||
<label class="col-md-8" for="destination_name" aria-haspopup="true" role="tooltip" [class.invalid]="targetName.errors && (targetName.dirty || targetName.touched)" [class.valid]="targetName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
<label class="col-md-8" for="destination_name" aria-haspopup="true" role="tooltip" [class.invalid]="targetName.errors && (targetName.dirty || targetName.touched)" [class.valid]="targetName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
||||||
<input type="text" id="destination_name" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.name" name="targetName" size="20" #targetName="ngModel" value="" required>
|
<input type="text" id="destination_name" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.name" name="targetName" size="20" #targetName="ngModel" required (keyup)="clearPassword($event)">
|
||||||
<span class="tooltip-content" *ngIf="targetName.errors && targetName.errors.required && (targetName.dirty || targetName.touched)">
|
<span class="tooltip-content" *ngIf="targetName.errors && targetName.errors.required && (targetName.dirty || targetName.touched)">
|
||||||
{{ 'DESTINATION.NAME_IS_REQUIRED' | translate }}
|
{{ 'DESTINATION.NAME_IS_REQUIRED' | translate }}
|
||||||
</span>
|
</span>
|
||||||
@ -23,7 +23,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_url" class="col-md-4 form-group-label-override">{{ 'DESTINATION.URL' | translate }}<span style="color: red">*</span></label>
|
<label for="destination_url" class="col-md-4 form-group-label-override">{{ 'DESTINATION.URL' | translate }}<span style="color: red">*</span></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">
|
<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" size="20" name="endpointUrl" #targetEndpoint="ngModel" required>
|
<input type="text" id="destination_url" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.endpoint" size="20" name="endpointUrl" #targetEndpoint="ngModel" required (keyup)="clearPassword($event)">
|
||||||
<span class="tooltip-content" *ngIf="targetEndpoint.errors && targetEndpoint.errors.required && (targetEndpoint.dirty || targetEndpoint.touched)">
|
<span class="tooltip-content" *ngIf="targetEndpoint.errors && targetEndpoint.errors.required && (targetEndpoint.dirty || targetEndpoint.touched)">
|
||||||
{{ 'DESTINATION.URL_IS_REQUIRED' | translate }}
|
{{ 'DESTINATION.URL_IS_REQUIRED' | translate }}
|
||||||
</span>
|
</span>
|
||||||
@ -31,11 +31,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_username" class="col-md-4 form-group-label-override">{{ 'DESTINATION.USERNAME' | translate }}</label>
|
<label for="destination_username" class="col-md-4 form-group-label-override">{{ 'DESTINATION.USERNAME' | 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" class="col-md-8" id="destination_username" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.username" size="20" name="username" #username="ngModel" (keyup)="clearPassword($event)">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="destination_password" class="col-md-4 form-group-label-override">{{ 'DESTINATION.PASSWORD' | translate }}</label>
|
<label for="destination_password" class="col-md-4 form-group-label-override">{{ 'DESTINATION.PASSWORD' | 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" class="col-md-8" id="destination_password" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.password" size="20" name="password" #password="ngModel" (focus)="clearPassword($event)">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="spin" class="col-md-4"></label>
|
<label for="spin" class="col-md-4"></label>
|
||||||
|
@ -11,6 +11,8 @@ import { Target } from '../target';
|
|||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
const FAKE_PASSWORD = 'rjGcfuRu';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'create-edit-destination',
|
selector: 'create-edit-destination',
|
||||||
templateUrl: './create-edit-destination.component.html',
|
templateUrl: './create-edit-destination.component.html',
|
||||||
@ -42,6 +44,8 @@ export class CreateEditDestinationComponent implements AfterViewChecked {
|
|||||||
|
|
||||||
hasChanged: boolean;
|
hasChanged: boolean;
|
||||||
|
|
||||||
|
endpointUrlHasChanged: boolean;
|
||||||
|
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent)
|
||||||
inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
@ -59,6 +63,7 @@ export class CreateEditDestinationComponent implements AfterViewChecked {
|
|||||||
this.editable = editable;
|
this.editable = editable;
|
||||||
|
|
||||||
this.hasChanged = false;
|
this.hasChanged = false;
|
||||||
|
this.endpointUrlHasChanged = false;
|
||||||
|
|
||||||
this.pingTestMessage = '';
|
this.pingTestMessage = '';
|
||||||
this.pingStatus = true;
|
this.pingStatus = true;
|
||||||
@ -75,7 +80,8 @@ export class CreateEditDestinationComponent implements AfterViewChecked {
|
|||||||
this.initVal.name = this.target.name;
|
this.initVal.name = this.target.name;
|
||||||
this.initVal.endpoint = this.target.endpoint;
|
this.initVal.endpoint = this.target.endpoint;
|
||||||
this.initVal.username = this.target.username;
|
this.initVal.username = this.target.username;
|
||||||
this.initVal.password = this.target.password;
|
this.initVal.password = FAKE_PASSWORD;
|
||||||
|
this.target.password = this.initVal.password;
|
||||||
},
|
},
|
||||||
error=>this.messageHandlerService.handleError(error)
|
error=>this.messageHandlerService.handleError(error)
|
||||||
);
|
);
|
||||||
@ -89,8 +95,23 @@ export class CreateEditDestinationComponent implements AfterViewChecked {
|
|||||||
this.translateService.get('DESTINATION.TESTING_CONNECTION').subscribe(res=>this.pingTestMessage=res);
|
this.translateService.get('DESTINATION.TESTING_CONNECTION').subscribe(res=>this.pingTestMessage=res);
|
||||||
this.pingStatus = true;
|
this.pingStatus = true;
|
||||||
this.testOngoing = !this.testOngoing;
|
this.testOngoing = !this.testOngoing;
|
||||||
|
|
||||||
|
let postedTarget: any = {};
|
||||||
|
|
||||||
|
if(!this.endpointUrlHasChanged) {
|
||||||
|
postedTarget = {
|
||||||
|
id: this.target.id
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
postedTarget = {
|
||||||
|
endpoint: this.target.endpoint,
|
||||||
|
username: this.target.username,
|
||||||
|
password: this.target.password
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this.replicationService
|
this.replicationService
|
||||||
.pingTarget(this.target)
|
.pingTarget(postedTarget)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response=>{
|
response=>{
|
||||||
this.pingStatus = true;
|
this.pingStatus = true;
|
||||||
@ -105,6 +126,13 @@ export class CreateEditDestinationComponent implements AfterViewChecked {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearPassword($event: any) {
|
||||||
|
if(this.editable) {
|
||||||
|
this.target.password = '';
|
||||||
|
this.endpointUrlHasChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
switch(this.actionType) {
|
switch(this.actionType) {
|
||||||
case ActionType.ADD_NEW:
|
case ActionType.ADD_NEW:
|
||||||
@ -144,6 +172,10 @@ export class CreateEditDestinationComponent implements AfterViewChecked {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case ActionType.EDIT:
|
case ActionType.EDIT:
|
||||||
|
if(!this.endpointUrlHasChanged) {
|
||||||
|
this.createEditDestinationOpened = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.replicationService
|
this.replicationService
|
||||||
.updateTarget(this.target)
|
.updateTarget(this.target)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
@ -209,7 +241,7 @@ export class CreateEditDestinationComponent implements AfterViewChecked {
|
|||||||
for(let i in data) {
|
for(let i in data) {
|
||||||
let current = data[i];
|
let current = data[i];
|
||||||
let origin = this.initVal[this.mappedName[i]];
|
let origin = this.initVal[this.mappedName[i]];
|
||||||
if((this.actionType === ActionType.EDIT && this.editable && !current) || (current && current !== origin)) {
|
if(((this.actionType === ActionType.EDIT && this.editable && !current) || current) && current !== origin) {
|
||||||
this.hasChanged = true;
|
this.hasChanged = true;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -140,6 +140,9 @@ export class ReplicationService {
|
|||||||
|
|
||||||
pingTarget(target: Target): Observable<any> {
|
pingTarget(target: Target): Observable<any> {
|
||||||
let body = new URLSearchParams();
|
let body = new URLSearchParams();
|
||||||
|
if(target.id) {
|
||||||
|
body.set('id', target.id + '');
|
||||||
|
}
|
||||||
body.set('endpoint', target.endpoint);
|
body.set('endpoint', target.endpoint);
|
||||||
body.set('username', target.username);
|
body.set('username', target.username);
|
||||||
body.set('password', target.password);
|
body.set('password', target.password);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<clr-modal [(clrModalOpen)]="opened" [clrModalClosable]="true" [clrModalStaticBackdrop]="false">
|
<clr-modal [(clrModalOpen)]="opened" [clrModalClosable]="false" [clrModalStaticBackdrop]="false">
|
||||||
<h3 class="modal-title margin-left-override">vmware</h3>
|
<h3 class="modal-title margin-left-override">vmware</h3>
|
||||||
<div class="modal-body margin-left-override">
|
<div class="modal-body margin-left-override">
|
||||||
<div>
|
<div>
|
||||||
|
@ -15,6 +15,8 @@ import { Target } from '../../replication/target';
|
|||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
const FAKE_PASSWORD: string = 'ywJZnDTM';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'create-edit-policy',
|
selector: 'create-edit-policy',
|
||||||
templateUrl: 'create-edit-policy.component.html',
|
templateUrl: 'create-edit-policy.component.html',
|
||||||
@ -85,7 +87,7 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
this.createEditPolicy.targetName = initialTarget.name;
|
this.createEditPolicy.targetName = initialTarget.name;
|
||||||
this.createEditPolicy.endpointUrl = initialTarget.endpoint;
|
this.createEditPolicy.endpointUrl = initialTarget.endpoint;
|
||||||
this.createEditPolicy.username = initialTarget.username;
|
this.createEditPolicy.username = initialTarget.username;
|
||||||
this.createEditPolicy.password = initialTarget.password;
|
this.createEditPolicy.password = FAKE_PASSWORD;
|
||||||
|
|
||||||
this.initVal.targetId = this.createEditPolicy.targetId;
|
this.initVal.targetId = this.createEditPolicy.targetId;
|
||||||
this.initVal.endpointUrl = this.createEditPolicy.endpointUrl;
|
this.initVal.endpointUrl = this.createEditPolicy.endpointUrl;
|
||||||
@ -160,7 +162,7 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
this.createEditPolicy.targetId = result.id;
|
this.createEditPolicy.targetId = result.id;
|
||||||
this.createEditPolicy.endpointUrl = result.endpoint;
|
this.createEditPolicy.endpointUrl = result.endpoint;
|
||||||
this.createEditPolicy.username = result.username;
|
this.createEditPolicy.username = result.username;
|
||||||
this.createEditPolicy.password = result.password;
|
this.createEditPolicy.password = FAKE_PASSWORD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +295,7 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
for(let i in data) {
|
for(let i in data) {
|
||||||
let origin = this.initVal[i];
|
let origin = this.initVal[i];
|
||||||
let current = data[i];
|
let current = data[i];
|
||||||
if((this.actionType === ActionType.EDIT && !this.readonly && !current) || (current && current !== origin)) {
|
if(((this.actionType === ActionType.EDIT && !this.readonly && !current ) || current) && current !== origin) {
|
||||||
this.hasChanged = true;
|
this.hasChanged = true;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -309,10 +311,14 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
this.pingStatus = true;
|
this.pingStatus = true;
|
||||||
this.translateService.get('REPLICATION.TESTING_CONNECTION').subscribe(res=>this.pingTestMessage=res);
|
this.translateService.get('REPLICATION.TESTING_CONNECTION').subscribe(res=>this.pingTestMessage=res);
|
||||||
this.testOngoing = !this.testOngoing;
|
this.testOngoing = !this.testOngoing;
|
||||||
let pingTarget = new Target();
|
let pingTarget: Target | any = {};
|
||||||
|
if(this.isCreateDestination) {
|
||||||
pingTarget.endpoint = this.createEditPolicy.endpointUrl;
|
pingTarget.endpoint = this.createEditPolicy.endpointUrl;
|
||||||
pingTarget.username = this.createEditPolicy.username;
|
pingTarget.username = this.createEditPolicy.username;
|
||||||
pingTarget.password = this.createEditPolicy.password;
|
pingTarget.password = this.createEditPolicy.password;
|
||||||
|
} else {
|
||||||
|
pingTarget.id = this.createEditPolicy.targetId;
|
||||||
|
}
|
||||||
this.replicationService
|
this.replicationService
|
||||||
.pingTarget(pingTarget)
|
.pingTarget(pingTarget)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
width: 60px;
|
width: 60px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
top: -8px;
|
top: -8px;
|
||||||
left: 8px;
|
left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esxc-gauge-small .esxc-gauge-circle-fill {
|
.esxc-gauge-small .esxc-gauge-circle-fill {
|
||||||
@ -181,6 +181,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -8px;
|
top: -8px;
|
||||||
|
width: 70px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.esxc-gauge-small .esxc-limit .esxc-value {
|
.esxc-gauge-small .esxc-limit .esxc-value {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<div class="form-group form-group-override">
|
<div class="form-group form-group-override">
|
||||||
<label for="username" class="required form-group-label-override">{{'PROFILE.USER_NAME' | translate}}</label>
|
<label for="username" class="required form-group-label-override">{{'PROFILE.USER_NAME' | translate}}</label>
|
||||||
<label for="username" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='getValidationState("username")'>
|
<label for="username" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='getValidationState("username")'>
|
||||||
<input type="text" required pattern='[^"~#$%]+' maxLengthExt="20" #usernameInput="ngModel" name="username" [(ngModel)]="newUser.username" id="username" size="36"
|
<input type="text" required pattern='[^"~#$%]+' maxLengthExt="20" #usernameInput="ngModel" name="username" [(ngModel)]="newUser.username" id="username" size="30"
|
||||||
(input)='handleValidation("username", false)'
|
(input)='handleValidation("username", false)'
|
||||||
(blur)='handleValidation("username", true)'>
|
(blur)='handleValidation("username", true)'>
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
@ -18,7 +18,7 @@
|
|||||||
<input name="email" type="text" #eamilInput="ngModel" [(ngModel)]="newUser.email"
|
<input name="email" type="text" #eamilInput="ngModel" [(ngModel)]="newUser.email"
|
||||||
required
|
required
|
||||||
email
|
email
|
||||||
id="email" size="36"
|
id="email" size="30"
|
||||||
(input)='handleValidation("email", false)'
|
(input)='handleValidation("email", false)'
|
||||||
(blur)='handleValidation("email", true)'>
|
(blur)='handleValidation("email", true)'>
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
@ -31,7 +31,7 @@
|
|||||||
<div class="form-group form-group-override">
|
<div class="form-group form-group-override">
|
||||||
<label for="realname" class="required form-group-label-override">{{'PROFILE.FULL_NAME' | translate}}</label>
|
<label for="realname" class="required form-group-label-override">{{'PROFILE.FULL_NAME' | translate}}</label>
|
||||||
<label for="realname" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='getValidationState("realname")'>
|
<label for="realname" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='getValidationState("realname")'>
|
||||||
<input type="text" name="realname" #fullNameInput="ngModel" [(ngModel)]="newUser.realname" required maxLengthExt="20" id="realname" size="36"
|
<input type="text" name="realname" #fullNameInput="ngModel" [(ngModel)]="newUser.realname" required maxLengthExt="20" id="realname" size="30"
|
||||||
(input)='handleValidation("realname", false)'
|
(input)='handleValidation("realname", false)'
|
||||||
(blur)='handleValidation("realname", true)'>
|
(blur)='handleValidation("realname", true)'>
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
@ -47,7 +47,7 @@
|
|||||||
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
||||||
name="newPassword"
|
name="newPassword"
|
||||||
[(ngModel)]="newUser.password"
|
[(ngModel)]="newUser.password"
|
||||||
#newPassInput="ngModel" size="36"
|
#newPassInput="ngModel" size="30"
|
||||||
(input)='handleValidation("newPassword", false)'
|
(input)='handleValidation("newPassword", false)'
|
||||||
(blur)='handleValidation("newPassword", true)'>
|
(blur)='handleValidation("newPassword", true)'>
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
@ -64,7 +64,7 @@
|
|||||||
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$"
|
||||||
name="confirmPassword"
|
name="confirmPassword"
|
||||||
[(ngModel)]="confirmedPwd"
|
[(ngModel)]="confirmedPwd"
|
||||||
#confirmPassInput="ngModel" size="36"
|
#confirmPassInput="ngModel" size="30"
|
||||||
(input)='handleValidation("confirmPassword", false)'
|
(input)='handleValidation("confirmPassword", false)'
|
||||||
(blur)='handleValidation("confirmPassword", true)'>
|
(blur)='handleValidation("confirmPassword", true)'>
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
@ -75,7 +75,7 @@
|
|||||||
<div class="form-group form-group-override">
|
<div class="form-group form-group-override">
|
||||||
<label for="comment" class="form-group-label-override">{{'PROFILE.COMMENT' | translate}}</label>
|
<label for="comment" class="form-group-label-override">{{'PROFILE.COMMENT' | translate}}</label>
|
||||||
<label for="comment" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='getValidationState("comment")'>
|
<label for="comment" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='getValidationState("comment")'>
|
||||||
<input type="text" #commentInput="ngModel" name="comment" [(ngModel)]="newUser.comment" maxLengthExt="20" id="comment" size="36"
|
<input type="text" #commentInput="ngModel" name="comment" [(ngModel)]="newUser.comment" maxLengthExt="20" id="comment" size="30"
|
||||||
(input)='handleValidation("comment", false)'
|
(input)='handleValidation("comment", false)'
|
||||||
(blur)='handleValidation("comment", true)'>
|
(blur)='handleValidation("comment", true)'>
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
|
@ -29,7 +29,7 @@ services:
|
|||||||
- ./common/config/adminserver/env
|
- ./common/config/adminserver/env
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- /data/config/:/etc/adminserver/
|
- /data/config/:/etc/adminserver/config/
|
||||||
- /data/secretkey:/etc/adminserver/key
|
- /data/secretkey:/etc/adminserver/key
|
||||||
- /data/:/data/
|
- /data/:/data/
|
||||||
ports:
|
ports:
|
||||||
|
Loading…
Reference in New Issue
Block a user