blob: 0dff17a861f963ee66e88d4b3354241ab9419f5a [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 Info Compose Package Model
20 */
21import { HttpClient, HttpHeaders } from '@angular/common/http';
SANDHYA.JS07decc02024-07-01 21:50:48 +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 { Router } from '@angular/router';
25import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
26import { TranslateService } from '@ngx-translate/core';
27import { NotifierService } from 'angular-notifier';
SANDHYA.JS07decc02024-07-01 21:50:48 +053028import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, URLPARAMS } from 'CommonModel';
kumaran.m3b4814a2020-05-01 19:48:54 +053029import { DataService } from 'DataService';
30import { environment } from 'environment';
31import * as jsyaml from 'js-yaml';
SANDHYA.JS07decc02024-07-01 21:50:48 +053032import { NSConfigData } from 'NSCONFIGTEMPLATEMODEL';
33import { NSDDetails } from 'NSDModel';
kumaran.m3b4814a2020-05-01 19:48:54 +053034import * as pako from 'pako';
35import { RestService } from 'RestService';
SANDHYA.JS07decc02024-07-01 21:50:48 +053036import { SharedService, isNullOrUndefined } from 'SharedService';
kumaran.m3b4814a2020-05-01 19:48:54 +053037
38/** This is added globally by the tar.js library */
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +053039// eslint-disable-next-line @typescript-eslint/no-explicit-any
kumaran.m3b4814a2020-05-01 19:48:54 +053040declare const Tar: any;
41
42/**
43 * Creating component
44 * @Component takes ComposePackages.html as template url
45 */
46@Component({
47 templateUrl: './ComposePackages.html',
48 styleUrls: ['./ComposePackages.scss']
49})
50/** Exporting a class @exports ComposePackages */
SANDHYA.JS0a34dfa2023-04-25 23:59:41 +053051// eslint-disable-next-line @angular-eslint/component-class-suffix
kumaran.m3b4814a2020-05-01 19:48:54 +053052export class ComposePackages implements OnInit {
53 /** Invoke service injectors @public */
54 public injector: Injector;
55
56 /** dataService to pass the data from one component to another @public */
57 public dataService: DataService;
58
59 /** Varaibles to hold http client @public */
60 public httpClient: HttpClient;
61
62 /** Instance for active modal service @public */
63 public activeModal: NgbActiveModal;
64
65 /** FormGroup instance added to the form @ html @public */
66 public packagesForm: FormGroup;
67
68 /** Form submission Add */
SANDHYA.JS07decc02024-07-01 21:50:48 +053069 public submitted = false;
kumaran.m3b4814a2020-05-01 19:48:54 +053070
71 /** To handle loader status for API call @public */
SANDHYA.JS07decc02024-07-01 21:50:48 +053072 public isLoadingResults = false;
kumaran.m3b4814a2020-05-01 19:48:54 +053073
74 /** Give the message for the loading @public */
SANDHYA.JS07decc02024-07-01 21:50:48 +053075 public message = 'PLEASEWAIT';
76
77 /** contains NSD name @public */
78 public nsName: {}[] = [];
79
80 /** contains NSD details @public */
81 public nsdDetails: {}[];
82
83 /** contains NSD details filtered by id @public */
84 public nsdName: string;
85
86 /** Contains config details @public */
87 public config: string;
88
89 /** contains NSD details filtered by name @public */
90 public nsId: string;
91
92 /** Check if template or not @public */
93 public template = false;
94
95 /** Data of NS config @public */
96 public details: NSConfigData;
97
98 /** Data of NF packages @public */
99 public nsConfigData: NSConfigData[] = [];
100
101 /** Element ref for fileInputConfig @public */
102 @ViewChild('fileInputConfig') fileInputConfig: ElementRef<HTMLInputElement>;
103
104 /** Element ref for fileInputConfigLabel @public */
105 @ViewChild('fileInputConfigLabel') fileInputConfigLabel: ElementRef<HTMLLabelElement>;
kumaran.m3b4814a2020-05-01 19:48:54 +0530106
107 /** FormBuilder instance added to the formBuilder @private */
108 private formBuilder: FormBuilder;
109
110 /** Instance of the rest service @private */
111 private restService: RestService;
112
113 /** Notifier service to popup notification @private */
114 private notifierService: NotifierService;
115
116 /** Controls the header form @private */
117 private headers: HttpHeaders;
118
SANDHYA.JS07decc02024-07-01 21:50:48 +0530119 /** Input contains component objects @public */
120 @Input() public params: URLPARAMS;
kumaran.m3b4814a2020-05-01 19:48:54 +0530121
122 /** Holds the end point @private */
123 private endPoint: string;
124
SANDHYA.JS07decc02024-07-01 21:50:48 +0530125 /** ModalData instance of modal @private */
126 private modalData: MODALCLOSERESPONSEDATA;
127
kumaran.m3b4814a2020-05-01 19:48:54 +0530128 /** Contains all methods related to shared @private */
129 private sharedService: SharedService;
130
131 /** Holds teh instance of AuthService class of type AuthService @private */
132 private router: Router;
133
134 /** Contains tranlsate instance @private */
135 private translateService: TranslateService;
136
137 constructor(injector: Injector) {
138 this.injector = injector;
139 this.dataService = this.injector.get(DataService);
140 this.restService = this.injector.get(RestService);
141 this.activeModal = this.injector.get(NgbActiveModal);
142 this.notifierService = this.injector.get(NotifierService);
143 this.formBuilder = this.injector.get(FormBuilder);
144 this.router = this.injector.get(Router);
145 this.translateService = this.injector.get(TranslateService);
146 this.sharedService = this.injector.get(SharedService);
147 }
148
Barath Kumar R063a3f12020-12-29 16:35:09 +0530149 /** convenience getter for easy access to form fields */
150 get f(): FormGroup['controls'] { return this.packagesForm.controls; }
151
kumaran.m3b4814a2020-05-01 19:48:54 +0530152 /**
153 * Lifecyle Hooks the trigger before component is instantiate
154 */
155 public ngOnInit(): void {
kumaran.m3b4814a2020-05-01 19:48:54 +0530156 this.initializeForm();
SANDHYA.JS07decc02024-07-01 21:50:48 +0530157 if (this.params.page === 'ns-config-template') {
158 this.template = true;
159 this.getNsdPackageDetails();
160 } else if (this.params.page === 'ns-config-template-edit') {
161 this.template = true;
162 this.getNsdPackageDetails();
163 this.getFormControl('nsdId').disable();
164 } else {
165 this.getFormControl('nsdId').disable();
166 this.getFormControl('config').disable();
167 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530168 }
169
170 /** initialize Forms @public */
171 public initializeForm(): void {
172 this.packagesForm = this.formBuilder.group({
SANDHYA.JS07decc02024-07-01 21:50:48 +0530173 name: ['', [Validators.required]],
174 nsdId: [null, [Validators.required]],
175 config: [null]
176 });
177 }
178
179 /** Get NSD Package details @public */
180 public getNsdPackageDetails(): void {
181 this.restService.getResource(environment.NSDESCRIPTORSCONTENT_URL)
182 .subscribe((nsdPackageData: NSDDetails[]): void => {
183 nsdPackageData.forEach((nsData: NSDDetails): void => {
184 const names: {} = {
185 nsName: nsData.name,
186 nsId: nsData._id
187 };
188 this.nsName.push(names);
189 });
190 this.nsdDetails = this.nsName;
191 if (this.params.page === 'ns-config-template-edit') {
192 this.getNSConfigDetails(environment.NSCONFIGTEMPLATE_URL + '/' + this.params.id, this.nsdDetails);
193 }
194 }, (error: ERRORDATA): void => {
195 this.restService.handleError(error, 'get');
196 });
197 }
198
199 /** Get the NSD Content List & patch value in edit form @public */
200 public getNSConfigDetails(URL: string, name: {}[]): void {
201 this.restService.getResource(URL).subscribe((content: NSConfigData): void => {
202 this.nsConfigData.push(content);
203 this.details = this.nsConfigData[0];
204 const nsId: string = 'nsId';
205 // eslint-disable-next-line security/detect-object-injection
206 const nsdId: {}[] = name.filter((nsdData: {}[]): boolean => nsdData[nsId] === this.details.nsdId);
207 const nsName: string = 'nsName';
208 for (const data of nsdId) {
209 // eslint-disable-next-line security/detect-object-injection
210 this.nsdName = data[nsName];
211 }
212 if (!isNullOrUndefined(this.details.config)) {
213 this.config = jsyaml.dump(this.details.config);
214 }
215 this.packagesForm.patchValue({ name: this.details.name, nsdId: this.nsdName, config: this.config });
216 this.isLoadingResults = false;
217 }, (error: ERRORDATA): void => {
218 this.restService.handleError(error, 'get');
219 this.isLoadingResults = false;
kumaran.m3b4814a2020-05-01 19:48:54 +0530220 });
221 }
222
kumaran.m3b4814a2020-05-01 19:48:54 +0530223 /** Create packages @public */
224 public createPackages(): void {
225 this.submitted = true;
SANDHYA.JS07decc02024-07-01 21:50:48 +0530226 this.modalData = {
227 message: 'Done'
228 };
kumaran.m3b4814a2020-05-01 19:48:54 +0530229 this.sharedService.cleanForm(this.packagesForm);
230 if (!this.packagesForm.invalid) {
231 this.isLoadingResults = true;
SANDHYA.JS07decc02024-07-01 21:50:48 +0530232 if (this.params.page === 'ns-package' || this.params.page === 'vnf-package') {
233 if (this.params.page === 'ns-package') {
234 this.endPoint = environment.NSDESCRIPTORSCONTENT_URL;
235 } else if (this.params.page === 'vnf-package') {
236 this.endPoint = environment.VNFPACKAGESCONTENT_URL;
237 }
238 const descriptor: string = this.packageYaml(this.params.page);
239 try {
240 // eslint-disable-next-line @typescript-eslint/no-explicit-any
241 const tar: any = new Tar();
242 const out: Uint8Array = tar.append(this.packagesForm.value.name + '/' + this.packagesForm.value.name + '.yaml',
243 descriptor, { type: '0' });
244 const gzipContent: Uint8Array = pako.gzip(out);
245 this.createPackageApi(gzipContent.buffer);
246 } catch (e) {
247 this.isLoadingResults = false;
248 this.notifierService.notify('error', this.translateService.instant('ERROR'));
249 }
250 } else {
251 try {
252 this.headers = new HttpHeaders({
253 Accept: 'application/json',
254 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
255 });
256 if (this.params.page === 'ns-config-template') {
257 this.endPoint = environment.NSCONFIGTEMPLATE_URL;
258 this.createTemplate(this.endPoint);
259 } else if (this.params.page === 'ns-config-template-edit') {
260 this.endPoint = environment.NSCONFIGTEMPLATE_URL + '/' + this.params.id + '/' + 'template_content';
261 this.editTemplate(this.endPoint);
262 }
263 } catch (e) {
264 this.isLoadingResults = false;
265 this.notifierService.notify('error', this.translateService.instant('ERROR'));
266 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530267 }
268 }
269 }
SANDHYA.JS07decc02024-07-01 21:50:48 +0530270
271 /** Post config template @public */
272 public createTemplate(urlHeader: string): void {
273 this.isLoadingResults = true;
274 const apiURLHeader: APIURLHEADER = {
275 url: urlHeader,
276 httpOptions: { headers: this.headers }
277 };
278 if (isNullOrUndefined(this.packagesForm.value.config) || this.packagesForm.value.config === '') {
279 delete this.packagesForm.value.config;
280 } else {
281 const validJSON: boolean = this.sharedService.checkJson(this.packagesForm.value.config);
282 if (validJSON) {
283 this.packagesForm.value.config = JSON.parse(this.packagesForm.value.config);
284 } else {
285 const getConfigJson: string = jsyaml.load(this.packagesForm.value.config, { json: true });
286 this.packagesForm.value.config = getConfigJson;
287 }
288 }
289 const nsName: string = 'nsName';
290 // eslint-disable-next-line security/detect-object-injection
291 const nsdId: {}[] = this.nsdDetails.filter((nsdData: {}[]): boolean => nsdData[nsName] === this.packagesForm.value.nsdId);
292 for (const data of nsdId) {
293 // eslint-disable-next-line @typescript-eslint/dot-notation
294 this.nsId = data['nsId'];
295 }
296 this.packagesForm.value.nsdId = this.nsId;
297 this.restService.postResource(apiURLHeader, (this.packagesForm.value)).subscribe((result: {}): void => {
298 this.activeModal.close(this.modalData);
299 this.isLoadingResults = false;
300 this.notifierService.notify('success', this.translateService.instant('PAGE.NSCONFIGTEMPLATE.TEMPLATECREATEDSUCCESSFULLY'));
301 }, (error: ERRORDATA): void => {
302 this.restService.handleError(error, 'post');
303 this.isLoadingResults = false;
304 });
305 }
306
307 /** Edit config template @public */
308 public editTemplate(urlHeader: string): void {
309 this.isLoadingResults = true;
310 const apiURLHeader: APIURLHEADER = {
311 url: urlHeader,
312 httpOptions: { headers: this.headers }
313 };
314 if (isNullOrUndefined(this.packagesForm.value.config) || this.packagesForm.value.config === '') {
315 delete this.packagesForm.value.config;
316 } else {
317 const validJSON: boolean = this.sharedService.checkJson(this.packagesForm.value.config);
318 if (validJSON) {
319 this.packagesForm.value.config = JSON.parse(this.packagesForm.value.config);
320 } else {
321 const getConfigJson: string = jsyaml.load(this.packagesForm.value.config, { json: true });
322 this.packagesForm.value.config = getConfigJson;
323 }
324 }
325 this.restService.putResource(apiURLHeader, (this.packagesForm.value)).subscribe((result: {}): void => {
326 this.activeModal.close(this.modalData);
327 this.isLoadingResults = false;
328 this.notifierService.notify('success', this.translateService.instant('PAGE.NSCONFIGTEMPLATE.TEMPLATEEDITEDSUCCESSFULLY'));
329 }, (error: ERRORDATA): void => {
330 this.restService.handleError(error, 'post');
331 this.isLoadingResults = false;
332 });
333 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530334 /** Create packages @public */
335 private createPackageApi(packageContent: ArrayBuffer | SharedArrayBuffer): void {
SANDHYA.JS07decc02024-07-01 21:50:48 +0530336 this.headers = new HttpHeaders({
337 'Content-Type': 'application/gzip',
338 Accept: 'application/json',
339 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
340 });
kumaran.m3b4814a2020-05-01 19:48:54 +0530341 const apiURLHeader: APIURLHEADER = {
342 url: this.endPoint,
343 httpOptions: { headers: this.headers }
344 };
Barath Kumar R063a3f12020-12-29 16:35:09 +0530345 this.restService.postResource(apiURLHeader, packageContent).subscribe((result: { id: string }): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530346 this.isLoadingResults = false;
347 this.activeModal.close();
348 this.composeNSPackages(result.id);
Barath Kumar R063a3f12020-12-29 16:35:09 +0530349 }, (error: ERRORDATA): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530350 this.isLoadingResults = false;
351 this.restService.handleError(error, 'post');
352 });
353 }
SANDHYA.JS07decc02024-07-01 21:50:48 +0530354 /** Config file process @private */
355 public configFile(files: FileList): void {
356 if (files && files.length === 1) {
357 const fileFormat: string = this.sharedService.fetchFileExtension(files).toLocaleLowerCase();
358 if (fileFormat === 'yaml' || fileFormat === 'yml') {
359 this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
360 this.packagesForm.get('config').setValue(fileContent);
361 }).catch((err: string): void => {
362 if (err === 'typeError') {
363 this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
364 } else {
365 this.notifierService.notify('error', this.translateService.instant('ERROR'));
366 }
367 this.fileInputConfigLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
368 this.fileInputConfig.nativeElement.value = null;
369 });
370 } else if (fileFormat === 'json') {
371 this.sharedService.getFileString(files, 'json').then((fileContent: string): void => {
372 const getConfigJson: string = jsyaml.load(fileContent, { json: true });
373 this.packagesForm.get('config').setValue(JSON.stringify(getConfigJson));
374 }).catch((err: string): void => {
375 if (err === 'typeError') {
376 this.notifierService.notify('error', this.translateService.instant('JSONFILETYPEERRROR'));
377 } else {
378 this.notifierService.notify('error', this.translateService.instant('ERROR'));
379 }
380 this.fileInputConfigLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
381 this.fileInputConfig.nativeElement.value = null;
382 });
383 }
384 } else if (files && files.length > 1) {
385 this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
386 }
387 this.fileInputConfigLabel.nativeElement.innerText = files[0].name;
388 this.fileInputConfig.nativeElement.value = null;
389 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530390 /** Compose NS Packages @private */
391 private composeNSPackages(id: string): void {
392 let packageUrl: string;
393 if (this.params.page === 'ns-package') {
394 packageUrl = '/packages/ns/compose/';
395 this.notifierService.notify('success', this.packagesForm.value.name + ' ' +
396 this.translateService.instant('PAGE.NSPACKAGE.CREATEDSUCCESSFULLY'));
397 } else if (this.params.page === 'vnf-package') {
398 packageUrl = '/packages/vnf/compose/';
399 this.notifierService.notify('success', this.packagesForm.value.name + ' ' +
400 this.translateService.instant('PAGE.VNFPACKAGE.CREATEDSUCCESSFULLY'));
401 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530402 this.router.navigate([packageUrl, id]).catch((): void => {
kumaran.m3b4814a2020-05-01 19:48:54 +0530403 // Catch Navigation Error
404 });
405 }
406 /** Deafult template for NS and VNF Packages @private */
407 private packageYaml(descriptorType: string): string {
408 let packageYaml: {} = {};
Barath Kumar R063a3f12020-12-29 16:35:09 +0530409 const composerName: string = 'NGUI Composer';
410 const composerDefaultVersion: string = '1.0';
kumaran.m3b4814a2020-05-01 19:48:54 +0530411 if (descriptorType === 'ns-package') {
412 packageYaml = {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530413 nsd: {
kumaran.m3b4814a2020-05-01 19:48:54 +0530414 nsd: [
415 {
kumaran.m3b4814a2020-05-01 19:48:54 +0530416 id: this.packagesForm.value.name,
Barath Kumar R063a3f12020-12-29 16:35:09 +0530417 name: this.packagesForm.value.name,
418 version: composerDefaultVersion,
419 description: this.packagesForm.value.name + ' descriptor',
420 designer: composerName,
421 df: [
422 {
423 id: 'default-df',
424 'vnf-profile': []
425 }
426 ]
kumaran.m3b4814a2020-05-01 19:48:54 +0530427 }
428 ]
429 }
430 };
431 } else {
432 packageYaml = {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530433 vnfd: {
434 id: this.packagesForm.value.name,
435 'product-name': this.packagesForm.value.name,
436 version: composerDefaultVersion,
437 description: this.packagesForm.value.name + ' descriptor',
438 provider: composerName,
439 df: [
kumaran.m3b4814a2020-05-01 19:48:54 +0530440 {
Barath Kumar R063a3f12020-12-29 16:35:09 +0530441 id: 'default-df',
442 'instantiation-level': [],
443 'vdu-profile': []
kumaran.m3b4814a2020-05-01 19:48:54 +0530444 }
Barath Kumar R063a3f12020-12-29 16:35:09 +0530445 ],
446 'ext-cpd': [],
447 vdu: [],
448 'sw-image-desc': [],
449 'virtual-storage-desc': []
kumaran.m3b4814a2020-05-01 19:48:54 +0530450 }
451 };
452 }
Barath Kumar R86e497d2021-05-04 17:16:14 +0530453 return jsyaml.dump(packageYaml, { sortKeys: true });
kumaran.m3b4814a2020-05-01 19:48:54 +0530454 }
SANDHYA.JS07decc02024-07-01 21:50:48 +0530455
456 /** Used to get the AbstractControl of controlName passed @private */
457 private getFormControl(controlName: string): AbstractControl {
458 // eslint-disable-next-line security/detect-object-injection
459 return this.packagesForm.controls[controlName];
460 }
kumaran.m3b4814a2020-05-01 19:48:54 +0530461}