🎨几乎全部完成
This commit is contained in:
parent
49a851ac92
commit
6af6eec866
159
.gitignore
vendored
159
.gitignore
vendored
@ -101,6 +101,165 @@ fabric.properties
|
|||||||
go.work
|
go.work
|
||||||
|
|
||||||
.idea
|
.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/*
|
template/tmp/*
|
||||||
logs/*
|
logs/*
|
||||||
|
@ -3,15 +3,22 @@ package command
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"gitee.ltd/lxh/logger/log"
|
"gitee.ltd/lxh/logger/log"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
"wireguard-ui/service"
|
"wireguard-ui/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 分隔符
|
||||||
// getConfigFileName
|
// getConfigFileName
|
||||||
// @description: 获取服务端配置文件名称
|
// @description: 获取服务端配置文件名称
|
||||||
// @return string
|
// @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()
|
data, err := service.Setting().GetWGSetForConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("获取服务端配置失败: %v", err.Error())
|
log.Errorf("获取服务端配置失败: %v", err.Error())
|
||||||
@ -29,23 +36,23 @@ func getConfigFileName() string {
|
|||||||
// RestartWireguard
|
// RestartWireguard
|
||||||
// @description: 是否重启
|
// @description: 是否重启
|
||||||
// @param isAsync // 是否异步执行
|
// @param isAsync // 是否异步执行
|
||||||
func RestartWireguard(isAsync bool) {
|
func RestartWireguard(isAsync bool, filePath string) {
|
||||||
if isAsync {
|
if isAsync {
|
||||||
go func() {
|
go func() {
|
||||||
StopWireguard() // 停止
|
StopWireguard(filePath) // 停止
|
||||||
StartWireguard() // 启动
|
StartWireguard(filePath) // 启动
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
StopWireguard() // 停止
|
StopWireguard(filePath) // 停止
|
||||||
StartWireguard() // 启动
|
StartWireguard(filePath) // 启动
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopWireguard
|
// StopWireguard
|
||||||
// @description: 停止服务端
|
// @description: 停止服务端
|
||||||
func StopWireguard() {
|
func StopWireguard(filePath string) {
|
||||||
configFileName := getConfigFileName()
|
configFileName := getConfigFileName(filePath)
|
||||||
|
|
||||||
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("wg-quick down %s", configFileName))
|
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("wg-quick down %s", configFileName))
|
||||||
if err := cmd.Run(); err == nil {
|
if err := cmd.Run(); err == nil {
|
||||||
@ -57,12 +64,13 @@ func StopWireguard() {
|
|||||||
|
|
||||||
// StartWireguard
|
// StartWireguard
|
||||||
// @description: 启动服务端
|
// @description: 启动服务端
|
||||||
func StartWireguard() {
|
func StartWireguard(filePath string) {
|
||||||
configFileName := getConfigFileName()
|
configFileName := getConfigFileName(filePath)
|
||||||
|
|
||||||
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("wg-quick up %s", configFileName))
|
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("wg-quick up %s", configFileName))
|
||||||
if err := cmd.Run(); err == nil {
|
if err := cmd.Run(); err == nil {
|
||||||
log.Infof("启动wireguard[%s]服务端成功", configFileName)
|
log.Infof("启动wireguard[%s]服务端成功", configFileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"wireguard-ui/config"
|
"wireguard-ui/config"
|
||||||
"wireguard-ui/global/client"
|
"wireguard-ui/global/client"
|
||||||
"wireguard-ui/model"
|
"wireguard-ui/model"
|
||||||
|
"wireguard-ui/service"
|
||||||
"wireguard-ui/template/render_data"
|
"wireguard-ui/template/render_data"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -113,20 +114,22 @@ func (w WireguardComponent) GenerateClientFile(clientInfo *model.Client, server
|
|||||||
// @receiver w
|
// @receiver w
|
||||||
// @return error
|
// @return error
|
||||||
func (w WireguardComponent) ServerControl(filePath string) {
|
func (w WireguardComponent) ServerControl(filePath string) {
|
||||||
switch config.Config.Wireguard.RestartMode {
|
if filePath == "" {
|
||||||
case "NOW": // 立即执行
|
data, err := service.Setting().GetWGSetForConfig()
|
||||||
w.watchConfigFile(filePath)
|
if err != nil {
|
||||||
case "DELAY": // 延迟执行
|
log.Errorf("获取服务端配置失败: %v", err.Error())
|
||||||
time.Sleep(time.Duration(config.Config.Wireguard.DelayTime) * time.Second)
|
return
|
||||||
w.watchConfigFile(filePath)
|
}
|
||||||
|
filePath = data.ConfigFilePath
|
||||||
}
|
}
|
||||||
|
w.watchConfigFile(filePath, config.Config.Wireguard.RestartMode, config.Config.Wireguard.DelayTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// watchConfigFile
|
// watchConfigFile
|
||||||
// @description: 监听并重新操作配置文件
|
// @description: 监听并重新操作配置文件
|
||||||
// @receiver w
|
// @receiver w
|
||||||
// @param filepath
|
// @param filepath
|
||||||
func (w WireguardComponent) watchConfigFile(filepath string) {
|
func (w WireguardComponent) watchConfigFile(filepath string, mode string, delay int64) {
|
||||||
go func() {
|
go func() {
|
||||||
watcher, err := fsnotify.NewWatcher()
|
watcher, err := fsnotify.NewWatcher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -146,7 +149,14 @@ func (w WireguardComponent) watchConfigFile(filepath string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if event.Op == fsnotify.Write {
|
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/response"
|
||||||
"wireguard-ui/http/vo"
|
"wireguard-ui/http/vo"
|
||||||
"wireguard-ui/model"
|
"wireguard-ui/model"
|
||||||
|
"wireguard-ui/script"
|
||||||
"wireguard-ui/service"
|
"wireguard-ui/service"
|
||||||
"wireguard-ui/utils"
|
"wireguard-ui/utils"
|
||||||
)
|
)
|
||||||
@ -44,7 +45,12 @@ func (ClientApi) Save(c *gin.Context) {
|
|||||||
return
|
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()
|
response.R(c).OK()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +70,12 @@ func (ClientApi) Delete(c *gin.Context) {
|
|||||||
return
|
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()
|
response.R(c).OK()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"gitee.ltd/lxh/logger/log"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"slices"
|
||||||
"wireguard-ui/http/param"
|
"wireguard-ui/http/param"
|
||||||
"wireguard-ui/http/response"
|
"wireguard-ui/http/response"
|
||||||
"wireguard-ui/model"
|
"wireguard-ui/model"
|
||||||
|
"wireguard-ui/script"
|
||||||
"wireguard-ui/service"
|
"wireguard-ui/service"
|
||||||
"wireguard-ui/utils"
|
"wireguard-ui/utils"
|
||||||
)
|
)
|
||||||
@ -35,6 +38,15 @@ func (setting) Set(c *gin.Context) {
|
|||||||
return
|
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()
|
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 }}
|
# CreatedAt: {{ .CreatedAt|html }}
|
||||||
# UpdatedAt: {{ .UpdatedAt|html }}
|
# UpdatedAt: {{ .UpdatedAt|html }}
|
||||||
# CreateUser: {{ .CreateUser|html }}
|
# CreateUser: {{ .CreateUser|html }}
|
||||||
|
# SyncAt: {{ .SyncAt|html }}
|
||||||
[Peer]
|
[Peer]
|
||||||
PublicKey = {{ .PublicKey|html }}
|
PublicKey = {{ .PublicKey|html }}
|
||||||
PresharedKey = {{ .PresharedKey|html }}
|
PresharedKey = {{ .PresharedKey|html }}
|
||||||
|
@ -30,12 +30,13 @@ type Client struct {
|
|||||||
PublicKey string `json:"publicKey"`
|
PublicKey string `json:"publicKey"`
|
||||||
PresharedKey string `json:"presharedKey"`
|
PresharedKey string `json:"presharedKey"`
|
||||||
AllowedIPS string `json:"allowedIps"`
|
AllowedIPS string `json:"allowedIps"`
|
||||||
PersistentKeepalive string `json:"persistentKeepalive"`
|
PersistentKeepalive int `json:"persistentKeepalive"`
|
||||||
Endpoint string `json:"endpoint"`
|
Endpoint string `json:"endpoint"`
|
||||||
CreateUser string `json:"createUser"`
|
CreateUser string `json:"createUser"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
CreatedAt string `json:"createdAt"`
|
CreatedAt string `json:"createdAt"`
|
||||||
UpdatedAt string `json:"updatedAt"`
|
UpdatedAt string `json:"updatedAt"`
|
||||||
|
SyncAt string `json:"syncAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Keys struct {
|
type Keys struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user