Skip to content

Commit

Permalink
[FEATURE] Fixes #205. Added Host management feature. (#210)
Browse files Browse the repository at this point in the history
  • Loading branch information
anvithks authored and wisererik committed Nov 22, 2019
1 parent 11bb81e commit 0afed07
Show file tree
Hide file tree
Showing 17 changed files with 1,060 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const routes: Routes = [
{path: 'block', loadChildren: './business/block/block.module#BlockModule'},
{path: 'createVolume', loadChildren: './business/block/create-volume/create-volume.module#CreateVolumeModule'},
{path: 'volumeDetails/:volumeId', loadChildren: './business/block/volume-detail/volume-detail.module#VolumeDetailModule'},
{path: 'createHost', loadChildren: './business/block/create-host/create-host.module#CreateHostModule'},
{path: 'hostDetails/:hostId', loadChildren: './business/block/host-detail/host-detail.module#HostDetailModule'},
{path: 'cloud', loadChildren: './business/cloud/cloud.module#CloudModule'},
{path: 'profile', loadChildren: './business/profile/profile.module#ProfileModule'},
{path: 'createProfile', loadChildren: './business/profile/createProfile/createProfile.module#CreateProfileModule'},
Expand Down
2 changes: 2 additions & 0 deletions src/app/business/block/block.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class BlockComponent implements OnInit{
showDropDown:boolean = false;
fromVolume:boolean = false;
fromFileShare:boolean = false;
fromHosts: boolean = false;
countItems = [];
constructor(
public I18N: I18NService,
Expand All @@ -54,6 +55,7 @@ export class BlockComponent implements OnInit{
this.fromBuckets = params.fromRoute === "fromBuckets";
this.fromVolume = params.fromRoute === "fromVolume";
this.fromFileShare = params.fromRoute === "fromFileShare";
this.fromHosts = params.fromRoute === "fromHosts";
}
);
}
Expand Down
6 changes: 6 additions & 0 deletions src/app/business/block/block.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,11 @@
</div>
<app-file-share></app-file-share>
</p-tabPanel>
<p-tabPanel header="Hosts" [selected]="fromHosts">
<div class="content-header">
<p>{{I18N.keyID['sds_block_hosts_descrip']}}</p>
</div>
<app-hosts></app-hosts>
</p-tabPanel>

</p-tabView>
2 changes: 2 additions & 0 deletions src/app/business/block/block.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { VolumeListModule } from './volumeList.module';
import { VolumeGroupModule } from './volumeGroup.module';
import { BucketsModule } from './buckets.module';
import { FileShareModule } from './fileShare.module';
import { HostsModule } from './hosts.module';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';

Expand All @@ -26,6 +27,7 @@ let routers = [{
ButtonModule,
BucketsModule,
FileShareModule,
HostsModule,
ReactiveFormsModule,
FormsModule,
CommonModule
Expand Down
63 changes: 63 additions & 0 deletions src/app/business/block/create-host/create-host.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<p-growl [value]="msgs" [sticky]="false" [life]="6000"></p-growl>
<div class="page-header">
<div class="custom-breadcrumb">
<span *ngFor="let item of items; index as i">
<a [ngClass]="{'font-color-class': i===0}" [routerLink]="[item.url,'fromHosts']">{{item.label}}</a>
<span *ngIf="(i+1) !== items.length">></span>
</span>
</div>
<div class="content-header">
<h1>{{i18n.keyID['sds_create_host']}}</h1>
<p>{{i18n.keyID['sds_block_createHost_desc']}}</p>
</div>
<hr />
</div>
<form [formGroup]="createHostform" [grid]="{label: 'ui-g-2', content:'ui-g-20'}" (ngSubmit)="onSubmit()" [errorMessage]="errorMessage">

<form-item [required]="true" label="{{label.name}}">
<input formControlName="hostName" type="text" size="30" pInputText [maxlength]="30" [minlength]="2">
</form-item>
<form-item [required]="true" label="{{label.osType}}">
<p-dropdown [options]="osTypeOptions" formControlName="osType" placeholder="Please choose"></p-dropdown>
</form-item>
<form-item [required]="true" label="{{label.ip}}">
<input formControlName="ip" type="text" size="30" pInputText>
</form-item>
<form-item [required]="true" label="{{label.accessMode}}">
<p-dropdown [options]="accessModeOptions" formControlName="accessMode" placeholder="Please choose"></p-dropdown>
</form-item>
<form-item [required]="true" label="{{label.availabilityZones}}">
<p-multiSelect [options]="availabilityZonesOptions" formControlName="availabilityZones" defaultLabel="Please choose multiple"></p-multiSelect>
</form-item>
<form-item [required]="true" label="{{label.initiators}}">
<a class="add-initiator" (click)="addNext()"><i class="fa fa-plus-circle" ></i></a>
<div class="initiator-array" formArrayName="initiators"
*ngFor="let item of createHostform.controls['initiators'].controls; let i = index">
<div class="ui-g ui-fluid" [formGroupName]="i">
<div class="ui-g-12 ui-md-4">
<div class="ui-inputgroup">
<input type="text" pInputText formControlName='portName' placeholder="Port">
</div>
</div>
<div class="ui-g-12 ui-md-4 ui-md-offset-1">
<div class="ui-inputgroup">
<p-dropdown [style]="{'min-width':125}" [options]="protocolOptions" formControlName="protocol" placeholder="Please choose protocol"></p-dropdown>
</div>
</div>
<div class="ui-g-12 ui-md-2 ui-md-offset-1">
<div class="ui-inputgroup">
<a disabled="createHostform.controls['initiators'].length > 1" class="remove-initiator" (click)="removeLink(i)"><i class="fa fa-minus-circle"></i></a>
</div>
</div>
</div>
</div>

</form-item>


<div class="bottom-button-margin">
<button pButton type="submit" class="ui-button-secondary" label="{{i18n.keyID['ok']}}" [disabled]="createHostform.invalid" ></button>
<button pButton type="button" label="{{i18n.keyID['cancel']}}" [routerLink]="['/block','fromHosts']"></button>
</div>
</form>

187 changes: 187 additions & 0 deletions src/app/business/block/create-host/create-host.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { trigger, state, style, transition, animate } from '@angular/animations';
import { Validators, FormControl, FormGroup, FormBuilder, FormArray } from '@angular/forms';

import { Message, SelectItem } from './../../../components/common/api';
import { AvailabilityZonesService } from './../../resource/resource.service';
import { HostsService} from './../hosts.service';
import { I18NService,Utils } from '../../../../app/shared/api';
import { Form } from '../../../components/form/form';

@Component({
selector: 'app-create-host',
templateUrl: './create-host.component.html',
styleUrls: [

],
animations: [
trigger('overlayState', [
state('hidden', style({
opacity: 0
})),
state('visible', style({
opacity: 1
})),
transition('visible => hidden', animate('400ms ease-in')),
transition('hidden => visible', animate('400ms ease-out'))
]),

trigger('notificationTopbar', [
state('hidden', style({
height: '0',
opacity: 0
})),
state('visible', style({
height: '*',
opacity: 1
})),
transition('visible => hidden', animate('400ms ease-in')),
transition('hidden => visible', animate('400ms ease-out'))
])
]
})
export class CreateHostComponent implements OnInit {

label = {
availabilityZones: this.i18n.keyID["sds_host_availability_zones"],
name: this.i18n.keyID["sds_block_volume_name"],
osType: this.i18n.keyID["sds_host_os_type"],
ip: this.i18n.keyID["sds_host_ip"],
accessMode: this.i18n.keyID["sds_host_access_mode"],
initiators: this.i18n.keyID["sds_host_initiators"]
};
msgs: Message[];
items;
availabilityZonesOptions = [];
osTypeOptions;
accessModeOptions;
protocolOptions;
createHostform;
errorMessage = {
"availabilityZones": { required: "Atleast one Zone is required."},
"accessMode": { required: "Access Mode is required."},
"osType": { required: "OS Type is required."},
"ip": {
required: "IP Address is required",
pattern: "Enter valid IPv4 address"
},
"hostName": {
required: "Host Name is required.",
maxlength: "Maximum 28 characters",
minlength: "Minimum 2 characters"
}
};
validRule = {
'validIp': '([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})' /* Validates IPv4 address */
};

constructor(
private router: Router,
private fb: FormBuilder,
private HostsService: HostsService,
private availabilityZonesService:AvailabilityZonesService,
public i18n:I18NService
) {}

ngOnInit() {
this.osTypeOptions = [
{
label: "Linux",
value: 'linux'
},
{
label: "Windows",
value: 'windows'
},
];
this.accessModeOptions = [
{
label: "Agentless",
value: "agentless"
}
];
this.protocolOptions = [
{
label: "iSCSI",
value: "iscsi"
},
{
label: "FC",
value: "fibre_channel"
},
{
label: "NVMeOF",
value: "nvmeof"
}
]
this.getAZ();
this.items = [
{ label: this.i18n.keyID["sds_Hosts_title"], url: '/block' },
{ label: this.i18n.keyID["sds_create_host"], url: '/createHost' }
];
this.createHostform = this.fb.group({
'availabilityZones': new FormControl('', Validators.required),
'hostName': new FormControl('', {validators: [Validators.required, Validators.maxLength(28), Validators.minLength(2)]}),
'accessMode': new FormControl('', Validators.required),
'osType': new FormControl('', Validators.required),
'ip': new FormControl('', {validators:[Validators.required, Validators.pattern(this.validRule.validIp)]}),
'initiators' : this.fb.array([this.createInitiators()])
});

}
createInitiators(){
return this.fb.group({
portName: new FormControl('', Validators.required),
protocol: new FormControl('', Validators.required)
})
}
addNext() {
(this.createHostform.controls['initiators'] as FormArray).push(this.createInitiators())
}
removeLink(i: number) {
if(this.createHostform.controls['initiators'].length > 1){
this.createHostform.controls['initiators'].removeAt(i);
}
}
onSubmit(){
if(this.createHostform.valid){
let param = {
"accessMode" : this.createHostform.value.accessMode,
"hostName" : this.createHostform.value.hostName,
"osType" : this.createHostform.value.osType,
"ip" : this.createHostform.value.ip,
"availabilityZones" : this.createHostform.value.availabilityZones,
"initiators" : this.createHostform.value.initiators
}
this.createHost(param);
}

}
createHost(param){
this.HostsService.createHost(param).subscribe((res) => {
this.msgs = [];
this.msgs.push({severity: 'success', summary: 'Success', detail: 'Host Created Successfully.'});
this.router.navigate(['/block',"fromHosts"]);
}, (error) =>{
this.msgs = [];
this.msgs.push({severity: 'error', summary: 'Error', detail: error.json().message});
});
}

getAZ(){
this.availabilityZonesService.getAZ().subscribe((azRes) => {
let AZs=azRes.json();
let azArr = [];
if(AZs && AZs.length !== 0){
AZs.forEach(item =>{
let obj = {label: item, value: item};
azArr.push(obj);
})
}
this.availabilityZonesOptions = azArr;
})
}


}
48 changes: 48 additions & 0 deletions src/app/business/block/create-host/create-host.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';

import { CreateHostComponent } from './create-host.component';

import { HttpService } from './../../../shared/api';
import { VolumeService,ReplicationService } from './../volume.service';
import { ProfileService } from './../../profile/profile.service';
import { AvailabilityZonesService } from './../../resource/resource.service';
import { HostsService } from '../hosts.service';
import { InputTextModule, CheckboxModule, ButtonModule, DropdownModule, MultiSelectModule, DialogModule, Message, GrowlModule, SpinnerModule, FormModule } from './../../../components/common/api';

let routers = [{
path: '',
component: CreateHostComponent
}]

@NgModule({
imports: [
RouterModule.forChild(routers),
ReactiveFormsModule,
FormsModule,
CommonModule,
InputTextModule,
CheckboxModule,
ButtonModule,
DropdownModule,
MultiSelectModule,
DialogModule,
GrowlModule,
SpinnerModule,
FormModule
],
declarations: [
CreateHostComponent
],
providers: [
HttpService,
VolumeService,
ProfileService,
ReplicationService,
AvailabilityZonesService,
HostsService
]
})
export class CreateHostModule { }
Loading

0 comments on commit 0afed07

Please sign in to comment.