mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-10 18:05:48 +02:00
feat: customize local environment name #313
This commit is contained in:
parent
4c74bc8619
commit
1e9de6f21b
13 changed files with 78 additions and 36 deletions
|
@ -11,6 +11,7 @@ func InitPublicRouter(r *gin.RouterGroup) {
|
|||
}
|
||||
|
||||
func InitPrivateRouter(r *gin.RouterGroup) {
|
||||
r.GET("settings/server/name", GetServerName)
|
||||
r.GET("settings", GetSettings)
|
||||
r.POST("settings", SaveSettings)
|
||||
|
||||
|
|
|
@ -6,9 +6,14 @@ import (
|
|||
"github.com/0xJacky/Nginx-UI/settings"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func GetServerName(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"name": settings.ServerSettings.Name,
|
||||
})
|
||||
}
|
||||
|
||||
func GetSettings(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"server": settings.ServerSettings,
|
||||
|
@ -35,10 +40,10 @@ func SaveSettings(c *gin.Context) {
|
|||
go cron.RestartLogrotate()
|
||||
}
|
||||
|
||||
fillSettings(&settings.ServerSettings, &json.Server)
|
||||
fillSettings(&settings.NginxSettings, &json.Nginx)
|
||||
fillSettings(&settings.OpenAISettings, &json.Openai)
|
||||
fillSettings(&settings.LogrotateSettings, &json.Logrotate)
|
||||
settings.ProtectedFill(&settings.ServerSettings, &json.Server)
|
||||
settings.ProtectedFill(&settings.NginxSettings, &json.Nginx)
|
||||
settings.ProtectedFill(&settings.OpenAISettings, &json.Openai)
|
||||
settings.ProtectedFill(&settings.LogrotateSettings, &json.Logrotate)
|
||||
|
||||
err := settings.Save()
|
||||
if err != nil {
|
||||
|
@ -48,16 +53,3 @@ func SaveSettings(c *gin.Context) {
|
|||
|
||||
GetSettings(c)
|
||||
}
|
||||
|
||||
func fillSettings(targetSettings interface{}, newSettings interface{}) {
|
||||
s := reflect.TypeOf(targetSettings).Elem()
|
||||
vt := reflect.ValueOf(targetSettings).Elem()
|
||||
vn := reflect.ValueOf(newSettings).Elem()
|
||||
|
||||
// copy the values from new to target settings if it is not protected
|
||||
for i := 0; i < s.NumField(); i++ {
|
||||
if s.Field(i).Tag.Get("protected") != "true" {
|
||||
vt.Field(i).Set(vn.Field(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ HttpHost = 0.0.0.0
|
|||
CertRenewalInterval = 7
|
||||
RecursiveNameservers =
|
||||
SkipInstallation = false
|
||||
Name =
|
||||
|
||||
[nginx]
|
||||
AccessLogPath = /var/log/nginx/access.log
|
||||
|
|
|
@ -8,6 +8,10 @@ const settings = {
|
|||
save(data: any) {
|
||||
return http.post('/settings', data)
|
||||
},
|
||||
|
||||
get_server_name() {
|
||||
return http.get('/settings/server/name')
|
||||
},
|
||||
}
|
||||
|
||||
export default settings
|
||||
|
|
|
@ -4,6 +4,7 @@ import { storeToRefs } from 'pinia'
|
|||
import { useRouter } from 'vue-router'
|
||||
import { computed, watch } from 'vue'
|
||||
import { useSettingsStore } from '@/pinia'
|
||||
import settings from '@/api/settings'
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
|
@ -25,6 +26,12 @@ watch(node_id, async () => {
|
|||
await router.push('/dashboard')
|
||||
location.reload()
|
||||
})
|
||||
|
||||
const { server_name } = storeToRefs(useSettingsStore())
|
||||
|
||||
settings.get_server_name().then(r => {
|
||||
server_name.value = r.name
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -35,7 +42,7 @@ watch(node_id, async () => {
|
|||
v-if="is_local"
|
||||
class="env-name"
|
||||
>
|
||||
{{ $gettext('Local') }}
|
||||
{{ server_name || $gettext('Local') }}
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
|
|
|
@ -9,6 +9,7 @@ export const useSettingsStore = defineStore('settings', {
|
|||
id: 0,
|
||||
name: 'Local',
|
||||
},
|
||||
server_name: '',
|
||||
}),
|
||||
getters: {
|
||||
is_remote(): boolean {
|
||||
|
|
|
@ -113,6 +113,9 @@ const errors: Record<string, Record<string, string>> = inject('errors') as Recor
|
|||
</template>
|
||||
</Draggable>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$gettext('Server Name')">
|
||||
<AInput v-model:value="data.server.name" />
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -23,7 +23,13 @@ const models = shallowRef([
|
|||
|
||||
<template>
|
||||
<AForm layout="vertical">
|
||||
<AFormItem :label="$gettext('Model')">
|
||||
<AFormItem
|
||||
:label="$gettext('Model')"
|
||||
:validate-status="errors?.openai?.model ? 'error' : ''"
|
||||
:help="errors?.openai?.model === 'alpha_num_dash_dot'
|
||||
? $gettext('The model name should only contain letters, numbers, dashes, and dots.')
|
||||
: ''"
|
||||
>
|
||||
<AAutoComplete
|
||||
v-model:value="data.openai.model"
|
||||
:options="models"
|
||||
|
@ -33,7 +39,7 @@ const models = shallowRef([
|
|||
:label="$gettext('API Base Url')"
|
||||
:validate-status="errors?.openai?.base_url ? 'error' : ''"
|
||||
:help="errors?.openai?.base_url === 'url'
|
||||
? $gettext('The url is not valid')
|
||||
? $gettext('The url is invalid.')
|
||||
: ''"
|
||||
>
|
||||
<AInput
|
||||
|
@ -45,7 +51,7 @@ const models = shallowRef([
|
|||
:label="$gettext('API Proxy')"
|
||||
:validate-status="errors?.openai?.proxy ? 'error' : ''"
|
||||
:help="errors?.openai?.proxy === 'url'
|
||||
? $gettext('The url is not valid')
|
||||
? $gettext('The url is invalid.')
|
||||
: ''"
|
||||
>
|
||||
<AInput
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { message } from 'ant-design-vue'
|
||||
import type { Ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
|
||||
import settings from '@/api/settings'
|
||||
import BasicSettings from '@/views/preference/BasicSettings.vue'
|
||||
|
@ -8,6 +9,7 @@ import OpenAISettings from '@/views/preference/OpenAISettings.vue'
|
|||
import NginxSettings from '@/views/preference/NginxSettings.vue'
|
||||
import type { Settings } from '@/views/preference/typedef'
|
||||
import LogrotateSettings from '@/views/preference/LogrotateSettings.vue'
|
||||
import { useSettingsStore } from '@/pinia'
|
||||
|
||||
const data = ref<Settings>({
|
||||
server: {
|
||||
|
@ -23,6 +25,7 @@ const data = ref<Settings>({
|
|||
node_secret: '',
|
||||
cert_renewal_interval: 7,
|
||||
recursive_nameservers: [],
|
||||
name: '',
|
||||
},
|
||||
nginx: {
|
||||
access_log_path: '',
|
||||
|
@ -49,12 +52,14 @@ settings.get().then(r => {
|
|||
data.value = r
|
||||
})
|
||||
|
||||
const { server_name } = storeToRefs(useSettingsStore())
|
||||
const errors = ref({}) as Ref<Record<string, Record<string, string>>>
|
||||
|
||||
async function save() {
|
||||
// fix type
|
||||
data.value.server.http_challenge_port = data.value.server.http_challenge_port.toString()
|
||||
settings.save(data.value).then(r => {
|
||||
server_name.value = r?.server?.name ?? ''
|
||||
data.value = r
|
||||
message.success($gettext('Save successfully'))
|
||||
errors.value = {}
|
||||
|
|
|
@ -12,6 +12,7 @@ export interface Settings {
|
|||
ca_dir: string
|
||||
cert_renewal_interval: number
|
||||
recursive_nameservers: string[]
|
||||
name: string
|
||||
}
|
||||
nginx: {
|
||||
access_log_path: string
|
||||
|
|
|
@ -20,7 +20,8 @@ type Server struct {
|
|||
GithubProxy string `json:"github_proxy" binding:"omitempty,url"`
|
||||
CertRenewalInterval int `json:"cert_renewal_interval" binding:"min=7,max=21"`
|
||||
RecursiveNameservers []string `json:"recursive_nameservers" binding:"omitempty,dive,hostname_port"`
|
||||
SkipInstallation bool `json:"skip_installation"`
|
||||
SkipInstallation bool `json:"skip_installation" protected:"true"`
|
||||
Name string `json:"name" binding:"omitempty,alpha_num_dash_dot"`
|
||||
}
|
||||
|
||||
func (s *Server) GetCADir() string {
|
||||
|
|
|
@ -6,7 +6,8 @@ import (
|
|||
"gopkg.in/ini.v1"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -69,19 +70,7 @@ func MapTo() {
|
|||
}
|
||||
}
|
||||
|
||||
func mapTo(section string, v interface{}) {
|
||||
err := Conf.Section(section).MapTo(v)
|
||||
if err != nil {
|
||||
log.Fatalf("Cfg.MapTo %s err: %v", section, err)
|
||||
}
|
||||
}
|
||||
|
||||
func reflectFrom(section string, v interface{}) {
|
||||
err := Conf.Section(section).ReflectFrom(v)
|
||||
if err != nil {
|
||||
log.Fatalf("Cfg.ReflectFrom %s err: %v", section, err)
|
||||
}
|
||||
}
|
||||
|
||||
func Save() (err error) {
|
||||
for k, v := range sections {
|
||||
|
@ -95,6 +84,33 @@ func Save() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func ProtectedFill(targetSettings interface{}, newSettings interface{}) {
|
||||
s := reflect.TypeOf(targetSettings).Elem()
|
||||
vt := reflect.ValueOf(targetSettings).Elem()
|
||||
vn := reflect.ValueOf(newSettings).Elem()
|
||||
|
||||
// copy the values from new to target settings if it is not protected
|
||||
for i := 0; i < s.NumField(); i++ {
|
||||
if s.Field(i).Tag.Get("protected") != "true" {
|
||||
vt.Field(i).Set(vn.Field(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mapTo(section string, v interface{}) {
|
||||
err := Conf.Section(section).MapTo(v)
|
||||
if err != nil {
|
||||
log.Fatalf("Cfg.MapTo %s err: %v", section, err)
|
||||
}
|
||||
}
|
||||
|
||||
func reflectFrom(section string, v interface{}) {
|
||||
err := Conf.Section(section).ReflectFrom(v)
|
||||
if err != nil {
|
||||
log.Fatalf("Cfg.ReflectFrom %s err: %v", section, err)
|
||||
}
|
||||
}
|
||||
|
||||
func parseEnv(ptr interface{}, prefix string) {
|
||||
err := env.ParseWithOptions(ptr, env.Options{
|
||||
Prefix: EnvPrefix + prefix,
|
||||
|
@ -105,3 +121,5 @@ func parseEnv(ptr interface{}, prefix string) {
|
|||
log.Fatalf("settings.parseEnv: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ func TestSetup(t *testing.T) {
|
|||
_ = os.Setenv("NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL", "14")
|
||||
_ = os.Setenv("NGINX_UI_SERVER_RECURSIVE_NAMESERVERS", "8.8.8.8")
|
||||
_ = os.Setenv("NGINX_UI_SERVER_SKIP_INSTALLATION", "true")
|
||||
_ = os.Setenv("NGINX_UI_SERVER_NAME", "test")
|
||||
|
||||
_ = os.Setenv("NGINX_UI_NGINX_ACCESS_LOG_PATH", "/tmp/nginx/access.log")
|
||||
_ = os.Setenv("NGINX_UI_NGINX_ERROR_LOG_PATH", "/tmp/nginx/error.log")
|
||||
|
@ -70,6 +71,7 @@ func TestSetup(t *testing.T) {
|
|||
assert.Equal(t, 14, ServerSettings.CertRenewalInterval)
|
||||
assert.Equal(t, []string{"8.8.8.8"}, ServerSettings.RecursiveNameservers)
|
||||
assert.Equal(t, true, ServerSettings.SkipInstallation)
|
||||
assert.Equal(t, "test", ServerSettings.Name)
|
||||
|
||||
assert.Equal(t, "/tmp/nginx/access.log", NginxSettings.AccessLogPath)
|
||||
assert.Equal(t, "/tmp/nginx/error.log", NginxSettings.ErrorLogPath)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue