From: SANDHYA.JS Date: Mon, 1 Jul 2024 16:20:48 +0000 (+0530) Subject: Feature 11009 Ns Config Template as first class citizens in OSM X-Git-Tag: release-v16.0-start~1 X-Git-Url: https://osm.etsi.org/gitweb/?a=commitdiff_plain;h=refs%2Fchanges%2F56%2F14456%2F2;p=osm%2FNG-UI.git Feature 11009 Ns Config Template as first class citizens in OSM - Added UI support - Added New page for NS config template under packages section - User can create, edit & delete template - Added template field under ns instance Change-Id: I3e9a895b4415165d6c96b9840dee64cc197b40e4 Signed-off-by: SANDHYA.JS --- diff --git a/src/app/AppModule.ts b/src/app/AppModule.ts index 1f58a5f..d9a089f 100644 --- a/src/app/AppModule.ts +++ b/src/app/AppModule.ts @@ -55,6 +55,7 @@ import { NetsliceInstancesActionComponent } from 'NetsliceInstancesActionCompone import { NetslicePackagesActionComponent } from 'NetslicePackagesAction'; import { Ng2SmartTableModule } from 'ng2-smart-table'; import { ToastrModule } from 'ngx-toastr'; +import { NSConfigTemplateActionComponent } from 'NSCONFIGTEMPLATEACTION'; import { NSInstancesActionComponent } from 'NSInstancesActionComponent'; import { NsPackagesActionComponent } from 'NsPackagesAction'; import { NsUpdateComponent } from 'NsUpdateComponent'; @@ -134,7 +135,8 @@ const customNotifierOptions: NotifierOptions = { NsUpdateComponent, WarningComponent, StartStopRebuildComponent, - HealingComponent + HealingComponent, + NSConfigTemplateActionComponent ], imports: [ NotifierModule.withConfig(customNotifierOptions), diff --git a/src/app/packages/PackagesModule.ts b/src/app/packages/PackagesModule.ts index 5a8ea2e..1cd7e81 100644 --- a/src/app/packages/PackagesModule.ts +++ b/src/app/packages/PackagesModule.ts @@ -36,6 +36,7 @@ import { NetsliceTemplateComponent } from 'NetsliceTemplate'; import { SidebarModule } from 'ng-sidebar'; import { Ng2SmartTableModule } from 'ng2-smart-table'; import { NSComposerComponent } from 'NSComposer'; +import { NSConfigTemplateComponent } from 'NSCONFIGTEMPLATE'; import { NSPackagesComponent } from 'NSPackages'; import { PackagesComponent } from 'Packages'; import { PagePerRowModule } from 'PagePerRowModule'; @@ -102,6 +103,14 @@ const routes: Routes = [ projectInfo, { title: 'VNFPACKAGES', url: '/packages/vnf' }, { title: '{id}', url: null }] }, component: VNFComposerComponent + }, + { + path: 'nsconfigtemplate', + data: { + breadcrumb: [{ title: 'PAGE.DASHBOARD.DASHBOARD', url: '/' }, { title: 'PAGE.DASHBOARD.PROJECTS', url: '/projects' }, + projectInfo, { title: 'PAGE.DASHBOARD.NSCONFIGTEMPLATE', url: null }] + }, + component: NSConfigTemplateComponent } ] } @@ -115,7 +124,7 @@ const routes: Routes = [ CodemirrorModule, TranslateModule, RouterModule.forChild(routes), NgbModule, NgSelectModule, PagePerRowModule, SidebarModule.forRoot(), LoaderModule, PageReloadModule], declarations: [PackagesComponent, NSPackagesComponent, VNFPackagesComponent, NetsliceTemplateComponent, - DragDirective, ShowContentComponent, NSComposerComponent, VNFComposerComponent, EditPackagesComponent, ClonePackageComponent], + DragDirective, ShowContentComponent, NSComposerComponent, VNFComposerComponent, EditPackagesComponent, ClonePackageComponent, NSConfigTemplateComponent], providers: [DataService], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) diff --git a/src/app/packages/instantiate-ns/InstantiateNsComponent.html b/src/app/packages/instantiate-ns/InstantiateNsComponent.html index 428515e..11f3a2e 100644 --- a/src/app/packages/instantiate-ns/InstantiateNsComponent.html +++ b/src/app/packages/instantiate-ns/InstantiateNsComponent.html @@ -47,7 +47,7 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
- @@ -98,6 +98,12 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
+ + +
{{'CONFIGFILEUPLOADLABEL' | translate}}
{{'FILEUPLOADLABEL' | translate}}
diff --git a/src/app/packages/instantiate-ns/InstantiateNsComponent.ts b/src/app/packages/instantiate-ns/InstantiateNsComponent.ts index 9ba89da..08d6232 100644 --- a/src/app/packages/instantiate-ns/InstantiateNsComponent.ts +++ b/src/app/packages/instantiate-ns/InstantiateNsComponent.ts @@ -18,18 +18,20 @@ /** * @file Instantiate NS Modal Component. */ -import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core'; +import { Component, ElementRef, Injector, Input, OnInit, ViewChild } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; import { NotifierService } from 'angular-notifier'; -import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel'; +import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, URLPARAMS } from 'CommonModel'; import { DataService } from 'DataService'; import { environment } from 'environment'; import * as jsyaml from 'js-yaml'; -import { NSCREATEPARAMS, NSData, NSDDetails } from 'NSDModel'; +import { NSCONFIG } from 'NSCONFIGTEMPLATEMODEL'; +import { NSData, NSDDetails } from 'NSDModel'; import { RestService } from 'RestService'; +import { Subscription } from 'rxjs'; import { SharedService, isNullOrUndefined } from 'SharedService'; import { VimAccountDetails } from 'VimAccountModel'; @@ -56,9 +58,15 @@ export class InstantiateNsComponent implements OnInit { /** Contains all vim account collections */ public vimAccountSelect: VimAccountDetails; + /** Contains all NS Config template details */ + public nsConfigSelect: NSCONFIG; + /** Instance for active modal service @public */ public activeModal: NgbActiveModal; + /** Used to subscribe nsdId @public */ + public nsdID: Subscription; + /** Variable set for twoway binding @public */ public nsdId: string; @@ -66,13 +74,13 @@ export class InstantiateNsComponent implements OnInit { public vimAccountId: string; /** Form submission Add */ - public submitted: boolean = false; + public submitted = false; /** Check the loading results @public */ - public isLoadingResults: boolean = false; + public isLoadingResults = false; /** Give the message for the loading @public */ - public message: string = 'PLEASEWAIT'; + public message = 'PLEASEWAIT'; /** Contains Selected VIM Details @public */ public selectedVIMDetails: VimAccountDetails = null; @@ -113,6 +121,9 @@ export class InstantiateNsComponent implements OnInit { /** Contains the ssh key to be hosted in dom @private */ private copySSHKey: string; + /** Input contains component objects @private */ + @Input() private params: URLPARAMS; + constructor(injector: Injector) { this.injector = injector; this.restService = this.injector.get(RestService); @@ -127,10 +138,11 @@ export class InstantiateNsComponent implements OnInit { public ngOnInit(): void { /** Setting up initial value for NSD */ - this.dataService.currentMessage.subscribe((event: NSData) => { - if (event.identifier !== undefined || event.identifier !== '' || event.identifier !== null) { + this.nsdID = this.dataService.currentMessage.subscribe((event: NSData) => { + if (!isNullOrUndefined(event?.identifier) || event?.identifier !== '') { this.nsdId = event.identifier; } + this.getDetailsconfigtemplateAccount(); }); /** On Initializing call the methods */ this.instantiateFormAction(); @@ -143,10 +155,11 @@ export class InstantiateNsComponent implements OnInit { this.instantiateForm = this.formBuilder.group({ nsName: ['', [Validators.required]], nsDescription: ['', [Validators.required]], - nsdId: ['', [Validators.required]], + nsdId: [null, [Validators.required]], vimAccountId: ['', [Validators.required]], ssh_keys: [null], - config: [null] + config: [null], + nsConfigTemplateId: [null] }); } @@ -171,6 +184,15 @@ export class InstantiateNsComponent implements OnInit { }); } + /** Call the ns config template details in the selection options @public */ + public getDetailsconfigtemplateAccount(): void { + this.restService.getResource(environment.NSCONFIGTEMPLATE_URL + '?nsdId=' + this.nsdId).subscribe((template: NSCONFIG) => { + this.nsConfigSelect = template; + }, (error: ERRORDATA) => { + this.restService.handleError(error, 'get'); + }); + } + /** On modal submit instantiateNsSubmit will called @public */ public instantiateNsSubmit(): void { this.submitted = true; @@ -181,6 +203,9 @@ export class InstantiateNsComponent implements OnInit { const modalData: MODALCLOSERESPONSEDATA = { message: 'Done' }; + if (isNullOrUndefined(this.instantiateForm.value.nsConfigTemplateId)) { + delete this.instantiateForm.value.nsConfigTemplateId; + } if (isNullOrUndefined(this.instantiateForm.value.ssh_keys) || this.instantiateForm.value.ssh_keys === '') { delete this.instantiateForm.value.ssh_keys; } else { @@ -206,6 +231,7 @@ export class InstantiateNsComponent implements OnInit { }); delete this.instantiateForm.value.config; } + delete this.instantiateForm.value.nsConfigTemplateId; } const apiURLHeader: APIURLHEADER = { url: environment.NSINSTANCESCONTENT_URL @@ -217,7 +243,7 @@ export class InstantiateNsComponent implements OnInit { this.translateService.instant('PAGE.NSINSTANCE.CREATEDSUCCESSFULLY')); this.router.navigate(['/instances/ns']).catch((): void => { // Catch Navigation Error - }); + }); }, (error: ERRORDATA) => { this.isLoadingResults = false; this.restService.handleError(error, 'post'); @@ -292,4 +318,11 @@ export class InstantiateNsComponent implements OnInit { this.selectedVIMDetails = vimDetails; } } + + /** + * Lifecyle Hooks the trigger before component is deleted + */ + public ngOnDestroy(): void { + this.nsdID.unsubscribe(); + } } diff --git a/src/app/packages/ns-config-template/NSConfigTemplateComponent.html b/src/app/packages/ns-config-template/NSConfigTemplateComponent.html new file mode 100644 index 0000000..b508609 --- /dev/null +++ b/src/app/packages/ns-config-template/NSConfigTemplateComponent.html @@ -0,0 +1,35 @@ + +
+
{{'PAGE.DASHBOARD.NSCONFIGTEMPLATE' | translate}}
+ + + +
+
+ + +
+
+ + +
+ \ No newline at end of file diff --git a/src/app/packages/ns-config-template/NSConfigTemplateComponent.scss b/src/app/packages/ns-config-template/NSConfigTemplateComponent.scss new file mode 100644 index 0000000..c55461a --- /dev/null +++ b/src/app/packages/ns-config-template/NSConfigTemplateComponent.scss @@ -0,0 +1,17 @@ +/* + Copyright 2020 TATA ELXSI + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Author: SANDHYA JS (sandhya.j@tataelxsi.co.in) +*/ \ No newline at end of file diff --git a/src/app/packages/ns-config-template/NSConfigTemplateComponent.ts b/src/app/packages/ns-config-template/NSConfigTemplateComponent.ts new file mode 100644 index 0000000..298207a --- /dev/null +++ b/src/app/packages/ns-config-template/NSConfigTemplateComponent.ts @@ -0,0 +1,224 @@ +/* + Copyright 2020 TATA ELXSI + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Author: SANDHYA JS (sandhya.j@tataelxsi.co.in) +*/ +/** + * @file NS Config Template details Component. + */ +import { HttpHeaders } from '@angular/common/http'; +import { Component, Injector, OnInit } from '@angular/core'; +import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateService } from '@ngx-translate/core'; +import { ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel'; +import { ComposePackages } from 'ComposePackages'; +import { DataService } from 'DataService'; +import { environment } from 'environment'; +import { LocalDataSource } from 'ng2-smart-table'; +import { NSConfigTemplateActionComponent } from 'NSCONFIGTEMPLATEACTION'; +import { NSCONFIG, NSConfigData } from 'NSCONFIGTEMPLATEMODEL'; +import { RestService } from 'RestService'; +import { Subscription } from 'rxjs'; +import { SharedService } from 'SharedService'; +import { VNFData } from 'VNFDModel'; + +/** + * Creating component + * @Component takes NSConfigTemplateComponent.html as template url + */ +@Component({ + selector: 'app-ns-config-template', + templateUrl: './NSConfigTemplateComponent.html', + styleUrls: ['./NSConfigTemplateComponent.scss'] +}) +/** Exporting a class @exports NSConfigTemplateComponent */ +export class NSConfigTemplateComponent implements OnInit { + /** To inject services @public */ + public injector: Injector; + + /** Data of smarttable populate through LocalDataSource @public */ + public dataSource: LocalDataSource = new LocalDataSource(); + + /** handle translate @public */ + public translateService: TranslateService; + + /** Columns list of the smart table @public */ + public columnLists: object = {}; + + /** Settings for smarttable to populate the table with columns @public */ + public settings: object = {}; + + /** Check the loading results @public */ + public isLoadingResults: boolean = true; + + /** Give the message for the loading @public */ + public message: string = 'PLEASEWAIT'; + + /** Class for empty and present data @public */ + public checkDataClass: string; + + /** Instance of the rest service @private */ + private restService: RestService; + + /** dataService to pass the data from one component to another @private */ + private dataService: DataService; + + /** Formation of appropriate Data for LocalDatasource @private */ + private nsConfigData: NSConfigData[] = []; + + /** Contains all methods related to shared @private */ + private sharedService: SharedService; + + /** Controls the header form @private */ + private headers: HttpHeaders; + + /** Instance of the modal service @private */ + private modalService: NgbModal; + + /** Instance of subscriptions @private */ + private generateDataSub: Subscription; + + constructor(injector: Injector) { + this.injector = injector; + this.restService = this.injector.get(RestService); + this.dataService = this.injector.get(DataService); + this.sharedService = this.injector.get(SharedService); + this.translateService = this.injector.get(TranslateService); + this.modalService = this.injector.get(NgbModal); + } + + /** + * Lifecyle Hooks the trigger before component is instantiate + */ + public ngOnInit(): void { + this.generateColumns(); + this.generateSettings(); + this.generateData(); + this.headers = new HttpHeaders({ + 'Content-Type': 'application/gzip', + Accept: 'application/json', + 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0' + }); + this.generateDataSub = this.sharedService.dataEvent.subscribe((): void => { this.generateData(); }); + } + + /** smart table Header Colums @public */ + public generateColumns(): void { + this.columnLists = { + name: { title: this.translateService.instant('NAME'), width: '25%' }, + identifier: { title: this.translateService.instant('IDENTIFIER'), width: '25%' }, + nsdId: { title: this.translateService.instant('PAGE.INSTANCEINSTANTIATE.NSID'), width: '25%' }, + created: { title: this.translateService.instant('Created'), width: '15%' }, + Actions: { + name: 'Action', width: '15%', filter: false, sort: false, type: 'custom', + title: this.translateService.instant('ACTIONS'), + valuePrepareFunction: (cell: VNFData, row: VNFData): VNFData => row, renderComponent: NSConfigTemplateActionComponent + } + }; + } + + /** smart table Data Settings @public */ + public generateSettings(): void { + this.settings = { + edit: { + editButtonContent: '', + confirmSave: true + }, + delete: { + deleteButtonContent: '', + confirmDelete: true + }, + columns: this.columnLists, + actions: { + add: false, + edit: false, + delete: false, + position: 'right' + }, + attr: this.sharedService.tableClassConfig(), + pager: this.sharedService.paginationPagerConfig(), + noDataMessage: this.translateService.instant('NODATAMSG') + }; + } + + /** smart table listing manipulation @public */ + public onChange(perPageValue: number): void { + this.dataSource.setPaging(1, perPageValue, true); + } + + /** OnUserRowSelect Function @public */ + public onUserRowSelect(event: MessageEvent): void { + Object.assign(event.data, { page: 'ns-config-template' }); + this.dataService.changeMessage(event.data); + } + + + /** Generate nsData object from loop and return for the datasource @public */ + public generatetemplateData(nsData: NSCONFIG): NSConfigData { + return { + nsdId: nsData.nsdId, + identifier: nsData._id, + operationalState: nsData._admin.operationalState, + created: this.sharedService.convertEpochTime(Number(nsData._admin.created)), + modified: this.sharedService.convertEpochTime(Number(nsData._admin.modified)), + name: nsData.name + }; + } + /** Handle compose new ns package method @public */ + public composeTemplate(): void { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const modalRef: NgbModalRef = this.modalService.open(ComposePackages, { backdrop: 'static' }); + modalRef.componentInstance.params = { page: 'ns-config-template' }; + modalRef.result.then((result: MODALCLOSERESPONSEDATA) => { + if (result) { + this.sharedService.callData(); + } + }).catch((): void => { + // Catch Navigation Error + }); + } + + /** + * Lifecyle hook which get trigger on component destruction + */ + public ngOnDestroy(): void { + this.generateDataSub.unsubscribe(); + } + + /** Fetching the data from server to Load in the smarttable @protected */ + protected generateData(): void { + this.isLoadingResults = true; + this.restService.getResource(environment.NSCONFIGTEMPLATE_URL).subscribe((nsdConfigData: NSCONFIG[]): void => { + this.nsConfigData = []; + nsdConfigData.forEach((nsddata: NSCONFIG): void => { + const vnfDataObj: NSConfigData = this.generatetemplateData(nsddata); + this.nsConfigData.push(vnfDataObj); + }); + if (this.nsConfigData.length > 0) { + this.checkDataClass = 'dataTables_present'; + } else { + this.checkDataClass = 'dataTables_empty'; + } + this.dataSource.load(this.nsConfigData).then((data: boolean): void => { + this.isLoadingResults = false; + }).catch((): void => { + this.isLoadingResults = false; + }); + }, (error: ERRORDATA): void => { + this.restService.handleError(error, 'get'); + this.isLoadingResults = false; + }); + } +} diff --git a/src/app/utilities/compose-packages/ComposePackages.html b/src/app/utilities/compose-packages/ComposePackages.html index 1067054..03ec3b7 100644 --- a/src/app/utilities/compose-packages/ComposePackages.html +++ b/src/app/utilities/compose-packages/ComposePackages.html @@ -17,24 +17,56 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i -->
\ No newline at end of file diff --git a/src/app/utilities/compose-packages/ComposePackages.ts b/src/app/utilities/compose-packages/ComposePackages.ts index 6f2a031..0dff17a 100644 --- a/src/app/utilities/compose-packages/ComposePackages.ts +++ b/src/app/utilities/compose-packages/ComposePackages.ts @@ -19,19 +19,21 @@ * @file Info Compose Package Model */ import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Component, Injector, Input, OnInit } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, ElementRef, Injector, Input, OnInit, ViewChild } from '@angular/core'; +import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; import { NotifierService } from 'angular-notifier'; -import { APIURLHEADER, ERRORDATA, URLPARAMS } from 'CommonModel'; +import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, URLPARAMS } from 'CommonModel'; import { DataService } from 'DataService'; import { environment } from 'environment'; import * as jsyaml from 'js-yaml'; +import { NSConfigData } from 'NSCONFIGTEMPLATEMODEL'; +import { NSDDetails } from 'NSDModel'; import * as pako from 'pako'; import { RestService } from 'RestService'; -import { SharedService } from 'SharedService'; +import { SharedService, isNullOrUndefined } from 'SharedService'; /** This is added globally by the tar.js library */ // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -64,13 +66,43 @@ export class ComposePackages implements OnInit { public packagesForm: FormGroup; /** Form submission Add */ - public submitted: boolean = false; + public submitted = false; /** To handle loader status for API call @public */ - public isLoadingResults: boolean = false; + public isLoadingResults = false; /** Give the message for the loading @public */ - public message: string = 'PLEASEWAIT'; + public message = 'PLEASEWAIT'; + + /** contains NSD name @public */ + public nsName: {}[] = []; + + /** contains NSD details @public */ + public nsdDetails: {}[]; + + /** contains NSD details filtered by id @public */ + public nsdName: string; + + /** Contains config details @public */ + public config: string; + + /** contains NSD details filtered by name @public */ + public nsId: string; + + /** Check if template or not @public */ + public template = false; + + /** Data of NS config @public */ + public details: NSConfigData; + + /** Data of NF packages @public */ + public nsConfigData: NSConfigData[] = []; + + /** Element ref for fileInputConfig @public */ + @ViewChild('fileInputConfig') fileInputConfig: ElementRef; + + /** Element ref for fileInputConfigLabel @public */ + @ViewChild('fileInputConfigLabel') fileInputConfigLabel: ElementRef; /** FormBuilder instance added to the formBuilder @private */ private formBuilder: FormBuilder; @@ -84,15 +116,15 @@ export class ComposePackages implements OnInit { /** Controls the header form @private */ private headers: HttpHeaders; - /** Create URL holds the end point of any packages @private */ - private createURL: string; - - /** Input contains component objects @private */ - @Input() private params: URLPARAMS; + /** Input contains component objects @public */ + @Input() public params: URLPARAMS; /** Holds the end point @private */ private endPoint: string; + /** ModalData instance of modal @private */ + private modalData: MODALCLOSERESPONSEDATA; + /** Contains all methods related to shared @private */ private sharedService: SharedService; @@ -121,48 +153,191 @@ export class ComposePackages implements OnInit { * Lifecyle Hooks the trigger before component is instantiate */ public ngOnInit(): void { - this.headers = new HttpHeaders({ - 'Content-Type': 'application/gzip', - Accept: 'application/json', - 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0' - }); this.initializeForm(); + if (this.params.page === 'ns-config-template') { + this.template = true; + this.getNsdPackageDetails(); + } else if (this.params.page === 'ns-config-template-edit') { + this.template = true; + this.getNsdPackageDetails(); + this.getFormControl('nsdId').disable(); + } else { + this.getFormControl('nsdId').disable(); + this.getFormControl('config').disable(); + } } /** initialize Forms @public */ public initializeForm(): void { this.packagesForm = this.formBuilder.group({ - name: ['', [Validators.required]] + name: ['', [Validators.required]], + nsdId: [null, [Validators.required]], + config: [null] + }); + } + + /** Get NSD Package details @public */ + public getNsdPackageDetails(): void { + this.restService.getResource(environment.NSDESCRIPTORSCONTENT_URL) + .subscribe((nsdPackageData: NSDDetails[]): void => { + nsdPackageData.forEach((nsData: NSDDetails): void => { + const names: {} = { + nsName: nsData.name, + nsId: nsData._id + }; + this.nsName.push(names); + }); + this.nsdDetails = this.nsName; + if (this.params.page === 'ns-config-template-edit') { + this.getNSConfigDetails(environment.NSCONFIGTEMPLATE_URL + '/' + this.params.id, this.nsdDetails); + } + }, (error: ERRORDATA): void => { + this.restService.handleError(error, 'get'); + }); + } + + /** Get the NSD Content List & patch value in edit form @public */ + public getNSConfigDetails(URL: string, name: {}[]): void { + this.restService.getResource(URL).subscribe((content: NSConfigData): void => { + this.nsConfigData.push(content); + this.details = this.nsConfigData[0]; + const nsId: string = 'nsId'; + // eslint-disable-next-line security/detect-object-injection + const nsdId: {}[] = name.filter((nsdData: {}[]): boolean => nsdData[nsId] === this.details.nsdId); + const nsName: string = 'nsName'; + for (const data of nsdId) { + // eslint-disable-next-line security/detect-object-injection + this.nsdName = data[nsName]; + } + if (!isNullOrUndefined(this.details.config)) { + this.config = jsyaml.dump(this.details.config); + } + this.packagesForm.patchValue({ name: this.details.name, nsdId: this.nsdName, config: this.config }); + this.isLoadingResults = false; + }, (error: ERRORDATA): void => { + this.restService.handleError(error, 'get'); + this.isLoadingResults = false; }); } /** Create packages @public */ public createPackages(): void { this.submitted = true; + this.modalData = { + message: 'Done' + }; this.sharedService.cleanForm(this.packagesForm); if (!this.packagesForm.invalid) { this.isLoadingResults = true; - if (this.params.page === 'ns-package') { - this.endPoint = environment.NSDESCRIPTORSCONTENT_URL; - } else if (this.params.page === 'vnf-package') { - this.endPoint = environment.VNFPACKAGESCONTENT_URL; + if (this.params.page === 'ns-package' || this.params.page === 'vnf-package') { + if (this.params.page === 'ns-package') { + this.endPoint = environment.NSDESCRIPTORSCONTENT_URL; + } else if (this.params.page === 'vnf-package') { + this.endPoint = environment.VNFPACKAGESCONTENT_URL; + } + const descriptor: string = this.packageYaml(this.params.page); + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const tar: any = new Tar(); + const out: Uint8Array = tar.append(this.packagesForm.value.name + '/' + this.packagesForm.value.name + '.yaml', + descriptor, { type: '0' }); + const gzipContent: Uint8Array = pako.gzip(out); + this.createPackageApi(gzipContent.buffer); + } catch (e) { + this.isLoadingResults = false; + this.notifierService.notify('error', this.translateService.instant('ERROR')); + } + } else { + try { + this.headers = new HttpHeaders({ + Accept: 'application/json', + 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0' + }); + if (this.params.page === 'ns-config-template') { + this.endPoint = environment.NSCONFIGTEMPLATE_URL; + this.createTemplate(this.endPoint); + } else if (this.params.page === 'ns-config-template-edit') { + this.endPoint = environment.NSCONFIGTEMPLATE_URL + '/' + this.params.id + '/' + 'template_content'; + this.editTemplate(this.endPoint); + } + } catch (e) { + this.isLoadingResults = false; + this.notifierService.notify('error', this.translateService.instant('ERROR')); + } + } + } + } + + /** Post config template @public */ + public createTemplate(urlHeader: string): void { + this.isLoadingResults = true; + const apiURLHeader: APIURLHEADER = { + url: urlHeader, + httpOptions: { headers: this.headers } + }; + if (isNullOrUndefined(this.packagesForm.value.config) || this.packagesForm.value.config === '') { + delete this.packagesForm.value.config; + } else { + const validJSON: boolean = this.sharedService.checkJson(this.packagesForm.value.config); + if (validJSON) { + this.packagesForm.value.config = JSON.parse(this.packagesForm.value.config); + } else { + const getConfigJson: string = jsyaml.load(this.packagesForm.value.config, { json: true }); + this.packagesForm.value.config = getConfigJson; } - const descriptor: string = this.packageYaml(this.params.page); - try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const tar: any = new Tar(); - const out: Uint8Array = tar.append(this.packagesForm.value.name + '/' + this.packagesForm.value.name + '.yaml', - descriptor, { type: '0' }); - const gzipContent: Uint8Array = pako.gzip(out); - this.createPackageApi(gzipContent.buffer); - } catch (e) { - this.isLoadingResults = false; - this.notifierService.notify('error', this.translateService.instant('ERROR')); + } + const nsName: string = 'nsName'; + // eslint-disable-next-line security/detect-object-injection + const nsdId: {}[] = this.nsdDetails.filter((nsdData: {}[]): boolean => nsdData[nsName] === this.packagesForm.value.nsdId); + for (const data of nsdId) { + // eslint-disable-next-line @typescript-eslint/dot-notation + this.nsId = data['nsId']; + } + this.packagesForm.value.nsdId = this.nsId; + this.restService.postResource(apiURLHeader, (this.packagesForm.value)).subscribe((result: {}): void => { + this.activeModal.close(this.modalData); + this.isLoadingResults = false; + this.notifierService.notify('success', this.translateService.instant('PAGE.NSCONFIGTEMPLATE.TEMPLATECREATEDSUCCESSFULLY')); + }, (error: ERRORDATA): void => { + this.restService.handleError(error, 'post'); + this.isLoadingResults = false; + }); + } + + /** Edit config template @public */ + public editTemplate(urlHeader: string): void { + this.isLoadingResults = true; + const apiURLHeader: APIURLHEADER = { + url: urlHeader, + httpOptions: { headers: this.headers } + }; + if (isNullOrUndefined(this.packagesForm.value.config) || this.packagesForm.value.config === '') { + delete this.packagesForm.value.config; + } else { + const validJSON: boolean = this.sharedService.checkJson(this.packagesForm.value.config); + if (validJSON) { + this.packagesForm.value.config = JSON.parse(this.packagesForm.value.config); + } else { + const getConfigJson: string = jsyaml.load(this.packagesForm.value.config, { json: true }); + this.packagesForm.value.config = getConfigJson; } } + this.restService.putResource(apiURLHeader, (this.packagesForm.value)).subscribe((result: {}): void => { + this.activeModal.close(this.modalData); + this.isLoadingResults = false; + this.notifierService.notify('success', this.translateService.instant('PAGE.NSCONFIGTEMPLATE.TEMPLATEEDITEDSUCCESSFULLY')); + }, (error: ERRORDATA): void => { + this.restService.handleError(error, 'post'); + this.isLoadingResults = false; + }); } /** Create packages @public */ private createPackageApi(packageContent: ArrayBuffer | SharedArrayBuffer): void { + this.headers = new HttpHeaders({ + 'Content-Type': 'application/gzip', + Accept: 'application/json', + 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0' + }); const apiURLHeader: APIURLHEADER = { url: this.endPoint, httpOptions: { headers: this.headers } @@ -176,6 +351,42 @@ export class ComposePackages implements OnInit { this.restService.handleError(error, 'post'); }); } + /** Config file process @private */ + public configFile(files: FileList): void { + if (files && files.length === 1) { + const fileFormat: string = this.sharedService.fetchFileExtension(files).toLocaleLowerCase(); + if (fileFormat === 'yaml' || fileFormat === 'yml') { + this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => { + this.packagesForm.get('config').setValue(fileContent); + }).catch((err: string): void => { + if (err === 'typeError') { + this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR')); + } else { + this.notifierService.notify('error', this.translateService.instant('ERROR')); + } + this.fileInputConfigLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE'); + this.fileInputConfig.nativeElement.value = null; + }); + } else if (fileFormat === 'json') { + this.sharedService.getFileString(files, 'json').then((fileContent: string): void => { + const getConfigJson: string = jsyaml.load(fileContent, { json: true }); + this.packagesForm.get('config').setValue(JSON.stringify(getConfigJson)); + }).catch((err: string): void => { + if (err === 'typeError') { + this.notifierService.notify('error', this.translateService.instant('JSONFILETYPEERRROR')); + } else { + this.notifierService.notify('error', this.translateService.instant('ERROR')); + } + this.fileInputConfigLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE'); + this.fileInputConfig.nativeElement.value = null; + }); + } + } else if (files && files.length > 1) { + this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION')); + } + this.fileInputConfigLabel.nativeElement.innerText = files[0].name; + this.fileInputConfig.nativeElement.value = null; + } /** Compose NS Packages @private */ private composeNSPackages(id: string): void { let packageUrl: string; @@ -241,4 +452,10 @@ export class ComposePackages implements OnInit { } return jsyaml.dump(packageYaml, { sortKeys: true }); } + + /** Used to get the AbstractControl of controlName passed @private */ + private getFormControl(controlName: string): AbstractControl { + // eslint-disable-next-line security/detect-object-injection + return this.packagesForm.controls[controlName]; + } } diff --git a/src/app/utilities/delete/DeleteComponent.ts b/src/app/utilities/delete/DeleteComponent.ts index d79d4e4..445c511 100644 --- a/src/app/utilities/delete/DeleteComponent.ts +++ b/src/app/utilities/delete/DeleteComponent.ts @@ -202,6 +202,9 @@ export class DeleteComponent { } else if (data.page === 'osmrepo') { this.deleteURL = environment.OSMREPOS_URL; this.notifyMessage = 'DELETEDSUCCESSFULLY'; + } else if (data.page === 'ns-config-template') { + this.deleteURL = environment.NSCONFIGTEMPLATE_URL; + this.notifyMessage = 'DELETEDSUCCESSFULLY'; } } /** Generate Data function @public */ diff --git a/src/app/utilities/ns-config-template-action/NSConfigTemplateActionComponent.html b/src/app/utilities/ns-config-template-action/NSConfigTemplateActionComponent.html new file mode 100644 index 0000000..e36916f --- /dev/null +++ b/src/app/utilities/ns-config-template-action/NSConfigTemplateActionComponent.html @@ -0,0 +1,28 @@ + +
+ + +
+ \ No newline at end of file diff --git a/src/app/utilities/ns-config-template-action/NSConfigTemplateActionComponent.scss b/src/app/utilities/ns-config-template-action/NSConfigTemplateActionComponent.scss new file mode 100644 index 0000000..c55461a --- /dev/null +++ b/src/app/utilities/ns-config-template-action/NSConfigTemplateActionComponent.scss @@ -0,0 +1,17 @@ +/* + Copyright 2020 TATA ELXSI + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Author: SANDHYA JS (sandhya.j@tataelxsi.co.in) +*/ \ No newline at end of file diff --git a/src/app/utilities/ns-config-template-action/NSConfigTemplateActionComponent.ts b/src/app/utilities/ns-config-template-action/NSConfigTemplateActionComponent.ts new file mode 100644 index 0000000..b653c5d --- /dev/null +++ b/src/app/utilities/ns-config-template-action/NSConfigTemplateActionComponent.ts @@ -0,0 +1,99 @@ +/* + Copyright 2020 TATA ELXSI + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Author: SANDHYA JS (sandhya.j@tataelxsi.co.in) +*/ +/** + * @file NSConfigTemplateAction Component + */ +import { Component, Injector } from '@angular/core'; +import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { MODALCLOSERESPONSEDATA } from 'CommonModel'; +import { ComposePackages } from 'ComposePackages'; +import { DeleteComponent } from 'DeleteComponent'; +import { NSConfigData } from 'NSCONFIGTEMPLATEMODEL'; +import { SharedService } from 'SharedService'; + +/** + * Creating component + * @Component takes NSConfigTemplateActionComponent.html as template url + */ +@Component({ + templateUrl: './NSConfigTemplateActionComponent.html', + styleUrls: ['./NSConfigTemplateActionComponent.scss'] +}) +/** Exporting a class @exports NSConfigTemplateActionComponent */ +export class NSConfigTemplateActionComponent { + /** To get the value from the vnfpackage via valuePrepareFunction default Property of ng-smarttable @public */ + public value: NSConfigData; + + /** To inject services @public */ + public injector: Injector; + + /** Check the loading results for loader status @public */ + public isLoadingDownloadResult: boolean = false; + + /** Give the message for the loading @public */ + public message: string = 'PLEASEWAIT'; + + /** Instance of the modal service @private */ + private modalService: NgbModal; + + /** Variables holds Template ID @private */ + private templateID: string; + + /** Contains all methods related to shared @private */ + private sharedService: SharedService; + + constructor(injector: Injector) { + this.injector = injector; + this.sharedService = this.injector.get(SharedService); + this.modalService = this.injector.get(NgbModal); + } + + /** + * Lifecyle Hooks the trigger before component is instantiate + */ + public ngOnInit(): void { + this.templateID = this.value.identifier; + } + + /** Delete NS Config template @public */ + public deleteTemplate(): void { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const modalRef: NgbModalRef = this.modalService.open(DeleteComponent, { backdrop: 'static' }); + modalRef.result.then((result: MODALCLOSERESPONSEDATA) => { + if (result) { + this.sharedService.callData(); + } + }).catch((): void => { + // Catch Navigation Error + }); + } + + /** Set instance for Template Edit @public */ + public templateEdit(): void { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const modalRef: NgbModalRef = this.modalService.open(ComposePackages, { backdrop: 'static' }); + modalRef.componentInstance.params = {id: this.templateID, page: 'ns-config-template-edit'}; + modalRef.result.then((result: MODALCLOSERESPONSEDATA) => { + if (result) { + this.sharedService.callData(); + } + }).catch((): void => { + // Catch Navigation Error + }); + } +} diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 870897c..87aaf98 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -94,7 +94,7 @@ "DELETELOADERMESSAGE": "Bitte warten Sie, während der Löschvorgang ausgeführt wird", "DELETELOADMESSAGE": "Bitte warten Sie, während der Löschvorgang ausgeführt wird", "WARNINGMESSAGE": "Es können nicht mehr als 25 Instanzen gelöscht werden", - "DELETENS":"NS löschen", + "DELETENS": "NS löschen", "VALUE": "Wert", "PERFORMACTION": "Aktion ausführen", "EXECUTE": "Execute", @@ -153,6 +153,7 @@ "NODATE": "Keine Datumsinformationen gefunden", "TYPEINFO": "Um einen neuen TYPW hinzuzufügen, geben Sie oben die Eingabe ein", "UPLOADCONFIGLABEL": "Bitte laden Sie eine Datei im .yaml- oder .yml-Format hoch", + "CONFIGFILEUPLOADLABEL": "Oder geben Sie Konfigurationsparameter ein", "NEWVERSIONTAG": "Hier ist die neue Version {{appVersion}} von OSM!", "SCALEOUT": "Scale Out", "SCALEIN": "Scale In", @@ -209,6 +210,7 @@ "RUNNINGINSTANCES": "Laufende Instanzen", "NETSLICETEMPLATE": "NetSlice Vorlage", "NETSLICEINSTANCE": "NetSlice Instanzen", + "NSCONFIGTEMPLATE": "NS-Konfigurationsvorlage", "USERS": "Benutzer", "PROJECTS": "Projekte", "USERSETTINGS": "Benutzereinstellungen", @@ -455,6 +457,13 @@ "NETSLICETEMPLATE": { "NETSLICETEMPLATEDETAILS": "Netzwerk-Slices-Vorlagendetails" }, + "NSCONFIGTEMPLATE": { + "NEWNSCONFIGTEMPLATE": "Neue NS-Konfigurationsvorlage", + "CREATENSCONFIGTEMPLATE": "Erstellen Sie eine NS-Konfigurationsvorlage", + "EDITNSCONFIGTEMPLATE": "Bearbeiten Sie die NS-Konfigurationsvorlage", + "TEMPLATECREATEDSUCCESSFULLY": "NS-Konfigurationsvorlage erfolgreich erstellt", + "TEMPLATEEDITEDSUCCESSFULLY": "NS-Konfigurationsvorlage erfolgreich bearbeitet" + }, "NSTINSTANCEINSTANTIATE": { "NEWINSTANCE": "Neue Instanz", "NSNAME": "Ns Name", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 375b9a5..99fbb15 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -94,7 +94,7 @@ "DELETELOADERMESSAGE": "Please wait while {{title}} deletion is in progress", "DELETELOADMESSAGE": "Please wait while deletion is in progress", "WARNINGMESSAGE": "Cannot delete more than 25 instances", - "DELETENS":"Delete NS", + "DELETENS": "Delete NS", "VALUE": "Value", "PERFORMACTION": "Perform Action", "EXECUTE": "Execute", @@ -153,6 +153,7 @@ "NODATE": "No date information found", "TYPEINFO": "To add a new TYPE, Please enter input above", "UPLOADCONFIGLABEL": "Please upload file with .yaml or .yml format", + "CONFIGFILEUPLOADLABEL": "Or enter config parameters", "NEWVERSIONTAG": "Here is the new version {{appVersion}} of OSM!", "SCALEOUT": "Scale Out", "SCALEIN": "Scale In", @@ -209,6 +210,7 @@ "RUNNINGINSTANCES": "Running Instances", "NETSLICETEMPLATE": "NetSlice Template", "NETSLICEINSTANCE": "NetSlice Instances", + "NSCONFIGTEMPLATE": "NS Config Template", "USERS": "Users", "PROJECTS": "Projects", "USERSETTINGS": "User Settings", @@ -455,6 +457,13 @@ "NETSLICETEMPLATE": { "NETSLICETEMPLATEDETAILS": "Network Slices Template Details" }, + "NSCONFIGTEMPLATE": { + "NEWNSCONFIGTEMPLATE": "New NS Config Template", + "CREATENSCONFIGTEMPLATE": "Create NS Config Template", + "EDITNSCONFIGTEMPLATE": "Edit NS Config Template", + "TEMPLATECREATEDSUCCESSFULLY": "NS Config Template Created Successfully", + "TEMPLATEEDITEDSUCCESSFULLY": "NS Config Template Edited Successfully" + }, "NSTINSTANCEINSTANTIATE": { "NEWINSTANCE": "New Instance", "NSNAME": "Ns Name", diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 2a5c884..34619a6 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -94,7 +94,7 @@ "DELETELOADERMESSAGE": "Por favor, espere mientras la eliminación está en progreso", "DELETELOADMESSAGE": "Por favor, espere mientras la eliminación está en progreso", "WARNINGMESSAGE": "No se pueden eliminar más de 25 instancias", - "DELETENS":"Eliminar NS", + "DELETENS": "Eliminar NS", "VALUE": "Valor", "PERFORMACTION": "Realizar una acción", "EXECUTE": "Ejecutar", @@ -153,6 +153,7 @@ "NODATE": "No se encontró información de fecha", "TYPEINFO": "Para agregar un nuevo TIPO, ingrese la entrada de arriba", "UPLOADCONFIGLABEL": "Cargue el archivo con formato .yaml o .yml", + "CONFIGFILEUPLOADLABEL": "O ingrese los parámetros de configuración", "NEWVERSIONTAG": "¡Aquí está la nueva versión {{appVersion}} de OSM!", "SCALEOUT": "Desescalar", "SCALEIN": "Escalar", @@ -197,7 +198,7 @@ "HEALING": "Curación Manual", "DAY1OPERATION": "Operación día 1", "SELECTVDU": "Seleccionar VDU", - "DATE":"Fecha", + "DATE": "Fecha", "PAGE": { "DASHBOARD": { "DASHBOARD": "Tablero", @@ -209,6 +210,7 @@ "RUNNINGINSTANCES": "Corriendo Instancias", "NETSLICETEMPLATE": "Plantilla NetSlice", "NETSLICEINSTANCE": "NetSlice Instancias", + "NSCONFIGTEMPLATE": "Plantilla de configuración NS", "USERS": "Usuarios", "PROJECTS": "Proyectos", "USERSETTINGS": "Ajustes de usuario", @@ -455,6 +457,13 @@ "NETSLICETEMPLATE": { "NETSLICETEMPLATEDETAILS": "Detalles de la plantilla Network Slices" }, + "NSCONFIGTEMPLATE": { + "NEWNSCONFIGTEMPLATE": "Nueva plantilla de configuración NS", + "CREATENSCONFIGTEMPLATE": "Crear plantilla de configuración NS", + "EDITNSCONFIGTEMPLATE": "Editar plantilla de configuración NS", + "TEMPLATECREATEDSUCCESSFULLY": "Plantilla de configuración NS creada correctamente", + "TEMPLATEEDITEDSUCCESSFULLY": "Plantilla de configuración NS editada correctamente" + }, "NSTINSTANCEINSTANTIATE": { "NEWINSTANCE": "Nueva instancia", "NSNAME": "Nombre de Ns", diff --git a/src/assets/i18n/pt.json b/src/assets/i18n/pt.json index e24b3ed..75eb921 100644 --- a/src/assets/i18n/pt.json +++ b/src/assets/i18n/pt.json @@ -94,7 +94,7 @@ "DELETELOADERMESSAGE": "Aguarde enquanto a exclusão está em andamento", "DELETELOADMESSAGE": "Aguarde enquanto a exclusão está em andamento", "WARNINGMESSAGE": "Não é possível excluir mais de 25 instâncias", - "DELETENS":"Excluir NS", + "DELETENS": "Excluir NS", "VALUE": "Valor", "PERFORMACTION": "Executar a ação", "EXECUTE": "Executar", @@ -153,6 +153,7 @@ "NODATE": "Nenhuma informação de data encontrada", "TYPEINFO": "Para adicionar um novo TIPO, insira a entrada acima", "UPLOADCONFIGLABEL": "Faça o upload do arquivo no formato .yaml ou .yml", + "CONFIGFILEUPLOADLABEL": "Ou insira os parâmetros de configuração", "NEWVERSIONTAG": "Aqui está a nova versão {{appVersion}} do OSM!", "SCALEOUT": "Dimensionar", "SCALEIN": "Escala em", @@ -197,7 +198,7 @@ "HEALING": "Cura Manual", "DAY1OPERATION": "Operação dia 1", "SELECTVDU": "Selecione VDU", - "DATE":"Data", + "DATE": "Data", "PAGE": { "DASHBOARD": { "DASHBOARD": "painel de controle", @@ -209,6 +210,7 @@ "RUNNINGINSTANCES": "Instâncias em execução", "NETSLICETEMPLATE": "Modelo de fatia líquida", "NETSLICEINSTANCE": "Instâncias de fatia líquida", + "NSCONFIGTEMPLATE": "Modelo de configuração NS", "USERS": "Comercial", "PROJECTS": "Projetos", "USERSETTINGS": "Configurações do usuário", @@ -455,6 +457,13 @@ "NETSLICETEMPLATE": { "NETSLICETEMPLATEDETAILS": "Detalhes do modelo de fatias de rede" }, + "NSCONFIGTEMPLATE": { + "NEWNSCONFIGTEMPLATE": "Novo modelo de configuração NS", + "CREATENSCONFIGTEMPLATE": "Criar modelo de configuração NS", + "EDITNSCONFIGTEMPLATE": "Editar modelo de configuração NS", + "TEMPLATECREATEDSUCCESSFULLY": "Modelo de configuração NS criado com sucesso", + "TEMPLATEEDITEDSUCCESSFULLY": "Modelo de configuração NS editado com sucesso" + }, "NSTINSTANCEINSTANTIATE": { "NEWINSTANCE": "Nova Instância", "NSNAME": "Ns Name", diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index b3b625d..5168356 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -79,5 +79,6 @@ export const environment = { GRAFANA_URL: GRAFANA_ENDPOINT + '/d', DOMAIN_URL: OSM_ADMIN_ENDPOINT + 'domains', OSM_VERSION_URL: OSM_VERSION, - OSMREPOS_URL: OSM_ADMIN_ENDPOINT + 'osmrepos' + OSMREPOS_URL: OSM_ADMIN_ENDPOINT + 'osmrepos', + NSCONFIGTEMPLATE_URL: OSM_NSD_ENDPOINT + 'ns_config_template' }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 3f80777..de8ae5c 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -79,5 +79,6 @@ export const environment = { GRAFANA_URL: GRAFANA_ENDPOINT + '/d', DOMAIN_URL: OSM_ADMIN_ENDPOINT + 'domains', OSM_VERSION_URL: OSM_VERSION, - OSMREPOS_URL: OSM_ADMIN_ENDPOINT + 'osmrepos' + OSMREPOS_URL: OSM_ADMIN_ENDPOINT + 'osmrepos', + NSCONFIGTEMPLATE_URL: OSM_NSD_ENDPOINT + 'ns_config_template' }; diff --git a/src/models/MenuModel.ts b/src/models/MenuModel.ts index 5944aef..9ec1472 100644 --- a/src/models/MenuModel.ts +++ b/src/models/MenuModel.ts @@ -80,6 +80,16 @@ export const MENU_ITEMS: MENUITEMS[] = [ icon: 'fas fa-layer-group', menuName: 'PAGE.DASHBOARD.NETSLICETEMPLATE', isChildExists: false + }, + { + liClass: '', + anchorTagClass: 'link', + routerLink: '/packages/nsconfigtemplate', + routerLinkActive: childActiveClass, + routerLinkActiveOptions: false, + icon: 'fas fa-file', + menuName: 'PAGE.DASHBOARD.NSCONFIGTEMPLATE', + isChildExists: false } ] }, diff --git a/src/models/NSConfigtemplateModel.ts b/src/models/NSConfigtemplateModel.ts new file mode 100644 index 0000000..59de05b --- /dev/null +++ b/src/models/NSConfigtemplateModel.ts @@ -0,0 +1,62 @@ +/* + Copyright 2020 TATA ELXSI + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Author: SANDHYA JS (sandhya.j@tataelxsi.co.in) + */ +/** + * @file Model for NS Config template related information. + */ +export interface NSCONFIG { + _admin: ADMINDETAILS; + _id: string; + vnf: ADDITIONAL[]; + nsdId: string; + name: string; +} + +export interface ADMINDETAILS { + created?: string; + modified?: string; + onboardingState?: string; + operationalState?: string; + projects_read?: string[]; + projects_write?: string[]; +} + +export interface ADDITIONAL { + vdu: PARAMS[]; + 'member-vnf-index'?: string; +} + +export interface PARAMS { + id?: string; + 'vim-flavor-id'?: string; +} + +/** Interface for VNFData */ +export interface NSConfigData { + nsdId?: string; + identifier?: string; + created?: string; + modified?: string; + onboardingState?: string; + operationalState?: string; + name?: string; + config?: {}; + vnf?: {}; + additionalParamsForVnf?: {}; + additionalParamsForNs?: {}; + vld?: {}; +} diff --git a/tsconfig.json b/tsconfig.json index 556f954..1a46126 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -157,7 +157,10 @@ "NsUpdateComponent": ["src/app/utilities/ns-update/NsUpdateComponent"], "WarningComponent": ["src/app/utilities/warning/WarningComponent"], "StartStopRebuildComponent": ["src/app/utilities/start-stop-rebuild/StartStopRebuildComponent"], - "HealingComponent": ["src/app/utilities/healing/HealingComponent"] + "HealingComponent": ["src/app/utilities/healing/HealingComponent"], + "NSCONFIGTEMPLATE": ["src/app/packages/ns-config-template/NSConfigTemplateComponent"], + "NSCONFIGTEMPLATEACTION" :["src/app/utilities/ns-config-template-action/NSConfigTemplateActionComponent"], + "NSCONFIGTEMPLATEMODEL": ["src/models/NSConfigtemplateModel"] }, "useDefineForClassFields": false }