1
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 31s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 1m18s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m24s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 1m11s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 1m43s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m28s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 1m2s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 1m33s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m51s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 1m1s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m38s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 1m10s
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 31s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 1m18s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m24s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 1m11s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 1m43s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m28s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 1m2s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 1m33s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m51s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 1m1s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m38s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 1m10s
This commit is contained in:
@@ -525,13 +525,24 @@ func (c *Client) handleClientPluginConn(stream net.Conn, msg *protocol.Message)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
key := req.PluginName + ":" + req.RuleName
|
|
||||||
c.pluginMu.RLock()
|
c.pluginMu.RLock()
|
||||||
handler, ok := c.runningPlugins[key]
|
var handler plugin.ClientPlugin
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
// 优先使用 PluginID 查找
|
||||||
|
if req.PluginID != "" {
|
||||||
|
handler, ok = c.runningPlugins[req.PluginID]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没找到,回退到 pluginName:ruleName
|
||||||
|
if !ok {
|
||||||
|
key := req.PluginName + ":" + req.RuleName
|
||||||
|
handler, ok = c.runningPlugins[key]
|
||||||
|
}
|
||||||
c.pluginMu.RUnlock()
|
c.pluginMu.RUnlock()
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
c.logWarnf("[Client] Plugin %s not running", key)
|
c.logWarnf("[Client] Plugin %s (ID: %s) not running", req.PluginName, req.PluginID)
|
||||||
stream.Close()
|
stream.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -696,10 +707,25 @@ func (c *Client) handleClientPluginStop(stream net.Conn, msg *protocol.Message)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
key := req.PluginName + ":" + req.RuleName
|
|
||||||
|
|
||||||
c.pluginMu.Lock()
|
c.pluginMu.Lock()
|
||||||
handler, ok := c.runningPlugins[key]
|
var handler plugin.ClientPlugin
|
||||||
|
var key string
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
// 优先使用 PluginID 查找
|
||||||
|
if req.PluginID != "" {
|
||||||
|
handler, ok = c.runningPlugins[req.PluginID]
|
||||||
|
if ok {
|
||||||
|
key = req.PluginID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没找到,回退到 pluginName:ruleName
|
||||||
|
if !ok {
|
||||||
|
key = req.PluginName + ":" + req.RuleName
|
||||||
|
handler, ok = c.runningPlugins[key]
|
||||||
|
}
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
if err := handler.Stop(); err != nil {
|
if err := handler.Stop(); err != nil {
|
||||||
c.logErrorf("[Client] Plugin %s stop error: %v", key, err)
|
c.logErrorf("[Client] Plugin %s stop error: %v", key, err)
|
||||||
@@ -754,13 +780,28 @@ func (c *Client) handlePluginConfigUpdate(stream net.Conn, msg *protocol.Message
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
key := req.PluginName + ":" + req.RuleName
|
|
||||||
c.logf("[Client] Config update for plugin %s", key)
|
|
||||||
|
|
||||||
c.pluginMu.RLock()
|
c.pluginMu.RLock()
|
||||||
handler, ok := c.runningPlugins[key]
|
var handler plugin.ClientPlugin
|
||||||
|
var key string
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
// 优先使用 PluginID 查找
|
||||||
|
if req.PluginID != "" {
|
||||||
|
handler, ok = c.runningPlugins[req.PluginID]
|
||||||
|
if ok {
|
||||||
|
key = req.PluginID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没找到,回退到 pluginName:ruleName
|
||||||
|
if !ok {
|
||||||
|
key = req.PluginName + ":" + req.RuleName
|
||||||
|
handler, ok = c.runningPlugins[key]
|
||||||
|
}
|
||||||
c.pluginMu.RUnlock()
|
c.pluginMu.RUnlock()
|
||||||
|
|
||||||
|
c.logf("[Client] Config update for plugin %s", key)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
c.sendPluginConfigUpdateResult(stream, req.PluginName, req.RuleName, false, "plugin not running")
|
c.sendPluginConfigUpdateResult(stream, req.PluginName, req.RuleName, false, "plugin not running")
|
||||||
return
|
return
|
||||||
|
|||||||
2
internal/server/app/dist/.gitkeep
vendored
2
internal/server/app/dist/.gitkeep
vendored
@@ -1,2 +0,0 @@
|
|||||||
# This file ensures the dist directory exists for go:embed
|
|
||||||
# The actual frontend files are built during CI/CD
|
|
||||||
@@ -372,17 +372,17 @@ func (h *ClientHandler) PluginAction(c *gin.Context) {
|
|||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case "start":
|
case "start":
|
||||||
err = h.app.GetServer().StartClientPlugin(clientID, pluginName, req.RuleName)
|
err = h.app.GetServer().StartClientPlugin(clientID, pluginID, pluginName, req.RuleName)
|
||||||
case "stop":
|
case "stop":
|
||||||
err = h.app.GetServer().StopClientPlugin(clientID, pluginName, req.RuleName)
|
err = h.app.GetServer().StopClientPlugin(clientID, pluginID, pluginName, req.RuleName)
|
||||||
case "restart":
|
case "restart":
|
||||||
err = h.app.GetServer().RestartClientPlugin(clientID, pluginName, req.RuleName)
|
err = h.app.GetServer().RestartClientPlugin(clientID, pluginID, pluginName, req.RuleName)
|
||||||
case "config":
|
case "config":
|
||||||
if req.Config == nil {
|
if req.Config == nil {
|
||||||
BadRequest(c, "config required")
|
BadRequest(c, "config required")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = h.app.GetServer().UpdateClientPluginConfig(clientID, pluginName, req.RuleName, req.Config, req.Restart)
|
err = h.app.GetServer().UpdateClientPluginConfig(clientID, pluginID, pluginName, req.RuleName, req.Config, req.Restart)
|
||||||
case "delete":
|
case "delete":
|
||||||
err = h.deleteClientPlugin(clientID, pluginID)
|
err = h.deleteClientPlugin(clientID, pluginID)
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ type ServerInterface interface {
|
|||||||
SyncPluginConfigToClient(clientID string, pluginName string, config map[string]string) error
|
SyncPluginConfigToClient(clientID string, pluginName string, config map[string]string) error
|
||||||
InstallJSPluginToClient(clientID string, req JSPluginInstallRequest) error
|
InstallJSPluginToClient(clientID string, req JSPluginInstallRequest) error
|
||||||
RestartClient(clientID string) error
|
RestartClient(clientID string) error
|
||||||
StartClientPlugin(clientID, pluginName, ruleName string) error
|
StartClientPlugin(clientID, pluginID, pluginName, ruleName string) error
|
||||||
StopClientPlugin(clientID, pluginName, ruleName string) error
|
StopClientPlugin(clientID, pluginID, pluginName, ruleName string) error
|
||||||
RestartClientPlugin(clientID, pluginName, ruleName string) error
|
RestartClientPlugin(clientID, pluginID, pluginName, ruleName string) error
|
||||||
UpdateClientPluginConfig(clientID, pluginName, ruleName string, config map[string]string, restart bool) error
|
UpdateClientPluginConfig(clientID, pluginID, pluginName, ruleName string, config map[string]string, restart bool) error
|
||||||
SendUpdateToClient(clientID, downloadURL string) error
|
SendUpdateToClient(clientID, downloadURL string) error
|
||||||
// 日志流
|
// 日志流
|
||||||
StartClientLogStream(clientID, sessionID string, lines int, follow bool, level string) (<-chan protocol.LogEntry, error)
|
StartClientLogStream(clientID, sessionID string, lines int, follow bool, level string) (<-chan protocol.LogEntry, error)
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ func (h *StoreHandler) Install(c *gin.Context) {
|
|||||||
dbClient.Rules[i].Type = req.PluginName
|
dbClient.Rules[i].Type = req.PluginName
|
||||||
dbClient.Rules[i].RemotePort = req.RemotePort
|
dbClient.Rules[i].RemotePort = req.RemotePort
|
||||||
dbClient.Rules[i].Enabled = boolPtr(true)
|
dbClient.Rules[i].Enabled = boolPtr(true)
|
||||||
|
dbClient.Rules[i].PluginID = pluginID
|
||||||
dbClient.Rules[i].AuthEnabled = req.AuthEnabled
|
dbClient.Rules[i].AuthEnabled = req.AuthEnabled
|
||||||
dbClient.Rules[i].AuthUsername = req.AuthUsername
|
dbClient.Rules[i].AuthUsername = req.AuthUsername
|
||||||
dbClient.Rules[i].AuthPassword = req.AuthPassword
|
dbClient.Rules[i].AuthPassword = req.AuthPassword
|
||||||
@@ -250,6 +251,7 @@ func (h *StoreHandler) Install(c *gin.Context) {
|
|||||||
Type: req.PluginName,
|
Type: req.PluginName,
|
||||||
RemotePort: req.RemotePort,
|
RemotePort: req.RemotePort,
|
||||||
Enabled: boolPtr(true),
|
Enabled: boolPtr(true),
|
||||||
|
PluginID: pluginID,
|
||||||
AuthEnabled: req.AuthEnabled,
|
AuthEnabled: req.AuthEnabled,
|
||||||
AuthUsername: req.AuthUsername,
|
AuthUsername: req.AuthUsername,
|
||||||
AuthPassword: req.AuthPassword,
|
AuthPassword: req.AuthPassword,
|
||||||
@@ -268,6 +270,7 @@ func (h *StoreHandler) Install(c *gin.Context) {
|
|||||||
Type: req.PluginName, // 使用插件名作为类型,让 isClientPlugin 识别
|
Type: req.PluginName, // 使用插件名作为类型,让 isClientPlugin 识别
|
||||||
RemotePort: req.RemotePort,
|
RemotePort: req.RemotePort,
|
||||||
Enabled: boolPtr(true),
|
Enabled: boolPtr(true),
|
||||||
|
PluginID: pluginID,
|
||||||
AuthEnabled: req.AuthEnabled,
|
AuthEnabled: req.AuthEnabled,
|
||||||
AuthUsername: req.AuthUsername,
|
AuthUsername: req.AuthUsername,
|
||||||
AuthPassword: req.AuthPassword,
|
AuthPassword: req.AuthPassword,
|
||||||
|
|||||||
@@ -1126,14 +1126,18 @@ func (s *Server) acceptClientPluginConns(cs *ClientSession, ln net.Listener, rul
|
|||||||
func (s *Server) handleClientPluginConn(cs *ClientSession, conn net.Conn, rule protocol.ProxyRule) {
|
func (s *Server) handleClientPluginConn(cs *ClientSession, conn net.Conn, rule protocol.ProxyRule) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
|
log.Printf("[Server] handleClientPluginConn: plugin=%s, auth=%v", rule.Type, rule.AuthEnabled)
|
||||||
|
|
||||||
// 如果启用了 HTTP Basic Auth,先进行认证
|
// 如果启用了 HTTP Basic Auth,先进行认证
|
||||||
var bufferedData []byte
|
var bufferedData []byte
|
||||||
if rule.AuthEnabled {
|
if rule.AuthEnabled {
|
||||||
authenticated, data := s.checkHTTPBasicAuth(conn, rule.AuthUsername, rule.AuthPassword)
|
authenticated, data := s.checkHTTPBasicAuth(conn, rule.AuthUsername, rule.AuthPassword)
|
||||||
if !authenticated {
|
if !authenticated {
|
||||||
|
log.Printf("[Server] Auth failed for plugin %s", rule.Type)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
bufferedData = data
|
bufferedData = data
|
||||||
|
log.Printf("[Server] Auth success, buffered %d bytes", len(bufferedData))
|
||||||
}
|
}
|
||||||
|
|
||||||
stream, err := cs.Session.Open()
|
stream, err := cs.Session.Open()
|
||||||
@@ -1144,6 +1148,7 @@ func (s *Server) handleClientPluginConn(cs *ClientSession, conn net.Conn, rule p
|
|||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
|
|
||||||
req := protocol.ClientPluginConnRequest{
|
req := protocol.ClientPluginConnRequest{
|
||||||
|
PluginID: rule.PluginID,
|
||||||
PluginName: rule.Type,
|
PluginName: rule.Type,
|
||||||
RuleName: rule.Name,
|
RuleName: rule.Name,
|
||||||
}
|
}
|
||||||
@@ -1331,6 +1336,7 @@ func (s *Server) pushClientInstalledPlugins(cs *ClientSession, alreadyPushed map
|
|||||||
Type: cp.Name,
|
Type: cp.Name,
|
||||||
RemotePort: cp.RemotePort,
|
RemotePort: cp.RemotePort,
|
||||||
Enabled: boolPtr(true),
|
Enabled: boolPtr(true),
|
||||||
|
PluginID: cp.ID,
|
||||||
AuthEnabled: cp.AuthEnabled,
|
AuthEnabled: cp.AuthEnabled,
|
||||||
AuthUsername: cp.AuthUsername,
|
AuthUsername: cp.AuthUsername,
|
||||||
AuthPassword: cp.AuthPassword,
|
AuthPassword: cp.AuthPassword,
|
||||||
@@ -1386,7 +1392,7 @@ func (s *Server) RestartClient(clientID string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StartClientPlugin 启动客户端插件
|
// StartClientPlugin 启动客户端插件
|
||||||
func (s *Server) StartClientPlugin(clientID, pluginName, ruleName string) error {
|
func (s *Server) StartClientPlugin(clientID, pluginID, pluginName, ruleName string) error {
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
_, ok := s.clients[clientID]
|
_, ok := s.clients[clientID]
|
||||||
s.mu.RUnlock()
|
s.mu.RUnlock()
|
||||||
@@ -1400,7 +1406,7 @@ func (s *Server) StartClientPlugin(clientID, pluginName, ruleName string) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StopClientPlugin 停止客户端插件
|
// StopClientPlugin 停止客户端插件
|
||||||
func (s *Server) StopClientPlugin(clientID, pluginName, ruleName string) error {
|
func (s *Server) StopClientPlugin(clientID, pluginID, pluginName, ruleName string) error {
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
cs, ok := s.clients[clientID]
|
cs, ok := s.clients[clientID]
|
||||||
s.mu.RUnlock()
|
s.mu.RUnlock()
|
||||||
@@ -1409,11 +1415,11 @@ func (s *Server) StopClientPlugin(clientID, pluginName, ruleName string) error {
|
|||||||
return fmt.Errorf("client %s not found or not online", clientID)
|
return fmt.Errorf("client %s not found or not online", clientID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.sendClientPluginStop(cs.Session, pluginName, ruleName)
|
return s.sendClientPluginStop(cs.Session, pluginID, pluginName, ruleName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendClientPluginStop 发送客户端插件停止命令
|
// sendClientPluginStop 发送客户端插件停止命令
|
||||||
func (s *Server) sendClientPluginStop(session *yamux.Session, pluginName, ruleName string) error {
|
func (s *Server) sendClientPluginStop(session *yamux.Session, pluginID, pluginName, ruleName string) error {
|
||||||
stream, err := session.Open()
|
stream, err := session.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -1421,6 +1427,7 @@ func (s *Server) sendClientPluginStop(session *yamux.Session, pluginName, ruleNa
|
|||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
|
|
||||||
req := protocol.ClientPluginStopRequest{
|
req := protocol.ClientPluginStopRequest{
|
||||||
|
PluginID: pluginID,
|
||||||
PluginName: pluginName,
|
PluginName: pluginName,
|
||||||
RuleName: ruleName,
|
RuleName: ruleName,
|
||||||
}
|
}
|
||||||
@@ -1566,7 +1573,7 @@ func (s *Server) ProxyPluginAPIRequest(clientID string, req protocol.PluginAPIRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RestartClientPlugin 重启客户端 JS 插件
|
// RestartClientPlugin 重启客户端 JS 插件
|
||||||
func (s *Server) RestartClientPlugin(clientID, pluginName, ruleName string) error {
|
func (s *Server) RestartClientPlugin(clientID, pluginID, pluginName, ruleName string) error {
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
_, ok := s.clients[clientID]
|
_, ok := s.clients[clientID]
|
||||||
s.mu.RUnlock()
|
s.mu.RUnlock()
|
||||||
@@ -1670,7 +1677,7 @@ func (s *Server) sendJSPluginRestart(session *yamux.Session, pluginName, ruleNam
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateClientPluginConfig 更新客户端插件配置
|
// UpdateClientPluginConfig 更新客户端插件配置
|
||||||
func (s *Server) UpdateClientPluginConfig(clientID, pluginName, ruleName string, config map[string]string, restart bool) error {
|
func (s *Server) UpdateClientPluginConfig(clientID, pluginID, pluginName, ruleName string, config map[string]string, restart bool) error {
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
cs, ok := s.clients[clientID]
|
cs, ok := s.clients[clientID]
|
||||||
s.mu.RUnlock()
|
s.mu.RUnlock()
|
||||||
@@ -1687,6 +1694,7 @@ func (s *Server) UpdateClientPluginConfig(clientID, pluginName, ruleName string,
|
|||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
|
|
||||||
req := protocol.PluginConfigUpdateRequest{
|
req := protocol.PluginConfigUpdateRequest{
|
||||||
|
PluginID: pluginID,
|
||||||
PluginName: pluginName,
|
PluginName: pluginName,
|
||||||
RuleName: ruleName,
|
RuleName: ruleName,
|
||||||
Config: config,
|
Config: config,
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ type ProxyRule struct {
|
|||||||
RemotePort int `json:"remote_port" yaml:"remote_port"` // 服务端监听端口
|
RemotePort int `json:"remote_port" yaml:"remote_port"` // 服务端监听端口
|
||||||
Enabled *bool `json:"enabled,omitempty" yaml:"enabled"` // 是否启用,默认为 true
|
Enabled *bool `json:"enabled,omitempty" yaml:"enabled"` // 是否启用,默认为 true
|
||||||
// Plugin 支持字段
|
// Plugin 支持字段
|
||||||
|
PluginID string `json:"plugin_id,omitempty" yaml:"plugin_id"` // 插件实例ID
|
||||||
PluginName string `json:"plugin_name,omitempty" yaml:"plugin_name"`
|
PluginName string `json:"plugin_name,omitempty" yaml:"plugin_name"`
|
||||||
PluginVersion string `json:"plugin_version,omitempty" yaml:"plugin_version"`
|
PluginVersion string `json:"plugin_version,omitempty" yaml:"plugin_version"`
|
||||||
PluginConfig map[string]string `json:"plugin_config,omitempty" yaml:"plugin_config"`
|
PluginConfig map[string]string `json:"plugin_config,omitempty" yaml:"plugin_config"`
|
||||||
@@ -218,6 +219,7 @@ type ClientPluginStartRequest struct {
|
|||||||
|
|
||||||
// ClientPluginStopRequest 停止客户端插件请求
|
// ClientPluginStopRequest 停止客户端插件请求
|
||||||
type ClientPluginStopRequest struct {
|
type ClientPluginStopRequest struct {
|
||||||
|
PluginID string `json:"plugin_id,omitempty"` // 插件ID(优先使用)
|
||||||
PluginName string `json:"plugin_name"` // 插件名称
|
PluginName string `json:"plugin_name"` // 插件名称
|
||||||
RuleName string `json:"rule_name"` // 规则名称
|
RuleName string `json:"rule_name"` // 规则名称
|
||||||
}
|
}
|
||||||
@@ -233,6 +235,7 @@ type ClientPluginStatusResponse struct {
|
|||||||
|
|
||||||
// ClientPluginConnRequest 客户端插件连接请求
|
// ClientPluginConnRequest 客户端插件连接请求
|
||||||
type ClientPluginConnRequest struct {
|
type ClientPluginConnRequest struct {
|
||||||
|
PluginID string `json:"plugin_id,omitempty"` // 插件ID(优先使用)
|
||||||
PluginName string `json:"plugin_name"` // 插件名称
|
PluginName string `json:"plugin_name"` // 插件名称
|
||||||
RuleName string `json:"rule_name"` // 规则名称
|
RuleName string `json:"rule_name"` // 规则名称
|
||||||
}
|
}
|
||||||
@@ -280,6 +283,7 @@ type ClientRestartResponse struct {
|
|||||||
|
|
||||||
// PluginConfigUpdateRequest 插件配置更新请求
|
// PluginConfigUpdateRequest 插件配置更新请求
|
||||||
type PluginConfigUpdateRequest struct {
|
type PluginConfigUpdateRequest struct {
|
||||||
|
PluginID string `json:"plugin_id,omitempty"` // 插件ID(优先使用)
|
||||||
PluginName string `json:"plugin_name"` // 插件名称
|
PluginName string `json:"plugin_name"` // 插件名称
|
||||||
RuleName string `json:"rule_name"` // 规则名称
|
RuleName string `json:"rule_name"` // 规则名称
|
||||||
Config map[string]string `json:"config"` // 新配置
|
Config map[string]string `json:"config"` // 新配置
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ $Platforms = @(
|
|||||||
@{OS="darwin"; Arch="amd64"},
|
@{OS="darwin"; Arch="amd64"},
|
||||||
@{OS="darwin"; Arch="arm64"}
|
@{OS="darwin"; Arch="arm64"}
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# 颜色输出函数
|
# 颜色输出函数
|
||||||
function Write-Info {
|
function Write-Info {
|
||||||
|
|||||||
Reference in New Issue
Block a user