mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-02-06 05:30:05 +00:00
ddns: store configuation in database (#435)
* ddns: store configuation in database Co-authored-by: nap0o <144927971+nap0o@users.noreply.github.com> * feat: split domain with soa lookup * switch to libdns interface * ddns: add unit test * ddns: skip TestSplitDomainSOA on ci network is not steady * fix error handling * fix error handling --------- Co-authored-by: nap0o <144927971+nap0o@users.noreply.github.com>
This commit is contained in:
@@ -2,73 +2,68 @@ package singleton
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
"github.com/libdns/cloudflare"
|
||||
"github.com/libdns/tencentcloud"
|
||||
|
||||
"github.com/naiba/nezha/model"
|
||||
ddns2 "github.com/naiba/nezha/pkg/ddns"
|
||||
"github.com/naiba/nezha/pkg/ddns/dummy"
|
||||
"github.com/naiba/nezha/pkg/ddns/webhook"
|
||||
)
|
||||
|
||||
const (
|
||||
ProviderWebHook = "webhook"
|
||||
ProviderCloudflare = "cloudflare"
|
||||
ProviderTencentCloud = "tencentcloud"
|
||||
var (
|
||||
ddnsCache map[uint64]*model.DDNSProfile
|
||||
ddnsCacheLock sync.RWMutex
|
||||
)
|
||||
|
||||
type ProviderFunc func(*ddns2.DomainConfig) ddns2.Provider
|
||||
func initDDNS() {
|
||||
OnDDNSUpdate()
|
||||
}
|
||||
|
||||
func RetryableUpdateDomain(provider ddns2.Provider, domainConfig *ddns2.DomainConfig, maxRetries int) {
|
||||
if domainConfig == nil {
|
||||
return
|
||||
func OnDDNSUpdate() {
|
||||
var ddns []*model.DDNSProfile
|
||||
DB.Find(&ddns)
|
||||
ddnsCacheLock.Lock()
|
||||
defer ddnsCacheLock.Unlock()
|
||||
ddnsCache = make(map[uint64]*model.DDNSProfile)
|
||||
for i := 0; i < len(ddns); i++ {
|
||||
ddnsCache[ddns[i].ID] = ddns[i]
|
||||
}
|
||||
for retries := 0; retries < maxRetries; retries++ {
|
||||
log.Printf("NEZHA>> 正在尝试更新域名(%s)DDNS(%d/%d)", domainConfig.FullDomain, retries+1, maxRetries)
|
||||
if err := provider.UpdateDomain(domainConfig); err != nil {
|
||||
log.Printf("NEZHA>> 尝试更新域名(%s)DDNS失败: %v", domainConfig.FullDomain, err)
|
||||
}
|
||||
|
||||
func GetDDNSProvidersFromProfiles(profileId []uint64, ip *ddns2.IP) ([]*ddns2.Provider, error) {
|
||||
profiles := make([]*model.DDNSProfile, 0, len(profileId))
|
||||
ddnsCacheLock.RLock()
|
||||
for _, id := range profileId {
|
||||
if profile, ok := ddnsCache[id]; ok {
|
||||
profiles = append(profiles, profile)
|
||||
} else {
|
||||
log.Printf("NEZHA>> 尝试更新域名(%s)DDNS成功", domainConfig.FullDomain)
|
||||
break
|
||||
return nil, fmt.Errorf("无法找到DDNS配置 ID %d", id)
|
||||
}
|
||||
}
|
||||
}
|
||||
ddnsCacheLock.RUnlock()
|
||||
|
||||
// Deprecated
|
||||
func GetDDNSProviderFromString(provider string) (ddns2.Provider, error) {
|
||||
switch provider {
|
||||
case ProviderWebHook:
|
||||
return ddns2.NewProviderWebHook(Conf.DDNS.WebhookURL, Conf.DDNS.WebhookMethod, Conf.DDNS.WebhookRequestBody, Conf.DDNS.WebhookHeaders), nil
|
||||
case ProviderCloudflare:
|
||||
return ddns2.NewProviderCloudflare(Conf.DDNS.AccessSecret), nil
|
||||
case ProviderTencentCloud:
|
||||
return ddns2.NewProviderTencentCloud(Conf.DDNS.AccessID, Conf.DDNS.AccessSecret), nil
|
||||
default:
|
||||
return new(ddns2.ProviderDummy), fmt.Errorf("无法找到配置的DDNS提供者 %s", provider)
|
||||
}
|
||||
}
|
||||
|
||||
func GetDDNSProviderFromProfile(profileName string) (ddns2.Provider, error) {
|
||||
profile, ok := Conf.DDNS.Profiles[profileName]
|
||||
if !ok {
|
||||
return new(ddns2.ProviderDummy), fmt.Errorf("未找到配置项 %s", profileName)
|
||||
}
|
||||
|
||||
switch profile.Provider {
|
||||
case ProviderWebHook:
|
||||
return ddns2.NewProviderWebHook(profile.WebhookURL, profile.WebhookMethod, profile.WebhookRequestBody, profile.WebhookHeaders), nil
|
||||
case ProviderCloudflare:
|
||||
return ddns2.NewProviderCloudflare(profile.AccessSecret), nil
|
||||
case ProviderTencentCloud:
|
||||
return ddns2.NewProviderTencentCloud(profile.AccessID, profile.AccessSecret), nil
|
||||
default:
|
||||
return new(ddns2.ProviderDummy), fmt.Errorf("无法找到配置的DDNS提供者 %s", profile.Provider)
|
||||
}
|
||||
}
|
||||
|
||||
func ValidateDDNSProvidersFromProfiles() error {
|
||||
validProviders := []string{ProviderWebHook, ProviderCloudflare, ProviderTencentCloud}
|
||||
for _, profile := range Conf.DDNS.Profiles {
|
||||
if ok := slices.Contains(validProviders, profile.Provider); !ok {
|
||||
return fmt.Errorf("无法找到配置的DDNS提供者%s", profile.Provider)
|
||||
providers := make([]*ddns2.Provider, 0, len(profiles))
|
||||
for _, profile := range profiles {
|
||||
provider := &ddns2.Provider{DDNSProfile: profile, IPAddrs: ip}
|
||||
switch profile.Provider {
|
||||
case model.ProviderDummy:
|
||||
provider.Setter = &dummy.Provider{}
|
||||
providers = append(providers, provider)
|
||||
case model.ProviderWebHook:
|
||||
provider.Setter = &webhook.Provider{DDNSProfile: profile}
|
||||
providers = append(providers, provider)
|
||||
case model.ProviderCloudflare:
|
||||
provider.Setter = &cloudflare.Provider{APIToken: profile.AccessSecret}
|
||||
providers = append(providers, provider)
|
||||
case model.ProviderTencentCloud:
|
||||
provider.Setter = &tencentcloud.Provider{SecretId: profile.AccessID, SecretKey: profile.AccessSecret}
|
||||
providers = append(providers, provider)
|
||||
default:
|
||||
return nil, fmt.Errorf("无法找到配置的DDNS提供者ID %d", profile.Provider)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return providers, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user