Replace from-scratch rewrite with real ngoduykhanh/wireguard-ui fork

The from-scratch Go rewrite had unresolved bugs (missing go.sum, UI
404s, path issues) from being built without a working local Go
toolchain to verify against. Switching strategy: use the actual
upstream wireguard-ui codebase (proven, battle-tested single-server
manager) as the base, and extend it for multi-server support instead
of re-deriving everything from zero.

Kept our own installers (bootstrap.sh, update.sh, scripts/install.sh,
scripts/proxmox-install.sh) - these still apply, just need updating
to build/install the upstream module layout instead of the old
cmd/wireguard-ui-multi structure.

Module path intentionally left as upstream's own
(github.com/ngoduykhanh/wireguard-ui) for now to avoid touching every
internal import; revisit if this needs to be fully rebranded.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-07-10 18:34:44 +02:00
co-authored by Claude Sonnet 5
parent 6eeea65ede
commit 867dc7740a
79 changed files with 11951 additions and 2548 deletions
+38
View File
@@ -0,0 +1,38 @@
package model
import (
"time"
)
// Client model
type Client struct {
ID string `json:"id"`
PrivateKey string `json:"private_key"`
PublicKey string `json:"public_key"`
PresharedKey string `json:"preshared_key"`
Name string `json:"name"`
TgUserid string `json:"telegram_userid"`
Email string `json:"email"`
SubnetRanges []string `json:"subnet_ranges,omitempty"`
AllocatedIPs []string `json:"allocated_ips"`
AllowedIPs []string `json:"allowed_ips"`
ExtraAllowedIPs []string `json:"extra_allowed_ips"`
Endpoint string `json:"endpoint"`
AdditionalNotes string `json:"additional_notes"`
UseServerDNS bool `json:"use_server_dns"`
Enabled bool `json:"enabled"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// ClientData includes the Client and extra data
type ClientData struct {
Client *Client
QRCode string
}
type QRCodeSettings struct {
Enabled bool
IncludeDNS bool
IncludeMTU bool
}
+9
View File
@@ -0,0 +1,9 @@
package model
// ClientDefaults Defaults for creation of new clients used in the templates
type ClientDefaults struct {
AllowedIps []string
ExtraAllowedIps []string
UseServerDNS bool
EnableAfterCreation bool
}
+20
View File
@@ -0,0 +1,20 @@
package model
// Interface model
type Interface struct {
Name string `json:"name"`
IPAddress string `json:"ip_address"`
}
// BaseData struct to pass value to the base template
type BaseData struct {
Active string
CurrentUser string
Admin bool
}
// ClientServerHashes struct, to save hashes to detect changes
type ClientServerHashes struct {
Client string `json:"client"`
Server string `json:"server"`
}
+28
View File
@@ -0,0 +1,28 @@
package model
import (
"time"
)
// Server model
type Server struct {
KeyPair *ServerKeypair
Interface *ServerInterface
}
// ServerKeypair model
type ServerKeypair struct {
PrivateKey string `json:"private_key"`
PublicKey string `json:"public_key"`
UpdatedAt time.Time `json:"updated_at"`
}
// ServerInterface model
type ServerInterface struct {
Addresses []string `json:"addresses"`
ListenPort int `json:"listen_port,string"` // ,string to get listen_port string input as int
UpdatedAt time.Time `json:"updated_at"`
PostUp string `json:"post_up"`
PreDown string `json:"pre_down"`
PostDown string `json:"post_down"`
}
+17
View File
@@ -0,0 +1,17 @@
package model
import (
"time"
)
// GlobalSetting model
type GlobalSetting struct {
EndpointAddress string `json:"endpoint_address"`
DNSServers []string `json:"dns_servers"`
MTU int `json:"mtu,string"`
PersistentKeepalive int `json:"persistent_keepalive,string"`
FirewallMark string `json:"firewall_mark"`
Table string `json:"table"`
ConfigFilePath string `json:"config_file_path"`
UpdatedAt time.Time `json:"updated_at"`
}
+10
View File
@@ -0,0 +1,10 @@
package model
// User model
type User struct {
Username string `json:"username"`
Password string `json:"password"`
// PasswordHash takes precedence over Password.
PasswordHash string `json:"password_hash"`
Admin bool `json:"admin"`
}
+31
View File
@@ -0,0 +1,31 @@
package model
import (
"errors"
"net"
"strings"
"time"
)
type WakeOnLanHost struct {
MacAddress string `json:"MacAddress"`
Name string `json:"Name"`
LatestUsed *time.Time `json:"LatestUsed"`
}
func (host WakeOnLanHost) ResolveResourceName() (string, error) {
resourceName := strings.Trim(host.MacAddress, " \t\r\n\000")
if len(resourceName) == 0 {
return "", errors.New("mac Address is Empty")
}
resourceName = strings.ToUpper(resourceName)
resourceName = strings.ReplaceAll(resourceName, ":", "-")
if _, err := net.ParseMAC(resourceName); err != nil {
return "", errors.New("invalid mac address")
}
return resourceName, nil
}
const WakeOnLanHostCollectionName = "wake_on_lan_hosts"