mirror of
https://github.com/h44z/wg-portal.git
synced 2025-06-28 01:07:03 +00:00
prepare frontend for different WireGuard backends (#426)
This commit is contained in:
parent
7fd2bbad02
commit
33dcc80078
@ -10,11 +10,13 @@ import isCidr from "is-cidr";
|
|||||||
import {isIP} from 'is-ip';
|
import {isIP} from 'is-ip';
|
||||||
import { freshInterface } from '@/helpers/models';
|
import { freshInterface } from '@/helpers/models';
|
||||||
import {peerStore} from "@/stores/peers";
|
import {peerStore} from "@/stores/peers";
|
||||||
|
import {settingsStore} from "@/stores/settings";
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const interfaces = interfaceStore()
|
const interfaces = interfaceStore()
|
||||||
const peers = peerStore()
|
const peers = peerStore()
|
||||||
|
const settings = settingsStore()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
interfaceId: String,
|
interfaceId: String,
|
||||||
@ -314,13 +316,21 @@ async function del() {
|
|||||||
<label class="form-label mt-4">{{ $t('modals.interface-edit.identifier.label') }}</label>
|
<label class="form-label mt-4">{{ $t('modals.interface-edit.identifier.label') }}</label>
|
||||||
<input v-model="formData.Identifier" class="form-control" :placeholder="$t('modals.interface-edit.identifier.placeholder')" type="text">
|
<input v-model="formData.Identifier" class="form-control" :placeholder="$t('modals.interface-edit.identifier.placeholder')" type="text">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="row">
|
||||||
<label class="form-label mt-4">{{ $t('modals.interface-edit.mode.label') }}</label>
|
<div class="form-group col-md-6">
|
||||||
<select v-model="formData.Mode" class="form-select">
|
<label class="form-label mt-4">{{ $t('modals.interface-edit.mode.label') }}</label>
|
||||||
<option value="server">{{ $t('modals.interface-edit.mode.server') }}</option>
|
<select v-model="formData.Mode" class="form-select">
|
||||||
<option value="client">{{ $t('modals.interface-edit.mode.client') }}</option>
|
<option value="server">{{ $t('modals.interface-edit.mode.server') }}</option>
|
||||||
<option value="any">{{ $t('modals.interface-edit.mode.any') }}</option>
|
<option value="client">{{ $t('modals.interface-edit.mode.client') }}</option>
|
||||||
</select>
|
<option value="any">{{ $t('modals.interface-edit.mode.any') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label class="form-label mt-4">{{ $t('modals.interface-edit.backend.label') }}</label>
|
||||||
|
<select v-model="formData.Backend" class="form-select">
|
||||||
|
<option v-for="backend in settings.Setting('AvailableBackends')" :value="backend.Id">{{ backend.Id === 'local' ? $t(backend.Name) : backend.Name }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label mt-4">{{ $t('modals.interface-edit.display-name.label') }}</label>
|
<label class="form-label mt-4">{{ $t('modals.interface-edit.display-name.label') }}</label>
|
||||||
@ -385,12 +395,14 @@ async function del() {
|
|||||||
<label class="form-label mt-4">{{ $t('modals.interface-edit.mtu.label') }}</label>
|
<label class="form-label mt-4">{{ $t('modals.interface-edit.mtu.label') }}</label>
|
||||||
<input v-model="formData.Mtu" class="form-control" :placeholder="$t('modals.interface-edit.mtu.placeholder')" type="number">
|
<input v-model="formData.Mtu" class="form-control" :placeholder="$t('modals.interface-edit.mtu.placeholder')" type="number">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6" v-if="formData.Backend==='local'">
|
||||||
<label class="form-label mt-4">{{ $t('modals.interface-edit.firewall-mark.label') }}</label>
|
<label class="form-label mt-4">{{ $t('modals.interface-edit.firewall-mark.label') }}</label>
|
||||||
<input v-model="formData.FirewallMark" class="form-control" :placeholder="$t('modals.interface-edit.firewall-mark.placeholder')" type="number">
|
<input v-model="formData.FirewallMark" class="form-control" :placeholder="$t('modals.interface-edit.firewall-mark.placeholder')" type="number">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group col-md-6" v-else>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row" v-if="formData.Backend==='local'">
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label class="form-label mt-4">{{ $t('modals.interface-edit.routing-table.label') }}</label>
|
<label class="form-label mt-4">{{ $t('modals.interface-edit.routing-table.label') }}</label>
|
||||||
<input v-model="formData.RoutingTable" aria-describedby="routingTableHelp" class="form-control" :placeholder="$t('modals.interface-edit.routing-table.placeholder')" type="text">
|
<input v-model="formData.RoutingTable" aria-describedby="routingTableHelp" class="form-control" :placeholder="$t('modals.interface-edit.routing-table.placeholder')" type="text">
|
||||||
|
@ -5,6 +5,7 @@ export function freshInterface() {
|
|||||||
DisplayName: "",
|
DisplayName: "",
|
||||||
Identifier: "",
|
Identifier: "",
|
||||||
Mode: "server",
|
Mode: "server",
|
||||||
|
Backend: "local",
|
||||||
|
|
||||||
PublicKey: "",
|
PublicKey: "",
|
||||||
PrivateKey: "",
|
PrivateKey: "",
|
||||||
|
@ -102,7 +102,7 @@
|
|||||||
},
|
},
|
||||||
"interface": {
|
"interface": {
|
||||||
"headline": "Schnittstellenstatus für",
|
"headline": "Schnittstellenstatus für",
|
||||||
"mode": "Modus",
|
"backend": "Backend",
|
||||||
"key": "Öffentlicher Schlüssel",
|
"key": "Öffentlicher Schlüssel",
|
||||||
"endpoint": "Öffentlicher Endpunkt",
|
"endpoint": "Öffentlicher Endpunkt",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
|
@ -102,7 +102,7 @@
|
|||||||
},
|
},
|
||||||
"interface": {
|
"interface": {
|
||||||
"headline": "Interface status for",
|
"headline": "Interface status for",
|
||||||
"mode": "mode",
|
"backend": "Backend",
|
||||||
"key": "Public Key",
|
"key": "Public Key",
|
||||||
"endpoint": "Public Endpoint",
|
"endpoint": "Public Endpoint",
|
||||||
"port": "Listening Port",
|
"port": "Listening Port",
|
||||||
@ -357,6 +357,10 @@
|
|||||||
"client": "Client Mode",
|
"client": "Client Mode",
|
||||||
"any": "Unknown Mode"
|
"any": "Unknown Mode"
|
||||||
},
|
},
|
||||||
|
"backend": {
|
||||||
|
"label": "Interface Backend",
|
||||||
|
"local": "Local WireGuard Backend"
|
||||||
|
},
|
||||||
"display-name": {
|
"display-name": {
|
||||||
"label": "Display Name",
|
"label": "Display Name",
|
||||||
"placeholder": "The descriptive name for the interface"
|
"placeholder": "The descriptive name for the interface"
|
||||||
|
@ -99,7 +99,7 @@
|
|||||||
},
|
},
|
||||||
"interface": {
|
"interface": {
|
||||||
"headline": "État de l'interface pour",
|
"headline": "État de l'interface pour",
|
||||||
"mode": "mode",
|
"backend": "backend",
|
||||||
"key": "Clé publique",
|
"key": "Clé publique",
|
||||||
"endpoint": "Point de terminaison public",
|
"endpoint": "Point de terminaison public",
|
||||||
"port": "Port d'écoute",
|
"port": "Port d'écoute",
|
||||||
|
@ -100,7 +100,7 @@
|
|||||||
},
|
},
|
||||||
"interface": {
|
"interface": {
|
||||||
"headline": "인터페이스 상태:",
|
"headline": "인터페이스 상태:",
|
||||||
"mode": "모드",
|
"backend": "백엔드",
|
||||||
"key": "공개 키",
|
"key": "공개 키",
|
||||||
"endpoint": "공개 엔드포인트",
|
"endpoint": "공개 엔드포인트",
|
||||||
"port": "수신 포트",
|
"port": "수신 포트",
|
||||||
|
@ -101,7 +101,7 @@
|
|||||||
},
|
},
|
||||||
"interface": {
|
"interface": {
|
||||||
"headline": "Status da interface para",
|
"headline": "Status da interface para",
|
||||||
"mode": "modo",
|
"mode": "backend",
|
||||||
"key": "Chave Pública",
|
"key": "Chave Pública",
|
||||||
"endpoint": "Endpoint Público",
|
"endpoint": "Endpoint Público",
|
||||||
"port": "Porta de Escuta",
|
"port": "Porta de Escuta",
|
||||||
|
@ -99,7 +99,7 @@
|
|||||||
},
|
},
|
||||||
"interface": {
|
"interface": {
|
||||||
"headline": "Статус интерфейса для",
|
"headline": "Статус интерфейса для",
|
||||||
"mode": "режим",
|
"backend": "бэкэнд",
|
||||||
"key": "Публичный ключ",
|
"key": "Публичный ключ",
|
||||||
"endpoint": "Публичная конечная точка",
|
"endpoint": "Публичная конечная точка",
|
||||||
"port": "Порт прослушивания",
|
"port": "Порт прослушивания",
|
||||||
|
@ -99,7 +99,7 @@
|
|||||||
},
|
},
|
||||||
"interface": {
|
"interface": {
|
||||||
"headline": "Статус інтерфейсу для",
|
"headline": "Статус інтерфейсу для",
|
||||||
"mode": "режим",
|
"backend": "бекенд",
|
||||||
"key": "Публічний ключ",
|
"key": "Публічний ключ",
|
||||||
"endpoint": "Публічна кінцева точка",
|
"endpoint": "Публічна кінцева точка",
|
||||||
"port": "Порт прослуховування",
|
"port": "Порт прослуховування",
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
},
|
},
|
||||||
"interface": {
|
"interface": {
|
||||||
"headline": "Trạng thái giao diện cho",
|
"headline": "Trạng thái giao diện cho",
|
||||||
"mode": "chế độ",
|
"backend": "phần sau",
|
||||||
"key": "Khóa Công khai",
|
"key": "Khóa Công khai",
|
||||||
"endpoint": "Điểm cuối Công khai",
|
"endpoint": "Điểm cuối Công khai",
|
||||||
"port": "Cổng Nghe",
|
"port": "Cổng Nghe",
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
},
|
},
|
||||||
"interface": {
|
"interface": {
|
||||||
"headline": "接口状态",
|
"headline": "接口状态",
|
||||||
"mode": "模式",
|
"backend": "后端",
|
||||||
"key": "公钥",
|
"key": "公钥",
|
||||||
"endpoint": "公开节点",
|
"endpoint": "公开节点",
|
||||||
"port": "监听端口",
|
"port": "监听端口",
|
||||||
|
@ -5,17 +5,20 @@ import PeerMultiCreateModal from "../components/PeerMultiCreateModal.vue";
|
|||||||
import InterfaceEditModal from "../components/InterfaceEditModal.vue";
|
import InterfaceEditModal from "../components/InterfaceEditModal.vue";
|
||||||
import InterfaceViewModal from "../components/InterfaceViewModal.vue";
|
import InterfaceViewModal from "../components/InterfaceViewModal.vue";
|
||||||
|
|
||||||
import {onMounted, ref} from "vue";
|
import {computed, onMounted, ref} from "vue";
|
||||||
import {peerStore} from "@/stores/peers";
|
import {peerStore} from "@/stores/peers";
|
||||||
import {interfaceStore} from "@/stores/interfaces";
|
import {interfaceStore} from "@/stores/interfaces";
|
||||||
import {notify} from "@kyvg/vue3-notification";
|
import {notify} from "@kyvg/vue3-notification";
|
||||||
import {settingsStore} from "@/stores/settings";
|
import {settingsStore} from "@/stores/settings";
|
||||||
import {humanFileSize} from '@/helpers/utils';
|
import {humanFileSize} from '@/helpers/utils';
|
||||||
|
import {useI18n} from "vue-i18n";
|
||||||
|
|
||||||
const settings = settingsStore()
|
const settings = settingsStore()
|
||||||
const interfaces = interfaceStore()
|
const interfaces = interfaceStore()
|
||||||
const peers = peerStore()
|
const peers = peerStore()
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
const viewedPeerId = ref("")
|
const viewedPeerId = ref("")
|
||||||
const editPeerId = ref("")
|
const editPeerId = ref("")
|
||||||
const multiCreatePeerId = ref("")
|
const multiCreatePeerId = ref("")
|
||||||
@ -45,6 +48,20 @@ function calculateInterfaceName(id, name) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calculateBackendName = computed(() => {
|
||||||
|
let backendId = interfaces.GetSelected.Backend
|
||||||
|
|
||||||
|
let backendName = "Unknown"
|
||||||
|
let availableBackends = settings.Setting('AvailableBackends') || []
|
||||||
|
availableBackends.forEach(backend => {
|
||||||
|
if (backend.Id === backendId) {
|
||||||
|
backendName = backend.Id === 'local' ? t(backend.Name) : backend.Name
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return backendName
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
async function download() {
|
async function download() {
|
||||||
await interfaces.LoadInterfaceConfig(interfaces.GetSelected.Identifier)
|
await interfaces.LoadInterfaceConfig(interfaces.GetSelected.Identifier)
|
||||||
|
|
||||||
@ -141,7 +158,7 @@ onMounted(async () => {
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-lg-8">
|
<div class="col-12 col-lg-8">
|
||||||
{{ $t('interfaces.interface.headline') }} <strong>{{interfaces.GetSelected.Identifier}}</strong> ({{interfaces.GetSelected.Mode}} {{ $t('interfaces.interface.mode') }})
|
{{ $t('interfaces.interface.headline') }} <strong>{{interfaces.GetSelected.Identifier}}</strong> ({{ $t('modals.interface-edit.mode.' + interfaces.GetSelected.Mode )}} | {{ $t('interfaces.interface.backend') + ": " + calculateBackendName }})
|
||||||
<span v-if="interfaces.GetSelected.Disabled" class="text-danger"><i class="fa fa-circle-xmark" :title="interfaces.GetSelected.DisabledReason"></i></span>
|
<span v-if="interfaces.GetSelected.Disabled" class="text-danger"><i class="fa fa-circle-xmark" :title="interfaces.GetSelected.DisabledReason"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-lg-4 text-lg-end">
|
<div class="col-12 col-lg-4 text-lg-end">
|
||||||
|
@ -96,10 +96,29 @@ func (e ConfigEndpoint) handleSettingsGet() http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
sessionUser := domain.GetUserInfo(r.Context())
|
sessionUser := domain.GetUserInfo(r.Context())
|
||||||
|
|
||||||
|
nameFn := func(backend config.Backend) []model.SettingsBackendNames {
|
||||||
|
names := make([]model.SettingsBackendNames, 0, len(backend.Mikrotik)+1)
|
||||||
|
|
||||||
|
names = append(names, model.SettingsBackendNames{
|
||||||
|
Id: backend.Default,
|
||||||
|
Name: "modals.interface-edit.backend.local",
|
||||||
|
})
|
||||||
|
for _, b := range backend.Mikrotik {
|
||||||
|
names = append(names, model.SettingsBackendNames{
|
||||||
|
Id: b.Id,
|
||||||
|
Name: b.DisplayName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return names
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// For anonymous users, we return the settings object with minimal information
|
// For anonymous users, we return the settings object with minimal information
|
||||||
if sessionUser.Id == domain.CtxUnknownUserId || sessionUser.Id == "" {
|
if sessionUser.Id == domain.CtxUnknownUserId || sessionUser.Id == "" {
|
||||||
respond.JSON(w, http.StatusOK, model.Settings{
|
respond.JSON(w, http.StatusOK, model.Settings{
|
||||||
WebAuthnEnabled: e.cfg.Auth.WebAuthn.Enabled,
|
WebAuthnEnabled: e.cfg.Auth.WebAuthn.Enabled,
|
||||||
|
AvailableBackends: []model.SettingsBackendNames{}, // return an empty list instead of null
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
respond.JSON(w, http.StatusOK, model.Settings{
|
respond.JSON(w, http.StatusOK, model.Settings{
|
||||||
@ -109,6 +128,7 @@ func (e ConfigEndpoint) handleSettingsGet() http.HandlerFunc {
|
|||||||
ApiAdminOnly: e.cfg.Advanced.ApiAdminOnly,
|
ApiAdminOnly: e.cfg.Advanced.ApiAdminOnly,
|
||||||
WebAuthnEnabled: e.cfg.Auth.WebAuthn.Enabled,
|
WebAuthnEnabled: e.cfg.Auth.WebAuthn.Enabled,
|
||||||
MinPasswordLength: e.cfg.Auth.MinPasswordLength,
|
MinPasswordLength: e.cfg.Auth.MinPasswordLength,
|
||||||
|
AvailableBackends: nameFn(e.cfg.Backend),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,16 @@ type Error struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
MailLinkOnly bool `json:"MailLinkOnly"`
|
MailLinkOnly bool `json:"MailLinkOnly"`
|
||||||
PersistentConfigSupported bool `json:"PersistentConfigSupported"`
|
PersistentConfigSupported bool `json:"PersistentConfigSupported"`
|
||||||
SelfProvisioning bool `json:"SelfProvisioning"`
|
SelfProvisioning bool `json:"SelfProvisioning"`
|
||||||
ApiAdminOnly bool `json:"ApiAdminOnly"`
|
ApiAdminOnly bool `json:"ApiAdminOnly"`
|
||||||
WebAuthnEnabled bool `json:"WebAuthnEnabled"`
|
WebAuthnEnabled bool `json:"WebAuthnEnabled"`
|
||||||
MinPasswordLength int `json:"MinPasswordLength"`
|
MinPasswordLength int `json:"MinPasswordLength"`
|
||||||
|
AvailableBackends []SettingsBackendNames `json:"AvailableBackends"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SettingsBackendNames struct {
|
||||||
|
Id string `json:"Id"`
|
||||||
|
Name string `json:"Name"`
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/h44z/wg-portal/internal"
|
"github.com/h44z/wg-portal/internal"
|
||||||
|
"github.com/h44z/wg-portal/internal/config"
|
||||||
"github.com/h44z/wg-portal/internal/domain"
|
"github.com/h44z/wg-portal/internal/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ type Interface struct {
|
|||||||
Identifier string `json:"Identifier" example:"wg0"` // device name, for example: wg0
|
Identifier string `json:"Identifier" example:"wg0"` // device name, for example: wg0
|
||||||
DisplayName string `json:"DisplayName"` // a nice display name/ description for the interface
|
DisplayName string `json:"DisplayName"` // a nice display name/ description for the interface
|
||||||
Mode string `json:"Mode" example:"server"` // the interface type, either 'server', 'client' or 'any'
|
Mode string `json:"Mode" example:"server"` // the interface type, either 'server', 'client' or 'any'
|
||||||
|
Backend string `json:"Backend" example:"local"` // the backend used for this interface e.g., local, mikrotik, ...
|
||||||
PrivateKey string `json:"PrivateKey" example:"abcdef=="` // private Key of the server interface
|
PrivateKey string `json:"PrivateKey" example:"abcdef=="` // private Key of the server interface
|
||||||
PublicKey string `json:"PublicKey" example:"abcdef=="` // public Key of the server interface
|
PublicKey string `json:"PublicKey" example:"abcdef=="` // public Key of the server interface
|
||||||
Disabled bool `json:"Disabled"` // flag that specifies if the interface is enabled (up) or not (down)
|
Disabled bool `json:"Disabled"` // flag that specifies if the interface is enabled (up) or not (down)
|
||||||
@ -57,6 +59,7 @@ func NewInterface(src *domain.Interface, peers []domain.Peer) *Interface {
|
|||||||
Identifier: string(src.Identifier),
|
Identifier: string(src.Identifier),
|
||||||
DisplayName: src.DisplayName,
|
DisplayName: src.DisplayName,
|
||||||
Mode: string(src.Type),
|
Mode: string(src.Type),
|
||||||
|
Backend: config.LocalBackendName, // TODO: add backend support
|
||||||
PrivateKey: src.PrivateKey,
|
PrivateKey: src.PrivateKey,
|
||||||
PublicKey: src.PublicKey,
|
PublicKey: src.PublicKey,
|
||||||
Disabled: src.IsDisabled(),
|
Disabled: src.IsDisabled(),
|
||||||
|
48
internal/config/backend.go
Normal file
48
internal/config/backend.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
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 BackendMikrotik struct {
|
||||||
|
Id string `yaml:"id"` // A unique id for the Mikrotik backend
|
||||||
|
DisplayName string `yaml:"display_name"` // A display name for the Mikrotik backend
|
||||||
|
|
||||||
|
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"`
|
||||||
|
}
|
@ -43,6 +43,8 @@ type Config struct {
|
|||||||
ApiAdminOnly bool `yaml:"api_admin_only"` // if true, only admin users can access the API
|
ApiAdminOnly bool `yaml:"api_admin_only"` // if true, only admin users can access the API
|
||||||
} `yaml:"advanced"`
|
} `yaml:"advanced"`
|
||||||
|
|
||||||
|
Backend Backend `yaml:"backend"`
|
||||||
|
|
||||||
Statistics struct {
|
Statistics struct {
|
||||||
UsePingChecks bool `yaml:"use_ping_checks"`
|
UsePingChecks bool `yaml:"use_ping_checks"`
|
||||||
PingCheckWorkers int `yaml:"ping_check_workers"`
|
PingCheckWorkers int `yaml:"ping_check_workers"`
|
||||||
@ -94,6 +96,12 @@ func (c *Config) LogStartupValues() {
|
|||||||
"oauthProviders", len(c.Auth.OAuth),
|
"oauthProviders", len(c.Auth.OAuth),
|
||||||
"ldapProviders", len(c.Auth.Ldap),
|
"ldapProviders", len(c.Auth.Ldap),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
slog.Debug("Config Backend",
|
||||||
|
"defaultBackend", c.Backend.Default,
|
||||||
|
"extraBackends", len(c.Backend.Mikrotik),
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultConfig returns the default configuration
|
// defaultConfig returns the default configuration
|
||||||
@ -117,6 +125,10 @@ func defaultConfig() *Config {
|
|||||||
DSN: "data/sqlite.db",
|
DSN: "data/sqlite.db",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg.Backend = Backend{
|
||||||
|
Default: LocalBackendName, // local backend is the default (using wgcrtl)
|
||||||
|
}
|
||||||
|
|
||||||
cfg.Web = WebConfig{
|
cfg.Web = WebConfig{
|
||||||
RequestLogging: false,
|
RequestLogging: false,
|
||||||
ExternalUrl: "http://localhost:8888",
|
ExternalUrl: "http://localhost:8888",
|
||||||
@ -194,6 +206,10 @@ func GetConfig() (*Config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cfg.Web.Sanitize()
|
cfg.Web.Sanitize()
|
||||||
|
err := cfg.Backend.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user