Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

Commit

Permalink
Add bandwidth endpoints to netquery service
Browse files Browse the repository at this point in the history
  • Loading branch information
ppacher committed Oct 10, 2023
1 parent d73af71 commit 8455403
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@ import { AppProfileService } from "./app-profile.service";
import { AppProfile } from "./app-profile.types";
import { DNSContext, IPScope, Reason, TLSContext, TunnelContext, Verdict } from "./network.types";
import { PORTMASTER_HTTP_API_ENDPOINT, PortapiService } from "./portapi.service";
import { Container } from "postcss";

export interface FieldSelect {
field: string;
}

export interface FieldAsSelect {
$field: {
field: string;
as: string;
}
}

export interface Count {
$count: {
field: string;
Expand Down Expand Up @@ -47,7 +55,7 @@ export interface Distinct {
$distinct: string;
}

export type Select = FieldSelect | Count | Distinct | Sum | Min;
export type Select = FieldSelect | FieldAsSelect | Count | Distinct | Sum | Min;

export interface Equal {
$eq: any;
Expand Down Expand Up @@ -96,17 +104,6 @@ export interface Condition {
[key: string]: string | Matcher | (string | Matcher)[];
}

export interface BatchQuery {
[key: string]: Query;
}

type BatchResult<T extends BatchQuery> = {
[key in keyof T]: {
results: { [field: string]: any }[];
error?: string;
}
}

export interface TextSearch {
fields: string[];
value: string;
Expand Down Expand Up @@ -212,6 +209,22 @@ interface BatchRequest {
[key: string]: Query
}

interface BandwidthBaseResult {
timestamp: number;
incoming: number;
outgoing: number;
}

export type ConnKeys = keyof NetqueryConnection

export type BandwidthChartResult<K extends ConnKeys> = {
[key in K]: NetqueryConnection[K];
} & BandwidthBaseResult

export type ProfileBandwidthChartResult = BandwidthChartResult<'profile'>;

export type ConnectionBandwidthChartResult = BandwidthChartResult<'id'>;

@Injectable({ providedIn: 'root' })
export class Netquery {
constructor(
Expand Down Expand Up @@ -245,6 +258,65 @@ export class Netquery {
)
}

profileBandwidthChart(profile?: string[], interval?: number): Observable<{ [profile: string]: ProfileBandwidthChartResult[] }> {
const cond: Condition = {}
if (!!profile) {
cond['profile'] = profile
}

return this.bandwidthChart(cond, ['profile'], interval)
.pipe(
map(results => {
const obj: {
[connId: string]: ProfileBandwidthChartResult[]
} = {};

results?.forEach(row => {
const arr = obj[row.profile] || []
arr.push(row)
obj[row.profile] = arr
})

return obj
})
)
}

bandwidthChart<K extends ConnKeys>(query: Condition, groupBy?: K[], interval?: number): Observable<BandwidthChartResult<K>[]> {
return this.http.post<{ results: BandwidthChartResult<K>[] }>(`${this.httpAPI}/v1/netquery/charts/bandwidth`, {
interval,
groupBy,
query,
})
.pipe(
map(response => response.results),
)
}

connectionBandwidthChart(connIds: string[], interval?: number): Observable<{ [connId: string]: ConnectionBandwidthChartResult[] }> {
const cond: Condition = {}
if (!!connIds) {
cond['id'] = connIds
}

return this.bandwidthChart(cond, ['id'], interval)
.pipe(
map(results => {
const obj: {
[connId: string]: ConnectionBandwidthChartResult[]
} = {};

results?.forEach(row => {
const arr = obj[row.id] || []
arr.push(row)
obj[row.id] = arr
})

return obj
})
)
}

activeConnectionChart(cond: Condition, textSearch?: TextSearch): Observable<ChartResult[]> {
return this.http.post<{ results: ChartResult[] }>(`${this.httpAPI}/v1/netquery/charts/connection-active`, {
query: cond,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<label class="relative" *ngIf="label">
{{ label }}
<div *ngIf="beta" class="absolute top-0 right-0 flex flex-col items-center justify-center gap-0 text-yellow-200">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
class="relative z-10 w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714c0 .597.237 1.17.659 1.591L19.8 15.3M14.25 3.104c.251.023.501.05.75.082M19.8 15.3l-1.57.393A9.065 9.065 0 0112 15a9.065 9.065 0 00-6.23-.693L5 14.5m14.8.8l1.402 1.402c1.232 1.232.65 3.318-1.067 3.611A48.309 48.309 0 0112 21c-2.773 0-5.491-.235-8.135-.687-1.718-.293-2.3-2.379-1.067-3.61L5 14.5" />
</svg>
<span class="-mt-1 uppercase" style="font-size: 0.6rem">BETA</span>
</div>

</label>

<ng-content></ng-content>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { coerceBooleanProperty } from "@angular/cdk/coercion";
import { ChangeDetectionStrategy, Component, Input } from "@angular/core";

@Component({
selector: 'app-dashboard-widget',
templateUrl: './dashboard-widget.component.html',
styles: [
`
:host {
@apply bg-gray-200 p-4 self-stretch rounded-md flex flex-col gap-2;
}
label {
@apply text-xs uppercase text-secondary font-light flex flex-row items-center gap-2 pb-2;
}
`
],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DashboardWidgetComponent {
@Input()
set beta(v: any) {
this._beta = coerceBooleanProperty(v)
}
get beta() { return this._beta }
private _beta = false;

@Input()
label: string = '';
}

0 comments on commit 8455403

Please sign in to comment.