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 { HttpHeaders } from '@angular/common/http';
22 import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
23 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
24 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
25 import { TranslateService } from '@ngx-translate/core';
26 import { NotifierService } from 'angular-notifier';
27 import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, TYPESECTION } from 'CommonModel';
28 import { environment } from 'environment';
29 import * as jsyaml from 'js-yaml';
30 import { RestService } from 'RestService';
31 import { SharedService, isNullOrUndefined } from 'SharedService';
32 import { VimAccountDetails } from 'VimAccountModel';
35 * @Component takes K8sAddClusterComponent.html as template url
38 selector: 'app-k8s-add-cluster',
39 templateUrl: './K8sAddClusterComponent.html',
40 styleUrls: ['./K8sAddClusterComponent.scss']
42 /** Exporting a class @exports K8sAddClusterComponent */
43 export class K8sAddClusterComponent implements OnInit {
44 /** To inject services @public */
45 public injector: Injector;
47 /** FormGroup instance added to the form @ html @public */
48 public k8sclusterForm: FormGroup;
50 /** Contains all vim account collections */
51 public vimAccountSelect: VimAccountDetails;
53 /** Contains all deployment methods */
54 public deploymentMethodsSelect: TYPESECTION[] = [];
56 /** Submited deployments methods format */
57 public deploymentMethodsSubmit: Map<string, boolean>;
59 /** Contains all deployment methods selected */
60 public selectedDeploymentMethods: string[] = ['helm-chart', 'helm-chart-v3', 'juju-bundle'];
62 /** Instance for active modal service @public */
63 public activeModal: NgbActiveModal;
65 /** Variable set for twoway bindng @public */
66 public vimAccountId: string;
68 /** Form submission Add */
69 public submitted: boolean = false;
71 /** Check the loading results @public */
72 public isLoadingResults: boolean = false;
74 /** Give the message for the loading @public */
75 public message: string = 'PLEASEWAIT';
77 /** Element ref for fileInputNets @public */
78 @ViewChild('fileInputNets', { static: true }) public fileInputNets: ElementRef;
80 /** Element ref for fileInputNetsLabel @public */
81 @ViewChild('fileInputNetsLabel', { static: true }) public fileInputNetsLabel: ElementRef;
83 /** Element ref for fileInputCredentials @public */
84 @ViewChild('fileInputCredentials', { static: true }) public fileInputCredentials: ElementRef;
86 /** Element ref for fileInputCredentialsLabel @public */
87 @ViewChild('fileInputCredentialsLabel', { static: true }) public fileInputCredentialsLabel: ElementRef;
89 /** FormBuilder instance added to the formBuilder @private */
90 private formBuilder: FormBuilder;
92 /** Utilizes rest service for any CRUD operations @private */
93 private restService: RestService;
95 /** Notifier service to popup notification @private */
96 private notifierService: NotifierService;
98 /** Contains tranlsate instance @private */
99 private translateService: TranslateService;
101 /** Controls the header form @private */
102 private headers: HttpHeaders;
104 /** Contains all methods related to shared @private */
105 private sharedService: SharedService;
107 constructor(injector: Injector) {
108 this.injector = injector;
109 this.restService = this.injector.get(RestService);
110 this.activeModal = this.injector.get(NgbActiveModal);
111 this.formBuilder = this.injector.get(FormBuilder);
112 this.notifierService = this.injector.get(NotifierService);
113 this.translateService = this.injector.get(TranslateService);
114 this.sharedService = this.injector.get(SharedService);
115 this.deploymentMethodsSelect = [
122 value: 'helm-chart-v3'
125 title: 'Juju bundle',
131 public ngOnInit(): void {
132 /** On Initializing call the methods */
133 this.k8sclusterFormAction();
134 this.getDetailsvimAccount();
135 this.headers = new HttpHeaders({
136 Accept: 'application/json',
137 'Content-Type': 'application/json',
138 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
142 /** On modal initializing forms @public */
143 public k8sclusterFormAction(): void {
144 this.k8sclusterForm = this.formBuilder.group({
145 name: ['', [Validators.required]],
146 k8s_version: ['', [Validators.required]],
147 vim_account: [null, [Validators.required]],
148 description: ['', [Validators.required]],
149 nets: ['', [Validators.required]],
150 deployment_methods: ['', [Validators.required]],
151 credentials: ['', [Validators.required]]
155 /** convenience getter for easy access to form fields */
156 get f(): FormGroup['controls'] { return this.k8sclusterForm.controls; }
158 /** Call the vimAccount details in the selection options @public */
159 public getDetailsvimAccount(): void {
160 this.isLoadingResults = true;
161 this.restService.getResource(environment.VIMACCOUNTS_URL).subscribe((vimAccounts: VimAccountDetails) => {
162 this.vimAccountSelect = vimAccounts;
163 this.isLoadingResults = false;
164 }, (error: ERRORDATA) => {
165 this.restService.handleError(error, 'get');
166 this.isLoadingResults = false;
170 /** On modal submit k8sAddClusterSubmit will called @public */
171 public k8sAddClusterSubmit(): void {
172 this.submitted = true;
173 this.sharedService.cleanForm(this.k8sclusterForm);
174 if (this.k8sclusterForm.invalid) {
177 const modalData: MODALCLOSERESPONSEDATA = {
180 const apiURLHeader: APIURLHEADER = {
181 url: environment.K8SCLUSTER_URL,
182 httpOptions: { headers: this.headers }
184 const validJSONCredentails: boolean = this.sharedService.checkJson(this.k8sclusterForm.value.credentials);
185 if (validJSONCredentails) {
186 this.k8sclusterForm.value.credentials = jsyaml.load(this.k8sclusterForm.value.credentials.toString(), { json: true });
188 this.notifierService.notify('error', this.translateService.instant('INVALIDCONFIG'));
191 const validJSONNets: boolean = this.sharedService.checkJson(this.k8sclusterForm.value.nets);
193 this.k8sclusterForm.value.nets = jsyaml.load(this.k8sclusterForm.value.nets.toString(), { json: true });
195 this.notifierService.notify('error', this.translateService.instant('INVALIDCONFIG'));
199 this.deploymentMethodsSubmit = new Map<string, boolean>();
200 /// Set deployment method Map
201 for (const methods of this.deploymentMethodsSelect) {
202 this.deploymentMethodsSubmit.set(methods.value, false);
205 this.k8sclusterForm.value.deployment_methods.forEach((dm: string): void => {
206 this.deploymentMethodsSubmit.set(dm, true);
208 // Transform Map to json object
209 const jsonDMObject: {} = {};
210 this.deploymentMethodsSubmit.forEach((value: boolean, key: string): void => {
211 // eslint-disable-next-line security/detect-object-injection
212 jsonDMObject[key] = value;
215 // Transform values to json
216 this.k8sclusterForm.value.deployment_methods = jsonDMObject;
218 this.isLoadingResults = true;
219 this.restService.postResource(apiURLHeader, this.k8sclusterForm.value).subscribe((result: {}) => {
220 this.activeModal.close(modalData);
221 this.isLoadingResults = false;
222 this.notifierService.notify('success', this.k8sclusterForm.value.name +
223 this.translateService.instant('PAGE.K8S.CREATEDSUCCESSFULLY'));
224 }, (error: ERRORDATA) => {
225 this.restService.handleError(error, 'post');
226 this.isLoadingResults = false;
230 /** Nets file process @private */
231 public netsFile(files: FileList): void {
232 if (files && files.length === 1) {
233 this.sharedService.getFileString(files, 'json').then((fileContent: string): void => {
234 const getNetsJson: string = jsyaml.load(fileContent, { json: true });
235 this.k8sclusterForm.get('nets').setValue(JSON.stringify(getNetsJson));
236 }).catch((err: string): void => {
237 if (err === 'typeError') {
238 this.notifierService.notify('error', this.translateService.instant('JSONFILETYPEERRROR'));
240 this.notifierService.notify('error', this.translateService.instant('ERROR'));
242 this.fileInputNetsLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
243 this.fileInputNets.nativeElement.value = null;
245 } else if (files && files.length > 1) {
246 this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
248 this.fileInputNetsLabel.nativeElement.innerText = files[0].name;
249 this.fileInputNets.nativeElement.value = null;
252 /** credentials file process @private */
253 public credentialsFile(files: FileList): void {
254 if (files && files.length === 1) {
255 this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
256 const getCredentialsJson: string = jsyaml.load(fileContent, { json: true });
257 this.k8sclusterForm.get('credentials').setValue(JSON.stringify(getCredentialsJson));
258 }).catch((err: string): void => {
259 if (err === 'typeError') {
260 this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
262 this.notifierService.notify('error', this.translateService.instant('ERROR'));
264 this.fileInputCredentialsLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
265 this.fileInputCredentials.nativeElement.value = null;
267 } else if (files && files.length > 1) {
268 this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
270 this.fileInputCredentialsLabel.nativeElement.innerText = files[0].name;
271 this.fileInputCredentials.nativeElement.value = null;