blob: bb5dcfa6c72bb51fac81dca7221bf5f07ceb6a15 [file] [log] [blame]
kumaran.m3b4814a2020-05-01 19:48:54 +05301/*
2 Copyright 2020 TATA ELXSI
3
4 Licensed under the Apache License, Version 2.0 (the 'License');
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15
16 Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
17*/
18/**
19 * @file K8sAddClusterComponent.ts.
20 */
21import { HttpHeaders } from '@angular/common/http';
SANDHYA.JS26570112024-07-05 21:35:46 +053022import { Component, ElementRef, Injector, Input, OnInit, ViewChild } from '@angular/core';
23import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
kumaran.m3b4814a2020-05-01 19:48:54 +053024import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
25import { TranslateService } from '@ngx-translate/core';
26import { NotifierService } from 'angular-notifier';
bacigalupof633dbf2022-03-25 17:24:56 +000027import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, TYPESECTION } from 'CommonModel';
kumaran.m3b4814a2020-05-01 19:48:54 +053028import { environment } from 'environment';
29import * as jsyaml from 'js-yaml';
SANDHYA.JS26570112024-07-05 21:35:46 +053030import { K8SPayload } from 'K8sModel';
kumaran.m3b4814a2020-05-01 19:48:54 +053031import { RestService } from 'RestService';
SANDHYA.JS26570112024-07-05 21:35:46 +053032import { SharedService } from 'SharedService';
kumaran.m3b4814a2020-05-01 19:48:54 +053033import { VimAccountDetails } from 'VimAccountModel';
34/**
35 * Creating Component
36 * @Component takes K8sAddClusterComponent.html as template url
37 */
38@Component({
39 selector: 'app-k8s-add-cluster',
40 templateUrl: './K8sAddClusterComponent.html',
41 styleUrls: ['./K8sAddClusterComponent.scss']
42})
43/** Exporting a class @exports K8sAddClusterComponent */
44export class K8sAddClusterComponent implements OnInit {
45 /** To inject services @public */
46 public injector: Injector;
47
48 /** FormGroup instance added to the form @ html @public */
49 public k8sclusterForm: FormGroup;
50
51 /** Contains all vim account collections */
52 public vimAccountSelect: VimAccountDetails;
53
SANDHYA.JS26570112024-07-05 21:35:46 +053054 /** Input contains Modal dialog component Instance @public */
55 @Input() public profileType: string;
56
57 /** Input contains Modal dialog component Instance @public */
58 @Input() public profileID: string;
59
bacigalupof633dbf2022-03-25 17:24:56 +000060 /** Contains all deployment methods */
61 public deploymentMethodsSelect: TYPESECTION[] = [];
62
63 /** Submited deployments methods format */
64 public deploymentMethodsSubmit: Map<string, boolean>;
65
66 /** Contains all deployment methods selected */
SANDHYA.JS26570112024-07-05 21:35:46 +053067 public selectedDeploymentMethods: string[] = ['helm-chart-v3', 'juju-bundle'];
bacigalupof633dbf2022-03-25 17:24:56 +000068
kumaran.m3b4814a2020-05-01 19:48:54 +053069 /** Instance for active modal service @public */
70 public activeModal: NgbActiveModal;
71
72 /** Variable set for twoway bindng @public */
73 public vimAccountId: string;
74
SANDHYA.JS26570112024-07-05 21:35:46 +053075 /** contains url @public */
76 public clusterUrl: string;
77
kumaran.m3b4814a2020-05-01 19:48:54 +053078 /** Form submission Add */
79 public submitted: boolean = false;
80
SANDHYA.JS26570112024-07-05 21:35:46 +053081 /** contains payload */
82 public payload: K8SPayload;
83
kumaran.m3b4814a2020-05-01 19:48:54 +053084 /** Check the loading results @public */
85 public isLoadingResults: boolean = false;
86
87 /** Give the message for the loading @public */
88 public message: string = 'PLEASEWAIT';
89
90 /** Element ref for fileInputNets @public */
91 @ViewChild('fileInputNets', { static: true }) public fileInputNets: ElementRef;
92
93 /** Element ref for fileInputNetsLabel @public */
94 @ViewChild('fileInputNetsLabel', { static: true }) public fileInputNetsLabel: ElementRef;
95
96 /** Element ref for fileInputCredentials @public */
97 @ViewChild('fileInputCredentials', { static: true }) public fileInputCredentials: ElementRef;
98
99 /** Element ref for fileInputCredentialsLabel @public */
100 @ViewChild('fileInputCredentialsLabel', { static: true }) public fileInputCredentialsLabel: ElementRef;
101
102 /** FormBuilder instance added to the formBuilder @private */
103 private formBuilder: FormBuilder;
104
105 /** Utilizes rest service for any CRUD operations @private */
106 private restService: RestService;
107
108 /** Notifier service to popup notification @private */
109 private notifierService: NotifierService;
110
111 /** Contains tranlsate instance @private */
112 private translateService: TranslateService;
113
114 /** Controls the header form @private */
115 private headers: HttpHeaders;
116
117 /** Contains all methods related to shared @private */
118 private sharedService: SharedService;
119
120 constructor(injector: Injector) {
121 this.injector = injector;
122 this.restService = this.injector.get(RestService);
123 this.activeModal = this.injector.get(NgbActiveModal);
124 this.formBuilder = this.injector.get(FormBuilder);
125 this.notifierService = this.injector.get(NotifierService);
126 this.translateService = this.injector.get(TranslateService);
127 this.sharedService = this.injector.get(SharedService);
bacigalupof633dbf2022-03-25 17:24:56 +0000128 this.deploymentMethodsSelect = [
129 {
bacigalupof633dbf2022-03-25 17:24:56 +0000130 title: 'Helm v3',
131 value: 'helm-chart-v3'
132 },
133 {
134 title: 'Juju bundle',
135 value: 'juju-bundle'
136 }
137 ];
kumaran.m3b4814a2020-05-01 19:48:54 +0530138 }
139
140 public ngOnInit(): void {
141 /** On Initializing call the methods */
142 this.k8sclusterFormAction();
143 this.getDetailsvimAccount();
144 this.headers = new HttpHeaders({
145 Accept: 'application/json',
146 'Content-Type': 'application/json',
147 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
148 });
149 }
150
151 /** On modal initializing forms @public */
152 public k8sclusterFormAction(): void {
153 this.k8sclusterForm = this.formBuilder.group({
154 name: ['', [Validators.required]],
155 k8s_version: ['', [Validators.required]],
156 vim_account: [null, [Validators.required]],
157 description: ['', [Validators.required]],
158 nets: ['', [Validators.required]],
bacigalupof633dbf2022-03-25 17:24:56 +0000159 deployment_methods: ['', [Validators.required]],
SANDHYA.JS26570112024-07-05 21:35:46 +0530160 credentials: ['', [Validators.required]],
161 region_name: [''],
162 resource_group: [''],
163 node_count: ['', [Validators.required]],
164 node_size: ['', [Validators.required]]
kumaran.m3b4814a2020-05-01 19:48:54 +0530165 });
166 }
167
168 /** convenience getter for easy access to form fields */
169 get f(): FormGroup['controls'] { return this.k8sclusterForm.controls; }
170
171 /** Call the vimAccount details in the selection options @public */
172 public getDetailsvimAccount(): void {
173 this.isLoadingResults = true;
174 this.restService.getResource(environment.VIMACCOUNTS_URL).subscribe((vimAccounts: VimAccountDetails) => {
175 this.vimAccountSelect = vimAccounts;
176 this.isLoadingResults = false;
177 }, (error: ERRORDATA) => {
178 this.restService.handleError(error, 'get');
179 this.isLoadingResults = false;
180 });
181 }
182
SANDHYA.JS26570112024-07-05 21:35:46 +0530183
184 /** Contain selected vimAccount details @public */
185 public getDetailsvim(event: VimAccountDetails): void {
186 this.vimAccountId = event._id;
187 }
188
kumaran.m3b4814a2020-05-01 19:48:54 +0530189 /** On modal submit k8sAddClusterSubmit will called @public */
190 public k8sAddClusterSubmit(): void {
SANDHYA.JS26570112024-07-05 21:35:46 +0530191 if (this.profileType === 'Manage') {
192 this.getFormControl('nets').disable();
193 this.getFormControl('credentials').disable();
194 this.getFormControl('deployment_methods').disable();
195 this.manageCluster();
196 } else if (this.profileType === 'Register') {
197 this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/register';
198 this.getFormControl('region_name').disable();
199 this.getFormControl('resource_group').disable();
200 this.getFormControl('node_count').disable();
201 this.getFormControl('node_size').disable();
202 this.registerCluster();
203 } else if (this.profileType === 'upgrade') {
204 this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'upgrade';
205 this.getFormControl('region_name').disable();
206 this.getFormControl('resource_group').disable();
207 this.getFormControl('node_count').disable();
208 this.getFormControl('node_size').disable();
209 this.getFormControl('nets').disable();
210 this.getFormControl('credentials').disable();
211 this.getFormControl('deployment_methods').disable();
212 this.getFormControl('name').disable();
213 this.getFormControl('vim_account').disable();
214 this.getFormControl('description').disable();
215 this.updateCluster();
216 } else if (this.profileType === 'scale') {
217 this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'scale';
218 this.getFormControl('region_name').disable();
219 this.getFormControl('resource_group').disable();
220 this.getFormControl('k8s_version').disable();
221 this.getFormControl('node_size').disable();
222 this.getFormControl('nets').disable();
223 this.getFormControl('credentials').disable();
224 this.getFormControl('deployment_methods').disable();
225 this.getFormControl('name').disable();
226 this.getFormControl('vim_account').disable();
227 this.getFormControl('description').disable();
228 this.updateCluster();
229 }
230 }
231
232 /** Register cluster @public */
233 public registerCluster(): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530234 this.submitted = true;
235 this.sharedService.cleanForm(this.k8sclusterForm);
236 if (this.k8sclusterForm.invalid) {
237 return;
238 }
239 const modalData: MODALCLOSERESPONSEDATA = {
240 message: 'Done'
241 };
kumaran.m3b4814a2020-05-01 19:48:54 +0530242 const validJSONCredentails: boolean = this.sharedService.checkJson(this.k8sclusterForm.value.credentials);
243 if (validJSONCredentails) {
244 this.k8sclusterForm.value.credentials = jsyaml.load(this.k8sclusterForm.value.credentials.toString(), { json: true });
245 } else {
246 this.notifierService.notify('error', this.translateService.instant('INVALIDCONFIG'));
247 return;
248 }
249 const validJSONNets: boolean = this.sharedService.checkJson(this.k8sclusterForm.value.nets);
250 if (validJSONNets) {
251 this.k8sclusterForm.value.nets = jsyaml.load(this.k8sclusterForm.value.nets.toString(), { json: true });
252 } else {
253 this.notifierService.notify('error', this.translateService.instant('INVALIDCONFIG'));
254 return;
255 }
bacigalupof633dbf2022-03-25 17:24:56 +0000256
257 this.deploymentMethodsSubmit = new Map<string, boolean>();
258 /// Set deployment method Map
259 for (const methods of this.deploymentMethodsSelect) {
260 this.deploymentMethodsSubmit.set(methods.value, false);
261 }
262
263 this.k8sclusterForm.value.deployment_methods.forEach((dm: string): void => {
264 this.deploymentMethodsSubmit.set(dm, true);
265 });
266 // Transform Map to json object
267 const jsonDMObject: {} = {};
268 this.deploymentMethodsSubmit.forEach((value: boolean, key: string): void => {
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +0530269 // eslint-disable-next-line security/detect-object-injection
bacigalupof633dbf2022-03-25 17:24:56 +0000270 jsonDMObject[key] = value;
271 });
272
273 // Transform values to json
274 this.k8sclusterForm.value.deployment_methods = jsonDMObject;
275
SANDHYA.JS26570112024-07-05 21:35:46 +0530276 this.k8sclusterForm.value.vim_account = this.vimAccountId;
277
278 const apiURLHeader: APIURLHEADER = {
279 url: this.clusterUrl,
280 httpOptions: { headers: this.headers }
281 };
282
kumaran.m3b4814a2020-05-01 19:48:54 +0530283 this.isLoadingResults = true;
284 this.restService.postResource(apiURLHeader, this.k8sclusterForm.value).subscribe((result: {}) => {
285 this.activeModal.close(modalData);
286 this.isLoadingResults = false;
287 this.notifierService.notify('success', this.k8sclusterForm.value.name +
SANDHYA.JS26570112024-07-05 21:35:46 +0530288 this.translateService.instant('PAGE.K8S.REGISTEREDSUCCESSFULLY'));
289 }, (error: ERRORDATA) => {
290 this.restService.handleError(error, 'post');
291 this.isLoadingResults = false;
292 });
293 }
294
295 /** Manage cluster @public */
296 public manageCluster(): void {
297 this.submitted = true;
298 this.sharedService.cleanForm(this.k8sclusterForm);
299 if (this.k8sclusterForm.invalid) {
300 return;
301 }
302 const modalData: MODALCLOSERESPONSEDATA = {
303 message: 'Done'
304 };
305 const apiURLHeader: APIURLHEADER = {
306 url: environment.K8SCREATECLUSTER_URL,
307 httpOptions: { headers: this.headers }
308 };
309
310 this.isLoadingResults = true;
311 const payload: K8SPayload = {
312 name: this.k8sclusterForm.value.name,
313 vim_account: this.k8sclusterForm.value.vim_account,
314 location: this.k8sclusterForm.value.location,
315 region_name: this.k8sclusterForm.value.region_name,
316 resource_group: this.k8sclusterForm.value.resource_group,
317 k8s_version: this.k8sclusterForm.value.k8s_version,
318 node_size: this.k8sclusterForm.value.node_size,
319 node_count: Number(this.k8sclusterForm.value.node_count),
320 description: this.k8sclusterForm.value.description
321 };
322 if (this.k8sclusterForm.value.region_name === '') {
323 delete payload.region_name;
324 } else if (this.k8sclusterForm.value.resource_group === '') {
325 delete payload.resource_group;
326 }
327 if (this.k8sclusterForm.value.region_name === '' && this.k8sclusterForm.value.resource_group === '') {
328 delete payload.region_name;
329 delete payload.resource_group;
330 }
331 this.restService.postResource(apiURLHeader, payload).subscribe((result: {}) => {
332 this.activeModal.close(modalData);
333 this.isLoadingResults = false;
334 this.notifierService.notify('success', this.k8sclusterForm.value.name +
kumaran.m3b4814a2020-05-01 19:48:54 +0530335 this.translateService.instant('PAGE.K8S.CREATEDSUCCESSFULLY'));
336 }, (error: ERRORDATA) => {
337 this.restService.handleError(error, 'post');
338 this.isLoadingResults = false;
339 });
340 }
341
SANDHYA.JS26570112024-07-05 21:35:46 +0530342 /** Update cluster @public */
343 public updateCluster(): void {
344 this.submitted = true;
345 this.sharedService.cleanForm(this.k8sclusterForm);
346 if (this.k8sclusterForm.invalid) {
347 return;
348 }
349 const modalData: MODALCLOSERESPONSEDATA = {
350 message: 'Done'
351 };
352 const apiURLHeader: APIURLHEADER = {
353 url: this.clusterUrl,
354 httpOptions: { headers: this.headers }
355 };
356
357 this.isLoadingResults = true;
358 if (this.profileType === 'upgrade') {
359 this.payload = {
360 k8s_version: this.k8sclusterForm.value.k8s_version
361 };
362 } else if (this.profileType === 'scale') {
363 this.payload = {
364 node_count: this.k8sclusterForm.value.node_count
365 };
366 }
367 this.restService.postResource(apiURLHeader, this.payload).subscribe((result: {}) => {
368 this.activeModal.close(modalData);
369 this.isLoadingResults = false;
370 this.notifierService.notify('success',
371 this.translateService.instant('PAGE.K8S.UPDATEDSUCCESSFULLY'));
372 }, (error: ERRORDATA) => {
373 this.restService.handleError(error, 'post');
374 this.isLoadingResults = false;
375 });
376 }
377
kumaran.m3b4814a2020-05-01 19:48:54 +0530378 /** Nets file process @private */
379 public netsFile(files: FileList): void {
380 if (files && files.length === 1) {
381 this.sharedService.getFileString(files, 'json').then((fileContent: string): void => {
382 const getNetsJson: string = jsyaml.load(fileContent, { json: true });
kumaran.m3b4814a2020-05-01 19:48:54 +0530383 this.k8sclusterForm.get('nets').setValue(JSON.stringify(getNetsJson));
384 }).catch((err: string): void => {
385 if (err === 'typeError') {
386 this.notifierService.notify('error', this.translateService.instant('JSONFILETYPEERRROR'));
387 } else {
388 this.notifierService.notify('error', this.translateService.instant('ERROR'));
389 }
390 this.fileInputNetsLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
391 this.fileInputNets.nativeElement.value = null;
392 });
393 } else if (files && files.length > 1) {
394 this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
395 }
396 this.fileInputNetsLabel.nativeElement.innerText = files[0].name;
397 this.fileInputNets.nativeElement.value = null;
398 }
399
400 /** credentials file process @private */
401 public credentialsFile(files: FileList): void {
402 if (files && files.length === 1) {
403 this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
404 const getCredentialsJson: string = jsyaml.load(fileContent, { json: true });
kumaran.m3b4814a2020-05-01 19:48:54 +0530405 this.k8sclusterForm.get('credentials').setValue(JSON.stringify(getCredentialsJson));
406 }).catch((err: string): void => {
407 if (err === 'typeError') {
408 this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
409 } else {
410 this.notifierService.notify('error', this.translateService.instant('ERROR'));
411 }
412 this.fileInputCredentialsLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
413 this.fileInputCredentials.nativeElement.value = null;
414 });
415 } else if (files && files.length > 1) {
416 this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
417 }
418 this.fileInputCredentialsLabel.nativeElement.innerText = files[0].name;
419 this.fileInputCredentials.nativeElement.value = null;
420 }
SANDHYA.JS26570112024-07-05 21:35:46 +0530421
422 /** Used to get the AbstractControl of controlName passed @private */
423 private getFormControl(controlName: string): AbstractControl {
424 // eslint-disable-next-line security/detect-object-injection
425 return this.k8sclusterForm.controls[controlName];
426 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530427}