Advanced Cluster Enhancements 85/14985/3
authorSANDHYA.JS <sandhya.j@tataelxsi.co.in>
Thu, 13 Feb 2025 10:54:46 +0000 (16:24 +0530)
committerSANDHYA.JS <sandhya.j@tataelxsi.co.in>
Wed, 26 Feb 2025 09:11:24 +0000 (14:41 +0530)
- Added edit cluster, profile type in OKA
- State to Git State in all pages
- Changed mandatory fields of edit profile
- Changed api in cluster page

Change-Id: I8a3239f83eb58a3997e4550fc030694c0a2a6c72
Signed-off-by: SANDHYA.JS <sandhya.j@tataelxsi.co.in>
22 files changed:
src/app/k8s/k8s-action/K8sActionComponent.html
src/app/k8s/k8s-add-cluster/K8sAddClusterComponent.html
src/app/k8s/k8s-add-cluster/K8sAddClusterComponent.ts
src/app/k8s/k8s-ksu/ksu-details/KSUComponent.ts
src/app/k8s/k8s-profile/k8s-app-profile-details/K8sAppProfileComponent.ts
src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.html
src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.ts
src/app/k8s/k8s-profile/k8s-infra-config-details/K8sInfraConfigProfileComponent.ts
src/app/k8s/k8s-profile/k8s-infra-controller-details/K8sInfraControllerProfileComponent.ts
src/app/k8s/k8s-profile/k8s-resource-profile/K8sResourceProfileComponent.ts
src/app/k8s/k8scluster/K8sClusterComponent.ts
src/app/packages/oka-packages/OKAPackageComponent.ts
src/app/utilities/compose-packages/ComposePackages.html
src/app/utilities/compose-packages/ComposePackages.ts
src/app/utilities/oka-packages-action/OkaPackagesActionComponent.ts
src/assets/i18n/de.json
src/assets/i18n/en.json
src/assets/i18n/es.json
src/assets/i18n/pt.json
src/models/CommonModel.ts
src/models/K8sModel.ts
src/models/VNFDModel.ts

index 5482868..28c3fd8 100644 (file)
@@ -42,7 +42,7 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
   </button>
   <div *ngIf="isCluster || !isCluster && !isKSU && !isProfile && getK8sType !== 'repo' " class="btn-group" placement="bottom-right" ngbDropdown
     display="dynamic" container="body">
-    <button type="button" class="btn btn-primary" [disabled]="!isCluster" ngbDropdownToggle placement="top"
+    <button type="button" class="btn btn-primary" [disabled]="!isCluster || state != 'CREATED'" ngbDropdownToggle placement="top"
       container="body" ngbTooltip="{{'Attach Profile' | translate}}">
       <i class="fas fa-link"></i>
     </button>
@@ -67,11 +67,15 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
     </div>
   </div>
   <div *ngIf="((isCluster || !isCluster)&& !isKSU && !isProfile && getK8sType !== 'repo'  )" class="btn-group" ngbDropdown display="dynamic" container="body">
-    <button type="button" [disabled]="!isCluster" class="btn btn-primary dropdown-toggle action-button"
+    <button type="button" [disabled]="!isCluster || state != 'CREATED'" class="btn btn-primary dropdown-toggle action-button"
       ngbDropdownToggle>
       {{'ACTION' | translate}}
     </button>
     <div class="dropdown-menu list-action-dropdown" ngbDropdownMenu>
+      <button *ngIf="isCluster" type="button" class="btn btn-primary dropdown-item" placement="left"
+        (click)="editCluster('update')" container="body" ngbTooltip="{{'PAGE.K8S.UPDATECLUSTER' | translate}}">
+        <i class="fa fa-edit icons"></i> {{'PAGE.K8S.UPDATECLUSTER' | translate}}
+      </button>
       <button *ngIf="isCluster" type="button" class="btn btn-primary dropdown-item" placement="left"
         (click)="editCluster('upgrade')" container="body" ngbTooltip="{{'PAGE.K8S.UPGRADECLUSTER' | translate}}">
         <i class="fa fa-arrow-up"></i> {{'PAGE.K8S.UPGRADECLUSTER' | translate}}
index 3d623ae..e8b57b6 100644 (file)
@@ -26,6 +26,9 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
     <h4 *ngIf="profileType === 'upgrade'" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.UPGRADECLUSTER' |
       translate}}
     </h4>
+    <h4 *ngIf="profileType === 'update'" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.UPDATECLUSTER' |
+      translate}}
+    </h4>
     <h4 *ngIf="profileType === 'vertical'" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.VERTICALSCALING' |
       translate}}
     </h4>
@@ -59,6 +62,13 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
           formControlName="name" id="name" [ngClass]="{ 'is-invalid': submitted && f.name.errors }" required>
       </div>
     </div>
+    <div class="form-group row mb-3" *ngIf="profileType === 'update'">
+      <label class="col-sm-4 col-form-label" for="name">{{'PAGE.K8S.NAME' | translate}}</label>
+      <div class="col-sm-8">
+        <input autocomplete="off" class="form-control" placeholder="{{'PAGE.K8S.NAME' | translate}}" type="text"
+          formControlName="update" id="name" [ngClass]="{ 'is-invalid': submitted && f.update.errors }">
+      </div>
+    </div>
     <div class="form-group row mb-3" *ngIf="profileType === 'Manage'|| !isChecked">
       <label class="col-sm-4 col-form-label" for="k8s_version">{{'PAGE.K8S.K8SVERSION' | translate}}*</label>
       <div class="col-sm-8">
@@ -88,7 +98,7 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
         </ng-select>
       </div>
     </div>
-    <div class="form-group row mb-3" *ngIf="profileType === 'Manage' || profileType === 'Register' || !isChecked">
+    <div class="form-group row mb-3" *ngIf="profileType === 'Manage' || profileType === 'Register' || !isChecked || profileType === 'update'">
       <label class="col-sm-4 col-form-label" for="description">{{'PAGE.K8S.DESCRIPTION' | translate}}</label>
       <div class="col-sm-8">
         <textarea class="form-control" placeholder="{{'PAGE.K8S.DESCRIPTION' | translate}}" type="text"
@@ -179,7 +189,7 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
     <button type="button" class="btn btn-danger" (click)="activeModal.close()">{{'CANCEL' | translate}}</button>
     <button *ngIf="profileType === 'Manage'" type="submit" class="btn btn-primary">{{'CREATE' | translate}}</button>
     <button *ngIf="profileType === 'Register'" type="submit" class="btn btn-primary">{{'REGISTER' | translate}}</button>
-    <button *ngIf="profileType === 'upgrade' || profileType === 'vertical' || profileType === 'horizontal'"
+    <button *ngIf="profileType === 'upgrade' || profileType === 'vertical' || profileType === 'horizontal' || profileType === 'update'"
       type="submit" class="btn btn-primary">{{'APPLY'
       | translate}}</button>
   </div>
index cf03f0f..37ddc13 100644 (file)
@@ -27,7 +27,7 @@ import { NotifierService } from 'angular-notifier';
 import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, TYPESECTION } from 'CommonModel';
 import { environment } from 'environment';
 import * as jsyaml from 'js-yaml';
-import { K8SPayload } from 'K8sModel';
+import { K8SCLUSTERDATA, K8SPayload } from 'K8sModel';
 import { RestService } from 'RestService';
 import { isNullOrUndefined, SharedService } from 'SharedService';
 import { VimAccountDetails } from 'VimAccountModel';
@@ -66,6 +66,9 @@ export class K8sAddClusterComponent implements OnInit {
   /** Contains all deployment methods selected */
   public selectedDeploymentMethods: string[] = ['helm-chart-v3', 'juju-bundle'];
 
+  /** Contains all action types */
+  public actionTypes: string[] = ['update', 'upgrade', 'horizontal', 'vertical'];
+
   /** Instance for active modal service @public */
   public activeModal: NgbActiveModal;
 
@@ -149,6 +152,11 @@ export class K8sAddClusterComponent implements OnInit {
       'Content-Type': 'application/json',
       'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
     });
+    this.actionTypes.forEach((type: string): void => {
+      if (type === this.profileType) {
+        this.k8sClusterDetail();
+      }
+    });
   }
 
   /** On modal initializing forms  @public */
@@ -168,7 +176,8 @@ export class K8sAddClusterComponent implements OnInit {
       bootstrap: [true],
       k8sVersion: ['', [Validators.required]],
       nodeCount: ['', [Validators.required]],
-      nodeSize: ['', [Validators.required]]
+      nodeSize: ['', [Validators.required]],
+      update: ['']
     });
   }
 
@@ -187,6 +196,26 @@ export class K8sAddClusterComponent implements OnInit {
     });
   }
 
+  /** patch the form values for edit @public */
+  public k8sClusterDetail(): void {
+    this.isLoadingResults = true;
+    this.restService.getResource(environment.K8SCREATECLUSTER_URL + '/' + this.profileID).subscribe((k8sData: K8SCLUSTERDATA) => {
+      if (this.profileType === 'update') {
+        this.k8sclusterForm.patchValue({ update: k8sData.name, description: !isNullOrUndefined(k8sData.description) ? k8sData.description : '' });
+      } else if (this.profileType === 'upgrade') {
+        this.k8sclusterForm.patchValue({ k8sVersion: !isNullOrUndefined(k8sData.k8s_version) ? k8sData.k8s_version : '' });
+      } else if (this.profileType === 'horizontal') {
+        this.k8sclusterForm.patchValue({ nodeCount: !isNullOrUndefined(k8sData.node_count) ? k8sData.node_count : '' });
+      } else if (this.profileType === 'vertical') {
+        this.k8sclusterForm.patchValue({ nodeSize: !isNullOrUndefined(k8sData.node_size) ? k8sData.node_size : '' });
+      }
+      this.isLoadingResults = false;
+    }, (error: ERRORDATA) => {
+      this.restService.handleError(error, 'get');
+      this.isLoadingResults = false;
+    });
+  }
+
   /** Call the event when checkbox is checked @public */
   public getValue(event: Event): void {
     this.isChecked = (event.target as HTMLInputElement).checked;
@@ -207,6 +236,7 @@ export class K8sAddClusterComponent implements OnInit {
       this.getFormControl('k8sVersion').disable();
       this.getFormControl('nodeSize').disable();
       this.getFormControl('nodeCount').disable();
+      this.getFormControl('update').disable();
       this.manageCluster();
     } else if (this.profileType === 'Register' && this.isChecked === true) {
       this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/register';
@@ -220,6 +250,7 @@ export class K8sAddClusterComponent implements OnInit {
       this.getFormControl('k8sVersion').disable();
       this.getFormControl('nodeSize').disable();
       this.getFormControl('nodeCount').disable();
+      this.getFormControl('update').disable();
       this.registerCluster();
     } if (this.isChecked === false && this.profileType === 'Register') {
       this.clusterUrl = environment.K8SCLUSTER_URL;
@@ -231,6 +262,7 @@ export class K8sAddClusterComponent implements OnInit {
       this.getFormControl('k8sVersion').disable();
       this.getFormControl('nodeSize').disable();
       this.getFormControl('nodeCount').disable();
+      this.getFormControl('update').disable();
       this.oldregisterCluster();
     } else if (this.profileType === 'upgrade' || this.profileType === 'horizontal' || this.profileType === 'vertical') {
       this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'update';
@@ -246,6 +278,7 @@ export class K8sAddClusterComponent implements OnInit {
       this.getFormControl('node_count').disable();
       this.getFormControl('node_size').disable();
       this.getFormControl('k8s_version').disable();
+      this.getFormControl('update').disable();
       if (this.profileType === 'upgrade') {
         this.getFormControl('nodeCount').disable();
         this.getFormControl('nodeSize').disable();
@@ -257,6 +290,24 @@ export class K8sAddClusterComponent implements OnInit {
         this.getFormControl('k8sVersion').disable();
       }
       this.updateCluster();
+    } else if (this.profileType === 'update') {
+      this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID;
+      this.getFormControl('bootstrap').disable();
+      this.getFormControl('region_name').disable();
+      this.getFormControl('resource_group').disable();
+      this.getFormControl('nets').disable();
+      this.getFormControl('credentials').disable();
+      this.getFormControl('deployment_methods').disable();
+      this.getFormControl('vim_account').disable();
+      this.getFormControl('node_count').disable();
+      this.getFormControl('node_size').disable();
+      this.getFormControl('k8s_version').disable();
+      this.getFormControl('nodeCount').disable();
+      this.getFormControl('k8sVersion').disable();
+      this.getFormControl('nodeSize').disable();
+      this.getFormControl('name').disable();
+
+      this.editCluster();
     }
   }
 
@@ -456,6 +507,51 @@ export class K8sAddClusterComponent implements OnInit {
     });
   }
 
+
+  /** Update cluster @public */
+  public editCluster(): void {
+    this.submitted = true;
+    this.sharedService.cleanForm(this.k8sclusterForm);
+    if (this.k8sclusterForm.invalid) {
+      return;
+    }
+    const modalData: MODALCLOSERESPONSEDATA = {
+      message: 'Done'
+    };
+    const apiURLHeader: APIURLHEADER = {
+      url: this.clusterUrl,
+      httpOptions: { headers: this.headers }
+    };
+    this.isLoadingResults = true;
+    if (this.k8sclusterForm.value.description === '') {
+      delete this.k8sclusterForm.value.description;
+      this.payload = {
+        name: this.k8sclusterForm.value.update
+      };
+    }
+    if (this.k8sclusterForm.value.update === '') {
+      delete this.k8sclusterForm.value.update;
+      this.payload = {
+        description: this.k8sclusterForm.value.description
+      };
+    }
+    if (this.k8sclusterForm.value.update !== '' && this.k8sclusterForm.value.description !== '') {
+      this.payload = {
+        name: this.k8sclusterForm.value.update,
+        description: this.k8sclusterForm.value.description
+      };
+    }
+    this.restService.patchResource(apiURLHeader, this.payload).subscribe((result: {}) => {
+      this.activeModal.close(modalData);
+      this.isLoadingResults = false;
+      this.notifierService.notify('success',
+        this.translateService.instant('PAGE.K8S.UPDATEDSUCCESSFULLY'));
+    }, (error: ERRORDATA) => {
+      this.restService.handleError(error, 'post');
+      this.isLoadingResults = false;
+    });
+  }
+
   /** Nets file process @private */
   public netsFile(files: FileList): void {
     if (files && files.length === 1) {
index 2591b4c..85a19d8 100644 (file)
@@ -121,7 +121,7 @@ export class KSUComponent implements OnInit, OnDestroy {
             name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
             identifier: { title: this.translateService.instant('IDENTIFIER'), width: '15%' },
             state: {
-                title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+                title: this.translateService.instant('GITSTATE'), width: '15%', type: 'html',
                 filter: {
                     type: 'list',
                     config: {
index 4772c4c..06cd6eb 100644 (file)
@@ -121,7 +121,7 @@ export class K8sAppProfileComponent implements OnInit, OnDestroy {
             name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
             identifier: { title: this.translateService.instant('IDENTIFIER'), width: '15%' },
             state: {
-                title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+                title: this.translateService.instant('GITSTATE'), width: '15%', type: 'html',
                 filter: {
                     type: 'list',
                     config: {
index 493cb5b..d43ff63 100644 (file)
@@ -23,7 +23,7 @@ Author: SANDHYA JS (sandhya.j@tataelxsi.co.in)
             <i class="fas fa-times-circle text-danger"></i>
         </button>
     </div>
-    <div class="modal-body modal-body-custom-height">
+    <div class="modal-body modal-body-custom-height" *ngIf="isAdd">
         <div class="form-group row mb-3">
             <label class="col-sm-12 col-form-label mandatory-label"
                 [ngClass]="{'text-danger': profileForm.invalid === true && submitted === true}">{{'MANDATORYCHECK' |
@@ -43,6 +43,26 @@ Author: SANDHYA JS (sandhya.j@tataelxsi.co.in)
             </div>
         </div>
     </div>
+    <div class="modal-body modal-body-custom-height"*ngIf="isEdit">
+        <div class="form-group row mb-3">
+            <label class="col-sm-12 col-form-label mandatory-label"
+                [ngClass]="{'text-danger': profileForm.invalid === true && submitted === true}">{{'MANDATORYCHECK' |
+                translate}}</label>
+            <label class="col-sm-4 col-form-label" for="name">{{'PAGE.K8S.NAME' | translate}}</label>
+            <div class="col-sm-8">
+                <input autocomplete="off" class="form-control" placeholder="{{'PAGE.K8S.NAME' | translate}}" type="text"
+                    formControlName="updatename" id="name" [ngClass]="{ 'is-invalid': submitted && f.updatename.errors }">
+            </div>
+        </div>
+        <div class="form-group row mb-3">
+            <label class="col-sm-4 col-form-label" for="description">{{'PAGE.K8S.DESCRIPTION' | translate}}</label>
+            <div class="col-sm-8">
+                <textarea class="form-control" placeholder="{{'PAGE.K8S.DESCRIPTION' | translate}}" type="text"
+                    formControlName="updatedescription" id="description"
+                    [ngClass]="{ 'is-invalid': submitted && f.updatedescription.errors }"></textarea>
+            </div>
+        </div>
+    </div>
     <div class="modal-footer">
         <button type="button" class="btn btn-danger" (click)="activeModal.close()">{{'CANCEL' | translate}}</button>
         <button *ngIf="isAdd" type="submit" class="btn btn-primary">{{'CREATE' | translate}}</button>
index 5299323..5120f37 100644 (file)
  * @file K8sInfraConfigAddComponent.ts.
  */
 import { HttpHeaders } from '@angular/common/http';
-import { Component,Injector, Input, OnInit} from '@angular/core';
+import { Component, Injector, Input, OnInit } from '@angular/core';
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { TranslateService } from '@ngx-translate/core';
 import { NotifierService } from 'angular-notifier';
 import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, TYPESECTION, URLPARAMS } from 'CommonModel';
 import { environment } from 'environment';
-import { INFRACONFIGPAYLOAD} from 'K8sModel';
+import { INFRACONFIGPAYLOAD } from 'K8sModel';
 import { RestService } from 'RestService';
 import { SharedService, isNullOrUndefined } from 'SharedService';
 /**
@@ -73,11 +73,14 @@ export class K8sInfraConfigAddComponent implements OnInit {
     /** Input contains Modal dialog component Instance @public */
     @Input() public profileDescription: string;
 
-     /** check Add @public */
-     public isAdd = false;
+    /** check Add @public */
+    public isAdd = false;
 
-     /** check Edit @public */
-     public isEdit = false;
+    /** check Edit @public */
+    public isEdit = false;
+
+    /** Edit Payload @public */
+    public payload: INFRACONFIGPAYLOAD;
 
     /** FormBuilder instance added to the formBuilder @private */
     private formBuilder: FormBuilder;
@@ -128,7 +131,9 @@ export class K8sInfraConfigAddComponent implements OnInit {
         this.profileForm = this.formBuilder.group({
             name: ['', [Validators.required]],
             default: [null],
-            description: ['', [Validators.required]]
+            description: ['', [Validators.required]],
+            updatename: [''],
+            updatedescription: ['']
         });
     }
 
@@ -168,6 +173,8 @@ export class K8sInfraConfigAddComponent implements OnInit {
         };
 
         this.isLoadingResults = true;
+        delete this.profileForm.value.updatename;
+        delete this.profileForm.value.updatedescription;
         const payload: INFRACONFIGPAYLOAD = {
             name: this.profileForm.value.name,
             description: this.profileForm.value.description
@@ -202,12 +209,26 @@ export class K8sInfraConfigAddComponent implements OnInit {
             url: this.profileUrl,
             httpOptions: { headers: this.headers }
         };
-        const payload: INFRACONFIGPAYLOAD = {
-            name: this.profileForm.value.name,
-            description: this.profileForm.value.description
-        };
+        delete this.profileForm.value.name;
+        delete this.profileForm.value.description;
+        if (this.profileForm.value.updatename === '') {
+            this.payload = {
+                description: this.profileForm.value.updatedescription
+            };
+            delete this.profileForm.value.updatename;
+        } else if (this.profileForm.value.updatedescription === '') {
+            this.payload = {
+                name: this.profileForm.value.updatename
+            };
+            delete this.profileForm.value.updatedescription;
+        } else {
+            this.payload = {
+                name: this.profileForm.value.updatenamename,
+                description: this.profileForm.value.updatedescription
+            };
+        }
 
-        this.restService.patchResource(apiURLHeader, payload).subscribe((result: {}) => {
+        this.restService.patchResource(apiURLHeader, this.payload).subscribe((result: {}) => {
             this.activeModal.close(modalData);
             this.isLoadingResults = false;
             this.notifierService.notify('success',
index 760124b..2c76dbf 100644 (file)
@@ -121,7 +121,7 @@ export class K8sInfraConfigProfileComponent implements OnInit, OnDestroy {
             name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
             identifier: { title: this.translateService.instant('IDENTIFIER'), width: '15%' },
             state: {
-                title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+                title: this.translateService.instant('GITSTATE'), width: '15%', type: 'html',
                 filter: {
                     type: 'list',
                     config: {
index 0402acf..f5c93ae 100644 (file)
@@ -121,7 +121,7 @@ export class K8sInfraControllerProfileComponent implements OnInit, OnDestroy {
             name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
             identifier: { title: this.translateService.instant('IDENTIFIER'), width: '15%' },
             state: {
-                title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+                title: this.translateService.instant('GITSTATE'), width: '15%', type: 'html',
                 filter: {
                     type: 'list',
                     config: {
index 296b0f6..b1dbf95 100644 (file)
@@ -121,7 +121,7 @@ export class K8sResourceProfileComponent implements OnInit, OnDestroy {
             name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
             identifier: { title: this.translateService.instant('IDENTIFIER'), width: '15%' },
             state: {
-                title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+                title: this.translateService.instant('GITSTATE'), width: '15%', type: 'html',
                 filter: {
                     type: 'list',
                     config: {
index 95c8e88..c79493e 100644 (file)
@@ -165,7 +165,7 @@ export class K8sClusterComponent implements OnInit, OnDestroy {
         }
       },
       state: {
-        title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+        title: this.translateService.instant('GITSTATE'), width: '15%', type: 'html',
         filter: {
           type: 'list',
           config: {
@@ -288,66 +288,27 @@ export class K8sClusterComponent implements OnInit, OnDestroy {
   /** Fetching the data from server to Load in the smarttable @protected */
   protected generateData(): void {
     this.isLoadingResults = true;
-    const tempURL: Observable<K8SCLUSTERDATA[]>[] = [];
-    const apiUrl1: string = environment.K8SCLUSTER_URL;
-    const apiUrl2: string = environment.K8SCREATECLUSTER_URL;
-    const response1$: Observable<K8SCLUSTERDATA[]> = this.restService.getResource(apiUrl1).pipe(
-      map((data: unknown) =>
-        data as K8SCLUSTERDATA[]
-      )
-    );
-    const response2$: Observable<K8SCLUSTERDATA[]> = this.restService.getResource(apiUrl2).pipe(
-      map((data: unknown) =>
-        data as K8SCLUSTERDATA[]
-      )
-    );
-    tempURL.push(response1$, response2$);
-    forkJoin(tempURL).subscribe(
-      ([response1, response2]) => {
-        if (!isNullOrUndefined(response1) && !isNullOrUndefined(response2)) {
-          const combinedResponse: K8SCLUSTERDATA[] = [...response1, ...response2];
-          const uniqueResponse = this.removeDuplicates(combinedResponse);
-          this.k8sClusterData = [];
-          uniqueResponse.forEach((clusterData: K8SCLUSTERDATA) => {
-            const k8sClusterDataObj: K8SCLUSTERDATADISPLAY = this.generateK8sclusterData(clusterData);
-            this.k8sClusterData.push(k8sClusterDataObj);
-          });
-          if (this.k8sClusterData.length > 0) {
-            this.checkDataClass = 'dataTables_present';
-          } else {
-            this.checkDataClass = 'dataTables_empty';
-          }
-          this.dataSource.load(this.k8sClusterData).then((data: boolean) => {
-            this.isLoadingResults = false;
-          }).catch(() => {
-            this.isLoadingResults = false;
-          });
+    this.restService.getResource(environment.K8SCREATECLUSTER_URL).subscribe((k8sClusterDatas: K8SCLUSTERDATA[]) => {
+      if (!isNullOrUndefined(k8sClusterDatas)) {
+        this.k8sClusterData = [];
+        k8sClusterDatas.forEach((clusterData: K8SCLUSTERDATA) => {
+          const k8sClusterDataObj: K8SCLUSTERDATADISPLAY = this.generateK8sclusterData(clusterData);
+          this.k8sClusterData.push(k8sClusterDataObj);
+        });
+        if (this.k8sClusterData.length > 0) {
+          this.checkDataClass = 'dataTables_present';
+        } else {
+          this.checkDataClass = 'dataTables_empty';
         }
-      }, (error: ERRORDATA) => {
-        this.restService.handleError(error, 'get');
-        this.isLoadingResults = false;
-      });
-  }
-
-  /** Removes duplicates based on 'name' and merges them if necessary */
-  private removeDuplicates(response: K8SCLUSTERDATA[]): K8SCLUSTERDATA[] {
-    const seenIds = new Set();
-    const uniqueResponse: K8SCLUSTERDATA[] = [];
-    response.forEach((obj) => {
-      if (!seenIds.has(obj.name)) {
-        uniqueResponse.push(obj);
-        seenIds.add(obj.name);
-      } else {
-        const existingObj = uniqueResponse.find((o) => o.name === obj.name);
-        Object.keys(obj).forEach((key) => {
-          // eslint-disable-next-line security/detect-object-injection
-          if (existingObj[key] !== obj[key]) {
-            // eslint-disable-next-line security/detect-object-injection
-            existingObj[key] = obj[key];
-          }
+        this.dataSource.load(this.k8sClusterData).then((data: boolean) => {
+          this.isLoadingResults = false;
+        }).catch(() => {
+          this.isLoadingResults = false;
         });
       }
+    }, (error: ERRORDATA) => {
+      this.restService.handleError(error, 'get');
+      this.isLoadingResults = false;
     });
-    return uniqueResponse;
   }
 }
index 061b090..702d8e6 100644 (file)
@@ -125,7 +125,7 @@ export class OKAPackageComponent implements OnInit {
             name: { title: this.translateService.instant('NAME'), width: '15%', sortDirection: 'asc' },
             identifier: { title: this.translateService.instant('IDENTIFIER'), width: '20%' },
             state: {
-                title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+                title: this.translateService.instant('GITSTATE'), width: '15%', type: 'html',
                 filter: {
                     type: 'list',
                     config: {
@@ -225,7 +225,7 @@ export class OKAPackageComponent implements OnInit {
     public composeOKAPackage(): void {
         // eslint-disable-next-line security/detect-non-literal-fs-filename
         const modalRef: NgbModalRef = this.modalService.open(ComposePackages, { backdrop: 'static' });
-        modalRef.componentInstance.params = { page: 'oka-packages' };
+        modalRef.componentInstance.params = { page: 'oka-packages', operationType: 'add'  };
         modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
             if (result) {
                 this.sharedService.callData();
index 048e8cd..007b0ab 100644 (file)
@@ -17,7 +17,7 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
 -->
 <form [formGroup]="packagesForm" (ngSubmit)="createPackages()" autocomplete="off">
   <div class="modal-header">
-    <h4 class="modal-title" *ngIf="params.page === 'vnf-packages' || params.page === 'ns-packages'"
+    <h4 class="modal-title" *ngIf="params.page === 'vnf-package' || params.page === 'ns-package'"
       id="modal-basic-title">{{'CREATEPACKAGE' | translate}}</h4>
     <h4 class="modal-title" *ngIf="params.page === 'ns-config-template'" id="modal-basic-title">
       {{'PAGE.NSCONFIGTEMPLATE.CREATENSCONFIGTEMPLATE' | translate}}</h4>
@@ -36,18 +36,32 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
       <label class="col-sm-12 col-form-label mandatory-label"
         [ngClass]="{'text-danger': packagesForm.invalid === true && submitted === true}">{{'MANDATORYCHECK' |
         translate}}</label>
-      <label class="col-sm-6 col-form-label" *ngIf="!template else configtemplate">{{'PACKAGE' | translate}} {{'NAME' |
-        translate}}*</label>
-      <ng-template #configtemplate>
-        <label class="col-sm-6 col-form-label">{{'NAME' | translate}}*</label>
-      </ng-template>
+      <label class="col-sm-6 col-form-label" *ngIf="!template && !oka">{{'PACKAGE' | translate}} {{'NAME' | translate}}*</label>
+      <label class="col-sm-6 col-form-label" *ngIf="!template && params.page === 'oka-packages'">{{'PACKAGE' | translate}} {{'NAME' | translate}}*</label>
+      <label class="col-sm-6 col-form-label" *ngIf="!template && params.page === 'oka-packages-edit'">{{'PACKAGE' | translate}} {{'NAME' | translate}}</label>
+      <label class="col-sm-6 col-form-label" *ngIf="template">{{'NAME' | translate}}*</label>
       <div class="col-sm-6">
         <input type="text" class="form-control" placeholder="{{'NAME' | translate}}" formControlName="name" id="name"
           [ngClass]="{ 'is-invalid': submitted && f.name.errors }" required>
       </div>
     </div>
     <div class="form-group row mb-3" *ngIf="oka">
-      <label class="col-sm-6 col-form-label" for="description">{{'PAGE.K8S.DESCRIPTION' | translate}}*</label>
+      <label class="col-sm-6 col-form-label" for="profile_type"
+        *ngIf="params.page === 'oka-packages'">{{'PAGE.K8S.PROFILETYPE' | translate}}*</label>
+      <label class="col-sm-6 col-form-label" for="profile_type"
+        *ngIf="params.page === 'oka-packages-edit'">{{'PAGE.K8S.PROFILETYPE' | translate}}</label>
+      <div class="col-sm-6">
+        <ng-select placeholder="{{'SELECT' | translate}} {{'TYPE' | translate}}" [items]="profileSelect"
+          bindLabel="title" bindValue="value" formControlName="profile_type" id="profile_type"
+          [ngClass]="{ 'is-invalid': submitted && f.profile_type.errors }" required>
+        </ng-select>
+      </div>
+    </div>
+    <div class="form-group row mb-3" *ngIf="oka">
+      <label class="col-sm-6 col-form-label" for="description"
+        *ngIf="params.page === 'oka-packages'">{{'PAGE.K8S.DESCRIPTION' | translate}}*</label>
+      <label class="col-sm-6 col-form-label" for="description"
+        *ngIf="params.page === 'oka-packages-edit'">{{'PAGE.K8S.DESCRIPTION' | translate}}</label>
       <div class="col-sm-6">
         <textarea class="form-control" placeholder="{{'PAGE.K8S.DESCRIPTION' | translate}}" type="text"
           formControlName="description" id="description" [ngClass]="{ 'is-invalid': submitted && f.description.errors }"
@@ -76,7 +90,8 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
       </div>
     </div>
     <div class="form-group row mb-3" *ngIf="oka">
-      <label class="col-sm-6 col-form-label">{{'PACKAGE' | translate}}*</label>
+      <label class="col-sm-6 col-form-label" *ngIf="params.page === 'oka-packages'">{{'PACKAGE' | translate}}*</label>
+      <label class="col-sm-6 col-form-label" *ngIf="params.page === 'oka-packages-edit'">{{'PACKAGE' | translate}}</label>
       <div class="col-sm-6">
         <label for="fileInput" class="custom-file-upload" *ngIf="this.params.page === 'oka-packages-edit'">
           <input type="file" #fileInput class="fileupload custom-file-input" formControlName="package"
@@ -95,7 +110,7 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
   <div class="modal-footer">
     <button type="button" class="btn btn-danger" (click)="activeModal.close()">{{'CANCEL' | translate}}</button>
     <button
-      *ngIf="params.page === 'ns-config-template' || params.page === 'oka-packages' || params.page === 'vnf-packages' || params.page === 'ns-packages'"
+      *ngIf="params.page === 'ns-config-template' || params.page === 'oka-packages' || params.page === 'vnf-package' || params.page === 'ns-package'"
       type="submit" class="btn btn-primary">{{'CREATE' | translate}}</button>
     <button *ngIf="params.page === 'ns-config-template-edit' || params.page === 'oka-packages-edit'" type="submit"
       class="btn btn-primary">{{'Edit' | translate}}</button>
index 17adaa0..a8114d0 100644 (file)
@@ -25,7 +25,7 @@ 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, URLPARAMS } from 'CommonModel';
+import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, TYPESECTION, URLPARAMS } from 'CommonModel';
 import { DataService } from 'DataService';
 import { environment } from 'environment';
 import * as jsyaml from 'js-yaml';
@@ -120,6 +120,12 @@ export class ComposePackages implements OnInit {
   /** Contains selected file name @public */
   public selectedFileName: string = 'Choose file...';
 
+  /** Contains all profile methods */
+  public profileSelect: TYPESECTION[] = [];
+
+  /** Contains all profile methods */
+  public operationType: string;
+
   /** Element ref for fileInputConfig @public */
   @ViewChild('fileInputConfig') fileInputConfig: ElementRef<HTMLInputElement>;
 
@@ -166,6 +172,22 @@ export class ComposePackages implements OnInit {
     this.router = this.injector.get(Router);
     this.translateService = this.injector.get(TranslateService);
     this.sharedService = this.injector.get(SharedService);
+    this.profileSelect = [
+      {
+        title: 'Infra Config Profile',
+        value: 'infra_config_profiles'
+      },
+      {
+        title: 'Infra Controller Profile',
+        value: 'infra_controller_profiles'
+      }, {
+        title: 'App Profile',
+        value: 'app_profiles'
+      }, {
+        title: 'Resource Profile',
+        value: 'resource_profiles'
+      }
+    ];
   }
 
   /** convenience getter for easy access to form fields */
@@ -180,11 +202,13 @@ export class ComposePackages implements OnInit {
       this.template = true;
       this.oka = false;
       this.getNsdPackageDetails();
+      this.getFormControl('profile_type').disable();
       this.getFormControl('description').disable();
     } else if (this.params.page === 'ns-config-template-edit') {
       this.template = true;
       this.oka = false;
       this.getNsdPackageDetails();
+      this.getFormControl('profile_type').disable();
       this.getFormControl('nsdId').disable();
       this.getFormControl('description').disable();
     } else if (this.params.page === 'oka-packages') {
@@ -205,8 +229,11 @@ export class ComposePackages implements OnInit {
       this.template = false;
       this.getFormControl('nsdId').disable();
       this.getFormControl('config').disable();
+      this.getFormControl('profile_type').disable();
       this.getFormControl('description').disable();
     }
+    this.operationType = this.params.operationType;
+    this.setValidatorsForOperation();
   }
 
   /** initialize Forms @public */
@@ -215,10 +242,30 @@ export class ComposePackages implements OnInit {
       name: ['', [Validators.required]],
       nsdId: [null, [Validators.required]],
       config: [null],
+      profile_type: [null],
       description: ['', [Validators.required]],
       package: ['']
     });
   }
+  /** Get NSD Package details @public */
+  public setValidatorsForOperation(): void {
+    if (this.params.page === 'oka-packages') {
+      this.packagesForm.get('name').setValidators([Validators.required]);
+      this.packagesForm.get('description').setValidators([Validators.required]);
+      this.packagesForm.get('package').setValidators([Validators.required]);
+      this.packagesForm.get('profile_type').setValidators([Validators.required]);
+    } else if (this.params.page === 'oka-packages-edit') {
+      this.packagesForm.get('profile_type').clearValidators();
+      this.packagesForm.get('name').clearValidators();
+      this.packagesForm.get('description').clearValidators();
+      this.packagesForm.get('package').clearValidators();
+    }
+    this.packagesForm.get('profile_type').updateValueAndValidity();
+    this.packagesForm.get('name').updateValueAndValidity();
+    this.packagesForm.get('description').updateValueAndValidity();
+    this.packagesForm.get('package').updateValueAndValidity();
+  }
+
 
   /** Get NSD Package details @public */
   public getNsdPackageDetails(): void {
@@ -250,7 +297,7 @@ export class ComposePackages implements OnInit {
         this.package_name = nsdPackageData.name;
         const package_file = nsdPackageData._admin.storage.zipfile;
         this.selectedFileName = package_file;
-        this.packagesForm.patchValue({ name: this.package_name, description: nsdPackageData.description });
+        this.packagesForm.patchValue({ name: this.package_name, description: nsdPackageData.description, profile_type: nsdPackageData.profile_type });
         this.fileInput.nativeElement.value = null;
       }, (error: ERRORDATA): void => {
         this.restService.handleError(error, 'get');
index 7fef0d9..6fdbd1b 100644 (file)
@@ -91,7 +91,7 @@ export class OkaPackagesActionComponent {
     public okaEdit(): 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.okaID, page: 'oka-packages-edit' };
+        modalRef.componentInstance.params = { id: this.okaID, page: 'oka-packages-edit', operationType: 'edit' };
         modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
             if (result) {
                 this.sharedService.callData();
index b3dbfe4..c53e157 100644 (file)
@@ -54,6 +54,7 @@
     "OPERATIONALSTATUS": "Betriebs Status",
     "OPERATIONALSTATE": "Betriebszustand",
     "STATE": "Staat",
+    "GITSTATE": "Git-Status",
     "CONFIGSTATUS": "Konfigurations Status",
     "DETAILEDSTATUS": "Detaillierter Status",
     "NSDNAME": "Nsd name",
             "HORIZONTALSCALING": "Horizontale Skalierung",
             "VERTICALSCALING": "Vertikale Skalierung",
             "BOOTSTRAP": "Bootstrap",
-            "BOOTSTRAPINFO": "Bereite dich auf GitOps vor"
+            "BOOTSTRAPINFO": "Bereite dich auf GitOps vor",
+             "UPDATECLUSTER": "Cluster aktualisieren"
         },
         "OSMREPO": {
             "MENUOSMREPO": "OSM-Repositorys",
index ada5d6e..19be970 100644 (file)
@@ -54,6 +54,7 @@
     "OPERATIONALSTATUS": "Operational Status",
     "OPERATIONALSTATE": "Operational State",
     "STATE": "State",
+    "GITSTATE": "Git State",
     "CONFIGSTATUS": "Config Status",
     "DETAILEDSTATUS": "Detailed Status",
     "NSDNAME": "Nsd name",
             "HORIZONTALSCALING": "Horizontal Scaling",
             "VERTICALSCALING": "Vertical Scaling",
             "BOOTSTRAP": "Bootstrap",
-            "BOOTSTRAPINFO": "Prepare for GitOps"
+            "BOOTSTRAPINFO": "Prepare for GitOps",
+            "UPDATECLUSTER": "Update Cluster"
         },
         "OSMREPO": {
             "MENUOSMREPO": "OSM Repositories",
index 8082d6e..01b7a99 100644 (file)
@@ -55,6 +55,7 @@
     "OPERATIONALSTATE": "Estado operacional",
     "CONFIGSTATUS": "Estado de configuración",
     "STATE": "Estado",
+    "GITSTATE": "Estado de Git",
     "DETAILEDSTATUS": "Estado detallado",
     "NSDNAME": "Nombre nsd",
     "NSTNAME": "Nst name",
             "HORIZONTALSCALING": "Escalado Horizontal",
             "VERTICALSCALING": "Escalado Vertical",
             "BOOTSTRAP": "Bootstrap",
-            "BOOTSTRAPINFO": "Prepárate para GitOps"
+            "BOOTSTRAPINFO": "Prepárate para GitOps",
+             "UPDATECLUSTER": "Actualizar clúster"
         },
         "OSMREPO": {
             "MENUOSMREPO": "Repositorios OSM",
index 8c099b1..f96300d 100644 (file)
@@ -54,6 +54,7 @@
     "OPERATIONALSTATUS": "Estado operacional",
     "OPERATIONALSTATE": "Estado operacional",
     "STATE": "Estado",
+    "GITSTATE": "Estado do Git",
     "CONFIGSTATUS": "Status da configuração",
     "DETAILEDSTATUS": "Status detalhado",
     "NSDNAME": "Nome nsd",
             "HORIZONTALSCALING": "Escalonamento Horizontal",
             "VERTICALSCALING": "Escalonamento Vertical",
             "BOOTSTRAP": "Bootstrap",
-            "BOOTSTRAPINFO": "Prepare-se para GitOps"
+            "BOOTSTRAPINFO": "Prepare-se para GitOps",
+             "UPDATECLUSTER": "Atualizar cluster"
         },
         "OSMREPO": {
             "MENUOSMREPO": "Repositórios OSM",
index cb69103..b8d8837 100644 (file)
@@ -137,6 +137,7 @@ export interface URLPARAMS {
     createdbyosm?: string;
     bootstrap?: boolean;
     key?: boolean;
+    operationType?: string;
 }
 /** Handle the Delete params */
 export interface DELETEPARAMS {
index 58a96b1..06a13b2 100644 (file)
@@ -36,6 +36,8 @@ export interface K8SCLUSTERDATA {
     created?: string;
     bootstrap?: boolean;
     key?: string;
+    node_count?: number;
+    node_size?: number;
 }
 /** Interface for K8SCLUSTERDATA */
 export interface K8SREPODATA {
index cb9c6b9..2334538 100644 (file)
@@ -86,6 +86,7 @@ export interface VNFD {
     kdu?: [];
     name?: string;
     state?: string;
+    profile_type?: string;
 }
 /** Interface for DF */
 export interface VNFCONFIG {