1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 08:19:15 +08:00

feat: 防火墙列表增加状态、策略筛选项 (#2121)

Refs #1859
This commit is contained in:
ssongliu 2023-08-30 14:56:11 +08:00 committed by GitHub
parent 529a7e6ea6
commit 9cecd66f3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 118 additions and 53 deletions

View File

@ -38,6 +38,10 @@ func (b *BaseApi) SearchFirewallRule(c *gin.Context) {
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
}
total, list, err := firewallService.SearchWithPage(req)
if err != nil {

View File

@ -9,8 +9,10 @@ type FirewallBaseInfo struct {
type RuleSearch struct {
PageInfo
Info string `json:"info"`
Type string `json:"type" validate:"required"`
Info string `json:"info"`
Status string `json:"status"`
Strategy string `json:"strategy"`
Type string `json:"type" validate:"required"`
}
type FirewallOperation struct {
@ -28,6 +30,7 @@ type PortRuleOperate struct {
}
type UpdateFirewallDescription struct {
Type string `json:"type"`
Address string `json:"address"`
Port string `json:"port"`
Protocol string `json:"protocol"`

View File

@ -3,6 +3,7 @@ package model
type Firewall struct {
BaseModel
Type string `gorm:"type:varchar(64);not null" json:"type"`
Port string `gorm:"type:varchar(64);not null" json:"port"`
Protocol string `gorm:"type:varchar(64);not null" json:"protocol"`
Address string `gorm:"type:varchar(64);not null" json:"address"`

View File

@ -24,7 +24,7 @@ type IHostRepo interface {
ListFirewallRecord() ([]model.Firewall, error)
SaveFirewallRecord(firewall *model.Firewall) error
DeleteFirewallRecordByID(id uint) error
DeleteFirewallRecord(port, protocol, address, strategy string) error
DeleteFirewallRecord(fType, port, protocol, address, strategy string) error
}
func NewIHostRepo() IHostRepo {
@ -136,9 +136,16 @@ func (h *HostRepo) SaveFirewallRecord(firewall *model.Firewall) error {
return global.DB.Save(firewall).Error
}
var data model.Firewall
_ = global.DB.Where("port = ? AND protocol = ? AND address = ? AND strategy = ?", firewall.Port, firewall.Protocol, firewall.Address, firewall.Strategy).First(&data)
if data.ID != 0 {
firewall.ID = data.ID
if firewall.Type == "port" {
_ = global.DB.Where("type = ? AND port = ? AND protocol = ? AND address = ? AND strategy = ?", "port", firewall.Port, firewall.Protocol, firewall.Address, firewall.Strategy).First(&data)
if data.ID != 0 {
firewall.ID = data.ID
}
} else {
_ = global.DB.Where("type = ? AND address = ? AND strategy = ?", "address", firewall.Address, firewall.Strategy).First(&data)
if data.ID != 0 {
firewall.ID = data.ID
}
}
return global.DB.Save(firewall).Error
}
@ -147,6 +154,6 @@ func (h *HostRepo) DeleteFirewallRecordByID(id uint) error {
return global.DB.Where("id = ?", id).Delete(&model.Firewall{}).Error
}
func (h *HostRepo) DeleteFirewallRecord(port, protocol, address, strategy string) error {
return global.DB.Where("port = ? AND protocol = ? AND address = ? AND strategy = ?", port, protocol, address, strategy).Delete(&model.Firewall{}).Error
func (h *HostRepo) DeleteFirewallRecord(fType, port, protocol, address, strategy string) error {
return global.DB.Where("type = ? AND port = ? AND protocol = ? AND address = ? AND strategy = ?", fType, port, protocol, address, strategy).Delete(&model.Firewall{}).Error
}

View File

@ -104,20 +104,57 @@ func (u *FirewallService) SearchWithPage(req dto.RuleSearch) (int64, interface{}
datas = addrs
}
}
total, start, end := len(datas), (req.Page-1)*req.PageSize, req.Page*req.PageSize
var datasFilterStatus []fireClient.FireInfo
if len(req.Status) != 0 {
for _, data := range datas {
portItem, _ := strconv.Atoi(data.Port)
if req.Status == "free" && !common.ScanPort(portItem) {
datasFilterStatus = append(datasFilterStatus, data)
}
if req.Status == "used" && common.ScanPort(portItem) {
datasFilterStatus = append(datasFilterStatus, data)
}
}
} else {
datasFilterStatus = datas
}
var datasFilterStrategy []fireClient.FireInfo
if len(req.Strategy) != 0 {
for _, data := range datasFilterStatus {
if req.Strategy == data.Strategy {
datasFilterStrategy = append(datasFilterStrategy, data)
}
}
} else {
datasFilterStrategy = datasFilterStatus
}
total, start, end := len(datasFilterStrategy), (req.Page-1)*req.PageSize, req.Page*req.PageSize
if start > total {
backDatas = make([]fireClient.FireInfo, 0)
} else {
if end >= total {
end = total
}
backDatas = datas[start:end]
backDatas = datasFilterStrategy[start:end]
}
datasFromDB, _ := hostRepo.ListFirewallRecord()
for i := 0; i < len(backDatas); i++ {
for _, des := range datasFromDB {
if backDatas[i].Port == des.Port && backDatas[i].Protocol == des.Protocol && backDatas[i].Strategy == des.Strategy && backDatas[i].Address == des.Address {
if req.Type != des.Type {
continue
}
if backDatas[i].Port == des.Port &&
req.Type == "port" &&
backDatas[i].Protocol == des.Protocol &&
backDatas[i].Strategy == des.Strategy &&
backDatas[i].Address == des.Address {
backDatas[i].Description = des.Description
break
}
if req.Type == "address" && backDatas[i].Strategy == des.Strategy && backDatas[i].Address == des.Address {
backDatas[i].Description = des.Description
break
}
@ -488,10 +525,11 @@ func (u *FirewallService) addPortsBeforeStart(client firewall.FirewallClient) er
func (u *FirewallService) addPortRecord(req dto.PortRuleOperate) error {
if req.Operation == "remove" {
return hostRepo.DeleteFirewallRecord(req.Port, req.Protocol, req.Address, req.Strategy)
return hostRepo.DeleteFirewallRecord("port", req.Port, req.Protocol, req.Address, req.Strategy)
}
return hostRepo.SaveFirewallRecord(&model.Firewall{
Type: "port",
Port: req.Port,
Protocol: req.Protocol,
Address: req.Address,
@ -502,9 +540,10 @@ func (u *FirewallService) addPortRecord(req dto.PortRuleOperate) error {
func (u *FirewallService) addAddressRecord(req dto.AddrRuleOperate) error {
if req.Operation == "remove" {
return hostRepo.DeleteFirewallRecord("", "", req.Address, req.Strategy)
return hostRepo.DeleteFirewallRecord("address", "", "", req.Address, req.Strategy)
}
return hostRepo.SaveFirewallRecord(&model.Firewall{
Type: "address",
Address: req.Address,
Strategy: req.Strategy,
Description: req.Description,

View File

@ -572,14 +572,12 @@ var UpdateCronjobWithDb = &gormigrate.Migration{
}
var AddTableFirewall = &gormigrate.Migration{
ID: "20230825-add-table-firewall",
ID: "20230828-add-table-firewall",
Migrate: func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&model.Firewall{}, model.SnapshotStatus{}, &model.Cronjob{}); err != nil {
return err
}
if err := tx.Exec("alter table remote_dbs rename to databases;").Error; err != nil {
return err
}
_ = tx.Exec("alter table remote_dbs rename to databases;").Error
return nil
},
}

View File

@ -66,6 +66,8 @@ export namespace Host {
pingStatus: string;
}
export interface RuleSearch extends ReqPage {
status: string;
strategy: string;
info: string;
type: string;
}

View File

@ -140,9 +140,7 @@
</el-table-column>
<el-table-column :label="$t('commons.table.description')" prop="description">
<template #default="{ row }">
<fu-read-write-switch :data="row.description" v-model="row.edit" @change="onChange(row)">
<el-input v-model="row.description" @blur="row.edit = false" />
</fu-read-write-switch>
<fu-input-rw-switch v-model="row.description" @blur="onChange(row)" />
</template>
</el-table-column>
<el-table-column
@ -382,10 +380,8 @@ const goRouter = async () => {
};
const onChange = async (info: any) => {
if (!info.edit) {
await updateMysqlDescription({ id: info.id, description: info.description });
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
}
await updateMysqlDescription({ id: info.id, description: info.description });
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
};
const goDashboard = async () => {

View File

@ -45,6 +45,16 @@
</el-col>
</el-row>
</template>
<template #search>
<div class="flx-align-center">
<el-select v-model="searchStrategy" @change="search()" clearable>
<template #prefix>{{ $t('firewall.strategy') }}</template>
<el-option :label="$t('commons.table.all')" value=""></el-option>
<el-option :label="$t('firewall.allow')" value="accept"></el-option>
<el-option :label="$t('firewall.deny')" value="drop"></el-option>
</el-select>
</div>
</template>
<template #main>
<ComplexTable
:pagination-config="paginationConfig"
@ -80,13 +90,7 @@
prop="description"
>
<template #default="{ row }">
<fu-read-write-switch
:data="row.description"
v-model="row.edit"
@change="onChange(row)"
>
<el-input v-model="row.description" @blur="row.edit = false" />
</fu-read-write-switch>
<fu-input-rw-switch v-model="row.description" @blur="onChange(row)" />
</template>
</el-table-column>
<fu-table-operations
@ -143,6 +147,7 @@ const loading = ref();
const activeTag = ref('address');
const selects = ref<any>([]);
const searchName = ref();
const searchStrategy = ref('');
const fireName = ref();
const maskShow = ref(true);
@ -165,6 +170,8 @@ const search = async () => {
}
let params = {
type: activeTag.value,
status: '',
strategy: searchStrategy.value,
info: searchName.value,
page: paginationConfig.currentPage,
pageSize: paginationConfig.pageSize,
@ -200,10 +207,9 @@ const toDoc = () => {
};
const onChange = async (info: any) => {
if (!info.edit) {
await updateFirewallDescription(info);
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
}
info.type = 'address';
await updateFirewallDescription(info);
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
};
const onChangeStatus = async (row: Host.RuleInfo, status: string) => {

View File

@ -35,6 +35,22 @@
</template>
</el-alert>
</template>
<template #search>
<div class="flx-align-center">
<el-select v-model="searchStatus" @change="search()" clearable>
<template #prefix>{{ $t('commons.table.status') }}</template>
<el-option :label="$t('commons.table.all')" value=""></el-option>
<el-option :label="$t('firewall.unUsed')" value="free"></el-option>
<el-option :label="$t('firewall.used')" value="used"></el-option>
</el-select>
<el-select v-model="searchStrategy" style="margin-left: 10px" @change="search()" clearable>
<template #prefix>{{ $t('firewall.strategy') }}</template>
<el-option :label="$t('commons.table.all')" value=""></el-option>
<el-option :label="$t('firewall.accept')" value="accept"></el-option>
<el-option :label="$t('firewall.drop')" value="drop"></el-option>
</el-select>
</div>
</template>
<template #toolbar>
<el-row>
<el-col :span="16">
@ -110,13 +126,7 @@
prop="description"
>
<template #default="{ row }">
<fu-read-write-switch
:data="row.description"
v-model="row.edit"
@change="onChange(row)"
>
<el-input v-model="row.description" @blur="row.edit = false" />
</fu-read-write-switch>
<fu-input-rw-switch v-model="row.description" @blur="onChange(row)" />
</template>
</el-table-column>
<fu-table-operations
@ -175,6 +185,8 @@ const loading = ref();
const activeTag = ref('port');
const selects = ref<any>([]);
const searchName = ref();
const searchStatus = ref('');
const searchStrategy = ref('');
const maskShow = ref(true);
const fireStatus = ref('running');
@ -197,6 +209,8 @@ const search = async () => {
}
let params = {
type: activeTag.value,
status: searchStatus.value,
strategy: searchStrategy.value,
info: searchName.value,
page: paginationConfig.currentPage,
pageSize: paginationConfig.pageSize,
@ -279,10 +293,9 @@ const onChangeStatus = async (row: Host.RuleInfo, status: string) => {
};
const onChange = async (info: any) => {
if (!info.edit) {
await updateFirewallDescription(info);
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
}
info.type = 'port';
await updateFirewallDescription(info);
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
};
const onDelete = async (row: Host.RuleInfo | null) => {

View File

@ -74,9 +74,7 @@
</el-table-column>
<el-table-column :label="$t('commons.table.description')" prop="description">
<template #default="{ row }">
<fu-read-write-switch :data="row.description" v-model="row.edit" @change="onChange(row)">
<el-input v-model="row.description" @blur="row.edit = false" />
</fu-read-write-switch>
<fu-input-rw-switch v-model="row.description" @blur="onChange(row)" />
</template>
</el-table-column>
<el-table-column
@ -205,10 +203,8 @@ const handleClose = () => {
};
const onChange = async (info: any) => {
if (!info.edit) {
await updateSnapshotDescription({ id: info.id, description: info.description });
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
}
await updateSnapshotDescription({ id: info.id, description: info.description });
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
};
const submitAddSnapshot = (formEl: FormInstance | undefined) => {