Add read-only support and UI indicators for MikroTik dynamic peers (#733)
Docker / Build and Push (push) Canceled after 0s
github-pages / deploy (push) Canceled after 0s
Test / make test (push) Canceled after 0s
Docker / release (push) Canceled after 0s

* Add dynamic Mikrotik peer support & UI/i18n

Introduce handling for dynamically created Mikrotik peers: add Dynamic/IsDynamic fields to domain, peer and interface models and API models; include "dynamic" in Mikrotik queries; skip updates/deletes for dynamic peers; sync dynamic flag when restoring state. Prevent modifying/deleting dynamic peers in manager. UI: disable selection/edit for dynamic peers and show badge. Implement Mikrotik interface hook execution. Add i18n keys/translations for dynamic-peer messages across languages.

* Fix Mikrotik hooks implementation and UI visibility
This commit is contained in:
Ondřej Zmatlík
2026-08-27 09:47:23 +02:00
committed by GitHub
parent 4a9bcd1b82
commit 87aef1c8ff
25 changed files with 1121 additions and 990 deletions
+1
View File
@@ -22,6 +22,7 @@ type MikrotikPeerExtras struct {
Comment string
IsResponder bool
Disabled bool
Dynamic bool
ClientEndpoint string
ClientAddress string
ClientDns string
+2
View File
@@ -58,6 +58,8 @@ type Interface struct {
CreateDefaultPeer bool // if true, default peers will be created for this interface
Backend InterfaceBackend // the backend that is used to manage the interface (wgctrl, mikrotik, ...)
DriverType string // the interface driver type (linux, software, ...)
IsDynamic bool `gorm:"column:is_dynamic;default:false"` // specifies if the interface is a dynamic object
Disabled *time.Time `gorm:"index"` // flag that specifies if the interface is enabled (up) or not (down)
DisabledReason string // the reason why the interface has been disabled
+5
View File
@@ -56,6 +56,8 @@ type Peer struct {
// Interface settings for the peer, used to generate the [interface] section in the peer config file
Interface PeerInterfaceConfig `gorm:"embedded"`
IsDynamic bool `gorm:"column:is_dynamic;default:false"` // specifies if the peer is a dynamic object (from Mikrotik)
}
func (p *Peer) IsDisabled() bool {
@@ -264,6 +266,7 @@ func ConvertPhysicalPeer(pp *PhysicalPeer) *Peer {
Interface: PeerInterfaceConfig{
KeyPair: pp.KeyPair,
},
IsDynamic: false,
}
if pp.GetExtras() == nil {
@@ -277,6 +280,7 @@ func ConvertPhysicalPeer(pp *PhysicalPeer) *Peer {
extras := pp.GetExtras().(MikrotikPeerExtras)
peer.Notes = extras.Comment
peer.DisplayName = extras.Name
peer.IsDynamic = extras.Dynamic
if extras.ClientEndpoint != "" { // if the client endpoint is set, we assume that this is a client peer
peer.Endpoint = NewConfigOption(extras.ClientEndpoint, true)
peer.Interface.Type = InterfaceTypeClient
@@ -369,6 +373,7 @@ func MergeToPhysicalPeer(pp *PhysicalPeer, p *Peer) {
ClientAddress: CidrsToString(p.Interface.Addresses),
ClientDns: p.Interface.DnsStr.GetValue(),
ClientKeepalive: p.PersistentKeepalive.GetValue(),
Dynamic: p.IsDynamic,
}
pp.SetExtras(extras)
case ControllerTypeLocal: