fix: address code review findings for DNS management
- CRITICAL: Change DNS zones endpoint from GET to POST to avoid leaking API token in URL query parameters - HIGH: Add sync.RWMutex to protect dnsProvider field in Server, Deployer, and proxy Manager against concurrent read/write races - HIGH: Capture old DNS provider reference synchronously before launching background cleanup goroutine - HIGH: Use getDNS()/getDNSProviderLocked() accessors instead of direct field reads in all DNS operations
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"sync"
|
||||
|
||||
"github.com/alexei/docker-watcher/internal/dns"
|
||||
"github.com/alexei/docker-watcher/internal/npm"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
type Manager struct {
|
||||
store *store.Store
|
||||
npm *npm.Client
|
||||
dnsMu sync.RWMutex
|
||||
dns dns.Provider // nil when wildcard DNS is active
|
||||
}
|
||||
|
||||
@@ -28,9 +30,18 @@ func NewManager(st *store.Store, npmClient *npm.Client) *Manager {
|
||||
|
||||
// SetDNSProvider sets the DNS provider for managing DNS records.
|
||||
func (m *Manager) SetDNSProvider(provider dns.Provider) {
|
||||
m.dnsMu.Lock()
|
||||
defer m.dnsMu.Unlock()
|
||||
m.dns = provider
|
||||
}
|
||||
|
||||
// getDNS returns the current DNS provider under read lock.
|
||||
func (m *Manager) getDNS() dns.Provider {
|
||||
m.dnsMu.RLock()
|
||||
defer m.dnsMu.RUnlock()
|
||||
return m.dns
|
||||
}
|
||||
|
||||
// CreateProxyRequest is the input for creating a standalone proxy.
|
||||
type CreateProxyRequest struct {
|
||||
Domain string `json:"domain"`
|
||||
@@ -315,7 +326,8 @@ func (m *Manager) ListAllProxies() ([]ProxyView, error) {
|
||||
|
||||
// ensureDNS creates or updates a DNS record for a standalone proxy domain. Best-effort.
|
||||
func (m *Manager) ensureDNS(ctx context.Context, domain, proxyID string) {
|
||||
if m.dns == nil {
|
||||
dnsProvider := m.getDNS()
|
||||
if dnsProvider == nil {
|
||||
return
|
||||
}
|
||||
settings, err := m.store.GetSettings()
|
||||
@@ -328,7 +340,7 @@ func (m *Manager) ensureDNS(ctx context.Context, domain, proxyID string) {
|
||||
return
|
||||
}
|
||||
|
||||
recordID, err := m.dns.EnsureRecord(ctx, domain, settings.ServerIP)
|
||||
recordID, err := dnsProvider.EnsureRecord(ctx, domain, settings.ServerIP)
|
||||
if err != nil {
|
||||
slog.Warn("dns: failed to create/update record for standalone proxy", "domain", domain, "error", err)
|
||||
return
|
||||
@@ -350,10 +362,11 @@ func (m *Manager) ensureDNS(ctx context.Context, domain, proxyID string) {
|
||||
|
||||
// removeDNS deletes a DNS record for a standalone proxy domain. Best-effort.
|
||||
func (m *Manager) removeDNS(ctx context.Context, domain string) {
|
||||
if m.dns == nil {
|
||||
dnsProvider := m.getDNS()
|
||||
if dnsProvider == nil {
|
||||
return
|
||||
}
|
||||
if err := m.dns.DeleteRecord(ctx, domain); err != nil {
|
||||
if err := dnsProvider.DeleteRecord(ctx, domain); err != nil {
|
||||
slog.Warn("dns: failed to delete record for standalone proxy", "domain", domain, "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user