From 1eb69ef2599b74bfe58769c21dfaa6293bec5c77 Mon Sep 17 00:00:00 2001 From: "zhong.zhou" Date: Mon, 15 Jun 2026 18:31:46 +0800 Subject: [PATCH] [volume]: support encrypted data volume creation Resolves: ZSV-12438 Change-Id: I68667a6a776e617866746673697475787a6b6467 --- ...CreateDataVolumeFromVolumeTemplateMsg.java | 12 ++++ ...olumeFromVolumeTemplateMsgDoc_zh_cn.groovy | 9 +++ .../header/volume/APICreateDataVolumeMsg.java | 13 +++++ .../APICreateDataVolumeMsgDoc_zh_cn.groovy | 9 +++ ...CreateDataVolumeFromVolumeTemplateMsg.java | 1 + .../header/volume/CreateDataVolumeMsg.java | 11 ++++ .../zstack/sdk/CreateDataVolumeAction.java | 3 + ...ateDataVolumeFromVolumeTemplateAction.java | 3 + .../storage/volume/VolumeManagerImpl.java | 2 + .../EncryptedDataVolumeCreateApiTest.java | 55 +++++++++++++++++++ 10 files changed, 118 insertions(+) create mode 100644 test/src/test/java/org/zstack/test/unittest/storage/volume/EncryptedDataVolumeCreateApiTest.java diff --git a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsg.java b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsg.java index 84d6f3b95a2..f56af5ccdcb 100755 --- a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsg.java +++ b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsg.java @@ -32,6 +32,8 @@ public class APICreateDataVolumeFromVolumeTemplateMsg extends APICreateMessage i private String primaryStorageUuid; @APIParam(resourceType = HostVO.class, required = false) private String hostUuid; + @APIParam(required = false) + private Boolean encrypted; public String getHostUuid() { return hostUuid; @@ -93,6 +95,16 @@ public void setDiskSize(long diskSize) { } + @Override + public Boolean getEncrypted() { + return encrypted; + } + + @Override + public void setEncrypted(Boolean encrypted) { + this.encrypted = encrypted; + } + public static APICreateDataVolumeFromVolumeTemplateMsg __example__() { APICreateDataVolumeFromVolumeTemplateMsg msg = new APICreateDataVolumeFromVolumeTemplateMsg(); msg.setDescription("dataVolume-from-volume-template"); diff --git a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsgDoc_zh_cn.groovy index ac72519f521..4d94ea17c65 100644 --- a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsgDoc_zh_cn.groovy @@ -66,6 +66,15 @@ doc { optional true since "0.6" } + column { + name "encrypted" + enclosedIn "params" + desc "是否创建加密云盘" + location "body" + type "Boolean" + optional true + since "5.1.0" + } column { name "resourceUuid" enclosedIn "params" diff --git a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java index 87c501b580c..fc9b6d00ddb 100755 --- a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java +++ b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java @@ -70,6 +70,9 @@ public class APICreateDataVolumeMsg extends APICreateMessage implements APIAudit @APIParam(required = false, resourceType = PrimaryStorageVO.class) private String primaryStorageUuid; + @APIParam(required = false) + private Boolean encrypted; + public String getPrimaryStorageUuid() { return primaryStorageUuid; } @@ -110,6 +113,16 @@ public void setDiskSize(long diskSize) { this.diskSize = diskSize; } + @Override + public Boolean getEncrypted() { + return encrypted; + } + + @Override + public void setEncrypted(Boolean encrypted) { + this.encrypted = encrypted; + } + public static APICreateDataVolumeMsg __example__() { APICreateDataVolumeMsg msg = new APICreateDataVolumeMsg(); msg.setResourceUuid(uuid()); diff --git a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsgDoc_zh_cn.groovy index c78b44e2abc..56b3c9c2601 100644 --- a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsgDoc_zh_cn.groovy @@ -57,6 +57,15 @@ doc { optional true since "0.6" } + column { + name "encrypted" + enclosedIn "params" + desc "是否创建加密云盘" + location "body" + type "Boolean" + optional true + since "5.1.0" + } column { name "resourceUuid" enclosedIn "params" diff --git a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeTemplateMsg.java b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeTemplateMsg.java index 06195687e39..26c316445dd 100644 --- a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeTemplateMsg.java +++ b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeTemplateMsg.java @@ -32,6 +32,7 @@ public CreateDataVolumeFromVolumeTemplateMsg(APICreateDataVolumeFromVolumeTempla hostUuid = amsg.getHostUuid(); resourceUuid = amsg.getResourceUuid(); accountUuid = amsg.getSession().getAccountUuid(); + encrypted = amsg.getEncrypted(); apiMsg = amsg; } diff --git a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeMsg.java b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeMsg.java index 833df491428..5bb159ea602 100644 --- a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeMsg.java +++ b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeMsg.java @@ -10,6 +10,7 @@ public class CreateDataVolumeMsg extends NeedReplyMessage implements VolumeCreat private String primaryStorageUuid; private String accountUuid; private String resourceUuid; + private Boolean encrypted; private APICreateDataVolumeMsg apiMsg; public String getPrimaryStorageUuid() { @@ -75,4 +76,14 @@ public APICreateDataVolumeMsg getApiMsg() { public void setApiMsg(APICreateDataVolumeMsg apiMsg) { this.apiMsg = apiMsg; } + + @Override + public Boolean getEncrypted() { + return encrypted; + } + + @Override + public void setEncrypted(Boolean encrypted) { + this.encrypted = encrypted; + } } diff --git a/sdk/src/main/java/org/zstack/sdk/CreateDataVolumeAction.java b/sdk/src/main/java/org/zstack/sdk/CreateDataVolumeAction.java index 1284384357e..8834e8b5a80 100644 --- a/sdk/src/main/java/org/zstack/sdk/CreateDataVolumeAction.java +++ b/sdk/src/main/java/org/zstack/sdk/CreateDataVolumeAction.java @@ -40,6 +40,9 @@ public Result throwExceptionIfError() { @Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false) public java.lang.String primaryStorageUuid; + @Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.Boolean encrypted; + @Param(required = false) public java.lang.String resourceUuid; diff --git a/sdk/src/main/java/org/zstack/sdk/CreateDataVolumeFromVolumeTemplateAction.java b/sdk/src/main/java/org/zstack/sdk/CreateDataVolumeFromVolumeTemplateAction.java index 85997ccdbde..290ab2408ec 100644 --- a/sdk/src/main/java/org/zstack/sdk/CreateDataVolumeFromVolumeTemplateAction.java +++ b/sdk/src/main/java/org/zstack/sdk/CreateDataVolumeFromVolumeTemplateAction.java @@ -40,6 +40,9 @@ public Result throwExceptionIfError() { @Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false) public java.lang.String hostUuid; + @Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.Boolean encrypted; + @Param(required = false) public java.lang.String resourceUuid; diff --git a/storage/src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java b/storage/src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java index c7ebab3d724..aa4a879fd5c 100755 --- a/storage/src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java +++ b/storage/src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java @@ -1147,6 +1147,7 @@ private void handle(CreateDataVolumeMsg msg) { vo.setType(VolumeType.Data); vo.setStatus(VolumeStatus.NotInstantiated); vo.setAccountUuid(msg.getAccountUuid()); + vo.setEncrypted(Boolean.TRUE.equals(msg.getEncrypted())); if (msg.getSystemTags() != null) { Iterator iterators = msg.getSystemTags().iterator(); @@ -1240,6 +1241,7 @@ private void handle(APICreateDataVolumeMsg msg) { cmsg.setDiskOfferingUuid(msg.getDiskOfferingUuid()); cmsg.setPrimaryStorageUuid(msg.getPrimaryStorageUuid()); cmsg.setDescription(msg.getDescription()); + cmsg.setEncrypted(msg.getEncrypted()); cmsg.setApiMsg(msg); bus.makeLocalServiceId(cmsg, VolumeConstant.SERVICE_ID); bus.send(cmsg, new CloudBusCallBack(msg) { diff --git a/test/src/test/java/org/zstack/test/unittest/storage/volume/EncryptedDataVolumeCreateApiTest.java b/test/src/test/java/org/zstack/test/unittest/storage/volume/EncryptedDataVolumeCreateApiTest.java new file mode 100644 index 00000000000..6b16cb6fe0f --- /dev/null +++ b/test/src/test/java/org/zstack/test/unittest/storage/volume/EncryptedDataVolumeCreateApiTest.java @@ -0,0 +1,55 @@ +package org.zstack.test.unittest.storage.volume; + +import org.junit.Assert; +import org.junit.Test; +import org.zstack.header.volume.APICreateDataVolumeFromVolumeTemplateMsg; +import org.zstack.header.volume.APICreateDataVolumeMsg; +import org.zstack.header.volume.CreateDataVolumeFromVolumeTemplateMsg; +import org.zstack.header.volume.CreateDataVolumeMsg; +import org.zstack.header.volume.VolumeCreateMessage; +import org.zstack.sdk.CreateDataVolumeAction; +import org.zstack.sdk.CreateDataVolumeFromVolumeTemplateAction; + +import java.lang.reflect.Field; + +public class EncryptedDataVolumeCreateApiTest { + @Test + public void testSdkCreateDataVolumeActionExposesEncryptedParameter() throws Exception { + Field encrypted = CreateDataVolumeAction.class.getField("encrypted"); + Assert.assertEquals(Boolean.class, encrypted.getType()); + } + + @Test + public void testSdkCreateDataVolumeFromVolumeTemplateActionExposesEncryptedParameter() throws Exception { + Field encrypted = CreateDataVolumeFromVolumeTemplateAction.class.getField("encrypted"); + Assert.assertEquals(Boolean.class, encrypted.getType()); + } + + @Test + public void testApiCreateDataVolumeMessageCarriesEncryptedFlag() { + VolumeCreateMessage msg = new APICreateDataVolumeMsg(); + msg.setEncrypted(Boolean.TRUE); + Assert.assertEquals(Boolean.TRUE, msg.getEncrypted()); + } + + @Test + public void testCreateDataVolumeMessageCarriesEncryptedFlag() { + CreateDataVolumeMsg msg = new CreateDataVolumeMsg(); + msg.setEncrypted(Boolean.TRUE); + Assert.assertEquals(Boolean.TRUE, msg.getEncrypted()); + } + + @Test + public void testApiCreateDataVolumeFromTemplateMessageCarriesEncryptedFlag() { + VolumeCreateMessage msg = new APICreateDataVolumeFromVolumeTemplateMsg(); + msg.setEncrypted(Boolean.TRUE); + Assert.assertEquals(Boolean.TRUE, msg.getEncrypted()); + } + + @Test + public void testCreateDataVolumeFromTemplateMessageCarriesEncryptedFlag() { + CreateDataVolumeFromVolumeTemplateMsg msg = new CreateDataVolumeFromVolumeTemplateMsg(); + msg.setEncrypted(Boolean.TRUE); + Assert.assertEquals(Boolean.TRUE, msg.getEncrypted()); + } +}