diff --git a/cmd/dashboard/controller/server.go b/cmd/dashboard/controller/server.go index c28f3c1..c0e9d89 100644 --- a/cmd/dashboard/controller/server.go +++ b/cmd/dashboard/controller/server.go @@ -84,12 +84,20 @@ func updateServer(c *gin.Context) (any, error) { s.HideForGuest = sf.HideForGuest s.EnableDDNS = sf.EnableDDNS s.DDNSProfiles = sf.DDNSProfiles + s.OverrideDDNSDomains = sf.OverrideDDNSDomains + ddnsProfilesRaw, err := utils.Json.Marshal(s.DDNSProfiles) if err != nil { return nil, err } s.DDNSProfilesRaw = string(ddnsProfilesRaw) + overrideDomainsRaw, err := utils.Json.Marshal(sf.OverrideDDNSDomains) + if err != nil { + return nil, err + } + s.OverrideDDNSDomainsRaw = string(overrideDomainsRaw) + if err := singleton.DB.Save(&s).Error; err != nil { return nil, newGormError("%v", err) } diff --git a/model/server.go b/model/server.go index e1dd272..7f42555 100644 --- a/model/server.go +++ b/model/server.go @@ -14,16 +14,18 @@ import ( type Server struct { Common - Name string `json:"name"` - UUID string `json:"uuid,omitempty" gorm:"unique"` - Note string `json:"note,omitempty"` // 管理员可见备注 - PublicNote string `json:"public_note,omitempty"` // 公开备注 - DisplayIndex int `json:"display_index"` // 展示排序,越大越靠前 - HideForGuest bool `json:"hide_for_guest,omitempty"` // 对游客隐藏 - EnableDDNS bool `json:"enable_ddns,omitempty"` // 启用DDNS - DDNSProfilesRaw string `gorm:"default:'[]';column:ddns_profiles_raw" json:"-"` + Name string `json:"name"` + UUID string `json:"uuid,omitempty" gorm:"unique"` + Note string `json:"note,omitempty"` // 管理员可见备注 + PublicNote string `json:"public_note,omitempty"` // 公开备注 + DisplayIndex int `json:"display_index"` // 展示排序,越大越靠前 + HideForGuest bool `json:"hide_for_guest,omitempty"` // 对游客隐藏 + EnableDDNS bool `json:"enable_ddns,omitempty"` // 启用DDNS + DDNSProfilesRaw string `gorm:"default:'[]';column:ddns_profiles_raw" json:"-"` + OverrideDDNSDomainsRaw string `gorm:"default:'{}';column:override_ddns_domains_raw" json:"-"` - DDNSProfiles []uint64 `gorm:"-" json:"ddns_profiles,omitempty" validate:"optional"` // DDNS配置 + DDNSProfiles []uint64 `gorm:"-" json:"ddns_profiles,omitempty" validate:"optional"` // DDNS配置 + OverrideDDNSDomains map[uint64][]string `gorm:"-" json:"override_ddns_domains,omitempty" validate:"optional"` Host *Host `gorm:"-" json:"host,omitempty"` State *HostState `gorm:"-" json:"state,omitempty"` @@ -53,6 +55,12 @@ func (s *Server) AfterFind(tx *gorm.DB) error { return nil } } + if s.OverrideDDNSDomainsRaw != "" { + if err := utils.Json.Unmarshal([]byte(s.OverrideDDNSDomainsRaw), &s.OverrideDDNSDomains); err != nil { + log.Println("NEZHA>> Server.AfterFind:", err) + return nil + } + } return nil } diff --git a/model/server_api.go b/model/server_api.go index de2df16..3155637 100644 --- a/model/server_api.go +++ b/model/server_api.go @@ -21,13 +21,14 @@ type StreamServerData struct { } type ServerForm struct { - Name string `json:"name,omitempty"` - Note string `json:"note,omitempty" validate:"optional"` // 管理员可见备注 - PublicNote string `json:"public_note,omitempty" validate:"optional"` // 公开备注 - DisplayIndex int `json:"display_index,omitempty" default:"0"` // 展示排序,越大越靠前 - HideForGuest bool `json:"hide_for_guest,omitempty" validate:"optional"` // 对游客隐藏 - EnableDDNS bool `json:"enable_ddns,omitempty" validate:"optional"` // 启用DDNS - DDNSProfiles []uint64 `gorm:"-" json:"ddns_profiles,omitempty" validate:"optional"` // DDNS配置 + Name string `json:"name,omitempty"` + Note string `json:"note,omitempty" validate:"optional"` // 管理员可见备注 + PublicNote string `json:"public_note,omitempty" validate:"optional"` // 公开备注 + DisplayIndex int `json:"display_index,omitempty" default:"0"` // 展示排序,越大越靠前 + HideForGuest bool `json:"hide_for_guest,omitempty" validate:"optional"` // 对游客隐藏 + EnableDDNS bool `json:"enable_ddns,omitempty" validate:"optional"` // 启用DDNS + DDNSProfiles []uint64 `json:"ddns_profiles,omitempty" validate:"optional"` // DDNS配置 + OverrideDDNSDomains map[uint64][]string `json:"override_ddns_domains,omitempty" validate:"optional"` } type ForceUpdateResponse struct { diff --git a/pkg/ddns/ddns.go b/pkg/ddns/ddns.go index 8c600e6..ce566d1 100644 --- a/pkg/ddns/ddns.go +++ b/pkg/ddns/ddns.go @@ -28,7 +28,6 @@ type Provider struct { ctx context.Context ipAddr string recordType string - domain string prefix string zone string @@ -43,25 +42,28 @@ func InitDNSServers(s string) { } } -func (provider *Provider) UpdateDomain(ctx context.Context) { +func (provider *Provider) GetProfileID() uint64 { + return provider.DDNSProfile.ID +} + +func (provider *Provider) UpdateDomain(ctx context.Context, overrideDomains ...string) { provider.ctx = ctx - for _, domain := range provider.DDNSProfile.Domains { + for _, domain := range utils.IfOr(len(overrideDomains) > 0, overrideDomains, provider.DDNSProfile.Domains) { for retries := 0; retries < int(provider.DDNSProfile.MaxRetries); retries++ { - provider.domain = domain - log.Printf("NEZHA>> Updating DNS Record of domain %s: %d/%d", provider.domain, retries+1, provider.DDNSProfile.MaxRetries) - if err := provider.updateDomain(); err != nil { - log.Printf("NEZHA>> Failed to update DNS record of domain %s: %v", provider.domain, err) + log.Printf("NEZHA>> Updating DNS Record of domain %s: %d/%d", domain, retries+1, provider.DDNSProfile.MaxRetries) + if err := provider.updateDomain(domain); err != nil { + log.Printf("NEZHA>> Failed to update DNS record of domain %s: %v", domain, err) } else { - log.Printf("NEZHA>> Update DNS record of domain %s succeed", provider.domain) + log.Printf("NEZHA>> Update DNS record of domain %s succeed", domain) break } } } } -func (provider *Provider) updateDomain() error { +func (provider *Provider) updateDomain(domain string) error { var err error - provider.prefix, provider.zone, err = splitDomainSOA(provider.domain) + provider.prefix, provider.zone, err = splitDomainSOA(domain) if err != nil { return err } diff --git a/service/rpc/nezha.go b/service/rpc/nezha.go index cd2ee7f..96e1c1c 100644 --- a/service/rpc/nezha.go +++ b/service/rpc/nezha.go @@ -231,11 +231,13 @@ func (s *NezhaHandler) ReportGeoIP(c context.Context, r *pb.GeoIP) (*pb.GeoIP, e (server.GeoIP == nil || server.GeoIP.IP != geoip.IP) { ipv4 := geoip.IP.IPv4Addr ipv6 := geoip.IP.IPv6Addr + providers, err := singleton.GetDDNSProvidersFromProfiles(server.DDNSProfiles, &ddns.IP{Ipv4Addr: ipv4, Ipv6Addr: ipv6}) if err == nil { for _, provider := range providers { + domains := server.OverrideDDNSDomains[provider.GetProfileID()] go func(provider *ddns.Provider) { - provider.UpdateDomain(context.Background()) + provider.UpdateDomain(context.Background(), domains...) }(provider) } } else {