diff --git a/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql b/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql index 4a5db563870..b523016aa3d 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql @@ -87,5 +87,3 @@ CALL `cloud`.`INSERT_EXTENSION_DETAIL_IF_NOT_EXISTS`('MaaS', 'orchestratorrequir CALL `cloud`.`IDEMPOTENT_DROP_UNIQUE_KEY`('counter', 'uc_counter__provider__source__value'); CALL `cloud`.`IDEMPOTENT_ADD_UNIQUE_KEY`('cloud.counter', 'uc_counter__provider__source__value__removed', '(provider, source, value, removed)'); - -CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','conserve_mode', 'tinyint(1) unsigned NULL DEFAULT 1'); diff --git a/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql b/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql index d330ecd0c0d..67c8a3c8320 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql @@ -49,3 +49,6 @@ CREATE TABLE IF NOT EXISTS `cloud`.`webhook_filter` ( INDEX `i_webhook_filter__webhook_id`(`webhook_id`), CONSTRAINT `fk_webhook_filter__webhook_id` FOREIGN KEY(`webhook_id`) REFERENCES `webhook`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','conserve_mode', 'tinyint(1) unsigned NULL DEFAULT 0'); +UPDATE `cloud`.`vpc_offerings` SET conserve_mode=1 WHERE name='Default VPC offering'; diff --git a/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java index 5232fbd7f66..93035157e21 100644 --- a/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java @@ -30,6 +30,8 @@ import java.util.Set; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.network.vpc.VpcOfferingVO; +import com.cloud.network.vpc.dao.VpcOfferingDao; import org.apache.commons.lang3.ObjectUtils; import org.springframework.stereotype.Component; @@ -159,6 +161,8 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, IpAddressManager _ipAddrMgr; @Inject RoutedIpv4Manager routedIpv4Manager; + @Inject + VpcOfferingDao vpcOfferingDao; private boolean _elbEnabled = false; static Boolean rulesContinueOnErrFlag = true; @@ -400,6 +404,11 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, throw new InvalidParameterValueException("Unable to create firewall rule as cannot find network by id=" + newRule.getNetworkId()); } boolean isNewRuleOnVpcNetwork = newRuleNetwork.getVpcId() != null; + boolean isVpcConserveModeEnabled = false; + if (isNewRuleOnVpcNetwork) { + VpcOfferingVO vpcOffering = vpcOfferingDao.findById(newRuleNetwork.getVpcId()); + isVpcConserveModeEnabled = vpcOffering != null && vpcOffering.isConserveMode(); + } for (FirewallRuleVO rule : rules) { if (rule.getId() == newRule.getId()) { @@ -448,9 +457,15 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, } } - // Checking if the rule applied is to the same network that is passed in the rule. (except for VPC networks) - if (!isNewRuleOnVpcNetwork && rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) { - throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule " + rule.getXid()); + // Checking if the rule applied is to the same network that is passed in the rule. + // (except for VPCs with conserve mode = true) + if ((!isNewRuleOnVpcNetwork || !isVpcConserveModeEnabled) + && rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) { + String errMsg = String.format("New rule is for a different network than what's specified in rule %s", rule.getXid()); + if (isNewRuleOnVpcNetwork) { + errMsg += String.format(" - VPC id=%s is not using conserve mode", newRuleNetwork.getVpcId()); + } + throw new NetworkRuleConflictException(errMsg); } //Check for the ICMP protocol. This has to be done separately from other protocols as we need to check the ICMP codes and ICMP type also. diff --git a/ui/src/views/network/LoadBalancing.vue b/ui/src/views/network/LoadBalancing.vue index aac72b94184..2e47f702f7b 100644 --- a/ui/src/views/network/LoadBalancing.vue +++ b/ui/src/views/network/LoadBalancing.vue @@ -97,7 +97,7 @@ {{ $t('label.add') }} -