mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-27 04:35:16 +01:00
Merge pull request #3708 from ywk253100/171129_ping
Refactor ping target API
This commit is contained in:
commit
6094cca159
@ -1670,31 +1670,6 @@ paths:
|
||||
description: Target not found.
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
'/targets/{id}/ping':
|
||||
post:
|
||||
summary: Ping target.
|
||||
description: |
|
||||
This endpoint is for ping target.
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
type: integer
|
||||
format: int64
|
||||
required: true
|
||||
description: The replication's target ID.
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
'200':
|
||||
description: Ping replication's target successfully.
|
||||
'400':
|
||||
description: Can not ping target.
|
||||
'401':
|
||||
description: User need to log in first.
|
||||
'404':
|
||||
description: Target ID does not exist.
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
'/targets/{id}':
|
||||
put:
|
||||
summary: Update replication's target.
|
||||
@ -2512,6 +2487,10 @@ definitions:
|
||||
PingTarget:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int
|
||||
description: Target ID.
|
||||
endpoint:
|
||||
type: string
|
||||
description: The target address URL string.
|
||||
|
@ -118,7 +118,6 @@ func init() {
|
||||
beego.Router("/api/targets/:id([0-9]+)", &TargetAPI{})
|
||||
beego.Router("/api/targets/:id([0-9]+)/policies/", &TargetAPI{}, "get:ListPolicies")
|
||||
beego.Router("/api/targets/ping", &TargetAPI{}, "post:Ping")
|
||||
beego.Router("/api/targets/:id([0-9]+)/ping", &TargetAPI{}, "post:PingByID")
|
||||
beego.Router("/api/policies/replication/:id([0-9]+)", &RepPolicyAPI{})
|
||||
beego.Router("/api/policies/replication", &RepPolicyAPI{}, "get:List")
|
||||
beego.Router("/api/policies/replication", &RepPolicyAPI{}, "post:Post;delete:Delete")
|
||||
@ -636,18 +635,6 @@ func (a testapi) PingTarget(authInfo usrInfo, body interface{}) (int, error) {
|
||||
return httpStatusCode, err
|
||||
}
|
||||
|
||||
//PingTargetByID ...
|
||||
func (a testapi) PingTargetByID(authInfo usrInfo, id int) (int, error) {
|
||||
_sling := sling.New().Post(a.basePath)
|
||||
|
||||
path := fmt.Sprintf("/api/targets/%d/ping", id)
|
||||
|
||||
_sling = _sling.Path(path)
|
||||
|
||||
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
|
||||
return httpStatusCode, err
|
||||
}
|
||||
|
||||
//Get target by targetID
|
||||
func (a testapi) GetTargetByID(authInfo usrInfo, targetID string) (int, error) {
|
||||
_sling := sling.New().Get(a.basePath)
|
||||
|
@ -84,48 +84,57 @@ func (t *TargetAPI) ping(endpoint, username, password string, insecure bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// PingByID ping target by ID
|
||||
func (t *TargetAPI) PingByID() {
|
||||
id := t.GetIDFromURL()
|
||||
|
||||
target, err := dao.GetRepTarget(id)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get target %d: %v", id, err)
|
||||
t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
||||
}
|
||||
if target == nil {
|
||||
t.CustomAbort(http.StatusNotFound, fmt.Sprintf("target %d not found", id))
|
||||
}
|
||||
|
||||
endpoint := target.URL
|
||||
username := target.Username
|
||||
password := target.Password
|
||||
insecure := target.Insecure
|
||||
if len(password) != 0 {
|
||||
password, err = utils.ReversibleDecrypt(password, t.secretKey)
|
||||
if err != nil {
|
||||
log.Errorf("failed to decrypt password: %v", err)
|
||||
t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
||||
}
|
||||
}
|
||||
t.ping(endpoint, username, password, insecure)
|
||||
}
|
||||
|
||||
// Ping validates whether the target is reachable and whether the credential is valid
|
||||
func (t *TargetAPI) Ping() {
|
||||
req := struct {
|
||||
Endpoint string `json:"endpoint"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Insecure bool `json:"insecure"`
|
||||
ID *int64 `json:"id"`
|
||||
Endpoint *string `json:"endpoint"`
|
||||
Username *string `json:"username"`
|
||||
Password *string `json:"password"`
|
||||
Insecure *bool `json:"insecure"`
|
||||
}{}
|
||||
t.DecodeJSONReq(&req)
|
||||
|
||||
if len(req.Endpoint) == 0 {
|
||||
t.CustomAbort(http.StatusBadRequest, "endpoint is required")
|
||||
target := &models.RepTarget{}
|
||||
if req.ID != nil {
|
||||
var err error
|
||||
target, err = dao.GetRepTarget(*req.ID)
|
||||
if err != nil {
|
||||
t.HandleInternalServerError(fmt.Sprintf("failed to get target %d: %v", *req.ID, err))
|
||||
return
|
||||
}
|
||||
if target == nil {
|
||||
t.HandleNotFound(fmt.Sprintf("target %d not found", *req.ID))
|
||||
return
|
||||
}
|
||||
if len(target.Password) != 0 {
|
||||
target.Password, err = utils.ReversibleDecrypt(target.Password, t.secretKey)
|
||||
if err != nil {
|
||||
t.HandleInternalServerError(fmt.Sprintf("failed to decrypt password: %v", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.ping(req.Endpoint, req.Username, req.Password, req.Insecure)
|
||||
if req.Endpoint != nil {
|
||||
target.URL = *req.Endpoint
|
||||
}
|
||||
if req.Username != nil {
|
||||
target.Username = *req.Username
|
||||
}
|
||||
if req.Password != nil {
|
||||
target.Password = *req.Password
|
||||
}
|
||||
if req.Insecure != nil {
|
||||
target.Insecure = *req.Insecure
|
||||
}
|
||||
|
||||
if len(target.URL) == 0 {
|
||||
t.HandleBadRequest("empty endpoint")
|
||||
return
|
||||
}
|
||||
|
||||
t.ping(target.URL, target.Username, target.Password, target.Insecure)
|
||||
}
|
||||
|
||||
// Get ...
|
||||
|
@ -15,11 +15,13 @@ package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vmware/harbor/tests/apitests/apilib"
|
||||
)
|
||||
|
||||
@ -110,72 +112,46 @@ func TestTargetsGet(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTargetPing(t *testing.T) {
|
||||
var httpStatusCode int
|
||||
var err error
|
||||
|
||||
assert := assert.New(t)
|
||||
apiTest := newHarborAPI()
|
||||
|
||||
fmt.Println("Testing Targets Ping Post API")
|
||||
//case 1
|
||||
body := struct {
|
||||
// 404: not exist target
|
||||
target01 := struct {
|
||||
ID int64 `json:"id"`
|
||||
}{
|
||||
ID: 10000,
|
||||
}
|
||||
|
||||
code, err := apiTest.PingTarget(*admin, target01)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusNotFound, code)
|
||||
|
||||
// 400: empty endpoint
|
||||
target02 := struct {
|
||||
Endpoint string `json:"endpoint"`
|
||||
}{
|
||||
Endpoint: "",
|
||||
}
|
||||
code, err = apiTest.PingTarget(*admin, target02)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusBadRequest, code)
|
||||
|
||||
// 200
|
||||
target03 := struct {
|
||||
ID int64 `json:"id"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Insecure bool `json:"insecure"`
|
||||
}{
|
||||
ID: int64(addTargetID),
|
||||
Endpoint: os.Getenv("REGISTRY_URL"),
|
||||
Username: adminName,
|
||||
Password: adminPwd,
|
||||
Insecure: true,
|
||||
}
|
||||
httpStatusCode, err = apiTest.PingTarget(*admin, body)
|
||||
if err != nil {
|
||||
t.Error("Error while ping target", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(int(200), httpStatusCode, "")
|
||||
}
|
||||
|
||||
//case 2
|
||||
body.Endpoint = ""
|
||||
httpStatusCode, err = apiTest.PingTarget(*admin, body)
|
||||
if err != nil {
|
||||
t.Error("Error while ping target", err.Error())
|
||||
} else {
|
||||
assert.Equal(int(400), httpStatusCode, "")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTargetPingByID(t *testing.T) {
|
||||
var httpStatusCode int
|
||||
var err error
|
||||
|
||||
assert := assert.New(t)
|
||||
apiTest := newHarborAPI()
|
||||
|
||||
fmt.Println("Testing Targets Ping Post API")
|
||||
|
||||
//-------------------case 1 : response code = 200------------------------//
|
||||
fmt.Println("case 1 : response code = 200")
|
||||
id := addTargetID
|
||||
httpStatusCode, err = apiTest.PingTargetByID(*admin, id)
|
||||
if err != nil {
|
||||
t.Error("Error whihle ping target", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
|
||||
}
|
||||
|
||||
//--------------case 2 : response code = 404,target not found------------//
|
||||
fmt.Println("case 2 : response code = 404,target not found")
|
||||
|
||||
id = 1111
|
||||
httpStatusCode, err = apiTest.PingTargetByID(*admin, id)
|
||||
if err != nil {
|
||||
t.Error("Error whihle ping target", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(int(404), httpStatusCode, "httpStatusCode should be 404")
|
||||
}
|
||||
code, err = apiTest.PingTarget(*admin, target03)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
}
|
||||
|
||||
func TestTargetGetByID(t *testing.T) {
|
||||
|
@ -114,7 +114,6 @@ func initRouters() {
|
||||
beego.Router("/api/targets/:id([0-9]+)", &api.TargetAPI{})
|
||||
beego.Router("/api/targets/:id([0-9]+)/policies/", &api.TargetAPI{}, "get:ListPolicies")
|
||||
beego.Router("/api/targets/ping", &api.TargetAPI{}, "post:Ping")
|
||||
beego.Router("/api/targets/:id([0-9]+)/ping", &api.TargetAPI{}, "post:PingByID")
|
||||
beego.Router("/api/logs", &api.LogAPI{})
|
||||
beego.Router("/api/configurations", &api.ConfigAPI{})
|
||||
beego.Router("/api/configurations/reset", &api.ConfigAPI{}, "post:Reset")
|
||||
|
@ -15,7 +15,7 @@ export const CREATE_EDIT_ENDPOINT_TEMPLATE: string = `
|
||||
<div class="form-group">
|
||||
<label for="destination_name" class="col-md-4 form-group-label-override required">{{ 'DESTINATION.NAME' | translate }}</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">
|
||||
<input type="text" id="destination_name" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.name" name="targetName" size="20" #targetName="ngModel" required (keyup)="changedTargetName($event)">
|
||||
<input type="text" id="destination_name" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.name" name="targetName" size="20" #targetName="ngModel" required>
|
||||
<span class="tooltip-content" *ngIf="targetName.errors && targetName.errors.required && (targetName.dirty || targetName.touched)">
|
||||
{{ 'DESTINATION.NAME_IS_REQUIRED' | translate }}
|
||||
</span>
|
||||
@ -24,7 +24,7 @@ export const CREATE_EDIT_ENDPOINT_TEMPLATE: string = `
|
||||
<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" size="20" name="endpointUrl" #targetEndpoint="ngModel" required (keyup)="clearPassword($event)" placeholder="http(s)://192.168.1.1">
|
||||
<input type="text" id="destination_url" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.endpoint" 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>
|
||||
@ -32,15 +32,15 @@ export const CREATE_EDIT_ENDPOINT_TEMPLATE: string = `
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<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" (keyup)="clearPassword($event)">
|
||||
<input type="text" class="col-md-8" id="destination_username" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.username" size="20" name="username" #username="ngModel">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<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" (focus)="clearPassword($event)">
|
||||
<input type="password" class="col-md-8" id="destination_password" [disabled]="testOngoing" [readonly]="!editable" [(ngModel)]="target.password" size="20" name="password" #password="ngModel">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="destination_insecure" class="col-md-4 form-group-label-override">{{'CONFIG.VERIFY_REMOTE_CERT' | translate }}</label>
|
||||
<clr-checkbox #insecure class="col-md-8" name="insecure" id="destination_insecure" [clrDisabled]="testOngoing" [clrChecked]="!target.insecure" (clrCheckedChange)="setInsecureValue($event)">
|
||||
<clr-checkbox #insecure class="col-md-8" name="insecure" id="destination_insecure" [clrDisabled]="testOngoing || !editable" [clrChecked]="!target.insecure" (clrCheckedChange)="setInsecureValue($event)">
|
||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right" style="top:-7px;">
|
||||
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
|
||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.VERIFY_REMOTE_CERT' | translate}}</span>
|
||||
@ -55,8 +55,8 @@ export const CREATE_EDIT_ENDPOINT_TEMPLATE: string = `
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline" (click)="testConnection()" [disabled]="testOngoing || onGoing || targetEndpoint.errors">{{ 'DESTINATION.TEST_CONNECTION' | translate }}</button>
|
||||
<button type="button" class="btn btn-outline" (click)="onCancel()" [disabled]="testOngoing || onGoing">{{ 'BUTTON.CANCEL' | translate }}</button>
|
||||
<button type="button" class="btn btn-outline" (click)="testConnection()" [disabled]="inProgress || targetEndpoint.errors">{{ 'DESTINATION.TEST_CONNECTION' | translate }}</button>
|
||||
<button type="button" class="btn btn-outline" (click)="onCancel()" [disabled]="inProgress">{{ 'BUTTON.CANCEL' | translate }}</button>
|
||||
<button type="submit" class="btn btn-primary" (click)="onSubmit()" [disabled]="!isValid">{{ 'BUTTON.OK' | translate }}</button>
|
||||
</div>
|
||||
</clr-modal>`;
|
@ -35,7 +35,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { CREATE_EDIT_ENDPOINT_STYLE } from './create-edit-endpoint.component.css';
|
||||
import { CREATE_EDIT_ENDPOINT_TEMPLATE } from './create-edit-endpoint.component.html';
|
||||
|
||||
import { toPromise, clone, compareValue } from '../utils';
|
||||
import { toPromise, clone, compareValue, isEmptyObject } from '../utils';
|
||||
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
@ -51,8 +51,6 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
createEditDestinationOpened: boolean;
|
||||
staticBackdrop: boolean = true;
|
||||
closable: boolean = false;
|
||||
|
||||
actionType: ActionType;
|
||||
editable: boolean;
|
||||
|
||||
target: Endpoint = this.initEndpoint();
|
||||
@ -62,11 +60,9 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
@ViewChild('targetForm')
|
||||
currentForm: NgForm;
|
||||
|
||||
endpointHasChanged: boolean;
|
||||
targetNameHasChanged: boolean;
|
||||
|
||||
testOngoing: boolean;
|
||||
onGoing: boolean;
|
||||
endpointId: number | string;
|
||||
|
||||
@ViewChild(InlineAlertComponent)
|
||||
inlineAlert: InlineAlertComponent;
|
||||
@ -84,41 +80,21 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
private ref: ChangeDetectorRef
|
||||
) { }
|
||||
|
||||
public get hasChanged(): boolean {
|
||||
if (this.actionType === ActionType.ADD_NEW) {
|
||||
//Create new
|
||||
return this.target && (
|
||||
(this.target.endpoint && this.target.endpoint.trim() !== "") ||
|
||||
(this.target.name && this.target.name.trim() !== "") ||
|
||||
(this.target.username && this.target.username.trim() !== "") ||
|
||||
(this.target.password && this.target.password.trim() !== "")) ||
|
||||
this.target.insecure;
|
||||
} else {
|
||||
//Edit
|
||||
return !compareValue(this.target, this.initVal);
|
||||
}
|
||||
}
|
||||
|
||||
public get isValid(): boolean {
|
||||
return !this.testOngoing &&
|
||||
!this.onGoing &&
|
||||
this.targetForm &&
|
||||
this.targetForm.valid &&
|
||||
this.editable &&
|
||||
(this.targetNameHasChanged || this.endpointHasChanged || this.checkboxHasChanged);
|
||||
!compareValue(this.target, this.initVal);
|
||||
}
|
||||
|
||||
public get inProgress(): boolean {
|
||||
return this.onGoing || this.testOngoing;
|
||||
}
|
||||
|
||||
public get checkboxHasChanged(): boolean {
|
||||
return (this.target.insecure !== this.initVal.insecure) ? true : false;
|
||||
}
|
||||
|
||||
setInsecureValue($event: any) {
|
||||
this.target.insecure = !$event;
|
||||
this.endpointHasChanged = true;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
@ -148,8 +124,6 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
|
||||
reset(): void {
|
||||
//Reset status variables
|
||||
this.endpointHasChanged = false;
|
||||
this.targetNameHasChanged = false;
|
||||
this.testOngoing = false;
|
||||
this.onGoing = false;
|
||||
|
||||
@ -157,6 +131,9 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
this.target = this.initEndpoint();
|
||||
this.initVal = this.initEndpoint();
|
||||
this.formValues = null;
|
||||
this.endpointId = '';
|
||||
|
||||
this.inlineAlert.close();
|
||||
}
|
||||
|
||||
//Forcely refresh the view
|
||||
@ -179,7 +156,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
//reset
|
||||
this.reset();
|
||||
if (targetId) {
|
||||
this.actionType = ActionType.EDIT;
|
||||
this.endpointId = targetId;
|
||||
this.translateService.get('DESTINATION.TITLE_EDIT').subscribe(res => this.modalTitle = res);
|
||||
toPromise<Endpoint>(this.endpointService
|
||||
.getEndpoint(targetId))
|
||||
@ -197,7 +174,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
})
|
||||
.catch(error => this.errorHandler.error(error));
|
||||
} else {
|
||||
this.actionType = ActionType.ADD_NEW;
|
||||
this.endpointId = '';
|
||||
this.translateService.get('DESTINATION.TITLE_ADD').subscribe(res => this.modalTitle = res);
|
||||
//Directly open the modal
|
||||
this.open();
|
||||
@ -206,14 +183,23 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
|
||||
testConnection() {
|
||||
let payload: Endpoint = this.initEndpoint();
|
||||
|
||||
if (this.endpointHasChanged) {
|
||||
if (!this.endpointId) {
|
||||
payload.endpoint = this.target.endpoint;
|
||||
payload.username = this.target.username;
|
||||
payload.password = this.target.password;
|
||||
payload.insecure = this.target.insecure;
|
||||
} else {
|
||||
}else {
|
||||
let changes: {[key: string]: any} = this.getChanges();
|
||||
for (let prop in payload) {
|
||||
delete payload[prop];
|
||||
}
|
||||
payload.id = this.target.id;
|
||||
if (!isEmptyObject(changes)) {
|
||||
let changekeys: {[key: string]: any} = Object.keys(this.getChanges());
|
||||
changekeys.forEach((key: string) => {
|
||||
payload[key] = changes[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.testOngoing = true;
|
||||
@ -232,27 +218,11 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
});
|
||||
}
|
||||
|
||||
changedTargetName($event: any) {
|
||||
if (this.editable) {
|
||||
this.targetNameHasChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
clearPassword($event: any) {
|
||||
if (this.editable) {
|
||||
this.target.password = '';
|
||||
this.endpointHasChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
switch (this.actionType) {
|
||||
case ActionType.ADD_NEW:
|
||||
this.addEndpoint();
|
||||
break;
|
||||
case ActionType.EDIT:
|
||||
this.updateEndpoint();
|
||||
break;
|
||||
if (this.endpointId) {
|
||||
this.updateEndpoint();
|
||||
} else {
|
||||
this.addEndpoint();
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,27 +256,19 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
if (this.onGoing) {
|
||||
return;//Avoid duplicated submitting
|
||||
}
|
||||
if (!(this.targetNameHasChanged || this.endpointHasChanged || this.checkboxHasChanged)) {
|
||||
return;//Avoid invalid submitting
|
||||
}
|
||||
|
||||
let payload: Endpoint = this.initEndpoint();
|
||||
if (this.targetNameHasChanged) {
|
||||
payload.name = this.target.name;
|
||||
}else {
|
||||
delete payload.name;
|
||||
for (let prop in payload) {
|
||||
delete payload[prop];
|
||||
}
|
||||
if (this.endpointHasChanged) {
|
||||
payload.endpoint = this.target.endpoint;
|
||||
payload.username = this.target.username;
|
||||
payload.password = this.target.password;
|
||||
}else {
|
||||
delete payload.endpoint;
|
||||
}
|
||||
if (this.checkboxHasChanged) {
|
||||
payload.insecure = this.target.insecure;
|
||||
}else {
|
||||
delete payload.insecure;
|
||||
let changes: {[key: string]: any} = this.getChanges();
|
||||
let changekeys: {[key: string]: any} = Object.keys(this.getChanges());
|
||||
if (isEmptyObject(changes)) {
|
||||
return;
|
||||
}
|
||||
changekeys.forEach((key: string) => {
|
||||
payload[key] = changes[key];
|
||||
});
|
||||
|
||||
if (!this.target.id) { return; }
|
||||
|
||||
@ -346,9 +308,10 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
if (this.hasChanged) {
|
||||
let changes: {[key: string]: any} = this.getChanges();
|
||||
if (!isEmptyObject(changes)) {
|
||||
this.inlineAlert.showInlineConfirmation({ message: 'ALERT.FORM_CHANGE_CONFIRMATION' });
|
||||
} else {
|
||||
}else {
|
||||
this.close();
|
||||
if (this.targetForm) {
|
||||
this.targetForm.reset();
|
||||
@ -388,5 +351,28 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
|
||||
}
|
||||
}
|
||||
}
|
||||
getChanges(): { [key: string]: any | any[] } {
|
||||
let changes: { [key: string]: any | any[] } = {};
|
||||
if (!this.target || !this.initVal) {
|
||||
return changes;
|
||||
}
|
||||
for (let prop in this.target) {
|
||||
let field: any = this.initVal[prop];
|
||||
if (!compareValue(field, this.target[prop])) {
|
||||
changes[prop] = this.target[prop];
|
||||
//Number
|
||||
if (typeof field === "number") {
|
||||
changes[prop] = +changes[prop];
|
||||
}
|
||||
|
||||
}
|
||||
//Trim string value
|
||||
if (typeof field === "string") {
|
||||
changes[prop] = ('' + changes[prop]).trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -185,22 +185,12 @@ export class EndpointDefaultService extends EndpointService {
|
||||
if(!endpoint) {
|
||||
return Promise.reject('Invalid endpoint.');
|
||||
}
|
||||
let requestUrl: string ;
|
||||
if(endpoint.id) {
|
||||
requestUrl = `${this._endpointUrl}/${endpoint.id}/ping`;
|
||||
return this.http
|
||||
.post(requestUrl, HTTP_JSON_OPTIONS)
|
||||
.toPromise()
|
||||
.then(response=>response.status)
|
||||
.catch(error=>Promise.reject(error));
|
||||
} else {
|
||||
requestUrl = `${this._endpointUrl}/ping`;
|
||||
let requestUrl: string = `${this._endpointUrl}/ping`;
|
||||
return this.http
|
||||
.post(requestUrl, endpoint, HTTP_JSON_OPTIONS)
|
||||
.toPromise()
|
||||
.then(response=>response.status)
|
||||
.catch(error=>Promise.reject(error));
|
||||
}
|
||||
}
|
||||
|
||||
public getEndpointWithReplicationRules(endpointId: number | string): Observable<any> | Promise<any> | any {
|
||||
|
@ -75,6 +75,7 @@ export interface Endpoint extends Base {
|
||||
password?: string;
|
||||
insecure: boolean;
|
||||
type: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user