init
This commit is contained in:
commit
b10790c212
40 changed files with 4149 additions and 0 deletions
152
gen/init.go
Normal file
152
gen/init.go
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"caddydash/config"
|
||||
"caddydash/db"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 把指定目录下的文件作为模板读入
|
||||
func ReadTmplToDB(dir string, cdb *db.ConfigDB) error {
|
||||
// 遍历目录下的所有文件
|
||||
files, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
if file.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
// 读取文件内容
|
||||
content, err := os.ReadFile(filepath.Join(dir, file.Name()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmplEntry := db.TemplateEntry{
|
||||
Filename: file.Name(),
|
||||
TemplateType: file.Name(),
|
||||
Content: content,
|
||||
UpdatedAt: time.Now().Unix(),
|
||||
}
|
||||
|
||||
// 存储到数据库
|
||||
err = cdb.SaveTemplate(tmplEntry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 输出tmpl名
|
||||
fmt.Printf("Read template: %s\n", file.Name())
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Add80SiteConfig(cfg *config.Config, cdb *db.ConfigDB) error {
|
||||
// 检查:80是否已存在于数据库中
|
||||
|
||||
_, err := cdb.GetParams(":80")
|
||||
if err == nil {
|
||||
// 如果存在,则不添加
|
||||
return nil
|
||||
}
|
||||
|
||||
siteConfig := CaddyUniConfig{
|
||||
DomainConfig: CaddyUniDomainConfig{
|
||||
Domain: ":80",
|
||||
MutiDomains: false,
|
||||
Domains: []string{":80"},
|
||||
},
|
||||
Mode: "uni",
|
||||
FileServer: CaddyUniFileServerConfig{
|
||||
EnableFileServer: true,
|
||||
FileDirPath: cfg.Server.CaddyDir + "pages/demo",
|
||||
EnableBrowser: false,
|
||||
},
|
||||
Log: CaddyUniLogConfig{
|
||||
EnableLog: true,
|
||||
LogDomain: ":80",
|
||||
},
|
||||
ErrorPage: CaddyUniErrorPageConfig{
|
||||
EnableErrorPage: true,
|
||||
},
|
||||
Encode: CaddyUniEncodeConfig{
|
||||
EnableEncode: true,
|
||||
},
|
||||
}
|
||||
|
||||
// 制作db.ParamsEntry
|
||||
gobData, err := EncodeGobConfig(siteConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
originConfig := db.CaddyfileConfig{
|
||||
Domain: ":80",
|
||||
TmplType: "file_server",
|
||||
FileServer: db.FileServerConfig{
|
||||
FileDirPath: cfg.Server.CaddyDir + "pages/demo",
|
||||
EnableBrowser: false,
|
||||
},
|
||||
Log: db.LogConfig{
|
||||
EnableLog: true,
|
||||
LogDomain: ":80",
|
||||
},
|
||||
ErrorPage: db.ErrorPageConfig{
|
||||
EnableErrorPage: true,
|
||||
},
|
||||
Encode: db.EncodeConfig{
|
||||
EnableEncode: true,
|
||||
},
|
||||
}
|
||||
*/
|
||||
|
||||
originGobData, err := EncodeGobConfig(siteConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
paramsEntry := db.ParamsEntry{
|
||||
Filename: ":80",
|
||||
TemplateType: "file_server",
|
||||
ParamsGOB: gobData,
|
||||
ParamsOrigin: originGobData,
|
||||
CreatedAt: time.Now().Unix(),
|
||||
UpdatedAt: time.Now().Unix(),
|
||||
}
|
||||
|
||||
filename := paramsEntry.Filename
|
||||
|
||||
// 保存到数据库
|
||||
err = cdb.SaveParams(paramsEntry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 渲染配置
|
||||
err = RenderConfig(filename, cdb)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("render config error: %w", err)
|
||||
return err
|
||||
}
|
||||
// 写入文件
|
||||
renderedEntry, err := cdb.GetRenderedConfig(filename)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("get rendered config error: %w", err)
|
||||
return err
|
||||
}
|
||||
err = os.WriteFile(cfg.Server.CaddyDir+"config.d/"+filename, renderedEntry.RenderedContent, 0644)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("write rendered config file error: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
150
gen/render.go
Normal file
150
gen/render.go
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"caddydash/db"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func RenderConfig(site string, cdb *db.ConfigDB) error {
|
||||
// 检索site config
|
||||
paramsEntry, err := cdb.GetParams(site)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var caddycfg CaddyUniConfig
|
||||
err = DecodeGobConfig(paramsEntry.ParamsGOB, &caddycfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 读取模板
|
||||
//tmplEntry, err := cdb.GetTemplate("reverse_proxy")
|
||||
tmplEntry, err := cdb.GetTemplate(caddycfg.Mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rpTmpl := string(tmplEntry.Content)
|
||||
// 使用caddycfg渲染最终产物
|
||||
parsedTmpl, parseErr := template.New(tmplEntry.Filename).Parse(rpTmpl)
|
||||
if parseErr != nil {
|
||||
return fmt.Errorf("db: failed to parse template content for '%s': %w", tmplEntry.Filename, parseErr)
|
||||
}
|
||||
var renderedContentBuilder bytes.Buffer
|
||||
if err := parsedTmpl.Execute(&renderedContentBuilder, caddycfg); err != nil {
|
||||
return fmt.Errorf("db: failed to render template '%s': %w", tmplEntry.Filename, err)
|
||||
}
|
||||
|
||||
// 保存渲染结果
|
||||
renderedEntry := db.RenderedConfigEntry{
|
||||
Filename: caddycfg.DomainConfig.Domain, // 使用域名作为文件名
|
||||
RenderedContent: renderedContentBuilder.Bytes(),
|
||||
}
|
||||
|
||||
// 保存渲染产物
|
||||
if err := cdb.SaveRenderedConfig(renderedEntry); err != nil {
|
||||
return fmt.Errorf("db: failed to save rendered config for '%s': %w", caddycfg.DomainConfig.Domain, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 把caddycfg内容转为GOB
|
||||
func EncodeGobConfig(caddycfg any) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
enc := gob.NewEncoder(&buf)
|
||||
if err := enc.Encode(caddycfg); err != nil {
|
||||
return nil, fmt.Errorf("db: failed to Encode struct to GOB: %w", err)
|
||||
}
|
||||
return buf.Bytes(), nil // 返回编码后的字节切片.
|
||||
}
|
||||
|
||||
func DecodeGobConfig(data []byte, tmplStruct any) error {
|
||||
buf := bytes.NewBuffer(data)
|
||||
dec := gob.NewDecoder(buf)
|
||||
if err := dec.Decode(tmplStruct); err != nil {
|
||||
return fmt.Errorf("db: failed to Decode GOB to struct: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
func RenderConfig(site string, cdb *db.ConfigDB) error {
|
||||
// 检索site config
|
||||
paramsEntry, err := cdb.GetParams(site)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var caddycfg any
|
||||
var specificConfigType interface{}
|
||||
|
||||
if paramsEntry.TemplateType == "reverse_proxy" {
|
||||
specificConfigType = &CaddyReverseProxyConfig{}
|
||||
} else if paramsEntry.TemplateType == "file_server" {
|
||||
specificConfigType = &CaddyFileServerConfig{}
|
||||
} else {
|
||||
return fmt.Errorf("unknown template type: %s", paramsEntry.TemplateType)
|
||||
}
|
||||
|
||||
err = DecodeGobConfig(paramsEntry.ParamsGOB, specificConfigType)
|
||||
if err != nil {
|
||||
log.Printf("decode gob config error: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
caddycfg = specificConfigType
|
||||
|
||||
// 读取模板
|
||||
//tmplEntry, err := cdb.GetTemplate("reverse_proxy")
|
||||
tmplEntry, err := cdb.GetTemplate(paramsEntry.TemplateType)
|
||||
if err != nil {
|
||||
log.Printf("get template error: %v", err)
|
||||
tmplList, err := cdb.RangeTemplates()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("template list: %v, GetName %s", tmplList, paramsEntry.TemplateType)
|
||||
return err
|
||||
}
|
||||
|
||||
rpTmpl := string(tmplEntry.Content)
|
||||
// 使用caddycfg渲染最终产物
|
||||
parsedTmpl, parseErr := template.New(tmplEntry.Filename).Parse(rpTmpl)
|
||||
if parseErr != nil {
|
||||
return fmt.Errorf("db: failed to parse template content for '%s': %w", tmplEntry.Filename, parseErr)
|
||||
}
|
||||
var renderedContentBuilder bytes.Buffer
|
||||
if err := parsedTmpl.Execute(&renderedContentBuilder, caddycfg); err != nil {
|
||||
return fmt.Errorf("db: failed to render template '%s': %w", tmplEntry.Filename, err)
|
||||
}
|
||||
|
||||
// 类型断言获得domain
|
||||
var domain string
|
||||
switch cfg := caddycfg.(type) {
|
||||
case *CaddyReverseProxyConfig:
|
||||
domain = cfg.Domain
|
||||
case *CaddyFileServerConfig:
|
||||
domain = cfg.Domain
|
||||
default:
|
||||
return fmt.Errorf("unknown config type for domain extraction")
|
||||
}
|
||||
|
||||
// 保存渲染结果
|
||||
renderedEntry := db.RenderedConfigEntry{
|
||||
Filename: domain, // 使用域名作为文件名
|
||||
RenderedContent: renderedContentBuilder.Bytes(),
|
||||
}
|
||||
|
||||
// 保存渲染产物
|
||||
if err := cdb.SaveRenderedConfig(renderedEntry); err != nil {
|
||||
return fmt.Errorf("db: failed to save rendered config for '%s': %w", domain, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
79
gen/struct.go
Normal file
79
gen/struct.go
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
package gen
|
||||
|
||||
/*
|
||||
type CaddyReverseProxyConfig struct {
|
||||
Domain string // 域名; 例如 example.com
|
||||
ReverseProxy string // 反向代理目标; 例如 127.0.0.1:8080 (这里简化为单个目标)
|
||||
Headers []string // 自定义响应Header
|
||||
HeadersUp []string // 自定义请求头列表; 例如 ["XXX0 XX", "XXX1 XXX"]
|
||||
EnableLog bool // 是否导入 log 指令
|
||||
LogDomain string // log 指令的域名参数
|
||||
EnableErrorPage bool // 是否导入 error_page 指令
|
||||
EnableEncode bool // 是否导入 encode 指令
|
||||
}
|
||||
|
||||
type CaddyFileServerConfig struct {
|
||||
Domain string // 域名; 例如 example.com
|
||||
FileDirPath string // 文件目录
|
||||
EnableBrowser bool // 是否导入 browse 指令
|
||||
Headers []string //
|
||||
EnableLog bool // 是否导入 log 指令
|
||||
LogDomain string // log 指令的域名参数
|
||||
EnableErrorPage bool // 是否导入 error_page 指令
|
||||
EnableEncode bool // 是否导入 encode 指令
|
||||
}
|
||||
*/
|
||||
|
||||
func HeadersMapToHeadersUp(headers map[string][]string) []string {
|
||||
var headersUp []string
|
||||
for key, values := range headers {
|
||||
for _, value := range values {
|
||||
headersUp = append(headersUp, key+" "+value)
|
||||
}
|
||||
}
|
||||
return headersUp
|
||||
}
|
||||
|
||||
type CaddyUniConfig struct {
|
||||
DomainConfig CaddyUniDomainConfig `json:"domain_config"`
|
||||
Mode string `json:"mode"`
|
||||
Upstream CaddyUniUpstreamConfig `json:"upstream_config"`
|
||||
FileServer CaddyUniFileServerConfig `json:"file_server_config"`
|
||||
Headers map[string][]string `json:"headers"`
|
||||
Log CaddyUniLogConfig `json:"log_config"`
|
||||
ErrorPage CaddyUniErrorPageConfig `json:"error_page_config"`
|
||||
Encode CaddyUniEncodeConfig `json:"encode_config"`
|
||||
}
|
||||
|
||||
type CaddyUniDomainConfig struct {
|
||||
Domain string `json:"domain"`
|
||||
MutiDomains bool `json:"muti_domains"`
|
||||
Domains []string `json:"domains"`
|
||||
}
|
||||
|
||||
type CaddyUniUpstreamConfig struct {
|
||||
EnableUpStream bool `json:"enable_upstream"`
|
||||
UpStream string `json:"upstream"`
|
||||
MutiUpStreams bool `json:"muti_upstream"`
|
||||
UpStreams []string `json:"upstream_servers"`
|
||||
UpStreamHeaders map[string][]string `json:"upstream_headers"`
|
||||
}
|
||||
|
||||
type CaddyUniFileServerConfig struct {
|
||||
EnableFileServer bool `json:"enable_file_server"`
|
||||
FileDirPath string `json:"file_dir_path"`
|
||||
EnableBrowser bool `json:"enable_browser"`
|
||||
}
|
||||
|
||||
type CaddyUniLogConfig struct {
|
||||
EnableLog bool `json:"enable_log"`
|
||||
LogDomain string `json:"log_domain"`
|
||||
}
|
||||
|
||||
type CaddyUniErrorPageConfig struct {
|
||||
EnableErrorPage bool `json:"enable_error_page"`
|
||||
}
|
||||
|
||||
type CaddyUniEncodeConfig struct {
|
||||
EnableEncode bool `json:"enable_encode"`
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue