diff --git a/network/src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java b/network/src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java index f5717441a68..6a16cee1e3a 100755 --- a/network/src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java +++ b/network/src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java @@ -444,6 +444,7 @@ private void validateIpv6Range(IpRangeInventory ipr) { } L3NetworkVO l3Vo = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, ipr.getL3NetworkUuid()).find(); + validateManagementNetworkIpRangeVersion(l3Vo, IPv6Constants.IPv6); List rangeVOS = Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.l3NetworkUuid, ipr.getL3NetworkUuid()).eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv6).list(); if (rangeVOS != null && !rangeVOS.isEmpty()) { @@ -622,6 +623,7 @@ private void validateAddressPool(IpRangeInventory ipr) { private void validate(IpRangeInventory ipr) { L3NetworkVO l3Vo = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, ipr.getL3NetworkUuid()).find(); + validateManagementNetworkIpRangeVersion(l3Vo, IPv6Constants.IPv4); if (ipr.getIpRangeType() == IpRangeType.AddressPool && l3Vo.getCategory() != L3NetworkCategory.Public) { throw new ApiMessageInterceptionException(argerr(ORG_ZSTACK_NETWORK_L3_10049, "l3 network [uuid %s: name %s] is not a public network, address pool range can not be added", l3Vo.getUuid(), l3Vo.getName())); @@ -769,6 +771,29 @@ private void validate(IpRangeInventory ipr) { } } + private void validateManagementNetworkIpRangeVersion(L3NetworkVO l3Vo, int newIpVersion) { + if (l3Vo.getCategory() != L3NetworkCategory.System) { + return; + } + + int existingIpVersion = newIpVersion == IPv6Constants.IPv4 ? IPv6Constants.IPv6 : IPv6Constants.IPv4; + boolean hasExistingIpRange = Q.New(IpRangeVO.class) + .eq(IpRangeVO_.l3NetworkUuid, l3Vo.getUuid()) + .eq(IpRangeVO_.ipVersion, existingIpVersion) + .isExists(); + if (!hasExistingIpRange) { + return; + } + + throw new ApiMessageInterceptionException(argerr(ORG_ZSTACK_NETWORK_L3_10082, + "management network l3[uuid:%s] cannot mix IPv4 and IPv6 IP ranges; existing IP version is %s, new IP version is %s", + l3Vo.getUuid(), getIpVersionName(existingIpVersion), getIpVersionName(newIpVersion))); + } + + private String getIpVersionName(int ipVersion) { + return ipVersion == IPv6Constants.IPv6 ? "IPv6" : "IPv4"; + } + private void validate(APIAddIpRangeMsg msg) { if (msg.getIpRangeType() == null) { msg.setIpRangeType(IpRangeType.Normal.toString()); diff --git a/test/src/test/groovy/org/zstack/test/integration/network/l3network/ipv6/Ipv6RangeCase.groovy b/test/src/test/groovy/org/zstack/test/integration/network/l3network/ipv6/Ipv6RangeCase.groovy index fe0c8c07818..c805abfc2ba 100644 --- a/test/src/test/groovy/org/zstack/test/integration/network/l3network/ipv6/Ipv6RangeCase.groovy +++ b/test/src/test/groovy/org/zstack/test/integration/network/l3network/ipv6/Ipv6RangeCase.groovy @@ -3,6 +3,8 @@ package org.zstack.test.integration.network.l3network.ipv6 import org.zstack.header.network.service.NetworkServiceType import org.zstack.network.service.eip.EipConstant import org.zstack.network.service.portforwarding.PortForwardingConstant +import org.zstack.sdk.AddIpRangeByNetworkCidrAction +import org.zstack.sdk.AddIpv6RangeByNetworkCidrAction import org.zstack.sdk.ImageInventory import org.zstack.sdk.InstanceOfferingInventory import org.zstack.sdk.IpRangeInventory @@ -15,6 +17,7 @@ import org.zstack.test.integration.network.NetworkTest import org.zstack.test.integration.network.l3network.Env import org.zstack.testlib.EnvSpec import org.zstack.testlib.SubCase +import org.zstack.utils.clouderrorcode.CloudOperationsErrorCode import org.zstack.utils.network.IPv6Constants import static java.util.Arrays.asList @@ -52,6 +55,7 @@ class Ipv6RangeCase extends SubCase { testAttachIpv6RangeAddressMode() testIpv6RangeWith2Ips() testIpv6RangeLastAddress() + testManagementNetworkRejectMixedIpRanges() } } @@ -500,5 +504,55 @@ class Ipv6RangeCase extends SubCase { addressMode = IPv6Constants.Stateful_DHCP } } -} + void testManagementNetworkRejectMixedIpRanges() { + L2NetworkInventory l2 = env.inventoryByName("l2") + + L3NetworkInventory ipv4ManagementL3 = createL3Network { + category = "System" + system = true + l2NetworkUuid = l2.uuid + name = "system-ipv4" + } + + addIpRangeByNetworkCidr { + name = "system-ipv4-range" + l3NetworkUuid = ipv4ManagementL3.uuid + networkCidr = "10.10.10.0/24" + } + + AddIpv6RangeByNetworkCidrAction addIpv6RangeAction = new AddIpv6RangeByNetworkCidrAction() + addIpv6RangeAction.name = "system-ipv6-range" + addIpv6RangeAction.l3NetworkUuid = ipv4ManagementL3.uuid + addIpv6RangeAction.networkCidr = "2005:2001::/64" + addIpv6RangeAction.addressMode = IPv6Constants.Stateful_DHCP + addIpv6RangeAction.sessionId = adminSession() + AddIpv6RangeByNetworkCidrAction.Result addIpv6RangeResult = addIpv6RangeAction.call() + assert addIpv6RangeResult.error != null + assert addIpv6RangeResult.error.globalErrorCode == CloudOperationsErrorCode.ORG_ZSTACK_NETWORK_L3_10082 + + L3NetworkInventory ipv6ManagementL3 = createL3Network { + category = "System" + system = true + l2NetworkUuid = l2.uuid + name = "system-ipv6" + ipVersion = 6 + } + + addIpv6RangeByNetworkCidr { + name = "system-ipv6-range" + l3NetworkUuid = ipv6ManagementL3.uuid + networkCidr = "2006:2001::/64" + addressMode = IPv6Constants.Stateful_DHCP + } + + AddIpRangeByNetworkCidrAction addIpRangeAction = new AddIpRangeByNetworkCidrAction() + addIpRangeAction.name = "system-ipv4-range" + addIpRangeAction.l3NetworkUuid = ipv6ManagementL3.uuid + addIpRangeAction.networkCidr = "10.10.11.0/24" + addIpRangeAction.sessionId = adminSession() + AddIpRangeByNetworkCidrAction.Result addIpRangeResult = addIpRangeAction.call() + assert addIpRangeResult.error != null + assert addIpRangeResult.error.globalErrorCode == CloudOperationsErrorCode.ORG_ZSTACK_NETWORK_L3_10082 + } +} diff --git a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java index 98fb901e470..733b3e482a9 100644 --- a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java +++ b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java @@ -978,6 +978,8 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_NETWORK_L3_10081 = "ORG_ZSTACK_NETWORK_L3_10081"; + public static final String ORG_ZSTACK_NETWORK_L3_10082 = "ORG_ZSTACK_NETWORK_L3_10082"; + public static final String ORG_ZSTACK_SNS_PLATFORM_UNIVERSALSMS_SUPPLIER_EMAY_10000 = "ORG_ZSTACK_SNS_PLATFORM_UNIVERSALSMS_SUPPLIER_EMAY_10000"; public static final String ORG_ZSTACK_CORE_VALIDATION_10000 = "ORG_ZSTACK_CORE_VALIDATION_10000";