mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
feat: 实现防火墙批量删除及修改功能
This commit is contained in:
parent
c9d36d84f7
commit
db74d010d7
@ -54,7 +54,7 @@ func (b *BaseApi) OperatePortRule(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := firewallService.OperatePortRule(req); err != nil {
|
||||
if err := firewallService.OperatePortRule(req, true); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
@ -80,7 +80,82 @@ func (b *BaseApi) OperateIPRule(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := firewallService.OperateAddressRule(req); err != nil {
|
||||
if err := firewallService.OperateAddressRule(req, true); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Create group
|
||||
// @Description 批量删除防火墙规则
|
||||
// @Accept json
|
||||
// @Param request body dto.BatchRuleOperate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/ip [post]
|
||||
func (b *BaseApi) BatchOperateRule(c *gin.Context) {
|
||||
var req dto.BatchRuleOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := firewallService.BacthOperateRule(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Create group
|
||||
// @Description 更新端口防火墙规则
|
||||
// @Accept json
|
||||
// @Param request body dto.PortRuleUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/update/port [post]
|
||||
func (b *BaseApi) UpdatePortRule(c *gin.Context) {
|
||||
var req dto.PortRuleUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := firewallService.UpdatePortRule(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Create group
|
||||
// @Description 更新 ip 防火墙规则
|
||||
// @Accept json
|
||||
// @Param request body dto.AddrRuleUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/update/ip [post]
|
||||
func (b *BaseApi) UpdateAddrRule(c *gin.Context) {
|
||||
var req dto.AddrRuleUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := firewallService.UpdateAddrRule(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package dto
|
||||
|
||||
type RuleSearch struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
}
|
||||
|
||||
@ -18,3 +19,18 @@ type AddrRuleOperate struct {
|
||||
Address string `json:"address" validate:"required"`
|
||||
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
||||
}
|
||||
|
||||
type PortRuleUpdate struct {
|
||||
OldRule PortRuleOperate `json:"oldRule"`
|
||||
NewRule PortRuleOperate `json:"newRule"`
|
||||
}
|
||||
|
||||
type AddrRuleUpdate struct {
|
||||
OldRule AddrRuleOperate `json:"oldRule"`
|
||||
NewRule AddrRuleOperate `json:"newRule"`
|
||||
}
|
||||
|
||||
type BatchRuleOperate struct {
|
||||
Type string `json:"type" validate:"required"`
|
||||
Rules []PortRuleOperate `json:"rules"`
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/firewall"
|
||||
fireClient "github.com/1Panel-dev/1Panel/backend/utils/firewall/client"
|
||||
@ -11,8 +13,11 @@ type FirewallService struct{}
|
||||
|
||||
type IFirewallService interface {
|
||||
SearchWithPage(search dto.RuleSearch) (int64, interface{}, error)
|
||||
OperatePortRule(req dto.PortRuleOperate) error
|
||||
OperateAddressRule(req dto.AddrRuleOperate) error
|
||||
OperatePortRule(req dto.PortRuleOperate, reload bool) error
|
||||
OperateAddressRule(req dto.AddrRuleOperate, reload bool) error
|
||||
UpdatePortRule(req dto.PortRuleUpdate) error
|
||||
UpdateAddrRule(req dto.AddrRuleUpdate) error
|
||||
BacthOperateRule(req dto.BatchRuleOperate) error
|
||||
}
|
||||
|
||||
func NewIFirewallService() IFirewallService {
|
||||
@ -33,13 +38,29 @@ func (u *FirewallService) SearchWithPage(req dto.RuleSearch) (int64, interface{}
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
datas = ports
|
||||
if len(req.Info) != 0 {
|
||||
for _, port := range ports {
|
||||
if strings.Contains(port.Port, req.Info) {
|
||||
datas = append(datas, port)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
datas = ports
|
||||
}
|
||||
} else {
|
||||
address, err := client.ListAddress()
|
||||
addrs, err := client.ListAddress()
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
datas = address
|
||||
if len(req.Info) != 0 {
|
||||
for _, addr := range addrs {
|
||||
if strings.Contains(addr.Address, req.Info) {
|
||||
datas = append(datas, addr)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
datas = addrs
|
||||
}
|
||||
}
|
||||
total, start, end := len(datas), (req.Page-1)*req.PageSize, req.Page*req.PageSize
|
||||
if start > total {
|
||||
@ -54,25 +75,36 @@ func (u *FirewallService) SearchWithPage(req dto.RuleSearch) (int64, interface{}
|
||||
return int64(total), backDatas, nil
|
||||
}
|
||||
|
||||
func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate) error {
|
||||
func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool) error {
|
||||
client, err := firewall.NewFirewallClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if client.Name() == "ufw" {
|
||||
req.Port = strings.ReplaceAll(req.Port, "-", ":")
|
||||
if req.Operation == "remove" && req.Protocol == "tcp/udp" {
|
||||
req.Protocol = ""
|
||||
return u.operatePort(client, req)
|
||||
}
|
||||
}
|
||||
|
||||
if req.Protocol == "tcp/udp" {
|
||||
req.Protocol = "tcp"
|
||||
if err := u.createPort(client, req); err != nil {
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
req.Protocol = "udp"
|
||||
}
|
||||
if err := u.createPort(client, req); err != nil {
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
return client.Reload()
|
||||
if reload {
|
||||
return client.Reload()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *FirewallService) OperateAddressRule(req dto.AddrRuleOperate) error {
|
||||
func (u *FirewallService) OperateAddressRule(req dto.AddrRuleOperate, reload bool) error {
|
||||
client, err := firewall.NewFirewallClient()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -82,18 +114,86 @@ func (u *FirewallService) OperateAddressRule(req dto.AddrRuleOperate) error {
|
||||
if err := copier.Copy(&fireInfo, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := client.RichRules(fireInfo, req.Operation); err != nil {
|
||||
|
||||
addressList := strings.Split(req.Address, ",")
|
||||
for _, addr := range addressList {
|
||||
if len(addr) == 0 {
|
||||
continue
|
||||
}
|
||||
fireInfo.Address = addr
|
||||
if err := client.RichRules(fireInfo, req.Operation); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if reload {
|
||||
return client.Reload()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *FirewallService) UpdatePortRule(req dto.PortRuleUpdate) error {
|
||||
client, err := firewall.NewFirewallClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := u.OperatePortRule(req.OldRule, false); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := u.OperatePortRule(req.NewRule, false); err != nil {
|
||||
return err
|
||||
}
|
||||
return client.Reload()
|
||||
}
|
||||
|
||||
func (u *FirewallService) createPort(client firewall.FirewallClient, req dto.PortRuleOperate) error {
|
||||
func (u *FirewallService) UpdateAddrRule(req dto.AddrRuleUpdate) error {
|
||||
client, err := firewall.NewFirewallClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := u.OperateAddressRule(req.OldRule, false); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := u.OperateAddressRule(req.NewRule, false); err != nil {
|
||||
return err
|
||||
}
|
||||
return client.Reload()
|
||||
}
|
||||
|
||||
func (u *FirewallService) BacthOperateRule(req dto.BatchRuleOperate) error {
|
||||
client, err := firewall.NewFirewallClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if req.Type == "port" {
|
||||
for _, rule := range req.Rules {
|
||||
if err := u.OperatePortRule(rule, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return client.Reload()
|
||||
}
|
||||
for _, rule := range req.Rules {
|
||||
itemRule := dto.AddrRuleOperate{Operation: rule.Operation, Address: rule.Address, Strategy: rule.Strategy}
|
||||
if err := u.OperateAddressRule(itemRule, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return client.Reload()
|
||||
}
|
||||
|
||||
func (u *FirewallService) operatePort(client firewall.FirewallClient, req dto.PortRuleOperate) error {
|
||||
var fireInfo fireClient.FireInfo
|
||||
if err := copier.Copy(&fireInfo, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if client.Name() == "ufw" {
|
||||
if len(fireInfo.Address) != 0 && fireInfo.Address != "Anywhere" {
|
||||
return client.RichRules(fireInfo, req.Operation)
|
||||
}
|
||||
return client.Port(fireInfo, req.Operation)
|
||||
}
|
||||
|
||||
if len(fireInfo.Address) != 0 || fireInfo.Strategy == "drop" {
|
||||
return client.RichRules(fireInfo, req.Operation)
|
||||
}
|
||||
|
@ -29,6 +29,9 @@ func (s *HostRouter) InitHostRouter(Router *gin.RouterGroup) {
|
||||
hostRouter.POST("/firewall/search", baseApi.SearchFirewallRule)
|
||||
hostRouter.POST("/firewall/port", baseApi.OperatePortRule)
|
||||
hostRouter.POST("/firewall/ip", baseApi.OperateIPRule)
|
||||
hostRouter.POST("/firewall/batch", baseApi.BatchOperateRule)
|
||||
hostRouter.POST("/firewall/update/port", baseApi.UpdatePortRule)
|
||||
hostRouter.POST("/firewall/update/addr", baseApi.UpdateAddrRule)
|
||||
|
||||
hostRouter.GET("/command", baseApi.ListCommand)
|
||||
hostRouter.POST("/command", baseApi.CreateCommand)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
)
|
||||
|
||||
type FirewallClient interface {
|
||||
Name() string
|
||||
Start() error
|
||||
Stop() error
|
||||
Reload() error
|
||||
|
@ -21,6 +21,10 @@ func NewFirewalld() (*Firewall, error) {
|
||||
return &Firewall{Client: ConnInfo}, nil
|
||||
}
|
||||
|
||||
func (f *Firewall) Name() string {
|
||||
return "firewalld"
|
||||
}
|
||||
|
||||
func (f *Firewall) Status() (string, error) {
|
||||
stdout, err := f.Client.Run("firewall-cmd --state")
|
||||
if err != nil {
|
||||
@ -80,7 +84,7 @@ func (f *Firewall) ListPort() ([]FireInfo, error) {
|
||||
continue
|
||||
}
|
||||
itemRule := f.loadInfo(rule)
|
||||
if len(itemRule.Port) != 0 {
|
||||
if len(itemRule.Port) != 0 && itemRule.Family == "ipv4" {
|
||||
datas = append(datas, itemRule)
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,10 @@ func NewUfw() (*Ufw, error) {
|
||||
return &Ufw{Client: ConnInfo}, nil
|
||||
}
|
||||
|
||||
func (f *Ufw) Name() string {
|
||||
return "ufw"
|
||||
}
|
||||
|
||||
func (f *Ufw) Status() (string, error) {
|
||||
stdout, err := f.Client.Run("sudo ufw status")
|
||||
if err != nil {
|
||||
@ -49,10 +53,6 @@ func (f *Ufw) Stop() error {
|
||||
}
|
||||
|
||||
func (f *Ufw) Reload() error {
|
||||
stdout, err := f.Client.Run("sudo ufw reload")
|
||||
if err != nil {
|
||||
return fmt.Errorf("reload firewall failed, err: %s", stdout)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -73,7 +73,8 @@ func (f *Ufw) ListPort() ([]FireInfo, error) {
|
||||
continue
|
||||
}
|
||||
itemFire := f.loadInfo(line, "port")
|
||||
if len(itemFire.Port) != 0 {
|
||||
if len(itemFire.Port) != 0 && itemFire.Port != "Anywhere" && !strings.Contains(itemFire.Port, ".") {
|
||||
itemFire.Port = strings.ReplaceAll(itemFire.Port, ":", "-")
|
||||
datas = append(datas, itemFire)
|
||||
}
|
||||
}
|
||||
@ -100,7 +101,11 @@ func (f *Ufw) ListAddress() ([]FireInfo, error) {
|
||||
continue
|
||||
}
|
||||
itemFire := f.loadInfo(line, "address")
|
||||
if len(itemFire.Port) == 0 {
|
||||
if strings.Contains(itemFire.Port, ".") {
|
||||
itemFire.Address += ("-" + itemFire.Port)
|
||||
itemFire.Port = ""
|
||||
}
|
||||
if len(itemFire.Port) == 0 && len(itemFire.Address) != 0 {
|
||||
datas = append(datas, itemFire)
|
||||
}
|
||||
}
|
||||
@ -108,16 +113,19 @@ func (f *Ufw) ListAddress() ([]FireInfo, error) {
|
||||
}
|
||||
|
||||
func (f *Ufw) Port(port FireInfo, operation string) error {
|
||||
switch operation {
|
||||
case "add":
|
||||
operation = "allow"
|
||||
case "remove":
|
||||
operation = "deny"
|
||||
switch port.Strategy {
|
||||
case "accept":
|
||||
port.Strategy = "allow"
|
||||
case "drop":
|
||||
port.Strategy = "deny"
|
||||
default:
|
||||
return fmt.Errorf("unsupport operation %s", operation)
|
||||
return fmt.Errorf("unsupport strategy %s", port.Strategy)
|
||||
}
|
||||
|
||||
command := fmt.Sprintf("sudo ufw %s %s", operation, port.Port)
|
||||
command := fmt.Sprintf("sudo ufw %s %s", port.Strategy, port.Port)
|
||||
if operation == "remove" {
|
||||
command = fmt.Sprintf("sudo ufw delete %s %s", port.Strategy, port.Port)
|
||||
}
|
||||
if len(port.Protocol) != 0 {
|
||||
command += fmt.Sprintf("/%s", port.Protocol)
|
||||
}
|
||||
@ -129,11 +137,25 @@ func (f *Ufw) Port(port FireInfo, operation string) error {
|
||||
}
|
||||
|
||||
func (f *Ufw) RichRules(rule FireInfo, operation string) error {
|
||||
ruleStr := "sudo ufw "
|
||||
switch rule.Strategy {
|
||||
case "accept":
|
||||
rule.Strategy = "allow"
|
||||
case "drop":
|
||||
rule.Strategy = "deny"
|
||||
default:
|
||||
return fmt.Errorf("unsupport strategy %s", rule.Strategy)
|
||||
}
|
||||
|
||||
ruleStr := fmt.Sprintf("sudo ufw %s ", rule.Strategy)
|
||||
if operation == "remove" {
|
||||
ruleStr = fmt.Sprintf("sudo ufw delete %s ", rule.Strategy)
|
||||
}
|
||||
if len(rule.Protocol) != 0 {
|
||||
ruleStr += fmt.Sprintf("proto %s ", rule.Protocol)
|
||||
}
|
||||
if len(rule.Address) != 0 {
|
||||
if strings.Contains(rule.Address, "-") {
|
||||
ruleStr += fmt.Sprintf("from %s to %s ", strings.Split(rule.Address, "-")[0], strings.Split(rule.Address, "-")[1])
|
||||
} else {
|
||||
ruleStr += fmt.Sprintf("from %s ", rule.Address)
|
||||
}
|
||||
if len(rule.Port) != 0 {
|
||||
@ -169,9 +191,12 @@ func (f *Ufw) loadInfo(line string, fireType string) FireInfo {
|
||||
if len(fields) < 4 {
|
||||
return itemInfo
|
||||
}
|
||||
if fields[1] == "(v6)" {
|
||||
return itemInfo
|
||||
}
|
||||
if fields[0] == "Anywhere" && fireType != "port" {
|
||||
itemInfo.Strategy = "drop"
|
||||
if fields[2] == "ALLOW" {
|
||||
if fields[1] == "ALLOW" {
|
||||
itemInfo.Strategy = "accept"
|
||||
}
|
||||
itemInfo.Address = fields[3]
|
||||
@ -184,27 +209,13 @@ func (f *Ufw) loadInfo(line string, fireType string) FireInfo {
|
||||
itemInfo.Port = fields[0]
|
||||
itemInfo.Protocol = "tcp/udp"
|
||||
}
|
||||
|
||||
if fields[1] == "(v6)" {
|
||||
if len(fields) < 5 {
|
||||
return itemInfo
|
||||
}
|
||||
itemInfo.Family = "ipv6"
|
||||
if fields[2] == "ALLOW" {
|
||||
itemInfo.Strategy = "accept"
|
||||
} else {
|
||||
itemInfo.Strategy = "drop"
|
||||
}
|
||||
itemInfo.Address = fields[4]
|
||||
itemInfo.Family = "ipv4"
|
||||
if fields[1] == "ALLOW" {
|
||||
itemInfo.Strategy = "accept"
|
||||
} else {
|
||||
itemInfo.Family = "ipv4"
|
||||
if fields[1] == "ALLOW" {
|
||||
itemInfo.Strategy = "accept"
|
||||
} else {
|
||||
itemInfo.Strategy = "drop"
|
||||
}
|
||||
itemInfo.Address = fields[3]
|
||||
itemInfo.Strategy = "drop"
|
||||
}
|
||||
itemInfo.Address = fields[3]
|
||||
|
||||
return itemInfo
|
||||
}
|
||||
|
@ -77,4 +77,16 @@ export namespace Host {
|
||||
address: string;
|
||||
strategy: string;
|
||||
}
|
||||
export interface UpdatePortRule {
|
||||
oldRule: RulePort;
|
||||
newRule: RulePort;
|
||||
}
|
||||
export interface UpdateAddrRule {
|
||||
oldRule: RuleIP;
|
||||
newRule: RuleIP;
|
||||
}
|
||||
export interface BatchRule {
|
||||
type: string;
|
||||
rules: Array<RulePort>;
|
||||
}
|
||||
}
|
||||
|
@ -81,3 +81,12 @@ export const operatePortRule = (params: Host.RulePort) => {
|
||||
export const operateIPRule = (params: Host.RuleIP) => {
|
||||
return http.post<Host.RuleIP>(`/hosts/firewall/ip`, params);
|
||||
};
|
||||
export const updatePortRule = (params: Host.UpdatePortRule) => {
|
||||
return http.post(`/hosts/firewall/update/port`, params);
|
||||
};
|
||||
export const updateAddrRule = (params: Host.UpdateAddrRule) => {
|
||||
return http.post(`/hosts/firewall/update/addr`, params);
|
||||
};
|
||||
export const batchOperateRule = (params: Host.BatchRule) => {
|
||||
return http.post(`/hosts/firewall/batch`, params);
|
||||
};
|
||||
|
@ -1184,12 +1184,16 @@ const message = {
|
||||
firewall: '防火墙',
|
||||
protocol: '协议',
|
||||
port: '端口',
|
||||
portHelper: '支持输入多个端口,如 80,81 或者范围端口,如 80-88',
|
||||
strategy: '策略',
|
||||
accept: '允许',
|
||||
drop: '拒绝',
|
||||
source: '来源',
|
||||
anyWhere: '所有 IP',
|
||||
address: '指定 IP',
|
||||
addressHelper1: '支持输入多个 IP ,如 172.16.10.11,172.16.10.99',
|
||||
addressHelper2: '支持输入 IP 段,如 172.16.10.0/24',
|
||||
addressHelper3: '支持输入 IP 范围,如 172.16.10.11-172.16.10.99',
|
||||
allIP: '所有 IP',
|
||||
portRule: '端口规则',
|
||||
ipRule: 'IP 规则',
|
||||
|
@ -4,10 +4,27 @@
|
||||
<LayoutContent v-loading="loading" :title="$t('firewall.firewall')">
|
||||
<template #toolbar>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-col :span="16">
|
||||
<el-button type="primary" @click="onOpenDialog('create')">
|
||||
{{ $t('commons.button.create') }} {{ $t('firewall.ipRule') }}
|
||||
</el-button>
|
||||
<el-button @click="onDelete(null)">
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<TableSetting @search="search()" />
|
||||
<div class="search-button">
|
||||
<el-input
|
||||
v-model="searchName"
|
||||
clearable
|
||||
@clear="search()"
|
||||
suffix-icon="Search"
|
||||
@keyup.enter="search()"
|
||||
@blur="search()"
|
||||
:placeholder="$t('commons.button.search')"
|
||||
></el-input>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -50,9 +67,10 @@
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import OperatrDialog from '@/views/host/firewall/ip/operate/index.vue';
|
||||
import FireRouter from '@/views/host/firewall/index.vue';
|
||||
import TableSetting from '@/components/table-setting/index.vue';
|
||||
import LayoutContent from '@/layout/layout-content.vue';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { operateIPRule, searchFireRule } from '@/api/modules/host';
|
||||
import { batchOperateRule, searchFireRule } from '@/api/modules/host';
|
||||
import { Host } from '@/api/interface/host';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import i18n from '@/lang';
|
||||
@ -61,6 +79,7 @@ import { MsgSuccess } from '@/utils/message';
|
||||
const loading = ref();
|
||||
const activeTag = ref('address');
|
||||
const selects = ref<any>([]);
|
||||
const searchName = ref();
|
||||
|
||||
const data = ref();
|
||||
const paginationConfig = reactive({
|
||||
@ -102,19 +121,36 @@ const onOpenDialog = async (
|
||||
dialogRef.value!.acceptParams(params);
|
||||
};
|
||||
|
||||
const onDelete = async (row: Host.RuleInfo | null) => {
|
||||
const onDelete = async (row: Host.RuleIP | null) => {
|
||||
ElMessageBox.confirm(i18n.global.t('commons.msg.delete'), i18n.global.t('commons.msg.deleteTitle'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'warning',
|
||||
}).then(async () => {
|
||||
let params = {
|
||||
operation: 'remove',
|
||||
address: row.address,
|
||||
strategy: row.strategy,
|
||||
};
|
||||
let rules = [];
|
||||
if (row) {
|
||||
rules.push({
|
||||
operation: 'remove',
|
||||
address: row.address,
|
||||
port: '',
|
||||
source: '',
|
||||
protocol: '',
|
||||
strategy: row.strategy,
|
||||
});
|
||||
} else {
|
||||
for (const item of selects.value) {
|
||||
rules.push({
|
||||
operation: 'remove',
|
||||
address: item.address,
|
||||
port: '',
|
||||
source: '',
|
||||
protocol: '',
|
||||
strategy: item.strategy,
|
||||
});
|
||||
}
|
||||
}
|
||||
loading.value = true;
|
||||
await operateIPRule(params)
|
||||
await batchOperateRule({ type: 'port', rules: rules })
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
@ -127,9 +163,15 @@ const onDelete = async (row: Host.RuleInfo | null) => {
|
||||
};
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('commons.button.edit'),
|
||||
click: (row: Host.RuleIP) => {
|
||||
onOpenDialog('edit', row);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: (row: Host.RuleInfo) => {
|
||||
click: (row: Host.RuleIP) => {
|
||||
onDelete(row);
|
||||
},
|
||||
},
|
||||
|
@ -14,6 +14,9 @@
|
||||
clearable
|
||||
v-model="dialogData.rowData!.address"
|
||||
/>
|
||||
<span class="input-help">{{ $t('firewall.addressHelper1') }}</span>
|
||||
<span class="input-help">{{ $t('firewall.addressHelper2') }}</span>
|
||||
<span class="input-help">{{ $t('firewall.addressHelper3') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('firewall.strategy')" prop="strategy">
|
||||
<el-radio-group v-model="dialogData.rowData!.strategy">
|
||||
@ -44,13 +47,15 @@ import { ElForm } from 'element-plus';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { Host } from '@/api/interface/host';
|
||||
import { operateIPRule } from '@/api/modules/host';
|
||||
import { operateIPRule, updateAddrRule } from '@/api/modules/host';
|
||||
import { deepCopy } from '@/utils/util';
|
||||
|
||||
const loading = ref();
|
||||
const oldRule = ref<Host.RuleIP>();
|
||||
|
||||
interface DialogProps {
|
||||
title: string;
|
||||
rowData?: Host.RulePort;
|
||||
rowData?: Host.RuleIP;
|
||||
getTableList?: () => Promise<any>;
|
||||
}
|
||||
const title = ref<string>('');
|
||||
@ -60,6 +65,9 @@ const dialogData = ref<DialogProps>({
|
||||
});
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
dialogData.value = params;
|
||||
if (dialogData.value.title === 'edit') {
|
||||
oldRule.value = deepCopy(params.rowData);
|
||||
}
|
||||
title.value = i18n.global.t('commons.button.' + dialogData.value.title);
|
||||
drawerVisiable.value = true;
|
||||
};
|
||||
@ -83,11 +91,31 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
loading.value = true;
|
||||
dialogData.value.rowData.operation = 'add';
|
||||
if (!dialogData.value.rowData) return;
|
||||
await operateIPRule(dialogData.value.rowData);
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
emit('search');
|
||||
drawerVisiable.value = false;
|
||||
if (dialogData.value.title === 'create') {
|
||||
await operateIPRule(dialogData.value.rowData)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
emit('search');
|
||||
drawerVisiable.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
oldRule.value.operation = 'remove';
|
||||
dialogData.value.rowData.operation = 'add';
|
||||
await updateAddrRule({ oldRule: oldRule.value, newRule: dialogData.value.rowData })
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
emit('search');
|
||||
drawerVisiable.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -4,10 +4,27 @@
|
||||
<LayoutContent v-loading="loading" :title="$t('firewall.firewall')">
|
||||
<template #toolbar>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-col :span="16">
|
||||
<el-button type="primary" @click="onOpenDialog('create')">
|
||||
{{ $t('commons.button.create') }}{{ $t('firewall.portRule') }}
|
||||
</el-button>
|
||||
<el-button @click="onDelete(null)">
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<TableSetting @search="search()" />
|
||||
<div class="search-button">
|
||||
<el-input
|
||||
v-model="searchName"
|
||||
clearable
|
||||
@clear="search()"
|
||||
suffix-icon="Search"
|
||||
@keyup.enter="search()"
|
||||
@blur="search()"
|
||||
:placeholder="$t('commons.button.search')"
|
||||
></el-input>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -51,10 +68,11 @@
|
||||
<script lang="ts" setup>
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import FireRouter from '@/views/host/firewall/index.vue';
|
||||
import TableSetting from '@/components/table-setting/index.vue';
|
||||
import OperatrDialog from '@/views/host/firewall/port/operate/index.vue';
|
||||
import LayoutContent from '@/layout/layout-content.vue';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { operatePortRule, searchFireRule } from '@/api/modules/host';
|
||||
import { batchOperateRule, searchFireRule } from '@/api/modules/host';
|
||||
import { Host } from '@/api/interface/host';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
@ -63,6 +81,7 @@ import { ElMessageBox } from 'element-plus';
|
||||
const loading = ref();
|
||||
const activeTag = ref('port');
|
||||
const selects = ref<any>([]);
|
||||
const searchName = ref();
|
||||
|
||||
const data = ref();
|
||||
const paginationConfig = reactive({
|
||||
@ -74,7 +93,7 @@ const paginationConfig = reactive({
|
||||
const search = async () => {
|
||||
let params = {
|
||||
type: activeTag.value,
|
||||
info: '',
|
||||
info: searchName.value,
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
};
|
||||
@ -112,16 +131,30 @@ const onDelete = async (row: Host.RuleInfo | null) => {
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'warning',
|
||||
}).then(async () => {
|
||||
let params = {
|
||||
operation: 'remove',
|
||||
address: row.address,
|
||||
port: row.port,
|
||||
source: '',
|
||||
protocol: row.protocol,
|
||||
strategy: row.strategy,
|
||||
};
|
||||
let rules = [];
|
||||
if (row) {
|
||||
rules.push({
|
||||
operation: 'remove',
|
||||
address: row.address,
|
||||
port: row.port,
|
||||
source: '',
|
||||
protocol: row.protocol,
|
||||
strategy: row.strategy,
|
||||
});
|
||||
} else {
|
||||
for (const item of selects.value) {
|
||||
rules.push({
|
||||
operation: 'remove',
|
||||
address: item.address,
|
||||
port: item.port,
|
||||
source: '',
|
||||
protocol: item.protocol,
|
||||
strategy: item.strategy,
|
||||
});
|
||||
}
|
||||
}
|
||||
loading.value = true;
|
||||
await operatePortRule(params)
|
||||
await batchOperateRule({ type: 'port', rules: rules })
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
@ -134,6 +167,12 @@ const onDelete = async (row: Host.RuleInfo | null) => {
|
||||
};
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('commons.button.edit'),
|
||||
click: (row: Host.RulePort) => {
|
||||
onOpenDialog('edit', row);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: (row: Host.RuleInfo) => {
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
<el-form-item :label="$t('firewall.port')" prop="port">
|
||||
<el-input clearable v-model.trim="dialogData.rowData!.port" />
|
||||
<span class="input-help">{{ $t('firewall.portHelper') }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('firewall.source')" prop="source">
|
||||
@ -63,9 +64,11 @@ import { ElForm } from 'element-plus';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { Host } from '@/api/interface/host';
|
||||
import { operatePortRule } from '@/api/modules/host';
|
||||
import { operatePortRule, updatePortRule } from '@/api/modules/host';
|
||||
import { deepCopy } from '@/utils/util';
|
||||
|
||||
const loading = ref();
|
||||
const oldRule = ref<Host.RulePort>();
|
||||
|
||||
interface DialogProps {
|
||||
title: string;
|
||||
@ -79,6 +82,14 @@ const dialogData = ref<DialogProps>({
|
||||
});
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
dialogData.value = params;
|
||||
if (dialogData.value.title === 'edit') {
|
||||
if (params.rowData.address && params.rowData.address !== 'Anywhere') {
|
||||
dialogData.value.rowData.source = 'address';
|
||||
} else {
|
||||
dialogData.value.rowData.source = 'anyWhere';
|
||||
}
|
||||
oldRule.value = deepCopy(params.rowData);
|
||||
}
|
||||
title.value = i18n.global.t('commons.button.' + dialogData.value.title);
|
||||
drawerVisiable.value = true;
|
||||
};
|
||||
@ -101,14 +112,34 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
loading.value = true;
|
||||
dialogData.value.rowData.operation = 'add';
|
||||
if (!dialogData.value.rowData) return;
|
||||
await operatePortRule(dialogData.value.rowData);
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
emit('search');
|
||||
drawerVisiable.value = false;
|
||||
loading.value = true;
|
||||
if (dialogData.value.title === 'create') {
|
||||
await operatePortRule(dialogData.value.rowData)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
emit('search');
|
||||
drawerVisiable.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
oldRule.value.operation = 'remove';
|
||||
dialogData.value.rowData.operation = 'add';
|
||||
await updatePortRule({ oldRule: oldRule.value, newRule: dialogData.value.rowData })
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
emit('search');
|
||||
drawerVisiable.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user