mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-04-13 21:32:55 +00:00
Support for docker containers
This commit is contained in:
parent
41e715feeb
commit
02a040662e
@ -40,6 +40,9 @@ import { VmwarePreferencesComponent } from './components/preferences/vmware/vmwa
|
||||
import { VmwareTemplatesComponent } from './components/preferences/vmware/vmware-templates/vmware-templates.component';
|
||||
import { VmwareTemplateDetailsComponent } from './components/preferences/vmware/vmware-template-details/vmware-template-details.component';
|
||||
import { AddVmwareTemplateComponent } from './components/preferences/vmware/add-vmware-template/add-vmware-template.component';
|
||||
import { DockerTemplatesComponent } from './components/preferences/docker/docker-templates/docker-templates.component';
|
||||
import { AddDockerTemplateComponent } from './components/preferences/docker/add-docker-template/add-docker-template.component';
|
||||
import { DockerTemplateDetailsComponent } from './components/preferences/docker/docker-template-details/docker-template-details.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@ -91,7 +94,11 @@ const routes: Routes = [
|
||||
// { path: 'server/:server_id/preferences/vmware', component: VmwarePreferencesComponent },
|
||||
{ path: 'server/:server_id/preferences/vmware/templates', component: VmwareTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/vmware/templates/:template_id', component: VmwareTemplateDetailsComponent },
|
||||
{ path: 'server/:server_id/preferences/vmware/addtemplate', component: AddVmwareTemplateComponent }
|
||||
{ path: 'server/:server_id/preferences/vmware/addtemplate', component: AddVmwareTemplateComponent },
|
||||
|
||||
{ path: 'server/:server_id/preferences/docker/templates', component: DockerTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/docker/templates/:template_id', component: DockerTemplateDetailsComponent },
|
||||
{ path: 'server/:server_id/preferences/docker/addtemplate', component: AddDockerTemplateComponent }
|
||||
]
|
||||
},
|
||||
{ path: 'server/:server_id/project/:project_id', component: ProjectMapComponent }
|
||||
|
@ -145,6 +145,11 @@ import { VmwareTemplateDetailsComponent } from './components/preferences/vmware/
|
||||
import { AddVmwareTemplateComponent } from './components/preferences/vmware/add-vmware-template/add-vmware-template.component';
|
||||
import { DeleteConfirmationDialogComponent } from './components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component';
|
||||
import { DeleteTemplateComponent } from './components/preferences/common/delete-template-component/delete-template.component';
|
||||
import { DockerService } from './services/docker.service';
|
||||
import { DockerTemplatesComponent } from './components/preferences/docker/docker-templates/docker-templates.component';
|
||||
import { DockerConfigurationService } from './services/docker-configuration.service';
|
||||
import { AddDockerTemplateComponent } from './components/preferences/docker/add-docker-template/add-docker-template.component';
|
||||
import { DockerTemplateDetailsComponent } from './components/preferences/docker/docker-template-details/docker-template-details.component';
|
||||
|
||||
if (environment.production) {
|
||||
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
|
||||
@ -233,7 +238,10 @@ if (environment.production) {
|
||||
VmwareTemplateDetailsComponent,
|
||||
AddVmwareTemplateComponent,
|
||||
DeleteConfirmationDialogComponent,
|
||||
DeleteTemplateComponent
|
||||
DeleteTemplateComponent,
|
||||
DockerTemplatesComponent,
|
||||
AddDockerTemplateComponent,
|
||||
DockerTemplateDetailsComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@ -296,7 +304,9 @@ if (environment.production) {
|
||||
VpcsConfigurationService,
|
||||
BuiltInTemplatesConfigurationService,
|
||||
VmwareService,
|
||||
VmwareConfigurationService
|
||||
VmwareConfigurationService,
|
||||
DockerService,
|
||||
DockerConfigurationService
|
||||
],
|
||||
entryComponents: [
|
||||
AddServerDialogComponent,
|
||||
|
@ -0,0 +1,95 @@
|
||||
<div class="content">
|
||||
<div class="default-header">
|
||||
<div class="row">
|
||||
<h1 class="col">New Docker container template</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="default-content">
|
||||
<div class="container mat-elevation-z8">
|
||||
<mat-vertical-stepper [linear]="true">
|
||||
<mat-step label="Server type">
|
||||
<mat-radio-group class="radio-group">
|
||||
<mat-radio-button class="radio-button" value="1" (click)="setServerType('remote computer')">Run this Docker container on a remote computer</mat-radio-button>
|
||||
<mat-radio-button class="radio-button" value="2" (click)="setServerType('gns3 vm')" checked>Run this Docker container on the GNS3 VM</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
</mat-step>
|
||||
<mat-step label="Docker Virtual Machine">
|
||||
<form [formGroup]="virtualMachineForm">
|
||||
<mat-radio-group class="radio-group">
|
||||
<mat-radio-button class="radio-button" value="1" (click)="setDiskImage('existingImage')" checked>Existing image</mat-radio-button>
|
||||
<mat-radio-button class="radio-button" value="2" (click)="setDiskImage('newImage')">New image</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<mat-select
|
||||
*ngIf="!newImageSelected"
|
||||
placeholder="Image list"
|
||||
[ngModelOptions]="{standalone: true}"
|
||||
[(ngModel)]="selectedImage">
|
||||
<mat-option *ngFor="let image of dockerImages" [value]="image">
|
||||
{{image.filename}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<div *ngIf="newImageSelected">
|
||||
<mat-form-field class="form-field">
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
[(ngModel)]="dockerTemplate.image"
|
||||
formControlName="filename"
|
||||
placeholder="Image name"/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
<mat-step label="Container name">
|
||||
<form [formGroup]="containerNameForm">
|
||||
<mat-form-field class="form-field">
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
[(ngModel)]="dockerTemplate.name"
|
||||
formControlName="templateName"
|
||||
placeholder="Container name"/>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</mat-step>
|
||||
<mat-step label="Network adapters">
|
||||
<form [formGroup]="networkAdaptersForm">
|
||||
<mat-form-field class="form-field">
|
||||
<input
|
||||
matInput
|
||||
type="number"
|
||||
[(ngModel)]="dockerTemplate.adapters"
|
||||
formControlName="adapters"
|
||||
placeholder="Adapters"/>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</mat-step>
|
||||
<mat-step label="Start command">
|
||||
<mat-form-field class="form-field">
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
[(ngModel)]="dockerTemplate.start_command"
|
||||
placeholder="Start command"/>
|
||||
</mat-form-field>
|
||||
</mat-step>
|
||||
<mat-step label="Console type">
|
||||
<mat-select
|
||||
placeholder="Console type"
|
||||
[ngModelOptions]="{standalone: true}"
|
||||
[(ngModel)]="dockerTemplate.console_type">
|
||||
<mat-option *ngFor="let type of consoleTypes" [value]="type">
|
||||
{{type}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-step>
|
||||
<mat-step label="Environment">
|
||||
<mat-form-field class="form-field">
|
||||
<textarea matInput type="text" [(ngModel)]="dockerTemplate.environment"></textarea>
|
||||
</mat-form-field>
|
||||
<div class="buttons-bar"><button mat-raised-button color="primary" (click)="addTemplate()">Add template</button></div>
|
||||
</mat-step>
|
||||
</mat-vertical-stepper>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,30 @@
|
||||
.form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.radio-button {
|
||||
width: 50%;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
.radio-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.buttons-bar {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.nonvisible {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.file-button {
|
||||
width: 18%;
|
||||
}
|
||||
|
||||
.file-name-form-field {
|
||||
padding-left: 2%;
|
||||
width: 80%;
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { Server } from '../../../../models/server';
|
||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
||||
import { ServerService } from '../../../../services/server.service';
|
||||
import { ToasterService } from '../../../../services/toaster.service';
|
||||
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { TemplateMocksService } from '../../../../services/template-mocks.service';
|
||||
import { DockerTemplate } from '../../../../models/templates/docker-template';
|
||||
import { DockerService } from '../../../../services/docker.service';
|
||||
import { DockerConfigurationService } from '../../../../services/docker-configuration.service';
|
||||
import { DockerImage } from '../../../../models/docker/docker-image';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-add-docker-template',
|
||||
templateUrl: './add-docker-template.component.html',
|
||||
styleUrls: ['./add-docker-template.component.scss']
|
||||
})
|
||||
export class AddDockerTemplateComponent implements OnInit {
|
||||
server: Server;
|
||||
dockerTemplate: DockerTemplate;
|
||||
consoleTypes: string[] = [];
|
||||
isGns3VmChosen: boolean = false;
|
||||
isRemoteComputerChosen: boolean = false;
|
||||
dockerImages: DockerImage[] = [];
|
||||
newImageSelected: boolean = false;
|
||||
|
||||
virtualMachineForm: FormGroup;
|
||||
containerNameForm: FormGroup;
|
||||
networkAdaptersForm: FormGroup;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private serverService: ServerService,
|
||||
private dockerService: DockerService,
|
||||
private toasterService: ToasterService,
|
||||
private router: Router,
|
||||
private formBuilder: FormBuilder,
|
||||
private templateMocksService: TemplateMocksService,
|
||||
private configurationService: DockerConfigurationService
|
||||
) {
|
||||
this.dockerTemplate = new DockerTemplate();
|
||||
|
||||
this.virtualMachineForm = this.formBuilder.group({
|
||||
filename: new FormControl('', Validators.required)
|
||||
});
|
||||
|
||||
this.containerNameForm = this.formBuilder.group({
|
||||
templateName: new FormControl('', Validators.required)
|
||||
});
|
||||
|
||||
this.networkAdaptersForm = this.formBuilder.group({
|
||||
adapters: new FormControl('', 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.consoleTypes = this.configurationService.getConsoleTypes();
|
||||
|
||||
this.templateMocksService.getDockerTemplate().subscribe((dockerTemplate: DockerTemplate) => {
|
||||
this.dockerTemplate = dockerTemplate;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
setServerType(serverType: string) {
|
||||
if (serverType === 'gns3 vm') {
|
||||
this.isGns3VmChosen = true;
|
||||
} else {
|
||||
this.isRemoteComputerChosen = true;
|
||||
}
|
||||
}
|
||||
|
||||
setDiskImage(value: string) {
|
||||
this.newImageSelected = value === "newImage";
|
||||
}
|
||||
|
||||
addTemplate() {
|
||||
if (!this.virtualMachineForm.invalid && !this.containerNameForm.invalid && !this.networkAdaptersForm.invalid) {
|
||||
this.dockerTemplate.template_id = uuid();
|
||||
|
||||
this.dockerService.addTemplate(this.server, this.dockerTemplate).subscribe((template: DockerTemplate) => {
|
||||
this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']);
|
||||
});
|
||||
} else {
|
||||
this.toasterService.error(`Fill all required fields`);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
<div class="content" [ngClass]="{ shadowed: isConfiguratorOpened || isSymbolSelectionOpened}">
|
||||
<div class="default-header">
|
||||
<div class="row">
|
||||
<h1 class="col">Docker image configuration</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="default-content" *ngIf="dockerTemplate">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
General settings
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<mat-form-field class="row">
|
||||
<input matInput type="text" [(ngModel)]="dockerTemplate.name" placeholder="Template name">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="row">
|
||||
<input matInput type="text" [(ngModel)]="dockerTemplate.default_name_format" placeholder="Default name format">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="row">
|
||||
<mat-select placeholder="Category" [(ngModel)]="dockerTemplate.category">
|
||||
<mat-option *ngFor="let category of categories" [value]="category[1]">
|
||||
{{category[0]}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="row">
|
||||
<input matInput type="text" [(ngModel)]="dockerTemplate.symbol" placeholder="Symbol">
|
||||
</mat-form-field>
|
||||
<button mat-raised-button class="symbolSelectionButton" (click)="chooseSymbol()">Choose symbol</button><br/><br/>
|
||||
<mat-form-field class="row">
|
||||
<input matInput type="text" [(ngModel)]="dockerTemplate.start_command" placeholder="Start command">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="row">
|
||||
<input matInput type="number" [(ngModel)]="dockerTemplate.adapters" placeholder="Adapters">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="select">
|
||||
<mat-select placeholder="Console type" [(ngModel)]="dockerTemplate.console_type">
|
||||
<mat-option *ngFor="let type of consoleTypes" [value]="type">
|
||||
{{type}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-checkbox [(ngModel)]="dockerTemplate.console_auto_start">
|
||||
Auto start console
|
||||
</mat-checkbox>
|
||||
<mat-form-field class="select">
|
||||
<mat-select placeholder="VNC console resolution" [(ngModel)]="dockerTemplate.console_resolution">
|
||||
<mat-option *ngFor="let resolution of consoleResolutions" [value]="resolution">
|
||||
{{resolution}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="row">
|
||||
<input matInput type="number" [(ngModel)]="dockerTemplate.console_http_port" placeholder="HTTP port in the container">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="row">
|
||||
<input matInput type="text" [(ngModel)]="dockerTemplate.console_http_path" placeholder="HTTP path">
|
||||
</mat-form-field>
|
||||
<h6>Environment</h6>
|
||||
<mat-form-field class="row">
|
||||
<textarea matInput type="text" [(ngModel)]="dockerTemplate.environment"></textarea>
|
||||
</mat-form-field>
|
||||
</mat-expansion-panel>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Advanced
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<h6>Extra hosts</h6>
|
||||
<mat-form-field class="row">
|
||||
<textarea matInput type="text" [(ngModel)]="dockerTemplate.extra_hosts"></textarea>
|
||||
</mat-form-field>
|
||||
</mat-expansion-panel>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Usage
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<mat-form-field class="row">
|
||||
<textarea matInput type="text" [(ngModel)]="dockerTemplate.usage"></textarea>
|
||||
</mat-form-field>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
<div class="buttons-bar"><button mat-raised-button color="primary" (click)="onSave()">Save</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content" class="configurator" *ngIf="isSymbolSelectionOpened">
|
||||
<div class="default-header">
|
||||
<div class="row">
|
||||
<h1 class="col">Symbol selection</h1>
|
||||
<button class="top-button" (click)="chooseSymbol()" mat-raised-button color="primary">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="default-content">
|
||||
<app-symbols [server]="server" [symbol]="dockerTemplate.symbol" (symbolChanged)="symbolChanged($event)"></app-symbols>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,63 @@
|
||||
.row {
|
||||
width: 100%;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nonvisible {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.file-button {
|
||||
width: 18%;
|
||||
}
|
||||
|
||||
.file-name-form-field {
|
||||
padding-right: 2%;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.configButton {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.configHideButton {
|
||||
margin-left: 80%;
|
||||
width: 20%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.shadowed {
|
||||
display: none;
|
||||
transition: 0.25s;
|
||||
}
|
||||
|
||||
.top-button {
|
||||
height: 36px;
|
||||
margin-top: 22px
|
||||
}
|
||||
|
||||
.symbolSelectionButton {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nonshadowed {
|
||||
opacity: 0;
|
||||
transition: 0.25s;
|
||||
}
|
||||
|
||||
th {
|
||||
border: 0px!important;
|
||||
}
|
||||
|
||||
th.mat-header-cell {
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
td.mat-cell {
|
||||
padding-top: 15px;
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute, ParamMap } from '@angular/router';
|
||||
import { ServerService } from '../../../../services/server.service';
|
||||
import { Server } from '../../../../models/server';
|
||||
import { ToasterService } from '../../../../services/toaster.service';
|
||||
import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter';
|
||||
import { DockerTemplate } from '../../../../models/templates/docker-template';
|
||||
import { DockerService } from '../../../../services/docker.service';
|
||||
import { DockerConfigurationService } from '../../../../services/docker-configuration.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-docker-template-details',
|
||||
templateUrl: './docker-template-details.component.html',
|
||||
styleUrls: ['./docker-template-details.component.scss']
|
||||
})
|
||||
export class DockerTemplateDetailsComponent implements OnInit {
|
||||
server: Server;
|
||||
dockerTemplate: DockerTemplate;
|
||||
|
||||
isSymbolSelectionOpened: boolean = false;
|
||||
|
||||
consoleTypes: string[] = [];
|
||||
consoleResolutions: string[] = [];
|
||||
categories = [];
|
||||
adapters: CustomAdapter[] = [];
|
||||
displayedColumns: string[] = ['adapter_number', 'port_name'];
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private serverService: ServerService,
|
||||
private dockerService: DockerService,
|
||||
private toasterService: ToasterService,
|
||||
private configurationService: DockerConfigurationService
|
||||
){}
|
||||
|
||||
ngOnInit(){
|
||||
const server_id = this.route.snapshot.paramMap.get("server_id");
|
||||
const template_id = this.route.snapshot.paramMap.get("template_id");
|
||||
this.serverService.get(parseInt(server_id, 10)).then((server: Server) => {
|
||||
this.server = server;
|
||||
|
||||
this.getConfiguration();
|
||||
this.dockerService.getTemplate(this.server, template_id).subscribe((dockerTemplate: DockerTemplate) => {
|
||||
this.dockerTemplate = dockerTemplate;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getConfiguration(){
|
||||
this.consoleTypes = this.configurationService.getConsoleTypes();
|
||||
this.categories = this.configurationService.getCategories();
|
||||
this.consoleResolutions = this.configurationService.getConsoleResolutions();
|
||||
}
|
||||
|
||||
onSave(){
|
||||
this.dockerService.saveTemplate(this.server, this.dockerTemplate).subscribe((savedTemplate: DockerTemplate) => {
|
||||
this.toasterService.success("Changes saved");
|
||||
});
|
||||
}
|
||||
|
||||
chooseSymbol() {
|
||||
this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened;
|
||||
}
|
||||
|
||||
symbolChanged(chosenSymbol: string) {
|
||||
this.dockerTemplate.symbol = chosenSymbol;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<div class="content">
|
||||
<div class="default-header">
|
||||
<div class="row">
|
||||
<h1 class="col">Docker container templates</h1>
|
||||
<button *ngIf="server" class="top-button" routerLink="/server/{{server.id}}/preferences/docker/addtemplate" mat-raised-button color="primary">Add Docker container template</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="default-content">
|
||||
<div class="container mat-elevation-z8">
|
||||
<mat-nav-list *ngIf="server">
|
||||
<mat-list-item *ngFor='let template of dockerTemplates'>
|
||||
<span class="name" routerLink="{{template.template_id}}">{{template.name}}</span>
|
||||
<button class="delete-button" mat-icon-button (click)="deleteTemplate(template)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</mat-list-item>
|
||||
</mat-nav-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-delete-template
|
||||
#deleteComponent
|
||||
[server]="server"
|
||||
(deleteEvent)="onDeleteEvent()">
|
||||
</app-delete-template>
|
@ -0,0 +1,12 @@
|
||||
.top-button {
|
||||
height: 36px;
|
||||
margin-top: 22px
|
||||
}
|
||||
|
||||
.name {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.delete-button {
|
||||
width: 10%;
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||
import { Server } from '../../../../models/server';
|
||||
import { ActivatedRoute, ParamMap } from '@angular/router';
|
||||
import { ServerService } from '../../../../services/server.service';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component';
|
||||
import { DockerTemplate } from '../../../../models/templates/docker-template';
|
||||
import { DockerService } from '../../../../services/docker.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-docker-templates',
|
||||
templateUrl: './docker-templates.component.html',
|
||||
styleUrls: ['./docker-templates.component.scss']
|
||||
})
|
||||
export class DockerTemplatesComponent implements OnInit {
|
||||
server: Server;
|
||||
dockerTemplates: DockerTemplate[] = [];
|
||||
@ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private serverService: ServerService,
|
||||
private dockerService: DockerService
|
||||
) {}
|
||||
|
||||
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.getTemplates();
|
||||
});
|
||||
}
|
||||
|
||||
getTemplates() {
|
||||
this.dockerTemplates = [];
|
||||
this.dockerService.getTemplates(this.server).subscribe((dockerTemplates: DockerTemplate[]) => {
|
||||
dockerTemplates.forEach((template) => {
|
||||
if ((template.template_type === 'docker') && !template.builtin) {
|
||||
this.dockerTemplates.push(template);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
deleteTemplate(template: DockerTemplate) {
|
||||
this.deleteComponent.deleteItem(template.name, template.template_id);
|
||||
}
|
||||
|
||||
onDeleteEvent(deletedTemplateId: string) {
|
||||
this.getTemplates();
|
||||
}
|
||||
}
|
@ -37,6 +37,11 @@
|
||||
VMware
|
||||
</button>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<button mat-button routerLink="/server/{{serverId}}/preferences/docker/templates">
|
||||
Docker
|
||||
</button>
|
||||
</mat-list-item>
|
||||
</mat-nav-list>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,7 +6,6 @@ import { switchMap } from 'rxjs/operators';
|
||||
import { QemuTemplate } from '../../../../models/templates/qemu-template';
|
||||
import { QemuService } from '../../../../services/qemu.service';
|
||||
import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component';
|
||||
import { VpcsTemplate } from '../../../../models/templates/vpcs-template';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -45,7 +44,7 @@ export class QemuVmTemplatesComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
deleteTemplate(template: VpcsTemplate) {
|
||||
deleteTemplate(template: QemuTemplate) {
|
||||
this.deleteComponent.deleteItem(template.name, template.template_id);
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@ export class VmwareTemplatesComponent implements OnInit {
|
||||
private route: ActivatedRoute,
|
||||
private serverService: ServerService,
|
||||
private vmwareService: VmwareService,
|
||||
private dialog: MatDialog,
|
||||
private toasterService: ToasterService
|
||||
) {}
|
||||
|
||||
|
@ -24,7 +24,6 @@ export class VpcsTemplatesComponent implements OnInit {
|
||||
private route: ActivatedRoute,
|
||||
private serverService: ServerService,
|
||||
private vpcsService: VpcsService,
|
||||
private dialog: MatDialog,
|
||||
private toasterService: ToasterService
|
||||
) {}
|
||||
|
||||
|
3
src/app/models/docker/docker-image.ts
Normal file
3
src/app/models/docker/docker-image.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export class DockerImage {
|
||||
filename: string;
|
||||
}
|
24
src/app/models/templates/docker-template.ts
Normal file
24
src/app/models/templates/docker-template.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { CustomAdapter } from '../qemu/qemu-custom-adapter';
|
||||
|
||||
export class DockerTemplate {
|
||||
adapters: number;
|
||||
builtin: boolean;
|
||||
category: string;
|
||||
compute_id: string;
|
||||
console_auto_start: boolean;
|
||||
console_http_path: string;
|
||||
console_http_port: number;
|
||||
console_resolution: string;
|
||||
console_type: string;
|
||||
custom_adapters: CustomAdapter[];
|
||||
default_name_format: string;
|
||||
environment: string;
|
||||
extra_hosts: string;
|
||||
image: string;
|
||||
name: string;
|
||||
start_command: string;
|
||||
symbol: string;
|
||||
template_id: string;
|
||||
template_type: string;
|
||||
usage: string;
|
||||
}
|
22
src/app/models/templates/iou-template.ts
Normal file
22
src/app/models/templates/iou-template.ts
Normal file
@ -0,0 +1,22 @@
|
||||
export class IouTemplate {
|
||||
builtin: boolean;
|
||||
category: string;
|
||||
compute_id: string;
|
||||
console_auto_start: boolean;
|
||||
console_type: string;
|
||||
default_name_format: string;
|
||||
ethernet_adapters: number;
|
||||
l1_keepalives: boolean;
|
||||
name: string;
|
||||
nvram: number;
|
||||
path: string;
|
||||
private_config: string;
|
||||
ram: number;
|
||||
serial_adapters: number;
|
||||
startup_config: string;
|
||||
symbol: string;
|
||||
template_id: string;
|
||||
template_type: string;
|
||||
usage: string;
|
||||
use_default_iou_values: boolean;
|
||||
}
|
32
src/app/services/docker-configuration.service.ts
Normal file
32
src/app/services/docker-configuration.service.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
@Injectable()
|
||||
export class DockerConfigurationService {
|
||||
getConsoleTypes() {
|
||||
return ['telnet', 'vnc', 'http', 'https', 'none'];
|
||||
}
|
||||
|
||||
getCategories() {
|
||||
let categories = [["Default", "guest"],
|
||||
["Routers", "routers"],
|
||||
["Switches", "switches"],
|
||||
["End devices", "end_devices"],
|
||||
["Security devices", "security_devices"]];
|
||||
|
||||
return categories;
|
||||
}
|
||||
|
||||
getConsoleResolutions() {
|
||||
let consoleResolutions = [
|
||||
'1920x1080',
|
||||
'1366x768',
|
||||
'1280x1024',
|
||||
'1280x800',
|
||||
'1024x768',
|
||||
'800x600',
|
||||
'640x480'
|
||||
];
|
||||
|
||||
return consoleResolutions;
|
||||
}
|
||||
}
|
0
src/app/services/docker.service.spec.ts
Normal file
0
src/app/services/docker.service.spec.ts
Normal file
32
src/app/services/docker.service.ts
Normal file
32
src/app/services/docker.service.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { HttpServer } from './http-server.service';
|
||||
import { Server } from '../models/server';
|
||||
import { Observable } from 'rxjs';
|
||||
import { DockerTemplate } from '../models/templates/docker-template';
|
||||
import { DockerImage } from '../models/docker/docker-image';
|
||||
|
||||
@Injectable()
|
||||
export class DockerService {
|
||||
constructor(private httpServer: HttpServer) {}
|
||||
|
||||
getTemplates(server: Server): Observable<DockerTemplate[]> {
|
||||
return this.httpServer.get<DockerTemplate[]>(server, '/templates') as Observable<DockerTemplate[]>;
|
||||
}
|
||||
|
||||
getTemplate(server: Server, template_id: string): Observable<any> {
|
||||
return this.httpServer.get<DockerTemplate>(server, `/templates/${template_id}`) as Observable<DockerTemplate>;
|
||||
}
|
||||
|
||||
getImages(server: Server): Observable<DockerImage[]> {
|
||||
return this.httpServer.get<DockerImage[]>(server, '/compute/docker/images') as Observable<DockerImage[]>;
|
||||
}
|
||||
|
||||
addTemplate(server: Server, dockerTemplate: any): Observable<any> {
|
||||
return this.httpServer.post<DockerTemplate>(server, `/templates`, dockerTemplate) as Observable<DockerTemplate>;
|
||||
}
|
||||
|
||||
saveTemplate(server: Server, dockerTemplate: any): Observable<any> {
|
||||
return this.httpServer.put<DockerTemplate>(server, `/templates/${dockerTemplate.template_id}`, dockerTemplate) as Observable<DockerTemplate>;
|
||||
|
||||
}
|
||||
}
|
@ -8,6 +8,9 @@ import { CloudTemplate } from '../models/templates/cloud-template';
|
||||
import { EthernetSwitchTemplate } from '../models/templates/ethernet-switch-template';
|
||||
import { IosTemplate } from '../models/templates/ios-template';
|
||||
import { VmwareTemplate } from '../models/templates/vmware-template';
|
||||
import { DockerTemplate } from '../models/templates/docker-template';
|
||||
import { CustomAdapter } from '../models/qemu/qemu-custom-adapter';
|
||||
import { IouTemplate } from '../models/templates/iou-template';
|
||||
|
||||
@Injectable()
|
||||
export class TemplateMocksService {
|
||||
@ -223,4 +226,58 @@ export class TemplateMocksService {
|
||||
|
||||
return of(template);
|
||||
}
|
||||
|
||||
getDockerTemplate() : Observable<DockerTemplate> {
|
||||
let template: DockerTemplate = {
|
||||
adapters: 1,
|
||||
builtin: false,
|
||||
category: 'guest',
|
||||
compute_id: 'vm',
|
||||
console_auto_start: false,
|
||||
console_http_path: '/',
|
||||
console_http_port: 80,
|
||||
console_resolution: '1024x768',
|
||||
console_type: 'telnet',
|
||||
custom_adapters: [],
|
||||
default_name_format: '{name}-{0}',
|
||||
environment: '',
|
||||
extra_hosts: '',
|
||||
image: '',
|
||||
name: '',
|
||||
start_command: '',
|
||||
symbol: ':/symbols/docker_guest.svg',
|
||||
template_id: '',
|
||||
template_type: 'docker',
|
||||
usage: ''
|
||||
};
|
||||
|
||||
return of(template);
|
||||
}
|
||||
|
||||
getIouTemplate() : Observable<IouTemplate> {
|
||||
let template: IouTemplate = {
|
||||
builtin: false,
|
||||
category: 'switch',
|
||||
compute_id: 'vm',
|
||||
console_auto_start: false,
|
||||
console_type: 'telnet',
|
||||
default_name_format: 'IOU{0}',
|
||||
ethernet_adapters: 1,
|
||||
l1_keepalives: false,
|
||||
name: '',
|
||||
nvram: 128,
|
||||
path: '',
|
||||
private_config: '',
|
||||
ram: 256,
|
||||
serial_adapters: 0,
|
||||
startup_config: 'iou_l2_base_startup-config.txt',
|
||||
symbol: ':/symbols/multilayer_switch.svg',
|
||||
template_id: '',
|
||||
template_type: 'iou',
|
||||
usage: '',
|
||||
use_default_iou_values: true
|
||||
};
|
||||
|
||||
return of(template);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user