github.com/TeaOSLab/EdgeNode@v1.3.8/internal/iplibrary/action_manager.go (about) 1 package iplibrary 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" 9 "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" 10 "github.com/TeaOSLab/EdgeNode/internal/remotelogs" 11 "strconv" 12 "sync" 13 ) 14 15 var SharedActionManager = NewActionManager() 16 17 // ActionManager 动作管理器定义 18 type ActionManager struct { 19 locker sync.Mutex 20 21 eventMap map[string][]ActionInterface // eventLevel => []instance 22 configMap map[int64]*firewallconfigs.FirewallActionConfig // id => config 23 instanceMap map[int64]ActionInterface // id => instance 24 } 25 26 // NewActionManager 获取动作管理对象 27 func NewActionManager() *ActionManager { 28 return &ActionManager{ 29 configMap: map[int64]*firewallconfigs.FirewallActionConfig{}, 30 instanceMap: map[int64]ActionInterface{}, 31 } 32 } 33 34 // UpdateActions 更新配置 35 func (this *ActionManager) UpdateActions(actions []*firewallconfigs.FirewallActionConfig) { 36 this.locker.Lock() 37 defer this.locker.Unlock() 38 39 // 关闭不存在的 40 newActionsMap := map[int64]*firewallconfigs.FirewallActionConfig{} 41 for _, action := range actions { 42 newActionsMap[action.Id] = action 43 } 44 for _, oldAction := range this.configMap { 45 _, ok := newActionsMap[oldAction.Id] 46 if !ok { 47 instance, ok := this.instanceMap[oldAction.Id] 48 if ok { 49 _ = instance.Close() 50 delete(this.instanceMap, oldAction.Id) 51 remotelogs.Println("IPLIBRARY/ACTION_MANAGER", "close action "+strconv.FormatInt(oldAction.Id, 10)) 52 } 53 } 54 } 55 56 // 添加新的或者更新老的 57 for _, newAction := range newActionsMap { 58 oldInstance, ok := this.instanceMap[newAction.Id] 59 if ok { 60 // 检查配置是否一致 61 oldConfigJSON, err := json.Marshal(this.configMap[newAction.Id]) 62 if err != nil { 63 remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type+": "+err.Error()) 64 continue 65 } 66 newConfigJSON, err := json.Marshal(newAction) 67 if err != nil { 68 remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type+": "+err.Error()) 69 continue 70 } 71 if !bytes.Equal(newConfigJSON, oldConfigJSON) { 72 _ = oldInstance.Close() 73 74 // 重新创建 75 // 之所以要重新创建,是因为前后的动作类型可能有变化,完全重建可以避免不必要的麻烦 76 newInstance, err := this.createInstance(newAction) 77 if err != nil { 78 remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "reload action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type+": "+err.Error()) 79 continue 80 } 81 remotelogs.Println("IPLIBRARY/ACTION_MANAGER", "reloaded "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type) 82 this.instanceMap[newAction.Id] = newInstance 83 } 84 } else { 85 // 创建 86 instance, err := this.createInstance(newAction) 87 if err != nil { 88 remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "load new action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type+": "+err.Error()) 89 continue 90 } 91 remotelogs.Println("IPLIBRARY/ACTION_MANAGER", "loaded action "+strconv.FormatInt(newAction.Id, 10)+", type:"+newAction.Type) 92 this.instanceMap[newAction.Id] = instance 93 } 94 } 95 96 // 更新配置 97 this.configMap = newActionsMap 98 this.eventMap = map[string][]ActionInterface{} 99 for _, action := range this.configMap { 100 instance, ok := this.instanceMap[action.Id] 101 if !ok { 102 continue 103 } 104 105 var instances = this.eventMap[action.EventLevel] 106 instances = append(instances, instance) 107 this.eventMap[action.EventLevel] = instances 108 } 109 } 110 111 // FindEventActions 查找事件对应的动作 112 func (this *ActionManager) FindEventActions(eventLevel string) []ActionInterface { 113 this.locker.Lock() 114 defer this.locker.Unlock() 115 return this.eventMap[eventLevel] 116 } 117 118 // AddItem 执行添加IP动作 119 func (this *ActionManager) AddItem(listType IPListType, item *pb.IPItem) { 120 instances, ok := this.eventMap[item.EventLevel] 121 if ok { 122 for _, instance := range instances { 123 err := instance.AddItem(listType, item) 124 if err != nil { 125 remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "add item '"+fmt.Sprintf("%d", item.Id)+"': "+err.Error()) 126 } 127 } 128 } 129 } 130 131 // DeleteItem 执行删除IP动作 132 func (this *ActionManager) DeleteItem(listType IPListType, item *pb.IPItem) { 133 instances, ok := this.eventMap[item.EventLevel] 134 if ok { 135 for _, instance := range instances { 136 err := instance.DeleteItem(listType, item) 137 if err != nil { 138 remotelogs.Error("IPLIBRARY/ACTION_MANAGER", "delete item '"+fmt.Sprintf("%d", item.Id)+"': "+err.Error()) 139 } 140 } 141 } 142 } 143 144 func (this *ActionManager) createInstance(config *firewallconfigs.FirewallActionConfig) (ActionInterface, error) { 145 var instance ActionInterface 146 switch config.Type { 147 case firewallconfigs.FirewallActionTypeIPSet: 148 instance = NewIPSetAction() 149 case firewallconfigs.FirewallActionTypeFirewalld: 150 instance = NewFirewalldAction() 151 case firewallconfigs.FirewallActionTypeIPTables: 152 instance = NewIPTablesAction() 153 case firewallconfigs.FirewallActionTypeScript: 154 instance = NewScriptAction() 155 case firewallconfigs.FirewallActionTypeHTTPAPI: 156 instance = NewHTTPAPIAction() 157 case firewallconfigs.FirewallActionTypeHTML: 158 instance = NewHTMLAction() 159 } 160 if instance == nil { 161 return nil, errors.New("can not create instance for type '" + config.Type + "'") 162 } 163 err := instance.Init(config) 164 if err != nil { 165 // 如果是警告错误,我们只是提示 166 if !IsFatalError(err) { 167 remotelogs.Error("IPLIBRARY/ACTION_MANAGER/CREATE_INSTANCE", "init '"+config.Type+"' failed: "+err.Error()) 168 } else { 169 return nil, err 170 } 171 } 172 return instance, nil 173 }