fix
This commit is contained in:
@@ -13,6 +13,10 @@ export const fetchAlertRecords = (data: {
|
||||
keyword?: string,
|
||||
sort?: string,
|
||||
order?: string,
|
||||
binding_id?: number,
|
||||
resource_category?: string,
|
||||
server_identity?: string,
|
||||
ip?: string,
|
||||
}) => {
|
||||
return request.get("/Alert/v1/record/list", { params: data });
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<a-form-item label="Agent URL配置">
|
||||
<a-input
|
||||
v-model="form.agent_config"
|
||||
placeholder="http://192.168.1.100:9100/dc-host/v1/control/command"
|
||||
placeholder="http://192.168.1.100:9100/dc-host/stats"
|
||||
allow-clear
|
||||
/>
|
||||
<template #extra>
|
||||
|
||||
@@ -16,16 +16,20 @@
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="host" label="主机地址" required>
|
||||
<a-input v-model="formData.host" placeholder="请输入主机地址" />
|
||||
<a-form-item
|
||||
field="host"
|
||||
label="主机地址(IPv4 / IPv6)"
|
||||
required
|
||||
>
|
||||
<a-input v-model="formData.host" placeholder="域名或 IP,如 server.example.com 或 192.168.1.10" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="20">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="ip_address" label="IP地址">
|
||||
<a-input v-model="formData.ip_address" placeholder="请输入IP地址" />
|
||||
<a-form-item field="ip_address" label="IP地址" required>
|
||||
<a-input v-model="formData.ip_address" placeholder="IPv4 或 IPv6,如 192.168.1.10" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
@@ -92,7 +96,7 @@
|
||||
</a-row>
|
||||
|
||||
<a-form-item field="agent_config" label="Agent 配置 URL">
|
||||
<a-input v-model="formData.agent_config" placeholder="http://192.168.1.100:9100/dc-host/v1/control/command" />
|
||||
<a-input v-model="formData.agent_config" placeholder="http://192.168.1.100:9100/dc-host/stats" />
|
||||
</a-form-item>
|
||||
|
||||
<a-row :gutter="20">
|
||||
@@ -182,9 +186,79 @@ const formData = reactive<ServerFormData>({
|
||||
ip_scan_port: 12429,
|
||||
})
|
||||
|
||||
/** 判断是否为合法 IPv4 字符串 */
|
||||
function isIPv4String(host: string): boolean {
|
||||
const h = host.trim()
|
||||
if (!h) return false
|
||||
const parts = h.split('.')
|
||||
if (parts.length !== 4) return false
|
||||
return parts.every((p) => {
|
||||
if (!/^\d{1,3}$/.test(p)) return false
|
||||
const n = Number(p)
|
||||
return n >= 0 && n <= 255
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 若主机地址为 IP,返回规范化后的 IP(IPv4 或 IPv6);否则返回 null
|
||||
*/
|
||||
function extractIpFromHost(host: string): string | null {
|
||||
const t = host.trim()
|
||||
if (!t) return null
|
||||
if (isIPv4String(t)) return t
|
||||
if (!t.includes(':')) return null
|
||||
try {
|
||||
const withBrackets = t.startsWith('[') && t.endsWith(']') ? t : `[${t}]`
|
||||
const u = new URL(`http://${withBrackets}/`)
|
||||
if (u.hostname.includes(':')) return u.hostname
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** 校验 IP 地址字段(IPv4 或 IPv6) */
|
||||
function isValidIpAddress(s: string): boolean {
|
||||
const t = s.trim()
|
||||
if (!t) return false
|
||||
if (isIPv4String(t)) return true
|
||||
try {
|
||||
const withBrackets = t.startsWith('[') && t.endsWith(']') ? t : `[${t}]`
|
||||
const u = new URL(`http://${withBrackets}/`)
|
||||
return u.hostname.includes(':')
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/** 主机为 IP 时同步到 IP 地址字段 */
|
||||
function syncIpFromHost() {
|
||||
const ip = extractIpFromHost(formData.host)
|
||||
if (ip) {
|
||||
formData.ip_address = ip
|
||||
}
|
||||
}
|
||||
|
||||
const rules = {
|
||||
name: [{ required: true, message: '请输入服务器名称' }],
|
||||
host: [{ required: true, message: '请输入主机地址' }],
|
||||
ip_address: [
|
||||
{ required: true, message: '请输入IP地址' },
|
||||
{
|
||||
validator: (value: string | undefined, cb: (error?: string) => void) => {
|
||||
const v = (value || '').trim()
|
||||
if (!v) {
|
||||
cb()
|
||||
return
|
||||
}
|
||||
if (!isValidIpAddress(v)) {
|
||||
cb('请输入合法的 IPv4 或 IPv6 地址')
|
||||
return
|
||||
}
|
||||
cb()
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
function validateAgentConfigURL(raw?: string): string | null {
|
||||
@@ -228,6 +302,7 @@ watch(
|
||||
is_ip_scan_server: props.record.is_ip_scan_server ?? false,
|
||||
ip_scan_port: props.record.ip_scan_port || 12429,
|
||||
})
|
||||
syncIpFromHost()
|
||||
} else {
|
||||
Object.assign(formData, {
|
||||
server_identity: '',
|
||||
@@ -255,6 +330,14 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => formData.host,
|
||||
() => {
|
||||
if (!props.visible) return
|
||||
syncIpFromHost()
|
||||
},
|
||||
)
|
||||
|
||||
const handleOk = async () => {
|
||||
try {
|
||||
await formRef.value?.validate()
|
||||
|
||||
@@ -460,19 +460,7 @@ const handleDelete = async (record: any) => {
|
||||
})
|
||||
}
|
||||
|
||||
/** dc-host `/dc-host/v1/control/command` 拉取本机采集指标(execute_task + service_collect) */
|
||||
const buildDcHostServiceCollectBody = () => ({
|
||||
command: 'execute_task' as const,
|
||||
params: {
|
||||
task_id: 0,
|
||||
task_name: 'service_collect',
|
||||
type: 'host' as const,
|
||||
config: '{}',
|
||||
timeout: 120,
|
||||
},
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
/** dc-host `GET agent_config`(一般为 `/dc-host/stats`)返回裸 Metrics JSON */
|
||||
// 获取所有服务器的监控指标
|
||||
const getAllMetrics = async () => {
|
||||
try {
|
||||
@@ -485,9 +473,8 @@ const getAllMetrics = async () => {
|
||||
let metricsUrl = record.agent_config
|
||||
|
||||
// 验证 URL 是否合法
|
||||
let agentUrl: URL
|
||||
try {
|
||||
agentUrl = new URL(metricsUrl)
|
||||
new URL(metricsUrl)
|
||||
} catch (urlError) {
|
||||
console.warn(`服务器 ${record.name} 的 agent_config 不是合法的 URL:`, metricsUrl)
|
||||
// 设置默认值 0
|
||||
@@ -496,12 +483,8 @@ const getAllMetrics = async () => {
|
||||
record.disk_info = { value: 0, total: '', used: '' }
|
||||
return
|
||||
}
|
||||
// dc-host 控制面拉取指标接口为 POST
|
||||
const isDcHostCommand = agentUrl.pathname.includes('/dc-host/v1/control/command')
|
||||
// 使用独立的 axios 实例请求外部 agent,绕过全局拦截器
|
||||
const response = isDcHostCommand
|
||||
? await agentAxios.post(metricsUrl, buildDcHostServiceCollectBody())
|
||||
: await agentAxios.get(metricsUrl)
|
||||
const response = await agentAxios.get(metricsUrl)
|
||||
console.log('获取指标数据:', response.data)
|
||||
if (response.data) {
|
||||
// 更新记录的监控数据
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user