🎨几乎全部完成
This commit is contained in:
parent
49a851ac92
commit
6af6eec866
159
.gitignore
vendored
159
.gitignore
vendored
@ -101,6 +101,165 @@ fabric.properties
|
||||
go.work
|
||||
|
||||
.idea
|
||||
web/.idea
|
||||
|
||||
web/node_modules
|
||||
web/.DS_Store
|
||||
web/dist
|
||||
web/dist-ssr
|
||||
web/*.local
|
||||
web/.eslintcache
|
||||
web/report.html
|
||||
web/vite.config.*.timestamp*
|
||||
|
||||
web/yarn.lock
|
||||
web/npm-debug.log*
|
||||
web/.pnpm-error.log*
|
||||
web/.pnpm-debug.log
|
||||
web/tests/**/coverage/
|
||||
web/.vscode/
|
||||
|
||||
# Editor directories and files
|
||||
web/*.suo
|
||||
web/*.ntvs*
|
||||
web/*.njsproj
|
||||
web/*.sln
|
||||
web/tsconfig.tsbuildinfo
|
||||
|
||||
template/tmp/*
|
||||
logs/*
|
||||
app.yaml
|
||||
*.db
|
||||
.env
|
||||
*.env
|
||||
|
||||
### GoLand+all template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### Go template
|
||||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
#
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
.idea
|
||||
web/.idea
|
||||
|
||||
web/node_modules
|
||||
web/.DS_Store
|
||||
web/dist
|
||||
web/dist-ssr
|
||||
web/*.local
|
||||
web/.eslintcache
|
||||
web/report.html
|
||||
web/vite.config.*.timestamp*
|
||||
|
||||
web/yarn.lock
|
||||
web/npm-debug.log*
|
||||
web/.pnpm-error.log*
|
||||
web/.pnpm-debug.log
|
||||
web/tests/**/coverage/
|
||||
web/.vscode/
|
||||
|
||||
# Editor directories and files
|
||||
web/*.suo
|
||||
web/*.ntvs*
|
||||
web/*.njsproj
|
||||
web/*.sln
|
||||
web/tsconfig.tsbuildinfo
|
||||
|
||||
template/tmp/*
|
||||
logs/*
|
||||
|
@ -3,15 +3,22 @@ package command
|
||||
import (
|
||||
"fmt"
|
||||
"gitee.ltd/lxh/logger/log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"wireguard-ui/service"
|
||||
)
|
||||
|
||||
// 分隔符
|
||||
// getConfigFileName
|
||||
// @description: 获取服务端配置文件名称
|
||||
// @return string
|
||||
func getConfigFileName() string {
|
||||
func getConfigFileName(filePath string) string {
|
||||
if filePath != "" {
|
||||
filePath = strings.Split(filePath, string(os.PathSeparator))[len(strings.Split(filePath, string(os.PathSeparator)))-1] // 这里取到的是wg0.conf
|
||||
filePath = strings.Split(filePath, ".conf")[0] // 这里取到的就是wg0
|
||||
return filePath
|
||||
}
|
||||
data, err := service.Setting().GetWGSetForConfig()
|
||||
if err != nil {
|
||||
log.Errorf("获取服务端配置失败: %v", err.Error())
|
||||
@ -29,23 +36,23 @@ func getConfigFileName() string {
|
||||
// RestartWireguard
|
||||
// @description: 是否重启
|
||||
// @param isAsync // 是否异步执行
|
||||
func RestartWireguard(isAsync bool) {
|
||||
func RestartWireguard(isAsync bool, filePath string) {
|
||||
if isAsync {
|
||||
go func() {
|
||||
StopWireguard() // 停止
|
||||
StartWireguard() // 启动
|
||||
StopWireguard(filePath) // 停止
|
||||
StartWireguard(filePath) // 启动
|
||||
}()
|
||||
} else {
|
||||
StopWireguard() // 停止
|
||||
StartWireguard() // 启动
|
||||
StopWireguard(filePath) // 停止
|
||||
StartWireguard(filePath) // 启动
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// StopWireguard
|
||||
// @description: 停止服务端
|
||||
func StopWireguard() {
|
||||
configFileName := getConfigFileName()
|
||||
func StopWireguard(filePath string) {
|
||||
configFileName := getConfigFileName(filePath)
|
||||
|
||||
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("wg-quick down %s", configFileName))
|
||||
if err := cmd.Run(); err == nil {
|
||||
@ -57,12 +64,13 @@ func StopWireguard() {
|
||||
|
||||
// StartWireguard
|
||||
// @description: 启动服务端
|
||||
func StartWireguard() {
|
||||
configFileName := getConfigFileName()
|
||||
func StartWireguard(filePath string) {
|
||||
configFileName := getConfigFileName(filePath)
|
||||
|
||||
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("wg-quick up %s", configFileName))
|
||||
if err := cmd.Run(); err == nil {
|
||||
log.Infof("启动wireguard[%s]服务端成功", configFileName)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"wireguard-ui/config"
|
||||
"wireguard-ui/global/client"
|
||||
"wireguard-ui/model"
|
||||
"wireguard-ui/service"
|
||||
"wireguard-ui/template/render_data"
|
||||
)
|
||||
|
||||
@ -113,20 +114,22 @@ func (w WireguardComponent) GenerateClientFile(clientInfo *model.Client, server
|
||||
// @receiver w
|
||||
// @return error
|
||||
func (w WireguardComponent) ServerControl(filePath string) {
|
||||
switch config.Config.Wireguard.RestartMode {
|
||||
case "NOW": // 立即执行
|
||||
w.watchConfigFile(filePath)
|
||||
case "DELAY": // 延迟执行
|
||||
time.Sleep(time.Duration(config.Config.Wireguard.DelayTime) * time.Second)
|
||||
w.watchConfigFile(filePath)
|
||||
if filePath == "" {
|
||||
data, err := service.Setting().GetWGSetForConfig()
|
||||
if err != nil {
|
||||
log.Errorf("获取服务端配置失败: %v", err.Error())
|
||||
return
|
||||
}
|
||||
filePath = data.ConfigFilePath
|
||||
}
|
||||
w.watchConfigFile(filePath, config.Config.Wireguard.RestartMode, config.Config.Wireguard.DelayTime)
|
||||
}
|
||||
|
||||
// watchConfigFile
|
||||
// @description: 监听并重新操作配置文件
|
||||
// @receiver w
|
||||
// @param filepath
|
||||
func (w WireguardComponent) watchConfigFile(filepath string) {
|
||||
func (w WireguardComponent) watchConfigFile(filepath string, mode string, delay int64) {
|
||||
go func() {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
@ -146,7 +149,14 @@ func (w WireguardComponent) watchConfigFile(filepath string) {
|
||||
}
|
||||
|
||||
if event.Op == fsnotify.Write {
|
||||
command.RestartWireguard(true)
|
||||
switch mode {
|
||||
case "NOW":
|
||||
command.RestartWireguard(false, filepath)
|
||||
case "DELAY":
|
||||
time.Sleep(time.Duration(delay) * time.Second)
|
||||
command.RestartWireguard(true, filepath)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 打印监听事件
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"wireguard-ui/http/response"
|
||||
"wireguard-ui/http/vo"
|
||||
"wireguard-ui/model"
|
||||
"wireguard-ui/script"
|
||||
"wireguard-ui/service"
|
||||
"wireguard-ui/utils"
|
||||
)
|
||||
@ -44,7 +45,12 @@ func (ClientApi) Save(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
component.Wireguard().ServerControl("E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\wg0.conf")
|
||||
go func() {
|
||||
if err := script.New().GenerateConfig(); err != nil {
|
||||
log.Errorf("执行脚本失败")
|
||||
}
|
||||
}()
|
||||
|
||||
response.R(c).OK()
|
||||
}
|
||||
|
||||
@ -64,7 +70,12 @@ func (ClientApi) Delete(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
component.Wireguard().ServerControl("E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\wg0.conf")
|
||||
go func() {
|
||||
if err := script.New().GenerateConfig(); err != nil {
|
||||
log.Errorf("执行脚本失败")
|
||||
}
|
||||
}()
|
||||
|
||||
response.R(c).OK()
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"gitee.ltd/lxh/logger/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
"slices"
|
||||
"wireguard-ui/http/param"
|
||||
"wireguard-ui/http/response"
|
||||
"wireguard-ui/model"
|
||||
"wireguard-ui/script"
|
||||
"wireguard-ui/service"
|
||||
"wireguard-ui/utils"
|
||||
)
|
||||
@ -35,6 +38,15 @@ func (setting) Set(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var whiteCodes = []string{"WG_SETTING", "WG_SERVER"}
|
||||
if slices.Contains(whiteCodes, p.Code) {
|
||||
go func() {
|
||||
if err := script.New().GenerateConfig(); err != nil {
|
||||
log.Errorf("执行脚本失败")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
response.R(c).OK()
|
||||
}
|
||||
|
||||
|
81
script/conf_script.go
Normal file
81
script/conf_script.go
Normal file
@ -0,0 +1,81 @@
|
||||
package script
|
||||
|
||||
import (
|
||||
"github.com/spf13/cast"
|
||||
"os"
|
||||
"time"
|
||||
"wireguard-ui/component"
|
||||
"wireguard-ui/http/param"
|
||||
"wireguard-ui/service"
|
||||
"wireguard-ui/template/render_data"
|
||||
)
|
||||
|
||||
// GenerateConfig
|
||||
// @description: 生成配置文件
|
||||
// @receiver script
|
||||
// @return error
|
||||
func (script) GenerateConfig() error {
|
||||
// 获取服务端相关配置
|
||||
serverEnt, err := service.Setting().GetWGServerForConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
global, err := service.Setting().GetWGSetForConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取客户端
|
||||
clientsEnt, _, err := service.Client().List(param.ClientList{
|
||||
Page: param.Page{
|
||||
Current: -1,
|
||||
Size: -1,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var clients []render_data.Client
|
||||
for _, client := range clientsEnt {
|
||||
clients = append(clients, render_data.Client{
|
||||
ID: client.Id,
|
||||
Name: client.Name,
|
||||
Email: client.Email,
|
||||
PublicKey: client.Keys.PublicKey,
|
||||
PresharedKey: client.Keys.PresharedKey,
|
||||
AllowedIPS: client.AllowedIpsStr,
|
||||
Endpoint: client.Endpoint,
|
||||
CreateUser: client.CreateUser,
|
||||
Enabled: cast.ToBool(client.Enabled),
|
||||
PersistentKeepalive: global.PersistentKeepalive,
|
||||
CreatedAt: client.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: client.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
SyncAt: time.Now().Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
execData := map[string]any{
|
||||
"Server": serverEnt,
|
||||
"Clients": clients,
|
||||
}
|
||||
|
||||
var templatePath, outFilePath string
|
||||
if os.Getenv("GIN_MODE") != "release" {
|
||||
templatePath = "E:\\Workspace\\Go\\wireguard-ui\\template\\conf\\wg.conf"
|
||||
outFilePath = "E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\wg0.conf"
|
||||
} else {
|
||||
templatePath = "./template/wg.conf"
|
||||
outFilePath = cast.ToString(global.ConfigFilePath)
|
||||
}
|
||||
|
||||
// 先渲染模板
|
||||
if err = component.Template().Execute(templatePath, outFilePath, execData); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 模板渲染成功,开始执行服务端控制
|
||||
component.Wireguard().ServerControl(outFilePath)
|
||||
return nil
|
||||
}
|
@ -15,6 +15,7 @@ Table = {{ .Server.Table|html }}
|
||||
# CreatedAt: {{ .CreatedAt|html }}
|
||||
# UpdatedAt: {{ .UpdatedAt|html }}
|
||||
# CreateUser: {{ .CreateUser|html }}
|
||||
# SyncAt: {{ .SyncAt|html }}
|
||||
[Peer]
|
||||
PublicKey = {{ .PublicKey|html }}
|
||||
PresharedKey = {{ .PresharedKey|html }}
|
||||
|
@ -30,12 +30,13 @@ type Client struct {
|
||||
PublicKey string `json:"publicKey"`
|
||||
PresharedKey string `json:"presharedKey"`
|
||||
AllowedIPS string `json:"allowedIps"`
|
||||
PersistentKeepalive string `json:"persistentKeepalive"`
|
||||
PersistentKeepalive int `json:"persistentKeepalive"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
CreateUser string `json:"createUser"`
|
||||
Enabled bool `json:"enabled"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
SyncAt string `json:"syncAt"`
|
||||
}
|
||||
|
||||
type Keys struct {
|
||||
|
Loading…
Reference in New Issue
Block a user