From e0be65a2520f76a2d182fc32b4c5347df86bd73e Mon Sep 17 00:00:00 2001 From: "shixin.ruan" Date: Wed, 27 May 2026 16:42:10 +0900 Subject: [PATCH] [vrouter]: select callback IP for VR Use a callback URL in the same IP family as the virtual router management NIC. This keeps IPv4-only vrouter agents reachable when MN is dual-stack and its default management IP is IPv6. Resolves: ZSTAC-85527 Change-Id: Iaa630fc59d30c2675db7bbe47cb1b7c8d58bb023 --- .../org/zstack/core/rest/RESTFacadeImpl.java | 5 ++++ .../org/zstack/header/rest/RESTFacade.java | 2 ++ .../service/virtualrouter/VirtualRouter.java | 6 ++-- .../virtualrouter/VirtualRouterManager.java | 3 ++ .../VirtualRouterManagerImpl.java | 28 +++++++++++++++++++ .../VirtualRouterDeployAgentFlow.java | 4 +-- .../virtualrouter/vyos/VyosConnectFlow.java | 2 +- 7 files changed, 45 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/zstack/core/rest/RESTFacadeImpl.java b/core/src/main/java/org/zstack/core/rest/RESTFacadeImpl.java index 41f1354ceb1..e4ae416ff42 100755 --- a/core/src/main/java/org/zstack/core/rest/RESTFacadeImpl.java +++ b/core/src/main/java/org/zstack/core/rest/RESTFacadeImpl.java @@ -986,6 +986,11 @@ public String getCallbackUrl() { return callbackUrl; } + @Override + public String buildCallbackUrl(String hostName) { + return buildCallbackUrl(hostName, port, path); + } + @Override public String getHostName() { return callbackHostName; diff --git a/header/src/main/java/org/zstack/header/rest/RESTFacade.java b/header/src/main/java/org/zstack/header/rest/RESTFacade.java index e9d3120f9d6..31f4ac15f4e 100755 --- a/header/src/main/java/org/zstack/header/rest/RESTFacade.java +++ b/header/src/main/java/org/zstack/header/rest/RESTFacade.java @@ -88,6 +88,8 @@ public interface RESTFacade { String getCallbackUrl(); + String buildCallbackUrl(String hostName); + String getHostName(); int getPort(); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java index de4468664dd..e896b0f664a 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java @@ -187,7 +187,8 @@ protected void handleLocalMessage(Message msg) { void doPing(String vrUuid, ReturnValueCompletion completion) { PingCmd cmd = new PingCmd(); cmd.setUuid(vrUuid); - restf.asyncJsonPost(buildUrl(vr.getManagementNic().getIp(), VirtualRouterConstant.VR_PING), cmd, new JsonAsyncRESTCallback(completion) { + restf.asyncJsonPost(buildUrl(vr.getManagementNic().getIp(), VirtualRouterConstant.VR_PING), + cmd, vrMgr.buildAgentCallbackUrlHeaders(vr.getManagementNic().getIp()), new JsonAsyncRESTCallback(completion) { @Override public void fail(ErrorCode err) { completion.fail(err); @@ -685,7 +686,8 @@ public void run(final SyncTaskChain chain) { self.getUuid(), msg.getPath())); } - restf.asyncJsonPost(buildUrl(vr.getManagementNic().getIp(), msg.getPath()), msg.getCommand(), new JsonAsyncRESTCallback(msg, chain) { + restf.asyncJsonPost(buildUrl(vr.getManagementNic().getIp(), msg.getPath()), + msg.getCommand(), vrMgr.buildAgentCallbackUrlHeaders(vr.getManagementNic().getIp()), new JsonAsyncRESTCallback(msg, chain) { @Override public void fail(ErrorCode err) { reply.setError(err); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManager.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManager.java index a7711086975..17a790f1020 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManager.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManager.java @@ -11,6 +11,7 @@ import org.zstack.header.vm.VmNicInventory; import java.util.List; +import java.util.Map; public interface VirtualRouterManager { @@ -18,6 +19,8 @@ public interface VirtualRouterManager { String buildUrl(String mgmtNicIp, String subPath); + Map buildAgentCallbackUrlHeaders(String mgmtNicIp); + List selectL3NetworksNeedingSpecificNetworkService(List candidate, NetworkServiceType nsType); List selectGuestL3NetworksNeedingSpecificNetworkService(List candidate, NetworkServiceType nsType, String publicUuid); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java index a876ee24a34..3e435674ae7 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java @@ -50,6 +50,8 @@ import org.zstack.header.query.ExpandedQueryAliasStruct; import org.zstack.header.query.ExpandedQueryStruct; import org.zstack.header.query.QueryBelongFilter; +import org.zstack.header.rest.RESTConstant; +import org.zstack.header.rest.RESTFacade; import org.zstack.header.tag.*; import org.zstack.header.vm.*; import org.zstack.identity.Account; @@ -117,6 +119,9 @@ public class VirtualRouterManagerImpl extends AbstractService implements Virtual private final Map hypervisorBackends = new HashMap(); private final Map vrParallelismDegrees = new ConcurrentHashMap(); + @Autowired + private RESTFacade restf; + private List virtualRouterPostCreateFlows; private List virtualRouterPostStartFlows; private List virtualRouterPostRebootFlows; @@ -967,6 +972,29 @@ public String buildUrl(String mgmtNicIp, String subPath) { return ub.build().toUriString(); } + @Override + public Map buildAgentCallbackUrlHeaders(String mgmtNicIp) { + return Collections.singletonMap(RESTConstant.CALLBACK_URL, restf.buildCallbackUrl(selectManagementIpForAgent(mgmtNicIp))); + } + + private String selectManagementIpForAgent(String agentIp) { + if (IPv6NetworkUtils.isIpv6Address(agentIp)) { + return Platform.getManagementServerIps().stream() + .filter(IPv6NetworkUtils::isIpv6Address) + .findFirst() + .orElse(Platform.getManagementServerIp()); + } + + if (NetworkUtils.isIpv4Address(agentIp)) { + return Platform.getManagementServerIps().stream() + .filter(NetworkUtils::isIpv4Address) + .findFirst() + .orElse(Platform.getManagementServerIp()); + } + + return Platform.getManagementServerIp(); + } + private void buildWorkFlowBuilder() { postCreateFlowsBuilder = FlowChainBuilder.newBuilder().setFlowClassNames(virtualRouterPostCreateFlows).construct(); postStartFlowsBuilder = FlowChainBuilder.newBuilder().setFlowClassNames(virtualRouterPostStartFlows).construct(); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployAgentFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployAgentFlow.java index 903f53d18d7..0b6e0617a14 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployAgentFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployAgentFlow.java @@ -110,7 +110,7 @@ public void run(final FlowTrigger trigger, Map data) { cmd.setUuid(vr.getUuid()); cmd.setRestartDnsmasqAfterNumberOfSIGUSER1(VirtualRouterGlobalConfig.RESTART_DNSMASQ_COUNT.value(Integer.class)); if (timeout == null) { - restf.asyncJsonPost(url, cmd, new JsonAsyncRESTCallback(trigger) { + restf.asyncJsonPost(url, cmd, vrMgr.buildAgentCallbackUrlHeaders(mgmtNic.getIp()), new JsonAsyncRESTCallback(trigger) { @Override public void fail(ErrorCode err) { trigger.fail(err); @@ -131,7 +131,7 @@ public Class getReturnClass() { } }); } else { - restf.asyncJsonPost(url, cmd, new JsonAsyncRESTCallback(trigger) { + restf.asyncJsonPost(url, cmd, vrMgr.buildAgentCallbackUrlHeaders(mgmtNic.getIp()), new JsonAsyncRESTCallback(trigger) { @Override public void fail(ErrorCode err) { trigger.fail(err); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java index b3a7037e4cc..26f1caf8f76 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java @@ -188,7 +188,7 @@ public void run(final FlowTrigger trigger, Map data) { cmd.setParms(parms); - restf.asyncJsonPost(url, cmd, new JsonAsyncRESTCallback(trigger) { + restf.asyncJsonPost(url, cmd, vrMgr.buildAgentCallbackUrlHeaders(mgmtNic.getIp()), new JsonAsyncRESTCallback(trigger) { @Override public void fail(ErrorCode err) { errs.add(err);