Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions conf/db/zsv/V5.1.0__schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ ALTER TABLE `zstack`.`VolumeEO` ADD COLUMN `encrypted` tinyint(1) NOT NULL DEFAU
ALTER TABLE `zstack`.`VolumeSnapshotEO` ADD COLUMN `encrypted` tinyint(1) NOT NULL DEFAULT 0;
ALTER TABLE `zstack`.`VolumeBackupVO` ADD COLUMN `encrypted` tinyint(1) NOT NULL DEFAULT 0;
ALTER TABLE `zstack`.`VmInstanceEO` ADD COLUMN `vmEncryption` tinyint(1) NOT NULL DEFAULT 0;
ALTER TABLE `zstack`.`LunVO` ADD COLUMN `encrypted` tinyint(1) NOT NULL DEFAULT 0;
ALTER TABLE `zstack`.`ScsiLunVmInstanceRefVO` ADD COLUMN `encrypted` tinyint(1) NOT NULL DEFAULT 0;
Comment on lines +8 to +9

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

NOT NULL 列缺少显式历史数据处理步骤(升级风险)

Line 8 和 Line 9 直接新增 NOT NULL 列,但当前迁移未体现“先处理历史数据再收紧约束”的步骤。按仓库 SQL 规范,这里需要通过存储过程或函数(或等价回填步骤)显式处理历史数据,再改为 NOT NULL

🔧 建议迁移方式(示例)
-ALTER TABLE `zstack`.`LunVO` ADD COLUMN `encrypted` tinyint(1) NOT NULL DEFAULT 0;
-ALTER TABLE `zstack`.`ScsiLunVmInstanceRefVO` ADD COLUMN `encrypted` tinyint(1) NOT NULL DEFAULT 0;
+ALTER TABLE `zstack`.`LunVO` ADD COLUMN `encrypted` tinyint(1) DEFAULT NULL;
+ALTER TABLE `zstack`.`ScsiLunVmInstanceRefVO` ADD COLUMN `encrypted` tinyint(1) DEFAULT NULL;
+
+-- 使用存储过程/函数(或等价批处理)回填历史数据
+UPDATE `zstack`.`LunVO` SET `encrypted` = 0 WHERE `encrypted` IS NULL;
+UPDATE `zstack`.`ScsiLunVmInstanceRefVO` SET `encrypted` = 0 WHERE `encrypted` IS NULL;
+
+ALTER TABLE `zstack`.`LunVO` MODIFY COLUMN `encrypted` tinyint(1) NOT NULL DEFAULT 0;
+ALTER TABLE `zstack`.`ScsiLunVmInstanceRefVO` MODIFY COLUMN `encrypted` tinyint(1) NOT NULL DEFAULT 0;

As per coding guidelines: "When NOT NULL exists, must use stored procedure or other functions to process historical data, this is very very important".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@conf/db/zsv/V5.1.0__schema.sql` around lines 8 - 9, The migration is adding
NOT NULL columns (encrypted) directly to LunVO and ScsiLunVmInstanceRefVO tables
without explicitly processing historical data first. According to repository
guidelines, you must first add the columns as nullable, then use a stored
procedure or explicit UPDATE statement to process and populate historical data
for existing rows, and finally alter the columns to be NOT NULL. Break the
current migration into three distinct steps: (1) add the encrypted column as
nullable with a default value to LunVO and ScsiLunVmInstanceRefVO, (2) create
and execute a stored procedure or UPDATE statement to handle historical data
backfill, and (3) alter both columns to NOT NULL after the data is processed.

Source: Coding guidelines


UPDATE `zstack`.`VolumeBackupVO` vb
SET vb.`encrypted` = 1
Expand All @@ -31,6 +33,13 @@ SELECT uuid, name, description, type, volumeUuid, format, treeUuid, parentUuid,
FROM `zstack`.`VolumeSnapshotEO`
WHERE deleted IS NULL;

DROP VIEW IF EXISTS `zstack`.`ScsiLunVO`;
CREATE VIEW `zstack`.`ScsiLunVO` AS
SELECT uuid, name, wwid, vendor, model, wwn, serial, type, hctl, path, size,
state, source, multipathDeviceUuid, encrypted, createDate, lastOpDate
FROM `zstack`.`LunVO`
WHERE source IN ('iSCSI', 'fiberChannel');

DROP VIEW IF EXISTS `zstack`.`VmInstanceVO`;
CREATE VIEW `zstack`.`VmInstanceVO` AS
SELECT uuid, name, description, zoneUuid, clusterUuid, imageUuid, hostUuid, internalId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public Result throwExceptionIfError() {
@Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false)
public boolean disableMultiPathAttach = false;

@Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false)
public java.lang.Boolean encrypted;

@Param(required = false)
public java.util.List systemTags;

Expand Down
8 changes: 8 additions & 0 deletions sdk/src/main/java/org/zstack/sdk/LunInventory.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ public java.lang.String getSource() {
return this.source;
}

public boolean encrypted;
public void setEncrypted(boolean encrypted) {
this.encrypted = encrypted;
}
public boolean getEncrypted() {
return this.encrypted;
}

public java.sql.Timestamp createDate;
public void setCreateDate(java.sql.Timestamp createDate) {
this.createDate = createDate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,12 @@ public boolean getAttachMultipath() {
return this.attachMultipath;
}

public boolean encrypted;
public void setEncrypted(boolean encrypted) {
this.encrypted = encrypted;
}
public boolean getEncrypted() {
return this.encrypted;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,31 @@ public class VolumeEncryptedSecretHelper {
private PluginRegistry pluginRegistry;

public EncryptedResourceKeyManager.ResourceKeyResult materializeDek(String volUuid, String kpUuid) {
return materializeResourceDek(volUuid, VolumeVO.class.getSimpleName(), kpUuid, "instantiate-volume");
}

public EncryptedResourceKeyManager.ResourceKeyResult materializeResourceDek(String resourceUuid, String resourceType,
String kpUuid, String purpose) {
EncryptedResourceKeyManager.GetOrCreateResourceKeyContext ctx =
new EncryptedResourceKeyManager.GetOrCreateResourceKeyContext();
ctx.setResourceUuid(volUuid);
ctx.setResourceType(VolumeVO.class.getSimpleName());
ctx.setResourceUuid(resourceUuid);
ctx.setResourceType(resourceType);
ctx.setKeyProviderUuid(kpUuid);
ctx.setPurpose("instantiate-volume");
ctx.setPurpose(purpose);

FutureReturnValueCompletion completion = new FutureReturnValueCompletion(null);
encryptedResourceKeyManager.getOrCreateKey(ctx, completion);
completion.await(TimeUnit.MINUTES.toMillis(5));
if (!completion.isSuccess()) {
throw new OperationFailureException(operr(
"failed to materialize encryption key for volume[uuid:%s]", volUuid)
"failed to materialize encryption key for resource[type:%s, uuid:%s]", resourceType, resourceUuid)
.withCause(completion.getErrorCode()));
}

EncryptedResourceKeyManager.ResourceKeyResult result = completion.getResult();
if (result == null || StringUtils.isBlank(result.getDekBase64())) {
throw new OperationFailureException(operr(
"key manager returned empty DEK for encrypted volume[uuid:%s]", volUuid));
"key manager returned empty DEK for encrypted resource[type:%s, uuid:%s]", resourceType, resourceUuid));
}
return result;
}
Expand Down Expand Up @@ -257,55 +262,67 @@ public String defineLibvirtSecretOnHost(String hostUuid, String vmUuid, String v

public String defineLibvirtSecretOnHost(String hostUuid, String vmUuid, String volUuid,
String dekBase64, Integer keyVersion, String secretUuid) {
if (StringUtils.isBlank(hostUuid) || StringUtils.isBlank(volUuid) ||
StringUtils.isBlank(dekBase64) || keyVersion == null) {
String description = String.format("LUKS DEK for volume %s", volUuid);
String usageInstance = KVMConstant.volumeSecretUsageInstance(volUuid);
String result = defineLibvirtSecretForResourceOnHost(hostUuid, vmUuid, volUuid, dekBase64,
keyVersion, secretUuid, "volume", usageInstance, description);

// Remember which host now owns this volume's libvirt secret so that
// expunge can clean it up later, even if the owning VM is gone by then.
// recreate=true overwrites any stale tag from a previous host.
try {
SystemTagCreator tc = VolumeSystemTags.VOLUME_LIBVIRT_SECRET_HOST.newSystemTagCreator(volUuid);
tc.setTagByTokens(Collections.singletonMap(
VolumeSystemTags.VOLUME_LIBVIRT_SECRET_HOST_TOKEN, hostUuid));
tc.inherent = false;
tc.recreate = true;
tc.create();
} catch (RuntimeException tagEx) {
// Tag write failure must not break the actual secret define -- the
// define already succeeded, the tag is for cleanup bookkeeping only.
logger.warn(String.format(
"failed to stamp VOLUME_LIBVIRT_SECRET_HOST tag on volume[uuid:%s] for host[uuid:%s]: %s",
volUuid, hostUuid, tagEx.getMessage()));
}

return result;
}

public String defineLibvirtSecretForResourceOnHost(String hostUuid, String vmUuid, String resourceUuid,
String dekBase64, Integer keyVersion, String secretUuid,
String purpose, String usageInstance, String description) {
if (StringUtils.isBlank(hostUuid) || StringUtils.isBlank(resourceUuid) ||
StringUtils.isBlank(dekBase64) || keyVersion == null ||
StringUtils.isBlank(purpose) || StringUtils.isBlank(usageInstance)) {
throw new OperationFailureException(operr(
"defineLibvirtSecretOnHost requires non-blank hostUuid, volUuid, dekBase64 and a non-null keyVersion"));
"defineLibvirtSecretForResourceOnHost requires non-blank hostUuid, resourceUuid, dekBase64, purpose, usageInstance and a non-null keyVersion"));
}
SecretHostDefineMsg defineMsg = new SecretHostDefineMsg();
defineMsg.setHostUuid(hostUuid);
defineMsg.setVmUuid(vmUuid);
defineMsg.setDekBase64(dekBase64);
defineMsg.setPurpose("volume");
defineMsg.setPurpose(purpose);
defineMsg.setKeyVersion(keyVersion);
defineMsg.setUsageInstance(KVMConstant.volumeSecretUsageInstance(volUuid));
defineMsg.setUsageInstance(usageInstance);
if (StringUtils.isNotBlank(secretUuid)) {
defineMsg.setSecretUuid(secretUuid);
}
defineMsg.setDescription(String.format("LUKS DEK for volume %s", volUuid));
defineMsg.setDescription(description);
bus.makeTargetServiceIdByResourceUuid(defineMsg, HostConstant.SERVICE_ID, hostUuid);

MessageReply reply = bus.call(defineMsg);
if (!reply.isSuccess()) {
throw new OperationFailureException(operr(
"failed to ensure libvirt secret for encrypted volume[uuid:%s] on host[uuid:%s]",
volUuid, hostUuid).withCause(reply.getError()));
"failed to ensure libvirt secret for encrypted resource[uuid:%s] on host[uuid:%s]",
resourceUuid, hostUuid).withCause(reply.getError()));
}
SecretHostDefineReply r = reply.castReply();
if (StringUtils.isBlank(r.getSecretUuid())) {
throw new OperationFailureException(operr(
"ensure volume LUKS secret on host succeeded but secretUuid is empty, host[uuid:%s]",
"ensure resource LUKS secret on host succeeded but secretUuid is empty, host[uuid:%s]",
hostUuid));
}

// Remember which host now owns this volume's libvirt secret so that
// expunge can clean it up later, even if the owning VM is gone by then.
// recreate=true overwrites any stale tag from a previous host.
try {
SystemTagCreator tc = VolumeSystemTags.VOLUME_LIBVIRT_SECRET_HOST.newSystemTagCreator(volUuid);
tc.setTagByTokens(Collections.singletonMap(
VolumeSystemTags.VOLUME_LIBVIRT_SECRET_HOST_TOKEN, hostUuid));
tc.inherent = false;
tc.recreate = true;
tc.create();
} catch (RuntimeException tagEx) {
// Tag write failure must not break the actual secret define -- the
// define already succeeded, the tag is for cleanup bookkeeping only.
logger.warn(String.format(
"failed to stamp VOLUME_LIBVIRT_SECRET_HOST tag on volume[uuid:%s] for host[uuid:%s]: %s",
volUuid, hostUuid, tagEx.getMessage()));
}

return r.getSecretUuid();
}

Expand All @@ -327,19 +344,29 @@ public String defineSecretFromBinding(String hostUuid, String vmUuid, String vol
}

public String defineSecretFromBinding(String hostUuid, String vmUuid, String volUuid, String kpUuid, String secretUuid) {
return defineSecretFromBindingForResource(hostUuid, vmUuid, volUuid, VolumeVO.class.getSimpleName(), kpUuid,
"volume", KVMConstant.volumeSecretUsageInstance(volUuid), secretUuid);
}

public String defineSecretFromBindingForResource(String hostUuid, String vmUuid, String resourceUuid,
String resourceType, String kpUuid, String secretPurpose,
String usageInstance, String secretUuid) {
if (StringUtils.isBlank(kpUuid)) {
throw new OperationFailureException(operr(
"encrypted volume[uuid:%s] has no key provider binding; cannot define libvirt secret on host[uuid:%s]",
volUuid, hostUuid));
"encrypted resource[type:%s, uuid:%s] has no key provider binding; cannot define libvirt secret on host[uuid:%s]",
resourceType, resourceUuid, hostUuid));
}
EncryptedResourceKeyManager.ResourceKeyResult keyResult = materializeDek(volUuid, kpUuid);
EncryptedResourceKeyManager.ResourceKeyResult keyResult = materializeResourceDek(resourceUuid, resourceType,
kpUuid, "define-" + secretPurpose + "-secret");
String dekBase64 = keyResult.getDekBase64();
if (StringUtils.isBlank(dekBase64)) {
throw new OperationFailureException(operr(
"encrypted volume[uuid:%s]: key manager returned empty DEK for libvirt secret",
volUuid));
"encrypted resource[type:%s, uuid:%s]: key manager returned empty DEK for libvirt secret",
resourceType, resourceUuid));
}
return defineLibvirtSecretOnHost(hostUuid, vmUuid, volUuid, dekBase64, keyResult.getKeyVersion(), secretUuid);
String description = String.format("LUKS DEK for %s %s", resourceType, resourceUuid);
return defineLibvirtSecretForResourceOnHost(hostUuid, vmUuid, resourceUuid, dekBase64,
keyResult.getKeyVersion(), secretUuid, secretPurpose, usageInstance, description);
}
Comment on lines +351 to 370

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

在参数合法性未确认前就物化 DEK,存在副作用顺序问题

Line 359 在校验 secretPurpose/usageInstance/resourceType 之前调用了 materializeResourceDek。如果这些参数无效,下游(Line 368-369)才失败,会留下“已物化但不可用”的密钥副作用,增加密钥系统噪音并放大排障复杂度。

🔧 建议修复
 public String defineSecretFromBindingForResource(String hostUuid, String vmUuid, String resourceUuid,
                                                  String resourceType, String kpUuid, String secretPurpose,
                                                  String usageInstance, String secretUuid) {
+    if (StringUtils.isBlank(hostUuid) || StringUtils.isBlank(resourceUuid)
+            || StringUtils.isBlank(resourceType)
+            || StringUtils.isBlank(secretPurpose)
+            || StringUtils.isBlank(usageInstance)) {
+        throw new OperationFailureException(operr(
+                "defineSecretFromBindingForResource requires non-blank hostUuid, resourceUuid, resourceType, secretPurpose and usageInstance"));
+    }
     if (StringUtils.isBlank(kpUuid)) {
         throw new OperationFailureException(operr(
                 "encrypted resource[type:%s, uuid:%s] has no key provider binding; cannot define libvirt secret on host[uuid:%s]",
                 resourceType, resourceUuid, hostUuid));
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@storage/src/main/java/org/zstack/storage/encrypt/VolumeEncryptedSecretHelper.java`
around lines 351 - 370, The method defineSecretFromBindingForResource
materializes the DEK by calling materializeResourceDek before validating all
required parameters, creating side effects in the key system if parameters like
secretPurpose, usageInstance, or resourceType are invalid. Add parameter
validation checks for secretPurpose, usageInstance, and resourceType (using
StringUtils.isBlank or appropriate validation) before the materializeResourceDek
call to ensure parameters are valid and prevent wasted materialization with
subsequent failures.


/**
Expand All @@ -350,12 +377,18 @@ public String defineSecretFromBinding(String hostUuid, String vmUuid, String vol
* contract, but key-agent does not include it in volume secret usage names.
*/
public String getSecretOnHost(String hostUuid, String vmUuid, String volUuid, Integer keyVersion) {
return getSecretForResourceOnHost(hostUuid, vmUuid, volUuid, keyVersion,
"volume", KVMConstant.volumeSecretUsageInstance(volUuid));
}

public String getSecretForResourceOnHost(String hostUuid, String vmUuid, String resourceUuid, Integer keyVersion,
String purpose, String usageInstance) {
SecretHostGetMsg msg = new SecretHostGetMsg();
msg.setHostUuid(hostUuid);
msg.setVmUuid(vmUuid);
msg.setPurpose("volume");
msg.setPurpose(purpose);
msg.setKeyVersion(keyVersion);
msg.setUsageInstance(KVMConstant.volumeSecretUsageInstance(volUuid));
msg.setUsageInstance(usageInstance);
bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid);

MessageReply reply = bus.call(msg);
Expand All @@ -368,28 +401,35 @@ public String getSecretOnHost(String hostUuid, String vmUuid, String volUuid, In
return null;
}
throw new OperationFailureException(operr(
"failed to get libvirt LUKS secret on host[uuid:%s] vm[uuid:%s] volume[uuid:%s] keyVersion[%s]: %s",
hostUuid, vmUuid, volUuid, keyVersion, err));
"failed to get libvirt LUKS secret on host[uuid:%s] vm[uuid:%s] resource[uuid:%s] keyVersion[%s]: %s",
hostUuid, vmUuid, resourceUuid, keyVersion, err));
}

public void deleteSecretOnHostBestEffort(String hostUuid, String vmUuid, String volUuid, Integer keyVersion) {
deleteSecretForResourceOnHostBestEffort(hostUuid, vmUuid, volUuid, keyVersion,
"volume", KVMConstant.volumeSecretUsageInstance(volUuid));
}

public void deleteSecretForResourceOnHostBestEffort(String hostUuid, String vmUuid, String resourceUuid,
Integer keyVersion, String purpose, String usageInstance) {
if (StringUtils.isBlank(hostUuid) || StringUtils.isBlank(vmUuid)
|| StringUtils.isBlank(volUuid) || keyVersion == null) {
|| StringUtils.isBlank(resourceUuid) || keyVersion == null
|| StringUtils.isBlank(purpose) || StringUtils.isBlank(usageInstance)) {
return;
}
SecretHostDeleteMsg msg = new SecretHostDeleteMsg();
msg.setHostUuid(hostUuid);
msg.setVmUuid(vmUuid);
msg.setPurpose("volume");
msg.setPurpose(purpose);
msg.setKeyVersion(keyVersion);
msg.setUsageInstance(KVMConstant.volumeSecretUsageInstance(volUuid));
msg.setUsageInstance(usageInstance);
bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid);

MessageReply reply = bus.call(msg);
if (!reply.isSuccess()) {
logger.warn(String.format(
"best-effort delete libvirt LUKS secret failed for volume[uuid:%s] on host[uuid:%s] vm[uuid:%s]: %s",
volUuid, hostUuid, vmUuid, reply.getError()));
"best-effort delete libvirt LUKS secret failed for resource[uuid:%s] on host[uuid:%s] vm[uuid:%s]: %s",
resourceUuid, hostUuid, vmUuid, reply.getError()));
}
}

Expand All @@ -414,6 +454,23 @@ public String resolveOrDefineSecretForVolume(String hostUuid, String vmUuid, Str
return defineSecretFromBinding(hostUuid, vmUuid, volUuid, kpUuid);
}

public String resolveOrDefineSecretForResource(String hostUuid, String vmUuid, String resourceUuid,
String resourceType, String kpUuid, Integer keyVersion,
String secretPurpose, String usageInstance) {
if (keyVersion == null) {
throw new OperationFailureException(operr(
"encrypted resource[type:%s, uuid:%s] has no key version bound; cannot resolve libvirt LUKS secret on host[uuid:%s] for vm[uuid:%s]",
resourceType, resourceUuid, hostUuid, vmUuid));
}
String secretUuid = getSecretForResourceOnHost(hostUuid, vmUuid, resourceUuid, keyVersion,
secretPurpose, usageInstance);
if (StringUtils.isNotBlank(secretUuid)) {
return secretUuid;
}
return defineSecretFromBindingForResource(hostUuid, vmUuid, resourceUuid, resourceType, kpUuid,
secretPurpose, usageInstance, null);
}

private String resolveVolumeLibvirtSecretUuidFromDomainXml(String hostUuid, String vmUuid, String volUuid) {
KVMAgentCommands.ResolveVolumeLibvirtSecretCmd cmd = new KVMAgentCommands.ResolveVolumeLibvirtSecretCmd();
cmd.setVmUuid(vmUuid);
Expand Down Expand Up @@ -484,4 +541,37 @@ public String resolveOrDefineSecretForVolumeMigration(String srcHostUuid, String
String kpUuid = volumeEncryptedResourceKeyBackend.findKeyProviderUuidByVolume(volUuid);
return defineSecretFromBinding(dstHostUuid, vmUuid, volUuid, kpUuid, sourceSecretUuid);
}

public String resolveOrDefineSecretForResourceMigration(String srcHostUuid, String dstHostUuid, String vmUuid,
String resourceUuid, String resourceType, String kpUuid,
Integer keyVersion, String secretPurpose,
String usageInstance) {
if (StringUtils.isBlank(srcHostUuid) || StringUtils.isBlank(dstHostUuid)
|| StringUtils.isBlank(vmUuid) || StringUtils.isBlank(resourceUuid)) {
throw new OperationFailureException(operr(
"resolve migration LUKS secret requires non-blank srcHostUuid, dstHostUuid, vmUuid and resourceUuid"));
}

if (keyVersion == null) {
throw new OperationFailureException(operr(
"encrypted resource[type:%s, uuid:%s] has no key version bound; cannot resolve migration LUKS secret for vm[uuid:%s]",
resourceType, resourceUuid, vmUuid));
}

String sourceSecretUuid = getSecretForResourceOnHost(srcHostUuid, vmUuid, resourceUuid, keyVersion,
secretPurpose, usageInstance);
if (StringUtils.isBlank(sourceSecretUuid)) {
sourceSecretUuid = defineSecretFromBindingForResource(srcHostUuid, vmUuid, resourceUuid, resourceType,
kpUuid, secretPurpose, usageInstance, null);
}

String destSecretUuid = getSecretForResourceOnHost(dstHostUuid, vmUuid, resourceUuid, keyVersion,
secretPurpose, usageInstance);
if (StringUtils.equals(destSecretUuid, sourceSecretUuid)) {
return destSecretUuid;
}

return defineSecretFromBindingForResource(dstHostUuid, vmUuid, resourceUuid, resourceType,
kpUuid, secretPurpose, usageInstance, sourceSecretUuid);
}
}