mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-04-20 08:10:49 +00:00
Initial implementation
This commit is contained in:
parent
ca42465ebc
commit
e507e26cda
@ -169,6 +169,10 @@ import { DateFilter } from './filters/dateFilter.pipe';
|
||||
import { NameFilter } from './filters/nameFilter.pipe';
|
||||
import { CustomAdaptersComponent } from './components/preferences/common/custom-adapters/custom-adapters.component';
|
||||
import { NodesMenuComponent } from './components/project-map/nodes-menu/nodes-menu.component';
|
||||
import { PacketFiltersDialogComponent } from './components/project-map/packet-capturing/packet-filters/packet-filters.component';
|
||||
import { HelpDialogComponent } from './components/project-map/help-dialog/help-dialog.component';
|
||||
import { StartCaptureActionComponent } from './components/project-map/context-menu/actions/start-capture/start-capture-action.component';
|
||||
import { StartCaptureDialogComponent } from './components/project-map/packet-capturing/start-capture/start-capture.component';
|
||||
|
||||
if (environment.production) {
|
||||
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
|
||||
@ -203,6 +207,8 @@ if (environment.production) {
|
||||
EditStyleActionComponent,
|
||||
EditTextActionComponent,
|
||||
DeleteActionComponent,
|
||||
PacketFiltersActionComponent,
|
||||
StartCaptureActionComponent,
|
||||
ProjectMapShortcutsComponent,
|
||||
SettingsComponent,
|
||||
PreferencesComponent,
|
||||
@ -224,6 +230,7 @@ if (environment.production) {
|
||||
InstallSoftwareComponent,
|
||||
StyleEditorDialogComponent,
|
||||
TextEditorDialogComponent,
|
||||
PacketFiltersDialogComponent,
|
||||
QemuPreferencesComponent,
|
||||
QemuVmTemplatesComponent,
|
||||
AddQemuVmTemplateComponent,
|
||||
@ -257,6 +264,8 @@ if (environment.production) {
|
||||
VmwareTemplateDetailsComponent,
|
||||
AddVmwareTemplateComponent,
|
||||
DeleteConfirmationDialogComponent,
|
||||
HelpDialogComponent,
|
||||
StartCaptureDialogComponent,
|
||||
DeleteTemplateComponent,
|
||||
DockerTemplatesComponent,
|
||||
AddDockerTemplateComponent,
|
||||
@ -355,9 +364,12 @@ if (environment.production) {
|
||||
ImportProjectDialogComponent,
|
||||
ConfirmationDialogComponent,
|
||||
StyleEditorDialogComponent,
|
||||
PacketFiltersDialogComponent,
|
||||
TextEditorDialogComponent,
|
||||
SymbolsComponent,
|
||||
DeleteConfirmationDialogComponent
|
||||
DeleteConfirmationDialogComponent,
|
||||
HelpDialogComponent,
|
||||
StartCaptureDialogComponent
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
|
@ -15,6 +15,7 @@ export class LinkToMapLinkConverter implements Converter<Link, MapLink> {
|
||||
mapLink.captureFileName = link.capture_file_name;
|
||||
mapLink.captureFilePath = link.capture_file_path;
|
||||
mapLink.capturing = link.capturing;
|
||||
mapLink.filters = link.filters;
|
||||
mapLink.linkType = link.link_type;
|
||||
mapLink.nodes = link.nodes.map(linkNode => this.linkNodeToMapLinkNode.convert(linkNode, { link_id: link.link_id }));
|
||||
mapLink.projectId = link.project_id;
|
||||
|
@ -15,6 +15,7 @@ export class MapLinkToLinkConverter implements Converter<MapLink, Link> {
|
||||
link.capture_file_name = mapLink.captureFileName;
|
||||
link.capture_file_path = mapLink.captureFilePath;
|
||||
link.capturing = mapLink.capturing;
|
||||
link.filters = mapLink.filters;
|
||||
link.link_type = mapLink.linkType;
|
||||
link.nodes = mapLink.nodes.map(mapLinkNode => this.mapLinkNodeToMapLinkNode.convert(mapLinkNode));
|
||||
link.project_id = mapLink.projectId;
|
||||
|
@ -1,12 +1,14 @@
|
||||
import { MapLinkNode } from './map-link-node';
|
||||
import { MapNode } from './map-node';
|
||||
import { Indexed } from '../../datasources/map-datasource';
|
||||
import { Filter } from '../../../models/filter';
|
||||
|
||||
export class MapLink implements Indexed {
|
||||
id: string;
|
||||
captureFileName: string;
|
||||
captureFilePath: string;
|
||||
capturing: boolean;
|
||||
filters?: Filter;
|
||||
linkType: string;
|
||||
nodes: MapLinkNode[];
|
||||
projectId: string;
|
||||
|
@ -32,6 +32,19 @@ export class LinkWidget implements Widget {
|
||||
return `translate (${translation.dx}, ${translation.dy})`;
|
||||
});
|
||||
|
||||
link_body.select('.svg-icon').remove();
|
||||
|
||||
link_body
|
||||
.filter(l => { return l.filters.frequency_drop })
|
||||
.append<SVGGElement>('g')
|
||||
.attr('class', 'svg-icon')
|
||||
.attr('transform', link => {
|
||||
return `translate (${(link.source.x + link.target.x)/2}, ${(link.source.y + link.target.y)/2})`
|
||||
})
|
||||
.attr('viewBox', '0 0 20 20')
|
||||
.append<SVGPathElement>('path')
|
||||
.attr('d', "M18.125,15.804l-4.038-4.037c0.675-1.079,1.012-2.308,1.01-3.534C15.089,4.62,12.199,1.75,8.584,1.75C4.815,1.75,1.982,4.726,2,8.286c0.021,3.577,2.908,6.549,6.578,6.549c1.241,0,2.417-0.347,3.44-0.985l4.032,4.026c0.167,0.166,0.43,0.166,0.596,0l1.479-1.478C18.292,16.234,18.292,15.968,18.125,15.804 M8.578,13.99c-3.198,0-5.716-2.593-5.733-5.71c-0.017-3.084,2.438-5.686,5.74-5.686c3.197,0,5.625,2.493,5.64,5.624C14.242,11.548,11.621,13.99,8.578,13.99 M16.349,16.981l-3.637-3.635c0.131-0.11,0.721-0.695,0.876-0.884l3.642,3.639L16.349,16.981z");
|
||||
|
||||
const serial_link_widget = new SerialLinkWidget();
|
||||
serial_link_widget.draw(link_body_merge);
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
<button mat-menu-item (click)="openPacketFilters()">
|
||||
<mat-icon>filter_list</mat-icon>
|
||||
<span>Packet filters</span>
|
||||
</button>
|
@ -0,0 +1,30 @@
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { Link } from '../../../../../models/link';
|
||||
import { Server } from '../../../../../models/server';
|
||||
import { Project } from '../../../../../models/project';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { PacketFiltersDialogComponent } from '../../../packet-capturing/packet-filters/packet-filters.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-packet-filters-action',
|
||||
templateUrl: './packet-filters-action.component.html'
|
||||
})
|
||||
export class PacketFiltersActionComponent {
|
||||
@Input() server: Server;
|
||||
@Input() project: Project;
|
||||
@Input() link: Link;
|
||||
|
||||
constructor(private dialog: MatDialog) {}
|
||||
|
||||
openPacketFilters() {
|
||||
const dialogRef = this.dialog.open(PacketFiltersDialogComponent, {
|
||||
width: '900px',
|
||||
height: '400px',
|
||||
autoFocus: false
|
||||
});
|
||||
let instance = dialogRef.componentInstance;
|
||||
instance.server = this.server;
|
||||
instance.project = this.project;
|
||||
instance.link = this.link;
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<button mat-menu-item *ngIf="!link.capturing" (click)="startCapture()">
|
||||
<mat-icon>loupe</mat-icon>
|
||||
<span>Start capture</span>
|
||||
</button>
|
@ -0,0 +1,26 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Server } from '../../../../../models/server';
|
||||
import { Link } from '../../../../../models/link';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { StartCaptureDialogComponent } from '../../../packet-capturing/start-capture/start-capture.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-start-capture-action',
|
||||
templateUrl: './start-capture-action.component.html'
|
||||
})
|
||||
export class StartCaptureActionComponent {
|
||||
@Input() server: Server;
|
||||
@Input() link: Link;
|
||||
|
||||
constructor(private dialog: MatDialog) {}
|
||||
|
||||
startCapture() {
|
||||
const dialogRef = this.dialog.open(StartCaptureDialogComponent, {
|
||||
width: '400px',
|
||||
autoFocus: false
|
||||
});
|
||||
let instance = dialogRef.componentInstance;
|
||||
instance.server = this.server;
|
||||
instance.link = this.link;
|
||||
}
|
||||
}
|
@ -26,6 +26,17 @@
|
||||
[nodes]="nodes"
|
||||
[drawings]="drawings"
|
||||
></app-move-layer-down-action>
|
||||
<app-start-capture-action
|
||||
*ngIf="!projectService.isReadOnly(project) && drawings.length===0 && nodes.length===0 && links.length===1"
|
||||
[server]="server"
|
||||
[link]="links[0]"
|
||||
></app-start-capture-action>
|
||||
<app-packet-filters-action
|
||||
*ngIf="!projectService.isReadOnly(project) && drawings.length===0 && nodes.length===0 && links.length===1"
|
||||
[server]="server"
|
||||
[project]="project"
|
||||
[link]="links[0]"
|
||||
></app-packet-filters-action>
|
||||
<app-delete-action
|
||||
*ngIf="!projectService.isReadOnly(project)"
|
||||
[server]="server"
|
||||
|
@ -0,0 +1,16 @@
|
||||
<h1 mat-dialog-title>{{title}}</h1>
|
||||
|
||||
<div class="modal-form-container">
|
||||
<div class="message" *ngFor="let message of messages; let i = index">
|
||||
<h6>
|
||||
{{message.name}}
|
||||
</h6>
|
||||
<span class="description">
|
||||
{{message.description}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button (click)="onCloseClick()" color="accent">Close</button>
|
||||
</div>
|
@ -0,0 +1,7 @@
|
||||
.message {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: #b0bec5;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { MatDialogRef } from '@angular/material';
|
||||
import { Message } from '../../../models/message';
|
||||
|
||||
@Component({
|
||||
selector: 'app-help-dialog',
|
||||
templateUrl: './help-dialog.component.html',
|
||||
styleUrls: ['./help-dialog.component.scss']
|
||||
})
|
||||
export class HelpDialogComponent {
|
||||
@Input() title: string;
|
||||
@Input() messages: Message[];
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<HelpDialogComponent>,
|
||||
) {}
|
||||
|
||||
onCloseClick() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
<h1 mat-dialog-title>Packet filters</h1>
|
||||
|
||||
<div class="modal-form-container">
|
||||
<mat-tab-group *ngIf="this.filters">
|
||||
<mat-tab label="Frequency drop">
|
||||
<mat-form-field class="input-field">
|
||||
<input matInput placeholder="Frequency" type="number" [(ngModel)]="filters.frequency_drop[0]">
|
||||
</mat-form-field>
|
||||
</mat-tab>
|
||||
<mat-tab label="Packet loss">
|
||||
<mat-form-field class="input-field">
|
||||
<input matInput placeholder="Chance" type="number" [(ngModel)]="filters.packet_loss[0]">
|
||||
</mat-form-field>
|
||||
</mat-tab>
|
||||
<mat-tab label="Delay">
|
||||
<mat-form-field class="input-field">
|
||||
<input matInput placeholder="Latency" type="number" [(ngModel)]="filters.delay[0]">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="input-field">
|
||||
<input matInput placeholder="Jitter" type="number" [(ngModel)]="filters.delay[1]">
|
||||
</mat-form-field>
|
||||
</mat-tab>
|
||||
<mat-tab label="Corrupt">
|
||||
<mat-form-field class="input-field">
|
||||
<input matInput placeholder="Latency" type="number" [(ngModel)]="filters.corrupt[0]">
|
||||
</mat-form-field>
|
||||
</mat-tab>
|
||||
<mat-tab label="Berkeley Packet Filter (BPF)">
|
||||
<mat-form-field class="input-field">
|
||||
<textarea matInput type="text" [(ngModel)]="filters.bpf[0]"></textarea>
|
||||
</mat-form-field>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button (click)="onNoClick()" color="accent">Cancel</button>
|
||||
<button mat-button (click)="onResetClick()" color="accent">Reset</button>
|
||||
<button mat-button (click)="onYesClick()" tabindex="2" mat-raised-button color="primary">Apply</button>
|
||||
<div class="divider"></div>
|
||||
<button mat-button (click)="onHelpClick()" color="accent">Help</button>
|
||||
</div>
|
@ -0,0 +1,59 @@
|
||||
.item {
|
||||
height: 25px;
|
||||
font-size: 10pt;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item-value {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.input-field {
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: fit-content;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.input-color {
|
||||
padding: 0px;
|
||||
border-width: 0px;
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input[type="color"] {
|
||||
-webkit-appearance: none;
|
||||
border: none;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
input[type="color"]::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input[type="color"]::-webkit-color-swatch {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.modal-form-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.modal-form-container > * {
|
||||
width: 100%;
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Link } from '../../../../models/link';
|
||||
import { Server } from '../../../../models/server';
|
||||
import { Project } from '../../../../models/project';
|
||||
import { MatDialogRef, MatDialog } from '@angular/material';
|
||||
import { LinkService } from '../../../../services/link.service';
|
||||
import { FilterDescription } from '../../../../models/filter-description';
|
||||
import { HelpDialogComponent } from '../../help-dialog/help-dialog.component';
|
||||
import { Message } from '../../../../models/message';
|
||||
import { Filter } from '../../../../models/filter';
|
||||
|
||||
@Component({
|
||||
selector: 'app-packet-filters',
|
||||
templateUrl: './packet-filters.component.html',
|
||||
styleUrls: ['./packet-filters.component.scss']
|
||||
})
|
||||
export class PacketFiltersDialogComponent implements OnInit{
|
||||
server: Server;
|
||||
project: Project;
|
||||
link: Link;
|
||||
filters: Filter;
|
||||
availableFilters: FilterDescription[];
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<PacketFiltersDialogComponent>,
|
||||
private linkService: LinkService,
|
||||
private dialog: MatDialog
|
||||
) {}
|
||||
|
||||
ngOnInit(){
|
||||
this.linkService.getLink(this.server, this.link.project_id, this.link.link_id).subscribe((link: Link) => {
|
||||
this.link = link;
|
||||
this.filters = {
|
||||
bpf: [],
|
||||
corrupt: [0],
|
||||
delay: [0, 0],
|
||||
frequency_drop: [0],
|
||||
packet_loss: [0]
|
||||
};
|
||||
|
||||
if (this.link.filters) {
|
||||
this.filters.bpf = this.link.filters.bpf ? this.link.filters.bpf : [];
|
||||
this.filters.corrupt = this.link.filters.corrupt ? this.link.filters.corrupt : [0];
|
||||
this.filters.delay = this.link.filters.delay ? this.link.filters.delay : [0, 0];
|
||||
this.filters.frequency_drop = this.link.filters.frequency_drop ? this.link.filters.frequency_drop : [0];
|
||||
this.filters.packet_loss = this.link.filters.packet_loss ? this.link.filters.packet_loss : [0];
|
||||
}
|
||||
});
|
||||
|
||||
this.linkService.getAvailableFilters(this.server, this.link).subscribe((availableFilters: FilterDescription[]) => {
|
||||
this.availableFilters = availableFilters;
|
||||
});
|
||||
}
|
||||
|
||||
onNoClick() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
onResetClick() {
|
||||
this.link.filters = {
|
||||
bpf: [],
|
||||
corrupt: [0],
|
||||
delay: [0, 0],
|
||||
frequency_drop: [0],
|
||||
packet_loss: [0]
|
||||
};
|
||||
|
||||
this.linkService.updateLink(this.server, this.link).subscribe((link: Link) => {
|
||||
this.dialogRef.close();
|
||||
});
|
||||
}
|
||||
|
||||
onYesClick() {
|
||||
this.link.filters = this.filters;
|
||||
this.linkService.updateLink(this.server, this.link).subscribe((link: Link) => {
|
||||
this.dialogRef.close();
|
||||
});
|
||||
}
|
||||
|
||||
onHelpClick() {
|
||||
const dialogRef = this.dialog.open(HelpDialogComponent, {
|
||||
width: '500px',
|
||||
autoFocus: false
|
||||
});
|
||||
let instance = dialogRef.componentInstance;
|
||||
instance.title = 'Help for filters';
|
||||
let messages: Message[] = [];
|
||||
this.availableFilters.forEach((filter: FilterDescription) => {
|
||||
messages.push({
|
||||
name: filter.name,
|
||||
description: filter.description
|
||||
});
|
||||
});
|
||||
instance.messages = messages;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<h1 mat-dialog-title>Packet capture</h1>
|
||||
|
||||
<div class="modal-form-container">
|
||||
<mat-form-field class="input-field">
|
||||
<mat-select
|
||||
placeholder="Link type"
|
||||
[(ngModel)]="linkType">
|
||||
<mat-option *ngFor="let type of linkTypes" [value]="type[1]">
|
||||
{{type[0]}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="input-field">
|
||||
<input
|
||||
placeholder="File name"
|
||||
matInput type="text"
|
||||
[(ngModel)]="filename" >
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button (click)="onNoClick()" color="accent">Cancel</button>
|
||||
<button mat-button (click)="onYesClick()" tabindex="2" mat-raised-button color="primary">Ok</button>
|
||||
</div>
|
@ -0,0 +1,56 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Server } from '../../../../models/server';
|
||||
import { Link } from '../../../../models/link';
|
||||
import { MatDialogRef } from '@angular/material';
|
||||
import { PacketFiltersDialogComponent } from '../packet-filters/packet-filters.component';
|
||||
import { LinkService } from '../../../../services/link.service';
|
||||
import { CapturingSettings } from '../../../../models/capturingSettings';
|
||||
|
||||
@Component({
|
||||
selector: 'app-start-capture',
|
||||
templateUrl: './start-capture.component.html',
|
||||
styleUrls: ['./start-capture.component.scss']
|
||||
})
|
||||
export class StartCaptureDialogComponent implements OnInit {
|
||||
server: Server;
|
||||
link: Link;
|
||||
linkTypes = [];
|
||||
|
||||
linkType: string;
|
||||
fileName: string;
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<PacketFiltersDialogComponent>,
|
||||
private linkService: LinkService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.link.link_type === 'ethernet') {
|
||||
this.linkTypes = [
|
||||
["Ethernet", "DLT_EN10MB"]
|
||||
];
|
||||
} else {
|
||||
this.linkTypes = [
|
||||
["Cisco HDLC", "DLT_C_HDLC"],
|
||||
["Cisco PPP", "DLT_PPP_SERIAL"],
|
||||
["Frame Relay", "DLT_FRELAY"],
|
||||
["ATM", "DLT_ATM_RFC1483"]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
onYesClick() {
|
||||
let captureSettings: CapturingSettings = {
|
||||
capture_file_name: this.fileName,
|
||||
data_link_type: this.linkType
|
||||
};
|
||||
|
||||
this.linkService.startCaptureOnLink(this.server, this.link, captureSettings).subscribe(() => {
|
||||
this.dialogRef.close();
|
||||
});
|
||||
}
|
||||
|
||||
onNoClick() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
@ -48,11 +48,6 @@ export class SnapshotMenuItemComponent implements OnInit {
|
||||
(created_snapshot: Snapshot) => {
|
||||
this.toaster.success(`Snapshot '${snapshot.name}' has been created.`);
|
||||
progress.close();
|
||||
},
|
||||
response => {
|
||||
const error = response.json();
|
||||
this.toaster.error(`Cannot create snapshot: ${error.message}`);
|
||||
progress.close();
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -19,7 +19,8 @@ import {
|
||||
MatTooltipModule,
|
||||
MatStepperModule,
|
||||
MatRadioModule,
|
||||
MatGridListModule
|
||||
MatGridListModule,
|
||||
MatTabsModule
|
||||
} from '@angular/material';
|
||||
|
||||
export const MATERIAL_IMPORTS = [
|
||||
@ -43,5 +44,6 @@ export const MATERIAL_IMPORTS = [
|
||||
MatTooltipModule,
|
||||
MatStepperModule,
|
||||
MatRadioModule,
|
||||
MatGridListModule
|
||||
MatGridListModule,
|
||||
MatTabsModule
|
||||
];
|
||||
|
4
src/app/models/capturingSettings.ts
Normal file
4
src/app/models/capturingSettings.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export class CapturingSettings {
|
||||
capture_file_name: string;
|
||||
data_link_type: string;
|
||||
}
|
14
src/app/models/filter-description.ts
Normal file
14
src/app/models/filter-description.ts
Normal file
@ -0,0 +1,14 @@
|
||||
export class FilterDescription {
|
||||
description: string;
|
||||
name: string;
|
||||
parameters: Parameter[];
|
||||
type: string;
|
||||
}
|
||||
|
||||
interface Parameter {
|
||||
maximum?: number;
|
||||
minimum?: number;
|
||||
name: string;
|
||||
type: string;
|
||||
unit?: string;
|
||||
}
|
7
src/app/models/filter.ts
Normal file
7
src/app/models/filter.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export class Filter {
|
||||
bpf?: string[];
|
||||
corrupt?: number[];
|
||||
delay?: number[];
|
||||
frequency_drop?: number[];
|
||||
packet_loss?: number[];
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
import { Node } from '../cartography/models/node';
|
||||
import { LinkNode } from './link-node';
|
||||
import { Filter } from './filter';
|
||||
|
||||
export class Link {
|
||||
capture_file_name: string;
|
||||
capture_file_path: string;
|
||||
capturing: boolean;
|
||||
filters?: Filter;
|
||||
link_id: string;
|
||||
link_type: string;
|
||||
nodes: LinkNode[];
|
||||
|
4
src/app/models/message.ts
Normal file
4
src/app/models/message.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export class Message {
|
||||
name?: string;
|
||||
description: string;
|
||||
}
|
@ -7,16 +7,13 @@ import { HttpServer } from './http-server.service';
|
||||
import { Port } from '../models/port';
|
||||
import { Link } from '../models/link';
|
||||
import { LinkNode } from '../models/link-node';
|
||||
import { FilterDescription } from '../models/filter-description';
|
||||
import { CapturingSettings } from '../models/capturingSettings';
|
||||
|
||||
@Injectable()
|
||||
export class LinkService {
|
||||
constructor(private httpServer: HttpServer) {}
|
||||
|
||||
deleteLink(server: Server, link: Link) {
|
||||
//return this.httpServer.delete(server, `/compute/projects/${link.project_id}/vpcs/nodes/${link.nodes[0].node_id}/adapters/0/ports/0/nio`)
|
||||
return this.httpServer.delete(server, `/projects/${link.project_id}/links/${link.link_id}`)
|
||||
}
|
||||
|
||||
createLink(server: Server, source_node: Node, source_port: Port, target_node: Node, target_port: Port) {
|
||||
return this.httpServer.post(server, `/projects/${source_node.project_id}/links`, {
|
||||
nodes: [
|
||||
@ -34,6 +31,22 @@ export class LinkService {
|
||||
});
|
||||
}
|
||||
|
||||
getLink(server: Server, projectId: string, linkId: string) {
|
||||
return this.httpServer.get<Link>(server, `/projects/${projectId}/links/${linkId}`);
|
||||
}
|
||||
|
||||
deleteLink(server: Server, link: Link) {
|
||||
return this.httpServer.delete(server, `/projects/${link.project_id}/links/${link.link_id}`)
|
||||
}
|
||||
|
||||
updateLink(server: Server, link: Link) {
|
||||
return this.httpServer.put<Link>(server, `/projects/${link.project_id}/links/${link.link_id}`, link);
|
||||
}
|
||||
|
||||
getAvailableFilters(server: Server, link: Link) {
|
||||
return this.httpServer.get<FilterDescription[]>(server, `/projects/${link.project_id}/links/${link.link_id}/available_filters`);
|
||||
}
|
||||
|
||||
updateNodes(server: Server, link: Link, nodes: LinkNode[]) {
|
||||
const requestNodes = nodes.map(linkNode => {
|
||||
return {
|
||||
@ -52,4 +65,16 @@ export class LinkService {
|
||||
|
||||
return this.httpServer.put(server, `/projects/${link.project_id}/links/${link.link_id}`, { nodes: requestNodes });
|
||||
}
|
||||
|
||||
startCaptureOnLink(server: Server, link: Link, settings: CapturingSettings) {
|
||||
return this.httpServer.post(server, `/projects/${link.project_id}/links/${link.link_id}/start_capture`, settings);
|
||||
}
|
||||
|
||||
stopCaptureOnLink(server: Server, link: Link) {
|
||||
return this.httpServer.post(server, `/projects/${link.project_id}/links/${link.link_id}/stop_capture`, {});
|
||||
}
|
||||
|
||||
streamPcap(server: Server, link: Link) {
|
||||
return this.httpServer.get(server, `/projects/${link.project_id}/links/${link.link_id}/pcap`)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user