diff --git a/.run/block.run.xml b/.run/block.run.xml new file mode 100644 index 0000000..e3a07c0 --- /dev/null +++ b/.run/block.run.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.run/build-darwin-amd64.run.xml b/.run/build-darwin-amd64.run.xml new file mode 100644 index 0000000..895c613 --- /dev/null +++ b/.run/build-darwin-amd64.run.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.run/build-linux-amd64.run.xml b/.run/build-linux-amd64.run.xml new file mode 100644 index 0000000..d39a4d6 --- /dev/null +++ b/.run/build-linux-amd64.run.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.run/build-windows-amd64.run.xml b/.run/build-windows-amd64.run.xml new file mode 100644 index 0000000..a4105ed --- /dev/null +++ b/.run/build-windows-amd64.run.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.run/conf show.run.xml b/.run/conf show.run.xml new file mode 100644 index 0000000..7093a03 --- /dev/null +++ b/.run/conf show.run.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.run/help.run.xml b/.run/help.run.xml new file mode 100644 index 0000000..6df1753 --- /dev/null +++ b/.run/help.run.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/cmd/cmd.go b/src/cmd/cmd.go index f38737a..545785c 100644 --- a/src/cmd/cmd.go +++ b/src/cmd/cmd.go @@ -1,7 +1,10 @@ package cmd import ( + "acme-mana/src/common" + "acme-mana/src/conf" "github.com/spf13/cobra" + "os" ) func InitCmd() (*cobra.Command, error) { @@ -10,6 +13,7 @@ func InitCmd() (*cobra.Command, error) { Short: "ACME协议客户端", Long: "基于 ACME 协议实现自动申请证书和续签证书", } + common.RootCmd = rootCmd rootCmd.AddCommand(initConfCmd()) rootCmd.AddCommand(initServerCmd()) @@ -18,7 +22,14 @@ func InitCmd() (*cobra.Command, error) { rootCmd.AddCommand(certCmd()) rootCmd.AddCommand(acmeCmd()) + flags := rootCmd.PersistentFlags() + flags.BoolP("force", "f", false, "强制执行") + flags.StringP("conf", "c", "config.yml", "指定配置文件") + _ = rootCmd.ParseFlags(os.Args) + + conf.InitAppConfig() err := rootCmd.Execute() + return rootCmd, err } diff --git a/src/cmd/handler.go b/src/cmd/handler.go index 0315c76..cc4ee38 100644 --- a/src/cmd/handler.go +++ b/src/cmd/handler.go @@ -1,12 +1,21 @@ package cmd import ( + "acme-mana/src/common" + "encoding/json" "fmt" + tea "github.com/charmbracelet/bubbletea" "github.com/spf13/cobra" ) +// 打印 配置信息 func confShow(cmd *cobra.Command, args []string) { - fmt.Println("show conf") + tea.Println() + confJson, err := json.MarshalIndent(common.AppConf, "", " ") + if err != nil { + fmt.Println("序列化配置信息失败:", err) + } + fmt.Println(string(confJson)) } func editServer(cmd *cobra.Command, args []string) { diff --git a/src/common/variable.go b/src/common/variable.go new file mode 100644 index 0000000..93aa393 --- /dev/null +++ b/src/common/variable.go @@ -0,0 +1,10 @@ +package common + +import ( + "acme-mana/src/model" + "github.com/spf13/cobra" +) + +var RootCmd *cobra.Command + +var AppConf *model.AppConfig diff --git a/src/conf/util.go b/src/conf/util.go new file mode 100644 index 0000000..28e6b5b --- /dev/null +++ b/src/conf/util.go @@ -0,0 +1,69 @@ +package conf + +import ( + "acme-mana/src/common" + "acme-mana/src/model" + "acme-mana/src/util" + "gopkg.in/yaml.v3" + "log" + "os" +) + +func readAppConfig(c *model.AppConfig) *model.AppConfig { + confFile, err := common.RootCmd.PersistentFlags().GetString("conf") + if err != nil { + log.Fatalln("读取配置文件参数失败") + } + + _, err = os.Stat(confFile) + if os.IsNotExist(err) { + log.Println("配置文件不存在, 自动创建") + writeConf(c, confFile) + } + + file, err := os.ReadFile(confFile) + if err != nil { + log.Fatalln("读取配置文件失败") + } + //var conf = &model.AppConfig{} + err = yaml.Unmarshal(file, c) + if err != nil { + log.Fatalln("解析配置文件失败") + } + return c +} + +func InitAppConfig() { + common.AppConf = DefaultAppConfig() +} + +func RefreshConfig() { + readAppConfig(common.AppConf) +} + +func writeConf(c *model.AppConfig, file string) { + out, err := yaml.Marshal(c) + if err != nil { + log.Fatalln("序列化配置文件失败") + } + util.MkFileDir(file) + err = os.WriteFile(file, out, 0644) + if err != nil { + log.Fatalln("写入配置文件失败") + } +} + +func DefaultAppConfig() *model.AppConfig { + return &model.AppConfig{ + Server: &model.ServerConf{ + Host: "0.0.0.0", + Port: 36851, + }, + Task: &model.TaskConf{ + Delay: 0, + Interval: 0, + }, + Certs: nil, + Providers: nil, + } +} diff --git a/src/config.go b/src/config.go index 564dcf1..0b44c59 100644 --- a/src/config.go +++ b/src/config.go @@ -12,6 +12,9 @@ import ( ) func ReadConfig() *AppConfig { + if DnsProviderSupports != nil { + return nil + } InitConfig() file, err := os.ReadFile(GetEnvConf().ConfFile) if err != nil { diff --git a/src/daemon.go b/src/daemon.go index 4245670..960e92e 100644 --- a/src/daemon.go +++ b/src/daemon.go @@ -2,7 +2,6 @@ package src import ( "encoding/json" - tea "github.com/charmbracelet/bubbletea" "log" "net" "os" @@ -76,20 +75,6 @@ func initLog() { } func showHelp() { - tea.Println("") - log.Printf(` - Usage: acme-mana [command] [options] - Commands: - help Show this help message - start Start the daemon - stop Stop the daemon - status Check the status of the daemon - dump Dump the configuration file - domains List all domains - pubkey Show the public key - apply Manually apply for a certificate - block Block the - `) } // 守护进程启动 diff --git a/src/model/conf.go b/src/model/conf.go new file mode 100644 index 0000000..d291e95 --- /dev/null +++ b/src/model/conf.go @@ -0,0 +1,34 @@ +package model + +type AppConfig struct { + Server *ServerConf `json:"server" yaml:"server"` + Task *TaskConf `json:"task" yaml:"task"` + Certs *[]CertConf `json:"cert" yaml:"cert"` + Providers *[]ProviderConf `json:"provider" yaml:"provider"` +} + +type ServerConf struct { + Host string `json:"host" yaml:"host"` + Port int `json:"port" yaml:"port"` +} + +type TaskConf struct { + // 启动延迟时间, 单位: 毫秒, 默认: 0 + Delay int `json:"delay" yaml:"delay"` + // 间隔时间 + Interval int `json:"interval" yaml:"interval"` +} + +type ProviderConf struct { + Name string `json:"name" yaml:"name"` + Type string `json:"type" yaml:"type"` + Conf map[string]string `json:"conf" yaml:"conf"` +} + +type CertConf struct { + Name string `json:"name" yaml:"name"` + Provider string `json:"use" yaml:"provider"` + Dir string `json:"dir" yaml:"dir"` + Email string `json:"email" yaml:"email"` + Host []string `json:"host" yaml:"host"` +} diff --git a/src/util/file-util.go b/src/util/file-util.go new file mode 100644 index 0000000..c2f9745 --- /dev/null +++ b/src/util/file-util.go @@ -0,0 +1,18 @@ +package util + +import ( + "log" + "os" + "path/filepath" +) + +// MkFileDir 创建文件所在的目录 +func MkFileDir(file string) { + dir := filepath.Dir(file) + if _, err := os.Stat(dir); os.IsNotExist(err) { + err := os.MkdirAll(dir, 0755) + if err != nil { + log.Fatal("创建目录失败!", err) + } + } +}