144 lines
3.7 KiB
Go
144 lines
3.7 KiB
Go
package service
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"git.zkcoi.com/zkcoi/meshray/internal/model"
|
|
"git.zkcoi.com/zkcoi/meshray/internal/store/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// PolicyService 策略管理服务
|
|
type PolicyService struct {
|
|
store *sqlite.Store
|
|
}
|
|
|
|
// NewPolicyService 创建策略服务实例
|
|
func NewPolicyService(store *sqlite.Store) *PolicyService {
|
|
return &PolicyService{store: store}
|
|
}
|
|
|
|
// ListPolicies 获取策略列表
|
|
func (s *PolicyService) ListPolicies() ([]model.Policy, error) {
|
|
var policies []model.Policy
|
|
err := s.store.DB().Order("created_at desc").Find(&policies).Error
|
|
return policies, err
|
|
}
|
|
|
|
// GetPolicyByID 根据 ID 获取策略
|
|
func (s *PolicyService) GetPolicyByID(id uint) (*model.Policy, error) {
|
|
var policy model.Policy
|
|
if err := s.store.DB().First(&policy, id).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errors.New("策略不存在")
|
|
}
|
|
return nil, err
|
|
}
|
|
return &policy, nil
|
|
}
|
|
|
|
// CreatePolicy 创建策略
|
|
func (s *PolicyService) CreatePolicy(req *model.Policy) (*model.Policy, error) {
|
|
if req.Name == "" {
|
|
return nil, errors.New("策略名称不能为空")
|
|
}
|
|
|
|
// 检查名称是否重复
|
|
var existing model.Policy
|
|
if err := s.store.DB().Where("name = ?", req.Name).First(&existing).Error; err == nil {
|
|
return nil, errors.New("策略名称已存在")
|
|
}
|
|
|
|
// 默认值
|
|
if req.Type == "" {
|
|
req.Type = "custom"
|
|
}
|
|
req.Enabled = true
|
|
|
|
if err := s.store.DB().Create(req).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return req, nil
|
|
}
|
|
|
|
// UpdatePolicy 更新策略
|
|
func (s *PolicyService) UpdatePolicy(id uint, updates map[string]interface{}) (*model.Policy, error) {
|
|
var policy model.Policy
|
|
if err := s.store.DB().First(&policy, id).Error; err != nil {
|
|
return nil, errors.New("策略不存在")
|
|
}
|
|
|
|
// 系统默认策略不可编辑
|
|
if policy.Type == "system" {
|
|
return nil, errors.New("系统默认策略不可编辑")
|
|
}
|
|
|
|
if err := s.store.DB().Model(&policy).Updates(updates).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &policy, nil
|
|
}
|
|
|
|
// DeletePolicy 删除策略
|
|
func (s *PolicyService) DeletePolicy(id uint) error {
|
|
var policy model.Policy
|
|
if err := s.store.DB().First(&policy, id).Error; err != nil {
|
|
return errors.New("策略不存在")
|
|
}
|
|
|
|
// 系统默认策略不可删除
|
|
if policy.Type == "system" {
|
|
return errors.New("系统默认策略不可删除")
|
|
}
|
|
|
|
// 检查是否有关联的组网
|
|
var count int64
|
|
s.store.DB().Model(&model.Network{}).Where("policy_id = ?", id).Count(&count)
|
|
if count > 0 {
|
|
return errors.New("该策略正在被组网引用,无法删除")
|
|
}
|
|
|
|
return s.store.DB().Delete(&policy).Error
|
|
}
|
|
|
|
// InitializeDefaultPolicy 初始化默认策略
|
|
func (s *PolicyService) InitializeDefaultPolicy() error {
|
|
// 检查是否已存在默认策略
|
|
var count int64
|
|
s.store.DB().Model(&model.Policy{}).Where("type = ?", "system").Count(&count)
|
|
if count > 0 {
|
|
return nil // 已存在默认策略
|
|
}
|
|
|
|
// 创建默认策略
|
|
defaultPolicy := &model.Policy{
|
|
Name: "系统默认策略",
|
|
Type: "system",
|
|
Description: "MeshRay 系统默认传输策略,包含基础的 P2P 直连和 TURN 中继功能",
|
|
Enabled: true,
|
|
IsDefault: true,
|
|
LayerConfig: `{
|
|
"tunnel": {"enabled": true},
|
|
"obfuscation": {"enabled": false, "method": "xor"},
|
|
"compression": {"enabled": false, "algorithm": "lz4"},
|
|
"mux": {"enabled": false, "protocol": "yamux", "streams": 4},
|
|
"fec": {"enabled": false, "mode": "rs", "redundancy": 20},
|
|
"qos": {"enabled": false},
|
|
"nat": {"enabled": true},
|
|
"relay": {"enabled": true}
|
|
}`,
|
|
GlobalParams: `{
|
|
"encryption": "chacha20poly1305",
|
|
"ipv6_enabled": false,
|
|
"connect_timeout": 10,
|
|
"fallback_threshold": 2000
|
|
}`,
|
|
}
|
|
|
|
if err := s.store.DB().Create(defaultPolicy).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|