NG-UI BUG 1118 YAML not supported in config text-area when launching NS
[osm/NG-UI.git] / src / app / packages / instantiate-ns / InstantiateNsComponent.ts
1 /*
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 Instantiate NS Modal Component.
20  */
21 import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
22 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
23 import { Router } from '@angular/router';
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 } from 'CommonModel';
28 import { DataService } from 'DataService';
29 import { environment } from 'environment';
30 import * as jsyaml from 'js-yaml';
31 import { NSCREATEPARAMS, NSData, NSDDetails } from 'NSDModel';
32 import { RestService } from 'RestService';
33 import { SharedService } from 'SharedService';
34 import { isNullOrUndefined } from 'util';
35 import { VimAccountDetails } from 'VimAccountModel';
36
37 /**
38  * Creating component
39  * @Component takes InstantiateNsComponent.html as template url
40  */
41 @Component({
42   selector: 'app-instantiate-ns',
43   templateUrl: './InstantiateNsComponent.html',
44   styleUrls: ['./InstantiateNsComponent.scss']
45 })
46 /** Exporting a class @exports InstantiateNsComponent */
47 export class InstantiateNsComponent implements OnInit {
48   /** To inject services @public */
49   public injector: Injector;
50
51   /** Contains all the nsd data collections */
52   public nsdSelect: NSDDetails;
53
54   /** FormGroup instance added to the form @ html @public */
55   public instantiateForm: FormGroup;
56
57   /** Contains all vim account collections */
58   public vimAccountSelect: VimAccountDetails;
59
60   /** Instance for active modal service @public */
61   public activeModal: NgbActiveModal;
62
63   /** Variable set for twoway binding @public */
64   public nsdId: string;
65
66   /** Variable set for twoway bindng @public  */
67   public vimAccountId: string;
68
69   /** Form submission Add */
70   public submitted: boolean = false;
71
72   /** Check the loading results @public */
73   public isLoadingResults: boolean = false;
74
75   /** Give the message for the loading @public */
76   public message: string = 'PLEASEWAIT';
77
78   /** Element ref for fileInputConfig @public */
79   @ViewChild('fileInputConfig', { static: true }) public fileInputConfig: ElementRef;
80
81   /** Element ref for fileInputConfigLabel @public */
82   @ViewChild('fileInputConfigLabel', { static: true }) public fileInputConfigLabel: ElementRef;
83
84   /** Element ref for fileInputSSH @public */
85   @ViewChild('fileInputSSH', { static: true }) public fileInputSSH: ElementRef;
86
87   /** Element ref for fileInputSSHLabel @public */
88   @ViewChild('fileInputSSHLabel', { static: true }) public fileInputSSHLabel: ElementRef;
89
90   /** Holds teh instance of AuthService class of type AuthService @private */
91   private router: Router;
92
93   /** FormBuilder instance added to the formBuilder @private */
94   private formBuilder: FormBuilder;
95
96   /** Utilizes rest service for any CRUD operations @private */
97   private restService: RestService;
98
99   /** Utilizes data service for any communication @private */
100   private dataService: DataService;
101
102   /** Notifier service to popup notification @private */
103   private notifierService: NotifierService;
104
105   /** Contains tranlsate instance @private */
106   private translateService: TranslateService;
107
108   /** Contains all methods related to shared @private */
109   private sharedService: SharedService;
110
111   /** Contains the ssh key to be hosted in dom @private */
112   private copySSHKey: string;
113
114   constructor(injector: Injector) {
115     this.injector = injector;
116     this.restService = this.injector.get(RestService);
117     this.activeModal = this.injector.get(NgbActiveModal);
118     this.formBuilder = this.injector.get(FormBuilder);
119     this.dataService = this.injector.get(DataService);
120     this.notifierService = this.injector.get(NotifierService);
121     this.router = this.injector.get(Router);
122     this.translateService = this.injector.get(TranslateService);
123     this.sharedService = this.injector.get(SharedService);
124   }
125
126   public ngOnInit(): void {
127     /** Setting up initial value for NSD */
128     this.dataService.currentMessage.subscribe((event: NSData) => {
129       if (event.identifier !== undefined || event.identifier !== '' || event.identifier !== null) {
130         this.nsdId = event.identifier;
131       }
132     });
133     /** On Initializing call the methods */
134     this.instantiateFormAction();
135     this.getDetailsnsd();
136     this.getDetailsvimAccount();
137   }
138
139   /** On modal initializing forms  @public */
140   public instantiateFormAction(): void {
141     this.instantiateForm = this.formBuilder.group({
142       nsName: ['', [Validators.required]],
143       nsDescription: ['', [Validators.required]],
144       nsdId: ['', [Validators.required]],
145       vimAccountId: ['', [Validators.required]],
146       ssh_keys: [null],
147       config: [null]
148     });
149   }
150
151   /** Convenience getter for easy access to form fields */
152   get f(): FormGroup['controls'] { return this.instantiateForm.controls; }
153
154   /** Call the nsd details in the selection options @public */
155   public getDetailsnsd(): void {
156     this.restService.getResource(environment.NSDESCRIPTORSCONTENT_URL).subscribe((nsPackages: NSDDetails) => {
157       this.nsdSelect = nsPackages;
158     }, (error: ERRORDATA) => {
159       this.restService.handleError(error, 'get');
160     });
161   }
162
163   /** Call the vimAccount details in the selection options @public */
164   public getDetailsvimAccount(): void {
165     this.restService.getResource(environment.VIMACCOUNTS_URL).subscribe((vimAccounts: VimAccountDetails) => {
166       this.vimAccountSelect = vimAccounts;
167     }, (error: ERRORDATA) => {
168       this.restService.handleError(error, 'get');
169     });
170   }
171
172   /** On modal submit instantiateNsSubmit will called @public */
173   public instantiateNsSubmit(): void {
174     this.submitted = true;
175     this.sharedService.cleanForm(this.instantiateForm);
176     if (this.instantiateForm.invalid) {
177       return;
178     }
179     const modalData: MODALCLOSERESPONSEDATA = {
180       message: 'Done'
181     };
182     if (isNullOrUndefined(this.instantiateForm.value.ssh_keys) || this.instantiateForm.value.ssh_keys === '') {
183       delete this.instantiateForm.value.ssh_keys;
184     } else {
185       this.copySSHKey = JSON.parse(JSON.stringify(this.instantiateForm.value.ssh_keys));
186       // tslint:disable-next-line: no-backbone-get-set-outside-model
187       this.instantiateForm.get('ssh_keys').setValue([this.copySSHKey]);
188     }
189     if (isNullOrUndefined(this.instantiateForm.value.config) || this.instantiateForm.value.config === '') {
190       delete this.instantiateForm.value.config;
191     } else {
192       const validJSON: boolean = this.sharedService.checkJson(this.instantiateForm.value.config);
193       if (validJSON) {
194         this.instantiateForm.value.config = JSON.parse(this.instantiateForm.value.config);
195         Object.keys(this.instantiateForm.value.config).forEach((item: string) => {
196           this.instantiateForm.value[item] = this.instantiateForm.value.config[item];
197         });
198         delete this.instantiateForm.value.config;
199       } else {
200         const getConfigJson: string = jsyaml.load(this.instantiateForm.value.config, { json: true });
201         Object.keys(getConfigJson).forEach((item: string) => {
202           this.instantiateForm.value[item] = getConfigJson[item];
203         });
204         delete this.instantiateForm.value.config;
205       }
206     }
207     const apiURLHeader: APIURLHEADER = {
208       url: environment.NSINSTANCESCONTENT_URL
209     };
210     this.isLoadingResults = true;
211     this.restService.postResource(apiURLHeader, this.instantiateForm.value).subscribe((result: {}) => {
212       this.activeModal.close(modalData);
213       this.notifierService.notify('success', this.instantiateForm.value.nsName +
214         this.translateService.instant('PAGE.NSINSTANCE.CREATEDSUCCESSFULLY'));
215       this.router.navigate(['/instances/ns']).catch();
216     }, (error: ERRORDATA) => {
217       this.isLoadingResults = false;
218       this.restService.handleError(error, 'post');
219       if (!isNullOrUndefined(this.copySSHKey)) {
220         // tslint:disable-next-line: no-backbone-get-set-outside-model
221         this.instantiateForm.get('ssh_keys').setValue(this.copySSHKey);
222       }
223     });
224   }
225
226   /** ssh file process @private */
227   public sshFile(files: FileList): void {
228     if (files && files.length === 1) {
229       this.sharedService.getFileString(files, 'pub').then((fileContent: string): void => {
230         const getSSHJson: string = jsyaml.load(fileContent, { json: true });
231         // tslint:disable-next-line: no-backbone-get-set-outside-model
232         this.instantiateForm.get('ssh_keys').setValue(getSSHJson);
233       }).catch((err: string): void => {
234         if (err === 'typeError') {
235           this.notifierService.notify('error', this.translateService.instant('PUBFILETYPEERRROR'));
236         } else {
237           this.notifierService.notify('error', this.translateService.instant('ERROR'));
238         }
239         this.fileInputSSHLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
240         this.fileInputSSH.nativeElement.value = null;
241       });
242     } else if (files && files.length > 1) {
243       this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
244     }
245     this.fileInputSSHLabel.nativeElement.innerText = files[0].name;
246     this.fileInputSSH.nativeElement.value = null;
247   }
248
249   /** Config file process @private */
250   public configFile(files: FileList): void {
251     if (files && files.length === 1) {
252       const fileFormat: string = this.sharedService.fetchFileExtension(files).toLocaleLowerCase();
253       if (fileFormat === 'yaml' || fileFormat === 'yml') {
254         this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
255           // tslint:disable-next-line: no-backbone-get-set-outside-model
256           this.instantiateForm.get('config').setValue(fileContent);
257         }).catch((err: string): void => {
258           if (err === 'typeError') {
259             this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
260           } else {
261             this.notifierService.notify('error', this.translateService.instant('ERROR'));
262           }
263           this.fileInputConfigLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
264           this.fileInputConfig.nativeElement.value = null;
265         });
266       } else if (fileFormat === 'json') {
267         this.sharedService.getFileString(files, 'json').then((fileContent: string): void => {
268           const getConfigJson: string = jsyaml.load(fileContent, { json: true });
269           // tslint:disable-next-line: no-backbone-get-set-outside-model
270           this.instantiateForm.get('config').setValue(JSON.stringify(getConfigJson));
271         }).catch((err: string): void => {
272           if (err === 'typeError') {
273             this.notifierService.notify('error', this.translateService.instant('JSONFILETYPEERRROR'));
274           } else {
275             this.notifierService.notify('error', this.translateService.instant('ERROR'));
276           }
277           this.fileInputConfigLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
278           this.fileInputConfig.nativeElement.value = null;
279         });
280       }
281     } else if (files && files.length > 1) {
282       this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
283     }
284     this.fileInputConfigLabel.nativeElement.innerText = files[0].name;
285     this.fileInputConfig.nativeElement.value = null;
286   }
287 }