mirror of
https://github.com/h44z/wg-portal.git
synced 2025-09-15 07:11:15 +00:00
Mikrotik integration (#467)
Allow MikroTik routes as WireGuard backends
This commit is contained in:
94
internal/config/backend.go
Normal file
94
internal/config/backend.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const LocalBackendName = "local"
|
||||
|
||||
type Backend struct {
|
||||
Default string `yaml:"default"` // The default backend to use (defaults to the internal backend)
|
||||
|
||||
Mikrotik []BackendMikrotik `yaml:"mikrotik"`
|
||||
}
|
||||
|
||||
// Validate checks the backend configuration for errors.
|
||||
func (b *Backend) Validate() error {
|
||||
if b.Default == "" {
|
||||
b.Default = LocalBackendName
|
||||
}
|
||||
|
||||
uniqueMap := make(map[string]struct{})
|
||||
for _, backend := range b.Mikrotik {
|
||||
if backend.Id == LocalBackendName {
|
||||
return fmt.Errorf("backend ID %q is a reserved keyword", LocalBackendName)
|
||||
}
|
||||
if _, exists := uniqueMap[backend.Id]; exists {
|
||||
return fmt.Errorf("backend ID %q is not unique", backend.Id)
|
||||
}
|
||||
uniqueMap[backend.Id] = struct{}{}
|
||||
}
|
||||
|
||||
if b.Default != LocalBackendName {
|
||||
if _, ok := uniqueMap[b.Default]; !ok {
|
||||
return fmt.Errorf("default backend %q is not defined in the configuration", b.Default)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type BackendBase struct {
|
||||
Id string `yaml:"id"` // A unique id for the backend
|
||||
DisplayName string `yaml:"display_name"` // A display name for the backend
|
||||
}
|
||||
|
||||
// GetDisplayName returns the display name of the backend.
|
||||
// If no display name is set, it falls back to the ID.
|
||||
func (b BackendBase) GetDisplayName() string {
|
||||
if b.DisplayName == "" {
|
||||
return b.Id // Fallback to ID if no display name is set
|
||||
}
|
||||
return b.DisplayName
|
||||
}
|
||||
|
||||
type BackendMikrotik struct {
|
||||
BackendBase `yaml:",inline"` // Embed the base fields
|
||||
|
||||
ApiUrl string `yaml:"api_url"` // The base URL of the Mikrotik API (e.g., "https://10.10.10.10:8729/rest")
|
||||
ApiUser string `yaml:"api_user"`
|
||||
ApiPassword string `yaml:"api_password"`
|
||||
ApiVerifyTls bool `yaml:"api_verify_tls"` // Whether to verify the TLS certificate of the Mikrotik API
|
||||
ApiTimeout time.Duration `yaml:"api_timeout"` // Timeout for API requests (default: 30 seconds)
|
||||
|
||||
// Concurrency controls the maximum number of concurrent API requests that this backend will issue
|
||||
// when enumerating interfaces and their details. If 0 or negative, a default of 5 is used.
|
||||
Concurrency int `yaml:"concurrency"`
|
||||
|
||||
Debug bool `yaml:"debug"` // Enable debug logging for the Mikrotik backend
|
||||
}
|
||||
|
||||
// GetConcurrency returns the configured concurrency for this backend or a sane default (5)
|
||||
// when the configured value is zero or negative.
|
||||
func (b *BackendMikrotik) GetConcurrency() int {
|
||||
if b == nil {
|
||||
return 5
|
||||
}
|
||||
if b.Concurrency <= 0 {
|
||||
return 5
|
||||
}
|
||||
return b.Concurrency
|
||||
}
|
||||
|
||||
// GetApiTimeout returns the configured API timeout or a sane default (30 seconds)
|
||||
// when the configured value is zero or negative.
|
||||
func (b *BackendMikrotik) GetApiTimeout() time.Duration {
|
||||
if b == nil {
|
||||
return 30 * time.Second
|
||||
}
|
||||
if b.ApiTimeout <= 0 {
|
||||
return 30 * time.Second
|
||||
}
|
||||
return b.ApiTimeout
|
||||
}
|
@@ -44,6 +44,8 @@ type Config struct {
|
||||
LimitAdditionalUserPeers int `yaml:"limit_additional_user_peers"`
|
||||
} `yaml:"advanced"`
|
||||
|
||||
Backend Backend `yaml:"backend"`
|
||||
|
||||
Statistics struct {
|
||||
UsePingChecks bool `yaml:"use_ping_checks"`
|
||||
PingCheckWorkers int `yaml:"ping_check_workers"`
|
||||
@@ -99,6 +101,12 @@ func (c *Config) LogStartupValues() {
|
||||
"minPasswordLength", c.Auth.MinPasswordLength,
|
||||
"hideLoginForm", c.Auth.HideLoginForm,
|
||||
)
|
||||
|
||||
slog.Debug("Config Backend",
|
||||
"defaultBackend", c.Backend.Default,
|
||||
"extraBackends", len(c.Backend.Mikrotik),
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
// defaultConfig returns the default configuration
|
||||
@@ -122,6 +130,10 @@ func defaultConfig() *Config {
|
||||
DSN: "data/sqlite.db",
|
||||
}
|
||||
|
||||
cfg.Backend = Backend{
|
||||
Default: LocalBackendName, // local backend is the default (using wgcrtl)
|
||||
}
|
||||
|
||||
cfg.Web = WebConfig{
|
||||
RequestLogging: false,
|
||||
ExternalUrl: "http://localhost:8888",
|
||||
@@ -201,6 +213,10 @@ func GetConfig() (*Config, error) {
|
||||
}
|
||||
|
||||
cfg.Web.Sanitize()
|
||||
err := cfg.Backend.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user