更新工作区配置,删除不再使用的Cloudflare相关文件,优化日志输出格式,增强主机信息收集功能,调整代码结构以提高可维护性。

This commit is contained in:
zeaslity
2025-03-28 00:15:08 +08:00
parent c2ca7eb6d7
commit 6816638267
19 changed files with 847 additions and 155 deletions

View File

@@ -40,7 +40,7 @@ func addAcmeSubcommands(cmd *cobra.Command) {
"/tmp/acme.sh",
)
if !ok {
log.Error("下载acme.sh失败", err)
log.Error("下载acme.sh失败 %v", err)
return
}
@@ -105,7 +105,7 @@ func addAcmeSubcommands(cmd *cobra.Command) {
// 执行命令
ok, output := op.SingleLineCommandExecutor([]string{"/root/.acme.sh/acme.sh", "--list"})
if !ok {
log.Error("列出acme全部的证书失败", output)
log.Error("列出acme全部的证书失败 %v", output)
return
}

View File

@@ -2,7 +2,7 @@ package cmd
import (
"agent-wdd/cmd/beans"
"agent-wdd/config"
"agent-wdd/host_info"
"agent-wdd/log"
"agent-wdd/op"
"agent-wdd/utils"
@@ -96,13 +96,13 @@ func addBaseSubcommands(cmd *cobra.Command) {
log.Info("Selinux 关闭!")
// 如果configCache的OS为空则收集OS信息
if config.ConfigCache.Agent.OS.Hostname == "" {
if host_info.ConfigCache.Agent.OS.Hostname == "" {
log.Warning("ConfigCache OS is nil")
config.ConfigCache.Agent.OS.Gather()
config.ConfigCache.Agent.OS.SaveConfig()
host_info.ConfigCache.Agent.OS.Gather()
host_info.ConfigCache.Agent.OS.SaveConfig()
}
os := config.ConfigCache.Agent.OS
os := host_info.ConfigCache.Agent.OS
if os.IsUbuntuType {
log.Info("Ubuntu 系统跳过关闭selinux")
return
@@ -234,7 +234,7 @@ func addBaseSubcommands(cmd *cobra.Command) {
log.Info("Common tool installation!")
// Whether It can connect to internet
if config.CanConnectInternet() <= 1 {
if host_info.CanConnectInternet() <= 1 {
log.Error("服务器无法连接互联网无法执行tools")
return
}
@@ -244,7 +244,7 @@ func addBaseSubcommands(cmd *cobra.Command) {
packOperator := op.AgentPackOperator
packOperator.PackageInit()
os := config.ConfigCache.Agent.OS
os := host_info.ConfigCache.Agent.OS
if os.IsUbuntuType {
packOperator.Install(ubuntuCommonTools)
} else {
@@ -299,7 +299,7 @@ func addHarborSubcommands(harborCmd *cobra.Command) {
utils.UnzipFile(harborLocalInstallPath, "/root/wdd/")
// 获取本机的内网IPv4地址
configCache := config.ConfigCache
configCache := host_info.ConfigCache
if len(configCache.Agent.Network.Interfaces) == 0 {
log.Error("没有获取到本机的ipv4地址无法安装harbor! 请执行 info all !")
}
@@ -596,7 +596,7 @@ func addDockerSubcommands(cmd *cobra.Command) {
packOperator := op.AgentPackOperator
packOperator.PackageInit()
configCache := config.ConfigCache
configCache := host_info.ConfigCache
if configCache.Agent.OS.IsUbuntuType {
// 安装apt-transport-https ca-certificates curl gnupg software-properties-common 依赖部分
packOperator.Install([]string{"apt-transport-https", "ca-certificates", "curl", "gnupg", "software-properties-common"})
@@ -886,7 +886,7 @@ func addDockerSubcommands(cmd *cobra.Command) {
}
// 获取当前内网IP
ip := config.ConfigCache.Agent.Network.Interfaces[0].IPv4
ip := host_info.ConfigCache.Agent.Network.Interfaces[0].IPv4
if ip == "" {
log.Error("获取当前内网IP失败, 无法进行docker config配置")
return
@@ -956,7 +956,7 @@ func addDockerComposeSubcommands(cmd *cobra.Command) {
log.Info("安装 Docker Compose 版本: %s", version)
// 检查是否可以连接互联网
if config.CanConnectInternet() <= 1 {
if host_info.CanConnectInternet() <= 1 {
log.Error("服务器无法连接互联网,无法在线安装 Docker Compose")
return
}

View File

@@ -11,28 +11,17 @@ import (
"github.com/spf13/cobra"
)
var (
const (
// 证书管理命令选项
cfAPIToken string
certDir string
emailAddr string
caServer string
daysRenewal int
cfAPIToken = "T7LxBemfe8SNGWkT9uz2XIc1e22ifAbBv_POJvDP"
certDir = "/root/wdd/cert_manager_wdd/"
emailAddr = "wdd@gmail.com"
caServer = "zerossl"
daysRenewal = 30
)
// 初始化证书管理配置
func initCertManagerConfig() *cert_manager_wdd.CertManager {
// 如果未指定API令牌提示用户
if cfAPIToken == "" {
log.Error("未指定Cloudflare API令牌请使用--token参数设置")
os.Exit(1)
}
// 如果未指定邮箱地址,使用默认值
if emailAddr == "" {
emailAddr = "cert@example.com"
log.Warning("未指定邮箱地址,使用默认值: %s", emailAddr)
}
// 创建证书管理器
certManager := cert_manager_wdd.NewCertManager(certDir, cfAPIToken, emailAddr)
@@ -59,12 +48,6 @@ func initCertManagerConfig() *cert_manager_wdd.CertManager {
// 添加证书管理命令
func addCertManagerSubcommands(cmd *cobra.Command) {
// 全局标志
cmd.PersistentFlags().StringVar(&cfAPIToken, "token", "", "Cloudflare API令牌")
cmd.PersistentFlags().StringVar(&certDir, "cert-dir", "", "证书保存目录")
cmd.PersistentFlags().StringVar(&emailAddr, "email", "", "申请证书使用的邮箱")
cmd.PersistentFlags().StringVar(&caServer, "ca", "letsencrypt", "CA服务器 (letsencrypt, zerossl)")
cmd.PersistentFlags().IntVar(&daysRenewal, "days", 30, "证书更新阈值天数")
// 申请证书命令
applyCmd := &cobra.Command{

723
agent-wdd/cmd/Cloudflare.go Normal file
View File

@@ -0,0 +1,723 @@
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
}
// 对于AAAAA或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
}
// 对于AAAAA或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 "记录内容"
}
}

View File

@@ -1,7 +1,7 @@
package cmd
import (
"agent-wdd/config"
"agent-wdd/host_info"
"github.com/spf13/cobra"
)
@@ -13,7 +13,7 @@ func addInfoSubcommands(cmd *cobra.Command) {
Use: "os",
Short: "主机操作系统相关的信息",
Run: func(cmd *cobra.Command, args []string) {
os := config.ConfigCache.Agent.OS
os := host_info.ConfigCache.Agent.OS
os.Gather()
os.SaveConfig()
@@ -25,7 +25,7 @@ func addInfoSubcommands(cmd *cobra.Command) {
Use: "network",
Short: "主机Network相关的信息",
Run: func(cmd *cobra.Command, args []string) {
network := config.ConfigCache.Agent.Network
network := host_info.ConfigCache.Agent.Network
network.Gather()
network.SaveConfig()
},
@@ -36,7 +36,7 @@ func addInfoSubcommands(cmd *cobra.Command) {
Use: "cpu",
Short: "主机cpu相关的信息",
Run: func(cmd *cobra.Command, args []string) {
cpu := config.ConfigCache.Agent.CPU
cpu := host_info.ConfigCache.Agent.CPU
cpu.Gather()
cpu.Save()
},
@@ -47,9 +47,9 @@ func addInfoSubcommands(cmd *cobra.Command) {
Use: "mem",
Short: "主机memory相关的信息",
Run: func(cmd *cobra.Command, args []string) {
mem := config.ConfigCache.Agent.Mem
mem := host_info.ConfigCache.Agent.Mem
mem.Gather()
swap := config.ConfigCache.Agent.Swap
swap := host_info.ConfigCache.Agent.Swap
swap.Gather()
mem.SaveConfig()
@@ -63,10 +63,10 @@ func addInfoSubcommands(cmd *cobra.Command) {
Use: "disk",
Short: "主机disk相关的信息",
Run: func(cmd *cobra.Command, args []string) {
//disks := config.ConfigCache.Agent.Disks
config.DiskListGather()
//disks := host_info.ConfigCache.Agent.Disks
host_info.DiskListGather()
config.DiskListSaveConfig()
host_info.DiskListSaveConfig()
},
}
@@ -83,7 +83,7 @@ func addInfoSubcommands(cmd *cobra.Command) {
disk.Run(cmd, args)
// 归一化
config.ConfigCache.NormalizeConfig()
host_info.ConfigCache.NormalizeConfig()
},
}

View File

@@ -2,7 +2,7 @@ package cmd
import (
"agent-wdd/cmd/xray"
"agent-wdd/config"
"agent-wdd/host_info"
"agent-wdd/log"
"agent-wdd/op"
"agent-wdd/utils"
@@ -229,7 +229,7 @@ func installVmess(port string) (bool, []string) {
result.Reset() // 清空全局buffer以备后续使用
// 输出 client的配置
configCache := config.ConfigCache
configCache := host_info.ConfigCache
// 获取服务器节点名称
serverNodeName := configCache.Agent.OS.Hostname

View File

@@ -1,7 +1,7 @@
package cmd
import (
"agent-wdd/config"
"agent-wdd/host_info"
"agent-wdd/log"
"agent-wdd/op"
"agent-wdd/utils"
@@ -16,14 +16,14 @@ func addZshSubcommands(cmd *cobra.Command) {
// 初始化安装命令
utils.CreateFolder("/root/wdd")
if config.CanConnectInternet() <= 1 {
if host_info.CanConnectInternet() <= 1 {
log.Error("无法连接互联网无法安装zsh")
return
}
// 判定config
if config.ConfigCache.Agent.Network.Public.IPv4 == "" {
network := config.ConfigCache.Agent.Network
if host_info.ConfigCache.Agent.Network.Public.IPv4 == "" {
network := host_info.ConfigCache.Agent.Network
network.Gather()
network.SaveConfig()
}
@@ -41,7 +41,7 @@ func addZshSubcommands(cmd *cobra.Command) {
ohMyZshInstallUrl := ""
if config.ConfigCache.Agent.Network.Internet == 7 {
if host_info.ConfigCache.Agent.Network.Internet == 7 {
ohMyZshInstallUrl = "https://gitea.107421.xyz/zeaslity/ohmyzsh/raw/branch/master/tools/install.sh"
} else {
ohMyZshInstallUrl = "https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh"
@@ -65,7 +65,7 @@ func addZshSubcommands(cmd *cobra.Command) {
"/root/wdd/zsh-install.sh",
}
if config.ConfigCache.Agent.Network.Internet == 7 {
if host_info.ConfigCache.Agent.Network.Internet == 7 {
op.SingleLineCommandExecutor([]string{
"export",
"REMOTE=https://gitea.107421.xyz/zeaslity/ohmyzsh.git",
@@ -106,7 +106,7 @@ func addZshSubcommands(cmd *cobra.Command) {
}
// 下载插件
if config.ConfigCache.Agent.Network.Internet == 7 {
if host_info.ConfigCache.Agent.Network.Internet == 7 {
// 执行硬编码命令, 安装插件
for _, command := range pluginsHardCodeUrl {
op.SingleLineCommandExecutor([]string{"git", "clone", command[0], command[1]})

View File

@@ -1,7 +1,7 @@
package cmd
import (
"agent-wdd/config"
"agent-wdd/host_info"
"fmt"
"io"
"os"
@@ -26,7 +26,7 @@ var rootCmd = &cobra.Command{
func init() {
// 初始化配置
cobra.OnInitialize(config.InitConfig)
cobra.OnInitialize(host_info.InitConfig)
}
func Execute() {
@@ -111,6 +111,9 @@ func Execute() {
}
addCertManagerSubcommands(certCmd)
// 添加Cloudflare命令
addCloudflareSubcommands(rootCmd)
helpCmd := &cobra.Command{
Use: "help",
Short: "帮助信息",