Merge pull request #524 from GNS3/node_configs

Support for editing config files - IOU & routers
This commit is contained in:
piotrpekala7 2019-10-08 09:23:44 +02:00 committed by GitHub
commit 3afcac3963
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 87 additions and 15 deletions

View File

@ -1,4 +1,6 @@
<button mat-menu-item (click)="editConfig()">
<button mat-menu-item
*ngIf="node.node_type==='vpcs' || node.node_type==='iou' || node.node_type==='dynamips'"
(click)="editConfig()">
<mat-icon>settings</mat-icon>
<span>Edit config</span>
</button>

View File

@ -1,4 +1,6 @@
<button mat-menu-item (click)="exportConfig()">
<button mat-menu-item
*ngIf="node.node_type==='vpcs' || node.node_type==='dynamips' || node.node_type==='iou'"
(click)="exportConfig()">
<mat-icon>call_made</mat-icon>
<span>Export config</span>
</button>

View File

@ -16,7 +16,7 @@ export class ExportConfigActionComponent {
) {}
exportConfig() {
this.nodeService.getConfiguration(this.server, this.node).subscribe((config: any) => {
this.nodeService.getStartupConfiguration(this.server, this.node).subscribe((config: any) => {
this.downloadByHtmlTag(config);
});
}
@ -25,7 +25,11 @@ export class ExportConfigActionComponent {
const element = document.createElement('a');
const fileType = 'text/plain';
element.setAttribute('href', `data:${fileType};charset=utf-8,${encodeURIComponent(config)}`);
element.setAttribute('download', `${this.node.name}_startup.vpc`);
if (this.node.node_type === 'vpcs') {
element.setAttribute('download', `${this.node.name}_startup.vpc`);
} else if (this.node.node_type === 'iou' || this.node.node_type === 'dynamips') {
element.setAttribute('download', `${this.node.name}_startup.cfg`);
}
var event = new MouseEvent("click");
element.dispatchEvent(event);

View File

@ -1,9 +1,18 @@
<h1 mat-dialog-title>Configuration for node {{node.name}}</h1>
<div class="modal-form-container">
<div *ngIf="node.node_type==='vpcs'" class="modal-form-container">
<textarea #textArea id="textArea" class="textArea" [(ngModel)]="config"></textarea>
</div>
<mat-tab-group *ngIf="node.node_type==='iou' || node.node_type==='dynamips'">
<mat-tab label="Startup config">
<textarea #textArea id="textArea" class="textAreaTab" [(ngModel)]="config"></textarea>
</mat-tab>
<mat-tab label="Private config">
<textarea #textArea id="textArea" class="textAreaTab" [(ngModel)]="privateConfig"></textarea>
</mat-tab>
</mat-tab-group>
<div mat-dialog-actions>
<button mat-button (click)="onCancelClick()" color="accent">Cancel</button>
<button mat-button (click)="onSaveClick()" tabindex="2" mat-raised-button color="primary">Apply</button>

View File

@ -2,3 +2,8 @@
width: 100%;
height: 350px;
}
.textAreaTab {
width: 100%;
height: 300px;
}

View File

@ -5,7 +5,8 @@ import {
MatFormFieldModule,
MatDialogRef,
MAT_DIALOG_DATA,
MatSnackBarModule
MatSnackBarModule,
MatTabsModule
} from '@angular/material';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ToasterService } from '../../../../services/toaster.service';
@ -36,7 +37,8 @@ describe('ConfigEditorDialogComponent', () => {
MatFormFieldModule,
NoopAnimationsModule,
MatSnackBarModule,
FormsModule
FormsModule,
MatTabsModule
],
providers: [
{ provide: MatDialogRef, useValue: dialogRef },

View File

@ -17,6 +17,7 @@ export class ConfigEditorDialogComponent implements OnInit {
node: Node;
config: any;
privateConfig: any;
constructor(
public dialogRef: MatDialogRef<ConfigEditorDialogComponent>,
@ -25,15 +26,28 @@ export class ConfigEditorDialogComponent implements OnInit {
) {}
ngOnInit() {
this.nodeService.getConfiguration(this.server, this.node).subscribe((config: any) => {
this.nodeService.getStartupConfiguration(this.server, this.node).subscribe((config: any) => {
this.config = config;
});
if (this.node.node_type === 'iou' || this.node.node_type === 'dynamips') {
this.nodeService.getPrivateConfiguration(this.server, this.node).subscribe((privateConfig: any) => {
this.privateConfig = privateConfig;
});
}
}
onSaveClick() {
this.nodeService.saveConfiguration(this.server, this.node, this.config).subscribe((response) => {
this.dialogRef.close();
this.toasterService.success(`Configuration for node ${this.node.name} saved.`);
if (this.node.node_type === 'iou' || this.node.node_type === 'dynamips') {
this.nodeService.savePrivateConfiguration(this.server, this.node, this.privateConfig).subscribe((resp) => {
this.dialogRef.close();
this.toasterService.success(`Configuration for node ${this.node.name} saved.`);
});
} else {
this.dialogRef.close();
this.toasterService.success(`Configuration for node ${this.node.name} saved.`);
}
});
}

View File

@ -119,7 +119,7 @@ export class MockedNodeService {
return of(node);
}
getConfiguration(server: Server, node: Node) {
getStartupConfiguration(server: Server, node: Node) {
return of('sample config');
}

View File

@ -127,13 +127,30 @@ export class NodeService {
return `putty.exe -telnet \%h \%p -wt \"\%d\" -gns3 5 -skin 4`;
}
getConfiguration(server: Server, node: Node) {
let urlPath: string = `/projects/${node.project_id}/nodes/${node.node_id}`
getStartupConfiguration(server: Server, node: Node) {
let urlPath: string = `/projects/${node.project_id}/nodes/${node.node_id}`;
if (node.node_type === 'vpcs') {
urlPath += '/files/startup.vpc';
return this.httpServer.get(server, urlPath, { responseType: 'text' as 'json'});
} else if (node.node_type === 'iou') {
urlPath += '/files/startup-config.cfg';
} else if (node.node_type === 'dynamips') {
urlPath += `/files/configs/i${node.node_id}_startup-config.cfg`;
}
return this.httpServer.get(server, urlPath, { responseType: 'text' as 'json'});
}
getPrivateConfiguration(server: Server, node: Node) {
let urlPath: string = `/projects/${node.project_id}/nodes/${node.node_id}`;
if (node.node_type === 'iou') {
urlPath += '/files/private-config.cfg';
} else if (node.node_type === 'dynamips') {
urlPath += `/files/configs/i${node.node_id}_private-config.cfg`;
}
return this.httpServer.get(server, urlPath, { responseType: 'text' as 'json'});
}
saveConfiguration(server: Server, node: Node, configuration: string) {
@ -141,7 +158,24 @@ export class NodeService {
if (node.node_type === 'vpcs') {
urlPath += '/files/startup.vpc';
return this.httpServer.post(server, urlPath, configuration);
} else if (node.node_type === 'iou') {
urlPath += '/files/startup-config.cfg';
} else if (node.node_type === 'dynamips') {
urlPath += `/files/configs/i${node.node_id}_startup-config.cfg`;
}
return this.httpServer.post(server, urlPath, configuration);
}
savePrivateConfiguration(server: Server, node: Node, configuration: string) {
let urlPath: string = `/projects/${node.project_id}/nodes/${node.node_id}`
if (node.node_type === 'iou') {
urlPath += '/files/private-config.cfg';
} else if (node.node_type === 'dynamips') {
urlPath += `/files/configs/i${node.node_id}_private-config.cfg`;
}
return this.httpServer.post(server, urlPath, configuration);
}
}