nginx-ui/settings/server_v1.go
2024-12-14 17:39:49 +08:00

231 lines
6.6 KiB
Go

package settings
import (
"github.com/elliotchance/orderedmap/v3"
"github.com/spf13/cast"
"github.com/uozi-tech/cosy/logger"
"github.com/uozi-tech/cosy/settings"
"gopkg.in/ini.v1"
"os"
"reflect"
)
// Note: This section will be deprecated in the future version.
type serverV1 struct {
HttpHost string `json:"http_host" protected:"true"`
HttpPort string `json:"http_port" protected:"true"`
RunMode string `json:"run_mode" protected:"true"`
JwtSecret string `json:"jwt_secret" protected:"true"`
NodeSecret string `json:"node_secret" protected:"true"`
HTTPChallengePort string `json:"http_challenge_port"`
Email string `json:"email" protected:"true"`
Database string `json:"database" protected:"true"`
StartCmd string `json:"start_cmd" protected:"true"`
CADir string `json:"ca_dir"`
Demo bool `json:"demo" protected:"true"`
PageSize int `json:"page_size" protected:"true"`
GithubProxy string `json:"github_proxy"`
CertRenewalInterval int `json:"cert_renewal_interval"`
RecursiveNameservers []string `json:"recursive_nameservers"`
SkipInstallation bool `json:"skip_installation" protected:"true"`
InsecureSkipVerify bool `json:"insecure_skip_verify" protected:"true"`
Name string `json:"name"`
}
type settingsV2 struct {
// Cosy
App settings.App
Server settings.Server
DataBase Database
// Nginx UI
Auth Auth
Casdoor Casdoor
Cert Cert
Cluster Cluster
Crypto Crypto
Http HTTP
Logrotate Logrotate
Nginx Nginx
Node Node
OpenAI OpenAI
Terminal Terminal
WebAuthn WebAuthn
}
func (v1 *serverV1) migrateToV2() (v2 *settingsV2) {
v2 = &settingsV2{}
v2.Server.Host = v1.HttpHost
v2.Server.Port = cast.ToUint(v1.HttpPort)
v2.Server.RunMode = v1.RunMode
v2.App.JwtSecret = v1.JwtSecret
v2.App.PageSize = v1.PageSize
v2.Node.Secret = v1.NodeSecret
v2.Cert.HTTPChallengePort = v1.HTTPChallengePort
v2.Cert.Email = v1.Email
v2.DataBase.Name = v1.Database
v2.Terminal.StartCmd = v1.StartCmd
v2.Cert.CADir = v1.CADir
v2.Node.Demo = v1.Demo
v2.Http.GithubProxy = v1.GithubProxy
v2.Cert.RenewalInterval = v1.CertRenewalInterval
v2.Cert.RecursiveNameservers = v1.RecursiveNameservers
v2.Node.SkipInstallation = v1.SkipInstallation
v2.Http.InsecureSkipVerify = v1.InsecureSkipVerify
v2.Node.Name = v1.Name
if v1.Database == "" {
v2.DataBase.Name = "database"
}
return
}
func isZeroValue(v reflect.Value) bool {
zeroValue := reflect.Zero(v.Type()).Interface()
return reflect.DeepEqual(v.Interface(), zeroValue)
}
func mergeStructs(src, dst interface{}) {
dstVal := reflect.ValueOf(dst).Elem()
srcVal := reflect.ValueOf(src).Elem()
for i := 0; i < dstVal.NumField(); i++ {
dstField := dstVal.Field(i)
srcField := srcVal.Field(i)
if isZeroValue(dstField) {
dstField.Set(srcField)
}
}
return
}
func migrate(confPath string) {
logger.Init("debug")
Conf, err := ini.LoadSources(ini.LoadOptions{
Loose: true,
AllowShadows: true,
}, confPath)
if err != nil {
logger.Fatalf("setting.init, fail to parse 'app.ini': %v", err)
}
var v1 = &serverV1{}
err = Conf.Section("server").MapTo(v1)
if err != nil {
logger.Error(err)
return
}
// If settings is v1, jwt_secret is not empty.
if v1.JwtSecret == "" {
return
}
// Cosy
app := &settings.App{}
server := &settings.Server{}
database := &Database{}
// Nginx UI
auth := &Auth{}
casdoor := &Casdoor{}
cert := &Cert{}
cluster := &Cluster{}
crypto := &Crypto{}
http := &HTTP{}
logrotate := &Logrotate{}
nginx := &Nginx{}
node := &Node{}
openai := &OpenAI{}
terminal := &Terminal{}
webauthn := &WebAuthn{}
var migrated = orderedmap.NewOrderedMap[string, any]()
migrated.Set("app", app)
migrated.Set("server", server)
migrated.Set("database", database)
migrated.Set("auth", auth)
migrated.Set("casdoor", casdoor)
migrated.Set("cert", cert)
migrated.Set("cluster", cluster)
migrated.Set("crypto", crypto)
migrated.Set("http", http)
migrated.Set("logrotate", logrotate)
migrated.Set("nginx", nginx)
migrated.Set("node", node)
migrated.Set("openai", openai)
migrated.Set("terminal", terminal)
migrated.Set("webauthn", webauthn)
for name, ptr := range migrated.AllFromFront() {
err = Conf.Section(name).MapTo(ptr)
if err != nil {
logger.Error("migrate.MapTo %s err: %v", name, err)
}
}
v2 := v1.migrateToV2()
mergeStructs(&v2.App, app)
mergeStructs(&v2.Server, server)
mergeStructs(&v2.DataBase, database)
mergeStructs(&v2.Auth, auth)
mergeStructs(&v2.Casdoor, casdoor)
mergeStructs(&v2.Cert, cert)
mergeStructs(&v2.Cluster, cluster)
mergeStructs(&v2.Crypto, crypto)
mergeStructs(&v2.Http, http)
mergeStructs(&v2.Logrotate, logrotate)
mergeStructs(&v2.Nginx, nginx)
mergeStructs(&v2.Node, node)
mergeStructs(&v2.OpenAI, openai)
mergeStructs(&v2.Terminal, terminal)
mergeStructs(&v2.WebAuthn, webauthn)
Conf = ini.Empty()
for section, ptr := range migrated.AllFromFront() {
err = Conf.Section(section).ReflectFrom(ptr)
if err != nil {
logger.Fatalf("migrate.ReflectFrom %s err: %v", section, err)
}
}
err = Conf.SaveTo(confPath)
if err != nil {
logger.Fatalf("Fail to save the migrated settings: %v", err)
return
}
migrateEnv()
}
func migrateEnv() {
deprecated := orderedmap.NewOrderedMap[string, string]()
deprecated.Set("SERVER_HTTP_HOST", "SERVER_HOST")
deprecated.Set("SERVER_HTTP_PORT", "SERVER_PORT")
deprecated.Set("SERVER_JWT_SECRET", "APP_JWT_SECRET")
deprecated.Set("SERVER_NODE_SECRET", "NODE_SECRET")
deprecated.Set("SERVER_HTTP_CHALLENGE_PORT", "CERT_HTTP_CHALLENGE_PORT")
deprecated.Set("SERVER_EMAIL", "CERT_EMAIL")
deprecated.Set("SERVER_DATABASE", "DATABASE_NAME")
deprecated.Set("SERVER_START_CMD", "TERMINAL_START_CMD")
deprecated.Set("SERVER_CA_DIR", "CERT_CA_DIR")
deprecated.Set("SERVER_DEMO", "NODE_DEMO")
deprecated.Set("SERVER_PAGE_SIZE", "APP_PAGE_SIZE")
deprecated.Set("SERVER_GITHUB_PROXY", "HTTP_GITHUB_PROXY")
deprecated.Set("SERVER_CERT_RENEWAL_INTERVAL", "CERT_RENEWAL_INTERVAL")
deprecated.Set("SERVER_RECURSIVE_NAMESERVERS", "CERT_RECURSIVE_NAMESERVERS")
deprecated.Set("SERVER_SKIP_INSTALLATION", "NODE_SKIP_INSTALLATION")
deprecated.Set("SERVER_NAME", "NODE_NAME")
for d, n := range deprecated.AllFromFront() {
oldValue := os.Getenv(EnvPrefix + d)
if oldValue != "" {
_ = os.Setenv(EnvPrefix+n, oldValue)
logger.Warnf("The environment variable %s is deprecated and has been automatically migrated to %s. "+
"Please update your environment variables as automatic migration may be removed in the future.",
EnvPrefix+d, EnvPrefix+n)
}
}
}