2 Copyright 2020 TATA ELXSI
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
8 http://www.apache.org/licenses/LICENSE-2.0
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.
16 Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
19 * @file K8sAddClusterComponent.ts.
21 import { isNullOrUndefined } from 'util';
22 import { HttpHeaders } from '@angular/common/http';
23 import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
24 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
25 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
26 import { TranslateService } from '@ngx-translate/core';
27 import { NotifierService } from 'angular-notifier';
28 import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, TYPESECTION } from 'CommonModel';
29 import { environment } from 'environment';
30 import * as jsyaml from 'js-yaml';
31 import { RestService } from 'RestService';
32 import { SharedService } from 'SharedService';
33 import { VimAccountDetails } from 'VimAccountModel';
36 * @Component takes K8sAddClusterComponent.html as template url
39 selector: 'app-k8s-add-cluster',
40 templateUrl: './K8sAddClusterComponent.html',
41 styleUrls: ['./K8sAddClusterComponent.scss']
43 /** Exporting a class @exports K8sAddClusterComponent */
44 export class K8sAddClusterComponent implements OnInit {
45 /** To inject services @public */
46 public injector: Injector;
48 /** FormGroup instance added to the form @ html @public */
49 public k8sclusterForm: FormGroup;
51 /** Contains all vim account collections */
52 public vimAccountSelect: VimAccountDetails;
54 /** Contains all deployment methods */
55 public deploymentMethodsSelect: TYPESECTION[] = [];
57 /** Submited deployments methods format */
58 public deploymentMethodsSubmit: Map<string, boolean>;
60 /** Contains all deployment methods selected */
61 public selectedDeploymentMethods: string[] = ['helm-chart', 'helm-chart-v3', 'juju-bundle'];
63 /** Instance for active modal service @public */
64 public activeModal: NgbActiveModal;
66 /** Variable set for twoway bindng @public */
67 public vimAccountId: string;
69 /** Form submission Add */
70 public submitted: boolean = false;
72 /** Check the loading results @public */
73 public isLoadingResults: boolean = false;
75 /** Give the message for the loading @public */
76 public message: string = 'PLEASEWAIT';
78 /** Element ref for fileInputNets @public */
79 @ViewChild('fileInputNets', { static: true }) public fileInputNets: ElementRef;
81 /** Element ref for fileInputNetsLabel @public */
82 @ViewChild('fileInputNetsLabel', { static: true }) public fileInputNetsLabel: ElementRef;
84 /** Element ref for fileInputCredentials @public */
85 @ViewChild('fileInputCredentials', { static: true }) public fileInputCredentials: ElementRef;
87 /** Element ref for fileInputCredentialsLabel @public */
88 @ViewChild('fileInputCredentialsLabel', { static: true }) public fileInputCredentialsLabel: ElementRef;
90 /** FormBuilder instance added to the formBuilder @private */
91 private formBuilder: FormBuilder;
93 /** Utilizes rest service for any CRUD operations @private */
94 private restService: RestService;
96 /** Notifier service to popup notification @private */
97 private notifierService: NotifierService;
99 /** Contains tranlsate instance @private */
100 private translateService: TranslateService;
102 /** Controls the header form @private */
103 private headers: HttpHeaders;
105 /** Contains all methods related to shared @private */
106 private sharedService: SharedService;
108 constructor(injector: Injector) {
109 this.injector = injector;
110 this.restService = this.injector.get(RestService);
111 this.activeModal = this.injector.get(NgbActiveModal);
112 this.formBuilder = this.injector.get(FormBuilder);
113 this.notifierService = this.injector.get(NotifierService);
114 this.translateService = this.injector.get(TranslateService);
115 this.sharedService = this.injector.get(SharedService);
116 this.deploymentMethodsSelect = [
123 value: 'helm-chart-v3'
126 title: 'Juju bundle',
132 public ngOnInit(): void {
133 /** On Initializing call the methods */
134 this.k8sclusterFormAction();
135 this.getDetailsvimAccount();
136 this.headers = new HttpHeaders({
137 Accept: 'application/json',
138 'Content-Type': 'application/json',
139 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
143 /** On modal initializing forms @public */
144 public k8sclusterFormAction(): void {
145 this.k8sclusterForm = this.formBuilder.group({
146 name: ['', [Validators.required]],
147 k8s_version: ['', [Validators.required]],
148 vim_account: [null, [Validators.required]],
149 description: ['', [Validators.required]],
150 nets: ['', [Validators.required]],
151 deployment_methods: ['', [Validators.required]],
152 credentials: ['', [Validators.required]]
156 /** convenience getter for easy access to form fields */
157 get f(): FormGroup['controls'] { return this.k8sclusterForm.controls; }
159 /** Call the vimAccount details in the selection options @public */
160 public getDetailsvimAccount(): void {
161 this.isLoadingResults = true;
162 this.restService.getResource(environment.VIMACCOUNTS_URL).subscribe((vimAccounts: VimAccountDetails) => {
163 this.vimAccountSelect = vimAccounts;
164 this.isLoadingResults = false;
165 }, (error: ERRORDATA) => {
166 this.restService.handleError(error, 'get');
167 this.isLoadingResults = false;
171 /** On modal submit k8sAddClusterSubmit will called @public */
172 public k8sAddClusterSubmit(): void {
173 this.submitted = true;
174 this.sharedService.cleanForm(this.k8sclusterForm);
175 if (this.k8sclusterForm.invalid) {
178 const modalData: MODALCLOSERESPONSEDATA = {
181 const apiURLHeader: APIURLHEADER = {
182 url: environment.K8SCLUSTER_URL,
183 httpOptions: { headers: this.headers }
185 const validJSONCredentails: boolean = this.sharedService.checkJson(this.k8sclusterForm.value.credentials);
186 if (validJSONCredentails) {
187 this.k8sclusterForm.value.credentials = jsyaml.load(this.k8sclusterForm.value.credentials.toString(), { json: true });
189 this.notifierService.notify('error', this.translateService.instant('INVALIDCONFIG'));
192 const validJSONNets: boolean = this.sharedService.checkJson(this.k8sclusterForm.value.nets);
194 this.k8sclusterForm.value.nets = jsyaml.load(this.k8sclusterForm.value.nets.toString(), { json: true });
196 this.notifierService.notify('error', this.translateService.instant('INVALIDCONFIG'));
200 this.deploymentMethodsSubmit = new Map<string, boolean>();
201 /// Set deployment method Map
202 for (const methods of this.deploymentMethodsSelect) {
203 this.deploymentMethodsSubmit.set(methods.value, false);
206 this.k8sclusterForm.value.deployment_methods.forEach((dm: string): void => {
207 this.deploymentMethodsSubmit.set(dm, true);
209 // Transform Map to json object
210 const jsonDMObject: {} = {};
211 this.deploymentMethodsSubmit.forEach((value: boolean, key: string): void => {
212 // eslint-disable-next-line security/detect-object-injection
213 jsonDMObject[key] = value;
216 // Transform values to json
217 this.k8sclusterForm.value.deployment_methods = jsonDMObject;
219 this.isLoadingResults = true;
220 this.restService.postResource(apiURLHeader, this.k8sclusterForm.value).subscribe((result: {}) => {
221 this.activeModal.close(modalData);
222 this.isLoadingResults = false;
223 this.notifierService.notify('success', this.k8sclusterForm.value.name +
224 this.translateService.instant('PAGE.K8S.CREATEDSUCCESSFULLY'));
225 }, (error: ERRORDATA) => {
226 this.restService.handleError(error, 'post');
227 this.isLoadingResults = false;
231 /** Nets file process @private */
232 public netsFile(files: FileList): void {
233 if (files && files.length === 1) {
234 this.sharedService.getFileString(files, 'json').then((fileContent: string): void => {
235 const getNetsJson: string = jsyaml.load(fileContent, { json: true });
236 this.k8sclusterForm.get('nets').setValue(JSON.stringify(getNetsJson));
237 }).catch((err: string): void => {
238 if (err === 'typeError') {
239 this.notifierService.notify('error', this.translateService.instant('JSONFILETYPEERRROR'));
241 this.notifierService.notify('error', this.translateService.instant('ERROR'));
243 this.fileInputNetsLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
244 this.fileInputNets.nativeElement.value = null;
246 } else if (files && files.length > 1) {
247 this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
249 this.fileInputNetsLabel.nativeElement.innerText = files[0].name;
250 this.fileInputNets.nativeElement.value = null;
253 /** credentials file process @private */
254 public credentialsFile(files: FileList): void {
255 if (files && files.length === 1) {
256 this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
257 const getCredentialsJson: string = jsyaml.load(fileContent, { json: true });
258 this.k8sclusterForm.get('credentials').setValue(JSON.stringify(getCredentialsJson));
259 }).catch((err: string): void => {
260 if (err === 'typeError') {
261 this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
263 this.notifierService.notify('error', this.translateService.instant('ERROR'));
265 this.fileInputCredentialsLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
266 this.fileInputCredentials.nativeElement.value = null;
268 } else if (files && files.length > 1) {
269 this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
271 this.fileInputCredentialsLabel.nativeElement.innerText = files[0].name;
272 this.fileInputCredentials.nativeElement.value = null;