增加IP级别和WAF动作

This commit is contained in:
刘祥超
2021-02-06 17:37:09 +08:00
parent ed302370e9
commit 245c4374b4
46 changed files with 1000 additions and 186 deletions

View File

@@ -71,6 +71,10 @@ func (this *RPCClient) NodeClusterRPC() pb.NodeClusterServiceClient {
return pb.NewNodeClusterServiceClient(this.pickConn()) return pb.NewNodeClusterServiceClient(this.pickConn())
} }
func (this *RPCClient) NodeClusterFirewallActionRPC() pb.NodeClusterFirewallActionServiceClient {
return pb.NewNodeClusterFirewallActionServiceClient(this.pickConn())
}
func (this *RPCClient) NodeGroupRPC() pb.NodeGroupServiceClient { func (this *RPCClient) NodeGroupRPC() pb.NodeGroupServiceClient {
return pb.NewNodeGroupServiceClient(this.pickConn()) return pb.NewNodeGroupServiceClient(this.pickConn())
} }

View File

@@ -0,0 +1,115 @@
package firewallActions
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/actions"
)
type CreatePopupAction struct {
actionutils.ParentAction
}
func (this *CreatePopupAction) Init() {
this.Nav("", "", "")
}
func (this *CreatePopupAction) RunGet(params struct {
ClusterId int64
}) {
this.Data["clusterId"] = params.ClusterId
this.Data["actionTypes"] = firewallconfigs.FindAllFirewallActionTypes()
this.Show()
}
func (this *CreatePopupAction) RunPost(params struct {
ClusterId int64
Name string
EventLevel string
Type string
// ipset
IpsetWhiteName string
IpsetBlackName string
IpsetAutoAddToIPTables bool
IpsetAutoAddToFirewalld bool
// script
ScriptPath string
// http api
HttpAPIURL string
Must *actions.Must
CSRF *actionutils.CSRF
}) {
defer this.CreateLogInfo("创建WAF动作")
params.Must.
Field("name", params.Name).
Require("请输入动作名称").
Field("type", params.Type).
Require("请选择动作类型")
var actionParams interface{} = nil
switch params.Type {
case firewallconfigs.FirewallActionTypeIPSet:
params.Must.
Field("ipsetWhiteName", params.IpsetWhiteName).
Require("请输入IPSet白名单名称").
Match(`^\w+$`, "请输入正确的IPSet白名单名称").
Field("ipsetBlackName", params.IpsetBlackName).
Require("请输入IPSet黑名单名称").
Match(`^\w+$`, "请输入正确的IPSet黑名单名称")
actionParams = &firewallconfigs.FirewallActionIPSetConfig{
WhiteName: params.IpsetWhiteName,
BlackName: params.IpsetBlackName,
AutoAddToIPTables: params.IpsetAutoAddToIPTables,
AutoAddToFirewalld: params.IpsetAutoAddToFirewalld,
}
case firewallconfigs.FirewallActionTypeIPTables:
actionParams = &firewallconfigs.FirewallActionIPTablesConfig{}
case firewallconfigs.FirewallActionTypeFirewalld:
actionParams = &firewallconfigs.FirewallActionFirewalldConfig{}
case firewallconfigs.FirewallActionTypeScript:
params.Must.
Field("scriptPath", params.ScriptPath).
Require("请输入脚本路径")
actionParams = &firewallconfigs.FirewallActionScriptConfig{
Path: params.ScriptPath,
}
case firewallconfigs.FirewallActionTypeHTTPAPI:
params.Must.
Field("httpAPIURL", params.HttpAPIURL).
Require("请输入API URL").
Match(`^(http|https):`, "API地址必须以http://或https://开头")
actionParams = &firewallconfigs.FirewallActionHTTPAPIConfig{
URL: params.HttpAPIURL,
}
default:
this.Fail("选择的类型'" + params.Type + "'暂时不支持")
}
actionParamsJSON, err := json.Marshal(actionParams)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().NodeClusterFirewallActionRPC().CreateNodeClusterFirewallAction(this.AdminContext(), &pb.CreateNodeClusterFirewallActionRequest{
NodeClusterId: params.ClusterId,
Name: params.Name,
EventLevel: params.EventLevel,
Type: params.Type,
ParamsJSON: actionParamsJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,24 @@
package firewallActions
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
type DeleteAction struct {
actionutils.ParentAction
}
func (this *DeleteAction) RunPost(params struct {
ActionId int64
}) {
defer this.CreateLogInfo("删除WAF动作 %d", params.ActionId)
_, err := this.RPC().NodeClusterFirewallActionRPC().DeleteNodeClusterFirewallAction(this.AdminContext(), &pb.DeleteNodeClusterFirewallActionRequest{NodeClusterFirewallActionId: params.ActionId})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,65 @@
package firewallActions
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/maps"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "setting", "")
this.SecondMenu("firewallAction")
}
func (this *IndexAction) RunGet(params struct {
ClusterId int64
}) {
actionsResp, err := this.RPC().NodeClusterFirewallActionRPC().FindAllEnabledNodeClusterFirewallActions(this.AdminContext(), &pb.FindAllEnabledNodeClusterFirewallActionsRequest{NodeClusterId: params.ClusterId})
if err != nil {
this.ErrorPage(err)
return
}
levelMaps := map[string][]maps.Map{} // level => actionMaps
for _, action := range actionsResp.NodeClusterFirewallActions {
actionMaps, ok := levelMaps[action.EventLevel]
if !ok {
actionMaps = []maps.Map{}
}
actionMaps = append(actionMaps, maps.Map{
"id": action.Id,
"name": action.Name,
"type": action.Type,
"typeName": firewallconfigs.FindFirewallActionTypeName(action.Type),
})
levelMaps[action.EventLevel] = actionMaps
}
levelMaps2 := []maps.Map{} // []levelMap
hasActions := false
for _, level := range firewallconfigs.FindAllFirewallEventLevels() {
actionMaps, ok := levelMaps[level.Code]
if !ok {
actionMaps = []maps.Map{}
} else {
hasActions = true
}
levelMaps2 = append(levelMaps2, maps.Map{
"name": level.Name,
"code": level.Code,
"actions": actionMaps,
})
}
this.Data["levels"] = levelMaps2
this.Data["hasActions"] = hasActions
this.Show()
}

View File

@@ -0,0 +1,144 @@
package firewallActions
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
)
type UpdatePopupAction struct {
actionutils.ParentAction
}
func (this *UpdatePopupAction) Init() {
this.Nav("", "", "")
}
func (this *UpdatePopupAction) RunGet(params struct {
ActionId int64
}) {
actionResp, err := this.RPC().NodeClusterFirewallActionRPC().FindEnabledNodeClusterFirewallAction(this.AdminContext(), &pb.FindEnabledNodeClusterFirewallActionRequest{NodeClusterFirewallActionId: params.ActionId})
if err != nil {
this.ErrorPage(err)
return
}
action := actionResp.NodeClusterFirewallAction
if action == nil {
this.NotFound("nodeClusterFirewallAction", params.ActionId)
return
}
actionParams := maps.Map{}
if len(action.ParamsJSON) > 0 {
err = json.Unmarshal(action.ParamsJSON, &actionParams)
if err != nil {
this.ErrorPage(err)
return
}
}
this.Data["action"] = maps.Map{
"id": action.Id,
"name": action.Name,
"eventLevel": action.EventLevel,
"params": actionParams,
"type": action.Type,
}
// 通用参数
this.Data["actionTypes"] = firewallconfigs.FindAllFirewallActionTypes()
this.Show()
}
func (this *UpdatePopupAction) RunPost(params struct {
ActionId int64
Name string
EventLevel string
Type string
// ipset
IpsetWhiteName string
IpsetBlackName string
IpsetAutoAddToIPTables bool
IpsetAutoAddToFirewalld bool
// script
ScriptPath string
// http api
HttpAPIURL string
Must *actions.Must
CSRF *actionutils.CSRF
}) {
defer this.CreateLogInfo("修改WAF动作 %d", params.ActionId)
params.Must.
Field("name", params.Name).
Require("请输入动作名称").
Field("type", params.Type).
Require("请选择动作类型")
var actionParams interface{} = nil
switch params.Type {
case firewallconfigs.FirewallActionTypeIPSet:
params.Must.
Field("ipsetWhiteName", params.IpsetWhiteName).
Require("请输入IPSet白名单名称").
Match(`^\w+$`, "请输入正确的IPSet白名单名称").
Field("ipsetBlackName", params.IpsetBlackName).
Require("请输入IPSet黑名单名称").
Match(`^\w+$`, "请输入正确的IPSet黑名单名称")
actionParams = &firewallconfigs.FirewallActionIPSetConfig{
WhiteName: params.IpsetWhiteName,
BlackName: params.IpsetBlackName,
AutoAddToIPTables: params.IpsetAutoAddToIPTables,
AutoAddToFirewalld: params.IpsetAutoAddToFirewalld,
}
case firewallconfigs.FirewallActionTypeIPTables:
actionParams = &firewallconfigs.FirewallActionIPTablesConfig{}
case firewallconfigs.FirewallActionTypeFirewalld:
actionParams = &firewallconfigs.FirewallActionFirewalldConfig{}
case firewallconfigs.FirewallActionTypeScript:
params.Must.
Field("scriptPath", params.ScriptPath).
Require("请输入脚本路径")
actionParams = &firewallconfigs.FirewallActionScriptConfig{
Path: params.ScriptPath,
}
case firewallconfigs.FirewallActionTypeHTTPAPI:
params.Must.
Field("httpAPIURL", params.HttpAPIURL).
Require("请输入API URL").
Match(`^(http|https):`, "API地址必须以http://或https://开头")
actionParams = &firewallconfigs.FirewallActionHTTPAPIConfig{
URL: params.HttpAPIURL,
}
default:
this.Fail("选择的类型'" + params.Type + "'暂时不支持")
}
actionParamsJSON, err := json.Marshal(actionParams)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().NodeClusterFirewallActionRPC().UpdateNodeClusterFirewallAction(this.AdminContext(), &pb.UpdateNodeClusterFirewallActionRequest{
NodeClusterFirewallActionId: params.ActionId,
Name: params.Name,
EventLevel: params.EventLevel,
Type: params.Type,
ParamsJSON: actionParamsJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -4,6 +4,7 @@ import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders" "github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/cache" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/cache"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/dns" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/dns"
firewallActions "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/firewall-actions"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/services" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/services"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/toa" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/toa"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/waf" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/waf"
@@ -43,6 +44,13 @@ func init() {
GetPost("", new(services.IndexAction)). GetPost("", new(services.IndexAction)).
GetPost("/status", new(services.StatusAction)). GetPost("/status", new(services.StatusAction)).
// 防火墙动作
Prefix("/clusters/cluster/settings/firewall-actions").
Get("", new(firewallActions.IndexAction)).
GetPost("/createPopup", new(firewallActions.CreatePopupAction)).
GetPost("/updatePopup", new(firewallActions.UpdatePopupAction)).
Post("/delete", new(firewallActions.DeleteAction)).
EndAll() EndAll()
}) })
} }

View File

@@ -86,6 +86,11 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, selectedIt
"isActive": selectedItem == "waf", "isActive": selectedItem == "waf",
"isOn": cluster.HttpFirewallPolicyId > 0, "isOn": cluster.HttpFirewallPolicyId > 0,
}) })
items = append(items, maps.Map{
"name": "WAF动作",
"url": "/clusters/cluster/settings/firewall-actions?clusterId=" + clusterId,
"isActive": selectedItem == "firewallAction",
})
items = append(items, maps.Map{ items = append(items, maps.Map{
"name": "健康检查", "name": "健康检查",
"url": "/clusters/cluster/settings/health?clusterId=" + clusterId, "url": "/clusters/cluster/settings/health?clusterId=" + clusterId,

View File

@@ -41,6 +41,7 @@ func (this *CreateIPPopupAction) RunPost(params struct {
ExpiredAt int64 ExpiredAt int64
Reason string Reason string
Type string Type string
EventLevel string
Must *actions.Must Must *actions.Must
CSRF *actionutils.CSRF CSRF *actionutils.CSRF
@@ -83,12 +84,13 @@ func (this *CreateIPPopupAction) RunPost(params struct {
} }
createResp, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{ createResp, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{
IpListId: params.ListId, IpListId: params.ListId,
IpFrom: params.IpFrom, IpFrom: params.IpFrom,
IpTo: params.IpTo, IpTo: params.IpTo,
ExpiredAt: params.ExpiredAt, ExpiredAt: params.ExpiredAt,
Reason: params.Reason, Reason: params.Reason,
Type: params.Type, Type: params.Type,
EventLevel: params.EventLevel,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -4,6 +4,7 @@ import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time" timeutil "github.com/iwind/TeaGo/utils/time"
) )
@@ -58,12 +59,13 @@ func (this *ListsAction) RunGet(params struct {
} }
itemMaps = append(itemMaps, maps.Map{ itemMaps = append(itemMaps, maps.Map{
"id": item.Id, "id": item.Id,
"ipFrom": item.IpFrom, "ipFrom": item.IpFrom,
"ipTo": item.IpTo, "ipTo": item.IpTo,
"expiredTime": expiredTime, "expiredTime": expiredTime,
"reason": item.Reason, "reason": item.Reason,
"type": item.Type, "type": item.Type,
"eventLevelName": firewallconfigs.FindFirewallEventLevelName(item.EventLevel),
}) })
} }
this.Data["items"] = itemMaps this.Data["items"] = itemMaps

View File

@@ -3,6 +3,7 @@ package ipadmin
import ( import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time" timeutil "github.com/iwind/TeaGo/utils/time"
@@ -55,13 +56,14 @@ func (this *TestAction) RunPost(params struct {
} }
if resp.IpItem != nil { if resp.IpItem != nil {
resultMap["item"] = maps.Map{ resultMap["item"] = maps.Map{
"id": resp.IpItem.Id, "id": resp.IpItem.Id,
"ipFrom": resp.IpItem.IpFrom, "ipFrom": resp.IpItem.IpFrom,
"ipTo": resp.IpItem.IpTo, "ipTo": resp.IpItem.IpTo,
"reason": resp.IpItem.Reason, "reason": resp.IpItem.Reason,
"expiredAt": resp.IpItem.ExpiredAt, "expiredAt": resp.IpItem.ExpiredAt,
"expiredTime": timeutil.FormatTime("Y-m-d H:i:s", resp.IpItem.ExpiredAt), "expiredTime": timeutil.FormatTime("Y-m-d H:i:s", resp.IpItem.ExpiredAt),
"type": resp.IpItem.Type, "type": resp.IpItem.Type,
"eventLevelName": firewallconfigs.FindFirewallEventLevelName(resp.IpItem.EventLevel),
} }
} }

View File

@@ -32,12 +32,13 @@ func (this *UpdateIPPopupAction) RunGet(params struct {
} }
this.Data["item"] = maps.Map{ this.Data["item"] = maps.Map{
"id": item.Id, "id": item.Id,
"ipFrom": item.IpFrom, "ipFrom": item.IpFrom,
"ipTo": item.IpTo, "ipTo": item.IpTo,
"expiredAt": item.ExpiredAt, "expiredAt": item.ExpiredAt,
"reason": item.Reason, "reason": item.Reason,
"type": item.Type, "type": item.Type,
"eventLevel": item.EventLevel,
} }
this.Data["type"] = item.Type this.Data["type"] = item.Type
@@ -49,11 +50,12 @@ func (this *UpdateIPPopupAction) RunPost(params struct {
FirewallPolicyId int64 FirewallPolicyId int64
ItemId int64 ItemId int64
IpFrom string IpFrom string
IpTo string IpTo string
ExpiredAt int64 ExpiredAt int64
Reason string Reason string
Type string Type string
EventLevel string
Must *actions.Must Must *actions.Must
CSRF *actionutils.CSRF CSRF *actionutils.CSRF
@@ -99,12 +101,13 @@ func (this *UpdateIPPopupAction) RunPost(params struct {
} }
_, err := this.RPC().IPItemRPC().UpdateIPItem(this.AdminContext(), &pb.UpdateIPItemRequest{ _, err := this.RPC().IPItemRPC().UpdateIPItem(this.AdminContext(), &pb.UpdateIPItemRequest{
IpItemId: params.ItemId, IpItemId: params.ItemId,
IpFrom: params.IpFrom, IpFrom: params.IpFrom,
IpTo: params.IpTo, IpTo: params.IpTo,
ExpiredAt: params.ExpiredAt, ExpiredAt: params.ExpiredAt,
Reason: params.Reason, Reason: params.Reason,
Type: params.Type, Type: params.Type,
EventLevel: params.EventLevel,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -4,6 +4,7 @@ import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time" timeutil "github.com/iwind/TeaGo/utils/time"
"time" "time"
@@ -70,13 +71,14 @@ func (this *AllowListAction) RunGet(params struct {
} }
itemMaps = append(itemMaps, maps.Map{ itemMaps = append(itemMaps, maps.Map{
"id": item.Id, "id": item.Id,
"ipFrom": item.IpFrom, "ipFrom": item.IpFrom,
"ipTo": item.IpTo, "ipTo": item.IpTo,
"expiredTime": expiredTime, "expiredTime": expiredTime,
"reason": item.Reason, "reason": item.Reason,
"type": item.Type, "type": item.Type,
"isExpired": item.ExpiredAt > 0 && item.ExpiredAt < time.Now().Unix(), "isExpired": item.ExpiredAt > 0 && item.ExpiredAt < time.Now().Unix(),
"eventLevelName": firewallconfigs.FindFirewallEventLevelName(item.EventLevel),
}) })
} }
this.Data["items"] = itemMaps this.Data["items"] = itemMaps

View File

@@ -27,18 +27,17 @@ func (this *CreateIPPopupAction) RunGet(params struct {
} }
func (this *CreateIPPopupAction) RunPost(params struct { func (this *CreateIPPopupAction) RunPost(params struct {
ListId int64 ListId int64
IpFrom string IpFrom string
IpTo string IpTo string
ExpiredAt int64 ExpiredAt int64
Reason string Reason string
Type string Type string
EventLevel string
Must *actions.Must Must *actions.Must
CSRF *actionutils.CSRF CSRF *actionutils.CSRF
}) { }) {
// TODO 校验ListId所属用户
switch params.Type { switch params.Type {
case "ipv4": case "ipv4":
params.Must. params.Must.
@@ -75,12 +74,13 @@ func (this *CreateIPPopupAction) RunPost(params struct {
} }
createResp, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{ createResp, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{
IpListId: params.ListId, IpListId: params.ListId,
IpFrom: params.IpFrom, IpFrom: params.IpFrom,
IpTo: params.IpTo, IpTo: params.IpTo,
ExpiredAt: params.ExpiredAt, ExpiredAt: params.ExpiredAt,
Reason: params.Reason, Reason: params.Reason,
Type: params.Type, Type: params.Type,
EventLevel: params.EventLevel,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -4,6 +4,7 @@ import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time" timeutil "github.com/iwind/TeaGo/utils/time"
"time" "time"
@@ -70,13 +71,14 @@ func (this *DenyListAction) RunGet(params struct {
} }
itemMaps = append(itemMaps, maps.Map{ itemMaps = append(itemMaps, maps.Map{
"id": item.Id, "id": item.Id,
"ipFrom": item.IpFrom, "ipFrom": item.IpFrom,
"ipTo": item.IpTo, "ipTo": item.IpTo,
"expiredTime": expiredTime, "expiredTime": expiredTime,
"reason": item.Reason, "reason": item.Reason,
"type": item.Type, "type": item.Type,
"isExpired": item.ExpiredAt > 0 && item.ExpiredAt < time.Now().Unix(), "isExpired": item.ExpiredAt > 0 && item.ExpiredAt < time.Now().Unix(),
"eventLevelName": firewallconfigs.FindFirewallEventLevelName(item.EventLevel),
}) })
} }
this.Data["items"] = itemMaps this.Data["items"] = itemMaps

View File

@@ -4,6 +4,7 @@ import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time" timeutil "github.com/iwind/TeaGo/utils/time"
@@ -68,13 +69,14 @@ func (this *TestAction) RunPost(params struct {
} }
if resp.IpItem != nil { if resp.IpItem != nil {
resultMap["item"] = maps.Map{ resultMap["item"] = maps.Map{
"id": resp.IpItem.Id, "id": resp.IpItem.Id,
"ipFrom": resp.IpItem.IpFrom, "ipFrom": resp.IpItem.IpFrom,
"ipTo": resp.IpItem.IpTo, "ipTo": resp.IpItem.IpTo,
"reason": resp.IpItem.Reason, "reason": resp.IpItem.Reason,
"expiredAt": resp.IpItem.ExpiredAt, "expiredAt": resp.IpItem.ExpiredAt,
"expiredTime": timeutil.FormatTime("Y-m-d H:i:s", resp.IpItem.ExpiredAt), "expiredTime": timeutil.FormatTime("Y-m-d H:i:s", resp.IpItem.ExpiredAt),
"type": resp.IpItem.Type, "type": resp.IpItem.Type,
"eventLevelName": firewallconfigs.FindFirewallEventLevelName(resp.IpItem.EventLevel),
} }
} }

View File

@@ -32,12 +32,13 @@ func (this *UpdateIPPopupAction) RunGet(params struct {
} }
this.Data["item"] = maps.Map{ this.Data["item"] = maps.Map{
"id": item.Id, "id": item.Id,
"ipFrom": item.IpFrom, "ipFrom": item.IpFrom,
"ipTo": item.IpTo, "ipTo": item.IpTo,
"expiredAt": item.ExpiredAt, "expiredAt": item.ExpiredAt,
"reason": item.Reason, "reason": item.Reason,
"type": item.Type, "type": item.Type,
"eventLevel": item.EventLevel,
} }
this.Data["type"] = item.Type this.Data["type"] = item.Type
@@ -48,11 +49,12 @@ func (this *UpdateIPPopupAction) RunGet(params struct {
func (this *UpdateIPPopupAction) RunPost(params struct { func (this *UpdateIPPopupAction) RunPost(params struct {
ItemId int64 ItemId int64
IpFrom string IpFrom string
IpTo string IpTo string
ExpiredAt int64 ExpiredAt int64
Reason string Reason string
Type string Type string
EventLevel string
Must *actions.Must Must *actions.Must
CSRF *actionutils.CSRF CSRF *actionutils.CSRF
@@ -98,12 +100,13 @@ func (this *UpdateIPPopupAction) RunPost(params struct {
} }
_, err := this.RPC().IPItemRPC().UpdateIPItem(this.AdminContext(), &pb.UpdateIPItemRequest{ _, err := this.RPC().IPItemRPC().UpdateIPItem(this.AdminContext(), &pb.UpdateIPItemRequest{
IpItemId: params.ItemId, IpItemId: params.ItemId,
IpFrom: params.IpFrom, IpFrom: params.IpFrom,
IpTo: params.IpTo, IpTo: params.IpTo,
ExpiredAt: params.ExpiredAt, ExpiredAt: params.ExpiredAt,
Reason: params.Reason, Reason: params.Reason,
Type: params.Type, Type: params.Type,
EventLevel: params.EventLevel,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -0,0 +1,16 @@
package ui
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
)
type EventLevelOptionsAction struct {
actionutils.ParentAction
}
func (this *EventLevelOptionsAction) RunPost(params struct{}) {
this.Data["eventLevels"] = firewallconfigs.FindAllFirewallEventLevels()
this.Success()
}

View File

@@ -23,6 +23,7 @@ func init() {
Get("/download", new(DownloadAction)). Get("/download", new(DownloadAction)).
GetPost("/selectProvincesPopup", new(SelectProvincesPopupAction)). GetPost("/selectProvincesPopup", new(SelectProvincesPopupAction)).
GetPost("/selectCountriesPopup", new(SelectCountriesPopupAction)). GetPost("/selectCountriesPopup", new(SelectCountriesPopupAction)).
Post("/eventLevelOptions", new(EventLevelOptionsAction)).
EndAll() EndAll()
}) })

View File

@@ -7,5 +7,6 @@ Vue.component("ip-item-text", {
<span v-if="vItem.ipTo.length > 0">- {{vItem.ipTo}}</span> <span v-if="vItem.ipTo.length > 0">- {{vItem.ipTo}}</span>
</span> </span>
<span v-if="vItem.type == 'ipv6'">{{vItem.ipFrom}}</span> <span v-if="vItem.type == 'ipv6'">{{vItem.ipFrom}}</span>
<span v-if="vItem.eventLevelName != null && vItem.eventLevelName.length > 0">&nbsp; 级别:{{vItem.eventLevelName}}</span>
</span>` </span>`
}) })

View File

@@ -19,6 +19,7 @@ Vue.component("ip-list-table", {
<tr> <tr>
<th style="width:18em">IP</th> <th style="width:18em">IP</th>
<th>类型</th> <th>类型</th>
<th>级别</th>
<th>过期时间</th> <th>过期时间</th>
<th>备注</th> <th>备注</th>
<th class="two op">操作</th> <th class="two op">操作</th>
@@ -35,6 +36,10 @@ Vue.component("ip-list-table", {
<span v-else-if="item.type == 'ipv6'">IPv6</span> <span v-else-if="item.type == 'ipv6'">IPv6</span>
<span v-else-if="item.type == 'all'"><strong>所有IP</strong></span> <span v-else-if="item.type == 'all'"><strong>所有IP</strong></span>
</td> </td>
<td>
<span v-if="item.eventLevelName != null && item.eventLevelName.length > 0">{{item.eventLevelName}}</span>
<span v-else class="disabled">-</span>
</td>
<td> <td>
<div v-if="item.expiredTime.length > 0"> <div v-if="item.expiredTime.length > 0">
{{item.expiredTime}} {{item.expiredTime}}

View File

@@ -1,34 +1,40 @@
Vue.component("message-row", { Vue.component("message-row", {
props: ["v-message"], props: ["v-message"],
data: function () { data: function () {
let paramsJSON = this.vMessage.params let paramsJSON = this.vMessage.params
let params = null let params = null
if (paramsJSON != null && paramsJSON.length > 0) { if (paramsJSON != null && paramsJSON.length > 0) {
params = JSON.parse(paramsJSON) params = JSON.parse(paramsJSON)
} }
return { return {
message: this.vMessage, message: this.vMessage,
params: params params: params
} }
}, },
methods: { methods: {
viewCert: function (certId) { viewCert: function (certId) {
teaweb.popup("/servers/certs/certPopup?certId=" + certId, { teaweb.popup("/servers/certs/certPopup?certId=" + certId, {
height: "28em", height: "28em",
width: "48em" width: "48em"
}) })
}, },
readMessage: function (messageId) { readMessage: function (messageId) {
Tea.action("/messages/readPage") Tea.action("/messages/readPage")
.params({"messageIds": [messageId]}) .params({"messageIds": [messageId]})
.post() .post()
.success(function () { .success(function () {
// 刷新父级页面Badge
if (window.parent.Tea != null && window.parent.Tea.Vue != null) {
window.parent.Tea.Vue.checkMessagesOnce()
}
// 刷新当前页面
teaweb.reload() teaweb.reload()
}) })
} }
}, },
template: `<div> template: `<div>
<table class="ui table selectable"> <table class="ui table selectable">
<tr :class="{error: message.level == 'error', positive: message.level == 'success', warning: message.level == 'warning'}"> <tr :class="{error: message.level == 'error', positive: message.level == 'success', warning: message.level == 'warning'}">
<td style="position: relative"> <td style="position: relative">

View File

@@ -0,0 +1,45 @@
Vue.component("firewall-event-level-options", {
props: ["v-value"],
mounted: function () {
let that = this
Tea.action("/ui/eventLevelOptions")
.post()
.success(function (resp) {
that.levels = resp.data.eventLevels
that.change()
})
},
data: function () {
let value = this.vValue
if (value == null || value.length == 0) {
value = "" // 不要给默认值,因为黑白名单等默认值均有不同
}
return {
levels: [],
description: "",
level: value
}
},
methods: {
change: function () {
this.$emit("change")
let that = this
let l = this.levels.$find(function (k, v) {
return v.code == that.level
})
if (l != null) {
this.description = l.description
} else {
this.description = ""
}
}
},
template: `<div>
<select class="ui dropdown auto-width" name="eventLevel" v-model="level" @change="change">
<option v-for="level in levels" :value="level.code">{{level.name}}</option>
</select>
<p class="comment">{{description}}</p>
</div>`
})

View File

@@ -59,6 +59,14 @@ Tea.context(function () {
}) })
} }
this.checkMessagesOnce = function () {
this.$post("/messages/badge")
.params({})
.success(function (resp) {
this.globalMessageBadge = resp.data.count
})
}
this.showMessages = function () { this.showMessages = function () {
teaweb.popup("/messages", { teaweb.popup("/messages", {
height: "24em", height: "24em",

View File

@@ -0,0 +1,97 @@
{$layout "layout_popup"}
<h3>添加动作</h3>
<form class="ui form" data-tea-action="$" data-tea-success="success">
<input type="hidden" name="clusterId" :value="clusterId"/>
<csrf-token></csrf-token>
<table class="ui table selectable definition">
<tr>
<td class="title">名称 *</td>
<td>
<input type="text" name="name" maxlength="50" ref="focus"/>
</td>
</tr>
<tr>
<td>级别</td>
<td>
<firewall-event-level-options :v-value="'critical'"></firewall-event-level-options>
</td>
</tr>
<tr>
<td>类型</td>
<td>
<select class="ui dropdown auto-width" name="type" v-model="type">
<option value="">[请选择]</option>
<option v-for="type in actionTypes" :value="type.code">{{type.name}}</option>
</select>
<p class="comment">{{typeDescription}}</p>
</td>
</tr>
<!-- IPSet -->
<tbody v-if="type == 'ipset'">
<tr>
<td>IPSet白名单名称 *</td>
<td>
<input type="text" name="ipsetWhiteName" value="edge_white_list" maxlength="64"/>
<p class="comment">只能是英文、数字、下划线的组合。</p>
</td>
</tr>
<tr>
<td>IPSet黑名单名称 *</td>
<td>
<input type="text" name="ipsetBlackName" value="edge_black_list" maxlength="64"/>
<p class="comment">只能是英文、数字、下划线的组合。</p>
</td>
</tr>
<tr>
<td>创建IPTables规则</td>
<td>
<checkbox name="ipsetAutoAddToIPTables" :value="true"></checkbox>
<p class="comment">是否尝试自动创建包含有此IPSet的IPTables规则。</p>
</td>
</tr>
<tr>
<td>创建Firewalld规则</td>
<td>
<checkbox name="ipsetAutoAddToFirewalld" :value="true"></checkbox>
<p class="comment">是否尝试自动创建包含有此IPSet的Firewalld规则。</p>
</td>
</tr>
</tbody>
<!-- Firewalld -->
<tbody v-if="type == 'firewalld'">
</tbody>
<!-- IPTables -->
<tbody v-if="type == 'iptables'">
</tbody>
<!-- 脚本 -->
<tbody v-if="type == 'script'">
<tr>
<td>脚本路径 *</td>
<td>
<input type="text" name="scriptPath" maxlength="200"/>
<p class="comment">可执行脚本文件的完整路径。</p>
</td>
</tr>
</tbody>
<!-- HTTP API -->
<tbody v-if="type == 'httpAPI'">
<tr>
<td>API URL *</td>
<td>
<input type="text" name="httpAPIURL" maxlength="200" placeholder="http|https://..."/>
<p class="comment">完整的API地址。</p>
</td>
</tr>
</tbody>
</table>
<submit-btn></submit-btn>
</form>

View File

@@ -0,0 +1,30 @@
Tea.context(function () {
this.$delay(function () {
let that = this
// 类型
this.$watch("type", function () {
that.changeType()
})
this.changeType()
})
/**
* 类型
*/
this.type = ""
this.typeDescription = ""
this.changeType = function () {
let that = this
let t = this.actionTypes.$find(function (k, v) {
return v.code == that.type
})
if (t != null) {
this.typeDescription = t.description
} else {
this.typeDescription = ""
}
}
})

View File

@@ -0,0 +1,36 @@
{$layout}
{$template "/left_menu"}
<div class="right-box">
<first-menu>
<menu-item @click.prevent="createAction">添加动作</menu-item>
<span class="item disabled">|</span>
<span class="item"><tip-icon content="可以设置WAF中的规则集和IP名单中的IP级别从而在匹配时触发对应的动作。"></tip-icon></span>
</first-menu>
<div class="margin"></div>
<div v-if="!hasActions">
<p class="comment">暂时还没有自定义动作。</p>
</div>
<div v-for="level in levels" v-if="level.actions.length > 0">
<h4 style="margin-bottom: 0">{{level.name}}级别</h4>
<p class="comment" v-if="level.actions.length == 0">暂时还没有定义动作。</p>
<table class="ui table selectable" v-if="level.actions.length > 0">
<thead>
<tr>
<th>名称</th>
<th class="four wide">类型</th>
<th class="two op">操作</th>
</tr>
</thead>
<tr v-for="action in level.actions">
<td>{{action.name}}</td>
<td>{{action.typeName}}</td>
<td>
<a href="" @click.prevent="updateAction(action.id)">修改</a> &nbsp; <a href="" @click.prevent="deleteAction(action.id)">删除</a>
</td>
</tr>
</table>
<div class="ui divider"></div>
</div>
</div>

View File

@@ -0,0 +1,36 @@
Tea.context(function () {
this.createAction = function () {
teaweb.popup(Tea.url(".createPopup", {clusterId: this.clusterId}), {
callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
})
}
this.updateAction = function (actionId) {
teaweb.popup(Tea.url(".updatePopup", {actionId: actionId}), {
callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
})
}
this.deleteAction = function (actionId) {
let that = this
teaweb.confirm("确定要删除此动作吗?", function () {
that.$post(".delete")
.params({
actionId: actionId
})
.success(function () {
teaweb.success("删除成功", function () {
teaweb.reload()
})
})
})
}
})

View File

@@ -0,0 +1,97 @@
{$layout "layout_popup"}
<h3>修改动作</h3>
<form class="ui form" data-tea-action="$" data-tea-success="success">
<input type="hidden" name="actionId" :value="action.id"/>
<csrf-token></csrf-token>
<table class="ui table selectable definition">
<tr>
<td class="title">名称 *</td>
<td>
<input type="text" name="name" maxlength="50" ref="focus" v-model="action.name"/>
</td>
</tr>
<tr>
<td>级别</td>
<td>
<firewall-event-level-options :v-value="eventLevel"></firewall-event-level-options>
</td>
</tr>
<tr>
<td>类型</td>
<td>
<select class="ui dropdown auto-width" name="type" v-model="type">
<option value="">[请选择]</option>
<option v-for="type in actionTypes" :value="type.code">{{type.name}}</option>
</select>
<p class="comment">{{typeDescription}}</p>
</td>
</tr>
<!-- IPSet -->
<tbody v-if="type == 'ipset'">
<tr>
<td>IPSet白名单名称 *</td>
<td>
<input type="text" name="ipsetWhiteName" value="edge_white_list" maxlength="64" v-model="action.params.whiteName"/>
<p class="comment">只能是英文、数字、下划线的组合。</p>
</td>
</tr>
<tr>
<td>IPSet黑名单名称 *</td>
<td>
<input type="text" name="ipsetBlackName" value="edge_black_list" maxlength="64" v-model="action.params.blackName"/>
<p class="comment">只能是英文、数字、下划线的组合。</p>
</td>
</tr>
<tr>
<td>创建IPTables规则</td>
<td>
<checkbox name="ipsetAutoAddToIPTables" v-model="action.params.autoAddToIPTables"></checkbox>
<p class="comment">是否尝试自动创建包含有此IPSet的IPTables规则。</p>
</td>
</tr>
<tr>
<td>创建Firewalld规则</td>
<td>
<checkbox name="ipsetAutoAddToFirewalld" v-model="action.params.autoAddToFirewalld"></checkbox>
<p class="comment">是否尝试自动创建包含有此IPSet的Firewalld规则。</p>
</td>
</tr>
</tbody>
<!-- Firewalld -->
<tbody v-if="type == 'firewalld'">
</tbody>
<!-- IPTables -->
<tbody v-if="type == 'iptables'">
</tbody>
<!-- 脚本 -->
<tbody v-if="type == 'script'">
<tr>
<td>脚本路径 *</td>
<td>
<input type="text" name="scriptPath" maxlength="200" v-model="action.params.path"/>
<p class="comment">可执行脚本文件的完整路径。</p>
</td>
</tr>
</tbody>
<!-- HTTP API -->
<tbody v-if="type == 'httpAPI'">
<tr>
<td>API URL *</td>
<td>
<input type="text" name="httpAPIURL" maxlength="200" placeholder="http|https://..." v-model="action.params.url"/>
<p class="comment">完整的API地址。</p>
</td>
</tr>
</tbody>
</table>
<submit-btn></submit-btn>
</form>

View File

@@ -0,0 +1,35 @@
Tea.context(function () {
this.$delay(function () {
let that = this
// 类型
this.$watch("type", function () {
that.changeType()
})
this.changeType()
})
/**
* 级别
*/
this.eventLevel = this.action.eventLevel
/**
* 类型
*/
this.type = this.action.type
this.typeDescription = ""
this.changeType = function () {
let that = this
let t = this.actionTypes.$find(function (k, v) {
return v.code == that.type
})
if (t != null) {
this.typeDescription = t.description
} else {
this.typeDescription = ""
}
}
})

View File

@@ -1,26 +1,38 @@
Tea.context(function () { Tea.context(function () {
this.updateAllRead = function () { this.updateAllRead = function () {
let that = this let that = this
teaweb.confirm("确定要设置所有的未读消息为已读吗?", function () { teaweb.confirm("确定要设置所有的未读消息为已读吗?", function () {
that.$post("/messages/readAll") that.$post("/messages/readAll")
.success(function () { .success(function () {
window.location = "/messages" // 刷新父级页面Badge
}) if (window.parent.Tea != null && window.parent.Tea.Vue != null) {
}) window.parent.Tea.Vue.checkMessagesOnce()
} }
this.updatePageRead = function () { window.location = "/messages"
let that = this })
teaweb.confirm("确定要设置当前页的未读消息为已读吗?", function () { })
let messageIds = [] }
that.messages.forEach(function (v) {
messageIds.push(v.id) this.updatePageRead = function () {
}) let that = this
that.$post("/messages/readPage") teaweb.confirm("确定要设置当前页的未读消息为已读吗?", function () {
.params({ let messageIds = []
messageIds: messageIds that.messages.forEach(function (v) {
}) messageIds.push(v.id)
.refresh() })
}) that.$post("/messages/readPage")
} .params({
messageIds: messageIds
})
.success(function () {
// 刷新父级页面Badge
if (window.parent.Tea != null && window.parent.Tea.Vue != null) {
window.parent.Tea.Vue.checkMessagesOnce()
}
teaweb.reload()
})
})
}
}) })

View File

@@ -1,7 +1,7 @@
{$layout "layout_popup"} {$layout "layout_popup"}
<h3 v-if="type == 'white'">添加IP到白名单</h3> <h3 v-if="listType == 'white'">添加IP到白名单</h3>
<h3 v-if="type == 'black'">添加IP到黑名单</h3> <h3 v-if="listType == 'black'">添加IP到黑名单</h3>
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success"> <form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
<input type="hidden" name="firewallPolicyId" :value="firewallPolicyId"/> <input type="hidden" name="firewallPolicyId" :value="firewallPolicyId"/>
@@ -49,6 +49,14 @@
</td> </td>
</tr> </tr>
</tbody> </tbody>
<tr>
<td>级别</td>
<td>
<firewall-event-level-options :v-value="eventLevel"></firewall-event-level-options>
</td>
</tr>
<tr> <tr>
<td colspan="2"><more-options-indicator></more-options-indicator></td> <td colspan="2"><more-options-indicator></more-options-indicator></td>
</tr> </tr>

View File

@@ -1,3 +1,4 @@
Tea.context(function () { Tea.context(function () {
this.type = "ipv4" this.type = "ipv4"
this.eventLevel = (this.listType == "white") ? "debug" : "critical"
}) })

View File

@@ -1,7 +1,7 @@
Tea.context(function () { Tea.context(function () {
this.updateItem = function (itemId) { this.updateItem = function (itemId) {
teaweb.popup(Tea.url(".updateIPPopup?firewallPolicyId=" + this.firewallPolicyId, {itemId: itemId}), { teaweb.popup(Tea.url(".updateIPPopup?firewallPolicyId=" + this.firewallPolicyId, {itemId: itemId}), {
height: "23em", height: "26em",
callback: function () { callback: function () {
teaweb.success("保存成功", function () { teaweb.success("保存成功", function () {
teaweb.reload() teaweb.reload()
@@ -27,7 +27,7 @@ Tea.context(function () {
*/ */
this.createIP = function (type) { this.createIP = function (type) {
teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, { teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
height: "23em", height: "26em",
callback: function () { callback: function () {
window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type
} }

View File

@@ -24,10 +24,10 @@
<div v-if="result.isFound"> <div v-if="result.isFound">
<div v-if="result.item != null"> <div v-if="result.item != null">
<div v-if="result.isAllowed"> <div v-if="result.isAllowed">
<span class="green">在白名单中 <ip-item-text :v-item="result.item"></ip-item-text><a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span> <span class="green">在白名单中 <ip-item-text :v-item="result.item"></ip-item-text>&nbsp;<a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span>
</div> </div>
<div v-else> <div v-else>
<span class="red">在黑名单中 <ip-item-text :v-item="result.item"></ip-item-text><a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span> <span class="red">在黑名单中 <ip-item-text :v-item="result.item"></ip-item-text>&nbsp;<a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span>
</div> </div>
</div> </div>
<div v-if="result.province != null"> <div v-if="result.province != null">

View File

@@ -24,7 +24,7 @@ Tea.context(function () {
this.updateItem = function (itemId) { this.updateItem = function (itemId) {
teaweb.popup(Tea.url(".updateIPPopup?firewallPolicyId=" + this.firewallPolicyId, {itemId: itemId}), { teaweb.popup(Tea.url(".updateIPPopup?firewallPolicyId=" + this.firewallPolicyId, {itemId: itemId}), {
height: "23em", height: "26em",
callback: function () { callback: function () {
teaweb.success("保存成功", function () { teaweb.success("保存成功", function () {
teaweb.reload() teaweb.reload()
@@ -32,4 +32,16 @@ Tea.context(function () {
} }
}) })
} }
/**
* 添加IP名单菜单
*/
this.createIP = function (type) {
teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
height: "26em",
callback: function () {
window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type
}
})
}
}) })

View File

@@ -39,6 +39,13 @@
</tr> </tr>
</tbody> </tbody>
<tr>
<td>级别</td>
<td>
<firewall-event-level-options :v-value="item.eventLevel"></firewall-event-level-options>
</td>
</tr>
<!-- IPv6 --> <!-- IPv6 -->
<tbody v-if="type == 'ipv6'"> <tbody v-if="type == 'ipv6'">
<tr> <tr>

View File

@@ -1,7 +1,7 @@
Tea.context(function () { Tea.context(function () {
this.updateItem = function (itemId) { this.updateItem = function (itemId) {
teaweb.popup(Tea.url(".updateIPPopup?listId=" + this.listId, {itemId: itemId}), { teaweb.popup(Tea.url(".updateIPPopup?listId=" + this.listId, {itemId: itemId}), {
height: "24em", height: "26em",
callback: function () { callback: function () {
teaweb.success("保存成功", function () { teaweb.success("保存成功", function () {
teaweb.reload() teaweb.reload()
@@ -27,7 +27,7 @@ Tea.context(function () {
*/ */
this.createIP = function (type) { this.createIP = function (type) {
teaweb.popup("/servers/server/settings/waf/ipadmin/createIPPopup?listId=" + this.listId + '&type=' + type, { teaweb.popup("/servers/server/settings/waf/ipadmin/createIPPopup?listId=" + this.listId + '&type=' + type, {
height: "24em", height: "26em",
callback: function () { callback: function () {
window.location.reload() window.location.reload()
} }

View File

@@ -57,7 +57,7 @@ Tea.context(function () {
*/ */
this.createIP = function (type) { this.createIP = function (type) {
teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, { teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
height: "23em", height: "30em",
callback: function () { callback: function () {
window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type
} }

View File

@@ -49,6 +49,13 @@
</tr> </tr>
</tbody> </tbody>
<tr>
<td>级别</td>
<td>
<firewall-event-level-options :v-value="eventLevel"></firewall-event-level-options>
</td>
</tr>
<tr> <tr>
<td colspan="2"><more-options-indicator></more-options-indicator></td> <td colspan="2"><more-options-indicator></more-options-indicator></td>
</tr> </tr>
@@ -66,6 +73,5 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p class="comment">添加后将会在5分钟内生效。</p>
<submit-btn></submit-btn> <submit-btn></submit-btn>
</form> </form>

View File

@@ -1,3 +1,4 @@
Tea.context(function () { Tea.context(function () {
this.type = "ipv4" this.type = "ipv4"
this.eventLevel = (this.listType == "white") ? "debug" : "critical"
}) })

View File

@@ -1,7 +1,7 @@
Tea.context(function () { Tea.context(function () {
this.updateItem = function (itemId) { this.updateItem = function (itemId) {
teaweb.popup(Tea.url(".updateIPPopup?listId=" + this.listId, {itemId: itemId}), { teaweb.popup(Tea.url(".updateIPPopup?listId=" + this.listId, {itemId: itemId}), {
height: "24em", height: "26em",
callback: function () { callback: function () {
teaweb.success("保存成功", function () { teaweb.success("保存成功", function () {
teaweb.reload() teaweb.reload()
@@ -27,7 +27,7 @@ Tea.context(function () {
*/ */
this.createIP = function (type) { this.createIP = function (type) {
teaweb.popup("/servers/server/settings/waf/ipadmin/createIPPopup?listId=" + this.listId + '&type=' + type, { teaweb.popup("/servers/server/settings/waf/ipadmin/createIPPopup?listId=" + this.listId + '&type=' + type, {
height: "24em", height: "26em",
callback: function () { callback: function () {
window.location.reload() window.location.reload()
} }

View File

@@ -1,36 +0,0 @@
Tea.context(function () {
this.updateItem = function (itemId) {
teaweb.popup(Tea.url(".updateIPPopup?firewallPolicyId=" + this.firewallPolicyId, {itemId: itemId}), {
height: "23em",
callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
})
}
this.deleteItem = function (itemId) {
let that = this
teaweb.confirm("确定要删除这个IP吗", function () {
that.$post(".deleteIP")
.params({
"firewallPolicyId": this.firewallPolicyId,
"itemId": itemId
})
.refresh()
})
}
/**
* 添加IP名单菜单
*/
this.createIP = function (type) {
teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
height: "23em",
callback: function () {
window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type
}
})
}
})

View File

@@ -43,7 +43,7 @@ Tea.context(function () {
*/ */
this.createIP = function (type) { this.createIP = function (type) {
teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, { teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
height: "23em", height: "30em",
callback: function () { callback: function () {
window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type
} }

View File

@@ -29,10 +29,10 @@
<div v-if="result.isFound"> <div v-if="result.isFound">
<div v-if="result.item != null"> <div v-if="result.item != null">
<div v-if="result.isAllowed"> <div v-if="result.isAllowed">
<span class="green">在白名单中 <ip-item-text :v-item="result.item"></ip-item-text><a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span> <span class="green">在白名单中 <ip-item-text :v-item="result.item"></ip-item-text>&nbsp;<a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span>
</div> </div>
<div v-else> <div v-else>
<span class="red">在黑名单中 <ip-item-text :v-item="result.item"></ip-item-text><a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span> <span class="red">在黑名单中 <ip-item-text :v-item="result.item"></ip-item-text>&nbsp;<a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span>
</div> </div>
</div> </div>
<div v-if="result.province != null"> <div v-if="result.province != null">

View File

@@ -24,7 +24,7 @@ Tea.context(function () {
this.updateItem = function (listId, itemId) { this.updateItem = function (listId, itemId) {
teaweb.popup(Tea.url(".updateIPPopup?listId=" + listId, {itemId: itemId}), { teaweb.popup(Tea.url(".updateIPPopup?listId=" + listId, {itemId: itemId}), {
height: "24em", height: "26em",
callback: function () { callback: function () {
teaweb.success("保存成功", function () { teaweb.success("保存成功", function () {

View File

@@ -49,7 +49,14 @@
</tr> </tr>
</tbody> </tbody>
<tr> <tr>
<td>级别</td>
<td>
<firewall-event-level-options :v-value="item.eventLevel"></firewall-event-level-options>
</td>
</tr>
<tr>
<td colspan="2"><more-options-indicator></more-options-indicator></td> <td colspan="2"><more-options-indicator></more-options-indicator></td>
</tr> </tr>
<tbody v-show="moreOptionsVisible"> <tbody v-show="moreOptionsVisible">