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:
2026-04-02 14:54:15 +03:00
parent c730cfaa45
commit 670948f113
243 changed files with 15971 additions and 535 deletions
+16 -4
View File
@@ -33,6 +33,7 @@ type Deployer struct {
notifier *notify.Notifier
eventBus EventPublisher
encKey [32]byte
dnsMu sync.RWMutex
dns dns.Provider // nil when wildcard DNS is active
// Graceful shutdown: tracks in-progress deploys.
@@ -69,9 +70,18 @@ func New(
// SetDNSProvider sets the DNS provider for managing DNS records during deployments.
// Pass nil to disable DNS management (wildcard DNS mode).
func (d *Deployer) SetDNSProvider(provider dns.Provider) {
d.dnsMu.Lock()
defer d.dnsMu.Unlock()
d.dns = provider
}
// getDNS returns the current DNS provider under read lock.
func (d *Deployer) getDNS() dns.Provider {
d.dnsMu.RLock()
defer d.dnsMu.RUnlock()
return d.dns
}
// Drain waits for all in-progress deploys to complete. Call this during graceful shutdown.
func (d *Deployer) Drain() {
d.shuttingDown.Store(true)
@@ -744,7 +754,8 @@ func (d *Deployer) publishInstanceStatus(instanceID, projectID, stageID, status
// ensureDNS creates or updates a DNS record for the given FQDN. Best-effort: logs warnings on failure.
func (d *Deployer) ensureDNS(ctx context.Context, fqdn, consumerType, consumerID, deployID string) {
if d.dns == nil {
dnsProvider := d.getDNS()
if dnsProvider == nil {
return
}
settings, err := d.store.GetSettings()
@@ -757,7 +768,7 @@ func (d *Deployer) ensureDNS(ctx context.Context, fqdn, consumerType, consumerID
return
}
recordID, err := d.dns.EnsureRecord(ctx, fqdn, settings.ServerIP)
recordID, err := dnsProvider.EnsureRecord(ctx, fqdn, settings.ServerIP)
if err != nil {
msg := fmt.Sprintf("DNS: failed to create/update record for %s: %v", fqdn, err)
slog.Warn(msg)
@@ -789,11 +800,12 @@ func (d *Deployer) ensureDNS(ctx context.Context, fqdn, consumerType, consumerID
// removeDNS deletes a DNS record for the given FQDN. Best-effort: logs warnings on failure.
func (d *Deployer) removeDNS(ctx context.Context, fqdn, deployID string) {
if d.dns == nil {
dnsProvider := d.getDNS()
if dnsProvider == nil {
return
}
if err := d.dns.DeleteRecord(ctx, fqdn); err != nil {
if err := dnsProvider.DeleteRecord(ctx, fqdn); err != nil {
msg := fmt.Sprintf("DNS: failed to delete record for %s: %v", fqdn, err)
slog.Warn(msg)
if deployID != "" {