Skip to content

Commit 7f60a6d

Browse files
committed
allow adding kms key in deploy vm
1 parent c1fdd07 commit 7f60a6d

File tree

26 files changed

+235
-84
lines changed

26 files changed

+235
-84
lines changed

api/src/main/java/com/cloud/offering/DiskOfferingInfo.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class DiskOfferingInfo {
2323
private Long _size;
2424
private Long _minIops;
2525
private Long _maxIops;
26+
private Long _kmsKeyId;
2627

2728
public DiskOfferingInfo() {
2829
}
@@ -38,6 +39,14 @@ public DiskOfferingInfo(DiskOffering diskOffering, Long size, Long minIops, Long
3839
_maxIops = maxIops;
3940
}
4041

42+
public DiskOfferingInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIops, Long kmsKeyId) {
43+
_diskOffering = diskOffering;
44+
_size = size;
45+
_minIops = minIops;
46+
_maxIops = maxIops;
47+
_kmsKeyId = kmsKeyId;
48+
}
49+
4150
public void setDiskOffering(DiskOffering diskOffering) {
4251
_diskOffering = diskOffering;
4352
}
@@ -69,4 +78,12 @@ public void setMaxIops(Long maxIops) {
6978
public Long getMaxIops() {
7079
return _maxIops;
7180
}
81+
82+
public void setKmsKeyId(Long kmsKeyId) {
83+
_kmsKeyId = kmsKeyId;
84+
}
85+
86+
public Long getKmsKeyId() {
87+
return _kmsKeyId;
88+
}
7289
}

api/src/main/java/com/cloud/vm/UserVmService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
226226
String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
227227
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
228228
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
229-
Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, Volume volume, Snapshot snapshot) throws InsufficientCapacityException,
229+
Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, Long rootDiskKmsKeyId, Volume volume, Snapshot snapshot) throws InsufficientCapacityException,
230230
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
231231

232232
/**
@@ -302,7 +302,7 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin
302302
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, List<VmDiskInfo> dataDiskInfoList, String group, HypervisorType hypervisor,
303303
HTTPMethod httpmethod, String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
304304
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
305-
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, String vmType, Volume volume, Snapshot snapshot) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
305+
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, Long rootDiskKmsKeyId, String vmType, Volume volume, Snapshot snapshot) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
306306

307307
/**
308308
* Creates a User VM in Advanced Zone (Security Group feature is disabled)
@@ -374,7 +374,7 @@ UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffe
374374
String hostName, String displayName, Long diskOfferingId, Long diskSize, List<VmDiskInfo> dataDiskInfoList, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
375375
Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
376376
Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
377-
Map<String, String> templateOvfPropertiesMap, boolean dynamicScalingEnabled, String vmType, Long overrideDiskOfferingId, Volume volume, Snapshot snapshot)
377+
Map<String, String> templateOvfPropertiesMap, boolean dynamicScalingEnabled, String vmType, Long overrideDiskOfferingId, Long rootDiskKmsKeyId, Volume volume, Snapshot snapshot)
378378

379379
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
380380

api/src/main/java/com/cloud/vm/VmDiskInfo.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public VmDiskInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIo
3333
_deviceId = deviceId;
3434
}
3535

36+
public VmDiskInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIops, Long deviceId, Long kmsKeyId) {
37+
super(diskOffering, size, minIops, maxIops, kmsKeyId);
38+
_deviceId = deviceId;
39+
}
40+
3641
public Long getDeviceId() {
3742
return _deviceId;
3843
}

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ public class ApiConstants {
194194
public static final String UTILIZATION = "utilization";
195195
public static final String DRIVER = "driver";
196196
public static final String ROOT_DISK_SIZE = "rootdisksize";
197+
public static final String ROOT_DISK_KMS_KEY_ID = "rootdiskkmskeyid";
197198
public static final String DHCP_OPTIONS_NETWORK_LIST = "dhcpoptionsnetworklist";
198199
public static final String DHCP_OPTIONS = "dhcpoptions";
199200
public static final String DHCP_PREFIX = "dhcp:";
@@ -863,6 +864,7 @@ public class ApiConstants {
863864
public static final String CHANGE_CIDR = "changecidr";
864865
public static final String PURPOSE = "purpose";
865866
public static final String KMS_KEY_ID = "kmskeyid";
867+
public static final String KMS_KEY_VERSION = "kmskeyversion";
866868
public static final String KEK_LABEL = "keklabel";
867869
public static final String KEY_BITS = "keybits";
868870
public static final String IS_TAGGED = "istagged";

api/src/main/java/org/apache/cloudstack/api/command/user/vm/BaseDeployVMCmd.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@
4040
import org.apache.cloudstack.api.response.DiskOfferingResponse;
4141
import org.apache.cloudstack.api.response.DomainResponse;
4242
import org.apache.cloudstack.api.response.HostResponse;
43+
import org.apache.cloudstack.api.response.KMSKeyResponse;
4344
import org.apache.cloudstack.api.response.NetworkResponse;
4445
import org.apache.cloudstack.api.response.ProjectResponse;
4546
import org.apache.cloudstack.api.response.SecurityGroupResponse;
4647
import org.apache.cloudstack.api.response.UserDataResponse;
4748
import org.apache.cloudstack.api.response.ZoneResponse;
4849
import org.apache.cloudstack.context.CallContext;
50+
import org.apache.cloudstack.kms.KMSKey;
4951
import org.apache.cloudstack.vm.lease.VMLeaseManager;
5052
import org.apache.commons.collections.CollectionUtils;
5153
import org.apache.commons.collections.MapUtils;
@@ -126,11 +128,19 @@ public abstract class BaseDeployVMCmd extends BaseAsyncCreateCustomIdCmd impleme
126128
since = "4.4")
127129
private Long rootdisksize;
128130

131+
@ACL
132+
@Parameter(name = ApiConstants.ROOT_DISK_KMS_KEY_ID,
133+
type = CommandType.UUID,
134+
entityType = KMSKeyResponse.class,
135+
description = "ID of the KMS Key to use for root disk encryption",
136+
since = "4.23.0")
137+
private Long rootDiskKmsKeyId;
138+
129139
@Parameter(name = ApiConstants.DATADISKS_DETAILS,
130140
type = CommandType.MAP,
131141
since = "4.21.0",
132142
description = "Disk offering details for creating multiple data volumes. Mutually exclusive with diskOfferingId." +
133-
" Example: datadisksdetails[0].diskofferingid=a2a73a84-19db-4852-8930-dfddef053341&datadisksdetails[0].size=10&datadisksdetails[0].miniops=100&datadisksdetails[0].maxiops=200")
143+
" Example: datadisksdetails[0].diskofferingid=a2a73a84-19db-4852-8930-dfddef053341&datadisksdetails[0].size=10&datadisksdetails[0].miniops=100&datadisksdetails[0].maxiops=200&datadisksdetails[0].kmskeyid=<uuid>")
134144
private Map dataDisksDetails;
135145

136146
@Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "an optional group for the virtual machine")
@@ -300,6 +310,10 @@ public Long getDiskOfferingId() {
300310
return diskOfferingId;
301311
}
302312

313+
public Long getRootDiskKmsKeyId() {
314+
return rootDiskKmsKeyId;
315+
}
316+
303317
public String getDeploymentPlanner() {
304318
return deploymentPlanner;
305319
}
@@ -581,7 +595,19 @@ public List<VmDiskInfo> getDataDiskInfoList() {
581595
minIops = Long.parseLong(dataDisk.get(ApiConstants.MIN_IOPS));
582596
maxIops = Long.parseLong(dataDisk.get(ApiConstants.MAX_IOPS));
583597
}
584-
VmDiskInfo vmDiskInfo = new VmDiskInfo(diskOffering, size, minIops, maxIops, deviceId);
598+
599+
// Extract KMS key ID if provided
600+
Long kmsKeyId = null;
601+
String kmsKeyUuid = dataDisk.get(ApiConstants.KMS_KEY_ID);
602+
if (kmsKeyUuid != null) {
603+
KMSKey kmsKey = _entityMgr.findByUuid(org.apache.cloudstack.kms.KMSKey.class, kmsKeyUuid);
604+
if (kmsKey == null) {
605+
throw new InvalidParameterValueException("Unable to find KMS key " + kmsKeyUuid);
606+
}
607+
kmsKeyId = kmsKey.getId();
608+
}
609+
610+
VmDiskInfo vmDiskInfo = new VmDiskInfo(diskOffering, size, minIops, maxIops, deviceId, kmsKeyId);
585611
vmDiskInfoList.add(vmDiskInfo);
586612
}
587613
this.dataDiskInfoList = vmDiskInfoList;

api/src/main/java/org/apache/cloudstack/api/response/VolumeResponse.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,14 @@ public class VolumeResponse extends BaseResponseWithTagInformation implements Co
309309
@Param(description = "the format of the disk encryption if applicable", since = "4.19.1")
310310
private String encryptionFormat;
311311

312+
@SerializedName(ApiConstants.KMS_KEY_ID)
313+
@Param(description = "KMS key id of the volume", since = "4.23.0")
314+
private String kmsKeyId;
315+
316+
@SerializedName(ApiConstants.KMS_KEY_VERSION)
317+
@Param(description = "Version number of the KMS key used for disk encryption if applicable", since = "4.23.0")
318+
private Integer kmsKeyVersion;
319+
312320
public String getPath() {
313321
return path;
314322
}
@@ -871,4 +879,20 @@ public void setVolumeRepairResult(Map<String, String> volumeRepairResult) {
871879
public void setEncryptionFormat(String encryptionFormat) {
872880
this.encryptionFormat = encryptionFormat;
873881
}
882+
883+
public String getKmsKeyId() {
884+
return kmsKeyId;
885+
}
886+
887+
public void setKmsKeyId(String kmsKeyId) {
888+
this.kmsKeyId = kmsKeyId;
889+
}
890+
891+
public Integer getKmsKeyVersion() {
892+
return kmsKeyVersion;
893+
}
894+
895+
public void setKmsKeyVersion(Integer kmsKeyVersion) {
896+
this.kmsKeyVersion = kmsKeyVersion;
897+
}
874898
}

engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId,
120120
void destroyVolume(Volume volume);
121121

122122
DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template,
123-
Account owner, Long deviceId);
123+
Account owner, Long deviceId, Long kmsKeyId);
124124

125125
VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo volume, HypervisorType rootDiskHyperType, StoragePool storagePool) throws NoTransitionException;
126126

@@ -150,7 +150,7 @@ DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Lon
150150
* Allocate a volume or multiple volumes in case of template is registered with the 'deploy-as-is' option, allowing multiple disks
151151
*/
152152
List<DiskProfile> allocateTemplatedVolumes(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
153-
Account owner, Volume volume, Snapshot snapshot);
153+
Account owner, Long kmsKeyId, Volume volume, Snapshot snapshot);
154154

155155
String getVmNameFromVolumeId(long volumeId);
156156

engine/api/src/main/java/org/apache/cloudstack/engine/service/api/OrchestrationService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ VirtualMachineEntity createVirtualMachine(@QueryParam("id") String id, @QueryPar
7171
@QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
7272
@QueryParam("root-disk-size") Long rootDiskSize, @QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap,
7373
@QueryParam("datadisktemplate-diskoffering-map") Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap, @QueryParam("disk-offering-id") Long diskOfferingId,
74-
@QueryParam("root-disk-offering-id") Long rootDiskOfferingId, List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException;
74+
@QueryParam("root-disk-offering-id") Long rootDiskOfferingId, @QueryParam("root-disk-kms-key-id") Long rootDiskKmsKeyId, List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException;
7575

7676
@POST
7777
VirtualMachineEntity createVirtualMachineFromScratch(@QueryParam("id") String id, @QueryParam("owner") String owner, @QueryParam("iso-id") String isoId,
@@ -80,7 +80,7 @@ VirtualMachineEntity createVirtualMachineFromScratch(@QueryParam("id") String id
8080
@QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags,
8181
@QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
8282
@QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap, @QueryParam("disk-offering-id") Long diskOfferingId,
83-
@QueryParam("data-disks-offering-info") List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException;
83+
@QueryParam("root-disk-kms-key-id") Long rootDiskKmsKeyId, @QueryParam("data-disks-offering-info") List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException;
8484

8585
@POST
8686
NetworkEntity createNetwork(String id, String name, String domainName, String cidr, String gateway);

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ public void allocate(final String vmInstanceName, final VirtualMachineTemplate t
585585
Long deviceId = dataDiskDeviceIds.get(index++);
586586
String volumeName = deviceId == null ? "DATA-" + persistedVm.getId() : "DATA-" + persistedVm.getId() + "-" + String.valueOf(deviceId);
587587
volumeMgr.allocateRawVolume(Type.DATADISK, volumeName, dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
588-
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, deviceId);
588+
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, deviceId, dataDiskOfferingInfo.getKmsKeyId());
589589
}
590590
}
591591
if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) {
@@ -595,7 +595,7 @@ public void allocate(final String vmInstanceName, final VirtualMachineTemplate t
595595
long diskOfferingSize = diskOffering.getDiskSize() / (1024 * 1024 * 1024);
596596
VMTemplateVO dataDiskTemplate = _templateDao.findById(dataDiskTemplateToDiskOfferingMap.getKey());
597597
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId() + "-" + String.valueOf( diskNumber), diskOffering, diskOfferingSize, null, null,
598-
persistedVm, dataDiskTemplate, owner, diskNumber);
598+
persistedVm, dataDiskTemplate, owner, diskNumber, null);
599599
diskNumber++;
600600
}
601601
}
@@ -625,12 +625,12 @@ private void allocateRootVolume(VMInstanceVO vm, VirtualMachineTemplate template
625625
String rootVolumeName = String.format("ROOT-%s", vm.getId());
626626
if (template.getFormat() == ImageFormat.ISO) {
627627
volumeMgr.allocateRawVolume(Type.ROOT, rootVolumeName, rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
628-
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vm, template, owner, null);
628+
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vm, template, owner, null, rootDiskOfferingInfo.getKmsKeyId());
629629
} else if (Arrays.asList(ImageFormat.BAREMETAL, ImageFormat.EXTERNAL).contains(template.getFormat())) {
630630
logger.debug("{} has format [{}]. Skipping ROOT volume [{}] allocation.", template, template.getFormat(), rootVolumeName);
631631
} else {
632632
volumeMgr.allocateTemplatedVolumes(Type.ROOT, rootVolumeName, rootDiskOfferingInfo.getDiskOffering(), rootDiskSizeFinal,
633-
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vm, owner, volume, snapshot);
633+
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vm, owner, rootDiskOfferingInfo.getKmsKeyId(), volume, snapshot);
634634
}
635635
} finally {
636636
// Remove volumeContext and pop vmContext back

0 commit comments

Comments
 (0)