From 95d064550664f6c01e1b6b124116b7216e182188 Mon Sep 17 00:00:00 2001 From: Piotr Pekala Date: Wed, 20 Nov 2019 02:37:51 -0800 Subject: [PATCH] Support for GNS3 VM preferences --- src/app/app-routing.module.ts | 2 + src/app/app.module.ts | 8 +- .../preferences/gns3vm/gns3vm.component.html | 44 +++++++++++ .../preferences/gns3vm/gns3vm.component.scss | 7 ++ .../gns3vm/gns3vm.component.spec.ts | 0 .../preferences/gns3vm/gns3vm.component.ts | 75 +++++++++++++++++++ .../preferences/preferences.component.html | 3 + src/app/models/gns3vm/gns3vm.ts | 9 +++ src/app/models/gns3vm/gns3vmEngine.ts | 8 ++ src/app/models/gns3vm/vm.ts | 3 + src/app/services/gns3vm.service.ts | 28 +++++++ 11 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 src/app/components/preferences/gns3vm/gns3vm.component.html create mode 100644 src/app/components/preferences/gns3vm/gns3vm.component.scss create mode 100644 src/app/components/preferences/gns3vm/gns3vm.component.spec.ts create mode 100644 src/app/components/preferences/gns3vm/gns3vm.component.ts create mode 100644 src/app/models/gns3vm/gns3vm.ts create mode 100644 src/app/models/gns3vm/gns3vmEngine.ts create mode 100644 src/app/models/gns3vm/vm.ts create mode 100644 src/app/services/gns3vm.service.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 073289f9..8586b738 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -58,6 +58,7 @@ import { TracengTemplatesComponent } from './components/preferences/traceng/trac import { AddTracengTemplateComponent } from './components/preferences/traceng/add-traceng/add-traceng-template.component'; import { TracengTemplateDetailsComponent } from './components/preferences/traceng/traceng-template-details/traceng-template-details.component'; import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component'; +import { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.component'; const routes: Routes = [ { @@ -74,6 +75,7 @@ const routes: Routes = [ { path: 'installed-software', component: InstalledSoftwareComponent }, { path: 'server/:server_id/project/:project_id/snapshots', component: ListOfSnapshotsComponent }, { path: 'server/:server_id/preferences', component: PreferencesComponent }, + { path: 'server/:server_id/preferences/gns3vm', component: Gns3vmComponent }, // { path: 'server/:server_id/preferences/general', component: GeneralPreferencesComponent }, { path: 'server/:server_id/preferences/builtin', component: BuiltInPreferencesComponent}, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index bdda351c..81f715a5 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -253,6 +253,8 @@ import { TemplateFilter } from './filters/templateFilter.pipe'; import { NotificationService } from './services/notification.service'; import { DeviceDetectorModule } from 'ngx-device-detector'; import { ConfigDialogComponent } from './components/project-map/context-menu/dialogs/config-dialog/config-dialog.component'; +import { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.component'; +import { Gns3vmService } from './services/gns3vm.service'; if (environment.production) { Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', { @@ -426,7 +428,8 @@ if (environment.production) { AlignHorizontallyActionComponent, AlignVerticallyActionComponent, ConfirmationBottomSheetComponent, - ConfigDialogComponent + ConfigDialogComponent, + Gns3vmComponent ], imports: [ BrowserModule, @@ -512,7 +515,8 @@ if (environment.production) { ComputeService, TracengService, PacketCaptureService, - NotificationService + NotificationService, + Gns3vmService ], entryComponents: [ AddServerDialogComponent, diff --git a/src/app/components/preferences/gns3vm/gns3vm.component.html b/src/app/components/preferences/gns3vm/gns3vm.component.html new file mode 100644 index 00000000..7b0ef435 --- /dev/null +++ b/src/app/components/preferences/gns3vm/gns3vm.component.html @@ -0,0 +1,44 @@ +
+
+
+

GNS3 VM preferences

+
+
+
+ + + Enable the GNS3 VM + + + + + {{engine.name}} + + + + + Run the VM in headless mode + +
+ + + + + + + + + +
+ + keep the GNS3 VM running + suspend the GNS3 VM + stop the GNS3 VM + +
+
+ + +
+
+
diff --git a/src/app/components/preferences/gns3vm/gns3vm.component.scss b/src/app/components/preferences/gns3vm/gns3vm.component.scss new file mode 100644 index 00000000..ae93f5c6 --- /dev/null +++ b/src/app/components/preferences/gns3vm/gns3vm.component.scss @@ -0,0 +1,7 @@ +.form-field { + width: 100%; +} + +.select { + width: 100%; +} diff --git a/src/app/components/preferences/gns3vm/gns3vm.component.spec.ts b/src/app/components/preferences/gns3vm/gns3vm.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/preferences/gns3vm/gns3vm.component.ts b/src/app/components/preferences/gns3vm/gns3vm.component.ts new file mode 100644 index 00000000..acc3a7a8 --- /dev/null +++ b/src/app/components/preferences/gns3vm/gns3vm.component.ts @@ -0,0 +1,75 @@ +import { Component, OnInit } from "@angular/core"; +import { ActivatedRoute, Router } from '@angular/router'; +import { Gns3vmService } from '../../../services/gns3vm.service'; +import { Gns3vm } from '../../../models/gns3vm/gns3vm'; +import { Server } from '../../../models/server'; +import { ServerService } from '../../../services/server.service'; +import { Gns3vmEngine } from '../../../models/gns3vm/gns3vmEngine'; +import { FormBuilder, FormControl, Validators, FormGroup } from '@angular/forms'; +import { ToasterService } from '../../../services/toaster.service'; + + +@Component({ + selector: 'app-gns3vm', + templateUrl: './gns3vm.component.html', + styleUrls: ['./gns3vm.component.scss'] +}) +export class Gns3vmComponent implements OnInit { + public server: Server; + public gns3vm: Gns3vm; + public vmEngines: Gns3vmEngine[]; + public vmForm: FormGroup; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private gns3vmService: Gns3vmService, + private router: Router, + private formBuilder: FormBuilder, + private toasterService: ToasterService + ) { + this.vmForm = this.formBuilder.group({ + vmname: new FormControl(null, [Validators.required]), + ram: new FormControl(null, [Validators.required]), + vcpus: new FormControl(null, [Validators.required]) + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get("server_id"); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.gns3vmService.getGns3vm(this.server).subscribe((vm: Gns3vm) => { + this.gns3vm = vm; + this.vmForm.controls['vmname'].setValue(this.gns3vm.vmname); + this.vmForm.controls['ram'].setValue(this.gns3vm.ram); + this.vmForm.controls['vcpus'].setValue(this.gns3vm.vcpus); + this.gns3vmService.getGns3vmEngines(this.server).subscribe((vmEngines: Gns3vmEngine[]) => { + this.vmEngines = vmEngines; + }); + }); + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences']); + } + + setCloseAction(action: string) { + this.gns3vm.when_exit = action; + } + + save() { + if (this.vmForm.valid) { + this.gns3vm.vmname = this.vmForm.get('vmname').value; + this.gns3vm.ram = this.vmForm.get('ram').value; + this.gns3vm.vcpus= this.vmForm.get('vcpus').value; + + this.gns3vmService.updateGns3vm(this.server, this.gns3vm).subscribe(() => { + this.toasterService.success('GNS3 VM updated.'); + }); + } else { + this.toasterService.error('Fill all required fields with correct values.'); + } + } +} diff --git a/src/app/components/preferences/preferences.component.html b/src/app/components/preferences/preferences.component.html index 3f4246a7..f3000cf1 100644 --- a/src/app/components/preferences/preferences.component.html +++ b/src/app/components/preferences/preferences.component.html @@ -7,6 +7,9 @@
+ + GNS3 VM + Built-in diff --git a/src/app/models/gns3vm/gns3vm.ts b/src/app/models/gns3vm/gns3vm.ts new file mode 100644 index 00000000..f853443d --- /dev/null +++ b/src/app/models/gns3vm/gns3vm.ts @@ -0,0 +1,9 @@ +export interface Gns3vm { + enable: boolean; + engine: string; + headless: boolean; + ram: number; + vcpus: number; + vmname: string; + when_exit: string; +} diff --git a/src/app/models/gns3vm/gns3vmEngine.ts b/src/app/models/gns3vm/gns3vmEngine.ts new file mode 100644 index 00000000..4cc9b144 --- /dev/null +++ b/src/app/models/gns3vm/gns3vmEngine.ts @@ -0,0 +1,8 @@ +export interface Gns3vmEngine { + description: string; + engine_id: string; + name: string; + support_headless: boolean; + support_ram: boolean; + support_when_exit: boolean; +} diff --git a/src/app/models/gns3vm/vm.ts b/src/app/models/gns3vm/vm.ts new file mode 100644 index 00000000..b67b272a --- /dev/null +++ b/src/app/models/gns3vm/vm.ts @@ -0,0 +1,3 @@ +export interface VM { + vmname: string; +} diff --git a/src/app/services/gns3vm.service.ts b/src/app/services/gns3vm.service.ts new file mode 100644 index 00000000..fa6e040c --- /dev/null +++ b/src/app/services/gns3vm.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { HttpServer } from './http-server.service'; +import { Server } from '../models/server'; +import { Observable } from 'rxjs'; +import { Gns3vm } from '../models/gns3vm/gns3vm'; +import { Gns3vmEngine } from '../models/gns3vm/gns3vmEngine'; +import { VM } from '../models/gns3vm/vm'; + +@Injectable() +export class Gns3vmService { + constructor(private httpServer: HttpServer) {} + + getGns3vm(server: Server): Observable { + return this.httpServer.get(server, '/gns3vm') as Observable; + } + + updateGns3vm(server: Server, gns3vm: Gns3vm): Observable { + return this.httpServer.put(server, `/gns3vm`, gns3vm) as Observable; + } + + getGns3vmEngines(server: Server): Observable { + return this.httpServer.get(server, '/gns3vm/engines') as Observable; + } + + getVms(server: Server, engine: Gns3vmEngine): Observable { + return this.httpServer.get(server, `/gns3vm/engines/${engine.engine_id}/vms`) + } +}