mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2026-10-31 18:21:51 +08:00
142 lines
4.1 KiB
Go
142 lines
4.1 KiB
Go
package plugin
|
|
|
|
import (
|
|
"SamWaf/common/zlog"
|
|
"SamWaf/globalobj"
|
|
pluginconfig "SamWaf/plugin/config"
|
|
"SamWaf/plugin/manager"
|
|
"SamWaf/utils"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
// InitPluginSystem 初始化插件系统
|
|
// 从 plugins.yml 配置文件加载插件配置(不使用数据库)
|
|
func InitPluginSystem() error {
|
|
zlog.Info("开始初始化插件系统...")
|
|
|
|
// 1. 读取插件配置文件
|
|
configPath := filepath.Join(utils.GetCurrentDir(), "conf", "plugins.yml")
|
|
systemConfig, err := loadPluginConfigFromFile(configPath)
|
|
if err != nil {
|
|
zlog.Error("加载插件配置文件失败", "path", configPath, "error", err)
|
|
// 配置文件加载失败不应该阻止系统启动,使用默认配置
|
|
zlog.Info("使用默认插件配置")
|
|
systemConfig = pluginconfig.DefaultPluginSystemConfig()
|
|
systemConfig.Enabled = false // 默认禁用
|
|
}
|
|
|
|
// 2. 创建插件管理器
|
|
pluginManager := manager.NewPluginManager(systemConfig)
|
|
globalobj.GWAF_RUNTIME_OBJ_PLUGIN_MANAGER = pluginManager
|
|
|
|
// 3. 如果插件系统未启用,直接返回
|
|
if !systemConfig.Enabled {
|
|
zlog.Info("插件系统未启用,跳过插件加载")
|
|
return nil
|
|
}
|
|
|
|
// 4. 加载每个启用的插件
|
|
loadedCount := 0
|
|
for _, pluginConfig := range systemConfig.List {
|
|
if !pluginConfig.Enabled {
|
|
zlog.Debug("插件未启用,跳过加载", "plugin_id", pluginConfig.ID, "plugin_name", pluginConfig.Name)
|
|
continue
|
|
}
|
|
|
|
zlog.Info("加载插件", "plugin_id", pluginConfig.ID, "plugin_name", pluginConfig.Name)
|
|
if err := pluginManager.LoadPlugin(&pluginConfig); err != nil {
|
|
zlog.Error("加载插件失败", "plugin_id", pluginConfig.ID, "error", err)
|
|
continue
|
|
}
|
|
|
|
loadedCount++
|
|
zlog.Info("插件加载成功", "plugin_id", pluginConfig.ID, "plugin_name", pluginConfig.Name)
|
|
}
|
|
|
|
zlog.Info("插件系统初始化完成", "总插件数", len(systemConfig.List), "已加载", loadedCount)
|
|
return nil
|
|
}
|
|
|
|
// loadPluginConfigFromFile 从 YAML 配置文件加载插件配置
|
|
func loadPluginConfigFromFile(configPath string) (*pluginconfig.PluginSystemConfig, error) {
|
|
// 检查文件是否存在
|
|
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
|
return nil, fmt.Errorf("配置文件不存在: %s", configPath)
|
|
}
|
|
|
|
// 读取文件内容
|
|
data, err := os.ReadFile(configPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("读取配置文件失败: %w", err)
|
|
}
|
|
|
|
// 定义配置文件结构
|
|
type ConfigFile struct {
|
|
Plugins pluginconfig.PluginSystemConfig `yaml:"plugins"`
|
|
}
|
|
|
|
var configFile ConfigFile
|
|
if err := yaml.Unmarshal(data, &configFile); err != nil {
|
|
return nil, fmt.Errorf("解析配置文件失败: %w", err)
|
|
}
|
|
|
|
zlog.Info("成功加载插件配置文件",
|
|
"enabled", configFile.Plugins.Enabled,
|
|
"plugin_count", len(configFile.Plugins.List))
|
|
|
|
return &configFile.Plugins, nil
|
|
}
|
|
|
|
// SavePluginConfigToFile 保存插件配置到文件
|
|
// 供 API 使用,用于在线修改配置
|
|
func SavePluginConfigToFile(systemConfig *pluginconfig.PluginSystemConfig) error {
|
|
configPath := filepath.Join(utils.GetCurrentDir(), "conf", "plugins.yml")
|
|
|
|
// 构造配置文件结构
|
|
type ConfigFile struct {
|
|
Plugins pluginconfig.PluginSystemConfig `yaml:"plugins"`
|
|
}
|
|
|
|
configFile := ConfigFile{
|
|
Plugins: *systemConfig,
|
|
}
|
|
|
|
// 序列化为 YAML
|
|
data, err := yaml.Marshal(&configFile)
|
|
if err != nil {
|
|
return fmt.Errorf("序列化配置失败: %w", err)
|
|
}
|
|
|
|
// 备份原配置文件
|
|
backupPath := configPath + ".backup"
|
|
if _, err := os.Stat(configPath); err == nil {
|
|
os.Rename(configPath, backupPath)
|
|
}
|
|
|
|
// 写入文件
|
|
if err := os.WriteFile(configPath, data, 0644); err != nil {
|
|
// 如果写入失败,恢复备份
|
|
if _, err := os.Stat(backupPath); err == nil {
|
|
os.Rename(backupPath, configPath)
|
|
}
|
|
return fmt.Errorf("写入配置文件失败: %w", err)
|
|
}
|
|
|
|
zlog.Info("插件配置已保存", "path", configPath)
|
|
return nil
|
|
}
|
|
|
|
// ShutdownPluginSystem 关闭插件系统
|
|
func ShutdownPluginSystem() error {
|
|
if globalobj.GWAF_RUNTIME_OBJ_PLUGIN_MANAGER == nil {
|
|
return nil
|
|
}
|
|
|
|
zlog.Info("关闭插件系统...")
|
|
return globalobj.GWAF_RUNTIME_OBJ_PLUGIN_MANAGER.Shutdown()
|
|
}
|