mirror of
https://github.com/h44z/wg-portal
synced 2025-02-26 05:49:14 +00:00
chore: update dependencies, refactor option types
This commit is contained in:
parent
6bb683047e
commit
bf9183256a
4
go.mod
4
go.mod
@ -11,14 +11,14 @@ require (
|
|||||||
github.com/glebarez/sqlite v1.11.0
|
github.com/glebarez/sqlite v1.11.0
|
||||||
github.com/go-ldap/ldap/v3 v3.4.8
|
github.com/go-ldap/ldap/v3 v3.4.8
|
||||||
github.com/prometheus-community/pro-bing v0.4.1
|
github.com/prometheus-community/pro-bing v0.4.1
|
||||||
github.com/prometheus/client_golang v1.20.4
|
github.com/prometheus/client_golang v1.20.5
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/swaggo/swag v1.16.3
|
github.com/swaggo/swag v1.16.3
|
||||||
github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f
|
github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f
|
||||||
github.com/utrack/gin-csrf v0.0.0-20190424104817-40fb8d2c8fca
|
github.com/utrack/gin-csrf v0.0.0-20190424104817-40fb8d2c8fca
|
||||||
github.com/vardius/message-bus v1.1.5
|
github.com/vardius/message-bus v1.1.5
|
||||||
github.com/vishvananda/netlink v1.1.0
|
github.com/vishvananda/netlink v1.3.0
|
||||||
github.com/xhit/go-simple-mail/v2 v2.16.0
|
github.com/xhit/go-simple-mail/v2 v2.16.0
|
||||||
github.com/yeqown/go-qrcode/v2 v2.2.4
|
github.com/yeqown/go-qrcode/v2 v2.2.4
|
||||||
golang.org/x/crypto v0.28.0
|
golang.org/x/crypto v0.28.0
|
||||||
|
12
go.sum
12
go.sum
@ -232,8 +232,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus-community/pro-bing v0.4.1 h1:aMaJwyifHZO0y+h8+icUz0xbToHbia0wdmzdVZ+Kl3w=
|
github.com/prometheus-community/pro-bing v0.4.1 h1:aMaJwyifHZO0y+h8+icUz0xbToHbia0wdmzdVZ+Kl3w=
|
||||||
github.com/prometheus-community/pro-bing v0.4.1/go.mod h1:aLsw+zqCaDoa2RLVVSX3+UiCkBBXTMtZC3c7EkfWnAE=
|
github.com/prometheus-community/pro-bing v0.4.1/go.mod h1:aLsw+zqCaDoa2RLVVSX3+UiCkBBXTMtZC3c7EkfWnAE=
|
||||||
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
|
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||||
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||||
@ -281,9 +281,8 @@ github.com/utrack/gin-csrf v0.0.0-20190424104817-40fb8d2c8fca h1:lpvAjPK+PcxnbcB
|
|||||||
github.com/utrack/gin-csrf v0.0.0-20190424104817-40fb8d2c8fca/go.mod h1:XXKxNbpoLihvvT7orUZbs/iZayg1n4ip7iJakJPAwA8=
|
github.com/utrack/gin-csrf v0.0.0-20190424104817-40fb8d2c8fca/go.mod h1:XXKxNbpoLihvvT7orUZbs/iZayg1n4ip7iJakJPAwA8=
|
||||||
github.com/vardius/message-bus v1.1.5 h1:YSAC2WB4HRlwc4neFPTmT88kzzoiQ+9WRRbej/E/LZc=
|
github.com/vardius/message-bus v1.1.5 h1:YSAC2WB4HRlwc4neFPTmT88kzzoiQ+9WRRbej/E/LZc=
|
||||||
github.com/vardius/message-bus v1.1.5/go.mod h1:6xladCV2lMkUAE4bzzS85qKOiB5miV7aBVRafiTJGqw=
|
github.com/vardius/message-bus v1.1.5/go.mod h1:6xladCV2lMkUAE4bzzS85qKOiB5miV7aBVRafiTJGqw=
|
||||||
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
|
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
|
||||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
|
||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
|
||||||
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
||||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||||
github.com/xhit/go-simple-mail/v2 v2.16.0 h1:ouGy/Ww4kuaqu2E2UrDw7SvLaziWTB60ICLkIkNVccA=
|
github.com/xhit/go-simple-mail/v2 v2.16.0 h1:ouGy/Ww4kuaqu2E2UrDw7SvLaziWTB60ICLkIkNVccA=
|
||||||
@ -337,7 +336,6 @@ golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
|||||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@ -345,9 +343,11 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
@ -4,12 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/h44z/wg-portal/internal/domain"
|
"github.com/h44z/wg-portal/internal/domain"
|
||||||
"github.com/h44z/wg-portal/internal/lowlevel"
|
"github.com/h44z/wg-portal/internal/lowlevel"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl"
|
"golang.zx2c4.com/wireguard/wgctrl"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// WgRepo implements all low-level WireGuard interactions.
|
// WgRepo implements all low-level WireGuard interactions.
|
||||||
@ -74,7 +75,11 @@ func (r *WgRepo) GetPeers(_ context.Context, deviceId domain.InterfaceIdentifier
|
|||||||
return peers, nil
|
return peers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *WgRepo) GetPeer(_ context.Context, deviceId domain.InterfaceIdentifier, id domain.PeerIdentifier) (*domain.PhysicalPeer, error) {
|
func (r *WgRepo) GetPeer(
|
||||||
|
_ context.Context,
|
||||||
|
deviceId domain.InterfaceIdentifier,
|
||||||
|
id domain.PeerIdentifier,
|
||||||
|
) (*domain.PhysicalPeer, error) {
|
||||||
return r.getPeer(deviceId, id)
|
return r.getPeer(deviceId, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +95,7 @@ func (r *WgRepo) convertWireGuardInterface(device *wgtypes.Device) (domain.Physi
|
|||||||
ListenPort: device.ListenPort,
|
ListenPort: device.ListenPort,
|
||||||
Addresses: nil,
|
Addresses: nil,
|
||||||
Mtu: 0,
|
Mtu: 0,
|
||||||
FirewallMark: int32(device.FirewallMark),
|
FirewallMark: uint32(device.FirewallMark),
|
||||||
DeviceUp: false,
|
DeviceUp: false,
|
||||||
ImportSource: "wgctrl",
|
ImportSource: "wgctrl",
|
||||||
DeviceType: device.Type.String(),
|
DeviceType: device.Type.String(),
|
||||||
@ -151,7 +156,11 @@ func (r *WgRepo) convertWireGuardPeer(peer *wgtypes.Peer) (domain.PhysicalPeer,
|
|||||||
return peerModel, nil
|
return peerModel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *WgRepo) SaveInterface(_ context.Context, id domain.InterfaceIdentifier, updateFunc func(pi *domain.PhysicalInterface) (*domain.PhysicalInterface, error)) error {
|
func (r *WgRepo) SaveInterface(
|
||||||
|
_ context.Context,
|
||||||
|
id domain.InterfaceIdentifier,
|
||||||
|
updateFunc func(pi *domain.PhysicalInterface) (*domain.PhysicalInterface, error),
|
||||||
|
) error {
|
||||||
physicalInterface, err := r.getOrCreateInterface(id)
|
physicalInterface, err := r.getOrCreateInterface(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -324,7 +333,12 @@ func (r *WgRepo) deleteLowLevelInterface(id domain.InterfaceIdentifier) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *WgRepo) SavePeer(_ context.Context, deviceId domain.InterfaceIdentifier, id domain.PeerIdentifier, updateFunc func(pp *domain.PhysicalPeer) (*domain.PhysicalPeer, error)) error {
|
func (r *WgRepo) SavePeer(
|
||||||
|
_ context.Context,
|
||||||
|
deviceId domain.InterfaceIdentifier,
|
||||||
|
id domain.PeerIdentifier,
|
||||||
|
updateFunc func(pp *domain.PhysicalPeer) (*domain.PhysicalPeer, error),
|
||||||
|
) error {
|
||||||
physicalPeer, err := r.getOrCreatePeer(deviceId, id)
|
physicalPeer, err := r.getOrCreatePeer(deviceId, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -342,7 +356,10 @@ func (r *WgRepo) SavePeer(_ context.Context, deviceId domain.InterfaceIdentifier
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *WgRepo) getOrCreatePeer(deviceId domain.InterfaceIdentifier, id domain.PeerIdentifier) (*domain.PhysicalPeer, error) {
|
func (r *WgRepo) getOrCreatePeer(deviceId domain.InterfaceIdentifier, id domain.PeerIdentifier) (
|
||||||
|
*domain.PhysicalPeer,
|
||||||
|
error,
|
||||||
|
) {
|
||||||
peer, err := r.getPeer(deviceId, id)
|
peer, err := r.getPeer(deviceId, id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return peer, nil
|
return peer, nil
|
||||||
@ -352,9 +369,13 @@ func (r *WgRepo) getOrCreatePeer(deviceId domain.InterfaceIdentifier, id domain.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create new peer
|
// create new peer
|
||||||
err = r.wg.ConfigureDevice(string(deviceId), wgtypes.Config{Peers: []wgtypes.PeerConfig{{
|
err = r.wg.ConfigureDevice(string(deviceId), wgtypes.Config{
|
||||||
PublicKey: id.ToPublicKey(),
|
Peers: []wgtypes.PeerConfig{
|
||||||
}}})
|
{
|
||||||
|
PublicKey: id.ToPublicKey(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
peer, err = r.getPeer(deviceId, id)
|
peer, err = r.getPeer(deviceId, id)
|
||||||
return peer, nil
|
return peer, nil
|
||||||
|
@ -5,132 +5,42 @@ import (
|
|||||||
"github.com/h44z/wg-portal/internal/domain"
|
"github.com/h44z/wg-portal/internal/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StringConfigOption struct {
|
type ConfigOption[T any] struct {
|
||||||
Value string `json:"Value"`
|
Value T `json:"Value"`
|
||||||
Overridable bool `json:"Overridable"`
|
Overridable bool `json:"Overridable"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStringConfigOption(value string, overridable bool) StringConfigOption {
|
func NewConfigOption[T any](value T, overridable bool) ConfigOption[T] {
|
||||||
return StringConfigOption{
|
return ConfigOption[T]{
|
||||||
Value: value,
|
Value: value,
|
||||||
Overridable: overridable,
|
Overridable: overridable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func StringConfigOptionFromDomain(opt domain.StringConfigOption) StringConfigOption {
|
func ConfigOptionFromDomain[T any](opt domain.ConfigOption[T]) ConfigOption[T] {
|
||||||
return StringConfigOption{
|
return ConfigOption[T]{
|
||||||
Value: opt.Value,
|
Value: opt.Value,
|
||||||
Overridable: opt.Overridable,
|
Overridable: opt.Overridable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func StringConfigOptionToDomain(opt StringConfigOption) domain.StringConfigOption {
|
func ConfigOptionToDomain[T any](opt ConfigOption[T]) domain.ConfigOption[T] {
|
||||||
return domain.StringConfigOption{
|
return domain.ConfigOption[T]{
|
||||||
Value: opt.Value,
|
Value: opt.Value,
|
||||||
Overridable: opt.Overridable,
|
Overridable: opt.Overridable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type StringSliceConfigOption struct {
|
func StringSliceConfigOptionFromDomain(opt domain.ConfigOption[string]) ConfigOption[[]string] {
|
||||||
Value []string `json:"Value"`
|
return ConfigOption[[]string]{
|
||||||
Overridable bool `json:"Overridable"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStringSliceConfigOption(value []string, overridable bool) StringSliceConfigOption {
|
|
||||||
return StringSliceConfigOption{
|
|
||||||
Value: value,
|
|
||||||
Overridable: overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func StringSliceConfigOptionFromDomain(opt domain.StringConfigOption) StringSliceConfigOption {
|
|
||||||
return StringSliceConfigOption{
|
|
||||||
Value: internal.SliceString(opt.Value),
|
Value: internal.SliceString(opt.Value),
|
||||||
Overridable: opt.Overridable,
|
Overridable: opt.Overridable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func StringSliceConfigOptionToDomain(opt StringSliceConfigOption) domain.StringConfigOption {
|
func StringSliceConfigOptionToDomain(opt ConfigOption[[]string]) domain.ConfigOption[string] {
|
||||||
return domain.StringConfigOption{
|
return domain.ConfigOption[string]{
|
||||||
Value: internal.SliceToString(opt.Value),
|
Value: internal.SliceToString(opt.Value),
|
||||||
Overridable: opt.Overridable,
|
Overridable: opt.Overridable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type IntConfigOption struct {
|
|
||||||
Value int `json:"Value"`
|
|
||||||
Overridable bool `json:"Overridable"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIntConfigOption(value int, overridable bool) IntConfigOption {
|
|
||||||
return IntConfigOption{
|
|
||||||
Value: value,
|
|
||||||
Overridable: overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func IntConfigOptionFromDomain(opt domain.IntConfigOption) IntConfigOption {
|
|
||||||
return IntConfigOption{
|
|
||||||
Value: opt.Value,
|
|
||||||
Overridable: opt.Overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func IntConfigOptionToDomain(opt IntConfigOption) domain.IntConfigOption {
|
|
||||||
return domain.IntConfigOption{
|
|
||||||
Value: opt.Value,
|
|
||||||
Overridable: opt.Overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Int32ConfigOption struct {
|
|
||||||
Value int32 `json:"Value"`
|
|
||||||
Overridable bool `json:"Overridable"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewInt32ConfigOption(value int32, overridable bool) Int32ConfigOption {
|
|
||||||
return Int32ConfigOption{
|
|
||||||
Value: value,
|
|
||||||
Overridable: overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Int32ConfigOptionFromDomain(opt domain.Int32ConfigOption) Int32ConfigOption {
|
|
||||||
return Int32ConfigOption{
|
|
||||||
Value: opt.Value,
|
|
||||||
Overridable: opt.Overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Int32ConfigOptionToDomain(opt Int32ConfigOption) domain.Int32ConfigOption {
|
|
||||||
return domain.Int32ConfigOption{
|
|
||||||
Value: opt.Value,
|
|
||||||
Overridable: opt.Overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type BoolConfigOption struct {
|
|
||||||
Value bool `json:"Value"`
|
|
||||||
Overridable bool `json:"Overridable"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBoolConfigOption(value bool, overridable bool) BoolConfigOption {
|
|
||||||
return BoolConfigOption{
|
|
||||||
Value: value,
|
|
||||||
Overridable: overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BoolConfigOptionFromDomain(opt domain.BoolConfigOption) BoolConfigOption {
|
|
||||||
return BoolConfigOption{
|
|
||||||
Value: opt.Value,
|
|
||||||
Overridable: opt.Overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BoolConfigOptionToDomain(opt BoolConfigOption) domain.BoolConfigOption {
|
|
||||||
return domain.BoolConfigOption{
|
|
||||||
Value: opt.Value,
|
|
||||||
Overridable: opt.Overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/h44z/wg-portal/internal"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/h44z/wg-portal/internal"
|
||||||
|
|
||||||
"github.com/h44z/wg-portal/internal/domain"
|
"github.com/h44z/wg-portal/internal/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ type Interface struct {
|
|||||||
Dns []string `json:"Dns"` // the dns server that should be set if the interface is up, comma separated
|
Dns []string `json:"Dns"` // the dns server that should be set if the interface is up, comma separated
|
||||||
DnsSearch []string `json:"DnsSearch"` // the dns search option string that should be set if the interface is up, will be appended to DnsStr
|
DnsSearch []string `json:"DnsSearch"` // the dns search option string that should be set if the interface is up, will be appended to DnsStr
|
||||||
Mtu int `json:"Mtu"` // the device MTU
|
Mtu int `json:"Mtu"` // the device MTU
|
||||||
FirewallMark int32 `json:"FirewallMark"` // a firewall mark
|
FirewallMark uint32 `json:"FirewallMark"` // a firewall mark
|
||||||
RoutingTable string `json:"RoutingTable"` // the routing table
|
RoutingTable string `json:"RoutingTable"` // the routing table
|
||||||
|
|
||||||
PreUp string `json:"PreUp"` // action that is executed before the device is up
|
PreUp string `json:"PreUp"` // action that is executed before the device is up
|
||||||
@ -37,7 +38,7 @@ type Interface struct {
|
|||||||
PeerDefAllowedIPs []string `json:"PeerDefAllowedIPs"` // the default allowed IP string for the peer
|
PeerDefAllowedIPs []string `json:"PeerDefAllowedIPs"` // the default allowed IP string for the peer
|
||||||
PeerDefMtu int `json:"PeerDefMtu"` // the default device MTU
|
PeerDefMtu int `json:"PeerDefMtu"` // the default device MTU
|
||||||
PeerDefPersistentKeepalive int `json:"PeerDefPersistentKeepalive"` // the default persistent keep-alive Value
|
PeerDefPersistentKeepalive int `json:"PeerDefPersistentKeepalive"` // the default persistent keep-alive Value
|
||||||
PeerDefFirewallMark int32 `json:"PeerDefFirewallMark"` // default firewall mark
|
PeerDefFirewallMark uint32 `json:"PeerDefFirewallMark"` // default firewall mark
|
||||||
PeerDefRoutingTable string `json:"PeerDefRoutingTable"` // the default routing table
|
PeerDefRoutingTable string `json:"PeerDefRoutingTable"` // the default routing table
|
||||||
|
|
||||||
PeerDefPreUp string `json:"PeerDefPreUp"` // default action that is executed before the device is up
|
PeerDefPreUp string `json:"PeerDefPreUp"` // default action that is executed before the device is up
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/h44z/wg-portal/internal"
|
"github.com/h44z/wg-portal/internal"
|
||||||
"github.com/h44z/wg-portal/internal/domain"
|
"github.com/h44z/wg-portal/internal/domain"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const ExpiryDateTimeLayout = "\"2006-01-02\""
|
const ExpiryDateTimeLayout = "\"2006-01-02\""
|
||||||
@ -48,30 +49,30 @@ type Peer struct {
|
|||||||
ExpiresAt ExpiryDate `json:"ExpiresAt,omitempty"` // expiry dates for peers
|
ExpiresAt ExpiryDate `json:"ExpiresAt,omitempty"` // expiry dates for peers
|
||||||
Notes string `json:"Notes"` // a note field for peers
|
Notes string `json:"Notes"` // a note field for peers
|
||||||
|
|
||||||
Endpoint StringConfigOption `json:"Endpoint"` // the endpoint address
|
Endpoint ConfigOption[string] `json:"Endpoint"` // the endpoint address
|
||||||
EndpointPublicKey StringConfigOption `json:"EndpointPublicKey"` // the endpoint public key
|
EndpointPublicKey ConfigOption[string] `json:"EndpointPublicKey"` // the endpoint public key
|
||||||
AllowedIPs StringSliceConfigOption `json:"AllowedIPs"` // all allowed ip subnets, comma seperated
|
AllowedIPs ConfigOption[[]string] `json:"AllowedIPs"` // all allowed ip subnets, comma seperated
|
||||||
ExtraAllowedIPs []string `json:"ExtraAllowedIPs"` // all allowed ip subnets on the server side, comma seperated
|
ExtraAllowedIPs []string `json:"ExtraAllowedIPs"` // all allowed ip subnets on the server side, comma seperated
|
||||||
PresharedKey string `json:"PresharedKey"` // the pre-shared Key of the peer
|
PresharedKey string `json:"PresharedKey"` // the pre-shared Key of the peer
|
||||||
PersistentKeepalive IntConfigOption `json:"PersistentKeepalive"` // the persistent keep-alive interval
|
PersistentKeepalive ConfigOption[int] `json:"PersistentKeepalive"` // the persistent keep-alive interval
|
||||||
|
|
||||||
PrivateKey string `json:"PrivateKey" example:"abcdef=="` // private Key of the server peer
|
PrivateKey string `json:"PrivateKey" example:"abcdef=="` // private Key of the server peer
|
||||||
PublicKey string `json:"PublicKey" example:"abcdef=="` // public Key of the server peer
|
PublicKey string `json:"PublicKey" example:"abcdef=="` // public Key of the server peer
|
||||||
|
|
||||||
Mode string // the peer interface type (server, client, any)
|
Mode string // the peer interface type (server, client, any)
|
||||||
|
|
||||||
Addresses []string `json:"Addresses"` // the interface ip addresses
|
Addresses []string `json:"Addresses"` // the interface ip addresses
|
||||||
CheckAliveAddress string `json:"CheckAliveAddress"` // optional ip address or DNS name that is used for ping checks
|
CheckAliveAddress string `json:"CheckAliveAddress"` // optional ip address or DNS name that is used for ping checks
|
||||||
Dns StringSliceConfigOption `json:"Dns"` // the dns server that should be set if the interface is up, comma separated
|
Dns ConfigOption[[]string] `json:"Dns"` // the dns server that should be set if the interface is up, comma separated
|
||||||
DnsSearch StringSliceConfigOption `json:"DnsSearch"` // the dns search option string that should be set if the interface is up, will be appended to DnsStr
|
DnsSearch ConfigOption[[]string] `json:"DnsSearch"` // the dns search option string that should be set if the interface is up, will be appended to DnsStr
|
||||||
Mtu IntConfigOption `json:"Mtu"` // the device MTU
|
Mtu ConfigOption[int] `json:"Mtu"` // the device MTU
|
||||||
FirewallMark Int32ConfigOption `json:"FirewallMark"` // a firewall mark
|
FirewallMark ConfigOption[uint32] `json:"FirewallMark"` // a firewall mark
|
||||||
RoutingTable StringConfigOption `json:"RoutingTable"` // the routing table
|
RoutingTable ConfigOption[string] `json:"RoutingTable"` // the routing table
|
||||||
|
|
||||||
PreUp StringConfigOption `json:"PreUp"` // action that is executed before the device is up
|
PreUp ConfigOption[string] `json:"PreUp"` // action that is executed before the device is up
|
||||||
PostUp StringConfigOption `json:"PostUp"` // action that is executed after the device is up
|
PostUp ConfigOption[string] `json:"PostUp"` // action that is executed after the device is up
|
||||||
PreDown StringConfigOption `json:"PreDown"` // action that is executed before the device is down
|
PreDown ConfigOption[string] `json:"PreDown"` // action that is executed before the device is down
|
||||||
PostDown StringConfigOption `json:"PostDown"` // action that is executed after the device is down
|
PostDown ConfigOption[string] `json:"PostDown"` // action that is executed after the device is down
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPeer(src *domain.Peer) *Peer {
|
func NewPeer(src *domain.Peer) *Peer {
|
||||||
@ -84,12 +85,12 @@ func NewPeer(src *domain.Peer) *Peer {
|
|||||||
DisabledReason: src.DisabledReason,
|
DisabledReason: src.DisabledReason,
|
||||||
ExpiresAt: ExpiryDate{src.ExpiresAt},
|
ExpiresAt: ExpiryDate{src.ExpiresAt},
|
||||||
Notes: src.Notes,
|
Notes: src.Notes,
|
||||||
Endpoint: StringConfigOptionFromDomain(src.Endpoint),
|
Endpoint: ConfigOptionFromDomain(src.Endpoint),
|
||||||
EndpointPublicKey: StringConfigOptionFromDomain(src.EndpointPublicKey),
|
EndpointPublicKey: ConfigOptionFromDomain(src.EndpointPublicKey),
|
||||||
AllowedIPs: StringSliceConfigOptionFromDomain(src.AllowedIPsStr),
|
AllowedIPs: StringSliceConfigOptionFromDomain(src.AllowedIPsStr),
|
||||||
ExtraAllowedIPs: internal.SliceString(src.ExtraAllowedIPsStr),
|
ExtraAllowedIPs: internal.SliceString(src.ExtraAllowedIPsStr),
|
||||||
PresharedKey: string(src.PresharedKey),
|
PresharedKey: string(src.PresharedKey),
|
||||||
PersistentKeepalive: IntConfigOptionFromDomain(src.PersistentKeepalive),
|
PersistentKeepalive: ConfigOptionFromDomain(src.PersistentKeepalive),
|
||||||
PrivateKey: src.Interface.PrivateKey,
|
PrivateKey: src.Interface.PrivateKey,
|
||||||
PublicKey: src.Interface.PublicKey,
|
PublicKey: src.Interface.PublicKey,
|
||||||
Mode: string(src.Interface.Type),
|
Mode: string(src.Interface.Type),
|
||||||
@ -97,13 +98,13 @@ func NewPeer(src *domain.Peer) *Peer {
|
|||||||
CheckAliveAddress: src.Interface.CheckAliveAddress,
|
CheckAliveAddress: src.Interface.CheckAliveAddress,
|
||||||
Dns: StringSliceConfigOptionFromDomain(src.Interface.DnsStr),
|
Dns: StringSliceConfigOptionFromDomain(src.Interface.DnsStr),
|
||||||
DnsSearch: StringSliceConfigOptionFromDomain(src.Interface.DnsSearchStr),
|
DnsSearch: StringSliceConfigOptionFromDomain(src.Interface.DnsSearchStr),
|
||||||
Mtu: IntConfigOptionFromDomain(src.Interface.Mtu),
|
Mtu: ConfigOptionFromDomain(src.Interface.Mtu),
|
||||||
FirewallMark: Int32ConfigOptionFromDomain(src.Interface.FirewallMark),
|
FirewallMark: ConfigOptionFromDomain(src.Interface.FirewallMark),
|
||||||
RoutingTable: StringConfigOptionFromDomain(src.Interface.RoutingTable),
|
RoutingTable: ConfigOptionFromDomain(src.Interface.RoutingTable),
|
||||||
PreUp: StringConfigOptionFromDomain(src.Interface.PreUp),
|
PreUp: ConfigOptionFromDomain(src.Interface.PreUp),
|
||||||
PostUp: StringConfigOptionFromDomain(src.Interface.PostUp),
|
PostUp: ConfigOptionFromDomain(src.Interface.PostUp),
|
||||||
PreDown: StringConfigOptionFromDomain(src.Interface.PreDown),
|
PreDown: ConfigOptionFromDomain(src.Interface.PreDown),
|
||||||
PostDown: StringConfigOptionFromDomain(src.Interface.PostDown),
|
PostDown: ConfigOptionFromDomain(src.Interface.PostDown),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,12 +124,12 @@ func NewDomainPeer(src *Peer) *domain.Peer {
|
|||||||
|
|
||||||
res := &domain.Peer{
|
res := &domain.Peer{
|
||||||
BaseModel: domain.BaseModel{},
|
BaseModel: domain.BaseModel{},
|
||||||
Endpoint: StringConfigOptionToDomain(src.Endpoint),
|
Endpoint: ConfigOptionToDomain(src.Endpoint),
|
||||||
EndpointPublicKey: StringConfigOptionToDomain(src.EndpointPublicKey),
|
EndpointPublicKey: ConfigOptionToDomain(src.EndpointPublicKey),
|
||||||
AllowedIPsStr: StringSliceConfigOptionToDomain(src.AllowedIPs),
|
AllowedIPsStr: StringSliceConfigOptionToDomain(src.AllowedIPs),
|
||||||
ExtraAllowedIPsStr: internal.SliceToString(src.ExtraAllowedIPs),
|
ExtraAllowedIPsStr: internal.SliceToString(src.ExtraAllowedIPs),
|
||||||
PresharedKey: domain.PreSharedKey(src.PresharedKey),
|
PresharedKey: domain.PreSharedKey(src.PresharedKey),
|
||||||
PersistentKeepalive: IntConfigOptionToDomain(src.PersistentKeepalive),
|
PersistentKeepalive: ConfigOptionToDomain(src.PersistentKeepalive),
|
||||||
DisplayName: src.DisplayName,
|
DisplayName: src.DisplayName,
|
||||||
Identifier: domain.PeerIdentifier(src.Identifier),
|
Identifier: domain.PeerIdentifier(src.Identifier),
|
||||||
UserIdentifier: domain.UserIdentifier(src.UserIdentifier),
|
UserIdentifier: domain.UserIdentifier(src.UserIdentifier),
|
||||||
@ -147,13 +148,13 @@ func NewDomainPeer(src *Peer) *domain.Peer {
|
|||||||
CheckAliveAddress: src.CheckAliveAddress,
|
CheckAliveAddress: src.CheckAliveAddress,
|
||||||
DnsStr: StringSliceConfigOptionToDomain(src.Dns),
|
DnsStr: StringSliceConfigOptionToDomain(src.Dns),
|
||||||
DnsSearchStr: StringSliceConfigOptionToDomain(src.DnsSearch),
|
DnsSearchStr: StringSliceConfigOptionToDomain(src.DnsSearch),
|
||||||
Mtu: IntConfigOptionToDomain(src.Mtu),
|
Mtu: ConfigOptionToDomain(src.Mtu),
|
||||||
FirewallMark: Int32ConfigOptionToDomain(src.FirewallMark),
|
FirewallMark: ConfigOptionToDomain(src.FirewallMark),
|
||||||
RoutingTable: StringConfigOptionToDomain(src.RoutingTable),
|
RoutingTable: ConfigOptionToDomain(src.RoutingTable),
|
||||||
PreUp: StringConfigOptionToDomain(src.PreUp),
|
PreUp: ConfigOptionToDomain(src.PreUp),
|
||||||
PostUp: StringConfigOptionToDomain(src.PostUp),
|
PostUp: ConfigOptionToDomain(src.PostUp),
|
||||||
PreDown: StringConfigOptionToDomain(src.PreDown),
|
PreDown: ConfigOptionToDomain(src.PreDown),
|
||||||
PostDown: StringConfigOptionToDomain(src.PostDown),
|
PostDown: ConfigOptionToDomain(src.PostDown),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,13 +3,14 @@ package app
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/h44z/wg-portal/internal/adapters"
|
"github.com/h44z/wg-portal/internal/adapters"
|
||||||
"github.com/h44z/wg-portal/internal/config"
|
"github.com/h44z/wg-portal/internal/config"
|
||||||
"github.com/h44z/wg-portal/internal/domain"
|
"github.com/h44z/wg-portal/internal/domain"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func migrateFromV1(cfg *config.Config, db *gorm.DB, source, typ string) error {
|
func migrateFromV1(cfg *config.Config, db *gorm.DB, source, typ string) error {
|
||||||
@ -137,7 +138,7 @@ func migrateV1Interfaces(oldDb, newDb *gorm.DB) error {
|
|||||||
DisplayName string
|
DisplayName string
|
||||||
PrivateKey string
|
PrivateKey string
|
||||||
ListenPort int
|
ListenPort int
|
||||||
FirewallMark int32
|
FirewallMark uint32
|
||||||
PublicKey string
|
PublicKey string
|
||||||
Mtu int
|
Mtu int
|
||||||
IPsStr string
|
IPsStr string
|
||||||
@ -288,7 +289,8 @@ func migrateV1Peers(oldDb, newDb *gorm.DB) error {
|
|||||||
ifaceType = domain.InterfaceTypeAny
|
ifaceType = domain.InterfaceTypeAny
|
||||||
}
|
}
|
||||||
var user domain.User
|
var user domain.User
|
||||||
err = newDb.First(&user, "identifier = ?", oldPeer.Email).Error // migrated users use the email address as identifier
|
err = newDb.First(&user, "identifier = ?",
|
||||||
|
oldPeer.Email).Error // migrated users use the email address as identifier
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fmt.Errorf("failed to find user %s for peer %s: %w", oldPeer.Email, oldPeer.PublicKey, err)
|
return fmt.Errorf("failed to find user %s for peer %s: %w", oldPeer.Email, oldPeer.PublicKey, err)
|
||||||
}
|
}
|
||||||
@ -325,20 +327,12 @@ func migrateV1Peers(oldDb, newDb *gorm.DB) error {
|
|||||||
CreatedAt: oldPeer.CreatedAt,
|
CreatedAt: oldPeer.CreatedAt,
|
||||||
UpdatedAt: oldPeer.UpdatedAt,
|
UpdatedAt: oldPeer.UpdatedAt,
|
||||||
},
|
},
|
||||||
Endpoint: domain.StringConfigOption{
|
Endpoint: domain.NewConfigOption(oldPeer.Endpoint, !oldPeer.IgnoreGlobalSettings),
|
||||||
Value: oldPeer.Endpoint, Overridable: !oldPeer.IgnoreGlobalSettings,
|
EndpointPublicKey: domain.NewConfigOption(iface.PublicKey, !oldPeer.IgnoreGlobalSettings),
|
||||||
},
|
AllowedIPsStr: domain.NewConfigOption(oldPeer.AllowedIPsStr, !oldPeer.IgnoreGlobalSettings),
|
||||||
EndpointPublicKey: domain.StringConfigOption{
|
ExtraAllowedIPsStr: oldPeer.AllowedIPsSrvStr,
|
||||||
Value: iface.PublicKey, Overridable: !oldPeer.IgnoreGlobalSettings,
|
PresharedKey: domain.PreSharedKey(oldPeer.PresharedKey),
|
||||||
},
|
PersistentKeepalive: domain.NewConfigOption(oldPeer.PersistentKeepalive, !oldPeer.IgnoreGlobalSettings),
|
||||||
AllowedIPsStr: domain.StringConfigOption{
|
|
||||||
Value: oldPeer.AllowedIPsStr, Overridable: !oldPeer.IgnoreGlobalSettings,
|
|
||||||
},
|
|
||||||
ExtraAllowedIPsStr: oldPeer.AllowedIPsSrvStr,
|
|
||||||
PresharedKey: domain.PreSharedKey(oldPeer.PresharedKey),
|
|
||||||
PersistentKeepalive: domain.IntConfigOption{
|
|
||||||
Value: oldPeer.PersistentKeepalive, Overridable: !oldPeer.IgnoreGlobalSettings,
|
|
||||||
},
|
|
||||||
DisplayName: oldPeer.Identifier,
|
DisplayName: oldPeer.Identifier,
|
||||||
Identifier: domain.PeerIdentifier(oldPeer.PublicKey),
|
Identifier: domain.PeerIdentifier(oldPeer.PublicKey),
|
||||||
UserIdentifier: user.Identifier,
|
UserIdentifier: user.Identifier,
|
||||||
@ -352,35 +346,17 @@ func migrateV1Peers(oldDb, newDb *gorm.DB) error {
|
|||||||
PrivateKey: oldPeer.PrivateKey,
|
PrivateKey: oldPeer.PrivateKey,
|
||||||
PublicKey: oldPeer.PublicKey,
|
PublicKey: oldPeer.PublicKey,
|
||||||
},
|
},
|
||||||
Type: ifaceType,
|
Type: ifaceType,
|
||||||
Addresses: ips,
|
Addresses: ips,
|
||||||
DnsStr: domain.StringConfigOption{
|
DnsStr: domain.NewConfigOption(oldPeer.DNSStr, !oldPeer.IgnoreGlobalSettings),
|
||||||
Value: oldPeer.DNSStr, Overridable: !oldPeer.IgnoreGlobalSettings,
|
DnsSearchStr: domain.NewConfigOption(iface.PeerDefDnsSearchStr, !oldPeer.IgnoreGlobalSettings),
|
||||||
},
|
Mtu: domain.NewConfigOption(oldPeer.Mtu, !oldPeer.IgnoreGlobalSettings),
|
||||||
DnsSearchStr: domain.StringConfigOption{
|
FirewallMark: domain.NewConfigOption(iface.PeerDefFirewallMark, !oldPeer.IgnoreGlobalSettings),
|
||||||
Value: iface.PeerDefDnsSearchStr, Overridable: !oldPeer.IgnoreGlobalSettings,
|
RoutingTable: domain.NewConfigOption(iface.PeerDefRoutingTable, !oldPeer.IgnoreGlobalSettings),
|
||||||
},
|
PreUp: domain.NewConfigOption(iface.PeerDefPreUp, !oldPeer.IgnoreGlobalSettings),
|
||||||
Mtu: domain.IntConfigOption{
|
PostUp: domain.NewConfigOption(iface.PeerDefPostUp, !oldPeer.IgnoreGlobalSettings),
|
||||||
Value: oldPeer.Mtu, Overridable: !oldPeer.IgnoreGlobalSettings,
|
PreDown: domain.NewConfigOption(iface.PeerDefPreDown, !oldPeer.IgnoreGlobalSettings),
|
||||||
},
|
PostDown: domain.NewConfigOption(iface.PeerDefPostDown, !oldPeer.IgnoreGlobalSettings),
|
||||||
FirewallMark: domain.Int32ConfigOption{
|
|
||||||
Value: iface.PeerDefFirewallMark, Overridable: !oldPeer.IgnoreGlobalSettings,
|
|
||||||
},
|
|
||||||
RoutingTable: domain.StringConfigOption{
|
|
||||||
Value: iface.PeerDefRoutingTable, Overridable: !oldPeer.IgnoreGlobalSettings,
|
|
||||||
},
|
|
||||||
PreUp: domain.StringConfigOption{
|
|
||||||
Value: iface.PeerDefPreUp, Overridable: !oldPeer.IgnoreGlobalSettings,
|
|
||||||
},
|
|
||||||
PostUp: domain.StringConfigOption{
|
|
||||||
Value: iface.PeerDefPostUp, Overridable: !oldPeer.IgnoreGlobalSettings,
|
|
||||||
},
|
|
||||||
PreDown: domain.StringConfigOption{
|
|
||||||
Value: iface.PeerDefPreDown, Overridable: !oldPeer.IgnoreGlobalSettings,
|
|
||||||
},
|
|
||||||
PostDown: domain.StringConfigOption{
|
|
||||||
Value: iface.PeerDefPostDown, Overridable: !oldPeer.IgnoreGlobalSettings,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package route
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/h44z/wg-portal/internal/app"
|
"github.com/h44z/wg-portal/internal/app"
|
||||||
"github.com/h44z/wg-portal/internal/config"
|
"github.com/h44z/wg-portal/internal/config"
|
||||||
"github.com/h44z/wg-portal/internal/domain"
|
"github.com/h44z/wg-portal/internal/domain"
|
||||||
@ -17,7 +18,7 @@ import (
|
|||||||
|
|
||||||
type routeRuleInfo struct {
|
type routeRuleInfo struct {
|
||||||
ifaceId domain.InterfaceIdentifier
|
ifaceId domain.InterfaceIdentifier
|
||||||
fwMark int
|
fwMark uint32
|
||||||
table int
|
table int
|
||||||
family int
|
family int
|
||||||
hasDefault bool
|
hasDefault bool
|
||||||
@ -210,7 +211,7 @@ func (m Manager) setFwMarkRules(rules []routeRuleInfo, family int) error {
|
|||||||
SuppressIfgroup: -1,
|
SuppressIfgroup: -1,
|
||||||
SuppressPrefixlen: -1,
|
SuppressPrefixlen: -1,
|
||||||
Priority: m.getRulePriority(existingRules),
|
Priority: m.getRulePriority(existingRules),
|
||||||
Mask: -1,
|
Mask: nil,
|
||||||
Goto: -1,
|
Goto: -1,
|
||||||
Flow: -1,
|
Flow: -1,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -220,7 +221,7 @@ func (m Manager) setFwMarkRules(rules []routeRuleInfo, family int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Manager) removeFwMarkRules(fwmark, table int, family int) error {
|
func (m Manager) removeFwMarkRules(fwmark uint32, table int, family int) error {
|
||||||
existingRules, err := m.nl.RuleList(family)
|
existingRules, err := m.nl.RuleList(family)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get existing rules for family %d: %w", family, err)
|
return fmt.Errorf("failed to get existing rules for family %d: %w", family, err)
|
||||||
@ -272,8 +273,8 @@ func (m Manager) setMainRule(rules []routeRuleInfo, family int) error {
|
|||||||
SuppressIfgroup: -1,
|
SuppressIfgroup: -1,
|
||||||
SuppressPrefixlen: 0,
|
SuppressPrefixlen: 0,
|
||||||
Priority: m.getMainRulePriority(existingRules),
|
Priority: m.getMainRulePriority(existingRules),
|
||||||
Mark: -1,
|
Mark: 0,
|
||||||
Mask: -1,
|
Mask: nil,
|
||||||
Goto: -1,
|
Goto: -1,
|
||||||
Flow: -1,
|
Flow: -1,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -424,20 +425,25 @@ func (m Manager) removeDeprecatedRoutes(link netlink.Link, family int, allowedIP
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Manager) getRoutingTableAndFwMark(iface *domain.Interface, allowedIPs []domain.Cidr, link netlink.Link) (table, fwmark int, err error) {
|
func (m Manager) getRoutingTableAndFwMark(
|
||||||
|
iface *domain.Interface,
|
||||||
|
allowedIPs []domain.Cidr,
|
||||||
|
link netlink.Link,
|
||||||
|
) (table int, fwmark uint32, err error) {
|
||||||
table = iface.GetRoutingTable()
|
table = iface.GetRoutingTable()
|
||||||
fwmark = int(iface.FirewallMark)
|
fwmark = iface.FirewallMark
|
||||||
|
|
||||||
if fwmark == 0 {
|
if fwmark == 0 {
|
||||||
fwmark = m.cfg.Advanced.RouteTableOffset + link.Attrs().Index // generate a new (temporary) firewall mark based on the interface index
|
// generate a new (temporary) firewall mark based on the interface index
|
||||||
logrus.Debugf("using fwmark %d to handle routes", table)
|
fwmark = uint32(m.cfg.Advanced.RouteTableOffset + link.Attrs().Index)
|
||||||
|
logrus.Debugf("%s: using fwmark %d to handle routes", iface.Identifier, table)
|
||||||
|
|
||||||
// apply the temporary fwmark to the wireguard interface
|
// apply the temporary fwmark to the wireguard interface
|
||||||
err = m.setFwMark(iface.Identifier, fwmark)
|
err = m.setFwMark(iface.Identifier, int(fwmark))
|
||||||
}
|
}
|
||||||
if table == 0 {
|
if table == 0 {
|
||||||
table = fwmark // generate a new routing table base on interface index
|
table = int(fwmark) // generate a new routing table base on interface index
|
||||||
logrus.Debugf("using routing table %d to handle default routes", table)
|
logrus.Debugf("%s: using routing table %d to handle default routes", iface.Identifier, table)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/h44z/wg-portal/internal"
|
"github.com/h44z/wg-portal/internal"
|
||||||
"github.com/h44z/wg-portal/internal/app"
|
"github.com/h44z/wg-portal/internal/app"
|
||||||
"github.com/h44z/wg-portal/internal/domain"
|
"github.com/h44z/wg-portal/internal/domain"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m Manager) GetImportableInterfaces(ctx context.Context) ([]domain.PhysicalInterface, error) {
|
func (m Manager) GetImportableInterfaces(ctx context.Context) ([]domain.PhysicalInterface, error) {
|
||||||
@ -25,7 +26,11 @@ func (m Manager) GetImportableInterfaces(ctx context.Context) ([]domain.Physical
|
|||||||
return physicalInterfaces, nil
|
return physicalInterfaces, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Manager) GetInterfaceAndPeers(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Interface, []domain.Peer, error) {
|
func (m Manager) GetInterfaceAndPeers(ctx context.Context, id domain.InterfaceIdentifier) (
|
||||||
|
*domain.Interface,
|
||||||
|
[]domain.Peer,
|
||||||
|
error,
|
||||||
|
) {
|
||||||
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -145,7 +150,11 @@ func (m Manager) ApplyPeerDefaults(ctx context.Context, in *domain.Interface) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Manager) RestoreInterfaceState(ctx context.Context, updateDbOnError bool, filter ...domain.InterfaceIdentifier) error {
|
func (m Manager) RestoreInterfaceState(
|
||||||
|
ctx context.Context,
|
||||||
|
updateDbOnError bool,
|
||||||
|
filter ...domain.InterfaceIdentifier,
|
||||||
|
) error {
|
||||||
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -177,22 +186,24 @@ func (m Manager) RestoreInterfaceState(ctx context.Context, updateDbOnError bool
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if updateDbOnError {
|
if updateDbOnError {
|
||||||
// disable interface in database as no physical interface exists
|
// disable interface in database as no physical interface exists
|
||||||
_ = m.db.SaveInterface(ctx, iface.Identifier, func(in *domain.Interface) (*domain.Interface, error) {
|
_ = m.db.SaveInterface(ctx, iface.Identifier,
|
||||||
now := time.Now()
|
func(in *domain.Interface) (*domain.Interface, error) {
|
||||||
in.Disabled = &now // set
|
now := time.Now()
|
||||||
in.DisabledReason = domain.DisabledReasonInterfaceMissing
|
in.Disabled = &now // set
|
||||||
return in, nil
|
in.DisabledReason = domain.DisabledReasonInterfaceMissing
|
||||||
})
|
return in, nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to create physical interface %s: %w", iface.Identifier, err)
|
return fmt.Errorf("failed to create physical interface %s: %w", iface.Identifier, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore peers
|
// restore peers
|
||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
err := m.wg.SavePeer(ctx, iface.Identifier, peer.Identifier, func(pp *domain.PhysicalPeer) (*domain.PhysicalPeer, error) {
|
err := m.wg.SavePeer(ctx, iface.Identifier, peer.Identifier,
|
||||||
domain.MergeToPhysicalPeer(pp, &peer)
|
func(pp *domain.PhysicalPeer) (*domain.PhysicalPeer, error) {
|
||||||
return pp, nil
|
domain.MergeToPhysicalPeer(pp, &peer)
|
||||||
})
|
return pp, nil
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create physical peer %s: %w", peer.Identifier, err)
|
return fmt.Errorf("failed to create physical peer %s: %w", peer.Identifier, err)
|
||||||
}
|
}
|
||||||
@ -205,17 +216,18 @@ func (m Manager) RestoreInterfaceState(ctx context.Context, updateDbOnError bool
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if updateDbOnError {
|
if updateDbOnError {
|
||||||
// disable interface in database as no physical interface is available
|
// disable interface in database as no physical interface is available
|
||||||
_ = m.db.SaveInterface(ctx, iface.Identifier, func(in *domain.Interface) (*domain.Interface, error) {
|
_ = m.db.SaveInterface(ctx, iface.Identifier,
|
||||||
if iface.IsDisabled() {
|
func(in *domain.Interface) (*domain.Interface, error) {
|
||||||
now := time.Now()
|
if iface.IsDisabled() {
|
||||||
in.Disabled = &now // set
|
now := time.Now()
|
||||||
in.DisabledReason = domain.DisabledReasonInterfaceMissing
|
in.Disabled = &now // set
|
||||||
} else {
|
in.DisabledReason = domain.DisabledReasonInterfaceMissing
|
||||||
in.Disabled = nil
|
} else {
|
||||||
in.DisabledReason = ""
|
in.Disabled = nil
|
||||||
}
|
in.DisabledReason = ""
|
||||||
return in, nil
|
}
|
||||||
})
|
return in, nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to change physical interface state for %s: %w", iface.Identifier, err)
|
return fmt.Errorf("failed to change physical interface state for %s: %w", iface.Identifier, err)
|
||||||
}
|
}
|
||||||
@ -392,9 +404,9 @@ func (m Manager) DeleteInterface(ctx context.Context, id domain.InterfaceIdentif
|
|||||||
return fmt.Errorf("deletion failure: %w", err)
|
return fmt.Errorf("deletion failure: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fwMark := int(existingInterface.FirewallMark)
|
fwMark := existingInterface.FirewallMark
|
||||||
if physicalInterface != nil && fwMark == 0 {
|
if physicalInterface != nil && fwMark == 0 {
|
||||||
fwMark = int(physicalInterface.FirewallMark)
|
fwMark = physicalInterface.FirewallMark
|
||||||
}
|
}
|
||||||
m.bus.Publish(app.TopicRouteRemove, domain.RoutingTableInfo{
|
m.bus.Publish(app.TopicRouteRemove, domain.RoutingTableInfo{
|
||||||
FwMark: fwMark,
|
FwMark: fwMark,
|
||||||
@ -410,7 +422,10 @@ func (m Manager) DeleteInterface(ctx context.Context, id domain.InterfaceIdentif
|
|||||||
|
|
||||||
// region helper-functions
|
// region helper-functions
|
||||||
|
|
||||||
func (m Manager) saveInterface(ctx context.Context, iface *domain.Interface, peers []domain.Peer) (*domain.Interface, error) {
|
func (m Manager) saveInterface(ctx context.Context, iface *domain.Interface, peers []domain.Peer) (
|
||||||
|
*domain.Interface,
|
||||||
|
error,
|
||||||
|
) {
|
||||||
stateChanged := m.hasInterfaceStateChanged(ctx, iface)
|
stateChanged := m.hasInterfaceStateChanged(ctx, iface)
|
||||||
|
|
||||||
if err := m.handleInterfacePreSaveHooks(stateChanged, iface); err != nil {
|
if err := m.handleInterfacePreSaveHooks(stateChanged, iface); err != nil {
|
||||||
@ -424,10 +439,11 @@ func (m Manager) saveInterface(ctx context.Context, iface *domain.Interface, pee
|
|||||||
err := m.db.SaveInterface(ctx, iface.Identifier, func(i *domain.Interface) (*domain.Interface, error) {
|
err := m.db.SaveInterface(ctx, iface.Identifier, func(i *domain.Interface) (*domain.Interface, error) {
|
||||||
iface.CopyCalculatedAttributes(i)
|
iface.CopyCalculatedAttributes(i)
|
||||||
|
|
||||||
err := m.wg.SaveInterface(ctx, iface.Identifier, func(pi *domain.PhysicalInterface) (*domain.PhysicalInterface, error) {
|
err := m.wg.SaveInterface(ctx, iface.Identifier,
|
||||||
domain.MergeToPhysicalInterface(pi, iface)
|
func(pi *domain.PhysicalInterface) (*domain.PhysicalInterface, error) {
|
||||||
return pi, nil
|
domain.MergeToPhysicalInterface(pi, iface)
|
||||||
})
|
return pi, nil
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to save physical interface %s: %w", iface.Identifier, err)
|
return nil, fmt.Errorf("failed to save physical interface %s: %w", iface.Identifier, err)
|
||||||
}
|
}
|
||||||
@ -441,9 +457,9 @@ func (m Manager) saveInterface(ctx context.Context, iface *domain.Interface, pee
|
|||||||
m.bus.Publish(app.TopicRouteUpdate, "interface updated: "+string(iface.Identifier))
|
m.bus.Publish(app.TopicRouteUpdate, "interface updated: "+string(iface.Identifier))
|
||||||
if iface.IsDisabled() {
|
if iface.IsDisabled() {
|
||||||
physicalInterface, _ := m.wg.GetInterface(ctx, iface.Identifier)
|
physicalInterface, _ := m.wg.GetInterface(ctx, iface.Identifier)
|
||||||
fwMark := int(iface.FirewallMark)
|
fwMark := iface.FirewallMark
|
||||||
if physicalInterface != nil && fwMark == 0 {
|
if physicalInterface != nil && fwMark == 0 {
|
||||||
fwMark = int(physicalInterface.FirewallMark)
|
fwMark = physicalInterface.FirewallMark
|
||||||
}
|
}
|
||||||
m.bus.Publish(app.TopicRouteRemove, domain.RoutingTableInfo{
|
m.bus.Publish(app.TopicRouteRemove, domain.RoutingTableInfo{
|
||||||
FwMark: fwMark,
|
FwMark: fwMark,
|
||||||
@ -702,18 +718,18 @@ func (m Manager) importPeer(ctx context.Context, in *domain.Interface, p *domain
|
|||||||
}
|
}
|
||||||
|
|
||||||
peer.InterfaceIdentifier = in.Identifier
|
peer.InterfaceIdentifier = in.Identifier
|
||||||
peer.EndpointPublicKey = domain.StringConfigOption{Value: in.PublicKey, Overridable: true}
|
peer.EndpointPublicKey = domain.NewConfigOption(in.PublicKey, true)
|
||||||
peer.AllowedIPsStr = domain.StringConfigOption{Value: in.PeerDefAllowedIPsStr, Overridable: true}
|
peer.AllowedIPsStr = domain.NewConfigOption(in.PeerDefAllowedIPsStr, true)
|
||||||
peer.Interface.Addresses = p.AllowedIPs // use allowed IP's as the peer IP's TODO: Should this also match server interface address' prefix length?
|
peer.Interface.Addresses = p.AllowedIPs // use allowed IP's as the peer IP's TODO: Should this also match server interface address' prefix length?
|
||||||
peer.Interface.DnsStr = domain.StringConfigOption{Value: in.PeerDefDnsStr, Overridable: true}
|
peer.Interface.DnsStr = domain.NewConfigOption(in.PeerDefDnsStr, true)
|
||||||
peer.Interface.DnsSearchStr = domain.StringConfigOption{Value: in.PeerDefDnsSearchStr, Overridable: true}
|
peer.Interface.DnsSearchStr = domain.NewConfigOption(in.PeerDefDnsSearchStr, true)
|
||||||
peer.Interface.Mtu = domain.IntConfigOption{Value: in.PeerDefMtu, Overridable: true}
|
peer.Interface.Mtu = domain.NewConfigOption(in.PeerDefMtu, true)
|
||||||
peer.Interface.FirewallMark = domain.Int32ConfigOption{Value: in.PeerDefFirewallMark, Overridable: true}
|
peer.Interface.FirewallMark = domain.NewConfigOption(in.PeerDefFirewallMark, true)
|
||||||
peer.Interface.RoutingTable = domain.StringConfigOption{Value: in.PeerDefRoutingTable, Overridable: true}
|
peer.Interface.RoutingTable = domain.NewConfigOption(in.PeerDefRoutingTable, true)
|
||||||
peer.Interface.PreUp = domain.StringConfigOption{Value: in.PeerDefPreUp, Overridable: true}
|
peer.Interface.PreUp = domain.NewConfigOption(in.PeerDefPreUp, true)
|
||||||
peer.Interface.PostUp = domain.StringConfigOption{Value: in.PeerDefPostUp, Overridable: true}
|
peer.Interface.PostUp = domain.NewConfigOption(in.PeerDefPostUp, true)
|
||||||
peer.Interface.PreDown = domain.StringConfigOption{Value: in.PeerDefPreDown, Overridable: true}
|
peer.Interface.PreDown = domain.NewConfigOption(in.PeerDefPreDown, true)
|
||||||
peer.Interface.PostDown = domain.StringConfigOption{Value: in.PeerDefPostDown, Overridable: true}
|
peer.Interface.PostDown = domain.NewConfigOption(in.PeerDefPostDown, true)
|
||||||
|
|
||||||
switch in.Type {
|
switch in.Type {
|
||||||
case domain.InterfaceTypeAny:
|
case domain.InterfaceTypeAny:
|
||||||
|
@ -102,12 +102,12 @@ func (m Manager) PreparePeer(ctx context.Context, id domain.InterfaceIdentifier)
|
|||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
UpdatedAt: time.Now(),
|
UpdatedAt: time.Now(),
|
||||||
},
|
},
|
||||||
Endpoint: domain.NewStringConfigOption(iface.PeerDefEndpoint, true),
|
Endpoint: domain.NewConfigOption(iface.PeerDefEndpoint, true),
|
||||||
EndpointPublicKey: domain.NewStringConfigOption(iface.PublicKey, true),
|
EndpointPublicKey: domain.NewConfigOption(iface.PublicKey, true),
|
||||||
AllowedIPsStr: domain.NewStringConfigOption(iface.PeerDefAllowedIPsStr, true),
|
AllowedIPsStr: domain.NewConfigOption(iface.PeerDefAllowedIPsStr, true),
|
||||||
ExtraAllowedIPsStr: "",
|
ExtraAllowedIPsStr: "",
|
||||||
PresharedKey: pk,
|
PresharedKey: pk,
|
||||||
PersistentKeepalive: domain.NewIntConfigOption(iface.PeerDefPersistentKeepalive, true),
|
PersistentKeepalive: domain.NewConfigOption(iface.PeerDefPersistentKeepalive, true),
|
||||||
DisplayName: fmt.Sprintf("Peer %s", internal.TruncateString(string(peerId), 8)),
|
DisplayName: fmt.Sprintf("Peer %s", internal.TruncateString(string(peerId), 8)),
|
||||||
Identifier: peerId,
|
Identifier: peerId,
|
||||||
UserIdentifier: currentUser.Id,
|
UserIdentifier: currentUser.Id,
|
||||||
@ -121,15 +121,15 @@ func (m Manager) PreparePeer(ctx context.Context, id domain.InterfaceIdentifier)
|
|||||||
Type: peerMode,
|
Type: peerMode,
|
||||||
Addresses: ips,
|
Addresses: ips,
|
||||||
CheckAliveAddress: "",
|
CheckAliveAddress: "",
|
||||||
DnsStr: domain.NewStringConfigOption(iface.PeerDefDnsStr, true),
|
DnsStr: domain.NewConfigOption(iface.PeerDefDnsStr, true),
|
||||||
DnsSearchStr: domain.NewStringConfigOption(iface.PeerDefDnsSearchStr, true),
|
DnsSearchStr: domain.NewConfigOption(iface.PeerDefDnsSearchStr, true),
|
||||||
Mtu: domain.NewIntConfigOption(iface.PeerDefMtu, true),
|
Mtu: domain.NewConfigOption(iface.PeerDefMtu, true),
|
||||||
FirewallMark: domain.NewInt32ConfigOption(iface.PeerDefFirewallMark, true),
|
FirewallMark: domain.NewConfigOption(iface.PeerDefFirewallMark, true),
|
||||||
RoutingTable: domain.NewStringConfigOption(iface.PeerDefRoutingTable, true),
|
RoutingTable: domain.NewConfigOption(iface.PeerDefRoutingTable, true),
|
||||||
PreUp: domain.NewStringConfigOption(iface.PeerDefPreUp, true),
|
PreUp: domain.NewConfigOption(iface.PeerDefPreUp, true),
|
||||||
PostUp: domain.NewStringConfigOption(iface.PeerDefPostUp, true),
|
PostUp: domain.NewConfigOption(iface.PeerDefPostUp, true),
|
||||||
PreDown: domain.NewStringConfigOption(iface.PeerDefPreDown, true),
|
PreDown: domain.NewConfigOption(iface.PeerDefPreDown, true),
|
||||||
PostDown: domain.NewStringConfigOption(iface.PeerDefPostDown, true),
|
PostDown: domain.NewConfigOption(iface.PeerDefPostDown, true),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +174,11 @@ func (m Manager) CreatePeer(ctx context.Context, peer *domain.Peer) (*domain.Pee
|
|||||||
return peer, nil
|
return peer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Manager) CreateMultiplePeers(ctx context.Context, interfaceId domain.InterfaceIdentifier, r *domain.PeerCreationRequest) ([]domain.Peer, error) {
|
func (m Manager) CreateMultiplePeers(
|
||||||
|
ctx context.Context,
|
||||||
|
interfaceId domain.InterfaceIdentifier,
|
||||||
|
r *domain.PeerCreationRequest,
|
||||||
|
) ([]domain.Peer, error) {
|
||||||
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,14 @@ package domain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/h44z/wg-portal/internal"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"math"
|
"math"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/h44z/wg-portal/internal"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -34,7 +35,7 @@ type Interface struct {
|
|||||||
DnsSearchStr string // the dns search option string that should be set if the interface is up, will be appended to DnsStr
|
DnsSearchStr string // the dns search option string that should be set if the interface is up, will be appended to DnsStr
|
||||||
|
|
||||||
Mtu int // the device MTU
|
Mtu int // the device MTU
|
||||||
FirewallMark int32 // a firewall mark
|
FirewallMark uint32 // a firewall mark
|
||||||
RoutingTable string // the routing table number or "off" if the routing table should not be managed
|
RoutingTable string // the routing table number or "off" if the routing table should not be managed
|
||||||
|
|
||||||
PreUp string // action that is executed before the device is up
|
PreUp string // action that is executed before the device is up
|
||||||
@ -61,7 +62,7 @@ type Interface struct {
|
|||||||
PeerDefAllowedIPsStr string // the default allowed IP string for the peer
|
PeerDefAllowedIPsStr string // the default allowed IP string for the peer
|
||||||
PeerDefMtu int // the default device MTU
|
PeerDefMtu int // the default device MTU
|
||||||
PeerDefPersistentKeepalive int // the default persistent keep-alive Value
|
PeerDefPersistentKeepalive int // the default persistent keep-alive Value
|
||||||
PeerDefFirewallMark int32 // default firewall mark
|
PeerDefFirewallMark uint32 // default firewall mark
|
||||||
PeerDefRoutingTable string // the default routing table
|
PeerDefRoutingTable string // the default routing table
|
||||||
|
|
||||||
PeerDefPreUp string // default action that is executed before the device is up
|
PeerDefPreUp string // default action that is executed before the device is up
|
||||||
@ -161,8 +162,8 @@ type PhysicalInterface struct {
|
|||||||
|
|
||||||
Addresses []Cidr // the interface ip addresses
|
Addresses []Cidr // the interface ip addresses
|
||||||
|
|
||||||
Mtu int // the device MTU
|
Mtu int // the device MTU
|
||||||
FirewallMark int32 // a firewall mark
|
FirewallMark uint32 // a firewall mark
|
||||||
|
|
||||||
DeviceUp bool // device status
|
DeviceUp bool // device status
|
||||||
|
|
||||||
@ -223,7 +224,7 @@ func MergeToPhysicalInterface(pi *PhysicalInterface, i *Interface) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RoutingTableInfo struct {
|
type RoutingTableInfo struct {
|
||||||
FwMark int
|
FwMark uint32
|
||||||
Table int
|
Table int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +242,7 @@ func (r RoutingTableInfo) ManagementEnabled() bool {
|
|||||||
|
|
||||||
func (r RoutingTableInfo) GetRoutingTable() int {
|
func (r RoutingTableInfo) GetRoutingTable() int {
|
||||||
if r.Table <= 0 {
|
if r.Table <= 0 {
|
||||||
return r.FwMark // use the dynamic routing table which has the same number as the firewall mark
|
return int(r.FwMark) // use the dynamic routing table which has the same number as the firewall mark
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.Table
|
return r.Table
|
||||||
|
@ -1,47 +1,19 @@
|
|||||||
package domain
|
package domain
|
||||||
|
|
||||||
type StringConfigOption struct {
|
type ConfigOption[T any] struct {
|
||||||
Value string `gorm:"column:v"`
|
Value T `gorm:"column:v"`
|
||||||
Overridable bool `gorm:"column:o"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o StringConfigOption) GetValue() string {
|
|
||||||
return o.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *StringConfigOption) SetValue(value string) {
|
|
||||||
o.Value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *StringConfigOption) TrySetValue(value string) bool {
|
|
||||||
if o.Overridable {
|
|
||||||
o.Value = value
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStringConfigOption(value string, overridable bool) StringConfigOption {
|
|
||||||
return StringConfigOption{
|
|
||||||
Value: value,
|
|
||||||
Overridable: overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type IntConfigOption struct {
|
|
||||||
Value int `gorm:"column:v"`
|
|
||||||
Overridable bool `gorm:"column:o"`
|
Overridable bool `gorm:"column:o"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o IntConfigOption) GetValue() int {
|
func (o *ConfigOption[T]) GetValue() T {
|
||||||
return o.Value
|
return o.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *IntConfigOption) SetValue(value int) {
|
func (o *ConfigOption[T]) SetValue(value T) {
|
||||||
o.Value = value
|
o.Value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *IntConfigOption) TrySetValue(value int) bool {
|
func (o *ConfigOption[T]) TrySetValue(value T) bool {
|
||||||
if o.Overridable {
|
if o.Overridable {
|
||||||
o.Value = value
|
o.Value = value
|
||||||
return true
|
return true
|
||||||
@ -49,64 +21,8 @@ func (o *IntConfigOption) TrySetValue(value int) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIntConfigOption(value int, overridable bool) IntConfigOption {
|
func NewConfigOption[T any](value T, overridable bool) ConfigOption[T] {
|
||||||
return IntConfigOption{
|
return ConfigOption[T]{
|
||||||
Value: value,
|
|
||||||
Overridable: overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Int32ConfigOption struct {
|
|
||||||
Value int32 `gorm:"column:v"`
|
|
||||||
Overridable bool `gorm:"column:o"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o Int32ConfigOption) GetValue() int32 {
|
|
||||||
return o.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Int32ConfigOption) SetValue(value int32) {
|
|
||||||
o.Value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Int32ConfigOption) TrySetValue(value int32) bool {
|
|
||||||
if o.Overridable {
|
|
||||||
o.Value = value
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewInt32ConfigOption(value int32, overridable bool) Int32ConfigOption {
|
|
||||||
return Int32ConfigOption{
|
|
||||||
Value: value,
|
|
||||||
Overridable: overridable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type BoolConfigOption struct {
|
|
||||||
Value bool `gorm:"column:v"`
|
|
||||||
Overridable bool `gorm:"column:o"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o BoolConfigOption) GetValue() bool {
|
|
||||||
return o.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *BoolConfigOption) SetValue(value bool) {
|
|
||||||
o.Value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *BoolConfigOption) TrySetValue(value bool) bool {
|
|
||||||
if o.Overridable {
|
|
||||||
o.Value = value
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBoolConfigOption(value bool, overridable bool) BoolConfigOption {
|
|
||||||
return BoolConfigOption{
|
|
||||||
Value: value,
|
Value: value,
|
||||||
Overridable: overridable,
|
Overridable: overridable,
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,13 @@ package domain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/h44z/wg-portal/internal"
|
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/h44z/wg-portal/internal"
|
||||||
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,12 +32,12 @@ type Peer struct {
|
|||||||
|
|
||||||
// WireGuard specific (for the [peer] section of the config file)
|
// WireGuard specific (for the [peer] section of the config file)
|
||||||
|
|
||||||
Endpoint StringConfigOption `gorm:"embedded;embeddedPrefix:endpoint_"` // the endpoint address
|
Endpoint ConfigOption[string] `gorm:"embedded;embeddedPrefix:endpoint_"` // the endpoint address
|
||||||
EndpointPublicKey StringConfigOption `gorm:"embedded;embeddedPrefix:endpoint_pubkey_"` // the endpoint public key
|
EndpointPublicKey ConfigOption[string] `gorm:"embedded;embeddedPrefix:endpoint_pubkey_"` // the endpoint public key
|
||||||
AllowedIPsStr StringConfigOption `gorm:"embedded;embeddedPrefix:allowed_ips_str_"` // all allowed ip subnets, comma seperated
|
AllowedIPsStr ConfigOption[string] `gorm:"embedded;embeddedPrefix:allowed_ips_str_"` // all allowed ip subnets, comma seperated
|
||||||
ExtraAllowedIPsStr string // all allowed ip subnets on the server side, comma seperated
|
ExtraAllowedIPsStr string // all allowed ip subnets on the server side, comma seperated
|
||||||
PresharedKey PreSharedKey // the pre-shared Key of the peer
|
PresharedKey PreSharedKey // the pre-shared Key of the peer
|
||||||
PersistentKeepalive IntConfigOption `gorm:"embedded;embeddedPrefix:persistent_keep_alive_"` // the persistent keep-alive interval
|
PersistentKeepalive ConfigOption[int] `gorm:"embedded;embeddedPrefix:persistent_keep_alive_"` // the persistent keep-alive interval
|
||||||
|
|
||||||
// WG Portal specific
|
// WG Portal specific
|
||||||
|
|
||||||
@ -124,18 +125,18 @@ type PeerInterfaceConfig struct {
|
|||||||
|
|
||||||
Type InterfaceType `gorm:"column:iface_type"` // the interface type (server, client, any)
|
Type InterfaceType `gorm:"column:iface_type"` // the interface type (server, client, any)
|
||||||
|
|
||||||
Addresses []Cidr `gorm:"many2many:peer_addresses;"` // the interface ip addresses
|
Addresses []Cidr `gorm:"many2many:peer_addresses;"` // the interface ip addresses
|
||||||
CheckAliveAddress string `gorm:"column:check_alive_address"` // optional ip address or DNS name that is used for ping checks
|
CheckAliveAddress string `gorm:"column:check_alive_address"` // optional ip address or DNS name that is used for ping checks
|
||||||
DnsStr StringConfigOption `gorm:"embedded;embeddedPrefix:iface_dns_str_"` // the dns server that should be set if the interface is up, comma separated
|
DnsStr ConfigOption[string] `gorm:"embedded;embeddedPrefix:iface_dns_str_"` // the dns server that should be set if the interface is up, comma separated
|
||||||
DnsSearchStr StringConfigOption `gorm:"embedded;embeddedPrefix:iface_dns_search_str_"` // the dns search option string that should be set if the interface is up, will be appended to DnsStr
|
DnsSearchStr ConfigOption[string] `gorm:"embedded;embeddedPrefix:iface_dns_search_str_"` // the dns search option string that should be set if the interface is up, will be appended to DnsStr
|
||||||
Mtu IntConfigOption `gorm:"embedded;embeddedPrefix:iface_mtu_"` // the device MTU
|
Mtu ConfigOption[int] `gorm:"embedded;embeddedPrefix:iface_mtu_"` // the device MTU
|
||||||
FirewallMark Int32ConfigOption `gorm:"embedded;embeddedPrefix:iface_firewall_mark_"` // a firewall mark
|
FirewallMark ConfigOption[uint32] `gorm:"embedded;embeddedPrefix:iface_firewall_mark_"` // a firewall mark
|
||||||
RoutingTable StringConfigOption `gorm:"embedded;embeddedPrefix:iface_routing_table_"` // the routing table
|
RoutingTable ConfigOption[string] `gorm:"embedded;embeddedPrefix:iface_routing_table_"` // the routing table
|
||||||
|
|
||||||
PreUp StringConfigOption `gorm:"embedded;embeddedPrefix:iface_pre_up_"` // action that is executed before the device is up
|
PreUp ConfigOption[string] `gorm:"embedded;embeddedPrefix:iface_pre_up_"` // action that is executed before the device is up
|
||||||
PostUp StringConfigOption `gorm:"embedded;embeddedPrefix:iface_post_up_"` // action that is executed after the device is up
|
PostUp ConfigOption[string] `gorm:"embedded;embeddedPrefix:iface_post_up_"` // action that is executed after the device is up
|
||||||
PreDown StringConfigOption `gorm:"embedded;embeddedPrefix:iface_pre_down_"` // action that is executed before the device is down
|
PreDown ConfigOption[string] `gorm:"embedded;embeddedPrefix:iface_pre_down_"` // action that is executed before the device is down
|
||||||
PostDown StringConfigOption `gorm:"embedded;embeddedPrefix:iface_post_down_"` // action that is executed after the device is down
|
PostDown ConfigOption[string] `gorm:"embedded;embeddedPrefix:iface_post_down_"` // action that is executed after the device is down
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PeerInterfaceConfig) AddressStr() string {
|
func (p *PeerInterfaceConfig) AddressStr() string {
|
||||||
@ -202,12 +203,12 @@ func (p PhysicalPeer) GetAllowedIPs() []net.IPNet {
|
|||||||
|
|
||||||
func ConvertPhysicalPeer(pp *PhysicalPeer) *Peer {
|
func ConvertPhysicalPeer(pp *PhysicalPeer) *Peer {
|
||||||
peer := &Peer{
|
peer := &Peer{
|
||||||
Endpoint: StringConfigOption{Value: pp.Endpoint, Overridable: true},
|
Endpoint: NewConfigOption(pp.Endpoint, true),
|
||||||
EndpointPublicKey: StringConfigOption{Value: "", Overridable: true},
|
EndpointPublicKey: NewConfigOption("", true),
|
||||||
AllowedIPsStr: StringConfigOption{Value: "", Overridable: true},
|
AllowedIPsStr: NewConfigOption("", true),
|
||||||
ExtraAllowedIPsStr: "",
|
ExtraAllowedIPsStr: "",
|
||||||
PresharedKey: pp.PresharedKey,
|
PresharedKey: pp.PresharedKey,
|
||||||
PersistentKeepalive: IntConfigOption{Value: pp.PersistentKeepalive, Overridable: true},
|
PersistentKeepalive: NewConfigOption(pp.PersistentKeepalive, true),
|
||||||
DisplayName: string(pp.Identifier),
|
DisplayName: string(pp.Identifier),
|
||||||
Identifier: pp.Identifier,
|
Identifier: pp.Identifier,
|
||||||
UserIdentifier: "",
|
UserIdentifier: "",
|
||||||
|
Loading…
Reference in New Issue
Block a user