Skip to content
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e995b46
Add KMS framework
vishesh92 Dec 17, 2025
e3a63ec
integrate volume encryption with kms
vishesh92 Dec 23, 2025
6079e0f
rotate keys wrapped with older versions
vishesh92 Jan 5, 2026
86e1d2b
allow adding kms key in deploy vm
vishesh92 Jan 7, 2026
6abcffa
temp commit
vishesh92 Jan 12, 2026
0d39a7b
Add some tests
vishesh92 Jan 19, 2026
f354da4
fixups and some ui changes
vishesh92 Jan 21, 2026
56cf3f6
Change wrapping algo for pkcs
vishesh92 Feb 10, 2026
529fd9d
fixups
vishesh92 Feb 11, 2026
6ba0af5
fix list apis
vishesh92 Feb 17, 2026
bca1b25
directly create the key in the store
vishesh92 Feb 24, 2026
d7c5e24
Add missing license
vishesh92 Feb 26, 2026
d8cdddb
fixup
vishesh92 Feb 26, 2026
949c00e
Fix missing labels and label generation
vishesh92 Feb 26, 2026
1087503
Fixup ui bug
vishesh92 Feb 27, 2026
0fe31fb
fixups
vishesh92 Mar 2, 2026
30891ee
Add smoke test
vishesh92 Mar 5, 2026
2c49e92
Fix test failures
vishesh92 Mar 5, 2026
b68661c
fixups
vishesh92 Mar 23, 2026
7740c5a
Merge branch 'main' into feature-kms
vishesh92 Apr 6, 2026
4739834
Address comments
vishesh92 Apr 14, 2026
61aa7ed
Merge branch 'main' into feature-kms
vishesh92 Apr 15, 2026
520da69
fix failing tests
vishesh92 Apr 15, 2026
b58c46c
Address comments
vishesh92 Apr 28, 2026
436d0bf
Merge branch 'main' into feature-kms
vishesh92 Apr 28, 2026
b9a8f0f
Fix pre-commit error
vishesh92 Apr 29, 2026
24771d4
fixup
vishesh92 Apr 29, 2026
33f3d3d
Fix failing unit tests
vishesh92 Apr 30, 2026
1979f2a
Merge branch 'main' into feature-kms
vishesh92 May 4, 2026
511b12c
fixup
vishesh92 May 4, 2026
3599b7d
fix UI bug
vishesh92 May 4, 2026
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
5 changes: 5 additions & 0 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@
<artifactId>cloud-framework-direct-download</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-framework-kms</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
29 changes: 29 additions & 0 deletions api/src/main/java/com/cloud/event/EventTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import org.apache.cloudstack.gpu.GpuDevice;
import org.apache.cloudstack.gpu.VgpuProfile;
import org.apache.cloudstack.ha.HAConfig;
import org.apache.cloudstack.kms.HSMProfile;
import org.apache.cloudstack.kms.KMSKey;
import org.apache.cloudstack.network.BgpPeer;
import org.apache.cloudstack.network.Ipv4GuestSubnetNetworkMap;
import org.apache.cloudstack.quota.QuotaTariff;
Expand Down Expand Up @@ -271,6 +273,20 @@ public class EventTypes {
public static final String EVENT_CA_CERTIFICATE_REVOKE = "CA.CERTIFICATE.REVOKE";
public static final String EVENT_CA_CERTIFICATE_PROVISION = "CA.CERTIFICATE.PROVISION";

// KMS (Key Management Service) events
public static final String EVENT_KMS_KEY_WRAP = "KMS.KEY.WRAP";
public static final String EVENT_KMS_KEY_UNWRAP = "KMS.KEY.UNWRAP";
public static final String EVENT_KMS_KEY_CREATE = "KMS.KEY.CREATE";
public static final String EVENT_KMS_KEY_UPDATE = "KMS.KEY.UPDATE";
public static final String EVENT_KMS_KEY_ROTATE = "KMS.KEY.ROTATE";
public static final String EVENT_KMS_KEY_DELETE = "KMS.KEY.DELETE";
public static final String EVENT_VOLUME_MIGRATE_TO_KMS = "VOLUME.MIGRATE.TO.KMS";
Comment thread
sureshanaparti marked this conversation as resolved.

// HSM Profile events
public static final String EVENT_HSM_PROFILE_CREATE = "HSM.PROFILE.CREATE";
public static final String EVENT_HSM_PROFILE_UPDATE = "HSM.PROFILE.UPDATE";
public static final String EVENT_HSM_PROFILE_DELETE = "HSM.PROFILE.DELETE";

// Account events
public static final String EVENT_ACCOUNT_ENABLE = "ACCOUNT.ENABLE";
public static final String EVENT_ACCOUNT_DISABLE = "ACCOUNT.DISABLE";
Expand Down Expand Up @@ -1015,6 +1031,19 @@ public class EventTypes {
entityEventDetails.put(EVENT_VOLUME_RECOVER, Volume.class);
entityEventDetails.put(EVENT_VOLUME_CHANGE_DISK_OFFERING, Volume.class);

// KMS Key Events
entityEventDetails.put(EVENT_KMS_KEY_CREATE, KMSKey.class);
entityEventDetails.put(EVENT_KMS_KEY_UPDATE, KMSKey.class);
entityEventDetails.put(EVENT_KMS_KEY_UNWRAP, KMSKey.class);
entityEventDetails.put(EVENT_KMS_KEY_WRAP, KMSKey.class);
entityEventDetails.put(EVENT_KMS_KEY_DELETE, KMSKey.class);
entityEventDetails.put(EVENT_KMS_KEY_ROTATE, KMSKey.class);

// HSM Profile Events
entityEventDetails.put(EVENT_HSM_PROFILE_CREATE, HSMProfile.class);
entityEventDetails.put(EVENT_HSM_PROFILE_UPDATE, HSMProfile.class);
entityEventDetails.put(EVENT_HSM_PROFILE_DELETE, HSMProfile.class);

Comment thread
sureshanaparti marked this conversation as resolved.
// Domains
entityEventDetails.put(EVENT_DOMAIN_CREATE, Domain.class);
entityEventDetails.put(EVENT_DOMAIN_DELETE, Domain.class);
Expand Down
17 changes: 17 additions & 0 deletions api/src/main/java/com/cloud/offering/DiskOfferingInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class DiskOfferingInfo {
private Long _size;
private Long _minIops;
private Long _maxIops;
private Long _kmsKeyId;

public DiskOfferingInfo() {
}
Expand All @@ -38,6 +39,14 @@ public DiskOfferingInfo(DiskOffering diskOffering, Long size, Long minIops, Long
_maxIops = maxIops;
}

public DiskOfferingInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIops, Long kmsKeyId) {
_diskOffering = diskOffering;
_size = size;
_minIops = minIops;
_maxIops = maxIops;
_kmsKeyId = kmsKeyId;
}

public void setDiskOffering(DiskOffering diskOffering) {
_diskOffering = diskOffering;
}
Expand Down Expand Up @@ -69,4 +78,12 @@ public void setMaxIops(Long maxIops) {
public Long getMaxIops() {
return _maxIops;
}

public void setKmsKeyId(Long kmsKeyId) {
_kmsKeyId = kmsKeyId;
}

public Long getKmsKeyId() {
return _kmsKeyId;
}
}
8 changes: 8 additions & 0 deletions api/src/main/java/com/cloud/storage/Volume.java
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,14 @@ enum Event {

void setPassphraseId(Long id);

Long getKmsKeyId();

void setKmsKeyId(Long id);

Long getKmsWrappedKeyId();

void setKmsWrappedKeyId(Long id);

String getEncryptFormat();

void setEncryptFormat(String encryptFormat);
Expand Down
6 changes: 3 additions & 3 deletions api/src/main/java/com/cloud/vm/UserVmService.java
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, Volume volume, Snapshot snapshot) throws InsufficientCapacityException,
Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, Long rootDiskKmsKeyId, Volume volume, Snapshot snapshot) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;

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

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

throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;

Expand Down
5 changes: 5 additions & 0 deletions api/src/main/java/com/cloud/vm/VmDiskInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ public VmDiskInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIo
_deviceId = deviceId;
}

public VmDiskInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIops, Long deviceId, Long kmsKeyId) {
super(diskOffering, size, minIops, maxIops, kmsKeyId);
_deviceId = deviceId;
}

public Long getDeviceId() {
return _deviceId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ public enum ApiCommandResourceType {
KubernetesSupportedVersion(null),
SharedFS(org.apache.cloudstack.storage.sharedfs.SharedFS.class),
Extension(org.apache.cloudstack.extension.Extension.class),
ExtensionCustomAction(org.apache.cloudstack.extension.ExtensionCustomAction.class);
ExtensionCustomAction(org.apache.cloudstack.extension.ExtensionCustomAction.class),
KmsKey(org.apache.cloudstack.kms.KMSKey.class),
HsmProfile(org.apache.cloudstack.kms.HSMProfile.class);

private final Class<?> clazz;

Expand Down
8 changes: 8 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ public class ApiConstants {
public static final String UTILIZATION = "utilization";
public static final String DRIVER = "driver";
public static final String ROOT_DISK_SIZE = "rootdisksize";
public static final String ROOT_DISK_KMS_KEY_ID = "rootdiskkmskeyid";
public static final String DHCP_OPTIONS_NETWORK_LIST = "dhcpoptionsnetworklist";
public static final String DHCP_OPTIONS = "dhcpoptions";
public static final String DHCP_PREFIX = "dhcp:";
Expand Down Expand Up @@ -866,7 +867,14 @@ public class ApiConstants {
public static final String ITERATIONS = "iterations";
public static final String SORT_BY = "sortby";
public static final String CHANGE_CIDR = "changecidr";
public static final String HSM_PROFILE = "hsmprofile";
public static final String HSM_PROFILE_ID = "hsmprofileid";
public static final String PURPOSE = "purpose";
public static final String KMS_KEY = "kmskey";
public static final String KMS_KEY_ID = "kmskeyid";
public static final String KMS_KEY_VERSION = "kmskeyversion";
public static final String KEK_LABEL = "keklabel";
public static final String KEY_BITS = "keybits";
public static final String IS_TAGGED = "istagged";
public static final String INSTANCE_NAME = "instancename";
public static final String CONSIDER_LAST_HOST = "considerlasthost";
Expand Down
52 changes: 35 additions & 17 deletions api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Set;

import org.apache.cloudstack.api.response.ConsoleSessionResponse;
import org.apache.cloudstack.api.response.KMSKeyResponse;
import org.apache.cloudstack.consoleproxy.ConsoleSession;
import org.apache.cloudstack.acl.apikeypair.ApiKeyPair;
import org.apache.cloudstack.acl.apikeypair.ApiKeyPairPermission;
Expand Down Expand Up @@ -156,6 +157,7 @@
import org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMap;
import org.apache.cloudstack.direct.download.DirectDownloadManager;
import org.apache.cloudstack.gui.theme.GuiThemeJoin;
import org.apache.cloudstack.kms.KMSKey;
import org.apache.cloudstack.management.ManagementServerHost;
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
import org.apache.cloudstack.region.PortableIp;
Expand Down Expand Up @@ -281,7 +283,8 @@ public interface ResponseGenerator {

List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, UserVm... userVms);

List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, EnumSet<VMDetails> details, UserVm... userVms);
List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, EnumSet<VMDetails> details,
UserVm... userVms);

SystemVmResponse createSystemVmResponse(VirtualMachine systemVM);

Expand All @@ -307,19 +310,22 @@ public interface ResponseGenerator {

LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer);

LBStickinessResponse createLBStickinessPolicyResponse(List<? extends StickinessPolicy> stickinessPolicies, LoadBalancer lb);
LBStickinessResponse createLBStickinessPolicyResponse(List<? extends StickinessPolicy> stickinessPolicies,
LoadBalancer lb);

LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb);

LBHealthCheckResponse createLBHealthCheckPolicyResponse(List<? extends HealthCheckPolicy> healthcheckPolicies, LoadBalancer lb);
LBHealthCheckResponse createLBHealthCheckPolicyResponse(List<? extends HealthCheckPolicy> healthcheckPolicies,
LoadBalancer lb);

LBHealthCheckResponse createLBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckPolicy, LoadBalancer lb);

PodResponse createPodResponse(Pod pod, Boolean showCapacities);

PodResponse createMinimalPodResponse(Pod pod);

ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities, Boolean showResourceIcon);
ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities,
Boolean showResourceIcon);

DataCenterGuestIpv6PrefixResponse createDataCenterGuestIpv6PrefixResponse(DataCenterGuestIpv6Prefix prefix);

Expand Down Expand Up @@ -359,7 +365,8 @@ public interface ResponseGenerator {

List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long zoneId, boolean readyOnly);

List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long snapshotId, Long volumeId, boolean readyOnly);
List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long snapshotId, Long volumeId,
boolean readyOnly);

SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List<? extends SecurityRule> securityRules);

Expand All @@ -378,14 +385,15 @@ public interface ResponseGenerator {
TemplateResponse createTemplateUpdateResponse(ResponseView view, VirtualMachineTemplate result);

List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
Long zoneId, boolean readyOnly);
Long zoneId, boolean readyOnly);

List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
List<Long> zoneIds, boolean readyOnly);
List<Long> zoneIds, boolean readyOnly);

List<CapacityResponse> createCapacityResponse(List<? extends Capacity> result, DecimalFormat format);

TemplatePermissionsResponse createTemplatePermissionsResponse(ResponseView view, List<String> accountNames, Long id);
TemplatePermissionsResponse createTemplatePermissionsResponse(ResponseView view, List<String> accountNames,
Long id);

AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd);

Expand All @@ -399,7 +407,8 @@ List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachine

Long getSecurityGroupId(String groupName, long accountId);

List<TemplateResponse> createIsoResponses(ResponseView view, VirtualMachineTemplate iso, Long zoneId, boolean readyOnly);
List<TemplateResponse> createIsoResponses(ResponseView view, VirtualMachineTemplate iso, Long zoneId,
boolean readyOnly);

ProjectResponse createProjectResponse(Project project);

Expand Down Expand Up @@ -500,13 +509,15 @@ List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachine

GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor osHypervisor);

HypervisorGuestOsNamesResponse createHypervisorGuestOSNamesResponse(List<Pair<String, String>> hypervisorGuestOsNames);
HypervisorGuestOsNamesResponse createHypervisorGuestOSNamesResponse(
List<Pair<String, String>> hypervisorGuestOsNames);

SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule sched);

UsageRecordResponse createUsageResponse(Usage usageRecord);

UsageRecordResponse createUsageResponse(Usage usageRecord, Map<String, Set<ResourceTagResponse>> resourceTagResponseMap, boolean oldFormat);
UsageRecordResponse createUsageResponse(Usage usageRecord,
Map<String, Set<ResourceTagResponse>> resourceTagResponseMap, boolean oldFormat);

public Map<String, Set<ResourceTagResponse>> getUsageResourceTags();

Expand All @@ -518,7 +529,8 @@ List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachine

public NicResponse createNicResponse(Nic result);

ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map<Ip, UserVm> lbInstances);
ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb,
Map<Ip, UserVm> lbInstances);

AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group);

Expand All @@ -544,9 +556,12 @@ List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachine

ManagementServerResponse createManagementResponse(ManagementServerHost mgmt);

List<RouterHealthCheckResultResponse> createHealthCheckResponse(VirtualMachine router, List<RouterHealthCheckResult> healthCheckResults);
List<RouterHealthCheckResultResponse> createHealthCheckResponse(VirtualMachine router,
List<RouterHealthCheckResult> healthCheckResults);

RollingMaintenanceResponse createRollingMaintenanceResponse(Boolean success, String details, List<RollingMaintenanceManager.HostUpdated> hostsUpdated, List<RollingMaintenanceManager.HostSkipped> hostsSkipped);
RollingMaintenanceResponse createRollingMaintenanceResponse(Boolean success, String details,
List<RollingMaintenanceManager.HostUpdated> hostsUpdated,
List<RollingMaintenanceManager.HostSkipped> hostsSkipped);

ResourceIconResponse createResourceIconResponse(ResourceIcon resourceIcon);

Expand All @@ -556,11 +571,14 @@ List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachine

DirectDownloadCertificateResponse createDirectDownloadCertificateResponse(DirectDownloadCertificate certificate);

List<DirectDownloadCertificateHostStatusResponse> createDirectDownloadCertificateHostMapResponse(List<DirectDownloadCertificateHostMap> hostMappings);
List<DirectDownloadCertificateHostStatusResponse> createDirectDownloadCertificateHostMapResponse(
List<DirectDownloadCertificateHostMap> hostMappings);

DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateHostStatusResponse(DirectDownloadManager.HostCertificateStatus status);
DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateHostStatusResponse(
DirectDownloadManager.HostCertificateStatus status);

DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateProvisionResponse(Long certificateId, Long hostId, Pair<Boolean, String> result);
DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateProvisionResponse(Long certificateId,
Long hostId, Pair<Boolean, String> result);

FirewallResponse createIpv6FirewallRuleResponse(FirewallRule acl);

Expand Down
Loading
Loading