添加策略匹配
This commit is contained in:
parent
9e706091d8
commit
6b1e37d9cd
|
|
@ -91,7 +91,9 @@
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
stripe
|
stripe
|
||||||
>
|
>
|
||||||
<el-table-column prop="id" label="ID" width="80" />
|
<el-table-column prop="ID" label="ID" width="80" />
|
||||||
|
<!-- 名称 -->
|
||||||
|
<el-table-column prop="name" label="名称" min-width="120" show-overflow-tooltip />
|
||||||
<el-table-column label="源信息" min-width="150">
|
<el-table-column label="源信息" min-width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div>{{ getSrcTypeText(scope.row.src_type) }}</div>
|
<div>{{ getSrcTypeText(scope.row.src_type) }}</div>
|
||||||
|
|
@ -165,6 +167,11 @@
|
||||||
size="default"
|
size="default"
|
||||||
>
|
>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="策略名称" prop="name">
|
||||||
|
<el-input v-model="policyForm.name"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="服务器ID" prop="server_id">
|
<el-form-item label="服务器ID" prop="server_id">
|
||||||
<el-input v-model="policyForm.server_id" disabled />
|
<el-input v-model="policyForm.server_id" disabled />
|
||||||
|
|
@ -265,6 +272,134 @@
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 策略匹配对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
title="策略匹配测试"
|
||||||
|
v-model="matchDialogVisible"
|
||||||
|
width="900px"
|
||||||
|
@close="resetMatchForm"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
:model="matchForm"
|
||||||
|
ref="matchFormRef"
|
||||||
|
label-width="120px"
|
||||||
|
size="default"
|
||||||
|
class="match-form"
|
||||||
|
>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="服务器" prop="server_id">
|
||||||
|
<el-select v-model="matchForm.server_id" placeholder="请选择服务器" style="width: 100%;">
|
||||||
|
<el-option
|
||||||
|
v-for="server in serverList"
|
||||||
|
:key="server.server_id"
|
||||||
|
:label="server.name"
|
||||||
|
:value="server.server_id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="IP类型" prop="ip_type">
|
||||||
|
<el-select v-model="matchForm.ip_type" placeholder="请选择IP类型">
|
||||||
|
<el-option label="IPv4" :value="4" />
|
||||||
|
<el-option label="IPv6" :value="6" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="源类型" prop="src_type">
|
||||||
|
<el-select v-model="matchForm.src_type" placeholder="请选择源类型" @change="onMatchSrcTypeChange">
|
||||||
|
<el-option label="IP地址" :value="0" />
|
||||||
|
<el-option label="网段" :value="1" />
|
||||||
|
<el-option label="用户ID" :value="2" />
|
||||||
|
<el-option label="组ID" :value="3" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="源值" prop="src_value">
|
||||||
|
<el-input
|
||||||
|
v-model="matchForm.src_value"
|
||||||
|
:placeholder="getSrcPlaceholder()"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="目标类型" prop="dst_type">
|
||||||
|
<el-select v-model="matchForm.dst_type" placeholder="请选择目标类型" @change="onMatchDstTypeChange">
|
||||||
|
<el-option label="IP地址" :value="0" />
|
||||||
|
<el-option label="网段" :value="1" />
|
||||||
|
<el-option label="用户ID" :value="2" />
|
||||||
|
<el-option label="组ID" :value="3" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="目标值" prop="dst_value">
|
||||||
|
<el-input
|
||||||
|
v-model="matchForm.dst_value"
|
||||||
|
:placeholder="getDstPlaceholder()"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="协议" prop="protocol">
|
||||||
|
<el-select v-model="matchForm.protocol" placeholder="请选择协议">
|
||||||
|
<el-option label="全部协议" :value="0" />
|
||||||
|
<el-option label="ICMP" :value="1" />
|
||||||
|
<el-option label="TCP" :value="6" />
|
||||||
|
<el-option label="UDP" :value="17" />
|
||||||
|
<el-option label="其他" :value="255" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="match-actions">
|
||||||
|
<el-button type="primary" @click="matchPolicy" :loading="matchLoading">匹配策略</el-button>
|
||||||
|
<el-button @click="resetMatchForm">重置</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 匹配结果 -->
|
||||||
|
<div v-if="matchResult" class="match-result">
|
||||||
|
<h4>匹配结果:</h4>
|
||||||
|
<div class="match-result-item">
|
||||||
|
<span>策略ID:</span>
|
||||||
|
<span>{{ matchResult.ID>0? matchResult.ID : '未匹配到策略,使用服务器配置'}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="match-result-item" v-if="matchResult.ID>0">
|
||||||
|
<span>策略名称:</span>
|
||||||
|
<span>{{ matchResult.name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="match-result-item">
|
||||||
|
<span>处置动作:</span>
|
||||||
|
<el-tag :type="matchResult.action === 1 ? 'success' : 'danger'" size="small">
|
||||||
|
{{ matchResult.action === 1 ? '允许' : '拒绝' }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="matchDialogVisible = false">关闭</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -277,11 +412,15 @@ import {
|
||||||
GetMyVPNPolicyHandler,
|
GetMyVPNPolicyHandler,
|
||||||
CreateMyVPNPolicyHandler,
|
CreateMyVPNPolicyHandler,
|
||||||
UpdateMyVPNPolicyHandler,
|
UpdateMyVPNPolicyHandler,
|
||||||
DeleteMyVPNPolicyHandler
|
DeleteMyVPNPolicyHandler,
|
||||||
|
MatchVPNPolicyHandler
|
||||||
} from '@/api/vpn';
|
} from '@/api/vpn';
|
||||||
|
import { match } from 'assert';
|
||||||
|
import { el } from 'element-plus/es/locale';
|
||||||
|
|
||||||
// VPN策略基础接口定义
|
// VPN策略基础接口定义
|
||||||
interface VPNPolicyBase {
|
interface VPNPolicyBase {
|
||||||
|
name: string;
|
||||||
server_id: string;
|
server_id: string;
|
||||||
ip_type: number; // 4, 6
|
ip_type: number; // 4, 6
|
||||||
src_type: number; // 0-ip,1-network, 2-userID, 3-groupID
|
src_type: number; // 0-ip,1-network, 2-userID, 3-groupID
|
||||||
|
|
@ -342,6 +481,25 @@ const matchDialogVisible = ref(false);
|
||||||
const isEdit = ref(false);
|
const isEdit = ref(false);
|
||||||
const policyFormRef = ref();
|
const policyFormRef = ref();
|
||||||
|
|
||||||
|
// 匹配表单
|
||||||
|
const matchForm = reactive({
|
||||||
|
server_id: '',
|
||||||
|
ip_type: 4,
|
||||||
|
src_type: 0,
|
||||||
|
src_value: '',
|
||||||
|
dst_type: 0,
|
||||||
|
dst_value: '',
|
||||||
|
protocol: 0,
|
||||||
|
src_ip: '',
|
||||||
|
src_user_id: 0,
|
||||||
|
dst_ip: '',
|
||||||
|
dst_user_id: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
// 匹配结果
|
||||||
|
const matchResult = ref<VPNPolicy>();
|
||||||
|
const matchLoading = ref(false);
|
||||||
|
|
||||||
// 搜索表单
|
// 搜索表单
|
||||||
const searchForm = reactive({
|
const searchForm = reactive({
|
||||||
src_type: undefined as number | undefined,
|
src_type: undefined as number | undefined,
|
||||||
|
|
@ -359,6 +517,7 @@ const pagination = reactive({
|
||||||
|
|
||||||
// 策略表单
|
// 策略表单
|
||||||
const policyForm = reactive<VPNPolicyBase & { id?: number }>({
|
const policyForm = reactive<VPNPolicyBase & { id?: number }>({
|
||||||
|
name: '',
|
||||||
id: undefined,
|
id: undefined,
|
||||||
server_id: '',
|
server_id: '',
|
||||||
ip_type: 4,
|
ip_type: 4,
|
||||||
|
|
@ -478,6 +637,100 @@ const refreshPolicies = () => {
|
||||||
//显示匹配对话框
|
//显示匹配对话框
|
||||||
const showMatchDialog = () => {
|
const showMatchDialog = () => {
|
||||||
matchDialogVisible.value = true;
|
matchDialogVisible.value = true;
|
||||||
|
// 默认选择当前选中的服务器
|
||||||
|
if (selectedServer.value) {
|
||||||
|
matchForm.server_id = selectedServer.value.server_id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 匹配策略
|
||||||
|
const matchPolicy = async () => {
|
||||||
|
if (!matchForm.server_id) {
|
||||||
|
ElMessage.warning('请选择服务器');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据类型设置对应的值
|
||||||
|
switch (matchForm.src_type) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
matchForm.src_ip = matchForm.src_value;
|
||||||
|
matchForm.src_user_id = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
matchForm.src_user_id = parseInt(matchForm.src_value) || 0;
|
||||||
|
matchForm.src_ip = '';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (matchForm.dst_type) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
matchForm.dst_ip = matchForm.dst_value;
|
||||||
|
matchForm.dst_user_id = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
matchForm.dst_user_id = parseInt(matchForm.dst_value) || 0;
|
||||||
|
matchForm.dst_ip = '';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
matchLoading.value = true;
|
||||||
|
try {
|
||||||
|
const response = await MatchVPNPolicyHandler(matchForm);
|
||||||
|
if (response["code"] == 0) {
|
||||||
|
if (response["data"] === 0){
|
||||||
|
if (!matchResult.value){
|
||||||
|
matchResult.value = {} as VPNPolicy;
|
||||||
|
}
|
||||||
|
matchResult.value.ID = 0;
|
||||||
|
matchResult.value.name = '未匹配到策略';
|
||||||
|
matchResult.value.action = serverList.value.find(item => item.server_id === matchForm.server_id)?.no_policy_action;
|
||||||
|
}else{
|
||||||
|
matchResult.value = response.data;
|
||||||
|
}
|
||||||
|
ElMessage.success('策略匹配成功');
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response["message"] || '策略匹配失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('策略匹配失败');
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
matchLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置匹配表单
|
||||||
|
const resetMatchForm = () => {
|
||||||
|
matchForm.server_id = selectedServer.value?.server_id || '';
|
||||||
|
matchForm.ip_type = 4;
|
||||||
|
matchForm.src_type = 0;
|
||||||
|
matchForm.src_value = '';
|
||||||
|
matchForm.dst_type = 0;
|
||||||
|
matchForm.dst_value = '';
|
||||||
|
matchForm.protocol = 0;
|
||||||
|
matchForm.src_ip = '';
|
||||||
|
matchForm.src_user_id = 0;
|
||||||
|
matchForm.dst_ip = '';
|
||||||
|
matchForm.dst_user_id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 匹配表单源类型改变
|
||||||
|
const onMatchSrcTypeChange = () => {
|
||||||
|
matchForm.src_ip = '';
|
||||||
|
matchForm.src_user_id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 匹配表单目标类型改变
|
||||||
|
const onMatchDstTypeChange = () => {
|
||||||
|
matchForm.dst_ip = '';
|
||||||
|
matchForm.dst_user_id = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 显示新增对话框
|
// 显示新增对话框
|
||||||
|
|
@ -970,4 +1223,25 @@ onMounted(() => {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.match-form {
|
||||||
|
max-height: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.match-actions {
|
||||||
|
margin: 20px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.match-result h4 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
color: #303133;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-match-result {
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
Reference in New Issue