This commit is contained in:
ZhuoQinghui 2024-12-27 14:02:58 +08:00
parent 55d241b873
commit e6d412c114
12 changed files with 363 additions and 75 deletions

View File

@ -31,7 +31,7 @@ func InitCmd() (*cobra.Command, error) {
//rootCmd.GenPowerShellCompletion(os.Stdout)
//rootCmd.GenZshCompletion(os.Stdout)
conf.InitAppConfig()
conf.LoadAppConfig()
err := rootCmd.Execute()
return rootCmd, err
@ -61,10 +61,13 @@ func initConfCmd() *cobra.Command {
func initServerCmd() *cobra.Command {
serverCmd := &cobra.Command{
Use: "server",
Short: "服务相关命令",
Long: "配置服务相关参数, 如监听端口,监听地址等",
Short: "服务命令",
Long: "acme-mana服务端相关命令, 配置服务相关参数, 如监听端口,监听地址等",
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
err := cmd.Help()
if err != nil {
return
}
},
}
editCmd := &cobra.Command{
@ -274,7 +277,7 @@ func acmeCmd() *cobra.Command {
acmeCmd := &cobra.Command{
Use: "acme",
Short: "ACME相关命令",
Long: "ACME相关命令",
Long: "acme.sh原生命令",
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
},

View File

@ -1,10 +1,7 @@
package common
import (
"acme-mana/src/model"
"github.com/spf13/cobra"
)
var RootCmd *cobra.Command
var AppConf *model.AppConfig

63
src/conf/conf.go Normal file
View File

@ -0,0 +1,63 @@
package conf
// AppConfig
// 配置文件
type AppConfig struct {
// 服务器配置
Server *ServerConf `json:"server" yaml:"server"`
// 网页配置
Web *WebConf `json:"web" yaml:"web"`
// 任务配置
Task *TaskConf `json:"task" yaml:"task"`
// 认证配置
Providers *[]ProviderConf `json:"provider" yaml:"provider"`
// 证书配置
Certs *[]CertConf `json:"cert" yaml:"cert"`
}
// ServerConf 服务端配置
type ServerConf struct {
// 监听地址
Host string `json:"host" yaml:"host"`
// 监听端口
Port int `json:"port" yaml:"port"`
// 通信密钥, DES 加密
Key string `json:"key" yaml:"key"`
}
// WebConf 网页服务配置
type WebConf struct {
// 是否启用
Enable bool `json:"enable" yaml:"enable"`
// 监听地址
Host string `json:"host" yaml:"host"`
// 监听端口
Port int `json:"port" yaml:"port"`
}
// TaskConf 定时任务配置
type TaskConf struct {
// 启动延迟时间, 单位: 毫秒, 默认: 0
Delay int `json:"delay" yaml:"delay"`
// 间隔时间
Interval int `json:"interval" yaml:"interval"`
}
// ProviderConf 三方认证配置
type ProviderConf struct {
// 认证名称
Name string `json:"name" yaml:"name"`
// 认证类型
Type string `json:"type" yaml:"type"`
// 认证配置
Conf map[string]string `json:"conf" yaml:"conf"`
}
// CertConf 证书配置
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"`
}

129
src/conf/func.go Normal file
View File

@ -0,0 +1,129 @@
package conf
import "log"
func Config() *AppConfig {
return appConf
}
func EditServer(host string, port int, key string) *AppConfig {
appConf.Server.Host = host
appConf.Server.Port = port
appConf.Server.Key = key
WriteConfig()
return appConf
}
func EditWeb(host string, port int) *AppConfig {
appConf.Web.Host = host
appConf.Web.Port = port
WriteConfig()
return appConf
}
func ExecWeb(run bool) *AppConfig {
appConf.Web.Enable = run
WriteConfig()
return appConf
}
func EditTask(delay int, interval int) *AppConfig {
appConf.Task.Delay = delay
appConf.Task.Interval = interval
WriteConfig()
return appConf
}
func FindProvider(name string) (*ProviderConf, int) {
for index, provider := range *appConf.Providers {
if provider.Name == name {
return &provider, index
}
}
return nil, -1
}
func AddProvider(name string, typeName string, conf map[string]string) *AppConfig {
provider, _ := FindProvider(name)
if provider != nil {
log.Fatal("已存在相同名称的配置")
return nil
}
provider = &ProviderConf{
Name: name,
Type: typeName,
Conf: conf,
}
providers := *appConf.Providers
newProviders := append(providers, *provider)
appConf.Providers = &newProviders
return appConf
}
func EditProvider(name string, typeName string, conf map[string]string) *AppConfig {
provider, _ := FindProvider(name)
if provider == nil {
log.Fatal("不存在该配置")
return nil
}
provider.Type = typeName
provider.Conf = conf
WriteConfig()
return appConf
}
func RmProvider(name string) *AppConfig {
_, index := FindProvider(name)
if index == -1 {
log.Fatal("不存在该配置")
}
providers := *appConf.Providers
newProviders := append(providers[:index], providers[index+1:]...)
appConf.Providers = &newProviders
return appConf
}
func FindCert(name string) (*CertConf, int) {
for index, cert := range *appConf.Certs {
if cert.Name == name {
return &cert, index
}
}
return nil, -1
}
func FindCertByProvider(provider string) *[]CertConf {
var result []CertConf
for _, cert := range *appConf.Certs {
if cert.Provider == provider {
result = append(result, cert)
}
}
return &result
}
func AddCert(cert *CertConf) *AppConfig {
certs := *appConf.Certs
newCerts := append(certs, *cert)
appConf.Certs = &newCerts
return appConf
}
func EditCert(name string, cert *CertConf) *AppConfig {
_, index := FindCert(name)
if index == -1 {
log.Fatal("不存在该配置")
}
certs := *appConf.Certs
certs[index] = *cert
appConf.Certs = &certs
return appConf
}
func RmCert(name string) *AppConfig {
_, index := FindCert(name)
if index == -1 {
log.Fatal("不存在该配置")
}
certs := *appConf.Certs
newCerts := append(certs[:index], certs[index+1:]...)
appConf.Certs = &newCerts
return appConf
}

View File

@ -2,54 +2,43 @@ 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) {
func LoadAppConfig() {
// 读取配置文件位置
confFile := getConfFile()
// 判断配资文件是否存在
if _, err := os.Stat(confFile); os.IsNotExist(err) {
log.Println("配置文件不存在, 自动创建")
writeConf(c, confFile)
config := defaultAppConfig()
log.Println("默认配置文件创建成功")
log.Println("服务器通信密钥: " + config.Server.Key)
appConf = config
writeConf(appConf, confFile)
} else {
appConf = readAppConfig(appConf)
}
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()
}
// RefreshConfig 刷新配置
func RefreshConfig() {
readAppConfig(common.AppConf)
readAppConfig(appConf)
}
// WriteConfig 写入配置文件
func WriteConfig() {
confFile, err := common.RootCmd.PersistentFlags().GetString("conf")
if err != nil {
log.Fatalln("读取配置文件参数失败")
}
writeConf(common.AppConf, confFile)
writeConf(appConf, confFile)
}
func writeConf(c *model.AppConfig, file string) {
func writeConf(c *AppConfig, file string) {
out, err := yaml.Marshal(c)
if err != nil {
log.Fatalln("序列化配置文件失败")
@ -61,13 +50,22 @@ func writeConf(c *model.AppConfig, file string) {
}
}
func DefaultAppConfig() *model.AppConfig {
return &model.AppConfig{
Server: &model.ServerConf{
// DefaultAppConfig 默认配置
func defaultAppConfig() *AppConfig {
serverKey := util.RandomStr(32)
return &AppConfig{
Server: &ServerConf{
Host: "0.0.0.0",
Port: 36851,
Key: serverKey,
},
Task: &model.TaskConf{
Web: &WebConf{
Enable: false,
Host: "0.0.0.0",
Port: 36852,
},
Task: &TaskConf{
Delay: 0,
Interval: 0,
},
@ -75,3 +73,27 @@ func DefaultAppConfig() *model.AppConfig {
Providers: nil,
}
}
// getConfFile 获取配置文件位置
func getConfFile() string {
confFile, err := common.RootCmd.PersistentFlags().GetString("conf")
if err != nil {
log.Fatalln("读取配置文件参数失败")
}
return confFile
}
// readAppConfig 读取配置文件
func readAppConfig(c *AppConfig) *AppConfig {
confFile := getConfFile()
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
}

3
src/conf/variable.go Normal file
View File

@ -0,0 +1,3 @@
package conf
var appConf *AppConfig

View File

@ -11,7 +11,10 @@ var service *gin.Engine
var isRunning bool
func Start() {
if isRunning {
return
}
go start()
}
func Stop() {

View File

@ -1,34 +0,0 @@
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"`
}

18
src/server/handle/cert.go Normal file
View File

@ -0,0 +1,18 @@
package handle
import (
"github.com/gin-gonic/gin"
"log"
)
func GetCert(context *gin.Context) {
log.Println("get cert")
}
func RefreshCert(context *gin.Context) {
log.Fatalln("refresh cert")
}
func domainList(context *gin.Context) {
log.Fatalln("domain list")
}

64
src/server/http-server.go Normal file
View File

@ -0,0 +1,64 @@
package server
import (
"acme-mana/src/conf"
"acme-mana/src/server/handle"
"context"
"errors"
"github.com/gin-gonic/gin"
"log"
"net/http"
"strconv"
"time"
)
type HttpServer struct {
server *http.Server `json:"server"`
status bool
engine *gin.Engine
}
func (s *HttpServer) InitServer() {
s.engine = gin.Default()
s.register()
s.status = false
config := conf.Config()
var serverConf = config.Server
s.server = &http.Server{
Addr: serverConf.Host + ":" + strconv.Itoa(serverConf.Port),
Handler: s.engine,
}
}
func (s *HttpServer) Start() {
go func() {
if err := s.server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
log.Printf("listen: %s\n\n", err)
s.status = true
} else {
s.status = false
}
}()
}
func (s *HttpServer) Stop() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
err := httpServer.server.Shutdown(ctx)
s.status = false
if err != nil {
log.Fatalln("Server Shutdown:", err)
}
}
func Status() bool {
return httpServer.status
}
func (s *HttpServer) register() {
service := s.engine
service.GET("/api/v1/refresh", handle.RefreshCert)
service.GET("/api/v1/cert", handle.GetCert)
service.GET("/api/v1/domain/list", handle.GetCert)
}

3
src/server/variable.go Normal file
View File

@ -0,0 +1,3 @@
package server
var httpServer *HttpServer

17
src/util/random.go Normal file
View File

@ -0,0 +1,17 @@
package util
import (
"math/rand"
"time"
)
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
func RandomStr(size int) string {
rand.NewSource(time.Now().UnixNano())
b := make([]byte, size)
for i := range b {
b[i] = letterBytes[rand.Intn(len(letterBytes))]
}
return string(b)
}