From 6381587307db8b40537555f5100c18a1780a0ff4 Mon Sep 17 00:00:00 2001 From: Muse Date: Mon, 19 Oct 2026 21:00:13 +0800 Subject: [PATCH] =?UTF-8?q?Agent=20=E8=8A=82=E7=82=B9=E5=85=8D=E5=A1=AB?= =?UTF-8?q?=E5=9C=B0=E5=9D=80/=E7=AB=AF=E5=8F=A3/API=E4=BB=A4=E7=89=8C?= =?UTF-8?q?=EF=BC=88=E5=89=8D=E5=90=8E=E7=AB=AF=E6=A0=A1=E9=AA=8C=EF=BC=89?= =?UTF-8?q?+=20=E8=A1=A5=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/web/service/node_contract.go | 14 ++++++++++++-- internal/web/translation/en-US.json | 6 +++--- internal/web/translation/zh-CN.json | 6 +++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/internal/web/service/node_contract.go b/internal/web/service/node_contract.go index 5526c0a..e1ca7d6 100644 --- a/internal/web/service/node_contract.go +++ b/internal/web/service/node_contract.go @@ -118,8 +118,8 @@ type NodeMutationRequest struct { Name string `json:"name" form:"name" validate:"required"` Remark string `json:"remark" form:"remark"` Scheme string `json:"scheme" form:"scheme" validate:"omitempty,oneof=http https"` - Address string `json:"address" form:"address" validate:"required"` - Port int `json:"port" form:"port" validate:"gte=1,lte=65535"` + Address string `json:"address" form:"address"` + Port int `json:"port" form:"port" validate:"gte=0,lte=65535"` BasePath string `json:"basePath" form:"basePath"` ApiToken *string `json:"apiToken,omitempty" form:"apiToken"` ClearApiToken bool `json:"clearApiToken,omitempty" form:"clearApiToken"` @@ -140,6 +140,16 @@ func (r *NodeMutationRequest) validateCredentials(create bool) error { if r == nil { return common.NewError("node request is required") } + // Agent nodes dial out to the master; address/port are not needed. + // Traditional nodes still require them. + if r.NodeType != "agent" { + if strings.TrimSpace(r.Address) == "" { + return common.NewError("address is required") + } + if r.Port < 1 || r.Port > 65535 { + return common.NewError("port must be between 1 and 65535") + } + } if r.ApiToken != nil && r.ClearApiToken { return common.NewError("apiToken and clearApiToken are mutually exclusive") } diff --git a/internal/web/translation/en-US.json b/internal/web/translation/en-US.json index 160efb5..e8e3ab5 100644 --- a/internal/web/translation/en-US.json +++ b/internal/web/translation/en-US.json @@ -1181,9 +1181,9 @@ "pinFetched": "Fetched the node's current certificate", "pinFetchFailed": "Could not fetch the certificate", "nodeType": "Node Type", - "nodeTypeTraditional": "Traditional Panel", - "nodeTypeAgent": "Agent", - "agentHint": "Agent nodes don't need a panel address. An agent token will be generated on creation for configuring the agent on the node machine.", + "nodeTypeTraditional": "Traditional Panel Node", + "nodeTypeAgent": "Agent Lightweight Node", + "agentHint": "Agent nodes connect out to the master; no address, port or API token needed. An install command is generated on creation.", "agentTokenTitle": "Agent Node Setup", "agentTokenCreated": "Node {{name}} created successfully", "agentTokenHint": "Copy the command below and run it on the node machine. This token is shown only once!", diff --git a/internal/web/translation/zh-CN.json b/internal/web/translation/zh-CN.json index 6e08e80..2ec503d 100644 --- a/internal/web/translation/zh-CN.json +++ b/internal/web/translation/zh-CN.json @@ -1063,9 +1063,9 @@ "pinFetched": "已获取节点当前证书", "pinFetchFailed": "无法获取证书", "nodeType": "节点类型", - "nodeTypeTraditional": "传统面板", - "nodeTypeAgent": "Agent", - "agentHint": "Agent 节点无需面板地址,创建后会自动生成 agent token,用于在节点机上配置 agent。", + "nodeTypeTraditional": "传统面板节点", + "nodeTypeAgent": "Agent 轻量节点", + "agentHint": "Agent 节点由节点机主动连接主控,无需填写地址、端口和 API 令牌。创建后会生成安装命令。", "agentTokenTitle": "Agent 节点安装", "agentTokenCreated": "节点 {{name}} 创建成功", "agentTokenHint": "复制下面的命令,在节点机上运行即可完成安装。此 token 只显示一次!",