diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 95311bf8..c1a1006b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -257,6 +257,7 @@ import { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.componen import { Gns3vmService } from './services/gns3vm.service'; import { ThemeService } from './services/theme.service'; import { ConfigureGns3VMDialogComponent } from './components/servers/configure-gns3vm-dialog/configure-gns3vm-dialog.component'; +import { ImportApplianceComponent } from './components/project-map/import-appliance/import-appliance.component'; if (environment.production) { Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', { @@ -432,7 +433,8 @@ if (environment.production) { ConfirmationBottomSheetComponent, ConfigDialogComponent, Gns3vmComponent, - ConfigureGns3VMDialogComponent + ConfigureGns3VMDialogComponent, + ImportApplianceComponent ], imports: [ BrowserModule, diff --git a/src/app/components/project-map/import-appliance/import-appliance.component.html b/src/app/components/project-map/import-appliance/import-appliance.component.html new file mode 100644 index 00000000..655de651 --- /dev/null +++ b/src/app/components/project-map/import-appliance/import-appliance.component.html @@ -0,0 +1,12 @@ + + diff --git a/src/app/components/project-map/import-appliance/import-appliance.component.scss b/src/app/components/project-map/import-appliance/import-appliance.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/project-map/import-appliance/import-appliance.component.spec.ts b/src/app/components/project-map/import-appliance/import-appliance.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/project-map/import-appliance/import-appliance.component.ts b/src/app/components/project-map/import-appliance/import-appliance.component.ts new file mode 100644 index 00000000..b7c50a08 --- /dev/null +++ b/src/app/components/project-map/import-appliance/import-appliance.component.ts @@ -0,0 +1,159 @@ +import { Component, Input, OnInit } from "@angular/core"; +import { Project } from '../../../models/project'; +import { Server } from '../../../models/server'; +import { ToasterService } from '../../../services/toaster.service'; +import { ServerResponse } from '../../../models/serverResponse'; +import { FileUploader, ParsedResponseHeaders, FileItem } from 'ng2-file-upload'; +import { Template } from '../../../models/template'; +import { DockerTemplate } from '../../../models/templates/docker-template'; +import { QemuTemplate } from '../../../models/templates/qemu-template'; +import { IouTemplate } from '../../../models/templates/iou-template'; +import { IosTemplate } from '../../../models/templates/ios-template'; +import { TemplateService } from '../../../services/template.service'; +import { DockerService } from '../../../services/docker.service'; +import { QemuService } from '../../../services/qemu.service'; +import { IouService } from '../../../services/iou.service'; +import { IosService } from '../../../services/ios.service'; +import { TemplatePortalDirective } from '@angular/cdk/portal'; + + +@Component({ + selector: 'app-import-appliance', + templateUrl: './import-appliance.component.html', + styleUrls: ['./import-appliance.component.scss'] +}) +export class ImportApplianceComponent implements OnInit { + @Input('project') project: Project; + @Input('server') server: Server; + uploader: FileUploader; + template; + + constructor( + private toasterService: ToasterService, + private dockerService: DockerService, + private qemuService: QemuService, + private iouService: IouService, + private iosService: IosService + ) {} + + ngOnInit() { + this.uploader = new FileUploader({}); + this.uploader.onAfterAddingFile = file => { + file.withCredentials = false; + }; + + this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => { + this.toasterService.error('An error has occured'); + }; + + this.uploader.onCompleteItem = ( + item: FileItem, + response: string, + status: number, + headers: ParsedResponseHeaders + ) => { + if (this.template.template_type === 'qemu') { + this.qemuService.addTemplate(this.server, this.template).subscribe(() => this.onUploadComplete()); + } else if (this.template.template_type === 'iou') { + this.iouService.addTemplate(this.server, this.template).subscribe(() => this.onUploadComplete()); + } else if (this.template.template_type === 'dynamips') { + this.iosService.addTemplate(this.server, this.template).subscribe(() => this.onUploadComplete()); + } else if (this.template.template_type === 'docker') { + this.dockerService.addTemplate(this.server, this.template).subscribe(() => this.onUploadComplete()); + } + }; + } + + private onUploadComplete() { + this.toasterService.success('Appliance imported successfully'); + this.uploader.queue = []; + } + + public uploadAppliance(event) { + let file: File = event.target.files[0]; + let name: string = file.name; + let fileReader: FileReader = new FileReader(); + + let template; + fileReader.onloadend = () => { + let appliance = JSON.parse(fileReader.result as string); + let emulator: string; + + if (appliance.qemu) { + // option to select qemu image is missing + template = new QemuTemplate(); + template.template_type = 'qemu'; + template.adapter_type = appliance.qemu.adapter_type; + template.adapters = appliance.qemu.adapters; + template.ram = appliance.qemu.ram; + template.options = appliance.qemu.options; + template.console_type = appliance.qemu.console_type; + } else if (appliance.iou) { + // option to choose IOU image is missing + template = new IouTemplate(); + template.template_type = 'iou'; + template.console_type = appliance.iou.console_type; + template.console_auto_start = appliance.iou.console_auto_start; + template.ethernet_adapters = appliance.iou.ethernet_adapters; + template.l1_keepalives = appliance.iou.l1_keepalives; + template.nvram = appliance.iou.nvram; + template.ram = appliance.iou.ram; + template.serial_adapters = appliance.iou.serial_adapters; + } else if (appliance.dynamips) { + // option to choose IOS image is missing + template = new IosTemplate(); + template.template_type = 'dynamips'; + template.platform = appliance.dynamips.platform; + template.ram = appliance.dynamips.ram; + template.nvram = appliance.dynamips.nvram; + template.startup_config = appliance.dynamips.startup_config; + template.wic0 = appliance.dynamips.wic0; + template.wic1 = appliance.dynamips.wic1; + template.wic2 = appliance.dynamips.wic2; + template.slot0 = appliance.dynamips.slot0; + template.slot1 = appliance.dynamips.slot1; + template.slot2 = appliance.dynamips.slot2; + template.slot3 = appliance.dynamips.slot3; + template.slot4 = appliance.dynamips.slot4; + template.slot5 = appliance.dynamips.slot5; + template.slot6 = appliance.dynamips.slot6; + template.slot7 = appliance.dynamips.slot7; + } else if (appliance.docker) { + template = new DockerTemplate(); + template.template_type = 'docker'; + template.adapters = appliance.docker.adapters; + template.console_type = appliance.docker.console_type; + template.image = appliance.docker.image; + } else { + this.toasterService.error("Template type not supported"); + return; + } + template.name = appliance.name; + template.category = appliance.category; + template.builtin = false; + template.default_name_format = '{name}-{0}'; + template.compute_id = "vm"; + // qemu - VM + // iou - VM + main server + // dynamips - vm + main server + // docker - vm + + if (template.category === 'guest') { + template.symbol = `:/symbols/computer.svg`; + } else { + template.symbol = `:/symbols/${template.category}_guest.svg`; + } + this.template = template; + + const url = this.getUploadPath(this.server, template.template_type, name); + this.uploader.queue.forEach(elem => (elem.url = url)); + const itemToUpload = this.uploader.queue[0]; + this.uploader.uploadItem(itemToUpload); + }; + fileReader.readAsText(file); + } + + private getUploadPath(server: Server, emulator: string, filename: string) { + return `http://${server.host}:${server.port}/v2/${emulator}/images/${filename}`; + } +} diff --git a/src/app/components/project-map/project-map.component.html b/src/app/components/project-map/project-map.component.html index bfdf440f..d976c9ee 100644 --- a/src/app/components/project-map/project-map.component.html +++ b/src/app/components/project-map/project-map.component.html @@ -75,6 +75,7 @@ call_received Import portable project +