mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-11-05 00:50:21 +00:00
Improve: Delete the corresponding DNS record if the IPv4/IPv6 address is empty.
This commit is contained in:
1 parent
eb48a178f8
commit
c684388153
1 file changed
+82
-4
+82
-4
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/libdns/libdns"
|
"github.com/libdns/libdns"
|
||||||
@@ -54,10 +55,13 @@ func (provider *Provider) updateDomain(ctx context.Context, domain string) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 独立处理 IPv4 更新
|
// 独立处理 IPv4 更新或删除
|
||||||
if *provider.DDNSProfile.EnableIPv4 {
|
if *provider.DDNSProfile.EnableIPv4 {
|
||||||
if provider.IPAddrs.IPv4Addr == "" {
|
if provider.IPAddrs.IPv4Addr == "" {
|
||||||
log.Printf("NEZHA>> Skip IPv4 update for domain %s: IPv4 address is empty", domain)
|
log.Printf("NEZHA>> IPv4 address is empty for domain %s, deleting A record...", domain)
|
||||||
|
if err = provider.deleteDomainRecord(ctx, "A"); err != nil {
|
||||||
|
return fmt.Errorf("failed to delete IPv4 record: %w", err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if err = provider.addDomainRecord(ctx, "A", provider.IPAddrs.IPv4Addr); err != nil {
|
if err = provider.addDomainRecord(ctx, "A", provider.IPAddrs.IPv4Addr); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -65,10 +69,13 @@ func (provider *Provider) updateDomain(ctx context.Context, domain string) error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 独立处理 IPv6 更新
|
// 独立处理 IPv6 更新或删除
|
||||||
if *provider.DDNSProfile.EnableIPv6 {
|
if *provider.DDNSProfile.EnableIPv6 {
|
||||||
if provider.IPAddrs.IPv6Addr == "" {
|
if provider.IPAddrs.IPv6Addr == "" {
|
||||||
log.Printf("NEZHA>> Skip IPv6 update for domain %s: IPv6 address is empty", domain)
|
log.Printf("NEZHA>> IPv6 address is empty for domain %s, deleting AAAA record...", domain)
|
||||||
|
if err = provider.deleteDomainRecord(ctx, "AAAA"); err != nil {
|
||||||
|
return fmt.Errorf("failed to delete IPv6 record: %w", err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if err = provider.addDomainRecord(ctx, "AAAA", provider.IPAddrs.IPv6Addr); err != nil {
|
if err = provider.addDomainRecord(ctx, "AAAA", provider.IPAddrs.IPv6Addr); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -96,6 +103,77 @@ func (provider *Provider) addDomainRecord(ctx context.Context, recType, addr str
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deleteDomainRecord 用于删除指定类型的解析记录
|
||||||
|
func (provider *Provider) deleteDomainRecord(ctx context.Context, recType string) error {
|
||||||
|
// 检查 libdns.RecordGetter 和 libdns.RecordDeleter
|
||||||
|
getter, ok := provider.Setter.(libdns.RecordGetter)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("dns provider does not support record getting")
|
||||||
|
}
|
||||||
|
|
||||||
|
deleter, ok := provider.Setter.(libdns.RecordDeleter)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("dns provider does not support record deletion")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取 DNS 记录
|
||||||
|
allRecords, err := getter.GetRecords(ctx, provider.zone)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get DNS records: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanName := func(name string) string {
|
||||||
|
return strings.ToLower(strings.TrimSuffix(name, "."))
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanPrefix := cleanName(provider.prefix)
|
||||||
|
cleanZone := cleanName(provider.zone)
|
||||||
|
targetRecType := strings.ToUpper(recType)
|
||||||
|
|
||||||
|
// 筛选和匹配
|
||||||
|
var targetRecords []libdns.Record
|
||||||
|
for _, rec := range allRecords {
|
||||||
|
rr := rec.RR()
|
||||||
|
recName := rr.Name
|
||||||
|
currentType := strings.ToUpper(rr.Type)
|
||||||
|
|
||||||
|
if currentType != targetRecType {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
relName := libdns.RelativeName(recName, provider.zone)
|
||||||
|
cleanRel := cleanName(relName)
|
||||||
|
cleanRRName := cleanName(recName)
|
||||||
|
|
||||||
|
var matchedName bool
|
||||||
|
if cleanPrefix == "" {
|
||||||
|
matchedName = cleanRel == "" || cleanRel == "@" || cleanRRName == cleanZone
|
||||||
|
} else {
|
||||||
|
matchedName = cleanRel == cleanPrefix || cleanRRName == cleanPrefix
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保留原始的 rec 接口(包含 Cloudflare 所需的 ProviderData 元数据),用于精准删除
|
||||||
|
if matchedName {
|
||||||
|
targetRecords = append(targetRecords, rec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 若未找到对应记录,则直接返回成功(视为已删除或不存在)
|
||||||
|
if len(targetRecords) == 0 {
|
||||||
|
log.Printf("NEZHA>> No matching %s record found for deletion under zone %s", recType, provider.zone)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行删除操作
|
||||||
|
_, err = deleter.DeleteRecords(ctx, provider.zone, targetRecords)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("deleter.DeleteRecords failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("NEZHA>> Successfully deleted %d matching %s record(s) for %s.%s", len(targetRecords), recType, provider.prefix, provider.zone)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (provider *Provider) splitDomainSOA(ctx context.Context, domain string) (prefix string, zone string, err error) {
|
func (provider *Provider) splitDomainSOA(ctx context.Context, domain string) (prefix string, zone string, err error) {
|
||||||
c := &dns.Client{Timeout: dnsTimeOut}
|
c := &dns.Client{Timeout: dnsTimeOut}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user