From cb0fb47e1cda78b54183103e91c3c09318bf1b3b Mon Sep 17 00:00:00 2001 From: Jacky Date: Mon, 6 May 2024 21:24:53 +0800 Subject: [PATCH] feat: use env to override settings --- Dockerfile | 2 + app.example.ini | 44 +++++++++--------- go.mod | 1 + go.sum | 2 + settings/settings.go | 41 ++++++++++++++--- settings/settings_test.go | 97 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 159 insertions(+), 28 deletions(-) create mode 100644 settings/settings_test.go diff --git a/Dockerfile b/Dockerfile index a2624cf1..5ccbf9dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,8 @@ ARG TARGETARCH ARG TARGETVARIANT EXPOSE 80 443 +ENV NGINX_UI_OFFICIAL_DOCKER=true + # register nginx-ui service COPY resources/docker/nginx-ui.run /etc/s6-overlay/s6-rc.d/nginx-ui/run RUN echo 'longrun' > /etc/s6-overlay/s6-rc.d/nginx-ui/type && \ diff --git a/app.example.ini b/app.example.ini index 0eaccf8c..ae9c8270 100644 --- a/app.example.ini +++ b/app.example.ini @@ -1,43 +1,43 @@ [server] HttpPort = 9000 RunMode = debug -JwtSecret = -Email = +JwtSecret = +Email = HTTPChallengePort = 9180 StartCmd = bash Database = database -CADir = -GithubProxy = -NodeSecret = +CADir = +GithubProxy = +NodeSecret = Demo = false PageSize = 10 HttpHost = 0.0.0.0 CertRenewalInterval = 7 -RecursiveNameservers = +RecursiveNameservers = [nginx] AccessLogPath = /var/log/nginx/access.log ErrorLogPath = /var/log/nginx/error.log -ConfigDir = -PIDPath = -TestConfigCmd = -ReloadCmd = -RestartCmd = +ConfigDir = +PIDPath = +TestConfigCmd = +ReloadCmd = +RestartCmd = [openai] -Model = -BaseUrl = -Proxy = -Token = +Model = +BaseUrl = +Proxy = +Token = [casdoor] -Endpoint = -ClientId = -ClientSecret = -Certificate = -Organization = -Application = -RedirectUri = +Endpoint = +ClientId = +ClientSecret = +Certificate = +Organization = +Application = +RedirectUri = [logrotate] Enabled = false diff --git a/go.mod b/go.mod index 9824cc42..0aac9896 100644 --- a/go.mod +++ b/go.mod @@ -92,6 +92,7 @@ require ( github.com/boombuler/barcode v1.0.1 // indirect github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/caarlos0/env/v11 v11.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.1 // indirect diff --git a/go.sum b/go.sum index 44134a90..0fcbb167 100644 --- a/go.sum +++ b/go.sum @@ -811,6 +811,8 @@ github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4 github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= +github.com/caarlos0/env/v11 v11.0.0 h1:ZIlkOjuL3xoZS0kmUJlF74j2Qj8GMOq3CDLX/Viak8Q= +github.com/caarlos0/env/v11 v11.0.0/go.mod h1:2RC3HQu8BQqtEK3V4iHPxj0jOdWdbPpWJ6pOueeU1xM= github.com/casdoor/casdoor-go-sdk v0.35.1 h1:vOGBjHQPw7U5BbnkJgX6/ZUf+PEix1wv4greuNzDCUY= github.com/casdoor/casdoor-go-sdk v0.35.1/go.mod h1:hVSgmSdwTCsBEJNt9r2K5aLVsoeMc37/N4Zzescy5SA= github.com/casdoor/casdoor-go-sdk v0.43.0 h1:iKDEJlHYwFNY70iWhdVrTTIKqdoqthv3Rxv4x1+rWko= diff --git a/settings/settings.go b/settings/settings.go index 14bcf358..544d3aeb 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -1,21 +1,23 @@ package settings import ( + "github.com/caarlos0/env/v11" "github.com/spf13/cast" "gopkg.in/ini.v1" "log" + "os" "strings" "time" ) -var Conf *ini.File - var ( buildTime string LastModified string -) -var ConfPath string + Conf *ini.File + ConfPath string + EnvPrefix = "NGINX_UI_" +) var sections = map[string]interface{}{ "server": &ServerSettings, @@ -39,9 +41,26 @@ func Setup() { var err error Conf, err = ini.LooseLoad(ConfPath) if err != nil { - log.Fatalf("setting.Setup: %v\n", err) + log.Fatalf("settings.Setup: %v\n", err) } MapTo() + + parseEnv(&ServerSettings, "SERVER_") + parseEnv(&NginxSettings, "NGINX_") + parseEnv(&OpenAISettings, "OPENAI_") + parseEnv(&CasdoorSettings, "CASDOOR_") + parseEnv(&LogrotateSettings, "LOGROTATE_") + + // if in official docker, set the restart cmd of nginx to "nginx -s stop", + // then the supervisor of s6-overlay will start the nginx again. + if cast.ToBool(os.Getenv("NGINX_UI_OFFICIAL_DOCKER")) { + NginxSettings.RestartCmd = "nginx -s stop" + } + + err = Save() + if err != nil { + log.Fatalf("settings.Setup: %v\n", err) + } } func MapTo() { @@ -75,6 +94,16 @@ func Save() (err error) { if err != nil { return } - Setup() return } + +func parseEnv(ptr interface{}, prefix string) { + err := env.ParseWithOptions(ptr, env.Options{ + Prefix: EnvPrefix + prefix, + UseFieldNameByDefault: true, + }) + + if err != nil { + log.Fatalf("settings.parseEnv: %v\n", err) + } +} diff --git a/settings/settings_test.go b/settings/settings_test.go new file mode 100644 index 00000000..bb2d73e2 --- /dev/null +++ b/settings/settings_test.go @@ -0,0 +1,97 @@ +package settings + +import ( + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +func TestSetup(t *testing.T) { + Init("../app.example.ini") + + _ = os.Setenv("NGINX_UI_OFFICIAL_DOCKER", "true") + + _ = os.Setenv("NGINX_UI_SERVER_HTTP_PORT", "8080") + _ = os.Setenv("NGINX_UI_SERVER_RUN_MODE", "test") + _ = os.Setenv("NGINX_UI_SERVER_JWT_SECRET", "newSecret123") + _ = os.Setenv("NGINX_UI_SERVER_HTTP_CHALLENGE_PORT", "9181") + _ = os.Setenv("NGINX_UI_SERVER_START_CMD", "start") + _ = os.Setenv("NGINX_UI_SERVER_DATABASE", "testDB") + _ = os.Setenv("NGINX_UI_SERVER_CA_DIR", "/test/ca") + _ = os.Setenv("NGINX_UI_SERVER_GITHUB_PROXY", "http://proxy.example.com") + _ = os.Setenv("NGINX_UI_SERVER_NODE_SECRET", "nodeSecret") + _ = os.Setenv("NGINX_UI_SERVER_DEMO", "true") + _ = os.Setenv("NGINX_UI_SERVER_PAGE_SIZE", "20") + _ = os.Setenv("NGINX_UI_SERVER_HTTP_HOST", "127.0.0.1") + _ = os.Setenv("NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL", "14") + _ = os.Setenv("NGINX_UI_SERVER_RECURSIVE_NAMESERVERS", "8.8.8.8") + + _ = os.Setenv("NGINX_UI_NGINX_ACCESS_LOG_PATH", "/tmp/nginx/access.log") + _ = os.Setenv("NGINX_UI_NGINX_ERROR_LOG_PATH", "/tmp/nginx/error.log") + _ = os.Setenv("NGINX_UI_NGINX_CONFIG_DIR", "/etc/nginx/conf") + _ = os.Setenv("NGINX_UI_NGINX_PID_PATH", "/var/run/nginx.pid") + _ = os.Setenv("NGINX_UI_NGINX_TEST_CONFIG_CMD", "nginx -t") + _ = os.Setenv("NGINX_UI_NGINX_RELOAD_CMD", "nginx -s reload") + _ = os.Setenv("NGINX_UI_NGINX_RESTART_CMD", "nginx -s restart") + + _ = os.Setenv("NGINX_UI_OPENAI_MODEL", "davinci") + _ = os.Setenv("NGINX_UI_OPENAI_BASE_URL", "https://api.openai.com") + _ = os.Setenv("NGINX_UI_OPENAI_PROXY", "https://proxy.openai.com") + _ = os.Setenv("NGINX_UI_OPENAI_TOKEN", "token123") + + _ = os.Setenv("NGINX_UI_CASDOOR_ENDPOINT", "https://casdoor.example.com") + _ = os.Setenv("NGINX_UI_CASDOOR_CLIENT_ID", "clientId") + _ = os.Setenv("NGINX_UI_CASDOOR_CLIENT_SECRET", "clientSecret") + _ = os.Setenv("NGINX_UI_CASDOOR_CERTIFICATE", "cert.pem") + _ = os.Setenv("NGINX_UI_CASDOOR_ORGANIZATION", "org1") + _ = os.Setenv("NGINX_UI_CASDOOR_APPLICATION", "app1") + _ = os.Setenv("NGINX_UI_CASDOOR_REDIRECT_URI", "https://redirect.example.com") + + _ = os.Setenv("NGINX_UI_LOGROTATE_ENABLED", "true") + _ = os.Setenv("NGINX_UI_LOGROTATE_CMD", "logrotate /custom/logrotate.conf") + _ = os.Setenv("NGINX_UI_LOGROTATE_INTERVAL", "60") + + Setup() + + assert.Equal(t, "8080", ServerSettings.HttpPort) + assert.Equal(t, "test", ServerSettings.RunMode) + assert.Equal(t, "newSecret123", ServerSettings.JwtSecret) + assert.Equal(t, "9181", ServerSettings.HTTPChallengePort) + assert.Equal(t, "start", ServerSettings.StartCmd) + assert.Equal(t, "testDB", ServerSettings.Database) + assert.Equal(t, "/test/ca", ServerSettings.CADir) + assert.Equal(t, "http://proxy.example.com", ServerSettings.GithubProxy) + assert.Equal(t, "nodeSecret", ServerSettings.NodeSecret) + assert.Equal(t, true, ServerSettings.Demo) + assert.Equal(t, 20, ServerSettings.PageSize) + assert.Equal(t, "127.0.0.1", ServerSettings.HttpHost) + assert.Equal(t, 14, ServerSettings.CertRenewalInterval) + assert.Equal(t, []string{"8.8.8.8"}, ServerSettings.RecursiveNameservers) + + assert.Equal(t, "/tmp/nginx/access.log", NginxSettings.AccessLogPath) + assert.Equal(t, "/tmp/nginx/error.log", NginxSettings.ErrorLogPath) + assert.Equal(t, "/etc/nginx/conf", NginxSettings.ConfigDir) + assert.Equal(t, "/var/run/nginx.pid", NginxSettings.PIDPath) + assert.Equal(t, "nginx -t", NginxSettings.TestConfigCmd) + assert.Equal(t, "nginx -s reload", NginxSettings.ReloadCmd) + assert.Equal(t, "nginx -s stop", NginxSettings.RestartCmd) + + assert.Equal(t, "davinci", OpenAISettings.Model) + assert.Equal(t, "https://api.openai.com", OpenAISettings.BaseUrl) + assert.Equal(t, "https://proxy.openai.com", OpenAISettings.Proxy) + assert.Equal(t, "token123", OpenAISettings.Token) + + assert.Equal(t, "https://casdoor.example.com", CasdoorSettings.Endpoint) + assert.Equal(t, "clientId", CasdoorSettings.ClientId) + assert.Equal(t, "clientSecret", CasdoorSettings.ClientSecret) + assert.Equal(t, "cert.pem", CasdoorSettings.Certificate) + assert.Equal(t, "org1", CasdoorSettings.Organization) + assert.Equal(t, "app1", CasdoorSettings.Application) + assert.Equal(t, "https://redirect.example.com", CasdoorSettings.RedirectUri) + + assert.Equal(t, true, LogrotateSettings.Enabled) + assert.Equal(t, "logrotate /custom/logrotate.conf", LogrotateSettings.CMD) + assert.Equal(t, 60, LogrotateSettings.Interval) + + os.Clearenv() +}