blob: 34ceeab12755898f148e66ae619b16cac5ce98d9 [file] [log] [blame]
/*
Copyright 2020 TATA ELXSI
Licensed under the Apache License, Version 2.0 (the 'License');
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
*/
/**
* @file K8sAddClusterComponent.ts.
*/
import { HttpHeaders } from '@angular/common/http';
import { Component, ElementRef, Injector, Input, OnInit, ViewChild } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core';
import { NotifierService } from 'angular-notifier';
import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, TYPESECTION } from 'CommonModel';
import { environment } from 'environment';
import * as jsyaml from 'js-yaml';
import { K8SCLUSTERDATA, K8SPayload } from 'K8sModel';
import { RestService } from 'RestService';
import { isNullOrUndefined, SharedService } from 'SharedService';
import { VimAccountDetails } from 'VimAccountModel';
/**
* Creating Component
* @Component takes K8sAddClusterComponent.html as template url
*/
@Component({
selector: 'app-k8s-add-cluster',
templateUrl: './K8sAddClusterComponent.html',
styleUrls: ['./K8sAddClusterComponent.scss']
})
/** Exporting a class @exports K8sAddClusterComponent */
export class K8sAddClusterComponent implements OnInit {
/** To inject services @public */
public injector: Injector;
/** FormGroup instance added to the form @ html @public */
public k8sclusterForm: FormGroup;
/** Contains all vim account collections */
public vimAccountSelect: VimAccountDetails;
/** Input contains Modal dialog component Instance @public */
@Input() public profileType: string;
/** Input contains Modal dialog component Instance @public */
@Input() public profileID: string;
/** Contains all deployment methods */
public deploymentMethodsSelect: TYPESECTION[] = [];
/** Submited deployments methods format */
public deploymentMethodsSubmit: Map<string, boolean>;
/** Contains all deployment methods selected */
public selectedDeploymentMethods: string[] = ['helm-chart-v3', 'juju-bundle'];
/** Contains all action types */
public actionTypes: string[] = ['update', 'upgrade'];
/** Instance for active modal service @public */
public activeModal: NgbActiveModal;
/** Variable set for twoway bindng @public */
public vimAccountId: string;
/** contains url @public */
public clusterUrl: string;
/** Form submission Add */
public submitted: boolean = false;
/** contains payload */
public payload: K8SPayload;
/** Check the checkbox status */
public isChecked: boolean = true;
/** Check the loading results @public */
public isLoadingResults: boolean = false;
/** Give the message for the loading @public */
public message: string = 'PLEASEWAIT';
/** Element ref for fileInputNets @public */
@ViewChild('fileInputNets', { static: true }) public fileInputNets: ElementRef;
/** Element ref for fileInputNetsLabel @public */
@ViewChild('fileInputNetsLabel', { static: true }) public fileInputNetsLabel: ElementRef;
/** Element ref for fileInputCredentials @public */
@ViewChild('fileInputCredentials', { static: true }) public fileInputCredentials: ElementRef;
/** Element ref for fileInputCredentialsLabel @public */
@ViewChild('fileInputCredentialsLabel', { static: true }) public fileInputCredentialsLabel: ElementRef;
/** FormBuilder instance added to the formBuilder @private */
private formBuilder: FormBuilder;
/** Utilizes rest service for any CRUD operations @private */
private restService: RestService;
/** Notifier service to popup notification @private */
private notifierService: NotifierService;
/** Contains tranlsate instance @private */
private translateService: TranslateService;
/** Controls the header form @private */
private headers: HttpHeaders;
/** Contains all methods related to shared @private */
private sharedService: SharedService;
constructor(injector: Injector) {
this.injector = injector;
this.restService = this.injector.get(RestService);
this.activeModal = this.injector.get(NgbActiveModal);
this.formBuilder = this.injector.get(FormBuilder);
this.notifierService = this.injector.get(NotifierService);
this.translateService = this.injector.get(TranslateService);
this.sharedService = this.injector.get(SharedService);
this.deploymentMethodsSelect = [
{
title: 'Helm v3',
value: 'helm-chart-v3'
},
{
title: 'Juju bundle',
value: 'juju-bundle'
}
];
}
public ngOnInit(): void {
/** On Initializing call the methods */
this.k8sclusterFormAction();
this.getDetailsvimAccount();
this.headers = new HttpHeaders({
Accept: 'application/json',
'Content-Type': 'application/json',
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
});
this.actionTypes.forEach((type: string): void => {
if (type === this.profileType) {
this.k8sClusterDetail();
}
});
}
/** On modal initializing forms @public */
public k8sclusterFormAction(): void {
this.k8sclusterForm = this.formBuilder.group({
name: ['', [Validators.required]],
k8s_version: ['', [Validators.required]],
vim_account: [null, [Validators.required]],
description: [''],
nets: ['', [Validators.required]],
deployment_methods: ['', [Validators.required]],
credentials: ['', [Validators.required]],
region_name: [''],
resource_group: [''],
node_count: ['', [Validators.required]],
node_size: ['', [Validators.required]],
bootstrap: [true],
k8sVersion: ['', [Validators.required]],
update: ['']
});
}
/** convenience getter for easy access to form fields */
get f(): FormGroup['controls'] { return this.k8sclusterForm.controls; }
/** Call the vimAccount details in the selection options @public */
public getDetailsvimAccount(): void {
this.isLoadingResults = true;
this.restService.getResource(environment.VIMACCOUNTS_URL).subscribe((vimAccounts: VimAccountDetails) => {
this.vimAccountSelect = vimAccounts;
this.isLoadingResults = false;
}, (error: ERRORDATA) => {
this.restService.handleError(error, 'get');
this.isLoadingResults = false;
});
}
/** patch the form values for edit @public */
public k8sClusterDetail(): void {
this.isLoadingResults = true;
this.restService.getResource(environment.K8SCREATECLUSTER_URL + '/' + this.profileID).subscribe((k8sData: K8SCLUSTERDATA) => {
if (this.profileType === 'update') {
this.k8sclusterForm.patchValue({ update: k8sData.name, description: !isNullOrUndefined(k8sData.description) ? k8sData.description : '' });
} else if (this.profileType === 'upgrade') {
this.k8sclusterForm.patchValue({ k8sVersion: !isNullOrUndefined(k8sData.k8s_version) ? k8sData.k8s_version : '' });
}
this.isLoadingResults = false;
}, (error: ERRORDATA) => {
this.restService.handleError(error, 'get');
this.isLoadingResults = false;
});
}
/** Call the event when checkbox is checked @public */
public getValue(event: Event): void {
this.isChecked = (event.target as HTMLInputElement).checked;
}
/** Contain selected vimAccount details @public */
public getDetailsvim(event: VimAccountDetails): void {
this.vimAccountId = event._id;
}
/** On modal submit k8sAddClusterSubmit will called @public */
public k8sAddClusterSubmit(): void {
if (this.profileType === 'Manage') {
this.getFormControl('nets').disable();
this.getFormControl('credentials').disable();
this.getFormControl('deployment_methods').disable();
this.getFormControl('k8sVersion').disable();
this.getFormControl('update').disable();
this.manageCluster();
} else if (this.profileType === 'Register' && this.isChecked === true) {
this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/register';
this.getFormControl('region_name').disable();
this.getFormControl('resource_group').disable();
this.getFormControl('k8s_version').disable();
this.getFormControl('node_size').disable();
this.getFormControl('node_count').disable();
this.getFormControl('nets').disable();
this.getFormControl('deployment_methods').disable();
this.getFormControl('k8sVersion').disable();
this.getFormControl('update').disable();
this.registerCluster();
} if (this.isChecked === false && this.profileType === 'Register') {
this.clusterUrl = environment.K8SCLUSTER_URL;
this.getFormControl('bootstrap').disable();
this.getFormControl('region_name').disable();
this.getFormControl('resource_group').disable();
this.getFormControl('node_count').disable();
this.getFormControl('node_size').disable();
this.getFormControl('k8sVersion').disable();
this.getFormControl('update').disable();
this.oldregisterCluster();
} else if (this.profileType === 'upgrade') {
this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'upgrade';
this.getFormControl('region_name').disable();
this.getFormControl('resource_group').disable();
this.getFormControl('nets').disable();
this.getFormControl('credentials').disable();
this.getFormControl('deployment_methods').disable();
this.getFormControl('name').disable();
this.getFormControl('vim_account').disable();
this.getFormControl('description').disable();
this.getFormControl('bootstrap').disable();
this.getFormControl('node_count').disable();
this.getFormControl('node_size').disable();
this.getFormControl('k8s_version').disable();
this.getFormControl('update').disable();
this.updateCluster();
} else if (this.profileType === 'update') {
this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID;
this.getFormControl('bootstrap').disable();
this.getFormControl('region_name').disable();
this.getFormControl('resource_group').disable();
this.getFormControl('nets').disable();
this.getFormControl('credentials').disable();
this.getFormControl('deployment_methods').disable();
this.getFormControl('vim_account').disable();
this.getFormControl('node_count').disable();
this.getFormControl('node_size').disable();
this.getFormControl('k8s_version').disable();
this.getFormControl('k8sVersion').disable();
this.getFormControl('name').disable();
this.editCluster();
}
}
/** Old Register cluster flow @public */
public oldregisterCluster(): void {
this.submitted = true;
this.sharedService.cleanForm(this.k8sclusterForm);
if (this.k8sclusterForm.invalid) {
return;
}
const modalData: MODALCLOSERESPONSEDATA = {
message: 'Done'
};
const validJSONCredentails: boolean = this.sharedService.checkJson(this.k8sclusterForm.value.credentials);
if (validJSONCredentails) {
this.k8sclusterForm.value.credentials = jsyaml.load(this.k8sclusterForm.value.credentials.toString(), { json: true });
} else {
this.notifierService.notify('error', this.translateService.instant('INVALIDCONFIG'));
return;
}
const validJSONNets: boolean = this.sharedService.checkJson(this.k8sclusterForm.value.nets);
if (validJSONNets) {
this.k8sclusterForm.value.nets = jsyaml.load(this.k8sclusterForm.value.nets.toString(), { json: true });
} else {
this.notifierService.notify('error', this.translateService.instant('INVALIDCONFIG'));
return;
}
this.deploymentMethodsSubmit = new Map<string, boolean>();
/// Set deployment method Map
for (const methods of this.deploymentMethodsSelect) {
this.deploymentMethodsSubmit.set(methods.value, false);
}
this.k8sclusterForm.value.deployment_methods.forEach((dm: string): void => {
this.deploymentMethodsSubmit.set(dm, true);
});
// Transform Map to json object
const jsonDMObject: {} = {};
this.deploymentMethodsSubmit.forEach((value: boolean, key: string): void => {
// eslint-disable-next-line security/detect-object-injection
jsonDMObject[key] = value;
});
// Transform values to json
this.k8sclusterForm.value.deployment_methods = jsonDMObject;
this.k8sclusterForm.value.vim_account = this.vimAccountId;
if (this.k8sclusterForm.value.description === '') {
delete this.k8sclusterForm.value.description;
}
const apiURLHeader: APIURLHEADER = {
url: this.clusterUrl,
httpOptions: { headers: this.headers }
};
this.isLoadingResults = true;
this.restService.postResource(apiURLHeader, this.k8sclusterForm.value).subscribe((result: {}) => {
this.activeModal.close(modalData);
this.isLoadingResults = false;
this.notifierService.notify('success', this.k8sclusterForm.value.name +
this.translateService.instant('PAGE.K8S.REGISTEREDSUCCESSFULLY'));
}, (error: ERRORDATA) => {
this.restService.handleError(error, 'post');
this.isLoadingResults = false;
});
}
/** New Register cluster flow @public */
public registerCluster(): void {
this.submitted = true;
this.sharedService.cleanForm(this.k8sclusterForm);
if (this.k8sclusterForm.invalid) {
return;
}
const modalData: MODALCLOSERESPONSEDATA = {
message: 'Done'
};
const validJSONCredentails: boolean = this.sharedService.checkJson(this.k8sclusterForm.value.credentials);
if (validJSONCredentails) {
this.k8sclusterForm.value.credentials = jsyaml.load(this.k8sclusterForm.value.credentials.toString(), { json: true });
} else {
this.notifierService.notify('error', this.translateService.instant('INVALIDCONFIG'));
return;
}
if (this.k8sclusterForm.value.description === '') {
delete this.k8sclusterForm.value.description;
}
const apiURLHeader: APIURLHEADER = {
url: this.clusterUrl,
httpOptions: { headers: this.headers }
};
this.isLoadingResults = true;
this.restService.postResource(apiURLHeader, this.k8sclusterForm.value).subscribe((result: {}) => {
this.activeModal.close(modalData);
this.isLoadingResults = false;
this.notifierService.notify('success', this.k8sclusterForm.value.name +
this.translateService.instant('PAGE.K8S.REGISTEREDSUCCESSFULLY'));
}, (error: ERRORDATA) => {
this.restService.handleError(error, 'post');
this.isLoadingResults = false;
});
}
/** Manage cluster @public */
public manageCluster(): void {
this.submitted = true;
this.sharedService.cleanForm(this.k8sclusterForm);
if (this.k8sclusterForm.invalid) {
return;
}
const modalData: MODALCLOSERESPONSEDATA = {
message: 'Done'
};
const apiURLHeader: APIURLHEADER = {
url: environment.K8SCREATECLUSTER_URL,
httpOptions: { headers: this.headers }
};
this.isLoadingResults = true;
const payload: K8SPayload = {
name: this.k8sclusterForm.value.name,
vim_account: this.k8sclusterForm.value.vim_account,
location: this.k8sclusterForm.value.location,
region_name: this.k8sclusterForm.value.region_name,
resource_group: this.k8sclusterForm.value.resource_group,
k8s_version: this.k8sclusterForm.value.k8s_version,
node_size: this.k8sclusterForm.value.node_size,
node_count: Number(this.k8sclusterForm.value.node_count),
description: this.k8sclusterForm.value.description,
bootstrap: Boolean(this.k8sclusterForm.value.bootstrap)
};
if (this.k8sclusterForm.value.region_name === '') {
delete payload.region_name;
} else if (this.k8sclusterForm.value.resource_group === '') {
delete payload.resource_group;
} else if (this.k8sclusterForm.value.description === '') {
delete payload.description;
}
if (this.k8sclusterForm.value.region_name === '' && this.k8sclusterForm.value.resource_group === '' && this.k8sclusterForm.value.description === '') {
delete payload.region_name;
delete payload.resource_group;
delete payload.description;
}
this.restService.postResource(apiURLHeader, payload).subscribe((result: {}) => {
this.activeModal.close(modalData);
this.isLoadingResults = false;
this.notifierService.notify('success', this.k8sclusterForm.value.name +
this.translateService.instant('PAGE.K8S.CREATEDSUCCESSFULLY'));
}, (error: ERRORDATA) => {
this.restService.handleError(error, 'post');
this.isLoadingResults = false;
});
}
/** Update cluster @public */
public updateCluster(): void {
this.submitted = true;
this.sharedService.cleanForm(this.k8sclusterForm);
if (this.k8sclusterForm.invalid) {
return;
}
const modalData: MODALCLOSERESPONSEDATA = {
message: 'Done'
};
const apiURLHeader: APIURLHEADER = {
url: this.clusterUrl,
httpOptions: { headers: this.headers }
};
if (this.profileType === 'upgrade') {
this.payload = {
k8s_version: this.k8sclusterForm.value.k8sVersion
};
}
this.isLoadingResults = true;
this.restService.postResource(apiURLHeader, this.payload).subscribe((result: {}) => {
this.activeModal.close(modalData);
this.isLoadingResults = false;
this.notifierService.notify('success',
this.translateService.instant('PAGE.K8S.UPDATEDSUCCESSFULLY'));
}, (error: ERRORDATA) => {
this.restService.handleError(error, 'post');
this.isLoadingResults = false;
});
}
/** Update cluster @public */
public editCluster(): void {
this.submitted = true;
this.sharedService.cleanForm(this.k8sclusterForm);
if (this.k8sclusterForm.invalid) {
return;
}
const modalData: MODALCLOSERESPONSEDATA = {
message: 'Done'
};
const apiURLHeader: APIURLHEADER = {
url: this.clusterUrl,
httpOptions: { headers: this.headers }
};
this.isLoadingResults = true;
if (this.k8sclusterForm.value.description === '') {
delete this.k8sclusterForm.value.description;
this.payload = {
name: this.k8sclusterForm.value.update
};
}
if (this.k8sclusterForm.value.update === '') {
delete this.k8sclusterForm.value.update;
this.payload = {
description: this.k8sclusterForm.value.description
};
}
if (this.k8sclusterForm.value.update !== '' && this.k8sclusterForm.value.description !== '') {
this.payload = {
name: this.k8sclusterForm.value.update,
description: this.k8sclusterForm.value.description
};
}
this.restService.patchResource(apiURLHeader, this.payload).subscribe((result: {}) => {
this.activeModal.close(modalData);
this.isLoadingResults = false;
this.notifierService.notify('success',
this.translateService.instant('PAGE.K8S.UPDATEDSUCCESSFULLY'));
}, (error: ERRORDATA) => {
this.restService.handleError(error, 'post');
this.isLoadingResults = false;
});
}
/** Nets file process @private */
public netsFile(files: FileList): void {
if (files && files.length === 1) {
this.sharedService.getFileString(files, 'json').then((fileContent: string): void => {
const getNetsJson: string = jsyaml.load(fileContent, { json: true });
this.k8sclusterForm.get('nets').setValue(JSON.stringify(getNetsJson));
}).catch((err: string): void => {
if (err === 'typeError') {
this.notifierService.notify('error', this.translateService.instant('JSONFILETYPEERRROR'));
} else {
this.notifierService.notify('error', this.translateService.instant('ERROR'));
}
this.fileInputNetsLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
this.fileInputNets.nativeElement.value = null;
});
} else if (files && files.length > 1) {
this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
}
this.fileInputNetsLabel.nativeElement.innerText = files[0].name;
this.fileInputNets.nativeElement.value = null;
}
/** credentials file process @private */
public credentialsFile(files: FileList): void {
if (files && files.length === 1) {
this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
const getCredentialsJson: string = jsyaml.load(fileContent, { json: true });
this.k8sclusterForm.get('credentials').setValue(JSON.stringify(getCredentialsJson));
}).catch((err: string): void => {
if (err === 'typeError') {
this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
} else {
this.notifierService.notify('error', this.translateService.instant('ERROR'));
}
this.fileInputCredentialsLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
this.fileInputCredentials.nativeElement.value = null;
});
} else if (files && files.length > 1) {
this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
}
this.fileInputCredentialsLabel.nativeElement.innerText = files[0].name;
this.fileInputCredentials.nativeElement.value = null;
}
/** Used to get the AbstractControl of controlName passed @private */
private getFormControl(controlName: string): AbstractControl {
// eslint-disable-next-line security/detect-object-injection
return this.k8sclusterForm.controls[controlName];
}
}