Files
mysql-tunnel/internal/config/save.go
T
2026-09-21 16:46:55 +08:00

100 lines
2.2 KiB
Go

package config
import (
"fmt"
"os"
"path/filepath"
"gopkg.in/yaml.v3"
)
func (c *Config) ToFile() File {
if c == nil {
return File{}
}
return File{
Listen: ListenFile{Host: c.ListenHost, Port: c.ListenPort},
LocalAuth: LocalAuthFile{Username: c.LocalUsername, Password: c.LocalPassword},
Tunnel: TunnelFile{
URL: c.TunnelURL,
EncodeBase64: c.EncodeBase64,
TLSInsecureSkipVerify: c.TLSInsecureSkipVerify,
},
Remote: RemoteFile{
Host: c.RemoteHost,
Port: c.RemotePort,
Username: c.RemoteUsername,
Password: c.RemotePassword,
Database: c.RemoteDatabase,
Charset: c.RemoteCharset,
},
Options: OptionsFile{
RequestTimeout: int(c.RequestTimeout.Seconds()),
MaxConnections: c.MaxConnections,
LogLevel: c.LogLevel,
LogSQL: c.LogSQL,
LogFile: relativeLogFile(c.Path, c.LogFile),
},
}
}
func relativeLogFile(cfgPath, logFile string) string {
if logFile == "" {
return DefaultLogFile
}
if !filepath.IsAbs(logFile) {
return filepath.ToSlash(filepath.Clean(logFile))
}
dir := filepath.Dir(cfgPath)
rel, err := filepath.Rel(dir, logFile)
if err != nil {
return logFile
}
return filepath.ToSlash(rel)
}
func Save(path string, c *Config) error {
if path == "" {
return fmt.Errorf("config path is empty")
}
if dir := filepath.Dir(path); dir != "" && dir != "." {
if err := os.MkdirAll(dir, 0o750); err != nil {
return err
}
}
raw, err := yaml.Marshal(c.ToFile())
if err != nil {
return err
}
out := append([]byte("# Written by mysql-tunnel. Contains secrets; do not commit.\n"), raw...)
return os.WriteFile(path, out, 0o600)
}
func DefaultSavePath() string {
if exe, err := os.Executable(); err == nil {
return filepath.Join(filepath.Dir(exe), "config.yaml")
}
return "config.yaml"
}
// LoadOrEmpty returns a parsed config, or defaults if the file is missing or invalid.
func LoadOrEmpty(path string) *Config {
if path == "" {
path = DefaultSavePath()
}
if _, err := os.Stat(path); err != nil {
c := Defaults()
c.Path = path
return &c
}
cfg, err := Parse(path, Overrides{})
if err != nil {
c := Defaults()
c.Path = path
c.Warnings = append(c.Warnings, err.Error())
return &c
}
cfg.ResolvePaths()
return cfg
}