From e2aad5ec970b39905c6b15c54d720622036a2c58 Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Sat, 6 May 2023 21:15:03 +0200 Subject: [PATCH] Add Wireguard UI --- client/src/App.vue | 4 ++ client/src/definitions.ts | 69 +++++++++++++++++-- client/src/pages/vpn/WireguardInterfaces.vue | 71 +++++++++++++++++++ client/src/pages/vpn/WireguardPeers.vue | 72 ++++++++++++++++++++ client/src/pages/vpn/WireguardStatus.vue | 38 +++++++++++ 5 files changed, 249 insertions(+), 5 deletions(-) create mode 100644 client/src/pages/vpn/WireguardInterfaces.vue create mode 100644 client/src/pages/vpn/WireguardPeers.vue create mode 100644 client/src/pages/vpn/WireguardStatus.vue diff --git a/client/src/App.vue b/client/src/App.vue index 47209f7..fabb049 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -13,6 +13,7 @@ import IConfig from '~icons/grommet-icons/document-config'; import IStaticRoutes from '~icons/material-symbols/drive-folder-upload-outline-sharp'; import IDNSServer from '~icons/carbon/server-dns'; import ITimeServer from '~icons/carbon/server-time'; +import IWireguard from '~icons/simple-icons/wireguard'; import IDHCPServer from '~icons/material-symbols/book-rounded'; enum NavState { Open, Reduced, Collapsed }; @@ -30,6 +31,9 @@ const navRoutes = { "/service/dhcpv4servers": { icon: IDHCPServer, caption: "DHCP v4" }, "/service/dnsservers": { icon: IDNSServer, caption: "DNS Server" }, "/service/ntpservers": { icon: ITimeServer, caption: "NTP Server" }, + "/vpn/wireguardstatus": { icon: IWireguard, caption: "Wireguard Status" }, + "/vpn/wireguardinterfaces": { icon: IWireguard, caption: "Wireguard Interfaces" }, + "/vpn/wireguardpeers": { icon: IWireguard, caption: "Wireguard Peers" }, "/config/config": { icon: IConfig, caption: "Config" }, }; diff --git a/client/src/definitions.ts b/client/src/definitions.ts index 8c532ea..5bfb91c 100644 --- a/client/src/definitions.ts +++ b/client/src/definitions.ts @@ -19,7 +19,7 @@ const GetInterfaces: SearchProvider = async (o) => { if (res.Error === null) { console.debug("interfaces", res.Data.Interfaces); let obj = {} as Options; - Object.keys(res.Data.Interfaces).forEach(function(key, index){ + Object.keys(res.Data.Interfaces).forEach(function (key, index) { obj[key] = { display: key, }; @@ -36,7 +36,24 @@ const GetAddresses: SearchProvider = async (o) => { if (res.Error === null) { console.debug("addresses", res.Data.Addresses); let obj = {} as Options; - Object.keys(res.Data.Addresses).forEach(function(key, index){ + Object.keys(res.Data.Addresses).forEach(function (key, index) { + obj[key] = { + display: key, + }; + }); + return obj; + } else { + console.debug("error", res); + return {} as Options; + } +}; + +const GetPeers: SearchProvider = async (o) => { + let res = await apiCall("VPN.GetWireguardPeers", {}); + if (res.Error === null) { + console.debug("peers", res.Data.WireguardPeers); + let obj = {} as Options; + Object.keys(res.Data.WireguardPeers).forEach(function (key, index) { obj[key] = { display: key, }; @@ -164,11 +181,11 @@ export const editTypes: { [key: string]: { [key: string]: any } } = { fields: [ { key: "interface", label: "Interface", as: "SingleSelect", props: { searchProvider: GetInterfaces } }, { key: "pool", label: "Pool", as: "MultiSelect", props: { searchProvider: GetAddresses } }, - { key: "gateway_mode", label: "Gateway Mode", as: "PillBar", props: { options: { none: { display: 'None' }, interface: { display: 'Interface' }, specify: { display: 'Specify' }} } }, + { key: "gateway_mode", label: "Gateway Mode", as: "PillBar", props: { options: { none: { display: 'None' }, interface: { display: 'Interface' }, specify: { display: 'Specify' } } } }, { key: "gateway", label: "Gateway", as: "SingleSelect", enabled: (values: any) => (values["gateway_mode"] == 'specify'), props: { searchProvider: GetAddresses } }, - { key: "dns_server_mode", label: "DNS Server Mode", as: "PillBar", props: { options: { none: { display: 'None' }, interface: { display: 'Interface' }, specify: { display: 'Specify' }} } }, + { key: "dns_server_mode", label: "DNS Server Mode", as: "PillBar", props: { options: { none: { display: 'None' }, interface: { display: 'Interface' }, specify: { display: 'Specify' } } } }, { key: "dns_servers", label: "DNS Servers", as: "MultiSelect", enabled: (values: any) => (values["dns_server_mode"] == 'specify'), props: { searchProvider: GetAddresses } }, - { key: "ntp_server_mode", label: "NTP Server Mode", as: "PillBar", props: { options: { none: { display: 'None' }, interface: { display: 'Interface' }, specify: { display: 'Specify' }} } }, + { key: "ntp_server_mode", label: "NTP Server Mode", as: "PillBar", props: { options: { none: { display: 'None' }, interface: { display: 'Interface' }, specify: { display: 'Specify' } } } }, { key: "ntp_servers", label: "NTP Servers", as: "MultiSelect", enabled: (values: any) => (values["ntp_server_mode"] == 'specify'), props: { searchProvider: GetAddresses } }, { key: "default_lease_time", label: "Default Lease Time", as: "NumberBox" }, { key: "max_lease_time", label: "Max Lease Time", as: "NumberBox" }, @@ -208,4 +225,46 @@ export const editTypes: { [key: string]: { [key: string]: any } } = { ], }, }, + "vpn": { + name: "VPN", + "wireguardinterfaces": { + name: "WireguardInterface", + validationSchema: toFormValidator( + zod.object({ + }), + ), + sections: [ + { + fields: [ + { key: "name", label: "Name", as: "TextBox", default: "placeholder" }, + { key: "public_key", label: "Public Key", as: "TextBox", default: "placeholder" }, + { key: "private_key", label: "Private Key", as: "TextBox", default: "placeholder" }, + { key: "listen_port", label: "Listen Port", as: "NumberBox" }, + { key: "peers", label: "Peers", as: "MultiSelect", props: { searchProvider: GetPeers } }, + { key: "comment", label: "Comment", as: "MultilineTextBox" }, + ], + }, + ], + }, + "wireguardpeers": { + name: "WireguardPeer", + validationSchema: toFormValidator( + zod.object({ + }), + ), + sections: [ + { + fields: [ + { key: "name", label: "Name", as: "TextBox", default: "placeholder" }, + { key: "public_key", label: "Public Key", as: "TextBox", default: "placeholder" }, + { key: "preshared_key", label: "Preshared Key", as: "TextBox", default: "placeholder" }, + { key: "allowed_ips", label: "Allowed IPs", as: "MultiSelect", props: { searchProvider: GetAddresses } }, + { key: "endpoint", label: "Endpoint", as: "TextBox", default: "placeholder" }, + { key: "persistent_keepalive", label: "Persistent Keepalive", as: "NumberBox" }, + { key: "comment", label: "Comment", as: "MultilineTextBox" }, + ], + }, + ], + }, + }, }; \ No newline at end of file diff --git a/client/src/pages/vpn/WireguardInterfaces.vue b/client/src/pages/vpn/WireguardInterfaces.vue new file mode 100644 index 0000000..025a17c --- /dev/null +++ b/client/src/pages/vpn/WireguardInterfaces.vue @@ -0,0 +1,71 @@ + + + \ No newline at end of file diff --git a/client/src/pages/vpn/WireguardPeers.vue b/client/src/pages/vpn/WireguardPeers.vue new file mode 100644 index 0000000..bf7c74b --- /dev/null +++ b/client/src/pages/vpn/WireguardPeers.vue @@ -0,0 +1,72 @@ + + + \ No newline at end of file diff --git a/client/src/pages/vpn/WireguardStatus.vue b/client/src/pages/vpn/WireguardStatus.vue new file mode 100644 index 0000000..88b22f7 --- /dev/null +++ b/client/src/pages/vpn/WireguardStatus.vue @@ -0,0 +1,38 @@ + + + + + \ No newline at end of file