initial opnsense connections page

This commit is contained in:
2024-11-02 01:26:41 -07:00
parent 3b2ed4ddea
commit 922e4c0580
12 changed files with 254 additions and 4 deletions

View File

@@ -5,16 +5,20 @@
const { data, children } = $props();
const { user } = data;
function getNavClass(path: string) {
return cn("hover:text-foreground/80 transition-colors",
$page.url.pathname === path ? "text-foreground" : "text-foreground/60");
}
</script>
<header class="p-4 sm:flex">
<span class=" mr-6 font-bold sm:inline-block">My App</span>
<nav class="flex items-center gap-6 text-sm">
<a href="/" class={cn("hover:text-foreground/80 transition-colors",
$page.url.pathname === "/" ? "text-foreground" : "text-foreground/60")}>Home</a>
<a href="/" class={getNavClass("/")}>Home</a>
{#if user}
<a href="/user" class={cn("hover:text-foreground/80 transition-colors",
$page.url.pathname === "/user" ? "text-foreground" : "text-foreground/60")}>Profile</a>
<a href="/user" class={getNavClass("/user")}>Profile</a>
<a href="/connections" class={getNavClass("/connections")}>Connections</a>
{/if}
</nav>
</header>

View File

@@ -0,0 +1,32 @@
import { error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { env } from '$env/dynamic/private';
import type { OpnsenseWgPeers } from '$lib/opnsense/wg';
export const GET: RequestHandler = async ({ url }) => {
const apiUrl = `${env.OPNSENSE_API_URL}/api/wireguard/service/show`;
const options: RequestInit = {
method: 'POST',
headers: {
Authorization: `Basic ${Buffer.from(`${env.OPNSENSE_API_KEY}:${env.OPNSENSE_API_SECRET}`).toString('base64')}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"current": 1,
// "rowCount": 7,
"sort": {},
"searchPhrase": "",
"type": ["peer"],
}),
};
console.log("Fetching peers from OPNsense WireGuard API: ", apiUrl, options)
const res = await fetch(apiUrl, options);
const peers = await res.json() as OpnsenseWgPeers;
if (!peers) {
error(500, "Error getting info from OPNsense API");
}
return new Response(JSON.stringify(peers));
};

View File

@@ -0,0 +1,66 @@
<script lang="ts">
import type { PageData } from './$types';
import { invalidate } from '$app/navigation';
import { onMount } from 'svelte';
const { data }: { data: PageData } = $props();
onMount(() => {
// refresh every 5 seconds
setInterval(() => {
console.log('Refreshing connections');
invalidate('/api/connections');
}, 5000);
});
function getSize(size: number) {
let sizes = ['Bytes', 'KiB', 'MiB', 'GiB',
'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
for (let i = 1; i < sizes.length; i++) {
if (size < Math.pow(1024, i))
return (Math.round((size / Math.pow(
1024, i - 1)) * 100) / 100) + ' ' + sizes[i - 1];
}
return size;
}
</script>
<svelte:head>
<title>Connections</title>
</svelte:head>
<table>
<thead>
<tr>
<th>Public Key</th>
<th>Endpoint</th>
<th>Allowed IPs</th>
<th>Latest Handshake</th>
<th>RX</th>
<th>TX</th>
<th>Persistent Keepalive</th>
<th>Name</th>
<th>Interface Name</th>
</tr>
</thead>
<tbody>
{#each data.peers.rows as peer}
<tr>
<td>{peer['public-key'].substring(0, 10)}</td>
<td>{peer.endpoint}</td>
<td>{peer['allowed-ips']}</td>
{#if peer['latest-handshake']}
<td>{new Date(peer['latest-handshake'] * 1000)}</td>
{:else}
<td>Never</td>
{/if}
<td>{getSize(peer['transfer-rx'])}</td>
<td>{getSize(peer['transfer-tx'])}</td>
<td>{peer['persistent-keepalive']}</td>
<td>{peer.name}</td>
<td>{peer.ifname}</td>
</tr>
{/each}
</tbody>
</table>

View File

@@ -0,0 +1,9 @@
import type { PageLoad } from './$types';
import type { OpnsenseWgPeers } from '$lib/opnsense/wg';
export const load: PageLoad = async ({ fetch, params }) => {
const res = await fetch('/api/connections');
const peers = await res.json() as OpnsenseWgPeers;
return { peers };
};