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
+