Browse Source

feat: reload cluster node settings from settings file #169

Jacky 1 year ago
parent
commit
e0366f949f

+ 18 - 0
api/cluster/environment.go

@@ -3,9 +3,11 @@ package cluster
 import (
 	"github.com/0xJacky/Nginx-UI/api"
 	"github.com/0xJacky/Nginx-UI/internal/analytic"
+	"github.com/0xJacky/Nginx-UI/internal/cluster"
 	"github.com/0xJacky/Nginx-UI/internal/cosy"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/query"
+	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/gin-gonic/gin"
 	"github.com/spf13/cast"
 	"net/http"
@@ -75,3 +77,19 @@ func DeleteEnvironment(c *gin.Context) {
 
 	c.JSON(http.StatusNoContent, nil)
 }
+
+func LoadEnvironmentFromSettings(c *gin.Context) {
+	err := settings.ReloadCluster()
+	if err != nil {
+		api.ErrHandler(c, err)
+		return
+	}
+
+	cluster.RegisterPredefinedNodes()
+
+	go analytic.RestartRetrieveNodesStatus()
+
+	c.JSON(http.StatusOK, gin.H{
+		"message": "ok",
+	})
+}

+ 1 - 0
api/cluster/router.go

@@ -5,6 +5,7 @@ import "github.com/gin-gonic/gin"
 func InitRouter(r *gin.RouterGroup) {
 	// Environment
 	r.GET("environments", GetEnvironmentList)
+	r.POST("environments/load_from_settings", LoadEnvironmentFromSettings)
 	envGroup := r.Group("environment")
 	{
 		envGroup.GET("/:id", GetEnvironment)

+ 3 - 0
app/src/App.vue

@@ -10,6 +10,7 @@ import en_US from 'ant-design-vue/es/locale/en_US'
 
 import { useSettingsStore } from '@/pinia'
 import gettext from '@/gettext'
+import loadTranslations from '@/api/translations'
 
 const media = window.matchMedia('(prefers-color-scheme: dark)')
 
@@ -49,6 +50,8 @@ const lang = computed(() => {
 
 const settings = useSettingsStore()
 const is_theme_dark = computed(() => settings.theme === 'dark')
+
+loadTranslations()
 </script>
 
 <template>

+ 13 - 1
app/src/api/environment.ts

@@ -1,3 +1,4 @@
+import http from '@/lib/http'
 import type { ModelBase } from '@/api/curd'
 import Curd from '@/api/curd'
 
@@ -14,6 +15,17 @@ export interface Node {
   token: string
   response_at?: Date
 }
-const environment: Curd<Environment> = new Curd('/environment')
+
+class EnvironmentCurd extends Curd<Environment> {
+  constructor() {
+    super('/environment')
+  }
+
+  load_from_settings() {
+    return http.post(`${this.plural}/load_from_settings`)
+  }
+}
+
+const environment: EnvironmentCurd = new EnvironmentCurd()
 
 export default environment

+ 19 - 0
app/src/api/translations.ts

@@ -0,0 +1,19 @@
+import gettext from '@/gettext'
+
+export default async function loadTranslations() {
+  const route = useRoute()
+
+  if (gettext.current !== 'en') {
+    await fetch(`${import.meta.env.VITE_API_ROOT}/translation/${gettext.current}`).then(async r => {
+      gettext.translations[gettext.current] = await r.json()
+    })
+
+    if (route?.meta?.name)
+      document.title = `${route.meta.name?.()} | Nginx UI`
+  }
+
+  watch(route, () => {
+    if (route?.meta?.name)
+      document.title = `${route.meta.name?.()} | Nginx UI`
+  })
+}

+ 11 - 17
app/src/components/SetLanguage/SetLanguage.vue

@@ -1,32 +1,27 @@
 <script setup lang="ts">
-import { ref, watch } from 'vue'
+import { watch } from 'vue'
 
 import { useSettingsStore } from '@/pinia'
-import http from '@/lib/http'
 import gettext from '@/gettext'
+import loadTranslations from '@/api/translations'
 
 const settings = useSettingsStore()
 
 const route = useRoute()
 
-const current = ref(gettext.current)
+const current = computed({
+  get() {
+    return gettext.current
+  },
+  set(v) {
+    gettext.current = v
+  },
+})
 
 const languageAvailable = gettext.available
 
-async function init() {
-  if (current.value !== 'en') {
-    await http.get(`/translation/${current.value}`).then(r => {
-      gettext.translations[current.value] = r
-    })
-
-    document.title = `${route.meta.name?.()} | Nginx UI`
-  }
-}
-
-init()
-
 watch(current, v => {
-  init()
+  loadTranslations()
   settings.set_language(v)
   gettext.current = v
 
@@ -34,7 +29,6 @@ watch(current, v => {
 
   document.title = `${name()} | Nginx UI`
 })
-
 </script>
 
 <template>

+ 16 - 2
app/src/views/environment/Environment.vue

@@ -1,6 +1,6 @@
 <script setup lang="tsx">
 import { h } from 'vue'
-import { Badge, Tag } from 'ant-design-vue'
+import { Badge, Tag, message } from 'ant-design-vue'
 import type { customRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
 import { datetime } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
 import environment from '@/api/environment'
@@ -130,14 +130,28 @@ const columns: Column[] = [{
   dataIndex: 'action',
 }]
 
+const curd = ref()
+function load_from_settings() {
+  environment.load_from_settings().then(() => {
+    curd.value.get_list()
+    message.success($gettext('Load successfully'))
+  }).catch(e => {
+    message.error(`${$gettext('Server error')} ${e?.message}`)
+  })
+}
 </script>
 
 <template>
   <StdCurd
+    ref="curd"
     :title="$gettext('Environment')"
     :api="environment"
     :columns="columns"
-  />
+  >
+    <template #extra>
+      <a @click="load_from_settings">{{ $gettext('Load from settings') }}</a>
+    </template>
+  </StdCurd>
 </template>
 
 <style lang="less" scoped>

+ 0 - 2
app/src/views/other/Error.vue

@@ -5,8 +5,6 @@ const route = useRoute()
 const info = computed(() => {
   if (typeof route.meta.error === 'function')
     return route.meta.error()
-  else if (typeof route.meta.error === 'string')
-    return route.meta.error
   else
     return $gettext('File Not Found')
 })

+ 2 - 2
internal/kernal/cluster.go → internal/cluster/cluster.go

@@ -1,4 +1,4 @@
-package kernal
+package cluster
 
 import (
 	"github.com/0xJacky/Nginx-UI/internal/logger"
@@ -10,7 +10,7 @@ import (
 	"strings"
 )
 
-func registerPredefinedClusterNodes() {
+func RegisterPredefinedNodes() {
 	if len(settings.ClusterSettings.Node) == 0 {
 		return
 	}

+ 1 - 1
internal/kernal/cluster_test.go → internal/cluster/cluster_test.go

@@ -1,4 +1,4 @@
-package kernal
+package cluster
 
 import (
 	"github.com/0xJacky/Nginx-UI/settings"

+ 2 - 1
internal/kernal/boot.go

@@ -3,6 +3,7 @@ package kernal
 import (
 	"github.com/0xJacky/Nginx-UI/internal/analytic"
 	"github.com/0xJacky/Nginx-UI/internal/cert"
+	"github.com/0xJacky/Nginx-UI/internal/cluster"
 	"github.com/0xJacky/Nginx-UI/internal/logger"
 	"github.com/0xJacky/Nginx-UI/internal/logrotate"
 	"github.com/0xJacky/Nginx-UI/internal/validation"
@@ -44,7 +45,7 @@ func InitAfterDatabase() {
 		registerPredefinedUser,
 		cert.InitRegister,
 		InitCronJobs,
-		registerPredefinedClusterNodes,
+		cluster.RegisterPredefinedNodes,
 		analytic.RetrieveNodesStatus,
 	}
 

+ 10 - 0
settings/cluster.go

@@ -7,3 +7,13 @@ type Cluster struct {
 var ClusterSettings = Cluster{
 	Node: []string{},
 }
+
+func ReloadCluster() (err error) {
+	err = load()
+
+	if err != nil {
+		return err
+	}
+
+	return mapTo("cluster", &ClusterSettings)
+}

+ 14 - 8
settings/settings.go

@@ -39,13 +39,18 @@ func Init(confPath string) {
 	Setup()
 }
 
-func Setup() {
-	var err error
+func load() (err error) {
 	Conf, err = ini.LoadSources(ini.LoadOptions{
 		Loose:        true,
 		AllowShadows: true,
 	}, ConfPath)
 
+	return
+}
+
+func Setup() {
+	err := load()
+
 	if err != nil {
 		log.Fatalf("settings.Setup: %v\n", err)
 	}
@@ -72,7 +77,11 @@ func Setup() {
 
 func MapTo() {
 	for k, v := range sections {
-		mapTo(k, v)
+		err := mapTo(k, v)
+
+		if err != nil {
+			log.Fatalf("Cfg.MapTo %s err: %v", k, err)
+		}
 	}
 }
 
@@ -101,11 +110,8 @@ func ProtectedFill(targetSettings interface{}, newSettings interface{}) {
 	}
 }
 
-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 mapTo(section string, v interface{}) error {
+	return Conf.Section(section).MapTo(v)
 }
 
 func reflectFrom(section string, v interface{}) {