724 lines
19 KiB
Go
724 lines
19 KiB
Go
package cmd
|
||
|
||
import (
|
||
"agent-wdd/cloudflare"
|
||
"agent-wdd/log"
|
||
"bufio"
|
||
"fmt"
|
||
"os"
|
||
"strconv"
|
||
"strings"
|
||
"text/tabwriter"
|
||
|
||
"github.com/spf13/cobra"
|
||
)
|
||
|
||
const (
|
||
// Cloudflare API设置选项
|
||
cfAPITokenDefault = "T7LxBemfe8SNGWkT9uz2XIc1e22ifAbBv_POJvDP" // 默认的API令牌,实际应用中应从配置文件或环境变量获取
|
||
)
|
||
|
||
// DNS记录类型常量
|
||
const (
|
||
DNSTypeA = "A"
|
||
DNSTypeAAAA = "AAAA"
|
||
DNSTypeCNAME = "CNAME"
|
||
DNSTypeTXT = "TXT"
|
||
DNSTypeMX = "MX"
|
||
DNSTypeSRV = "SRV"
|
||
)
|
||
|
||
// 初始化Cloudflare客户端
|
||
func initCloudflareClient() *cloudflare.CloudflareClient {
|
||
log.Debug("初始化Cloudflare客户端")
|
||
return cloudflare.GetInstance(cfAPITokenDefault)
|
||
}
|
||
|
||
// 询问用户确认
|
||
func askForConfirmation(prompt string) bool {
|
||
reader := bufio.NewReader(os.Stdin)
|
||
for {
|
||
fmt.Printf("%s [y/n]: ", prompt)
|
||
response, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
log.Error("读取用户输入失败: %v", err)
|
||
return false
|
||
}
|
||
|
||
response = strings.ToLower(strings.TrimSpace(response))
|
||
if response == "y" || response == "yes" {
|
||
return true
|
||
} else if response == "n" || response == "no" {
|
||
return false
|
||
}
|
||
}
|
||
}
|
||
|
||
// 添加Cloudflare命令
|
||
func addCloudflareSubcommands(cmd *cobra.Command) {
|
||
// 域名管理命令
|
||
domainCmd := &cobra.Command{
|
||
Use: "domain",
|
||
Short: "Cloudflare域名管理",
|
||
Long: "管理Cloudflare上的域名(查询域名列表、查看域名详情等)",
|
||
}
|
||
|
||
// 域名列表命令
|
||
listDomainsCmd := &cobra.Command{
|
||
Use: "list",
|
||
Short: "列出所有域名",
|
||
Run: func(cmd *cobra.Command, args []string) {
|
||
log.Info("获取域名列表")
|
||
client := initCloudflareClient()
|
||
zones, err := client.ListZones(nil)
|
||
if err != nil {
|
||
log.Error("获取域名列表失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
if len(zones) == 0 {
|
||
log.Info("未找到任何域名")
|
||
return
|
||
}
|
||
|
||
printDomainsList(zones)
|
||
},
|
||
}
|
||
|
||
// 查看域名详情命令
|
||
getDomainCmd := &cobra.Command{
|
||
Use: "get [域名]",
|
||
Short: "获取域名详情",
|
||
Args: cobra.ExactArgs(1),
|
||
Run: func(cmd *cobra.Command, args []string) {
|
||
domain := args[0]
|
||
log.Info("获取域名详情: %s", domain)
|
||
client := initCloudflareClient()
|
||
zone, err := client.GetZone(domain)
|
||
if err != nil {
|
||
log.Error("获取域名详情失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
printDomainDetails(zone)
|
||
},
|
||
}
|
||
|
||
// DNS记录管理命令
|
||
dnsCmd := &cobra.Command{
|
||
Use: "dns",
|
||
Short: "DNS记录管理",
|
||
Long: "管理Cloudflare上的DNS记录(查询、创建、更新、删除)",
|
||
}
|
||
|
||
// 列出DNS记录命令
|
||
listDNSCmd := &cobra.Command{
|
||
Use: "list [域名]",
|
||
Short: "列出域名的所有DNS记录",
|
||
Args: cobra.ExactArgs(1),
|
||
Run: func(cmd *cobra.Command, args []string) {
|
||
domain := args[0]
|
||
log.Info("获取域名 %s 的DNS记录", domain)
|
||
client := initCloudflareClient()
|
||
|
||
// 先获取zone ID
|
||
zone, err := client.GetZone(domain)
|
||
if err != nil {
|
||
log.Error("获取域名信息失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
records, err := client.ListDNSRecords(zone.ID, nil)
|
||
if err != nil {
|
||
log.Error("获取DNS记录失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
if len(records) == 0 {
|
||
log.Info("未找到任何DNS记录")
|
||
return
|
||
}
|
||
|
||
printDNSRecordsList(records, domain)
|
||
},
|
||
}
|
||
|
||
// 创建DNS记录命令
|
||
createDNSCmd := &cobra.Command{
|
||
Use: "create [域名]",
|
||
Short: "创建DNS记录",
|
||
Args: cobra.ExactArgs(1),
|
||
Run: func(cmd *cobra.Command, args []string) {
|
||
domain := args[0]
|
||
log.Info("为域名 %s 创建DNS记录", domain)
|
||
client := initCloudflareClient()
|
||
|
||
// 先获取zone ID
|
||
zone, err := client.GetZone(domain)
|
||
if err != nil {
|
||
log.Error("获取域名信息失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// 交互式收集DNS记录信息
|
||
record, err := collectDNSRecordInfo(domain)
|
||
if err != nil {
|
||
log.Error("收集DNS记录信息失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// 确认信息
|
||
fmt.Println("\n即将创建以下DNS记录:")
|
||
fmt.Printf("名称: %s\n", record.Name)
|
||
fmt.Printf("类型: %s\n", record.Type)
|
||
fmt.Printf("内容: %s\n", record.Content)
|
||
fmt.Printf("TTL: %d\n", record.TTL)
|
||
if record.Priority > 0 {
|
||
fmt.Printf("优先级: %d\n", record.Priority)
|
||
}
|
||
fmt.Printf("代理状态: %v\n", record.Proxied)
|
||
|
||
if !askForConfirmation("确认创建此DNS记录?") {
|
||
log.Info("已取消创建DNS记录")
|
||
return
|
||
}
|
||
|
||
// 创建DNS记录
|
||
createdRecord, err := client.CreateDNSRecord(zone.ID, record)
|
||
if err != nil {
|
||
log.Error("创建DNS记录失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
log.Info("DNS记录创建成功")
|
||
printDNSRecordDetails(createdRecord, domain)
|
||
},
|
||
}
|
||
|
||
// 更新DNS记录命令
|
||
updateDNSCmd := &cobra.Command{
|
||
Use: "update [域名]",
|
||
Short: "更新DNS记录",
|
||
Args: cobra.ExactArgs(1),
|
||
Run: func(cmd *cobra.Command, args []string) {
|
||
domain := args[0]
|
||
log.Info("更新域名 %s 的DNS记录", domain)
|
||
client := initCloudflareClient()
|
||
|
||
// 先获取zone ID
|
||
zone, err := client.GetZone(domain)
|
||
if err != nil {
|
||
log.Error("获取域名信息失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// 获取域名到ID的映射
|
||
dnsNameToIDMap := client.GetDNSNameToIDMap(zone.ID)
|
||
if len(dnsNameToIDMap) == 0 {
|
||
log.Error("未找到ZoneID %s Zone %s 的任何DNS记录", zone.ID, zone.Name)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// recordID 为空,则获取所有DNS记录
|
||
recordID := dnsNameToIDMap[domain]
|
||
if recordID == "" {
|
||
log.Error("未找到zoneID %s Zone %s 域名 %s 的DNS记录", zone.ID, zone.Name, domain)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// 获取当前记录
|
||
currentRecord, err := client.GetDNSRecord(zone.ID, recordID)
|
||
if err != nil {
|
||
log.Error("获取DNS记录失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// 显示当前记录
|
||
fmt.Println("当前DNS记录:")
|
||
printDNSRecordDetails(currentRecord, domain)
|
||
|
||
// 交互式收集更新后的DNS记录信息
|
||
updatedRecord, err := updateDNSRecordInfo(*currentRecord)
|
||
if err != nil {
|
||
log.Error("收集DNS记录更新信息失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// 确认信息
|
||
fmt.Println("\n即将更新为以下DNS记录:")
|
||
fmt.Printf("名称: %s\n", updatedRecord.Name)
|
||
fmt.Printf("类型: %s\n", updatedRecord.Type)
|
||
fmt.Printf("内容: %s\n", updatedRecord.Content)
|
||
fmt.Printf("TTL: %d\n", updatedRecord.TTL)
|
||
if updatedRecord.Priority > 0 {
|
||
fmt.Printf("优先级: %d\n", updatedRecord.Priority)
|
||
}
|
||
fmt.Printf("代理状态: %v\n", updatedRecord.Proxied)
|
||
|
||
if !askForConfirmation("确认更新此DNS记录?") {
|
||
log.Info("已取消更新DNS记录")
|
||
return
|
||
}
|
||
|
||
// 更新DNS记录
|
||
updatedRecordResult, err := client.UpdateDNSRecord(zone.ID, recordID, updatedRecord)
|
||
if err != nil {
|
||
log.Error("更新DNS记录失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
log.Info("DNS记录更新成功")
|
||
printDNSRecordDetails(updatedRecordResult, domain)
|
||
},
|
||
}
|
||
|
||
// 删除DNS记录命令
|
||
deleteDNSCmd := &cobra.Command{
|
||
Use: "delete [域名]",
|
||
Short: "删除DNS记录",
|
||
Args: cobra.ExactArgs(1),
|
||
Run: func(cmd *cobra.Command, args []string) {
|
||
domain := args[0]
|
||
log.Info("删除域名 %s 的DNS记录", domain)
|
||
client := initCloudflareClient()
|
||
|
||
// 先获取zone ID
|
||
zone, err := client.GetZone(domain)
|
||
if err != nil {
|
||
log.Error("获取域名信息失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// 获取域名到ID的映射
|
||
dnsNameToIDMap := client.GetDNSNameToIDMap(zone.ID)
|
||
if len(dnsNameToIDMap) == 0 {
|
||
log.Error("未找到ZoneID %s Zone %s 的任何DNS记录", zone.ID, zone.Name)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// recordID 为空,则获取所有DNS记录
|
||
recordID := dnsNameToIDMap[domain]
|
||
if recordID == "" {
|
||
log.Error("未找到zoneID %s Zone %s 域名 %s 的DNS记录", zone.ID, zone.Name, domain)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// 获取要删除的记录信息
|
||
record, err := client.GetDNSRecord(zone.ID, recordID)
|
||
if err != nil {
|
||
log.Error("获取DNS记录信息失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
// 显示要删除的记录
|
||
fmt.Println("即将删除以下DNS记录:")
|
||
printDNSRecordDetails(record, domain)
|
||
|
||
// 请求确认
|
||
if !askForConfirmation("确认删除此DNS记录? 此操作不可恢复!") {
|
||
log.Info("已取消删除DNS记录")
|
||
return
|
||
}
|
||
|
||
// 二次确认
|
||
fmt.Println("\n⚠️ 警告: 删除DNS记录可能会影响网站访问、邮件服务等功能")
|
||
if !askForConfirmation("再次确认删除此DNS记录?") {
|
||
log.Info("已取消删除DNS记录")
|
||
return
|
||
}
|
||
|
||
// 删除DNS记录
|
||
success, err := client.DeleteDNSRecord(zone.ID, recordID)
|
||
if err != nil {
|
||
log.Error("删除DNS记录失败: %v", err)
|
||
os.Exit(1)
|
||
}
|
||
|
||
if success {
|
||
log.Info("DNS记录删除成功")
|
||
} else {
|
||
log.Error("DNS记录删除失败")
|
||
os.Exit(1)
|
||
}
|
||
},
|
||
}
|
||
|
||
// 添加域名管理子命令
|
||
domainCmd.AddCommand(listDomainsCmd, getDomainCmd)
|
||
|
||
// 添加DNS管理子命令
|
||
dnsCmd.AddCommand(listDNSCmd, createDNSCmd, updateDNSCmd, deleteDNSCmd)
|
||
|
||
// 将所有主要命令添加到父命令
|
||
cmd.AddCommand(domainCmd, dnsCmd)
|
||
}
|
||
|
||
// 打印域名列表
|
||
func printDomainsList(zones []cloudflare.Zone) {
|
||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||
fmt.Fprintln(w, "域名\t状态\t名称服务器\t创建时间")
|
||
fmt.Fprintln(w, "----\t----\t---------\t--------")
|
||
|
||
for _, zone := range zones {
|
||
nameServers := strings.Join(zone.NameServers, ", ")
|
||
createdOn := zone.CreatedOn[:10] // 仅显示日期部分
|
||
status := zone.Status
|
||
if zone.Paused {
|
||
status += " (已暂停)"
|
||
}
|
||
|
||
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n",
|
||
zone.Name,
|
||
status,
|
||
nameServers,
|
||
createdOn)
|
||
}
|
||
|
||
w.Flush()
|
||
}
|
||
|
||
// 打印域名详情
|
||
func printDomainDetails(zone *cloudflare.Zone) {
|
||
fmt.Printf("================== 域名详情 ==================\n")
|
||
fmt.Printf("域名: %s\n", zone.Name)
|
||
fmt.Printf("ID: %s\n", zone.ID)
|
||
fmt.Printf("状态: %s\n", zone.Status)
|
||
fmt.Printf("暂停: %v\n", zone.Paused)
|
||
fmt.Printf("类型: %s\n", zone.Type)
|
||
fmt.Printf("开发模式: %d\n", zone.DevelopmentMode)
|
||
fmt.Printf("名称服务器: %s\n", strings.Join(zone.NameServers, ", "))
|
||
fmt.Printf("原始名称服务器: %s\n", strings.Join(zone.OriginalNameServers, ", "))
|
||
fmt.Printf("修改时间: %s\n", zone.ModifiedOn)
|
||
fmt.Printf("创建时间: %s\n", zone.CreatedOn)
|
||
fmt.Printf("激活时间: %s\n", zone.ActivatedOn)
|
||
if zone.Account.Name != "" {
|
||
fmt.Printf("账户: %s (%s)\n", zone.Account.Name, zone.Account.ID)
|
||
}
|
||
fmt.Printf("==================================================\n")
|
||
}
|
||
|
||
// 打印DNS记录列表
|
||
func printDNSRecordsList(records []cloudflare.DNSRecord, domain string) {
|
||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||
fmt.Fprintf(w, "域名: %s\n\n", domain)
|
||
fmt.Fprintln(w, "名称\t类型\t内容\tTTL\t代理\t优先级\t备注")
|
||
fmt.Fprintln(w, "----\t----\t----\t---\t----\t-----\t----")
|
||
|
||
for _, record := range records {
|
||
ttl := "自动"
|
||
if record.TTL > 1 {
|
||
ttl = strconv.Itoa(record.TTL)
|
||
}
|
||
|
||
priority := "-"
|
||
if record.Priority > 0 {
|
||
priority = strconv.Itoa(record.Priority)
|
||
}
|
||
|
||
proxied := "否"
|
||
if record.Proxied {
|
||
proxied = "是"
|
||
}
|
||
|
||
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
|
||
record.Name,
|
||
record.Type,
|
||
record.Content,
|
||
ttl,
|
||
proxied,
|
||
priority,
|
||
record.Comment)
|
||
}
|
||
|
||
w.Flush()
|
||
}
|
||
|
||
// 打印DNS记录详情
|
||
func printDNSRecordDetails(record *cloudflare.DNSRecord, domain string) {
|
||
fmt.Printf("================ DNS记录详情 ================\n")
|
||
fmt.Printf("域名: %s\n", domain)
|
||
fmt.Printf("ID: %s\n", record.ID)
|
||
fmt.Printf("名称: %s\n", record.Name)
|
||
fmt.Printf("类型: %s\n", record.Type)
|
||
fmt.Printf("内容: %s\n", record.Content)
|
||
|
||
ttl := "自动"
|
||
if record.TTL > 1 {
|
||
ttl = strconv.Itoa(record.TTL)
|
||
}
|
||
fmt.Printf("TTL: %s\n", ttl)
|
||
|
||
fmt.Printf("代理: %v\n", record.Proxied)
|
||
|
||
if record.Priority > 0 {
|
||
fmt.Printf("优先级: %d\n", record.Priority)
|
||
}
|
||
|
||
if record.Comment != "" {
|
||
fmt.Printf("备注: %s\n", record.Comment)
|
||
}
|
||
|
||
if record.CreatedOn != "" {
|
||
fmt.Printf("创建时间: %s\n", record.CreatedOn)
|
||
}
|
||
|
||
if record.ModifiedOn != "" {
|
||
fmt.Printf("修改时间: %s\n", record.ModifiedOn)
|
||
}
|
||
fmt.Printf("==============================================\n")
|
||
}
|
||
|
||
// 交互式收集DNS记录信息
|
||
func collectDNSRecordInfo(domain string) (cloudflare.DNSRecord, error) {
|
||
reader := bufio.NewReader(os.Stdin)
|
||
record := cloudflare.DNSRecord{
|
||
Proxied: false, // 默认不代理
|
||
TTL: 1, // 默认自动TTL
|
||
}
|
||
|
||
// 获取记录名称
|
||
fmt.Print("请输入记录名称 (例如: www): ")
|
||
name, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return record, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
name = strings.TrimSpace(name)
|
||
|
||
// 如果用户仅输入@,则使用根域名
|
||
if name == "@" {
|
||
record.Name = domain
|
||
} else if name != "" {
|
||
// 否则添加域名后缀
|
||
record.Name = name + "." + domain
|
||
} else {
|
||
return record, fmt.Errorf("记录名称不能为空")
|
||
}
|
||
|
||
// 获取记录类型
|
||
fmt.Printf("请选择记录类型:\n")
|
||
fmt.Printf("1) A (IPv4地址)\n")
|
||
fmt.Printf("2) AAAA (IPv6地址)\n")
|
||
fmt.Printf("3) CNAME (别名)\n")
|
||
fmt.Printf("4) TXT (文本记录)\n")
|
||
fmt.Printf("5) MX (邮件服务器)\n")
|
||
fmt.Printf("6) SRV (服务记录)\n")
|
||
fmt.Print("请输入选项 (1-6): ")
|
||
typeChoice, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return record, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
typeChoice = strings.TrimSpace(typeChoice)
|
||
|
||
switch typeChoice {
|
||
case "1":
|
||
record.Type = DNSTypeA
|
||
case "2":
|
||
record.Type = DNSTypeAAAA
|
||
case "3":
|
||
record.Type = DNSTypeCNAME
|
||
case "4":
|
||
record.Type = DNSTypeTXT
|
||
case "5":
|
||
record.Type = DNSTypeMX
|
||
case "6":
|
||
record.Type = DNSTypeSRV
|
||
default:
|
||
return record, fmt.Errorf("无效的记录类型选择")
|
||
}
|
||
|
||
// 获取记录内容
|
||
fmt.Printf("请输入记录内容 (%s): ", getContentHint(record.Type))
|
||
content, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return record, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
content = strings.TrimSpace(content)
|
||
if content == "" {
|
||
return record, fmt.Errorf("记录内容不能为空")
|
||
}
|
||
record.Content = content
|
||
|
||
// 对于MX记录,获取优先级
|
||
if record.Type == DNSTypeMX {
|
||
fmt.Print("请输入优先级 (1-100,默认10): ")
|
||
priorityStr, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return record, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
priorityStr = strings.TrimSpace(priorityStr)
|
||
|
||
priority := 10 // 默认优先级
|
||
if priorityStr != "" {
|
||
p, err := strconv.Atoi(priorityStr)
|
||
if err != nil {
|
||
return record, fmt.Errorf("无效的优先级: %w", err)
|
||
}
|
||
if p < 1 || p > 100 {
|
||
return record, fmt.Errorf("优先级必须在1到100之间")
|
||
}
|
||
priority = p
|
||
}
|
||
record.Priority = priority
|
||
}
|
||
|
||
// 获取TTL
|
||
fmt.Print("请输入TTL (1表示自动,最小值120,建议值1800或3600): ")
|
||
ttlStr, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return record, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
ttlStr = strings.TrimSpace(ttlStr)
|
||
|
||
if ttlStr != "" {
|
||
ttl, err := strconv.Atoi(ttlStr)
|
||
if err != nil {
|
||
return record, fmt.Errorf("无效的TTL: %w", err)
|
||
}
|
||
if ttl != 1 && ttl < 120 {
|
||
return record, fmt.Errorf("TTL不能小于120")
|
||
}
|
||
record.TTL = ttl
|
||
}
|
||
|
||
// 对于A,AAAA或CNAME记录,询问是否代理
|
||
if record.Type == DNSTypeA || record.Type == DNSTypeAAAA || record.Type == DNSTypeCNAME {
|
||
fmt.Print("是否通过Cloudflare代理 (y/n,默认n): ")
|
||
proxyStr, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return record, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
proxyStr = strings.ToLower(strings.TrimSpace(proxyStr))
|
||
if proxyStr == "y" || proxyStr == "yes" {
|
||
record.Proxied = true
|
||
}
|
||
}
|
||
|
||
// 获取备注(可选)
|
||
fmt.Print("请输入备注 (可选): ")
|
||
comment, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return record, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
comment = strings.TrimSpace(comment)
|
||
if comment != "" {
|
||
record.Comment = comment
|
||
}
|
||
|
||
return record, nil
|
||
}
|
||
|
||
// 更新DNS记录信息
|
||
func updateDNSRecordInfo(currentRecord cloudflare.DNSRecord) (cloudflare.DNSRecord, error) {
|
||
reader := bufio.NewReader(os.Stdin)
|
||
updatedRecord := currentRecord
|
||
|
||
// 获取记录内容
|
||
fmt.Printf("请输入新的记录内容 (%s) [当前值: %s]: ", getContentHint(currentRecord.Type), currentRecord.Content)
|
||
content, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return updatedRecord, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
content = strings.TrimSpace(content)
|
||
if content != "" {
|
||
updatedRecord.Content = content
|
||
}
|
||
|
||
// 对于MX记录,获取优先级
|
||
if currentRecord.Type == DNSTypeMX {
|
||
fmt.Printf("请输入新的优先级 (1-100) [当前值: %d]: ", currentRecord.Priority)
|
||
priorityStr, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return updatedRecord, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
priorityStr = strings.TrimSpace(priorityStr)
|
||
|
||
if priorityStr != "" {
|
||
p, err := strconv.Atoi(priorityStr)
|
||
if err != nil {
|
||
return updatedRecord, fmt.Errorf("无效的优先级: %w", err)
|
||
}
|
||
if p < 1 || p > 100 {
|
||
return updatedRecord, fmt.Errorf("优先级必须在1到100之间")
|
||
}
|
||
updatedRecord.Priority = p
|
||
}
|
||
}
|
||
|
||
// 获取TTL
|
||
ttlStr := "自动"
|
||
if currentRecord.TTL > 1 {
|
||
ttlStr = strconv.Itoa(currentRecord.TTL)
|
||
}
|
||
fmt.Printf("请输入新的TTL (1表示自动,最小值120,建议值1800或3600) [当前值: %s]: ", ttlStr)
|
||
newTTLStr, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return updatedRecord, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
newTTLStr = strings.TrimSpace(newTTLStr)
|
||
|
||
if newTTLStr != "" {
|
||
ttl, err := strconv.Atoi(newTTLStr)
|
||
if err != nil {
|
||
return updatedRecord, fmt.Errorf("无效的TTL: %w", err)
|
||
}
|
||
if ttl != 1 && ttl < 120 {
|
||
return updatedRecord, fmt.Errorf("TTL不能小于120")
|
||
}
|
||
updatedRecord.TTL = ttl
|
||
}
|
||
|
||
// 对于A,AAAA或CNAME记录,询问是否代理
|
||
if currentRecord.Type == DNSTypeA || currentRecord.Type == DNSTypeAAAA || currentRecord.Type == DNSTypeCNAME {
|
||
proxyStr := "n"
|
||
if currentRecord.Proxied {
|
||
proxyStr = "y"
|
||
}
|
||
fmt.Printf("是否通过Cloudflare代理 (y/n) [当前值: %s]: ", proxyStr)
|
||
newProxyStr, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return updatedRecord, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
newProxyStr = strings.ToLower(strings.TrimSpace(newProxyStr))
|
||
if newProxyStr != "" {
|
||
if newProxyStr == "y" || newProxyStr == "yes" {
|
||
updatedRecord.Proxied = true
|
||
} else if newProxyStr == "n" || newProxyStr == "no" {
|
||
updatedRecord.Proxied = false
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取备注(可选)
|
||
fmt.Printf("请输入新的备注 (可选) [当前值: %s]: ", currentRecord.Comment)
|
||
comment, err := reader.ReadString('\n')
|
||
if err != nil {
|
||
return updatedRecord, fmt.Errorf("读取输入失败: %w", err)
|
||
}
|
||
comment = strings.TrimSpace(comment)
|
||
if comment != "" {
|
||
updatedRecord.Comment = comment
|
||
}
|
||
|
||
return updatedRecord, nil
|
||
}
|
||
|
||
// 根据记录类型获取内容提示
|
||
func getContentHint(recordType string) string {
|
||
switch recordType {
|
||
case DNSTypeA:
|
||
return "IPv4地址,例如: 192.168.1.1"
|
||
case DNSTypeAAAA:
|
||
return "IPv6地址,例如: 2001:db8::1"
|
||
case DNSTypeCNAME:
|
||
return "域名,例如: example.com"
|
||
case DNSTypeTXT:
|
||
return "文本内容"
|
||
case DNSTypeMX:
|
||
return "邮件服务器域名,例如: mail.example.com"
|
||
case DNSTypeSRV:
|
||
return "SRV记录,例如: 10 5 5060 sip.example.com"
|
||
default:
|
||
return "记录内容"
|
||
}
|
||
}
|