This is an automated email from the ASF dual-hosted git repository. Pearl1594 pushed a commit to branch netris-improvements in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit b66eb66623ee9bfe84e57a1163c1ffa296511e66 Author: Pearl Dsilva <[email protected]> AuthorDate: Mon Jul 6 09:16:41 2026 -0400 Add check for vnet name length and cleanup vpc and vnet resources on failure of creation of allocation * Netris - Support NAT, PF for Secondary IP * Allow PF rules to be correctly created on secondary IP of a VM on netris * unique static nat names on netris by adding public IP - handle backward compatibility --------- Co-authored-by: Pearl Dsilva <[email protected]> * Netris - Support for L2 networks * Add support for L2 networks in Netris * remove the need to add connectivity to identify netris provider, remove changes to ui and create net offering * create vpc network and use it for l2 networks * dont fail if deletion on netris doesnt succeed * remove connectivity capability * update vpc name when l2 name is updated --------- Co-authored-by: Pearl Dsilva <[email protected]> * Netris - CKS support Co-authored-by: Pearl Dsilva <[email protected]> * Netris - Enable Global Routing Flag for NATTED Dual-Stack VPCs * Set globalRouting = true, when network offering is NATTED, dual-stack * update global routing based on routing mode and ip protocol type --------- Co-authored-by: Pearl Dsilva <[email protected]> Co-authored-by: nvazquez <[email protected]> * Netris - Fix allocate vnets with the correct account ID so that release succeeds on network deletion * Fix allocate vnets with the correct account ID so that release succeeds on network deletion * add fix for vpc tiers as well * move entire vnet cleanup logic to trash from shutdown, so that it works for all network types for netris * cleanup vnets when reservation id is null --------- Co-authored-by: Pearl Dsilva <[email protected]> * Netris - Add support to include VPN service for NATTED Netris offerings * Add support to include VPN service for NATTED Netris offerings * missing changes of global routing * Remove extra space --------- Co-authored-by: Pearl Dsilva <[email protected]> Co-authored-by: nvazquez <[email protected]> * Netris - Support Redundant Virtual Routers for Netris VPC networks * Add support for redundant routers for Netris VPC networks * address comment * default null network mode to natted for netris * preventing vpc and ipam creation if already exists --------- Co-authored-by: Pearl Dsilva <[email protected]> * Netris - Enable autoscaling groups for Netris network offerings * Enable autoscaling groups for Netris network offerings * Fix UI loading for services when network mode changes for external providers and show vm autoscaling always set to true / non-editable for netris when LB is selected i.e, natted mode * Revert removed comment --------- Co-authored-by: Pearl Dsilva <[email protected]> Co-authored-by: nvazquez <[email protected]> * merge conflict * systemvm: fix VPC VPN issue when network id is bigger than 1000 on Netris * show networks for vnf nic mappings * Add a check to prevent re-adding existing ACLs * Add a check to prevent re-adding existing ACLs * change message compare statement * Add check for vnet name length and cleanup vpc and vnet resources on failure of creation of allocation * add name length validation to update path --------- Co-authored-by: Pearl Dsilva <[email protected]> Co-authored-by: nvazquez <[email protected]> Co-authored-by: Wei Zhou <[email protected]> --- .../resource/NetrisResourceObjectUtils.java | 12 ++++ .../cloudstack/service/NetrisApiClientImpl.java | 66 +++++++++++++++++++--- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResourceObjectUtils.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResourceObjectUtils.java index d67054398f6..5b7b9d8973d 100644 --- a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResourceObjectUtils.java +++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResourceObjectUtils.java @@ -16,6 +16,7 @@ // under the License. package org.apache.cloudstack.resource; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.offering.NetworkOffering; import org.apache.cloudstack.agent.api.NetrisCommand; import org.apache.commons.lang3.ArrayUtils; @@ -24,6 +25,8 @@ import java.util.Objects; public class NetrisResourceObjectUtils { + public static final int NETRIS_VNET_NAME_MAX_LENGTH = 50; + public enum NetrisObjectType { VPC, IPAM_ALLOCATION, IPAM_SUBNET, VNET, SNAT, STATICNAT, DNAT, STATICROUTE, ACL, LB } @@ -102,6 +105,15 @@ public class NetrisResourceObjectUtils { return stringBuilder.toString(); } + public static void validateNetrisVnetNameLength(String netrisVnetName, String networkName) { + if (netrisVnetName.length() > NETRIS_VNET_NAME_MAX_LENGTH) { + throw new InvalidParameterValueException( + String.format("The resulting Netris vNet name '%s' exceeds the maximum allowed length of %d characters (actual: %d). " + + "Please use a shorter network name (current: '%s')", + netrisVnetName, NETRIS_VNET_NAME_MAX_LENGTH, netrisVnetName.length(), networkName)); + } + } + public static NetworkOffering.NetworkMode getNetworkMode(NetworkOffering.NetworkMode mode) { return Objects.isNull(mode) ? NetworkOffering.NetworkMode.NATTED : mode; } diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java index cb4ed59333b..bc6dd912be5 100644 --- a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java +++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java @@ -345,8 +345,19 @@ public class NetrisApiClientImpl implements NetrisApiClient { String netrisIpamAllocationName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_ALLOCATION, cmd.getCidr()); String vpcCidr = cmd.getCidr(); - InlineResponse2004Data createdIpamAllocation = createIpamAllocationInternal(netrisIpamAllocationName, vpcCidr, createdVpc.getData()); - return createdIpamAllocation != null; + VPCListing vpcListing = createdVpc.getData(); + InlineResponse2004Data createdIpamAllocation = createIpamAllocationInternal(netrisIpamAllocationName, vpcCidr, vpcListing); + if (createdIpamAllocation == null) { + logger.warn("IPAM Allocation creation failed for VPC {}, rolling back VPC", netrisVpcName); + try { + deleteVpcInternal(vpcListing); + } catch (Exception e) { + logger.error("Failed to rollback VPC {} after IPAM Allocation failure - manual cleanup may be required: {}", + netrisVpcName, e.getMessage()); + } + return false; + } + return true; } @Override @@ -1240,8 +1251,13 @@ public class NetrisApiClientImpl implements NetrisApiClient { } String netrisV6Cidr = cmd.getIpv6Cidr(); + VPCListing associatedVpc = null; + String netrisSubnetName = null; + String netrisV6IpamAllocationName = null; + String netrisV6SubnetName = null; + boolean createdIpv6Allocation = false; + try { - VPCListing associatedVpc; if (isL2) { associatedVpc = getOrCreateL2Vpc(cmd); if (associatedVpc == null) { @@ -1264,19 +1280,22 @@ public class NetrisApiClientImpl implements NetrisApiClient { vNetName = String.format("N%s-%s", networkId, networkName); } String netrisVnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VNET, vNetName); + NetrisResourceObjectUtils.validateNetrisVnetNameLength(netrisVnetName, networkName); if (!isL2) { - String netrisSubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(cmd.getVpcId()), vnetCidr); + netrisSubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(cmd.getVpcId()), vnetCidr); createIpamSubnetInternal(netrisSubnetName, vnetCidr, SubnetBody.PurposeEnum.COMMON, associatedVpc, ipv4GlobalRouting); if (Objects.nonNull(netrisV6Cidr)) { - String netrisV6IpamAllocationName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_ALLOCATION, netrisV6Cidr); - String netrisV6SubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(cmd.getVpcId()), netrisV6Cidr); + netrisV6IpamAllocationName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_ALLOCATION, netrisV6Cidr); + netrisV6SubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(cmd.getVpcId()), netrisV6Cidr); BigDecimal ipamAllocationId = getIpamAllocationIdByPrefixAndVpc(netrisV6Cidr, associatedVpc); if (ipamAllocationId == null) { - InlineResponse2004Data createdIpamAllocation = createIpamAllocationInternal(netrisV6IpamAllocationName, netrisV6Cidr, associatedVpc); - if (Objects.isNull(createdIpamAllocation)) { + InlineResponse2004Data createdIpamAllocationData = createIpamAllocationInternal(netrisV6IpamAllocationName, netrisV6Cidr, associatedVpc); + if (Objects.isNull(createdIpamAllocationData)) { + rollbackVnetResources(associatedVpc, netrisSubnetName, null, null, networkName); throw new CloudRuntimeException(String.format("Failed to create Netris IPAM Allocation %s for VPC %s", netrisV6IpamAllocationName, associatedVpc.getName())); } + createdIpv6Allocation = true; } createIpamSubnetInternal(netrisV6SubnetName, netrisV6Cidr, SubnetBody.PurposeEnum.COMMON, associatedVpc, ipv6GlobalRouting); } @@ -1287,9 +1306,17 @@ public class NetrisApiClientImpl implements NetrisApiClient { if (vnetResponse == null || !vnetResponse.isIsSuccess()) { String reason = vnetResponse == null ? "Empty response" : "Operation failed on Netris"; logger.debug("The Netris vNet creation {} failed: {}", vNetName, reason); + if (!isL2) { + rollbackVnetResources(associatedVpc, netrisSubnetName, netrisV6SubnetName, + createdIpv6Allocation ? netrisV6IpamAllocationName : null, networkName); + } return false; } - } catch (ApiException e) { + } catch (Exception e) { + if (!isL2 && associatedVpc != null) { + rollbackVnetResources(associatedVpc, netrisSubnetName, netrisV6SubnetName, + createdIpv6Allocation ? netrisV6IpamAllocationName : null, networkName); + } throw new CloudRuntimeException(String.format("Failed to create Netris vNet %s", networkName), e); } return true; @@ -1324,6 +1351,7 @@ public class NetrisApiClientImpl implements NetrisApiClient { String netrisVnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VNET, vNetName) ; String prevNetrisVnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VNET, prevVnetName) ; + NetrisResourceObjectUtils.validateNetrisVnetNameLength(netrisVnetName, networkName); VnetResAddBody response = updateVnetInternal(associatedVpc, netrisVnetName, prevNetrisVnetName); if (response == null || !response.isIsSuccess()) { String reason = response == null ? "Empty response" : "Operation failed on Netris"; @@ -1958,6 +1986,26 @@ public class NetrisApiClientImpl implements NetrisApiClient { } } + private void rollbackVnetResources(VPCListing associatedVpc, String ipv4SubnetName, String ipv6SubnetName, + String ipv6AllocationName, String networkName) { + logger.warn("Rolling back Netris resources created for network {}", networkName); + FilterByVpc vpcFilter = new FilterByVpc(); + vpcFilter.add(associatedVpc.getId()); + try { + if (ipv6SubnetName != null) { + deleteSubnetInternal(vpcFilter, null, ipv6SubnetName); + } + if (ipv6AllocationName != null) { + deleteVpcIpamAllocationInternal(associatedVpc, ipv6AllocationName); + } + if (ipv4SubnetName != null) { + deleteSubnetInternal(vpcFilter, null, ipv4SubnetName); + } + } catch (Exception e) { + logger.error("Failed to rollback Netris resources for network {} - manual cleanup may be required: {}", networkName, e.getMessage()); + } + } + private SubnetBody getIpamSubnetBody(VPCListing vpc, SubnetBody.PurposeEnum purpose, String subnetName, String subnetPrefix, Boolean isGlobalRouting) { SubnetBody subnetBody = new SubnetBody(); subnetBody.setName(subnetName);
