Advanced Cluster Management - NGUI

	- Added new OKA packages module under packages
	- Added Profiless, KSU under k8s section
	- Feature 11020. 11022, 11023, 11024, 11025, 11026

Change-Id: Ibddeb4d5693ce24d80e378277693405c810f6e04
Signed-off-by: SANDHYA.JS <sandhya.j@tataelxsi.co.in>
diff --git a/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.html b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.html
new file mode 100644
index 0000000..e75cc7e
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.html
@@ -0,0 +1,126 @@
+<!--
+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)
+-->
+<form [formGroup]="KsuForm" (ngSubmit)="KSUAddSubmit();">
+    <div class="modal-header">
+        <h4 *ngIf="profileType === 'add'" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.ADDKSU' | translate}}</h4>
+        <h4 *ngIf="profileType === 'edit'"class="modal-title" id="modal-basic-title">{{'PAGE.K8S.EDITKSU' | translate}}</h4>
+        <h4 *ngIf="profileType === 'move'"class="modal-title" id="modal-basic-title">{{'PAGE.K8S.MOVE' | translate}}</h4>
+        <h4 *ngIf="profileType === 'clone'"class="modal-title" id="modal-basic-title">{{'PAGE.K8S.CLONE' | translate}}</h4>
+        <button class="button-xs" type="button" class="close" aria-label="Close" (click)="activeModal.close()">
+            <i class="fas fa-times-circle text-danger"></i>
+        </button>
+    </div>
+    <div class="modal-body modal-body-custom-height">
+        <div class="form-group row mb-3" *ngIf="isClone || isKsu">
+            <label class="col-sm-12 col-form-label mandatory-label"
+                [ngClass]="{'text-danger': KsuForm.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="name" id="name" [ngClass]="{ 'is-invalid': submitted && f.name.errors }" required>
+            </div>
+        </div>
+        <div class="form-group row mb-3"*ngIf="isKsu">
+            <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="description" id="description"
+                    [ngClass]="{ 'is-invalid': submitted && f.description.errors }" required></textarea>
+            </div>
+        </div>
+        <div class="form-group row mb-3" *ngIf="isClone || isMove || isKsu">
+            <label class="col-sm-4 col-form-label" for="profile_type">{{'PAGE.K8S.PROFILETYPE' | translate}}*</label>
+            <div class="col-sm-8">
+                <ng-select (change)="getprofileDetails($event.value)"
+                    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="isClone || isMove || isKsu">
+            <label class="col-sm-4 col-form-label" for="id">{{'PAGE.K8S.PROFILENAME' | translate}}*</label>
+            <div class="col-sm-8">
+                <ng-select placeholder=" {{'SELECT' | translate}} {{'NAME' |
+                    translate}}" [items]="profileDetails" bindLabel="name" bindValue="id" formControlName="id" id="id"
+                    [ngClass]="{ 'is-invalid': submitted && f.id.errors }" required>
+                </ng-select>
+            </div>
+        </div>
+        <div class="form-group row p-2 bg-light text-white justify-content-end mb-3"*ngIf="isKsu">
+            <div class="col-4">
+                <button class="button-xs" type="button" class="btn btn-primary" (click)="addOka()">
+                    <i class="fas fa-plus-circle"></i>{{'PAGE.K8S.SELECTOKA' | translate}}</button>
+            </div>
+        </div>
+        <ng-container *ngIf="isKsu">
+            <div formArrayName="oka" *ngFor="let params of getControls(); let i = index;">
+                <div class="form-group row" [formGroupName]="i">
+                    <div class="card bg-light">
+                        <div class="card-body">
+                            <div class="form-group row">
+                                <label class="col-sm-3 col-md-3 col-form-label" for="_id{{i}}">{{'PAGE.K8S.OKA' |
+                                    translate}}</label>
+                                <div class="col-sm-8 col-md-8">
+                                    <ng-select
+                                        placeholder="{{'SELECT' | translate}} {{'PAGE.K8S.OKANAME' | translate}}" [items]="okaDetail" bindLabel="name"
+                                        bindValue="id" formControlName="_id" id="_id{{i}}"
+                                        [ngClass]="{ 'is-invalid': submitted && params.controls._id.errors }">
+                                    </ng-select>
+                                    <div class="fileupload-text mt-1 mb-1">or {{'PAGE.K8S.PATH' | translate}}</div>
+                                <div class="col-sm-8 col-md-8">
+                                    <input autocomplete="off" class="form-control"
+                                        placeholder="{{'PAGE.K8S.PATH' | translate}}" type="text" formControlName="sw_catalog_path"
+                                        id="sw_catalog_path" [ngClass]="{ 'is-invalid': submitted && params.controls.sw_catalog_path.errors }">
+                                </div>
+                                </div>
+                                <label class="col-sm-3 col-md-3 col-form-label"
+                                    for="transformation{{i}}">{{'PAGE.K8S.TRANSFORMFILE' |
+                                    translate}}</label>
+                                <div class="col-sm-8 col-md-8">
+                                    <textarea rows="5" cols="50" class="form-control" placeholder="{{'YAMLCONFIG' | translate}}"
+                                        formControlName="transformation" id="transformation"></textarea>
+                                    <div class="fileupload-text mt-1 mb-1">{{'FILEUPLOADLABEL' | translate}}</div>
+                                    <div class="custom-file">
+                                        <input type="file" #fileInputConfig class="fileupload custom-file-input"
+                                            (change)="configFile($event.target.files)" id="customConfigFile">
+                                    </div>
+                                </div>
+                                <div class="col-sm-1">
+                                    <button class="button-xs" type="button" class="close" (click)="removeMapping(i)"
+                                        placement="right" ngbTooltip="{{ 'CANCEL' | translate }}">
+                                        <i class="fas fa-minus-circle text-danger"></i>
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </ng-container>
+    </div>
+    <div class="modal-footer">
+        <button type="button" class="btn btn-danger" (click)="activeModal.close()">{{'CANCEL' | translate}}</button>
+        <button *ngIf="profileType === 'add'" type="submit" class="btn btn-primary">{{'CREATE' | translate}}</button>
+        <button *ngIf="profileType === 'edit'" type="submit" class="btn btn-primary">{{'Edit' | translate}}</button>
+        <button *ngIf="profileType === 'move'" type="submit" class="btn btn-primary">{{'Move' | translate}}</button>
+        <button *ngIf="profileType === 'clone'" type="submit" class="btn btn-primary">{{'Clone' | translate}}</button>
+    </div>
+</form>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.scss b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.scss
new file mode 100644
index 0000000..c55461a
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.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/k8s/k8s-ksu/ksu-add/KSUAddComponent.ts b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.ts
new file mode 100644
index 0000000..26f86f1
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.ts
@@ -0,0 +1,481 @@
+/*
+ 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 KSUAddComponent.ts.
+ */
+import { HttpHeaders } from '@angular/common/http';
+import { Component, ElementRef, Injector, Input, OnInit, ViewChild } from '@angular/core';
+import { AbstractControl, FormArray, 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 * as jsyaml from 'js-yaml';
+import { INFRACONFIGPAYLOAD, KSU, OKA } from 'K8sModel';
+import { RestService } from 'RestService';
+import { isNullOrUndefined, SharedService } from 'SharedService';
+/**
+ * Creating Component
+ * @Component takes KSUAddComponent.html as template url
+ */
+@Component({
+    selector: 'app-ksu-add',
+    templateUrl: './KSUAddComponent.html',
+    styleUrls: ['./KSUAddComponent.scss']
+})
+/** Exporting a class @exports KSUAddComponent */
+export class KSUAddComponent implements OnInit {
+    /** To inject services @public */
+    public injector: Injector;
+
+    /** FormGroup instance added to the form @ html @public */
+    public KsuForm: FormGroup;
+
+    /** Contains all deployment methods */
+    public profileSelect: TYPESECTION[] = [];
+
+    /** Instance for active modal service @public */
+    public activeModal: NgbActiveModal;
+
+    /** Form submission Add */
+    public submitted: boolean = false;
+
+    /** check move action */
+    public isMove: boolean = false;
+
+    /** check clone action */
+    public isClone: boolean = false;
+
+    /** check KSU */
+    public isKsu: boolean = false;
+
+    /** Check the loading results @public */
+    public isLoadingResults: boolean = false;
+
+    /** Give the message for the loading @public */
+    public message: string = 'PLEASEWAIT';
+
+    /** contains url @public */
+    public profileUrl: string;
+
+    /** contains profileData @public */
+    public profileData: {}[] = [];
+
+    /** OKA array @private */
+    private okaArray: FormArray;
+
+    /** contains profile details @public */
+    public profileDetails: {}[];
+
+    /** contains Oka Data @public */
+    public okaData: {}[] = [];
+
+    /** contains OKA details @public */
+    public okaDetail: {}[];
+
+    /** contains payload @public */
+    public payload: INFRACONFIGPAYLOAD | KSU;
+
+    /** oka Form array @private */
+    private okaFormArray: FormArray;
+
+    /** Input contains Modal dialog component Instance @public */
+    @Input() public profileType: string;
+
+    /** Input contains Modal dialog component Instance @public */
+    @Input() public profileID: string;
+
+    /** Element ref for fileInputConfig @public */
+    @ViewChild('fileInputConfig') fileInputConfig: ElementRef<HTMLInputElement>;
+
+    /** Element ref for fileInputConfigLabel @public */
+    @ViewChild('fileInputConfigLabel') fileInputConfigLabel: ElementRef<HTMLLabelElement>;
+
+    /** FormBuilder instance added to the formBuilder @private */
+    private formBuilder: FormBuilder;
+
+    /** Utilizes rest service for any CRUD operations @private */
+    private restService: RestService;
+
+    /** Notifier service to popup notification @private */
+    private notifierService: NotifierService;
+
+    /** Contains tranlsate instance @private */
+    private translateService: TranslateService;
+
+    /** Controls the header form @private */
+    private headers: HttpHeaders;
+
+    /** Contains all methods related to shared @private */
+    private sharedService: SharedService;
+
+    constructor(injector: Injector) {
+        this.injector = injector;
+        this.restService = this.injector.get(RestService);
+        this.activeModal = this.injector.get(NgbActiveModal);
+        this.formBuilder = this.injector.get(FormBuilder);
+        this.notifierService = this.injector.get(NotifierService);
+        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'
+            }
+        ];
+    }
+
+    public ngOnInit(): void {
+        /** On Initializing call the methods */
+        this.KsuFormAction();
+        this.headers = new HttpHeaders({
+            Accept: 'application/json',
+            'Content-Type': 'application/json',
+            'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
+        });
+        this.okaDetails();
+        if (this.profileType === 'clone') {
+            this.isClone = true;
+        } else if (this.profileType === 'move') {
+            this.isMove = true;
+        } else if (this.profileType === 'edit') {
+            this.isKsu = true;
+            this.getksuDetails();
+        } else {
+            this.isKsu = true;
+        }
+    }
+
+    /** Generate primitive params @public */
+    get okaParamsBuilder(): FormGroup {
+        return this.formBuilder.group({
+            _id: [null],
+            sw_catalog_path: [null],
+            transformation: [null]
+        });
+    }
+
+
+    /** On modal initializing forms  @public */
+    public KsuFormAction(): void {
+        this.KsuForm = this.formBuilder.group({
+            name: ['', [Validators.required]],
+            description: ['', [Validators.required]],
+            profile_type: [null, [Validators.required]],
+            id: [null, [Validators.required]],
+            oka: this.formBuilder.array([])
+        });
+    }
+
+    /** Handle FormArray Controls @public */
+    public getControls(): AbstractControl[] {
+        return (this.KsuForm.get('oka') as FormArray).controls;
+    }
+
+    /** convenience getter for easy access to form fields */
+    get f(): FormGroup['controls'] { return this.KsuForm.controls; }
+
+    /** Get OKA details @public */
+    public okaDetails(): void {
+        this.isLoadingResults = true;
+        this.restService.getResource(environment.OKAPACKAGES_URL)
+            .subscribe((okaData: []): void => {
+                okaData.forEach((okaDetail: INFRACONFIGPAYLOAD): void => {
+                    const oka: {} = {
+                        name: okaDetail.name,
+                        id: okaDetail._id
+                    };
+                    this.okaData.push(oka);
+                });
+                this.okaDetail = this.okaData;
+                this.isLoadingResults = false;
+            }, (error: ERRORDATA): void => {
+                this.isLoadingResults = false;
+                this.restService.handleError(error, 'get');
+            });
+    }
+
+    /** Get KSU details @public */
+    public getksuDetails(): void {
+        this.restService.getResource(environment.KSU_URL + '/' + this.profileID)
+            .subscribe((ksuData: KSU): void => {
+                this.KsuForm.patchValue({ id: ksuData.profile._id, name: ksuData.name, description: ksuData.description, profile_type: ksuData.profile.profile_type });
+                this.getprofileDetails(this.KsuForm.value.profile_type, ksuData.profile.name);
+                ksuData.oka.forEach((data: OKA): void => {
+                    this.okaArray = this.KsuForm.get('oka') as FormArray;
+                    const transformations: string = JSON.stringify(data.transformation);
+                    if (!isNullOrUndefined(data._id)) {
+                        data.sw_catalog_path = null;
+                    } else if (!isNullOrUndefined(data.sw_catalog_path)) {
+                        data._id = null;
+                    }
+                    const okaFormGroup = this.formBuilder.group({
+                        _id: data._id,
+                        sw_catalog_path: data.sw_catalog_path,
+                        transformation: transformations
+                    });
+                    this.okaArray.push(okaFormGroup);
+                });
+            }, (error: ERRORDATA): void => {
+                this.restService.handleError(error, 'get');
+            });
+    }
+
+
+    /** On modal submit ksuAddSubmit will called @public */
+    public KSUAddSubmit(): void {
+        if (this.profileType === 'move') {
+            this.profileUrl = environment.KSU_URL + '/' + this.profileID + '/move';
+            this.payload = {
+                profile: {
+                    _id: this.KsuForm.value.id,
+                    profile_type: this.KsuForm.value.profile_type
+                }
+            };
+            this.getFormControl('description').disable();
+            this.getFormControl('oka').disable();
+            this.getFormControl('name').disable();
+        } else if (this.profileType === 'clone') {
+            this.getFormControl('description').disable();
+            this.getFormControl('oka').disable();
+            this.profileUrl = environment.KSU_URL + '/' + this.profileID + '/clone';
+            this.payload = {
+                name: this.KsuForm.value.name,
+                profile: {
+                    _id: this.KsuForm.value.id,
+                    profile_type: this.KsuForm.value.profile_type
+                }
+            };
+        } else if (this.profileType === 'edit' || this.profileType === 'add') {
+            this.addEditKSU();
+        }
+        this.submitted = true;
+        this.sharedService.cleanForm(this.KsuForm);
+        if (this.KsuForm.invalid) {
+            return;
+        }
+        if (this.profileType === 'edit') {
+            this.editKSU();
+        } else {
+            this.addKSU();
+        }
+    }
+
+    /** Add/Edit KSU @public */
+    public addEditKSU(): void {
+        this.okaArray = this.KsuForm.get('oka') as FormArray;
+        const transValue = this.okaArray.at(0).get('transformation').value;
+        const validJSON: boolean = this.sharedService.checkJson(transValue);
+        if (validJSON) {
+            for (let i = 0; i < this.okaArray.length; i++) {
+                const formGroup = this.okaArray.at(i) as FormGroup;
+                formGroup.patchValue({
+                    transformation: JSON.parse(transValue)
+                });
+            }
+        } else {
+            const getConfigJson: string = jsyaml.load(transValue, { json: true });
+            for (let i = 0; i < this.okaArray.length; i++) {
+                const formGroup = this.okaArray.at(i) as FormGroup;
+                formGroup.patchValue({
+                    transformation: JSON.parse(getConfigJson)
+                });
+            }
+        }
+        if (this.profileType === 'edit') {
+            this.profileUrl = environment.KSU_URL + '/' + this.profileID;
+            this.payload = {
+                name: this.KsuForm.value.name,
+                description: this.KsuForm.value.description,
+                profile: {
+                    _id: this.KsuForm.value.id,
+                    sw_catalog_path: this.KsuForm.value.sw_catalog_path,
+                    profile_type: this.KsuForm.value.profile_type
+                },
+                oka: this.KsuForm.value.oka
+            };
+        } else {
+            this.profileUrl = environment.KSU_URL;
+            this.payload = {
+                ksus: [{
+                    name: this.KsuForm.value.name,
+                    description: this.KsuForm.value.description,
+                    profile: {
+                        _id: this.KsuForm.value.id,
+                        sw_catalog_path: this.KsuForm.value.sw_catalog_path,
+                        profile_type: this.KsuForm.value.profile_type
+                    },
+                    oka: this.KsuForm.value.oka
+                }]
+            };
+        }
+    }
+    /** Add/move/clone KSU @public */
+    public addKSU(): void {
+        this.isLoadingResults = true;
+        const modalData: MODALCLOSERESPONSEDATA = {
+            message: 'Done'
+        };
+        const apiURLHeader: APIURLHEADER = {
+            url: this.profileUrl,
+            httpOptions: { headers: this.headers }
+        };
+        this.restService.postResource(apiURLHeader, this.payload).subscribe((result: {}) => {
+            this.activeModal.close(modalData);
+            this.isLoadingResults = false;
+            if (this.profileType === 'move') {
+                this.notifierService.notify('success',
+                    this.translateService.instant('PAGE.K8S.MOVEDSUCCESSFULLY'));
+            } else if (this.profileType === 'clone') {
+                this.notifierService.notify('success',
+                    this.translateService.instant('PAGE.K8S.CLONEDSUCCESSFULLY'));
+            } else {
+                this.notifierService.notify('success',
+                    this.translateService.instant('PAGE.K8S.KSUCREATEDSUCCESSFULLY'));
+            }
+        }, (error: ERRORDATA) => {
+            this.restService.handleError(error, 'post');
+            // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+            if (error.error.status === 422 || error.error.status === 400) {
+                this.activeModal.close(modalData);
+            }
+            this.isLoadingResults = false;
+        });
+    }
+
+    /** Edit KSU @public */
+    public editKSU(): void {
+        this.isLoadingResults = true;
+        const modalData: MODALCLOSERESPONSEDATA = {
+            message: 'Done'
+        };
+        const apiURLHeader: APIURLHEADER = {
+            url: this.profileUrl,
+            httpOptions: { headers: this.headers }
+        };
+        this.restService.patchResource(apiURLHeader, this.payload).subscribe((result: {}) => {
+            this.activeModal.close(modalData);
+            this.isLoadingResults = false;
+            this.notifierService.notify('success',
+                this.translateService.instant('PAGE.K8S.KSUEDITEDSUCCESSFULLY'));
+        }, (error: ERRORDATA) => {
+            this.restService.handleError(error, 'post');
+            // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+            if (error.error.status === 422 || error.error.status === 400) {
+                this.activeModal.close(modalData);
+            }
+            this.isLoadingResults = false;
+        });
+    }
+
+    /** 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.okaArray = this.KsuForm.get('oka') as FormArray;
+                    for (let i = 0; i < this.okaArray.length; i++) {
+                        const formGroup = this.okaArray.at(i) as FormGroup;
+                        formGroup.patchValue({
+                            transformation: fileContent // Set the value for the specified key
+                        });
+                    }
+                }).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.KsuForm.get('transformation').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;
+    }
+    /** Add OKA @public */
+    public addOka(): void {
+        this.okaFormArray = this.KsuForm.get('oka') as FormArray;
+        this.okaFormArray.push(this.okaParamsBuilder);
+    }
+
+    /** Remove OKA @public */
+    public removeMapping(index: number): void {
+        this.okaFormArray.removeAt(index);
+    }
+
+    /** Get profile details @public */
+    public getprofileDetails(event: string, name?: string): void {
+        this.profileData = [];
+        if (event === 'infra_config_profiles') {
+            this.profileUrl = environment.K8SINFRACONFIGPROFILE_URL;
+        } else if (event === 'infra_controller_profiles') {
+            this.profileUrl = environment.K8SINFRACONTROLLERPROFILE_URL;
+        } else if (event === 'app_profiles') {
+            this.profileUrl = environment.K8SAPPPROFILE_URL;
+        } else if (event === 'resource_profiles') {
+            this.profileUrl = environment.K8SRESOURCEPROFILE_URL;
+        }
+        this.restService.getResource(this.profileUrl)
+            .subscribe((profileData: []): void => {
+                profileData.forEach((profileDetail: INFRACONFIGPAYLOAD): void => {
+                    const profile: {} = {
+                        name: profileDetail.name,
+                        id: profileDetail._id
+                    };
+                    this.profileData.push(profile);
+                });
+                this.profileDetails = this.profileData;
+            }, (error: ERRORDATA): void => {
+                this.restService.handleError(error, 'get');
+            });
+    }
+    /** Used to get the AbstractControl of controlName passed @private */
+    private getFormControl(controlName: string): AbstractControl {
+        // eslint-disable-next-line security/detect-object-injection
+        return this.KsuForm.controls[controlName];
+    }
+}
diff --git a/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.html b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.html
new file mode 100644
index 0000000..de83ac5
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.html
@@ -0,0 +1,45 @@
+<!--
+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)
+-->
+<div class="d-flex flex-row justify-content-between">
+  <div class="d-flex align-items-center header-style">{{'PAGE.K8S.KSU' | translate}}</div>
+  <span class="button">
+    <button class="btn btn-primary me-2" type="button" placement="top" container="body"
+      ngbTooltip="{{'Create Profile' | translate}}" (click)="addKSU()">
+      <i class="fas fa-plus-circle" aria-hidden="true"></i>&nbsp; {{'PAGE.K8S.ADDKSU' | translate}}
+    </button>
+  </span>
+</div>
+<div class="mt-2 mb-2 list-utilites-actions">
+  <div class="col-auto me-auto">
+    <nav class="custom-items-config">
+      <span><i class="fas fa-clock text-success"></i>{{operationalStateFirstStep}}</span>
+      <span><i class="fas fa-spinner text-warning"></i>{{operationalStateSecondStep}}</span>
+      <span><i class="fas fa-spinner text-danger"></i>{{operationalStateThirdStep}}</span>
+      <span><i class="fas fa-times-circle text-danger"></i>{{operationalStateFourthStep}}</span>
+      <span><i class="fas fa-times-circle text-warning"></i>{{operationalStateFifthStep}}</span>
+    </nav>
+  </div>
+  <page-per-row class="me-2" (pagePerRow)="onChange($event)"></page-per-row>
+  <page-reload></page-reload>
+</div>
+<div class="smarttable-style bg-white mt-1">
+  <ng2-smart-table [ngClass]="checkDataClass" [settings]="settings" [source]="dataSource"
+    (userRowSelect)="onUserRowSelect($event)">
+  </ng2-smart-table>
+</div>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.scss b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.scss
new file mode 100644
index 0000000..c55461a
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.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/k8s/k8s-ksu/ksu-details/KSUComponent.ts b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.ts
new file mode 100644
index 0000000..2591b4c
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.ts
@@ -0,0 +1,254 @@
+/*
+ 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 KSUComponent.ts.
+ */
+import { Component, Injector, OnDestroy, OnInit } from '@angular/core';
+import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { TranslateService } from '@ngx-translate/core';
+import { CONFIGCONSTANT, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
+import { DataService } from 'DataService';
+import { environment } from 'environment';
+import { K8sActionComponent } from 'K8sActionComponent';
+import { INFRACONFIGPAYLOAD, K8SCreateCLUSTERDATA } from 'K8sModel';
+import { LocalDataSource } from 'ng2-smart-table';
+import { RestService } from 'RestService';
+import { Subscription } from 'rxjs';
+import { SharedService } from 'SharedService';
+import { KSUAddComponent } from '../ksu-add/KSUAddComponent';
+/**
+ * Creating Component
+ * @Component takes KSUComponent.html as template url
+ */
+@Component({
+    selector: 'app-ksu-details',
+    templateUrl: './KSUComponent.html',
+    styleUrls: ['./KSUComponent.scss']
+})
+/** Exporting a class @exports KSUComponent */
+export class KSUComponent implements OnInit, OnDestroy {
+    /** To inject services @public */
+    public injector: Injector;
+
+    /** handle translate @public */
+    public translateService: TranslateService;
+
+    /** Data of smarttable populate through LocalDataSource @public */
+    public dataSource: LocalDataSource = new LocalDataSource();
+
+    /** Columns list of the smart table @public */
+    public columnList: object = {};
+
+    /** Settings for smarttable to populate the table with columns @public */
+    public settings: object = {};
+
+    /** operational State created data @public */
+    public operationalStateFirstStep: string = CONFIGCONSTANT.k8OperationalStateFirstStep;
+
+    /** operational State in creation data @public */
+    public operationalStateSecondStep: string = CONFIGCONSTANT.k8OperationalStateStateSecondStep;
+
+    /** operational State in deletion data @public */
+    public operationalStateThirdStep: string = CONFIGCONSTANT.k8OperationalStateThirdStep;
+
+    /** operational State failed deletion data @public */
+    public operationalStateFourthStep: string = CONFIGCONSTANT.k8OperationalStateFourthStep;
+
+    /** operational State failed creation data @public */
+    public operationalStateFifthStep: string = CONFIGCONSTANT.k8OperationalStateFifthStep;
+
+    /** 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 ksuData: {}[] = [];
+
+    /** Contains all methods related to shared @private */
+    private sharedService: SharedService;
+
+    /** 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 */
+    public ngOnInit(): void {
+        this.generateColumns();
+        this.generateSettings();
+        this.generateData();
+        this.generateDataSub = this.sharedService.dataEvent.subscribe(() => { this.generateData(); });
+    }
+
+    /** smart table Header Colums @public */
+    public generateColumns(): void {
+        this.columnList = {
+            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',
+                filter: {
+                    type: 'list',
+                    config: {
+                        selectText: 'Select',
+                        list: [
+                            { value: this.operationalStateFirstStep, title: this.operationalStateFirstStep },
+                            { value: this.operationalStateSecondStep, title: this.operationalStateSecondStep },
+                            { value: this.operationalStateThirdStep, title: this.operationalStateThirdStep },
+                            { value: this.operationalStateThirdStep, title: this.operationalStateFourthStep },
+                            { value: this.operationalStateThirdStep, title: this.operationalStateFifthStep }
+                        ]
+                    }
+                },
+                valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): string => {
+                    if (row.state === this.operationalStateFirstStep) {
+                        return `<span class="icon-label" title="${row.state}">
+                                 <i class="fas fa-clock text-success"></i>
+                                 </span>`;
+                    } else if (row.state === this.operationalStateSecondStep) {
+                        return `<span class="icon-label" title="${row.state}">
+                                 <i class="fas fa-spinner text-warning"></i>
+                                 </span>`;
+                    } else if (row.state === this.operationalStateThirdStep) {
+                        return `<span class="icon-label" title="${row.state}">
+                                 <i class="fas fa-spinner text-danger"></i>
+                                 </span>`;
+                    } else if (row.state === this.operationalStateFourthStep) {
+                        return `<span class="icon-label" title="${row.state}">
+                                 <i class="fas fa-times-circle text-danger"></i>
+                                 </span>`;
+                    } else if (row.state === this.operationalStateFifthStep) {
+                        return `<span class="icon-label" title="${row.state}">
+                                 <i class="fas fa-times-circle text-warning"></i>
+                                 </span>`;
+                    } else {
+                        return `<span>${row.state}</span>`;
+                    }
+                }
+            },
+            created: { title: this.translateService.instant('CREATED'), width: '10%' },
+            modified: { title: this.translateService.instant('MODIFIED'), width: '10%' },
+            Actions: {
+                name: 'Action', width: '5%', filter: false, sort: false, title: this.translateService.instant('ACTIONS'), type: 'custom',
+                valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD => row,
+                renderComponent: K8sActionComponent
+            }
+        };
+    }
+
+    /** smart table Data Settings @public */
+    public generateSettings(): void {
+        this.settings = {
+            columns: this.columnList,
+            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);
+    }
+
+    /** smart table listing manipulation @public */
+    public onUserRowSelect(event: MessageEvent): void {
+        Object.assign(event.data, { page: 'k8-ksu' });
+        this.dataService.changeMessage(event.data);
+    }
+
+    /** Compose new KSU @public */
+    public addKSU(): void {
+        // eslint-disable-next-line security/detect-non-literal-fs-filename
+        const modalRef: NgbModalRef = this.modalService.open(KSUAddComponent, { backdrop: 'static' });
+        modalRef.componentInstance.profileType = 'add';
+        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();
+    }
+
+    /** Generate KSU object from loop and return for the datasource @public */
+    public generateKSUData(ksudata: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD {
+        return {
+            name: ksudata.name,
+            identifier: ksudata._id,
+            created: this.sharedService.convertEpochTime(Number(ksudata._admin.created)),
+            modified: this.sharedService.convertEpochTime(Number(ksudata._admin.modified)),
+            description: ksudata.description,
+            pageType: 'k8-ksu',
+            state: ksudata.state
+        };
+    }
+
+    /** Fetching the data from server to Load in the smarttable @protected */
+    protected generateData(): void {
+        this.isLoadingResults = true;
+        this.restService.getResource(environment.KSU_URL).subscribe((kSUData: K8SCreateCLUSTERDATA[]) => {
+            this.ksuData = [];
+            kSUData.forEach((KSUDetail: INFRACONFIGPAYLOAD) => {
+                const ksuDataObj: INFRACONFIGPAYLOAD = this.generateKSUData(KSUDetail);
+                this.ksuData.push(ksuDataObj);
+            });
+            if (this.ksuData.length > 0) {
+                this.checkDataClass = 'dataTables_present';
+            } else {
+                this.checkDataClass = 'dataTables_empty';
+            }
+            this.dataSource.load(this.ksuData).then((data: boolean) => {
+                this.isLoadingResults = false;
+            }).catch(() => {
+                this.isLoadingResults = false;
+            });
+        }, (error: ERRORDATA) => {
+            this.restService.handleError(error, 'get');
+            this.isLoadingResults = false;
+        });
+    }
+}