diff --git a/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java b/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java index 1537ed30318..e806761229d 100755 --- a/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java @@ -152,6 +152,10 @@ private ZoneInventory createZoneFromApiMessage(APICreateZoneMsg msg) { new SQLBatch() { @Override protected void scripts() { + if (msg.getDefault() == null && !q(ZoneVO.class).isExists()) { + finalVO.setDefault(true); + } + if (finalVO.isDefault()) { sql(ZoneVO.class) .set(ZoneVO_.isDefault, false) @@ -181,7 +185,7 @@ private void createDefaultManagementNetworkIpVersionTagIfAbsent(String zoneUuid) } private void createZone(APICreateZoneMsg msg, ReturnValueCompletion completion) { - if (msg.getDefault() == null || !msg.getDefault()) { + if (msg.getDefault() != null && !msg.getDefault()) { completion.success(createZoneFromApiMessage(msg)); return; } diff --git a/conf/db/upgrade/V5.5.28__schema.sql b/conf/db/upgrade/V5.5.28__schema.sql index b30064a2a08..cc96f27fdf0 100644 --- a/conf/db/upgrade/V5.5.28__schema.sql +++ b/conf/db/upgrade/V5.5.28__schema.sql @@ -199,6 +199,38 @@ WHERE NOT EXISTS ( AND st.tag LIKE 'managementNetwork::ipVersion::%' ); +-- ZSTAC-75952: backfill one default zone for deployments affected by zone creation without isDefault. +DROP PROCEDURE IF EXISTS backfill_default_zone_if_absent; +DELIMITER $$ +CREATE PROCEDURE backfill_default_zone_if_absent() +BEGIN + DECLARE default_zone_count BIGINT DEFAULT 0; + DECLARE first_zone_uuid VARCHAR(32) DEFAULT NULL; + + SELECT COUNT(*) INTO default_zone_count + FROM `zstack`.`ZoneVO` + WHERE `isDefault` = 1; + + IF default_zone_count = 0 THEN + SET first_zone_uuid = ( + SELECT `uuid` + FROM `zstack`.`ZoneVO` + ORDER BY `createDate` ASC, `uuid` ASC + LIMIT 1 + ); + + IF first_zone_uuid IS NOT NULL THEN + UPDATE `zstack`.`ZoneEO` + SET `isDefault` = 1 + WHERE `uuid` = first_zone_uuid; + END IF; + END IF; +END $$ +DELIMITER ; + +CALL backfill_default_zone_if_absent(); +DROP PROCEDURE IF EXISTS backfill_default_zone_if_absent; + ALTER TABLE `zstack`.`ConsoleProxyAgentVO` ADD COLUMN `consoleProxyOverriddenIpv4` varchar(255) DEFAULT NULL; ALTER TABLE `zstack`.`ConsoleProxyAgentVO` ADD COLUMN `consoleProxyOverriddenIpv6` varchar(255) DEFAULT NULL; diff --git a/test/src/test/groovy/org/zstack/test/integration/compute/ZoneCase.groovy b/test/src/test/groovy/org/zstack/test/integration/compute/ZoneCase.groovy index 67e86160548..c8a864c8c41 100644 --- a/test/src/test/groovy/org/zstack/test/integration/compute/ZoneCase.groovy +++ b/test/src/test/groovy/org/zstack/test/integration/compute/ZoneCase.groovy @@ -10,12 +10,13 @@ import org.zstack.testlib.EnvSpec import org.zstack.testlib.SubCase /** - * 1. test create zone as default zone - * 2. test batch create zone as default zone - * 3. test update zone to default zone - * 4. test batch update zone to default zone - * 5. test query default zone - * 6. test delete default zone + * 1. test first created zone defaults to default zone + * 2. test create zone as default zone + * 3. test batch create zone as default zone + * 4. test update zone to default zone + * 5. test batch update zone to default zone + * 6. test query default zone + * 7. test delete default zone */ class ZoneCase extends SubCase { EnvSpec env @@ -33,6 +34,7 @@ class ZoneCase extends SubCase { @Override void test() { env.create { + testFirstCreatedZoneDefaultsToDefaultZone() testCreateZoneAsDefaultZone() testBatchCreateZoneAsDefaultZone() testUpdateZoneToDefaultZone() @@ -48,6 +50,22 @@ class ZoneCase extends SubCase { env.delete() } + void testFirstCreatedZoneDefaultsToDefaultZone() { + ZoneInventory zone = createZone { + name = "first-zone" + description = "first-zone" + } as ZoneInventory + + assert zone.isDefault + assert Q.New(ZoneVO.class) + .eq(ZoneVO_.uuid, zone.uuid) + .eq(ZoneVO_.isDefault, true) + .isExists() + assert Q.New(ZoneVO.class) + .eq(ZoneVO_.isDefault, true) + .count() == 1 + } + void testCreateZoneAsDefaultZone() { ZoneInventory zone = createZone { name = "zone1"