mirror of https://github.com/apache/cloudstack.git
resolve conflicts
This commit is contained in:
commit
cc4faae58f
|
|
@ -58,8 +58,6 @@ github:
|
|||
- GaOrtiga
|
||||
- bhouse-nexthop
|
||||
|
||||
protected_branches:
|
||||
|
||||
rulesets:
|
||||
- name: "Default Branch Protection"
|
||||
type: branch
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ import org.apache.cloudstack.gpu.GpuCard;
|
|||
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;
|
||||
|
|
@ -46,7 +48,7 @@ import org.apache.cloudstack.storage.object.Bucket;
|
|||
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||
import org.apache.cloudstack.storage.sharedfs.SharedFS;
|
||||
import org.apache.cloudstack.usage.Usage;
|
||||
import org.apache.cloudstack.vm.schedule.VMSchedule;
|
||||
import org.apache.cloudstack.schedule.ResourceSchedule;
|
||||
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenterGuestIpv6Prefix;
|
||||
|
|
@ -128,17 +130,18 @@ public class EventTypes {
|
|||
public static final String EVENT_VM_UNMANAGE = "VM.UNMANAGE";
|
||||
public static final String EVENT_VM_RECOVER = "VM.RECOVER";
|
||||
|
||||
// VM Schedule
|
||||
public static final String EVENT_VM_SCHEDULE_CREATE = "VM.SCHEDULE.CREATE";
|
||||
public static final String EVENT_VM_SCHEDULE_UPDATE = "VM.SCHEDULE.UPDATE";
|
||||
public static final String EVENT_VM_SCHEDULE_DELETE = "VM.SCHEDULE.DELETE";
|
||||
|
||||
// VM Schedule action-execution events (fired when a scheduled action runs).
|
||||
public static final String EVENT_VM_SCHEDULE_START = "VM.SCHEDULE.START";
|
||||
public static final String EVENT_VM_SCHEDULE_STOP = "VM.SCHEDULE.STOP";
|
||||
public static final String EVENT_VM_SCHEDULE_REBOOT = "VM.SCHEDULE.REBOOT";
|
||||
public static final String EVENT_VM_SCHEDULE_FORCE_STOP = "VM.SCHEDULE.FORCE.STOP";
|
||||
public static final String EVENT_VM_SCHEDULE_FORCE_REBOOT = "VM.SCHEDULE.FORCE.REBOOT";
|
||||
|
||||
// Generic Resource Schedule CRUD events (apply to all resource types).
|
||||
public static final String EVENT_SCHEDULE_CREATE = "SCHEDULE.CREATE";
|
||||
public static final String EVENT_SCHEDULE_UPDATE = "SCHEDULE.UPDATE";
|
||||
public static final String EVENT_SCHEDULE_DELETE = "SCHEDULE.DELETE";
|
||||
|
||||
// Domain Router
|
||||
public static final String EVENT_ROUTER_CREATE = "ROUTER.CREATE";
|
||||
public static final String EVENT_ROUTER_DESTROY = "ROUTER.DESTROY";
|
||||
|
|
@ -274,6 +277,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";
|
||||
|
||||
// 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";
|
||||
|
|
@ -679,6 +696,7 @@ public class EventTypes {
|
|||
public static final String EVENT_AUTOSCALEVMGROUP_DISABLE = "AUTOSCALEVMGROUP.DISABLE";
|
||||
public static final String EVENT_AUTOSCALEVMGROUP_SCALEDOWN = "AUTOSCALEVMGROUP.SCALEDOWN";
|
||||
public static final String EVENT_AUTOSCALEVMGROUP_SCALEUP = "AUTOSCALEVMGROUP.SCALEUP";
|
||||
public static final String EVENT_AUTOSCALEVMGROUP_SCHEDULE_UPDATE = "AUTOSCALEVMGROUP.SCHEDULE.UPDATE";
|
||||
|
||||
public static final String EVENT_BAREMETAL_DHCP_SERVER_ADD = "PHYSICAL.DHCP.ADD";
|
||||
public static final String EVENT_BAREMETAL_DHCP_SERVER_DELETE = "PHYSICAL.DHCP.DELETE";
|
||||
|
|
@ -902,15 +920,18 @@ public class EventTypes {
|
|||
entityEventDetails.put(EVENT_VM_IMPORT, VirtualMachine.class);
|
||||
entityEventDetails.put(EVENT_VM_UNMANAGE, VirtualMachine.class);
|
||||
|
||||
// VMSchedule
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_CREATE, VMSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_DELETE, VMSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_UPDATE, VMSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_START, VMSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_STOP, VMSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_REBOOT, VMSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_FORCE_STOP, VMSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_FORCE_REBOOT, VMSchedule.class);
|
||||
// VMSchedule action-execution events
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_START, ResourceSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_STOP, ResourceSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_REBOOT, ResourceSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_FORCE_STOP, ResourceSchedule.class);
|
||||
entityEventDetails.put(EVENT_VM_SCHEDULE_FORCE_REBOOT, ResourceSchedule.class);
|
||||
entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_SCHEDULE_UPDATE, ResourceSchedule.class);
|
||||
|
||||
// Generic Resource Schedule
|
||||
entityEventDetails.put(EVENT_SCHEDULE_CREATE, ResourceSchedule.class);
|
||||
entityEventDetails.put(EVENT_SCHEDULE_UPDATE, ResourceSchedule.class);
|
||||
entityEventDetails.put(EVENT_SCHEDULE_DELETE, ResourceSchedule.class);
|
||||
|
||||
entityEventDetails.put(EVENT_ROUTER_CREATE, VirtualRouter.class);
|
||||
entityEventDetails.put(EVENT_ROUTER_DESTROY, VirtualRouter.class);
|
||||
|
|
@ -1029,6 +1050,20 @@ 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);
|
||||
entityEventDetails.put(EVENT_VOLUME_MIGRATE_TO_KMS, 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);
|
||||
|
||||
// Domains
|
||||
entityEventDetails.put(EVENT_DOMAIN_CREATE, Domain.class);
|
||||
entityEventDetails.put(EVENT_DOMAIN_DELETE, Domain.class);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public interface Host extends StateObject<Status>, Identity, Partition, HAResour
|
|||
String HOST_OVFTOOL_VERSION = "host.ovftool.version";
|
||||
String HOST_VIRTV2V_VERSION = "host.virtv2v.version";
|
||||
String HOST_SSH_PORT = "host.ssh.port";
|
||||
String HOST_CDROM_MAX_COUNT = "host.cdrom.max.count";
|
||||
String GUEST_OS_CATEGORY_ID = "guest.os.category.id";
|
||||
String GUEST_OS_RULE = "guest.os.rule";
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public class DiskOfferingInfo {
|
|||
private Long _size;
|
||||
private Long _minIops;
|
||||
private Long _maxIops;
|
||||
private Long _kmsKeyId;
|
||||
|
||||
public DiskOfferingInfo() {
|
||||
}
|
||||
|
|
@ -38,6 +39,14 @@ public class DiskOfferingInfo {
|
|||
_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;
|
||||
}
|
||||
|
|
@ -69,4 +78,12 @@ public class DiskOfferingInfo {
|
|||
public Long getMaxIops() {
|
||||
return _maxIops;
|
||||
}
|
||||
|
||||
public void setKmsKeyId(Long kmsKeyId) {
|
||||
_kmsKeyId = kmsKeyId;
|
||||
}
|
||||
|
||||
public Long getKmsKeyId() {
|
||||
return _kmsKeyId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -275,6 +275,14 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
|
|||
|
||||
void setPassphraseId(Long id);
|
||||
|
||||
Long getKmsKeyId();
|
||||
|
||||
void setKmsKeyId(Long id);
|
||||
|
||||
Long getKmsWrappedKeyId();
|
||||
|
||||
void setKmsWrappedKeyId(Long id);
|
||||
|
||||
String getEncryptFormat();
|
||||
|
||||
void setEncryptFormat(String encryptFormat);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public interface VolumeApiService {
|
|||
Volume allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException;
|
||||
|
||||
Volume allocVolume(long ownerId, Long zoneId, Long diskOfferingId, Long vmId, Long snapshotId, String name,
|
||||
Long cmdSize, Boolean displayVolume, Long cmdMinIops, Long cmdMaxIops, String customId)
|
||||
Long cmdSize, Boolean displayVolume, Long cmdMinIops, Long cmdMaxIops, String customId, Long kmsKeyId)
|
||||
throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public class DiskProfile {
|
|||
null);
|
||||
this.hyperType = hyperType;
|
||||
this.provisioningType = offering.getProvisioningType();
|
||||
this.requiresEncryption = offering.getEncrypt() || vol.getPassphraseId() != null;
|
||||
this.requiresEncryption = offering.getEncrypt() || vol.getPassphraseId() != null || vol.getKmsKeyId() != null;
|
||||
}
|
||||
|
||||
public DiskProfile(DiskProfile dp) {
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ public interface UserVmService {
|
|||
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;
|
||||
|
||||
/**
|
||||
|
|
@ -305,7 +305,7 @@ public interface UserVmService {
|
|||
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)
|
||||
|
|
@ -377,7 +377,7 @@ public interface UserVmService {
|
|||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ public class VmDiskInfo extends DiskOfferingInfo {
|
|||
_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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -202,6 +202,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:";
|
||||
|
|
@ -886,7 +887,14 @@ public class ApiConstants {
|
|||
public static final String ITEMS = "items";
|
||||
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";
|
||||
|
|
@ -1343,8 +1351,10 @@ public class ApiConstants {
|
|||
public static final String VNF_CONFIGURE_MANAGEMENT = "vnfconfiguremanagement";
|
||||
public static final String VNF_CIDR_LIST = "vnfcidrlist";
|
||||
|
||||
public static final String AUTHORIZE_URL = "authorizeurl";
|
||||
public static final String CLIENT_ID = "clientid";
|
||||
public static final String REDIRECT_URI = "redirecturi";
|
||||
public static final String TOKEN_URL = "tokenurl";
|
||||
|
||||
public static final String IS_TAG_A_RULE = "istagarule";
|
||||
|
||||
|
|
|
|||
|
|
@ -281,7 +281,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);
|
||||
|
||||
|
|
@ -307,11 +308,13 @@ 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);
|
||||
|
||||
|
|
@ -319,7 +322,8 @@ public interface ResponseGenerator {
|
|||
|
||||
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);
|
||||
|
||||
|
|
@ -361,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);
|
||||
|
||||
|
|
@ -380,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);
|
||||
|
||||
|
|
@ -401,7 +407,8 @@ public interface ResponseGenerator {
|
|||
|
||||
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);
|
||||
|
||||
|
|
@ -502,13 +509,15 @@ public interface ResponseGenerator {
|
|||
|
||||
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();
|
||||
|
||||
|
|
@ -520,7 +529,8 @@ public interface ResponseGenerator {
|
|||
|
||||
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);
|
||||
|
||||
|
|
@ -546,9 +556,12 @@ public interface ResponseGenerator {
|
|||
|
||||
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);
|
||||
|
||||
|
|
@ -558,11 +571,14 @@ public interface ResponseGenerator {
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.kms;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.AsyncJobResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.KMSKeyResponse;
|
||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.kms.KMSException;
|
||||
import org.apache.cloudstack.kms.KMSKey;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "migrateVolumesToKMS",
|
||||
description = "Migrates encrypted volumes to KMS",
|
||||
responseObject = AsyncJobResponse.class,
|
||||
since = "4.23.0",
|
||||
authorized = {RoleType.Admin},
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false)
|
||||
public class MigrateVolumesToKMSCmd extends BaseAsyncCmd {
|
||||
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT,
|
||||
type = CommandType.STRING,
|
||||
description = "Migrate volumes for specific account")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = DomainResponse.class,
|
||||
description = "Domain ID")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.VOLUME_IDS,
|
||||
type = CommandType.LIST,
|
||||
collectionType = CommandType.UUID,
|
||||
entityType = VolumeResponse.class,
|
||||
required = true,
|
||||
description = "List of volume IDs to migrate")
|
||||
private List<Long> volumeIds;
|
||||
|
||||
@Parameter(name = ApiConstants.KMS_KEY_ID,
|
||||
required = true,
|
||||
type = CommandType.UUID,
|
||||
entityType = KMSKeyResponse.class,
|
||||
description = "KMS Key ID to use for migrating volumes")
|
||||
private Long kmsKeyId;
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public List<Long> getVolumeIds() {
|
||||
return volumeIds;
|
||||
}
|
||||
|
||||
public Long getKmsKeyId() {
|
||||
return kmsKeyId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
kmsManager.migrateVolumesToKMS(this);
|
||||
} catch (KMSException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
|
||||
"Failed to migrate volumes to KMS: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
KMSKey key = _entityMgr.findById(KMSKey.class, kmsKeyId);
|
||||
if (key != null) {
|
||||
return key.getAccountId();
|
||||
}
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return com.cloud.event.EventTypes.EVENT_VOLUME_MIGRATE_TO_KMS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Migrating volumes to KMS key: " + _uuidMgr.getUuid(KMSKey.class, kmsKeyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.KmsKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getApiResourceId() {
|
||||
return kmsKeyId;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
|||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
|
||||
import org.apache.cloudstack.api.response.TemplateResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
|
|
@ -51,6 +52,10 @@ public class DetachIsoCmd extends BaseAsyncCmd implements UserCmd {
|
|||
description = "If true, ejects the ISO before detaching on VMware. Default: false", since = "4.15.1")
|
||||
protected Boolean forced;
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class,
|
||||
description = "The ID of the ISO to detach. Required when the Instance has more than one ISO attached.", since = "4.23.0")
|
||||
protected Long id;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -104,7 +109,7 @@ public class DetachIsoCmd extends BaseAsyncCmd implements UserCmd {
|
|||
|
||||
@Override
|
||||
public void execute() {
|
||||
boolean result = _templateService.detachIso(virtualMachineId, null, isForced());
|
||||
boolean result = _templateService.detachIso(virtualMachineId, id, isForced());
|
||||
if (result) {
|
||||
UserVm userVm = _entityMgr.findById(UserVm.class, virtualMachineId);
|
||||
UserVmResponse response = _responseGenerator.createUserVmResponse(getResponseView(), "virtualmachine", userVm).get(0);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cloudstack.api.command.user.kms;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.HSMProfileResponse;
|
||||
import org.apache.cloudstack.api.response.KMSKeyResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.kms.KMSException;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "createKMSKey",
|
||||
description = "Creates a new KMS key (Key Encryption Key) for encryption",
|
||||
responseObject = KMSKeyResponse.class,
|
||||
since = "4.23.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User},
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false)
|
||||
public class CreateKMSKeyCmd extends BaseCmd implements UserCmd {
|
||||
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME,
|
||||
required = true,
|
||||
type = CommandType.STRING,
|
||||
description = "Name of the KMS key")
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.DESCRIPTION,
|
||||
type = CommandType.STRING,
|
||||
description = "Description of the KMS key")
|
||||
private String description;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID,
|
||||
required = true,
|
||||
type = CommandType.UUID,
|
||||
entityType = ZoneResponse.class,
|
||||
description = "Zone ID where the key will be valid")
|
||||
private Long zoneId;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT,
|
||||
type = CommandType.STRING,
|
||||
description = "Account name (for creating keys for child accounts - requires domain admin or admin)")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = DomainResponse.class,
|
||||
description = "Domain ID (for creating keys for child accounts - requires domain admin or admin)")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = ProjectResponse.class,
|
||||
description = "ID of the project to create the KMS key for")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.KEY_BITS,
|
||||
type = CommandType.INTEGER,
|
||||
description = "Key size in bits: 128, 192, or 256 (default: 256)")
|
||||
private Integer keyBits;
|
||||
|
||||
@Parameter(name = ApiConstants.HSM_PROFILE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = HSMProfileResponse.class,
|
||||
required = true,
|
||||
description = "ID of HSM profile to create key in")
|
||||
private Long hsmProfileId;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public Integer getKeyBits() {
|
||||
return keyBits != null ? keyBits : 256;
|
||||
}
|
||||
|
||||
public Long getHsmProfileId() {
|
||||
return hsmProfileId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceAllocationException {
|
||||
try {
|
||||
KMSKeyResponse response = kmsManager.createKMSKey(this);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} catch (KMSException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
|
||||
"Failed to create KMS key: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Long accountId = _accountService.finalizeAccountId(accountName, domainId, projectId, true);
|
||||
if (accountId != null) {
|
||||
return accountId;
|
||||
}
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.KmsKey;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cloudstack.api.command.user.kms;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||
import org.apache.cloudstack.api.response.KMSKeyResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.kms.KMSException;
|
||||
import org.apache.cloudstack.kms.KMSKey;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "deleteKMSKey",
|
||||
description = "Deletes a KMS key (only if not in use)",
|
||||
responseObject = SuccessResponse.class,
|
||||
since = "4.23.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User},
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false)
|
||||
public class DeleteKMSKeyCmd extends BaseAsyncCmd implements UserCmd {
|
||||
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
required = true,
|
||||
type = CommandType.UUID,
|
||||
entityType = KMSKeyResponse.class,
|
||||
description = "The UUID of the KMS key to delete")
|
||||
private Long id;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
SuccessResponse response = kmsManager.deleteKMSKey(this);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} catch (KMSException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
|
||||
"Failed to delete KMS key: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
KMSKey key = _entityMgr.findById(KMSKey.class, id);
|
||||
if (key != null) {
|
||||
return key.getAccountId();
|
||||
}
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.KmsKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getApiResourceId() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_KMS_KEY_DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "deleting KMS key: " + getId();
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cloudstack.api.command.user.kms;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||
import org.apache.cloudstack.api.response.HSMProfileResponse;
|
||||
import org.apache.cloudstack.api.response.KMSKeyResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "listKMSKeys",
|
||||
description = "Lists KMS keys available to the caller",
|
||||
responseObject = KMSKeyResponse.class,
|
||||
responseView = ResponseView.Restricted,
|
||||
since = "4.23.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User},
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false)
|
||||
public class ListKMSKeysCmd extends BaseListProjectAndAccountResourcesCmd implements UserCmd {
|
||||
private static final String s_name = "listkmskeysresponse";
|
||||
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = KMSKeyResponse.class,
|
||||
description = "List KMS key by UUID")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = ZoneResponse.class,
|
||||
description = "Filter by zone ID")
|
||||
private Long zoneId;
|
||||
|
||||
@Parameter(name = ApiConstants.ENABLED,
|
||||
type = CommandType.BOOLEAN,
|
||||
description = "Filter by enabled status")
|
||||
private Boolean enabled;
|
||||
|
||||
@Parameter(name = ApiConstants.HSM_PROFILE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = HSMProfileResponse.class,
|
||||
description = "Filter by HSM profile ID")
|
||||
private Long hsmProfileId;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public Long getHsmProfileId() {
|
||||
return hsmProfileId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ListResponse<KMSKeyResponse> listResponse = kmsManager.listKMSKeys(this);
|
||||
listResponse.setResponseName(getCommandName());
|
||||
setResponseObject(listResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.kms;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.AsyncJobResponse;
|
||||
import org.apache.cloudstack.api.response.HSMProfileResponse;
|
||||
import org.apache.cloudstack.api.response.KMSKeyResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.kms.KMSException;
|
||||
import org.apache.cloudstack.kms.KMSKey;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "rotateKMSKey",
|
||||
description = "Rotates KMS key (KEK) by creating new version and scheduling gradual re-encryption",
|
||||
responseObject = AsyncJobResponse.class,
|
||||
since = "4.23.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User},
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false)
|
||||
public class RotateKMSKeyCmd extends BaseAsyncCmd {
|
||||
private static final String s_name = "rotatekmskeyresponse";
|
||||
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
required = true,
|
||||
type = CommandType.UUID,
|
||||
entityType = KMSKeyResponse.class,
|
||||
description = "KMS Key UUID to rotate")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.KEY_BITS,
|
||||
type = CommandType.INTEGER,
|
||||
description = "Key size for new KEK (default: same as current)")
|
||||
private Integer keyBits;
|
||||
|
||||
@Parameter(name = ApiConstants.HSM_PROFILE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = HSMProfileResponse.class,
|
||||
description = "The target HSM profile ID for the new KEK version. If provided, migrates the key to "
|
||||
+ "this HSM.")
|
||||
private Long hsmProfileId;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Integer getKeyBits() {
|
||||
return keyBits;
|
||||
}
|
||||
|
||||
public Long getHsmProfileId() {
|
||||
return hsmProfileId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
kmsManager.rotateKMSKey(this);
|
||||
SuccessResponse response = new SuccessResponse();
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} catch (KMSException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
|
||||
"Failed to rotate KMS key: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
KMSKey key = _entityMgr.findById(KMSKey.class, id);
|
||||
if (key != null) {
|
||||
return key.getAccountId();
|
||||
}
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return com.cloud.event.EventTypes.EVENT_KMS_KEY_ROTATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Rotating KMS key: " + _uuidMgr.getUuid(KMSKey.class, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.KmsKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getApiResourceId() {
|
||||
return getId();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cloudstack.api.command.user.kms;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.KMSKeyResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.kms.KMSException;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "updateKMSKey",
|
||||
description = "Updates KMS key name, description, or enabled status",
|
||||
responseObject = KMSKeyResponse.class,
|
||||
since = "4.23.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User},
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false)
|
||||
public class UpdateKMSKeyCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
required = true,
|
||||
type = CommandType.UUID,
|
||||
entityType = KMSKeyResponse.class,
|
||||
description = "The UUID of the KMS key to update")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME,
|
||||
type = CommandType.STRING,
|
||||
description = "New name for the key")
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.DESCRIPTION,
|
||||
type = CommandType.STRING,
|
||||
description = "New description for the key")
|
||||
private String description;
|
||||
|
||||
@Parameter(name = ApiConstants.ENABLED,
|
||||
type = CommandType.BOOLEAN,
|
||||
description = "whether the key should be enabled")
|
||||
private Boolean enabled;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
KMSKeyResponse response = kmsManager.updateKMSKey(this);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} catch (KMSException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
|
||||
"Failed to update KMS key: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.KmsKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getApiResourceId() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.command.user.kms.hsm;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.HSMProfileResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.kms.KMSException;
|
||||
import org.apache.cloudstack.kms.HSMProfile;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Map;
|
||||
|
||||
@APICommand(name = "createHSMProfile", description = "Creates a new HSM profile", responseObject = HSMProfileResponse.class,
|
||||
requestHasSensitiveInfo = true, responseHasSensitiveInfo = true, since = "4.23.0",
|
||||
authorized = { RoleType.Admin })
|
||||
public class CreateHSMProfileCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true,
|
||||
description = "the name of the HSM profile")
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING,
|
||||
description = "the protocol of the HSM profile (PKCS11, KMIP, etc.). Default is 'pkcs11'")
|
||||
private String protocol;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
|
||||
description = "the zone ID where the HSM profile is available. If null, global scope (for admin only)")
|
||||
private Long zoneId;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class,
|
||||
description = "the domain ID where the HSM profile is available. If specified without an account, "
|
||||
+ "the profile is domain-scoped and usable by all accounts directly in that domain.")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING,
|
||||
description = "the account name of the HSM profile owner. Must be used with domainId. "
|
||||
+ "Leave empty (with a domainId) to create a domain-scoped profile shared by all "
|
||||
+ "accounts in that domain.")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class,
|
||||
description = "the ID of the project to add the HSM profile for")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.IS_PUBLIC, type = CommandType.BOOLEAN,
|
||||
description = "whether this is a public HSM profile available to all users globally (root admin only). "
|
||||
+ "Default is false")
|
||||
private Boolean isPublic;
|
||||
|
||||
@Parameter(name = ApiConstants.VENDOR_NAME, type = CommandType.STRING, description = "the vendor name of the HSM")
|
||||
private String vendorName;
|
||||
|
||||
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
|
||||
description = "HSM configuration details (protocol specific)")
|
||||
private Map<String, String> details;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
if (StringUtils.isBlank(protocol)) {
|
||||
return "pkcs11";
|
||||
}
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public Boolean getIsPublic() {
|
||||
return isPublic != null && isPublic;
|
||||
}
|
||||
|
||||
public String getVendorName() {
|
||||
return vendorName;
|
||||
}
|
||||
|
||||
public Map<String, String> getDetails() {
|
||||
return convertDetailsToMap(details);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
|
||||
ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
HSMProfile profile = kmsManager.addHSMProfile(this);
|
||||
HSMProfileResponse response = kmsManager.createHSMProfileResponse(profile);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} catch (KMSException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Long accountId = _accountService.finalizeAccountId(accountName, domainId, projectId, true);
|
||||
if (accountId != null) {
|
||||
return accountId;
|
||||
}
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.HsmProfile;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.command.user.kms.hsm;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.HSMProfileResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.kms.KMSException;
|
||||
import org.apache.cloudstack.kms.HSMProfile;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "deleteHSMProfile", description = "Deletes an HSM profile", responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.23.0",
|
||||
authorized = { RoleType.Admin })
|
||||
public class DeleteHSMProfileCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HSMProfileResponse.class, required = true,
|
||||
description = "the ID of the HSM profile")
|
||||
private Long id;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
|
||||
ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = kmsManager.deleteHSMProfile(this);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete HSM profile");
|
||||
}
|
||||
} catch (KMSException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
HSMProfile profile = _entityMgr.findById(HSMProfile.class, id);
|
||||
if (profile != null && profile.getAccountId() > 0) {
|
||||
return profile.getAccountId();
|
||||
}
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.HsmProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getApiResourceId() {
|
||||
return getId();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.command.user.kms.hsm;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.HSMProfileResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "listHSMProfiles", description = "Lists HSM profiles", responseObject = HSMProfileResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = true, since = "4.23.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class ListHSMProfilesCmd extends BaseListProjectAndAccountResourcesCmd {
|
||||
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HSMProfileResponse.class,
|
||||
description = "the HSM profile ID")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
|
||||
description = "the zone ID")
|
||||
private Long zoneId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, description = "the protocol of the HSM profile")
|
||||
private String protocol;
|
||||
|
||||
@Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, description = "list only enabled profiles")
|
||||
private Boolean enabled;
|
||||
|
||||
@Parameter(name = ApiConstants.IS_PUBLIC,
|
||||
type = CommandType.BOOLEAN,
|
||||
description = "when true, non-admin users see only system (global) profiles")
|
||||
private Boolean isPublic;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public Boolean getIsPublic() {
|
||||
return isPublic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ListResponse<HSMProfileResponse> response = kmsManager.listHSMProfiles(this);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.command.user.kms.hsm;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.HSMProfileResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.kms.KMSException;
|
||||
import org.apache.cloudstack.kms.HSMProfile;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "updateHSMProfile", description = "Updates an HSM profile",
|
||||
responseObject = HSMProfileResponse.class,
|
||||
requestHasSensitiveInfo = true, responseHasSensitiveInfo = true, since = "4.23.0",
|
||||
authorized = { RoleType.Admin })
|
||||
public class UpdateHSMProfileCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HSMProfileResponse.class, required = true,
|
||||
description = "the ID of the HSM profile")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the HSM profile")
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN,
|
||||
description = "whether the HSM profile is enabled")
|
||||
private Boolean enabled;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
|
||||
ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
HSMProfile profile = kmsManager.updateHSMProfile(this);
|
||||
HSMProfileResponse response = kmsManager.createHSMProfileResponse(profile);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} catch (KMSException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
HSMProfile profile = _entityMgr.findById(HSMProfile.class, id);
|
||||
if (profile != null && profile.getAccountId() > 0) {
|
||||
return profile.getAccountId();
|
||||
}
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.HsmProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getApiResourceId() {
|
||||
return getId();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.schedule;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@APICommand(name = "createResourceSchedule", description = "Create Resource Schedule", responseObject = ResourceScheduleResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.23.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class CreateResourceScheduleCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_TYPE, type = CommandType.STRING, required = true, description = "Type of the resource")
|
||||
private String resourceType;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_ID, type = CommandType.STRING, required = true, description = "ID of the resource for which schedule is to be defined")
|
||||
private String resourceId;
|
||||
|
||||
@Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, required = false, description = "Description of the schedule")
|
||||
private String description;
|
||||
|
||||
@Parameter(name = ApiConstants.SCHEDULE, type = CommandType.STRING, required = true, description = "Schedule for action on resource in cron format. e.g. '0 15 10 * *' for 'at 15:00 on 10th day of every month'")
|
||||
private String schedule;
|
||||
|
||||
@Parameter(name = ApiConstants.TIMEZONE, type = CommandType.STRING, required = true, description = "Specifies a timezone for this command. For more information on the timezone parameter, see TimeZone Format.")
|
||||
private String timeZone;
|
||||
|
||||
@Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, required = true, description = "Action to take on the resource.")
|
||||
private String action;
|
||||
|
||||
@Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, required = false, description = "Start date from which the schedule becomes active. Defaults to current date plus 1 minute. (Format \"yyyy-MM-dd hh:mm:ss\")")
|
||||
private Date startDate;
|
||||
|
||||
@Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, required = false, description = "End date after which the schedule becomes inactive. (Format \"yyyy-MM-dd hh:mm:ss\")")
|
||||
private Date endDate;
|
||||
|
||||
@Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, required = false, description = "Enable schedule. Defaults to true")
|
||||
private Boolean enabled;
|
||||
|
||||
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = false, description = "Map of (key/value pairs) details for the schedule.")
|
||||
private Map details;
|
||||
|
||||
public ApiCommandResourceType getResourceType() {
|
||||
ApiCommandResourceType type = EnumUtils.getEnumIgnoreCase(ApiCommandResourceType.class, resourceType);
|
||||
if (type == null) {
|
||||
throw new InvalidParameterValueException("Unknown resource type: " + resourceType);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getSchedule() {
|
||||
return schedule;
|
||||
}
|
||||
|
||||
public String getTimeZone() {
|
||||
return timeZone;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public Date getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
if (enabled == null) {
|
||||
enabled = true;
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public Map<String, String> getDetails() {
|
||||
return convertDetailsToMap(details);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ResourceScheduleResponse response = resourceScheduleManager.createSchedule(getResourceType(), getResourceId(),
|
||||
getDescription(), getSchedule(), getTimeZone(), getAction(), getStartDate(), getEndDate(), getEnabled(), getDetails());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getAccountId();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.schedule;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "deleteResourceSchedule", description = "Delete Resource Schedule", responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.23.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class DeleteResourceScheduleCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_TYPE, type = CommandType.STRING, required = true, description = "Type of the resource")
|
||||
private String resourceType;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_ID, type = CommandType.STRING, required = true, description = "ID of the resource for which schedules are to be deleted")
|
||||
private String resourceId;
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ResourceScheduleResponse.class, required = false, description = "ID of the schedule to be deleted")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = ResourceScheduleResponse.class, required = false, description = "comma separated list of schedule ids to be deleted")
|
||||
private List<Long> ids;
|
||||
|
||||
public ApiCommandResourceType getResourceType() {
|
||||
ApiCommandResourceType type = EnumUtils.getEnumIgnoreCase(ApiCommandResourceType.class, resourceType);
|
||||
if (type == null) {
|
||||
throw new InvalidParameterValueException("Unknown resource type: " + resourceType);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<Long> getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
resourceScheduleManager.removeSchedule(getResourceType(), getResourceId(), getId(), getIds());
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getAccountId();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.schedule;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "listResourceSchedule", description = "List Resource Schedules", responseObject = ResourceScheduleResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.23.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class ListResourceScheduleCmd extends BaseListCmd {
|
||||
|
||||
@Inject
|
||||
ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ResourceScheduleResponse.class, required = false, description = "ID of the schedule")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = ResourceScheduleResponse.class, required = false, description = "comma separated list of schedule ids")
|
||||
private List<Long> ids;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_TYPE, type = CommandType.STRING, required = true, description = "Type of the resource.")
|
||||
private String resourceType;
|
||||
|
||||
@Parameter(name = ApiConstants.RESOURCE_ID, type = CommandType.STRING, required = true, description = "ID of the resource for which schedules are to be listed.")
|
||||
private String resourceId;
|
||||
|
||||
@Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, required = false, description = "Action to take on the resource.")
|
||||
private String action;
|
||||
|
||||
@Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, required = false, description = "Filter by enabled status.")
|
||||
private Boolean enabled;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<Long> getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public ApiCommandResourceType getResourceType() {
|
||||
ApiCommandResourceType type = EnumUtils.getEnumIgnoreCase(ApiCommandResourceType.class, resourceType);
|
||||
if (type == null) {
|
||||
throw new InvalidParameterValueException("Unknown resource type: " + resourceType);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ListResponse<ResourceScheduleResponse> response = resourceScheduleManager.listSchedule(
|
||||
getId(), getIds(), getResourceType(), getResourceId(), getAction(), getEnabled(),
|
||||
getStartIndex(), getPageSizeVal()
|
||||
);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.schedule;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@APICommand(name = "updateResourceSchedule", description = "Update Resource Schedule", responseObject = ResourceScheduleResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.23.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class UpdateResourceScheduleCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ResourceScheduleResponse.class, required = true, description = "ID of the schedule to be updated")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, required = false, description = "Description of the schedule")
|
||||
private String description;
|
||||
|
||||
@Parameter(name = ApiConstants.SCHEDULE, type = CommandType.STRING, required = false, description = "Schedule for action on resource in cron format.")
|
||||
private String schedule;
|
||||
|
||||
@Parameter(name = ApiConstants.TIMEZONE, type = CommandType.STRING, required = false, description = "Specifies a timezone for this command.")
|
||||
private String timeZone;
|
||||
|
||||
@Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, required = false, description = "Start date from which the schedule becomes active.")
|
||||
private Date startDate;
|
||||
|
||||
@Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, required = false, description = "End date after which the schedule becomes inactive.")
|
||||
private Date endDate;
|
||||
|
||||
@Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, required = false, description = "Enable or disable the schedule.")
|
||||
private Boolean enabled;
|
||||
|
||||
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = false, description = "Map of (key/value pairs) details for the schedule.")
|
||||
private Map details;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getSchedule() {
|
||||
return schedule;
|
||||
}
|
||||
|
||||
public String getTimeZone() {
|
||||
return timeZone;
|
||||
}
|
||||
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public Date getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public Map<String, String> getDetails() {
|
||||
return convertDetailsToMap(details);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ResourceScheduleResponse response = resourceScheduleManager.updateSchedule(getId(), getDescription(), getSchedule(),
|
||||
getTimeZone(), getStartDate(), getEndDate(), getEnabled(), getDetails());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getAccountId();
|
||||
}
|
||||
}
|
||||
|
|
@ -40,12 +40,14 @@ import org.apache.cloudstack.api.command.user.UserCmd;
|
|||
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.KMSKeyResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupResponse;
|
||||
import org.apache.cloudstack.api.response.UserDataResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.kms.KMSKey;
|
||||
import org.apache.cloudstack.vm.lease.VMLeaseManager;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
|
|
@ -126,11 +128,19 @@ public abstract class BaseDeployVMCmd extends BaseAsyncCreateCustomIdCmd impleme
|
|||
since = "4.4")
|
||||
private Long rootdisksize;
|
||||
|
||||
@ACL
|
||||
@Parameter(name = ApiConstants.ROOT_DISK_KMS_KEY_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = KMSKeyResponse.class,
|
||||
description = "ID of the KMS Key to use for root disk encryption",
|
||||
since = "4.23.0")
|
||||
private Long rootDiskKmsKeyId;
|
||||
|
||||
@Parameter(name = ApiConstants.DATADISKS_DETAILS,
|
||||
type = CommandType.MAP,
|
||||
since = "4.21.0",
|
||||
description = "Disk offering details for creating multiple data volumes. Mutually exclusive with diskOfferingId." +
|
||||
" Example: datadisksdetails[0].diskofferingid=a2a73a84-19db-4852-8930-dfddef053341&datadisksdetails[0].size=10&datadisksdetails[0].miniops=100&datadisksdetails[0].maxiops=200")
|
||||
" 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>")
|
||||
private Map dataDisksDetails;
|
||||
|
||||
@Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "an optional group for the virtual machine")
|
||||
|
|
@ -300,6 +310,10 @@ public abstract class BaseDeployVMCmd extends BaseAsyncCreateCustomIdCmd impleme
|
|||
return diskOfferingId;
|
||||
}
|
||||
|
||||
public Long getRootDiskKmsKeyId() {
|
||||
return rootDiskKmsKeyId;
|
||||
}
|
||||
|
||||
public String getDeploymentPlanner() {
|
||||
return deploymentPlanner;
|
||||
}
|
||||
|
|
@ -581,7 +595,19 @@ public abstract class BaseDeployVMCmd extends BaseAsyncCreateCustomIdCmd impleme
|
|||
minIops = Long.parseLong(dataDisk.get(ApiConstants.MIN_IOPS));
|
||||
maxIops = Long.parseLong(dataDisk.get(ApiConstants.MAX_IOPS));
|
||||
}
|
||||
VmDiskInfo vmDiskInfo = new VmDiskInfo(diskOffering, size, minIops, maxIops, deviceId);
|
||||
|
||||
// Extract KMS key ID if provided
|
||||
Long kmsKeyId = null;
|
||||
String kmsKeyUuid = dataDisk.get(ApiConstants.KMS_KEY_ID);
|
||||
if (kmsKeyUuid != null) {
|
||||
KMSKey kmsKey = _entityMgr.findByUuid(org.apache.cloudstack.kms.KMSKey.class, kmsKeyUuid);
|
||||
if (kmsKey == null) {
|
||||
throw new InvalidParameterValueException("Unable to find KMS key " + kmsKeyUuid);
|
||||
}
|
||||
kmsKeyId = kmsKey.getId();
|
||||
}
|
||||
|
||||
VmDiskInfo vmDiskInfo = new VmDiskInfo(diskOffering, size, minIops, maxIops, deviceId, kmsKeyId);
|
||||
vmDiskInfoList.add(vmDiskInfo);
|
||||
}
|
||||
this.dataDiskInfoList = vmDiskInfoList;
|
||||
|
|
|
|||
|
|
@ -22,23 +22,26 @@ import com.cloud.exception.InvalidParameterValueException;
|
|||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VMScheduleResponse;
|
||||
import org.apache.cloudstack.vm.schedule.VMScheduleManager;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Date;
|
||||
|
||||
@Deprecated
|
||||
@APICommand(name = "createVMSchedule", description = "Create Instance Schedule", responseObject = VMScheduleResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class CreateVMScheduleCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
VMScheduleManager vmScheduleManager;
|
||||
ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
|
|
@ -75,14 +78,14 @@ public class CreateVMScheduleCmd extends BaseCmd {
|
|||
type = CommandType.DATE,
|
||||
required = false,
|
||||
description = "Start date from which the schedule becomes active. Defaults to current date plus 1 minute."
|
||||
+ "Use format \"yyyy-MM-dd hh:mm:ss\")")
|
||||
+ "(Format \"yyyy-MM-dd hh:mm:ss\")")
|
||||
private Date startDate;
|
||||
|
||||
@Parameter(name = ApiConstants.END_DATE,
|
||||
type = CommandType.DATE,
|
||||
required = false,
|
||||
description = "End date after which the schedule becomes inactive"
|
||||
+ "Use format \"yyyy-MM-dd hh:mm:ss\")")
|
||||
+ "(Format \"yyyy-MM-dd hh:mm:ss\")")
|
||||
private Date endDate;
|
||||
|
||||
@Parameter(name = ApiConstants.ENABLED,
|
||||
|
|
@ -91,9 +94,9 @@ public class CreateVMScheduleCmd extends BaseCmd {
|
|||
description = "Enable Instance schedule. Defaults to true")
|
||||
private Boolean enabled;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
/// //////////////// Accessors ///////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
|
|
@ -130,13 +133,19 @@ public class CreateVMScheduleCmd extends BaseCmd {
|
|||
return enabled;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
/// //////////// API Implementation///////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
VMScheduleResponse response = vmScheduleManager.createSchedule(this);
|
||||
String resourceIdStr = getVmId() != null ? String.valueOf(getVmId()) : null;
|
||||
|
||||
ResourceScheduleResponse scheduleResponse = resourceScheduleManager.createSchedule(
|
||||
ApiCommandResourceType.VirtualMachine,
|
||||
resourceIdStr, getDescription(), getSchedule(), getTimeZone(), getAction(),
|
||||
getStartDate(), getEndDate(), getEnabled(), null);
|
||||
VMScheduleResponse response = new VMScheduleResponse(scheduleResponse);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.cloud.exception.InvalidParameterValueException;
|
|||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
|
|
@ -30,19 +31,19 @@ import org.apache.cloudstack.api.ServerApiException;
|
|||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VMScheduleResponse;
|
||||
import org.apache.cloudstack.vm.schedule.VMSchedule;
|
||||
import org.apache.cloudstack.vm.schedule.VMScheduleManager;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
@APICommand(name = "deleteVMSchedule", description = "Delete Instance Schedule.", responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class DeleteVMScheduleCmd extends BaseCmd {
|
||||
@Inject
|
||||
VMScheduleManager vmScheduleManager;
|
||||
ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
|
|
@ -50,12 +51,14 @@ public class DeleteVMScheduleCmd extends BaseCmd {
|
|||
required = true,
|
||||
description = "ID of Instance")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = VMScheduleResponse.class,
|
||||
required = false,
|
||||
description = "ID of Instance schedule")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.IDS,
|
||||
type = CommandType.LIST,
|
||||
collectionType = CommandType.UUID,
|
||||
|
|
@ -64,9 +67,9 @@ public class DeleteVMScheduleCmd extends BaseCmd {
|
|||
description = "IDs of Instance schedule")
|
||||
private List<Long> ids;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
/// //////////////// Accessors ///////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
|
|
@ -83,18 +86,21 @@ public class DeleteVMScheduleCmd extends BaseCmd {
|
|||
return vmId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
/// //////////// API Implementation///////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
long rowsRemoved = vmScheduleManager.removeSchedule(this);
|
||||
String resourceIdStr = getVmId() != null ? String.valueOf(getVmId()) : null;
|
||||
long rowsRemoved = resourceScheduleManager.removeSchedule(
|
||||
ApiCommandResourceType.VirtualMachine,
|
||||
resourceIdStr, getId(), getIds());
|
||||
|
||||
if (rowsRemoved > 0) {
|
||||
final SuccessResponse response = new SuccessResponse();
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName(VMSchedule.class.getSimpleName().toLowerCase());
|
||||
response.setObjectName("vmschedule");
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete Instance Schedules");
|
||||
|
|
|
|||
|
|
@ -20,23 +20,27 @@ package org.apache.cloudstack.api.command.user.vm;
|
|||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VMScheduleResponse;
|
||||
import org.apache.cloudstack.vm.schedule.VMSchedule;
|
||||
import org.apache.cloudstack.vm.schedule.VMScheduleManager;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
@APICommand(name = "listVMSchedule", description = "List Instance Schedules.", responseObject = VMScheduleResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class ListVMScheduleCmd extends BaseListCmd {
|
||||
@Inject
|
||||
VMScheduleManager vmScheduleManager;
|
||||
ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
|
|
@ -61,12 +65,12 @@ public class ListVMScheduleCmd extends BaseListCmd {
|
|||
@Parameter(name = ApiConstants.ENABLED,
|
||||
type = CommandType.BOOLEAN,
|
||||
required = false,
|
||||
description = "ID of Instance schedule")
|
||||
description = "Filter by enabled status")
|
||||
private Boolean enabled;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
/// //////////////// Accessors ///////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
|
|
@ -84,14 +88,26 @@ public class ListVMScheduleCmd extends BaseListCmd {
|
|||
return enabled;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
/// //////////// API Implementation///////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
@Override
|
||||
public void execute() {
|
||||
ListResponse<VMScheduleResponse> response = vmScheduleManager.listSchedule(this);
|
||||
String resourceIdStr = getVmId() != null ? String.valueOf(getVmId()) : null;
|
||||
|
||||
ListResponse<ResourceScheduleResponse> scheduleResponse = resourceScheduleManager.listSchedule(
|
||||
getId(), null, ApiCommandResourceType.VirtualMachine, resourceIdStr, getAction(), getEnabled(),
|
||||
getStartIndex(), getPageSizeVal()
|
||||
);
|
||||
|
||||
List<VMScheduleResponse> vmScheduleResponses = new ArrayList<>();
|
||||
for (ResourceScheduleResponse resourceScheduleResponse : scheduleResponse.getResponses()) {
|
||||
vmScheduleResponses.add(new VMScheduleResponse(resourceScheduleResponse));
|
||||
}
|
||||
ListResponse<VMScheduleResponse> response = new ListResponse<>();
|
||||
response.setResponses(vmScheduleResponses, scheduleResponse.getCount());
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName(VMSchedule.class.getSimpleName().toLowerCase());
|
||||
response.setObjectName("vmschedule");
|
||||
setResponseObject(response);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,22 +22,25 @@ import com.cloud.exception.InvalidParameterValueException;
|
|||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.VMScheduleResponse;
|
||||
import org.apache.cloudstack.vm.schedule.VMSchedule;
|
||||
import org.apache.cloudstack.vm.schedule.VMScheduleManager;
|
||||
import org.apache.cloudstack.schedule.ResourceSchedule;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Date;
|
||||
|
||||
@Deprecated
|
||||
@APICommand(name = "updateVMSchedule", description = "Update Instance Schedule.", responseObject = VMScheduleResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class UpdateVMScheduleCmd extends BaseCmd {
|
||||
@Inject
|
||||
VMScheduleManager vmScheduleManager;
|
||||
ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
type = CommandType.UUID,
|
||||
|
|
@ -68,14 +71,14 @@ public class UpdateVMScheduleCmd extends BaseCmd {
|
|||
type = CommandType.DATE,
|
||||
required = false,
|
||||
description = "Start date from which the schedule becomes active"
|
||||
+ "Use format \"yyyy-MM-dd hh:mm:ss\")")
|
||||
+ "(Format \"yyyy-MM-dd hh:mm:ss\")")
|
||||
private Date startDate;
|
||||
|
||||
@Parameter(name = ApiConstants.END_DATE,
|
||||
type = CommandType.DATE,
|
||||
required = false,
|
||||
description = "End date after which the schedule becomes inactive"
|
||||
+ "Use format \"yyyy-MM-dd hh:mm:ss\")")
|
||||
+ "(Format \"yyyy-MM-dd hh:mm:ss\")")
|
||||
private Date endDate;
|
||||
|
||||
@Parameter(name = ApiConstants.ENABLED,
|
||||
|
|
@ -84,9 +87,9 @@ public class UpdateVMScheduleCmd extends BaseCmd {
|
|||
description = "Enable Instance schedule")
|
||||
private Boolean enabled;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
/// //////////////// Accessors ///////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
|
|
@ -116,24 +119,29 @@ public class UpdateVMScheduleCmd extends BaseCmd {
|
|||
return enabled;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
/// //////////// API Implementation///////////////////
|
||||
/// //////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
VMScheduleResponse response = vmScheduleManager.updateSchedule(this);
|
||||
ResourceScheduleResponse scheduleResponse = resourceScheduleManager.updateSchedule(
|
||||
getId(), getDescription(), getSchedule(), getTimeZone(), getStartDate(), getEndDate(), getEnabled(), null);
|
||||
VMScheduleResponse response = new VMScheduleResponse(scheduleResponse);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
VMSchedule vmSchedule = _entityMgr.findById(VMSchedule.class, getId());
|
||||
if (vmSchedule == null) {
|
||||
throw new InvalidParameterValueException(String.format("Unable to find vmSchedule by id=%d", getId()));
|
||||
ResourceSchedule schedule = _entityMgr.findById(ResourceSchedule.class, getId());
|
||||
if (schedule == null || !ApiCommandResourceType.VirtualMachine.equals(schedule.getResourceType())) {
|
||||
throw new InvalidParameterValueException(String.format("Unable to find VM schedule by id=%d", getId()));
|
||||
}
|
||||
VirtualMachine vm = _entityMgr.findById(VirtualMachine.class, schedule.getResourceId());
|
||||
if (vm == null) {
|
||||
throw new InvalidParameterValueException(String.format("Unable to find VM schedule by id=%d", getId()));
|
||||
}
|
||||
VirtualMachine vm = _entityMgr.findById(VirtualMachine.class, vmSchedule.getVmId());
|
||||
return vm.getAccountId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.apache.cloudstack.api.ServerApiException;
|
|||
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.KMSKeyResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.SnapshotResponse;
|
||||
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||
|
|
@ -110,6 +111,13 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd implements UserC
|
|||
description = "The ID of the Instance; to be used with snapshot Id, Instance to which the volume gets attached after creation")
|
||||
private Long virtualMachineId;
|
||||
|
||||
@Parameter(name = ApiConstants.KMS_KEY_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = KMSKeyResponse.class,
|
||||
description = "ID of the KMS Key for volume encryption (required if encryption enabled for zone)",
|
||||
since = "4.23.0")
|
||||
private Long kmsKeyId;
|
||||
|
||||
@Parameter(name = ApiConstants.STORAGE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = StoragePoolResponse.class,
|
||||
|
|
@ -190,6 +198,10 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd implements UserC
|
|||
return virtualMachineId;
|
||||
}
|
||||
|
||||
public Long getKmsKeyId() {
|
||||
return kmsKeyId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.cloudstack.api.command.user.UserCmd;
|
|||
import org.apache.cloudstack.api.response.ClusterResponse;
|
||||
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.KMSKeyResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.PodResponse;
|
||||
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
||||
|
|
@ -90,6 +91,9 @@ public class ListVolumesCmd extends BaseListRetrieveOnlyResourceCountCmd impleme
|
|||
@Parameter(name = ApiConstants.DISK_OFFERING_ID, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "List volumes by disk offering", since = "4.4")
|
||||
private Long diskOfferingId;
|
||||
|
||||
@Parameter(name = ApiConstants.KMS_KEY_ID, type = CommandType.UUID, entityType = KMSKeyResponse.class, description = "List volumes by KMS Key", since = "4.23")
|
||||
private Long kmsKeyId;
|
||||
|
||||
@Parameter(name = ApiConstants.DISPLAY_VOLUME, type = CommandType.BOOLEAN, description = "List resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {
|
||||
RoleType.Admin})
|
||||
private Boolean display;
|
||||
|
|
@ -136,6 +140,10 @@ public class ListVolumesCmd extends BaseListRetrieveOnlyResourceCountCmd impleme
|
|||
return diskOfferingId;
|
||||
}
|
||||
|
||||
public Long getKmsKeyId() {
|
||||
return kmsKeyId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class AttachedIsoResponse extends BaseResponse {
|
||||
|
||||
@SerializedName("id")
|
||||
@Param(description = "The ID of the attached ISO")
|
||||
private String id;
|
||||
|
||||
@SerializedName("name")
|
||||
@Param(description = "The name of the attached ISO")
|
||||
private String name;
|
||||
|
||||
@SerializedName("displaytext")
|
||||
@Param(description = "The display text of the attached ISO")
|
||||
private String displayText;
|
||||
|
||||
@SerializedName("deviceseq")
|
||||
@Param(description = "The cdrom slot that holds this ISO (3=hdc, 4=hdd, ...)")
|
||||
private Integer deviceSeq;
|
||||
|
||||
@SerializedName("bootable")
|
||||
@Param(description = "Whether this is the bootable ISO for the VM")
|
||||
private Boolean bootable;
|
||||
|
||||
public AttachedIsoResponse() {
|
||||
}
|
||||
|
||||
public AttachedIsoResponse(String id, String name, String displayText, Integer deviceSeq, boolean bootable) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.displayText = displayText;
|
||||
this.deviceSeq = deviceSeq;
|
||||
this.bootable = bootable;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDisplayText() {
|
||||
return displayText;
|
||||
}
|
||||
|
||||
public Integer getDeviceSeq() {
|
||||
return deviceSeq;
|
||||
}
|
||||
|
||||
public Boolean getBootable() {
|
||||
return bootable;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.kms.HSMProfile;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = HSMProfile.class)
|
||||
public class HSMProfileResponse extends BaseResponse implements ControlledViewEntityResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the ID of the HSM profile")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.NAME)
|
||||
@Param(description = "the name of the HSM profile")
|
||||
private String name;
|
||||
|
||||
@SerializedName(ApiConstants.PROTOCOL)
|
||||
@Param(description = "the protocol of the HSM profile")
|
||||
private String protocol;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT_ID)
|
||||
@Param(description = "the account ID of the HSM profile owner")
|
||||
private String accountId;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT)
|
||||
@Param(description = "the account name of the HSM profile owner")
|
||||
private String accountName;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_ID)
|
||||
@Param(description = "the domain ID of the HSM profile owner")
|
||||
private String domainId;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN)
|
||||
@Param(description = "the domain name of the HSM profile owner")
|
||||
private String domainName;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_PATH)
|
||||
@Param(description = "the domain path of the HSM profile owner")
|
||||
private String domainPath;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT_ID)
|
||||
@Param(description = "the project ID of the HSM profile owner")
|
||||
private String projectId;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT)
|
||||
@Param(description = "the project name of the HSM profile owner")
|
||||
private String projectName;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_ID)
|
||||
@Param(description = "the zone ID where the HSM profile is available")
|
||||
private String zoneId;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_NAME)
|
||||
@Param(description = "the zone name where the HSM profile is available")
|
||||
private String zoneName;
|
||||
|
||||
@SerializedName("vendor")
|
||||
@Param(description = "the vendor name of the HSM profile")
|
||||
private String vendorName;
|
||||
|
||||
@SerializedName(ApiConstants.STATE)
|
||||
@Param(description = "the state of the HSM profile")
|
||||
private String state;
|
||||
|
||||
@SerializedName(ApiConstants.ENABLED)
|
||||
@Param(description = "whether the HSM profile is enabled")
|
||||
private Boolean enabled;
|
||||
|
||||
@SerializedName(ApiConstants.IS_PUBLIC)
|
||||
@Param(description = "whether this is a system HSM profile available to all users globally")
|
||||
private Boolean isPublic;
|
||||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "the date the HSM profile was created")
|
||||
private Date created;
|
||||
|
||||
@SerializedName(ApiConstants.DETAILS)
|
||||
@Param(description = "HSM configuration details (sensitive values are encrypted)")
|
||||
private Map<String, String> details;
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void setAccountId(String accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainId(String domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainName(String domainName) {
|
||||
this.domainName = domainName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainPath(String domainPath) {
|
||||
this.domainPath = domainPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProjectId(String projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProjectName(String projectName) {
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
public void setZoneId(String zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public void setZoneName(String zoneName) {
|
||||
this.zoneName = zoneName;
|
||||
}
|
||||
|
||||
public void setVendorName(String vendorName) {
|
||||
this.vendorName = vendorName;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void setIsPublic(Boolean isPublic) {
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public void setDetails(Map<String, String> details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public String getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public String getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public String getDomainName() {
|
||||
return domainName;
|
||||
}
|
||||
|
||||
public String getDomainPath() {
|
||||
return domainPath;
|
||||
}
|
||||
|
||||
public String getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public String getProjectName() {
|
||||
return projectName;
|
||||
}
|
||||
|
||||
public String getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public String getZoneName() {
|
||||
return zoneName;
|
||||
}
|
||||
|
||||
public String getVendorName() {
|
||||
return vendorName;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public Boolean getPublic() {
|
||||
return isPublic;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public Map<String, String> getDetails() {
|
||||
return details;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.kms.KMSKey;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@EntityReference(value = KMSKey.class)
|
||||
public class KMSKeyResponse extends BaseResponse implements ControlledViewEntityResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the UUID of the key")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.NAME)
|
||||
@Param(description = "the name of the key")
|
||||
private String name;
|
||||
|
||||
@SerializedName(ApiConstants.DESCRIPTION)
|
||||
@Param(description = "the description of the key")
|
||||
private String description;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT)
|
||||
@Param(description = "the account owning the key")
|
||||
private String accountName;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT_ID)
|
||||
@Param(description = "the account ID owning the key")
|
||||
private String accountId;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_ID)
|
||||
@Param(description = "the domain ID of the key")
|
||||
private String domainId;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN)
|
||||
@Param(description = "the domain name of the key")
|
||||
private String domainName;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_PATH)
|
||||
@Param(description = "the domain path of the key")
|
||||
private String domainPath;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_ID)
|
||||
@Param(description = "the zone ID where the key is valid")
|
||||
private String zoneId;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_NAME)
|
||||
@Param(description = "the zone name where the key is valid")
|
||||
private String zoneName;
|
||||
|
||||
@SerializedName(ApiConstants.HSM_PROFILE_ID)
|
||||
@Param(description = "the zone ID where the key is valid")
|
||||
private String hsmProfileId;
|
||||
|
||||
@SerializedName(ApiConstants.HSM_PROFILE)
|
||||
@Param(description = "the zone name where the key is valid")
|
||||
private String hsmProfileName;
|
||||
|
||||
@SerializedName(ApiConstants.ALGORITHM)
|
||||
@Param(description = "the encryption algorithm")
|
||||
private String algorithm;
|
||||
|
||||
@SerializedName(ApiConstants.KEY_BITS)
|
||||
@Param(description = "the key size in bits")
|
||||
private Integer keyBits;
|
||||
|
||||
@SerializedName(ApiConstants.VERSION)
|
||||
@Param(description = "the key size in bits")
|
||||
private Integer version;
|
||||
|
||||
@SerializedName(ApiConstants.ENABLED)
|
||||
@Param(description = "whether the key is enabled")
|
||||
private Boolean enabled;
|
||||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "the creation timestamp")
|
||||
private Date created;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT_ID)
|
||||
@Param(description = "the project ID of the key")
|
||||
private String projectId;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT)
|
||||
@Param(description = "the project name of the key")
|
||||
private String projectName;
|
||||
|
||||
@SerializedName(ApiConstants.KEK_LABEL)
|
||||
@Param(description = "the provider-specific KEK label (admin only)", authorized = { RoleType.Admin })
|
||||
private String kekLabel;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProjectId(String projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProjectName(String projectName) {
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
public String getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(String accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public String getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainId(String domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public String getDomainName() {
|
||||
return domainName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainName(String domainName) {
|
||||
this.domainName = domainName;
|
||||
}
|
||||
|
||||
public String getDomainPath() {
|
||||
return domainPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainPath(String domainPath) {
|
||||
this.domainPath = domainPath;
|
||||
}
|
||||
|
||||
public String getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public void setZoneId(String zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public String getZoneName() {
|
||||
return zoneName;
|
||||
}
|
||||
|
||||
public void setZoneName(String zoneName) {
|
||||
this.zoneName = zoneName;
|
||||
}
|
||||
|
||||
public String getHsmProfileId() {
|
||||
return hsmProfileId;
|
||||
}
|
||||
|
||||
public void setHsmProfileId(String hsmProfileId) {
|
||||
this.hsmProfileId = hsmProfileId;
|
||||
}
|
||||
|
||||
public String getHsmProfileName() {
|
||||
return hsmProfileName;
|
||||
}
|
||||
|
||||
public void setHsmProfileName(String hsmProfileName) {
|
||||
this.hsmProfileName = hsmProfileName;
|
||||
}
|
||||
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public void setAlgorithm(String algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public Integer getKeyBits() {
|
||||
return keyBits;
|
||||
}
|
||||
|
||||
public void setKeyBits(Integer keyBits) {
|
||||
this.keyBits = keyBits;
|
||||
}
|
||||
|
||||
public Integer getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getKekLabel() {
|
||||
return kekLabel;
|
||||
}
|
||||
|
||||
public void setKekLabel(String kekLabel) {
|
||||
this.kekLabel = kekLabel;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.schedule.ResourceSchedule;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = ResourceSchedule.class)
|
||||
public class ResourceScheduleResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "The ID of resource schedule")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_TYPE)
|
||||
@Param(description = "Type of the resource")
|
||||
private ApiCommandResourceType resourceType;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ID)
|
||||
@Param(description = "ID of the resource")
|
||||
private String resourceId;
|
||||
|
||||
@SerializedName(ApiConstants.DESCRIPTION)
|
||||
@Param(description = "Description of resource schedule")
|
||||
private String description;
|
||||
|
||||
@SerializedName(ApiConstants.SCHEDULE)
|
||||
@Param(description = "Cron formatted resource schedule")
|
||||
private String schedule;
|
||||
|
||||
@SerializedName(ApiConstants.TIMEZONE)
|
||||
@Param(description = "Timezone of the schedule")
|
||||
private String timeZone;
|
||||
|
||||
@SerializedName(ApiConstants.ACTION)
|
||||
@Param(description = "Action")
|
||||
private ResourceSchedule.Action action;
|
||||
|
||||
@SerializedName(ApiConstants.ENABLED)
|
||||
@Param(description = "Resource schedule is enabled")
|
||||
private boolean enabled;
|
||||
|
||||
@SerializedName(ApiConstants.START_DATE)
|
||||
@Param(description = "Date from which the schedule is active")
|
||||
private Date startDate;
|
||||
|
||||
@SerializedName(ApiConstants.END_DATE)
|
||||
@Param(description = "Date after which the schedule becomes inactive")
|
||||
private Date endDate;
|
||||
|
||||
@SerializedName(ApiConstants.DETAILS)
|
||||
@Param(description = "Schedule details")
|
||||
private Map<String, String> details;
|
||||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "Date when the schedule was created")
|
||||
private Date created;
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setResourceType(ApiCommandResourceType resourceType) {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
public ApiCommandResourceType getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setSchedule(String schedule) {
|
||||
this.schedule = schedule;
|
||||
}
|
||||
|
||||
public String getSchedule() {
|
||||
return schedule;
|
||||
}
|
||||
|
||||
public void setTimeZone(String timeZone) {
|
||||
this.timeZone = timeZone;
|
||||
}
|
||||
|
||||
public String getTimeZone() {
|
||||
return timeZone;
|
||||
}
|
||||
|
||||
public void setAction(ResourceSchedule.Action action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public ResourceSchedule.Action getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setStartDate(Date startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public void setEndDate(Date endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public Date getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
public void setDetails(Map<String, String> details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public Map<String, String> getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
}
|
||||
|
|
@ -166,6 +166,14 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
|||
@Param(description = "An alternate display text of the ISO attached to the Instance")
|
||||
private String isoDisplayText;
|
||||
|
||||
@SerializedName("isos")
|
||||
@Param(description = "All ISOs attached to the Instance, keyed by cdrom slot. The first entry mirrors isoid/isoname for back-compat.", responseObject = AttachedIsoResponse.class, since = "4.23.0")
|
||||
private List<AttachedIsoResponse> isos;
|
||||
|
||||
@SerializedName("isomaxcount")
|
||||
@Param(description = "Maximum number of ISOs that may be attached to this Instance, after applying the cluster-scoped vm.iso.max.count and the hypervisor's own cap.", since = "4.23.0")
|
||||
private Integer isoMaxCount;
|
||||
|
||||
@SerializedName(ApiConstants.SERVICE_OFFERING_ID)
|
||||
@Param(description = "The ID of the service offering of the Instance")
|
||||
private String serviceOfferingId;
|
||||
|
|
@ -871,6 +879,22 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
|||
this.isoId = isoId;
|
||||
}
|
||||
|
||||
public void setIsos(List<AttachedIsoResponse> isos) {
|
||||
this.isos = isos;
|
||||
}
|
||||
|
||||
public List<AttachedIsoResponse> getIsos() {
|
||||
return isos;
|
||||
}
|
||||
|
||||
public void setIsoMaxCount(Integer isoMaxCount) {
|
||||
this.isoMaxCount = isoMaxCount;
|
||||
}
|
||||
|
||||
public Integer getIsoMaxCount() {
|
||||
return isoMaxCount;
|
||||
}
|
||||
|
||||
public void setIsoName(String isoName) {
|
||||
this.isoName = isoName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ import com.google.gson.annotations.SerializedName;
|
|||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.vm.schedule.VMSchedule;
|
||||
import org.apache.cloudstack.schedule.ResourceSchedule;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@EntityReference(value = VMSchedule.class)
|
||||
@EntityReference(value = ResourceSchedule.class)
|
||||
public class VMScheduleResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "The ID of Instance schedule")
|
||||
|
|
@ -51,7 +51,7 @@ public class VMScheduleResponse extends BaseResponse {
|
|||
|
||||
@SerializedName(ApiConstants.ACTION)
|
||||
@Param(description = "Action")
|
||||
private VMSchedule.Action action;
|
||||
private ResourceSchedule.Action action;
|
||||
|
||||
@SerializedName(ApiConstants.ENABLED)
|
||||
@Param(description = "VM schedule is enabled")
|
||||
|
|
@ -69,6 +69,20 @@ public class VMScheduleResponse extends BaseResponse {
|
|||
@Param(description = "Date when the schedule was created")
|
||||
private Date created;
|
||||
|
||||
public VMScheduleResponse(ResourceScheduleResponse scheduleResponse) {
|
||||
super("vmschedule");
|
||||
this.id = scheduleResponse.getId();
|
||||
this.vmId = scheduleResponse.getResourceId();
|
||||
this.description = scheduleResponse.getDescription();
|
||||
this.schedule = scheduleResponse.getSchedule();
|
||||
this.timeZone = scheduleResponse.getTimeZone();
|
||||
this.action = scheduleResponse.getAction();
|
||||
this.enabled = scheduleResponse.getEnabled();
|
||||
this.startDate = scheduleResponse.getStartDate();
|
||||
this.endDate = scheduleResponse.getEndDate();
|
||||
this.created = scheduleResponse.getCreated();
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
|
@ -89,7 +103,7 @@ public class VMScheduleResponse extends BaseResponse {
|
|||
this.timeZone = timeZone;
|
||||
}
|
||||
|
||||
public void setAction(VMSchedule.Action action) {
|
||||
public void setAction(ResourceSchedule.Action action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
|
|
@ -105,5 +119,7 @@ public class VMScheduleResponse extends BaseResponse {
|
|||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {this.created = created;}
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -309,6 +309,18 @@ public class VolumeResponse extends BaseResponseWithTagInformation implements Co
|
|||
@Param(description = "the format of the disk encryption if applicable", since = "4.19.1")
|
||||
private String encryptionFormat;
|
||||
|
||||
@SerializedName(ApiConstants.KMS_KEY)
|
||||
@Param(description = "KMS key name of the volume", since = "4.23.0")
|
||||
private String kmsKey;
|
||||
|
||||
@SerializedName(ApiConstants.KMS_KEY_ID)
|
||||
@Param(description = "KMS key id of the volume", since = "4.23.0")
|
||||
private String kmsKeyId;
|
||||
|
||||
@SerializedName(ApiConstants.KMS_KEY_VERSION)
|
||||
@Param(description = "Version number of the KMS key used for disk encryption if applicable", since = "4.23.0")
|
||||
private Integer kmsKeyVersion;
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
|
@ -868,7 +880,35 @@ public class VolumeResponse extends BaseResponseWithTagInformation implements Co
|
|||
this.volumeRepairResult = volumeRepairResult;
|
||||
}
|
||||
|
||||
public String getEncryptionFormat() {
|
||||
return encryptionFormat;
|
||||
}
|
||||
|
||||
public void setEncryptionFormat(String encryptionFormat) {
|
||||
this.encryptionFormat = encryptionFormat;
|
||||
}
|
||||
|
||||
public String getKmsKey() {
|
||||
return kmsKey;
|
||||
}
|
||||
|
||||
public void setKmsKey(String kmsKey) {
|
||||
this.kmsKey = kmsKey;
|
||||
}
|
||||
|
||||
public String getKmsKeyId() {
|
||||
return kmsKeyId;
|
||||
}
|
||||
|
||||
public void setKmsKeyId(String kmsKeyId) {
|
||||
this.kmsKeyId = kmsKeyId;
|
||||
}
|
||||
|
||||
public Integer getKmsKeyVersion() {
|
||||
return kmsKeyVersion;
|
||||
}
|
||||
|
||||
public void setKmsKeyVersion(Integer kmsKeyVersion) {
|
||||
this.kmsKeyVersion = kmsKeyVersion;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public interface HSMProfile extends Identity, InternalIdentity, ControlledEntity {
|
||||
String getName();
|
||||
|
||||
String getProtocol();
|
||||
|
||||
long getAccountId();
|
||||
|
||||
long getDomainId();
|
||||
|
||||
Long getZoneId();
|
||||
|
||||
String getVendorName();
|
||||
|
||||
boolean isEnabled();
|
||||
|
||||
boolean getIsPublic();
|
||||
|
||||
Date getCreated();
|
||||
|
||||
Date getRemoved();
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cloudstack.kms;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.framework.kms.KeyPurpose;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* KMS Key (Key Encryption Key) metadata.
|
||||
* Represents a KEK that can be used to wrap/unwrap Data Encryption Keys (DEKs).
|
||||
* KEKs are account-scoped and used for envelope encryption.
|
||||
*/
|
||||
public interface KMSKey extends Identity, InternalIdentity, ControlledEntity {
|
||||
|
||||
String getName();
|
||||
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* Provider-specific KEK label/ID (internal identifier used by the KMS provider)
|
||||
*/
|
||||
String getKekLabel();
|
||||
|
||||
KeyPurpose getPurpose();
|
||||
|
||||
Long getZoneId();
|
||||
|
||||
String getAlgorithm();
|
||||
|
||||
Integer getKeyBits();
|
||||
|
||||
boolean isEnabled();
|
||||
|
||||
Date getCreated();
|
||||
|
||||
Date getRemoved();
|
||||
|
||||
Long getHsmProfileId();
|
||||
}
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms;
|
||||
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import org.apache.cloudstack.api.command.admin.kms.MigrateVolumesToKMSCmd;
|
||||
import org.apache.cloudstack.api.command.user.kms.RotateKMSKeyCmd;
|
||||
import org.apache.cloudstack.api.command.user.kms.CreateKMSKeyCmd;
|
||||
import org.apache.cloudstack.api.command.user.kms.DeleteKMSKeyCmd;
|
||||
import org.apache.cloudstack.api.command.user.kms.ListKMSKeysCmd;
|
||||
import org.apache.cloudstack.api.command.user.kms.UpdateKMSKeyCmd;
|
||||
import org.apache.cloudstack.api.command.user.kms.hsm.CreateHSMProfileCmd;
|
||||
import org.apache.cloudstack.api.command.user.kms.hsm.DeleteHSMProfileCmd;
|
||||
import org.apache.cloudstack.api.command.user.kms.hsm.ListHSMProfilesCmd;
|
||||
import org.apache.cloudstack.api.command.user.kms.hsm.UpdateHSMProfileCmd;
|
||||
import org.apache.cloudstack.api.response.HSMProfileResponse;
|
||||
import org.apache.cloudstack.api.response.KMSKeyResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.framework.kms.KMSException;
|
||||
import org.apache.cloudstack.framework.kms.KMSProvider;
|
||||
import org.apache.cloudstack.framework.kms.WrappedKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface KMSManager extends Manager, Configurable {
|
||||
|
||||
ConfigKey<Integer> KMSDekSizeBits = new ConfigKey<>(
|
||||
"Advanced",
|
||||
Integer.class,
|
||||
"kms.dek.size.bits",
|
||||
"256",
|
||||
"The size of Data Encryption Keys (DEK) in bits (128, 192, or 256)",
|
||||
true,
|
||||
ConfigKey.Scope.Global
|
||||
);
|
||||
|
||||
ConfigKey<Integer> KMSRetryCount = new ConfigKey<>(
|
||||
"Advanced",
|
||||
Integer.class,
|
||||
"kms.retry.count",
|
||||
"3",
|
||||
"Number of retry attempts for transient KMS failures",
|
||||
true,
|
||||
ConfigKey.Scope.Global
|
||||
);
|
||||
|
||||
ConfigKey<Integer> KMSRetryDelayMs = new ConfigKey<>(
|
||||
"Advanced",
|
||||
Integer.class,
|
||||
"kms.retry.delay.ms",
|
||||
"1000",
|
||||
"Delay in milliseconds between KMS retry attempts (exponential backoff)",
|
||||
true,
|
||||
ConfigKey.Scope.Global
|
||||
);
|
||||
|
||||
ConfigKey<Integer> KMSOperationTimeoutSec = new ConfigKey<>(
|
||||
"Advanced",
|
||||
Integer.class,
|
||||
"kms.operation.timeout.sec",
|
||||
"30",
|
||||
"Timeout in seconds for KMS cryptographic operations",
|
||||
true,
|
||||
ConfigKey.Scope.Global
|
||||
);
|
||||
|
||||
ConfigKey<Integer> KMSRewrapBatchSize = new ConfigKey<>(
|
||||
"Advanced",
|
||||
Integer.class,
|
||||
"kms.rewrap.batch.size",
|
||||
"50",
|
||||
"Number of wrapped keys to rewrap per batch in background job",
|
||||
true,
|
||||
ConfigKey.Scope.Global
|
||||
);
|
||||
|
||||
ConfigKey<Long> KMSRewrapIntervalMs = new ConfigKey<>(
|
||||
"Advanced",
|
||||
Long.class,
|
||||
"kms.rewrap.interval.ms",
|
||||
"300000",
|
||||
"Interval in milliseconds between background rewrap job executions (default: 5 minutes)",
|
||||
true,
|
||||
ConfigKey.Scope.Global
|
||||
);
|
||||
|
||||
ConfigKey<Integer> KMSOperationPoolCoreSize = new ConfigKey<>(
|
||||
"Advanced",
|
||||
Integer.class,
|
||||
"kms.operation.pool.core.size",
|
||||
"2",
|
||||
"Minimum number of threads kept alive for KMS cryptographic operations",
|
||||
true,
|
||||
ConfigKey.Scope.Global
|
||||
);
|
||||
|
||||
ConfigKey<Integer> KMSOperationPoolMaxSize = new ConfigKey<>(
|
||||
"Advanced",
|
||||
Integer.class,
|
||||
"kms.operation.pool.max.size",
|
||||
"100",
|
||||
"Maximum number of concurrent threads for KMS cryptographic operations. " +
|
||||
"Set this to match the concurrency limit of your HSM appliance or external KMS provider.",
|
||||
true,
|
||||
ConfigKey.Scope.Global
|
||||
);
|
||||
|
||||
/**
|
||||
* List all registered KMS providers
|
||||
*
|
||||
* @return list of available providers
|
||||
*/
|
||||
List<? extends KMSProvider> listKMSProviders();
|
||||
|
||||
/**
|
||||
* Get a specific KMS provider by name
|
||||
*
|
||||
* @param name provider name
|
||||
* @return the provider, or null if not found
|
||||
*/
|
||||
KMSProvider getKMSProvider(String name);
|
||||
|
||||
/**
|
||||
* Check if caller has permission to use a KMS key
|
||||
*
|
||||
* @param callerAccountId the caller's account ID
|
||||
* @param key the KMS key
|
||||
* @return true if caller has permission
|
||||
*/
|
||||
boolean hasPermission(Long callerAccountId, KMSKey key);
|
||||
|
||||
/**
|
||||
* Validates that the KMS key can be used for volume encryption: key exists, not deleted,
|
||||
* owner account matches the volume owner, key state is Enabled, and key purpose is VOLUME_ENCRYPTION.
|
||||
* No-op if kmsKeyId is null.
|
||||
*
|
||||
* @param owner the account that will own the volume
|
||||
* @param kmsKeyId the KMS key database ID
|
||||
* @param zoneId the zone ID of the target resource (volume/VM)
|
||||
* @throws InvalidParameterValueException if key not found, disabled, wrong purpose, zone mismatch, or account mismatch
|
||||
*/
|
||||
void checkKmsKeyForVolumeEncryption(Account owner, Long kmsKeyId, Long zoneId);
|
||||
|
||||
/**
|
||||
* Unwrap a DEK by wrapped key ID, trying multiple KEK versions if needed
|
||||
*
|
||||
* @param wrappedKeyId the wrapped key database ID
|
||||
* @return plaintext DEK (caller must zeroize!)
|
||||
* @throws KMSException if unwrap fails
|
||||
*/
|
||||
byte[] unwrapKey(Long wrappedKeyId) throws KMSException;
|
||||
|
||||
/**
|
||||
* Generate and wrap a DEK using a specific KMS key UUID
|
||||
*
|
||||
* @param kmsKey the KMS key
|
||||
* @param callerAccountId the caller's account ID
|
||||
* @return wrapped key ready for database storage
|
||||
* @throws KMSException if operation fails
|
||||
*/
|
||||
WrappedKey generateVolumeKeyWithKek(KMSKey kmsKey, Long callerAccountId) throws KMSException;
|
||||
|
||||
/**
|
||||
* Create a KMS key and return the response object.
|
||||
* Handles validation, account resolution, and permission checks.
|
||||
*
|
||||
* @param cmd the create command with all parameters
|
||||
* @return KMSKeyResponse
|
||||
* @throws KMSException if creation fails
|
||||
*/
|
||||
KMSKeyResponse createKMSKey(CreateKMSKeyCmd cmd) throws KMSException;
|
||||
|
||||
/**
|
||||
* List KMS keys and return the response object.
|
||||
* Handles validation and permission checks.
|
||||
*
|
||||
* @param cmd the list command with all parameters
|
||||
* @return ListResponse with KMSKeyResponse objects
|
||||
*/
|
||||
ListResponse<KMSKeyResponse> listKMSKeys(ListKMSKeysCmd cmd);
|
||||
|
||||
/**
|
||||
* Update a KMS key and return the response object.
|
||||
* Handles validation and permission checks.
|
||||
*
|
||||
* @param cmd the update command with all parameters
|
||||
* @return KMSKeyResponse
|
||||
* @throws KMSException if update fails
|
||||
*/
|
||||
KMSKeyResponse updateKMSKey(UpdateKMSKeyCmd cmd) throws KMSException;
|
||||
|
||||
boolean deleteKMSWrappedKey(Volume vol) throws KMSException;
|
||||
|
||||
/**
|
||||
* Delete a KMS key and return the response object.
|
||||
* Handles validation and permission checks.
|
||||
*
|
||||
* @param cmd the delete command with all parameters
|
||||
* @return SuccessResponse
|
||||
* @throws KMSException if deletion fails
|
||||
*/
|
||||
SuccessResponse deleteKMSKey(DeleteKMSKeyCmd cmd) throws KMSException;
|
||||
|
||||
/**
|
||||
* Rotate KEK by creating new version and scheduling gradual re-encryption
|
||||
*
|
||||
* @param cmd the rotate command with all parameters
|
||||
* @return New KEK version UUID
|
||||
* @throws KMSException if rotation fails
|
||||
*/
|
||||
String rotateKMSKey(RotateKMSKeyCmd cmd) throws KMSException;
|
||||
|
||||
/**
|
||||
* Migrate passphrase-based volumes to KMS encryption
|
||||
*
|
||||
* @param cmd the migrate command with all parameters
|
||||
* @return Number of volumes successfully migrated
|
||||
* @throws KMSException if migration fails
|
||||
*/
|
||||
int migrateVolumesToKMS(MigrateVolumesToKMSCmd cmd) throws KMSException;
|
||||
|
||||
/**
|
||||
* Delete all KMS keys owned by an account (called during account cleanup)
|
||||
*
|
||||
* @param accountId the account ID
|
||||
* @return true if all keys were successfully deleted
|
||||
*/
|
||||
boolean deleteKMSKeysByAccountId(Long accountId);
|
||||
|
||||
/**
|
||||
* Add a new HSM profile
|
||||
*
|
||||
* @param cmd the add command
|
||||
* @return the created HSM profile
|
||||
* @throws KMSException if addition fails
|
||||
*/
|
||||
HSMProfile addHSMProfile(CreateHSMProfileCmd cmd) throws KMSException;
|
||||
|
||||
/**
|
||||
* List HSM profiles
|
||||
*
|
||||
* @param cmd the list command
|
||||
* @return list of HSM profiles
|
||||
*/
|
||||
ListResponse<HSMProfileResponse> listHSMProfiles(ListHSMProfilesCmd cmd);
|
||||
|
||||
/**
|
||||
* Delete an HSM profile
|
||||
*
|
||||
* @param cmd the delete command
|
||||
* @return true if deletion was successful
|
||||
* @throws KMSException if deletion fails
|
||||
*/
|
||||
boolean deleteHSMProfile(DeleteHSMProfileCmd cmd) throws KMSException;
|
||||
|
||||
/**
|
||||
* Update an HSM profile
|
||||
*
|
||||
* @param cmd the update command
|
||||
* @return the updated HSM profile
|
||||
* @throws KMSException if update fails
|
||||
*/
|
||||
HSMProfile updateHSMProfile(UpdateHSMProfileCmd cmd) throws KMSException;
|
||||
|
||||
/**
|
||||
* Create a response object for an HSM profile
|
||||
*
|
||||
* @param profile the HSM profile
|
||||
* @return the response object
|
||||
*/
|
||||
HSMProfileResponse createHSMProfileResponse(HSMProfile profile);
|
||||
}
|
||||
|
|
@ -16,20 +16,31 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.vm.schedule;
|
||||
package org.apache.cloudstack.schedule;
|
||||
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.Date;
|
||||
|
||||
public interface VMSchedule extends Identity, InternalIdentity {
|
||||
enum Action {
|
||||
START, STOP, REBOOT, FORCE_STOP, FORCE_REBOOT
|
||||
public interface ResourceSchedule extends Identity, InternalIdentity {
|
||||
|
||||
/**
|
||||
* Common contract for scheduler actions. Each provider defines its own enum
|
||||
* implementing this interface so the generic machinery can call {@link #name()}
|
||||
* and {@link #getEventType()} without knowing the concrete type.
|
||||
*/
|
||||
interface Action {
|
||||
String name();
|
||||
|
||||
String getEventType();
|
||||
}
|
||||
|
||||
long getVmId();
|
||||
ApiCommandResourceType getResourceType();
|
||||
|
||||
long getResourceId();
|
||||
|
||||
String getDescription();
|
||||
|
||||
|
|
@ -37,7 +48,7 @@ public interface VMSchedule extends Identity, InternalIdentity {
|
|||
|
||||
String getTimeZone();
|
||||
|
||||
Action getAction();
|
||||
String getActionName();
|
||||
|
||||
boolean getEnabled();
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.schedule;
|
||||
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface ResourceScheduleManager {
|
||||
|
||||
ResourceScheduleResponse createSchedule(ApiCommandResourceType resourceType, String resourceUuid,
|
||||
String description, String schedule, String timeZone, String action,
|
||||
Date startDate, Date endDate, boolean enabled, Map<String, String> details);
|
||||
|
||||
ResourceScheduleResponse updateSchedule(Long id, String description, String schedule, String timeZone,
|
||||
Date startDate, Date endDate, Boolean enabled, Map<String, String> details);
|
||||
|
||||
ListResponse<ResourceScheduleResponse> listSchedule(Long id, List<Long> ids, ApiCommandResourceType resourceType,
|
||||
String resourceUuid, String action, Boolean enabled,
|
||||
Long startIndex, Long pageSize);
|
||||
|
||||
Long removeSchedule(ApiCommandResourceType resourceType, String resourceUuid, Long id, List<Long> ids);
|
||||
|
||||
void removeSchedulesForResource(ApiCommandResourceType resourceType, long resourceId);
|
||||
}
|
||||
|
|
@ -16,23 +16,26 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.vm.schedule;
|
||||
package org.apache.cloudstack.schedule;
|
||||
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public interface VMScheduledJob extends Identity, InternalIdentity {
|
||||
long getVmId();
|
||||
public interface ResourceScheduledJob extends Identity, InternalIdentity {
|
||||
ApiCommandResourceType getResourceType();
|
||||
|
||||
long getVmScheduleId();
|
||||
long getResourceId();
|
||||
|
||||
long getScheduleId();
|
||||
|
||||
Long getAsyncJobId();
|
||||
|
||||
void setAsyncJobId(long asyncJobId);
|
||||
|
||||
VMSchedule.Action getAction();
|
||||
String getActionName();
|
||||
|
||||
Date getScheduledTime();
|
||||
}
|
||||
|
|
@ -16,21 +16,16 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.vm.schedule.dao;
|
||||
package org.apache.cloudstack.schedule.autoscale;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.vm.schedule.VMScheduledJobVO;
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.schedule.ResourceSchedule;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface VMScheduledJobDao extends GenericDao<VMScheduledJobVO, Long> {
|
||||
|
||||
List<VMScheduledJobVO> listJobsToStart(Date currentTimestamp);
|
||||
|
||||
int expungeJobsForSchedules(List<Long> scheduleId, Date dateAfter);
|
||||
|
||||
int expungeJobsBefore(Date currentTimestamp);
|
||||
|
||||
VMScheduledJobVO findByScheduleAndTimestamp(long scheduleId, Date scheduledTimestamp);
|
||||
public enum AutoScaleScheduleAction implements ResourceSchedule.Action {
|
||||
UPDATE {
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_AUTOSCALEVMGROUP_SCHEDULE_UPDATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.schedule.vm;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.schedule.ResourceSchedule;
|
||||
|
||||
public enum VMScheduleAction implements ResourceSchedule.Action {
|
||||
START {
|
||||
@Override
|
||||
public String getEventType() { return EventTypes.EVENT_VM_SCHEDULE_START; }
|
||||
},
|
||||
STOP {
|
||||
@Override
|
||||
public String getEventType() { return EventTypes.EVENT_VM_SCHEDULE_STOP; }
|
||||
},
|
||||
REBOOT {
|
||||
@Override
|
||||
public String getEventType() { return EventTypes.EVENT_VM_SCHEDULE_REBOOT; }
|
||||
},
|
||||
FORCE_STOP {
|
||||
@Override
|
||||
public String getEventType() { return EventTypes.EVENT_VM_SCHEDULE_FORCE_STOP; }
|
||||
},
|
||||
FORCE_REBOOT {
|
||||
@Override
|
||||
public String getEventType() { return EventTypes.EVENT_VM_SCHEDULE_FORCE_REBOOT; }
|
||||
};
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.vm.schedule;
|
||||
|
||||
import org.apache.cloudstack.api.command.user.vm.CreateVMScheduleCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.DeleteVMScheduleCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ListVMScheduleCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.UpdateVMScheduleCmd;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.VMScheduleResponse;
|
||||
|
||||
public interface VMScheduleManager {
|
||||
VMScheduleResponse createSchedule(CreateVMScheduleCmd createVMScheduleCmd);
|
||||
|
||||
VMScheduleResponse createResponse(VMSchedule vmSchedule);
|
||||
|
||||
ListResponse<VMScheduleResponse> listSchedule(ListVMScheduleCmd listVMScheduleCmd);
|
||||
|
||||
VMScheduleResponse updateSchedule(UpdateVMScheduleCmd updateVMScheduleCmd);
|
||||
|
||||
long removeScheduleByVmId(long vmId, boolean expunge);
|
||||
|
||||
Long removeSchedule(DeleteVMScheduleCmd deleteVMScheduleCmd);
|
||||
}
|
||||
|
|
@ -21,8 +21,9 @@ package org.apache.cloudstack.api.command.user.vm;
|
|||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.VMScheduleResponse;
|
||||
import org.apache.cloudstack.vm.schedule.VMScheduleManager;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
|
@ -34,9 +35,11 @@ import org.mockito.MockitoAnnotations;
|
|||
|
||||
public class CreateVMScheduleCmdTest {
|
||||
@Mock
|
||||
public VMScheduleManager vmScheduleManager;
|
||||
public ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Mock
|
||||
public EntityManager entityManager;
|
||||
|
||||
@InjectMocks
|
||||
private CreateVMScheduleCmd createVMScheduleCmd = new CreateVMScheduleCmd();
|
||||
|
||||
|
|
@ -59,10 +62,19 @@ public class CreateVMScheduleCmdTest {
|
|||
*/
|
||||
@Test
|
||||
public void testSuccessfulExecution() {
|
||||
VMScheduleResponse vmScheduleResponse = Mockito.mock(VMScheduleResponse.class);
|
||||
Mockito.when(vmScheduleManager.createSchedule(createVMScheduleCmd)).thenReturn(vmScheduleResponse);
|
||||
ResourceScheduleResponse scheduleResponse = new ResourceScheduleResponse();
|
||||
scheduleResponse.setId("schedule-uuid");
|
||||
scheduleResponse.setResourceId("vm-uuid");
|
||||
Mockito.when(resourceScheduleManager.createSchedule(
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
|
||||
Mockito.anyBoolean(), Mockito.any()
|
||||
)).thenReturn(scheduleResponse);
|
||||
createVMScheduleCmd.execute();
|
||||
Assert.assertEquals(vmScheduleResponse, createVMScheduleCmd.getResponseObject());
|
||||
VMScheduleResponse response = (VMScheduleResponse) createVMScheduleCmd.getResponseObject();
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals("schedule-uuid", org.springframework.test.util.ReflectionTestUtils.getField(response, "id"));
|
||||
Assert.assertEquals("vm-uuid", org.springframework.test.util.ReflectionTestUtils.getField(response, "vmId"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -72,7 +84,11 @@ public class CreateVMScheduleCmdTest {
|
|||
*/
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testInvalidParameterValueException() {
|
||||
Mockito.when(vmScheduleManager.createSchedule(createVMScheduleCmd)).thenThrow(InvalidParameterValueException.class);
|
||||
Mockito.when(resourceScheduleManager.createSchedule(
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
|
||||
Mockito.anyBoolean(), Mockito.any()
|
||||
)).thenThrow(new InvalidParameterValueException("Invalid schedule"));
|
||||
createVMScheduleCmd.execute();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@ import com.cloud.utils.db.EntityManager;
|
|||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.vm.schedule.VMSchedule;
|
||||
import org.apache.cloudstack.vm.schedule.VMScheduleManager;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
|
@ -36,7 +35,8 @@ import org.mockito.MockitoAnnotations;
|
|||
|
||||
public class DeleteVMScheduleCmdTest {
|
||||
@Mock
|
||||
public VMScheduleManager vmScheduleManager;
|
||||
public ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Mock
|
||||
public EntityManager entityManager;
|
||||
|
||||
|
|
@ -64,9 +64,11 @@ public class DeleteVMScheduleCmdTest {
|
|||
public void testSuccessfulExecution() {
|
||||
final SuccessResponse response = new SuccessResponse();
|
||||
response.setResponseName(deleteVMScheduleCmd.getCommandName());
|
||||
response.setObjectName(VMSchedule.class.getSimpleName().toLowerCase());
|
||||
response.setObjectName("vmschedule");
|
||||
|
||||
Mockito.when(vmScheduleManager.removeSchedule(deleteVMScheduleCmd)).thenReturn(1L);
|
||||
Mockito.when(resourceScheduleManager.removeSchedule(
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()
|
||||
)).thenReturn(1L);
|
||||
deleteVMScheduleCmd.execute();
|
||||
SuccessResponse actualResponse = (SuccessResponse) deleteVMScheduleCmd.getResponseObject();
|
||||
Assert.assertEquals(response.getResponseName(), actualResponse.getResponseName());
|
||||
|
|
@ -80,7 +82,9 @@ public class DeleteVMScheduleCmdTest {
|
|||
*/
|
||||
@Test(expected = ServerApiException.class)
|
||||
public void testServerApiException() {
|
||||
Mockito.when(vmScheduleManager.removeSchedule(deleteVMScheduleCmd)).thenReturn(0L);
|
||||
Mockito.when(resourceScheduleManager.removeSchedule(
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()
|
||||
)).thenReturn(0L);
|
||||
deleteVMScheduleCmd.execute();
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +95,9 @@ public class DeleteVMScheduleCmdTest {
|
|||
*/
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testInvalidParameterValueException() {
|
||||
Mockito.when(vmScheduleManager.removeSchedule(deleteVMScheduleCmd)).thenThrow(InvalidParameterValueException.class);
|
||||
Mockito.when(resourceScheduleManager.removeSchedule(
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()
|
||||
)).thenThrow(new InvalidParameterValueException("Invalid schedule"));
|
||||
deleteVMScheduleCmd.execute();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ package org.apache.cloudstack.api.command.user.vm;
|
|||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.VMScheduleResponse;
|
||||
import org.apache.cloudstack.vm.schedule.VMScheduleManager;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
|
@ -36,7 +37,8 @@ import java.util.Collections;
|
|||
|
||||
public class ListVMScheduleCmdTest {
|
||||
@Mock
|
||||
public VMScheduleManager vmScheduleManager;
|
||||
public ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@InjectMocks
|
||||
private ListVMScheduleCmd listVMScheduleCmd = new ListVMScheduleCmd();
|
||||
private AutoCloseable closeable;
|
||||
|
|
@ -58,12 +60,14 @@ public class ListVMScheduleCmdTest {
|
|||
*/
|
||||
@Test
|
||||
public void testEmptyResponse() {
|
||||
ListResponse<VMScheduleResponse> response = new ListResponse<VMScheduleResponse>();
|
||||
response.setResponses(new ArrayList<VMScheduleResponse>());
|
||||
Mockito.when(vmScheduleManager.listSchedule(listVMScheduleCmd)).thenReturn(response);
|
||||
ListResponse<ResourceScheduleResponse> response = new ListResponse<ResourceScheduleResponse>();
|
||||
response.setResponses(new ArrayList<ResourceScheduleResponse>());
|
||||
Mockito.when(resourceScheduleManager.listSchedule(
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()
|
||||
)).thenReturn(response);
|
||||
listVMScheduleCmd.execute();
|
||||
ListResponse<VMScheduleResponse> actualResponseObject = (ListResponse<VMScheduleResponse>) listVMScheduleCmd.getResponseObject();
|
||||
Assert.assertEquals(response, actualResponseObject);
|
||||
Assert.assertEquals(0L, actualResponseObject.getResponses().size());
|
||||
}
|
||||
|
||||
|
|
@ -74,15 +78,22 @@ public class ListVMScheduleCmdTest {
|
|||
*/
|
||||
@Test
|
||||
public void testNonEmptyResponse() {
|
||||
ListResponse<VMScheduleResponse> listResponse = new ListResponse<VMScheduleResponse>();
|
||||
VMScheduleResponse response = Mockito.mock(VMScheduleResponse.class);
|
||||
ListResponse<ResourceScheduleResponse> listResponse = new ListResponse<ResourceScheduleResponse>();
|
||||
ResourceScheduleResponse response = new ResourceScheduleResponse();
|
||||
response.setId("schedule-uuid");
|
||||
response.setResourceId("vm-uuid");
|
||||
listResponse.setResponses(Collections.singletonList(response));
|
||||
Mockito.when(vmScheduleManager.listSchedule(listVMScheduleCmd)).thenReturn(listResponse);
|
||||
Mockito.when(resourceScheduleManager.listSchedule(
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()
|
||||
)).thenReturn(listResponse);
|
||||
listVMScheduleCmd.execute();
|
||||
ListResponse<VMScheduleResponse> actualResponseObject = (ListResponse<VMScheduleResponse>) listVMScheduleCmd.getResponseObject();
|
||||
Assert.assertEquals(listResponse, actualResponseObject);
|
||||
Assert.assertEquals(1L, actualResponseObject.getResponses().size());
|
||||
Assert.assertEquals(response, actualResponseObject.getResponses().get(0));
|
||||
Assert.assertEquals("schedule-uuid",
|
||||
org.springframework.test.util.ReflectionTestUtils.getField(actualResponseObject.getResponses().get(0), "id"));
|
||||
Assert.assertEquals("vm-uuid",
|
||||
org.springframework.test.util.ReflectionTestUtils.getField(actualResponseObject.getResponses().get(0), "vmId"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -92,7 +103,10 @@ public class ListVMScheduleCmdTest {
|
|||
*/
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testInvalidParameterValueException() {
|
||||
Mockito.when(vmScheduleManager.listSchedule(listVMScheduleCmd)).thenThrow(InvalidParameterValueException.class);
|
||||
Mockito.when(resourceScheduleManager.listSchedule(
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()
|
||||
)).thenThrow(InvalidParameterValueException.class);
|
||||
listVMScheduleCmd.execute();
|
||||
ListResponse<VMScheduleResponse> actualResponseObject = (ListResponse<VMScheduleResponse>) listVMScheduleCmd.getResponseObject();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,11 @@ package org.apache.cloudstack.api.command.user.vm;
|
|||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.response.ResourceScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.VMScheduleResponse;
|
||||
import org.apache.cloudstack.vm.schedule.VMSchedule;
|
||||
import org.apache.cloudstack.vm.schedule.VMScheduleManager;
|
||||
import org.apache.cloudstack.schedule.ResourceSchedule;
|
||||
import org.apache.cloudstack.schedule.ResourceScheduleManager;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
|
@ -35,9 +37,11 @@ import org.mockito.MockitoAnnotations;
|
|||
|
||||
public class UpdateVMScheduleCmdTest {
|
||||
@Mock
|
||||
public VMScheduleManager vmScheduleManager;
|
||||
public ResourceScheduleManager resourceScheduleManager;
|
||||
|
||||
@Mock
|
||||
public EntityManager entityManager;
|
||||
|
||||
@InjectMocks
|
||||
private UpdateVMScheduleCmd updateVMScheduleCmd = new UpdateVMScheduleCmd();
|
||||
|
||||
|
|
@ -60,10 +64,18 @@ public class UpdateVMScheduleCmdTest {
|
|||
*/
|
||||
@Test
|
||||
public void testSuccessfulExecution() {
|
||||
VMScheduleResponse vmScheduleResponse = Mockito.mock(VMScheduleResponse.class);
|
||||
Mockito.when(vmScheduleManager.updateSchedule(updateVMScheduleCmd)).thenReturn(vmScheduleResponse);
|
||||
ResourceScheduleResponse scheduleResponse = new ResourceScheduleResponse();
|
||||
scheduleResponse.setId("schedule-uuid");
|
||||
scheduleResponse.setResourceId("vm-uuid");
|
||||
Mockito.when(resourceScheduleManager.updateSchedule(
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()
|
||||
)).thenReturn(scheduleResponse);
|
||||
updateVMScheduleCmd.execute();
|
||||
Assert.assertEquals(vmScheduleResponse, updateVMScheduleCmd.getResponseObject());
|
||||
VMScheduleResponse response = (VMScheduleResponse) updateVMScheduleCmd.getResponseObject();
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals("schedule-uuid", org.springframework.test.util.ReflectionTestUtils.getField(response, "id"));
|
||||
Assert.assertEquals("vm-uuid", org.springframework.test.util.ReflectionTestUtils.getField(response, "vmId"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -73,7 +85,10 @@ public class UpdateVMScheduleCmdTest {
|
|||
*/
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testInvalidParameterValueException() {
|
||||
Mockito.when(vmScheduleManager.updateSchedule(updateVMScheduleCmd)).thenThrow(InvalidParameterValueException.class);
|
||||
Mockito.when(resourceScheduleManager.updateSchedule(
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
|
||||
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()
|
||||
)).thenThrow(new InvalidParameterValueException("Invalid schedule"));
|
||||
updateVMScheduleCmd.execute();
|
||||
}
|
||||
|
||||
|
|
@ -84,11 +99,12 @@ public class UpdateVMScheduleCmdTest {
|
|||
*/
|
||||
@Test
|
||||
public void testSuccessfulGetEntityOwnerId() {
|
||||
VMSchedule vmSchedule = Mockito.mock(VMSchedule.class);
|
||||
ResourceSchedule schedule = Mockito.mock(ResourceSchedule.class);
|
||||
VirtualMachine vm = Mockito.mock(VirtualMachine.class);
|
||||
|
||||
Mockito.when(entityManager.findById(VMSchedule.class, updateVMScheduleCmd.getId())).thenReturn(vmSchedule);
|
||||
Mockito.when(entityManager.findById(VirtualMachine.class, vmSchedule.getVmId())).thenReturn(vm);
|
||||
Mockito.when(schedule.getResourceType()).thenReturn(ApiCommandResourceType.VirtualMachine);
|
||||
Mockito.when(entityManager.findById(ResourceSchedule.class, updateVMScheduleCmd.getId())).thenReturn(schedule);
|
||||
Mockito.when(entityManager.findById(VirtualMachine.class, schedule.getResourceId())).thenReturn(vm);
|
||||
|
||||
long ownerId = updateVMScheduleCmd.getEntityOwnerId();
|
||||
Assert.assertEquals(vm.getAccountId(), ownerId);
|
||||
|
|
@ -101,8 +117,7 @@ public class UpdateVMScheduleCmdTest {
|
|||
*/
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void testFailureGetEntityOwnerId() {
|
||||
VMSchedule vmSchedule = Mockito.mock(VMSchedule.class);
|
||||
Mockito.when(entityManager.findById(VMSchedule.class, updateVMScheduleCmd.getId())).thenReturn(null);
|
||||
long ownerId = updateVMScheduleCmd.getEntityOwnerId();
|
||||
Mockito.when(entityManager.findById(ResourceSchedule.class, updateVMScheduleCmd.getId())).thenReturn(null);
|
||||
updateVMScheduleCmd.getEntityOwnerId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public final class AttachedIsoResponseTest {
|
||||
|
||||
@Test
|
||||
public void testFullConstructorPopulatesAllFields() {
|
||||
AttachedIsoResponse response = new AttachedIsoResponse("uuid-1", "alpine-iso", "Alpine boot", 3, true);
|
||||
Assert.assertEquals("uuid-1", response.getId());
|
||||
Assert.assertEquals("alpine-iso", response.getName());
|
||||
Assert.assertEquals("Alpine boot", response.getDisplayText());
|
||||
Assert.assertEquals(Integer.valueOf(3), response.getDeviceSeq());
|
||||
Assert.assertTrue(response.getBootable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoArgConstructorLeavesFieldsNull() {
|
||||
AttachedIsoResponse response = new AttachedIsoResponse();
|
||||
Assert.assertNull(response.getId());
|
||||
Assert.assertNull(response.getName());
|
||||
Assert.assertNull(response.getDisplayText());
|
||||
Assert.assertNull(response.getDeviceSeq());
|
||||
Assert.assertNull(response.getBootable());
|
||||
}
|
||||
}
|
||||
|
|
@ -256,6 +256,16 @@
|
|||
<artifactId>cloud-plugin-metrics</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-kms-database</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-kms-pkcs11</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-network-nvp</artifactId>
|
||||
|
|
|
|||
|
|
@ -367,5 +367,8 @@
|
|||
<bean id="sharedFSProvidersRegistry" class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
|
||||
</bean>
|
||||
|
||||
<bean id="kmsProvidersRegistry" class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
|
||||
</bean>
|
||||
|
||||
<bean id="dnsProvidersRegistry" class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry" />
|
||||
</beans>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
name=kms
|
||||
parent=core
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
|
||||
>
|
||||
<bean class="org.apache.cloudstack.spring.lifecycle.registry.RegistryLifecycle">
|
||||
<property name="registry" ref="kmsProvidersRegistry" />
|
||||
<property name="typeClass" value="org.apache.cloudstack.framework.kms.KMSProvider" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
|
@ -120,7 +120,7 @@ public interface VolumeOrchestrationService {
|
|||
void destroyVolume(Volume volume);
|
||||
|
||||
DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template,
|
||||
Account owner, Long deviceId, boolean incrementResourceCount);
|
||||
Account owner, Long deviceId, Long kmsKeyId, boolean incrementResourceCount);
|
||||
|
||||
VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo volume, HypervisorType rootDiskHyperType, StoragePool storagePool) throws NoTransitionException;
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ public interface VolumeOrchestrationService {
|
|||
* Allocate a volume or multiple volumes in case of template is registered with the 'deploy-as-is' option, allowing multiple disks
|
||||
*/
|
||||
List<DiskProfile> allocateTemplatedVolumes(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
|
||||
Account owner, Volume volume, Snapshot snapshot);
|
||||
Account owner, Long kmsKeyId, Volume volume, Snapshot snapshot);
|
||||
|
||||
String getVmNameFromVolumeId(long volumeId);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public interface OrchestrationService {
|
|||
@QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
|
||||
@QueryParam("root-disk-size") Long rootDiskSize, @QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap,
|
||||
@QueryParam("datadisktemplate-diskoffering-map") Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap, @QueryParam("disk-offering-id") Long diskOfferingId,
|
||||
@QueryParam("root-disk-offering-id") Long rootDiskOfferingId, List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException;
|
||||
@QueryParam("root-disk-offering-id") Long rootDiskOfferingId, @QueryParam("root-disk-kms-key-id") Long rootDiskKmsKeyId, List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException;
|
||||
|
||||
@POST
|
||||
VirtualMachineEntity createVirtualMachineFromScratch(@QueryParam("id") String id, @QueryParam("owner") String owner, @QueryParam("iso-id") String isoId,
|
||||
|
|
@ -80,7 +80,7 @@ public interface OrchestrationService {
|
|||
@QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags,
|
||||
@QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
|
||||
@QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap, @QueryParam("disk-offering-id") Long diskOfferingId,
|
||||
@QueryParam("data-disks-offering-info") List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException;
|
||||
@QueryParam("root-disk-kms-key-id") Long rootDiskKmsKeyId, @QueryParam("data-disks-offering-info") List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException;
|
||||
|
||||
@POST
|
||||
NetworkEntity createNetwork(String id, String name, String domainName, String cidr, String gateway);
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@ public interface TemplateService {
|
|||
|
||||
void handleTemplateSync(DataStore store);
|
||||
|
||||
void enforceSecStorageCopyLimit(long templateId, long zoneId);
|
||||
|
||||
boolean canCopyTemplateToImageStore(long templateId, long zoneId);
|
||||
|
||||
void replicateTemplateUpToCap(long templateId, long zoneId);
|
||||
|
||||
void downloadBootstrapSysTemplate(DataStore store);
|
||||
|
||||
void addSystemVMTemplatesToSecondary(DataStore store);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ import com.cloud.vm.VirtualMachineProfile;
|
|||
public interface TemplateManager {
|
||||
static final String AllowPublicUserTemplatesCK = "allow.public.user.templates";
|
||||
static final String TemplatePreloaderPoolSizeCK = "template.preloader.pool.size";
|
||||
static final String PublicTemplateSecStorageCopyCK = "secstorage.public.template.copy.max";
|
||||
static final String PrivateTemplateSecStorageCopyCK = "secstorage.private.template.copy.max";
|
||||
|
||||
static final ConfigKey<Boolean> AllowPublicUserTemplates = new ConfigKey<Boolean>("Advanced", Boolean.class, AllowPublicUserTemplatesCK, "true",
|
||||
"If false, users will not be able to create public Templates.", true, ConfigKey.Scope.Account);
|
||||
|
|
@ -64,6 +66,33 @@ public interface TemplateManager {
|
|||
true,
|
||||
ConfigKey.Scope.Global);
|
||||
|
||||
ConfigKey<Integer> PublicTemplateSecStorageCopy = new ConfigKey<Integer>("Advanced", Integer.class,
|
||||
PublicTemplateSecStorageCopyCK, "0",
|
||||
"Maximum number of secondary storage pools to which a public template is copied. " +
|
||||
"0 means copy to all secondary storage pools (default behavior).",
|
||||
true, ConfigKey.Scope.Zone);
|
||||
|
||||
ConfigKey<Integer> PrivateTemplateSecStorageCopy = new ConfigKey<Integer>("Advanced", Integer.class,
|
||||
PrivateTemplateSecStorageCopyCK, "1",
|
||||
"Maximum number of secondary storage pools to which a private template is copied. " +
|
||||
"Default is 1 to preserve existing behavior.",
|
||||
true, ConfigKey.Scope.Zone);
|
||||
|
||||
ConfigKey<Integer> VmIsoMaxCount = new ConfigKey<Integer>("Advanced",
|
||||
Integer.class,
|
||||
"vm.iso.max.count", "1",
|
||||
"Maximum number of ISOs that may be attached to a VM.",
|
||||
true,
|
||||
ConfigKey.Scope.Cluster);
|
||||
|
||||
// KVM/libvirt maps deviceSeq=3 to hdc (hda/hdb are taken by the root volume on i440fx/IDE).
|
||||
// user_vm.iso_id has always pointed at this slot; additional cdroms live in vm_iso_map.
|
||||
int CDROM_PRIMARY_DEVICE_SEQ = 3;
|
||||
|
||||
// Fallback per-VM cdrom cap when the placement host hasn't advertised host.cdrom.max.count
|
||||
// (older agent, never-deployed VM, etc.).
|
||||
int DEFAULT_CDROM_MAX_PER_VM = 1;
|
||||
|
||||
static final String VMWARE_TOOLS_ISO = "vmware-tools.iso";
|
||||
static final String XS_TOOLS_ISO = "xs-tools.iso";
|
||||
|
||||
|
|
@ -138,6 +167,12 @@ public interface TemplateManager {
|
|||
|
||||
List<DataStore> getImageStoreByTemplate(long templateId, Long zoneId);
|
||||
|
||||
/**
|
||||
* Max number of secondary storage copies for the template in this zone; {@code 0} means no limit.
|
||||
* SYSTEM/ROUTING/BUILTIN templates are always exempt (returns {@code 0}).
|
||||
*/
|
||||
int getSecStorageCopyLimit(VMTemplateVO template, long zoneId);
|
||||
|
||||
TemplateInfo prepareIso(long isoId, long dcId, Long hostId, Long poolId);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -601,7 +601,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
Long deviceId = dataDiskDeviceIds.get(index++);
|
||||
String volumeName = deviceId == null ? "DATA-" + persistedVm.getId() : "DATA-" + persistedVm.getId() + "-" + String.valueOf(deviceId);
|
||||
volumeMgr.allocateRawVolume(Type.DATADISK, volumeName, dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
|
||||
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, deviceId, true);
|
||||
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, deviceId, dataDiskOfferingInfo.getKmsKeyId(), true);
|
||||
}
|
||||
}
|
||||
if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) {
|
||||
|
|
@ -611,7 +611,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
long diskOfferingSize = diskOffering.getDiskSize() / (1024 * 1024 * 1024);
|
||||
VMTemplateVO dataDiskTemplate = _templateDao.findById(dataDiskTemplateToDiskOfferingMap.getKey());
|
||||
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId() + "-" + String.valueOf( diskNumber), diskOffering, diskOfferingSize, null, null,
|
||||
persistedVm, dataDiskTemplate, owner, diskNumber, true);
|
||||
persistedVm, dataDiskTemplate, owner, diskNumber, null, true);
|
||||
diskNumber++;
|
||||
}
|
||||
}
|
||||
|
|
@ -641,12 +641,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
String rootVolumeName = String.format("ROOT-%s", vm.getId());
|
||||
if (template.getFormat() == ImageFormat.ISO) {
|
||||
volumeMgr.allocateRawVolume(Type.ROOT, rootVolumeName, rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
|
||||
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vm, template, owner, null, true);
|
||||
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vm, template, owner, null, rootDiskOfferingInfo.getKmsKeyId(), true);
|
||||
} else if (Arrays.asList(ImageFormat.BAREMETAL, ImageFormat.EXTERNAL).contains(template.getFormat())) {
|
||||
logger.debug("{} has format [{}]. Skipping ROOT volume [{}] allocation.", template, template.getFormat(), rootVolumeName);
|
||||
} else {
|
||||
volumeMgr.allocateTemplatedVolumes(Type.ROOT, rootVolumeName, rootDiskOfferingInfo.getDiskOffering(), rootDiskSizeFinal,
|
||||
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vm, owner, volume, snapshot);
|
||||
rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vm, owner, rootDiskOfferingInfo.getKmsKeyId(), volume, snapshot);
|
||||
}
|
||||
} finally {
|
||||
// Remove volumeContext and pop vmContext back
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||
public VirtualMachineEntity createVirtualMachine(String id, String owner, String templateId, String hostName, String displayName, String hypervisor, int cpu,
|
||||
int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, List<NicProfile>> networkNicMap, DeploymentPlan plan,
|
||||
Long rootDiskSize, Map<String, Map<Integer, String>> extraDhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Long dataDiskOfferingId, Long rootDiskOfferingId,
|
||||
List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException {
|
||||
Long rootDiskKmsKeyId, List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot) throws InsufficientCapacityException {
|
||||
|
||||
// VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks,
|
||||
// vmEntityManager);
|
||||
|
|
@ -199,6 +199,7 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||
}
|
||||
rootDiskOfferingInfo.setDiskOffering(rootDiskOffering);
|
||||
rootDiskOfferingInfo.setSize(rootDiskSize);
|
||||
rootDiskOfferingInfo.setKmsKeyId(rootDiskKmsKeyId);
|
||||
|
||||
if (rootDiskOffering.isCustomizedIops() != null && rootDiskOffering.isCustomizedIops()) {
|
||||
Map<String, String> userVmDetails = _vmInstanceDetailsDao.listDetailsKeyPairs(vm.getId());
|
||||
|
|
@ -281,7 +282,7 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||
@Override
|
||||
public VirtualMachineEntity createVirtualMachineFromScratch(String id, String owner, String isoId, String hostName, String displayName, String hypervisor, String os,
|
||||
int cpu, int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, List<NicProfile>> networkNicMap, DeploymentPlan plan,
|
||||
Map<String, Map<Integer, String>> extraDhcpOptionMap, Long diskOfferingId, List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot)
|
||||
Map<String, Map<Integer, String>> extraDhcpOptionMap, Long diskOfferingId, Long rootDiskKmsKeyId, List<VmDiskInfo> dataDiskInfoList, Volume volume, Snapshot snapshot)
|
||||
throws InsufficientCapacityException {
|
||||
|
||||
// VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks, vmEntityManager);
|
||||
|
|
@ -317,6 +318,7 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||
|
||||
rootDiskOfferingInfo.setDiskOffering(diskOffering);
|
||||
rootDiskOfferingInfo.setSize(size);
|
||||
rootDiskOfferingInfo.setKmsKeyId(rootDiskKmsKeyId);
|
||||
|
||||
if (diskOffering.isCustomizedIops() != null && diskOffering.isCustomizedIops()) {
|
||||
Map<String, String> userVmDetails = _vmInstanceDetailsDao.listDetailsKeyPairs(vm.getId());
|
||||
|
|
|
|||
|
|
@ -89,6 +89,13 @@ import org.apache.cloudstack.resourcelimit.Reserver;
|
|||
import org.apache.cloudstack.secret.PassphraseVO;
|
||||
import org.apache.cloudstack.secret.dao.PassphraseDao;
|
||||
import org.apache.cloudstack.snapshot.SnapshotHelper;
|
||||
import org.apache.cloudstack.kms.KMSManager;
|
||||
import org.apache.cloudstack.kms.KMSKeyVO;
|
||||
import org.apache.cloudstack.kms.KMSWrappedKeyVO;
|
||||
import org.apache.cloudstack.kms.dao.KMSKeyDao;
|
||||
import org.apache.cloudstack.kms.dao.KMSWrappedKeyDao;
|
||||
import org.apache.cloudstack.framework.kms.KMSException;
|
||||
import org.apache.cloudstack.framework.kms.WrappedKey;
|
||||
import org.apache.cloudstack.storage.command.CommandResult;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
|
|
@ -287,6 +294,12 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
|
||||
@Inject
|
||||
private DataStoreProviderManager dataStoreProviderMgr;
|
||||
@Inject
|
||||
private KMSManager kmsManager;
|
||||
@Inject
|
||||
private KMSKeyDao kmsKeyDao;
|
||||
@Inject
|
||||
private KMSWrappedKeyDao kmsWrappedKeyDao;
|
||||
|
||||
private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
|
||||
protected List<StoragePoolAllocator> _storagePoolAllocators;
|
||||
|
|
@ -323,7 +336,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
// Find a destination storage pool with the specified criteria
|
||||
DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volumeInfo.getDiskOfferingId());
|
||||
DiskProfile dskCh = new DiskProfile(volumeInfo.getId(), volumeInfo.getVolumeType(), volumeInfo.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(),
|
||||
diskOffering.isUseLocalStorage(), diskOffering.isRecreatable(), null, (diskOffering.getEncrypt() || volumeInfo.getPassphraseId() != null));
|
||||
diskOffering.isUseLocalStorage(), diskOffering.isRecreatable(), null, (diskOffering.getEncrypt() || volumeInfo.getPassphraseId() != null || volumeInfo.getKmsKeyId() != null));
|
||||
|
||||
dskCh.setHyperType(dataDiskHyperType);
|
||||
storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
|
||||
|
|
@ -358,9 +371,13 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
newVol.setInstanceId(oldVol.getInstanceId());
|
||||
newVol.setRecreatable(oldVol.isRecreatable());
|
||||
newVol.setFormat(oldVol.getFormat());
|
||||
if ((diskOffering == null || diskOffering.getEncrypt()) && oldVol.getPassphraseId() != null) {
|
||||
PassphraseVO passphrase = passphraseDao.persist(new PassphraseVO(true));
|
||||
newVol.setPassphraseId(passphrase.getId());
|
||||
if ((diskOffering == null || diskOffering.getEncrypt())) {
|
||||
if (oldVol.getKmsKeyId() != null) {
|
||||
newVol.setKmsKeyId(oldVol.getKmsKeyId());
|
||||
} else if (oldVol.getPassphraseId() != null) {
|
||||
PassphraseVO passphrase = passphraseDao.persist(new PassphraseVO(true));
|
||||
newVol.setPassphraseId(passphrase.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return _volsDao.persist(newVol);
|
||||
|
|
@ -515,7 +532,9 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
|
||||
if (diskOffering.getEncrypt()) {
|
||||
VolumeVO vol = (VolumeVO) volume;
|
||||
volume = setPassphraseForVolumeEncryption(vol);
|
||||
// Retrieve KMS key from volume's kmsKeyId if provided
|
||||
KMSKeyVO kmsKey = getKmsKeyFromVolume(vol);
|
||||
volume = setPassphraseForVolumeEncryption(vol, kmsKey, volume.getAccountId());
|
||||
}
|
||||
DataCenter dc = _entityMgr.findById(DataCenter.class, volume.getDataCenterId());
|
||||
DiskProfile dskCh = new DiskProfile(volume, diskOffering, snapshot.getHypervisorType());
|
||||
|
|
@ -652,7 +671,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
}
|
||||
|
||||
protected DiskProfile createDiskCharacteristics(VolumeInfo volumeInfo, VirtualMachineTemplate template, DataCenter dc, DiskOffering diskOffering) {
|
||||
boolean requiresEncryption = diskOffering.getEncrypt() || volumeInfo.getPassphraseId() != null;
|
||||
boolean requiresEncryption = diskOffering.getEncrypt() || volumeInfo.getPassphraseId() != null || volumeInfo.getKmsKeyId() != null;
|
||||
if (volumeInfo.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
|
||||
String templateToString = getReflectOnlySelectedFields(template);
|
||||
String zoneToString = getReflectOnlySelectedFields(dc);
|
||||
|
|
@ -732,7 +751,9 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
|
||||
if (diskOffering.getEncrypt()) {
|
||||
VolumeVO vol = _volsDao.findById(volumeInfo.getId());
|
||||
setPassphraseForVolumeEncryption(vol);
|
||||
// Retrieve KMS key from volume's kmsKeyId if provided
|
||||
KMSKeyVO kmsKey = getKmsKeyFromVolume(vol);
|
||||
setPassphraseForVolumeEncryption(vol, kmsKey, vol.getAccountId());
|
||||
volumeInfo = volFactory.getVolume(volumeInfo.getId());
|
||||
}
|
||||
}
|
||||
|
|
@ -996,8 +1017,10 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", create = true)
|
||||
@Override
|
||||
public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner,
|
||||
Long deviceId, boolean incrementResourceCount) {
|
||||
public DiskProfile allocateRawVolume(
|
||||
Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm,
|
||||
VirtualMachineTemplate template, Account owner, Long deviceId, Long kmsKeyId, boolean incrementResourceCount
|
||||
) {
|
||||
if (size == null) {
|
||||
size = offering.getDiskSize();
|
||||
} else {
|
||||
|
|
@ -1030,6 +1053,11 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
vol.setDisplayVolume(userVm.isDisplayVm());
|
||||
}
|
||||
|
||||
// Set KMS key ID if provided
|
||||
if (kmsKeyId != null) {
|
||||
vol.setKmsKeyId(kmsKeyId);
|
||||
}
|
||||
|
||||
vol.setFormat(getSupportedImageFormatForCluster(vm.getHypervisorType()));
|
||||
vol = _volsDao.persist(vol);
|
||||
|
||||
|
|
@ -1049,7 +1077,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
}
|
||||
|
||||
private DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
|
||||
Account owner, long deviceId, String configurationId, Volume volume, Snapshot snapshot) {
|
||||
Account owner, long deviceId, String configurationId, Long kmsKeyId, Volume volume, Snapshot snapshot) {
|
||||
assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template.";
|
||||
|
||||
if (volume != null) {
|
||||
|
|
@ -1099,6 +1127,11 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
vol.setDisplayVolume(userVm.isDisplayVm());
|
||||
}
|
||||
|
||||
// Set KMS key ID if provided
|
||||
if (kmsKeyId != null) {
|
||||
vol.setKmsKeyId(kmsKeyId);
|
||||
}
|
||||
|
||||
vol = _volsDao.persist(vol);
|
||||
|
||||
saveVolumeDetails(offering.getId(), vol.getId());
|
||||
|
|
@ -1188,7 +1221,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating ROOT volume", create = true)
|
||||
@Override
|
||||
public List<DiskProfile> allocateTemplatedVolumes(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
|
||||
Account owner, Volume volume, Snapshot snapshot) {
|
||||
Account owner, Long kmsKeyId, Volume volume, Snapshot snapshot) {
|
||||
String templateToString = getReflectOnlySelectedFields(template);
|
||||
|
||||
int volumesNumber = 1;
|
||||
|
|
@ -1235,7 +1268,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
}
|
||||
logger.info("Adding disk object [{}] to VM [{}]", volumeName, vm);
|
||||
DiskProfile diskProfile = allocateTemplatedVolume(type, volumeName, offering, volumeSize, minIops, maxIops,
|
||||
template, vm, owner, deviceId, configurationId, volume, snapshot);
|
||||
template, vm, owner, deviceId, configurationId, kmsKeyId, volume, snapshot);
|
||||
profiles.add(diskProfile);
|
||||
}
|
||||
|
||||
|
|
@ -1945,7 +1978,9 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
if (vol.getState() == Volume.State.Allocated || vol.getState() == Volume.State.Creating) {
|
||||
DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, vol.getDiskOfferingId());
|
||||
if (diskOffering.getEncrypt()) {
|
||||
vol = setPassphraseForVolumeEncryption(vol);
|
||||
// Retrieve KMS key from volume's kmsKeyId if provided
|
||||
KMSKeyVO kmsKey = getKmsKeyFromVolume(vol);
|
||||
vol = setPassphraseForVolumeEncryption(vol, kmsKey, vol.getAccountId());
|
||||
}
|
||||
newVol = vol;
|
||||
} else {
|
||||
|
|
@ -2081,16 +2116,72 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
return new Pair<>(newVol, destPool);
|
||||
}
|
||||
|
||||
private VolumeVO setPassphraseForVolumeEncryption(VolumeVO volume) {
|
||||
if (volume.getPassphraseId() != null) {
|
||||
/**
|
||||
* Helper method to retrieve KMS key from volume's kmsKeyId
|
||||
*/
|
||||
private KMSKeyVO getKmsKeyFromVolume(VolumeVO volume) {
|
||||
if (volume.getKmsKeyId() == null) {
|
||||
return null;
|
||||
}
|
||||
return kmsKeyDao.findById(volume.getKmsKeyId());
|
||||
}
|
||||
|
||||
private VolumeVO setKmsKeyForVolumeEncryption(VolumeVO volume, KMSKeyVO kmsKey, Long callerAccountId) {
|
||||
// Determine caller account ID if not provided
|
||||
if (callerAccountId == null) {
|
||||
callerAccountId = volume.getAccountId();
|
||||
}
|
||||
|
||||
// Validate permission
|
||||
if (!kmsManager.hasPermission(callerAccountId, kmsKey)) {
|
||||
throw new CloudRuntimeException("No permission to use KMS key: " + kmsKey);
|
||||
}
|
||||
|
||||
try {
|
||||
logger.debug("Generating and wrapping DEK for volume {} using KMS key {}", volume.getName(), kmsKey.getUuid());
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
// Generate and wrap DEK using active KEK version
|
||||
WrappedKey wrappedKey = kmsManager.generateVolumeKeyWithKek(kmsKey, callerAccountId);
|
||||
|
||||
// The wrapped key is already persisted by generateVolumeKeyWithKek, get its ID
|
||||
KMSWrappedKeyVO wrappedKeyVO = kmsWrappedKeyDao.findByUuid(wrappedKey.getUuid());
|
||||
if (wrappedKeyVO == null) {
|
||||
throw new CloudRuntimeException("Failed to find persisted wrapped key: " + wrappedKey.getUuid());
|
||||
}
|
||||
|
||||
// Set the wrapped key ID on the volume
|
||||
volume.setKmsWrappedKeyId(wrappedKeyVO.getId());
|
||||
|
||||
long finishTime = System.currentTimeMillis();
|
||||
logger.debug("Generating and persisting wrapped key took {} ms for volume: {}",
|
||||
(finishTime - startTime), volume.getName());
|
||||
|
||||
return _volsDao.persist(volume);
|
||||
|
||||
} catch (KMSException e) {
|
||||
throw new CloudRuntimeException("KMS failure while setting up volume encryption: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
private VolumeVO setPassphraseForVolumeEncryption(VolumeVO volume, KMSKeyVO kmsKey, Long callerAccountId) {
|
||||
// If volume already has encryption set up, return it
|
||||
if (volume.getKmsWrappedKeyId() != null || volume.getPassphraseId() != null) {
|
||||
return volume;
|
||||
}
|
||||
logger.debug("Creating passphrase for the volume: " + volume.getName());
|
||||
if (kmsKey != null) {
|
||||
return setKmsKeyForVolumeEncryption(volume, kmsKey, callerAccountId);
|
||||
}
|
||||
// Legacy: passphrase-based encryption (fallback when KMS not enabled or KMS key not specified)
|
||||
return setPassphraseForVolumeEncryption(volume);
|
||||
}
|
||||
|
||||
private VolumeVO setPassphraseForVolumeEncryption(VolumeVO volume) {
|
||||
logger.debug("Creating passphrase for the volume: {}", volume.getName());
|
||||
long startTime = System.currentTimeMillis();
|
||||
PassphraseVO passphrase = passphraseDao.persist(new PassphraseVO(true));
|
||||
volume.setPassphraseId(passphrase.getId());
|
||||
long finishTime = System.currentTimeMillis();
|
||||
logger.debug("Creating and persisting passphrase took: " + (finishTime - startTime) + " ms for the volume: " + volume.toString());
|
||||
logger.debug("Creating and persisting passphrase took: {} ms for the volume: {}", finishTime - startTime, volume.toString());
|
||||
return _volsDao.persist(volume);
|
||||
}
|
||||
|
||||
|
|
@ -2119,7 +2210,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
PrimaryDataStoreDriver driver = (PrimaryDataStoreDriver) store.getDriver();
|
||||
long newSize = driver.getVolumeSizeRequiredOnPool(vol.getSize(),
|
||||
template == null ? null : template.getSize(),
|
||||
vol.getPassphraseId() != null);
|
||||
vol.getPassphraseId() != null || vol.getKmsKeyId() != null);
|
||||
|
||||
if (newSize == vol.getSize()) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -280,6 +280,7 @@ public class VolumeOrchestratorTest {
|
|||
Mockito.when(oldVol.isRecreatable()).thenReturn(false);
|
||||
Mockito.when(oldVol.getFormat()).thenReturn(Storage.ImageFormat.QCOW2);
|
||||
Mockito.when(oldVol.getPassphraseId()).thenReturn(null); // no encryption
|
||||
Mockito.when(oldVol.getKmsKeyId()).thenReturn(null); // no encryption
|
||||
|
||||
VolumeVO persistedVol = Mockito.mock(VolumeVO.class);
|
||||
Mockito.when(volumeDao.persist(Mockito.any(VolumeVO.class))).thenReturn(persistedVol);
|
||||
|
|
@ -308,6 +309,7 @@ public class VolumeOrchestratorTest {
|
|||
Mockito.when(oldVol.getInstanceId()).thenReturn(7L);
|
||||
Mockito.when(oldVol.isRecreatable()).thenReturn(true);
|
||||
Mockito.when(oldVol.getFormat()).thenReturn(Storage.ImageFormat.RAW);
|
||||
Mockito.when(oldVol.getKmsKeyId()).thenReturn(null);
|
||||
Mockito.when(oldVol.getPassphraseId()).thenReturn(42L);
|
||||
|
||||
PassphraseVO passphrase = Mockito.mock(PassphraseVO.class);
|
||||
|
|
@ -341,9 +343,6 @@ public class VolumeOrchestratorTest {
|
|||
VolumeVO persistedVol = Mockito.mock(VolumeVO.class);
|
||||
Mockito.when(volumeDao.persist(Mockito.any())).thenReturn(persistedVol);
|
||||
|
||||
PassphraseVO mockPassPhrase = Mockito.mock(PassphraseVO.class);
|
||||
Mockito.when(passphraseDao.persist(Mockito.any())).thenReturn(mockPassPhrase);
|
||||
|
||||
VolumeVO result = volumeOrchestrator.allocateDuplicateVolumeVO(oldVol, null, 222L);
|
||||
assertNotNull(result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@
|
|||
<artifactId>cloud-framework-db</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-framework-kms</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.alert.AlertVO;
|
||||
|
|
@ -28,7 +29,7 @@ import com.cloud.utils.db.GenericDaoBase;
|
|||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.db.UpdateBuilder;
|
||||
|
||||
@Component
|
||||
public class AlertDaoImpl extends GenericDaoBase<AlertVO, Long> implements AlertDao {
|
||||
|
|
@ -107,25 +108,20 @@ public class AlertDaoImpl extends GenericDaoBase<AlertVO, Long> implements Alert
|
|||
}
|
||||
sc.setParameters("archived", false);
|
||||
|
||||
boolean result = true;
|
||||
;
|
||||
List<AlertVO> alerts = listBy(sc);
|
||||
if (ids != null && alerts.size() < ids.size()) {
|
||||
result = false;
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
if (alerts != null && !alerts.isEmpty()) {
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
txn.start();
|
||||
for (AlertVO alert : alerts) {
|
||||
alert = lockRow(alert.getId(), true);
|
||||
alert.setArchived(true);
|
||||
update(alert.getId(), alert);
|
||||
txn.commit();
|
||||
}
|
||||
txn.close();
|
||||
|
||||
if (CollectionUtils.isEmpty(alerts)) {
|
||||
return true;
|
||||
}
|
||||
return result;
|
||||
|
||||
AlertVO alertForUpdate = createForUpdate();
|
||||
alertForUpdate.setArchived(true);
|
||||
UpdateBuilder ub = getUpdateBuilder(alertForUpdate);
|
||||
update(ub, sc, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ package com.cloud.event.dao;
|
|||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.event.Event.State;
|
||||
|
|
@ -29,12 +31,13 @@ import com.cloud.utils.db.GenericDaoBase;
|
|||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.db.UpdateBuilder;
|
||||
|
||||
@Component
|
||||
public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements EventDao {
|
||||
protected final SearchBuilder<EventVO> CompletedEventSearch;
|
||||
protected final SearchBuilder<EventVO> ToArchiveOrDeleteEventSearch;
|
||||
protected final SearchBuilder<EventVO> ArchiveByIdsSearch;
|
||||
|
||||
public EventDaoImpl() {
|
||||
CompletedEventSearch = createSearchBuilder();
|
||||
|
|
@ -51,6 +54,10 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements Event
|
|||
ToArchiveOrDeleteEventSearch.and("createdDateL", ToArchiveOrDeleteEventSearch.entity().getCreateDate(), Op.LTEQ);
|
||||
ToArchiveOrDeleteEventSearch.and("archived", ToArchiveOrDeleteEventSearch.entity().getArchived(), Op.EQ);
|
||||
ToArchiveOrDeleteEventSearch.done();
|
||||
|
||||
ArchiveByIdsSearch = createSearchBuilder();
|
||||
ArchiveByIdsSearch.and("id", ArchiveByIdsSearch.entity().getId(), Op.IN);
|
||||
ArchiveByIdsSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -100,16 +107,16 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements Event
|
|||
|
||||
@Override
|
||||
public void archiveEvents(List<EventVO> events) {
|
||||
if (events != null && !events.isEmpty()) {
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
txn.start();
|
||||
for (EventVO event : events) {
|
||||
event = lockRow(event.getId(), true);
|
||||
event.setArchived(true);
|
||||
update(event.getId(), event);
|
||||
txn.commit();
|
||||
}
|
||||
txn.close();
|
||||
if (CollectionUtils.isEmpty(events)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Long> ids = events.stream().map(EventVO::getId).collect(Collectors.toList());
|
||||
SearchCriteria<EventVO> sc = ArchiveByIdsSearch.create();
|
||||
sc.setParameters("id", ids.toArray(new Object[ids.size()]));
|
||||
EventVO eventForUpdate = createForUpdate();
|
||||
eventForUpdate.setArchived(true);
|
||||
UpdateBuilder ub = getUpdateBuilder(eventForUpdate);
|
||||
update(ub, sc, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -646,16 +646,22 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
sc.setParameters("lastPinged", lastPingSecondsAfter);
|
||||
sc.setParameters("status", Status.Disconnected, Status.Down, Status.Alert);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<HostVO> hosts = lockRows(sc, null, true); // exclusive lock
|
||||
for (HostVO host : hosts) {
|
||||
host.setManagementServerId(null);
|
||||
update(host.getId(), host);
|
||||
sb.append(host.getId());
|
||||
sb.append(" ");
|
||||
// SELECT before bulk UPDATE to preserve per-host-ID trace logging — the bulk UPDATE
|
||||
// cannot return which rows it matched since the WHERE column is being set to NULL
|
||||
if (logger.isTraceEnabled()) {
|
||||
List<HostVO> hosts = listBy(sc);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (HostVO host : hosts) {
|
||||
sb.append(host.getId());
|
||||
sb.append(" ");
|
||||
}
|
||||
logger.trace("Following hosts will be reset: {}", sb);
|
||||
}
|
||||
|
||||
logger.trace("Following hosts got reset: {}", sb);
|
||||
HostVO host = createForUpdate();
|
||||
host.setManagementServerId(null);
|
||||
UpdateBuilder ub = getUpdateBuilder(host);
|
||||
update(ub, sc, null);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
package com.cloud.network;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
|
|
@ -25,8 +26,11 @@ import javax.persistence.GenerationType;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import com.cloud.network.rules.HealthCheckPolicy;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
@Entity
|
||||
|
|
@ -68,6 +72,10 @@ public class LBHealthCheckPolicyVO implements HealthCheckPolicy {
|
|||
@Column(name = "display", updatable = true, nullable = false)
|
||||
protected boolean display = true;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
protected LBHealthCheckPolicyVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
|||
ReleaseSearch.and("ipId", ReleaseSearch.entity().getSourceIpAddressId(), Op.EQ);
|
||||
ReleaseSearch.and("purpose", ReleaseSearch.entity().getPurpose(), Op.EQ);
|
||||
ReleaseSearch.and("ports", ReleaseSearch.entity().getSourcePortStart(), Op.IN);
|
||||
ReleaseSearch.and("removed", ReleaseSearch.entity().getRemoved(), Op.NULL);
|
||||
ReleaseSearch.done();
|
||||
|
||||
SystemRuleSearch = createSearchBuilder();
|
||||
|
|
|
|||
|
|
@ -32,8 +32,9 @@ public class LBHealthCheckPolicyDaoImpl extends GenericDaoBase<LBHealthCheckPoli
|
|||
public void remove(long loadBalancerId) {
|
||||
SearchCriteria<LBHealthCheckPolicyVO> sc = createSearchCriteria();
|
||||
sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
|
||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||
|
||||
expunge(sc);
|
||||
remove(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -41,8 +42,9 @@ public class LBHealthCheckPolicyDaoImpl extends GenericDaoBase<LBHealthCheckPoli
|
|||
SearchCriteria<LBHealthCheckPolicyVO> sc = createSearchCriteria();
|
||||
sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
|
||||
sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke);
|
||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||
|
||||
expunge(sc);
|
||||
remove(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -28,4 +28,6 @@ public interface LBStickinessPolicyDao extends GenericDao<LBStickinessPolicyVO,
|
|||
List<LBStickinessPolicyVO> listByLoadBalancerIdAndDisplayFlag(long loadBalancerId, boolean forDisplay);
|
||||
|
||||
List<LBStickinessPolicyVO> listByLoadBalancerId(long loadBalancerId, boolean revoke);
|
||||
|
||||
List<LBStickinessPolicyVO> listByLoadBalancerId(long loadBalancerId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,9 @@ public class LBStickinessPolicyDaoImpl extends GenericDaoBase<LBStickinessPolicy
|
|||
public void remove(long loadBalancerId) {
|
||||
SearchCriteria<LBStickinessPolicyVO> sc = createSearchCriteria();
|
||||
sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
|
||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||
|
||||
expunge(sc);
|
||||
remove(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -40,8 +41,9 @@ public class LBStickinessPolicyDaoImpl extends GenericDaoBase<LBStickinessPolicy
|
|||
SearchCriteria<LBStickinessPolicyVO> sc = createSearchCriteria();
|
||||
sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
|
||||
sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke);
|
||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||
|
||||
expunge(sc);
|
||||
remove(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -62,4 +64,10 @@ public class LBStickinessPolicyDaoImpl extends GenericDaoBase<LBStickinessPolicy
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LBStickinessPolicyVO> listByLoadBalancerId(long loadBalancerId) {
|
||||
SearchCriteria<LBStickinessPolicyVO> sc = createSearchCriteria();
|
||||
sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package com.cloud.network.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
|
@ -30,9 +31,12 @@ import javax.persistence.GenerationType;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import com.cloud.network.rules.StickinessPolicy;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
@Entity
|
||||
|
|
@ -68,6 +72,10 @@ public class LBStickinessPolicyVO implements StickinessPolicy {
|
|||
@Column(name = "display", updatable = true, nullable = false)
|
||||
protected boolean display = true;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
protected LBStickinessPolicyVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,17 @@
|
|||
// under the License.
|
||||
package com.cloud.network.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
@Entity
|
||||
|
|
@ -45,6 +49,10 @@ public class LoadBalancerCertMapVO implements InternalIdentity {
|
|||
@Column(name = "revoke")
|
||||
private boolean revoke = false;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
public LoadBalancerCertMapVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,9 @@ public class LoadBalancerVMMapDaoImpl extends GenericDaoBase<LoadBalancerVMMapVO
|
|||
public void remove(long loadBalancerId) {
|
||||
SearchCriteria<LoadBalancerVMMapVO> sc = createSearchCriteria();
|
||||
sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
|
||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||
|
||||
expunge(sc);
|
||||
remove(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -43,11 +44,12 @@ public class LoadBalancerVMMapDaoImpl extends GenericDaoBase<LoadBalancerVMMapVO
|
|||
SearchCriteria<LoadBalancerVMMapVO> sc = createSearchCriteria();
|
||||
sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
|
||||
sc.addAnd("instanceId", SearchCriteria.Op.IN, instanceIds.toArray());
|
||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||
if (revoke != null) {
|
||||
sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke);
|
||||
}
|
||||
|
||||
expunge(sc);
|
||||
remove(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -56,12 +58,13 @@ public class LoadBalancerVMMapDaoImpl extends GenericDaoBase<LoadBalancerVMMapVO
|
|||
sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
|
||||
sc.addAnd("instanceId", SearchCriteria.Op.IN, instanceId);
|
||||
sc.addAnd("instanceIp", SearchCriteria.Op.EQ, instanceIp);
|
||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||
|
||||
if (revoke != null) {
|
||||
sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke);
|
||||
}
|
||||
|
||||
expunge(sc);
|
||||
remove(sc);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,9 +22,14 @@ import javax.persistence.GeneratedValue;
|
|||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@Table(name = "load_balancer_vm_map")
|
||||
public class LoadBalancerVMMapVO implements InternalIdentity {
|
||||
|
|
@ -48,6 +53,10 @@ public class LoadBalancerVMMapVO implements InternalIdentity {
|
|||
@Column(name = "state")
|
||||
private String state;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date removed = null;
|
||||
|
||||
public LoadBalancerVMMapVO() {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ import javax.persistence.Id;
|
|||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
|
@ -82,6 +84,10 @@ public class FirewallRuleVO implements FirewallRule {
|
|||
@Column(name = GenericDao.CREATED_COLUMN)
|
||||
Date created;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
@Column(name = "network_id")
|
||||
Long networkId;
|
||||
|
||||
|
|
@ -203,6 +209,10 @@ public class FirewallRuleVO implements FirewallRule {
|
|||
return created;
|
||||
}
|
||||
|
||||
public Date getRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
protected FirewallRuleVO() {
|
||||
uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ public class SecurityGroupWorkDaoImpl extends GenericDaoBase<SecurityGroupWorkVO
|
|||
//ensure that there is no job in Processing state for the same VM
|
||||
processing = true;
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Security Group work take: found a job in Scheduled and Processing vmid=" + work.getInstanceId());
|
||||
logger.trace("Security Group work take: found a job in Scheduled and Processing vmid={}", work.getInstanceId());
|
||||
}
|
||||
}
|
||||
work.setServerId(serverId);
|
||||
|
|
@ -141,26 +141,16 @@ public class SecurityGroupWorkDaoImpl extends GenericDaoBase<SecurityGroupWorkVO
|
|||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public void updateStep(Long vmId, Long logSequenceNumber, Step step) {
|
||||
final TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
txn.start();
|
||||
SearchCriteria<SecurityGroupWorkVO> sc = VmIdSeqNumSearch.create();
|
||||
sc.setParameters("vmId", vmId);
|
||||
sc.setParameters("seqno", logSequenceNumber);
|
||||
|
||||
final Filter filter = new Filter(SecurityGroupWorkVO.class, null, true, 0l, 1l);
|
||||
|
||||
final List<SecurityGroupWorkVO> vos = lockRows(sc, filter, true);
|
||||
if (vos.size() == 0) {
|
||||
txn.commit();
|
||||
return;
|
||||
}
|
||||
SecurityGroupWorkVO work = vos.get(0);
|
||||
work.setStep(step);
|
||||
update(work.getId(), work);
|
||||
|
||||
txn.commit();
|
||||
SecurityGroupWorkVO workForUpdate = createForUpdate();
|
||||
workForUpdate.setStep(step);
|
||||
// LIMIT 1 preserves the original single-row semantics: op_nwgrp_work has no
|
||||
// uniqueness on (instance_id, seq_no), so without it duplicate rows would all be updated.
|
||||
update(workForUpdate, sc, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -172,21 +162,10 @@ public class SecurityGroupWorkDaoImpl extends GenericDaoBase<SecurityGroupWorkVO
|
|||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public void updateStep(Long workId, Step step) {
|
||||
final TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
txn.start();
|
||||
|
||||
SecurityGroupWorkVO work = lockRow(workId, true);
|
||||
if (work == null) {
|
||||
txn.commit();
|
||||
return;
|
||||
}
|
||||
work.setStep(step);
|
||||
update(work.getId(), work);
|
||||
|
||||
txn.commit();
|
||||
|
||||
SecurityGroupWorkVO workForUpdate = createForUpdate();
|
||||
workForUpdate.setStep(step);
|
||||
update(workId, workForUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -182,6 +182,12 @@ public class VolumeVO implements Volume {
|
|||
@Column(name = "passphrase_id")
|
||||
private Long passphraseId;
|
||||
|
||||
@Column(name = "kms_key_id")
|
||||
private Long kmsKeyId;
|
||||
|
||||
@Column(name = "kms_wrapped_key_id")
|
||||
private Long kmsWrappedKeyId;
|
||||
|
||||
@Column(name = "encrypt_format")
|
||||
private String encryptFormat;
|
||||
|
||||
|
|
@ -683,6 +689,14 @@ public class VolumeVO implements Volume {
|
|||
|
||||
public void setPassphraseId(Long id) { this.passphraseId = id; }
|
||||
|
||||
public Long getKmsKeyId() { return kmsKeyId; }
|
||||
|
||||
public void setKmsKeyId(Long id) { this.kmsKeyId = id; }
|
||||
|
||||
public Long getKmsWrappedKeyId() { return kmsWrappedKeyId; }
|
||||
|
||||
public void setKmsWrappedKeyId(Long id) { this.kmsWrappedKeyId = id; }
|
||||
|
||||
public String getEncryptFormat() { return encryptFormat; }
|
||||
|
||||
public void setEncryptFormat(String encryptFormat) { this.encryptFormat = encryptFormat; }
|
||||
|
|
|
|||
|
|
@ -111,6 +111,17 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.S
|
|||
*/
|
||||
List<VolumeVO> listVolumesByPassphraseId(long passphraseId);
|
||||
|
||||
/**
|
||||
* List volumes with passphrase_id for migration to KMS
|
||||
*
|
||||
* @param zoneId Zone ID (required)
|
||||
* @param accountId Account ID filter (optional, null for all accounts)
|
||||
* @param domainId Domain ID filter (optional, null for all domains)
|
||||
* @param limit Maximum number of volumes to return
|
||||
* @return list of volumes that need migration
|
||||
*/
|
||||
Pair<List<VolumeVO>, Integer> listVolumesForKMSMigration(Long zoneId, Long accountId, Long domainId, Integer limit);
|
||||
|
||||
/**
|
||||
* Gets the Total Primary Storage space allocated for an account
|
||||
*
|
||||
|
|
@ -169,6 +180,8 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.S
|
|||
|
||||
VolumeVO findByLastIdAndState(long lastVolumeId, Volume.State...states);
|
||||
|
||||
boolean existsWithKmsKey(long kmsKeyId);
|
||||
|
||||
/**
|
||||
* Retrieves volume by its externalId
|
||||
*
|
||||
|
|
@ -176,4 +189,6 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.S
|
|||
* @return Volume Object of matching search criteria
|
||||
*/
|
||||
VolumeVO findByExternalUuid(String externalUuid);
|
||||
|
||||
List<VolumeVO> findByKmsWrappedKeyId(Long kmsWrappedKeyId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import javax.inject.Inject;
|
|||
|
||||
import org.apache.cloudstack.reservation.ReservationVO;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.cloudstack.kms.dao.KMSWrappedKeyDao;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
|
@ -80,11 +81,14 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
protected GenericSearchBuilder<VolumeVO, SumCount> secondaryStorageSearch;
|
||||
private final SearchBuilder<VolumeVO> poolAndPathSearch;
|
||||
final GenericSearchBuilder<VolumeVO, Integer> CountByOfferingId;
|
||||
private final SearchBuilder<VolumeVO> kmsMigrationSearch;
|
||||
|
||||
@Inject
|
||||
ReservationDao reservationDao;
|
||||
@Inject
|
||||
ResourceTagDao tagsDao;
|
||||
@Inject
|
||||
KMSWrappedKeyDao kmsWrappedKeyDao;
|
||||
|
||||
// need to account for zone-wide primary storage where storage_pool has
|
||||
// null-value pod and cluster, where hypervisor information is stored in
|
||||
|
|
@ -412,6 +416,8 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
AllFieldsSearch.and("passphraseId", AllFieldsSearch.entity().getPassphraseId(), Op.EQ);
|
||||
AllFieldsSearch.and("iScsiName", AllFieldsSearch.entity().get_iScsiName(), Op.EQ);
|
||||
AllFieldsSearch.and("path", AllFieldsSearch.entity().getPath(), Op.EQ);
|
||||
AllFieldsSearch.and("kmsKeyId", AllFieldsSearch.entity().getKmsKeyId(), Op.EQ);
|
||||
AllFieldsSearch.and("kmsWrappedKeyId", AllFieldsSearch.entity().getKmsWrappedKeyId(), Op.EQ);
|
||||
AllFieldsSearch.done();
|
||||
|
||||
RootDiskStateSearch = createSearchBuilder();
|
||||
|
|
@ -528,6 +534,13 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
CountByOfferingId.select(null, Func.COUNT, CountByOfferingId.entity().getId());
|
||||
CountByOfferingId.and("diskOfferingId", CountByOfferingId.entity().getDiskOfferingId(), Op.EQ);
|
||||
CountByOfferingId.done();
|
||||
|
||||
kmsMigrationSearch = createSearchBuilder();
|
||||
kmsMigrationSearch.and("passphraseId", kmsMigrationSearch.entity().getPassphraseId(), Op.NNULL);
|
||||
kmsMigrationSearch.and("zoneId", kmsMigrationSearch.entity().getDataCenterId(), Op.EQ);
|
||||
kmsMigrationSearch.and("accountId", kmsMigrationSearch.entity().getAccountId(), Op.EQ);
|
||||
kmsMigrationSearch.and("domainId", kmsMigrationSearch.entity().getDomainId(), Op.EQ);
|
||||
kmsMigrationSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -748,6 +761,21 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<VolumeVO>, Integer> listVolumesForKMSMigration(Long zoneId, Long accountId, Long domainId, Integer limit) {
|
||||
SearchCriteria<VolumeVO> sc = kmsMigrationSearch.create();
|
||||
|
||||
Filter filter = new Filter(limit);
|
||||
sc.setParameters("zoneId", zoneId);
|
||||
if (accountId != null) {
|
||||
sc.setParameters("accountId", accountId);
|
||||
}
|
||||
if (domainId != null) {
|
||||
sc.setParameters("domainId", domainId);
|
||||
}
|
||||
return searchAndCount(sc, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public boolean remove(Long id) {
|
||||
|
|
@ -756,6 +784,17 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
logger.debug(String.format("Removing volume %s from DB", id));
|
||||
VolumeVO entry = findById(id);
|
||||
if (entry != null) {
|
||||
// Clean up KMS wrapped key if volume was encrypted with KMS
|
||||
if (entry.getKmsWrappedKeyId() != null) {
|
||||
try {
|
||||
kmsWrappedKeyDao.remove(entry.getKmsWrappedKeyId());
|
||||
logger.debug("Removed KMS wrapped key [id={}] for volume [id={}, uuid={}]",
|
||||
entry.getKmsWrappedKeyId(), id, entry.getUuid());
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to remove KMS wrapped key [id={}] for volume [id={}, uuid={}]: {}",
|
||||
entry.getKmsWrappedKeyId(), id, entry.getUuid(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
tagsDao.removeByIdAndType(id, ResourceObjectType.Volume);
|
||||
}
|
||||
boolean result = super.remove(id);
|
||||
|
|
@ -952,9 +991,24 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean existsWithKmsKey(long kmsKeyId) {
|
||||
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("kmsKeyId", kmsKeyId);
|
||||
sc.setParameters("notDestroyed", Volume.State.Expunged, Volume.State.Destroy);
|
||||
return findOneBy(sc) != null;
|
||||
}
|
||||
|
||||
public VolumeVO findByExternalUuid(String externalUuid) {
|
||||
SearchCriteria<VolumeVO> sc = ExternalUuidSearch.create();
|
||||
sc.setParameters("externalUuid", externalUuid);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VolumeVO> findByKmsWrappedKeyId(Long kmsWrappedKeyId) {
|
||||
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("kmsWrappedKeyId", kmsWrappedKeyId);
|
||||
sc.setParameters("notDestroyed", Volume.State.Expunged);
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,9 +61,6 @@ public class UsageJobDaoImpl extends GenericDaoBase<UsageJobVO, Long> implements
|
|||
public void updateJobSuccess(Long jobId, long startMillis, long endMillis, long execTime, boolean success) {
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
try {
|
||||
txn.start();
|
||||
|
||||
UsageJobVO job = lockRow(jobId, Boolean.TRUE);
|
||||
UsageJobVO jobForUpdate = createForUpdate();
|
||||
jobForUpdate.setStartMillis(startMillis);
|
||||
jobForUpdate.setEndMillis(endMillis);
|
||||
|
|
@ -71,11 +68,8 @@ public class UsageJobDaoImpl extends GenericDaoBase<UsageJobVO, Long> implements
|
|||
jobForUpdate.setStartDate(new Date(startMillis));
|
||||
jobForUpdate.setEndDate(new Date(endMillis));
|
||||
jobForUpdate.setSuccess(success);
|
||||
update(job.getId(), jobForUpdate);
|
||||
|
||||
txn.commit();
|
||||
update(jobId, jobForUpdate);
|
||||
} catch (Exception ex) {
|
||||
txn.rollback();
|
||||
logger.error("error updating job success date", ex);
|
||||
throw new CloudRuntimeException(ex.getMessage());
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.vm;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
@Entity
|
||||
@Table(name = "vm_iso_map")
|
||||
public class VmIsoMapVO implements InternalIdentity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "vm_id")
|
||||
private long vmId;
|
||||
|
||||
@Column(name = "iso_id")
|
||||
private long isoId;
|
||||
|
||||
@Column(name = "device_seq")
|
||||
private int deviceSeq;
|
||||
|
||||
@Column(name = "created")
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date created;
|
||||
|
||||
public VmIsoMapVO() {
|
||||
}
|
||||
|
||||
public VmIsoMapVO(long vmId, long isoId, int deviceSeq) {
|
||||
this.vmId = vmId;
|
||||
this.isoId = isoId;
|
||||
this.deviceSeq = deviceSeq;
|
||||
this.created = new Date();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public long getIsoId() {
|
||||
return isoId;
|
||||
}
|
||||
|
||||
public int getDeviceSeq() {
|
||||
return deviceSeq;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.vm.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.vm.VmIsoMapVO;
|
||||
|
||||
public interface VmIsoMapDao extends GenericDao<VmIsoMapVO, Long> {
|
||||
List<VmIsoMapVO> listByVmId(long vmId);
|
||||
|
||||
List<VmIsoMapVO> listByIsoId(long isoId);
|
||||
|
||||
VmIsoMapVO findByVmIdDeviceSeq(long vmId, int deviceSeq);
|
||||
|
||||
VmIsoMapVO findByVmIdIsoId(long vmId, long isoId);
|
||||
|
||||
int removeByVmId(long vmId);
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.vm.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.vm.VmIsoMapVO;
|
||||
|
||||
@Component
|
||||
public class VmIsoMapDaoImpl extends GenericDaoBase<VmIsoMapVO, Long> implements VmIsoMapDao {
|
||||
|
||||
private SearchBuilder<VmIsoMapVO> ListByVmId;
|
||||
private SearchBuilder<VmIsoMapVO> ListByIsoId;
|
||||
private SearchBuilder<VmIsoMapVO> ByVmIdDeviceSeq;
|
||||
private SearchBuilder<VmIsoMapVO> ByVmIdIsoId;
|
||||
|
||||
protected VmIsoMapDaoImpl() {
|
||||
ListByVmId = createSearchBuilder();
|
||||
ListByVmId.and("vmId", ListByVmId.entity().getVmId(), SearchCriteria.Op.EQ);
|
||||
ListByVmId.done();
|
||||
|
||||
ListByIsoId = createSearchBuilder();
|
||||
ListByIsoId.and("isoId", ListByIsoId.entity().getIsoId(), SearchCriteria.Op.EQ);
|
||||
ListByIsoId.done();
|
||||
|
||||
ByVmIdDeviceSeq = createSearchBuilder();
|
||||
ByVmIdDeviceSeq.and("vmId", ByVmIdDeviceSeq.entity().getVmId(), SearchCriteria.Op.EQ);
|
||||
ByVmIdDeviceSeq.and("deviceSeq", ByVmIdDeviceSeq.entity().getDeviceSeq(), SearchCriteria.Op.EQ);
|
||||
ByVmIdDeviceSeq.done();
|
||||
|
||||
ByVmIdIsoId = createSearchBuilder();
|
||||
ByVmIdIsoId.and("vmId", ByVmIdIsoId.entity().getVmId(), SearchCriteria.Op.EQ);
|
||||
ByVmIdIsoId.and("isoId", ByVmIdIsoId.entity().getIsoId(), SearchCriteria.Op.EQ);
|
||||
ByVmIdIsoId.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VmIsoMapVO> listByVmId(long vmId) {
|
||||
SearchCriteria<VmIsoMapVO> sc = ListByVmId.create();
|
||||
sc.setParameters("vmId", vmId);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VmIsoMapVO> listByIsoId(long isoId) {
|
||||
SearchCriteria<VmIsoMapVO> sc = ListByIsoId.create();
|
||||
sc.setParameters("isoId", isoId);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VmIsoMapVO findByVmIdDeviceSeq(long vmId, int deviceSeq) {
|
||||
SearchCriteria<VmIsoMapVO> sc = ByVmIdDeviceSeq.create();
|
||||
sc.setParameters("vmId", vmId);
|
||||
sc.setParameters("deviceSeq", deviceSeq);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VmIsoMapVO findByVmIdIsoId(long vmId, long isoId) {
|
||||
SearchCriteria<VmIsoMapVO> sc = ByVmIdIsoId.create();
|
||||
sc.setParameters("vmId", vmId);
|
||||
sc.setParameters("isoId", isoId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int removeByVmId(long vmId) {
|
||||
SearchCriteria<VmIsoMapVO> sc = ListByVmId.create();
|
||||
sc.setParameters("vmId", vmId);
|
||||
return remove(sc);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms;
|
||||
|
||||
import org.apache.cloudstack.api.ResourceDetail;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "kms_hsm_profile_details")
|
||||
public class HSMProfileDetailsVO implements ResourceDetail {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "profile_id")
|
||||
private long resourceId;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "value")
|
||||
private String value;
|
||||
|
||||
public HSMProfileDetailsVO() {
|
||||
}
|
||||
|
||||
public HSMProfileDetailsVO(long profileId, String name, String value) {
|
||||
this.resourceId = profileId;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplay() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "kms_hsm_profiles")
|
||||
public class HSMProfileVO implements HSMProfile {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "uuid")
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "protocol")
|
||||
private String protocol;
|
||||
|
||||
@Column(name = "account_id")
|
||||
private Long accountId;
|
||||
|
||||
@Column(name = "domain_id")
|
||||
private Long domainId;
|
||||
|
||||
@Column(name = "zone_id")
|
||||
private Long zoneId;
|
||||
|
||||
@Column(name = "vendor_name")
|
||||
private String vendorName;
|
||||
|
||||
@Column(name = "enabled")
|
||||
private boolean enabled;
|
||||
|
||||
@Column(name = "is_public")
|
||||
private boolean isPublic;
|
||||
|
||||
@Column(name = "created")
|
||||
private Date created;
|
||||
|
||||
@Column(name = "removed")
|
||||
private Date removed;
|
||||
|
||||
public HSMProfileVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.created = new Date();
|
||||
this.isPublic = false;
|
||||
}
|
||||
|
||||
public HSMProfileVO(String name, String protocol, Long accountId, Long domainId, Long zoneId, String vendorName) {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.name = name;
|
||||
this.protocol = protocol;
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.zoneId = zoneId;
|
||||
this.vendorName = vendorName;
|
||||
this.enabled = true;
|
||||
this.isPublic = false;
|
||||
this.created = new Date();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("HSMProfileVO %s",
|
||||
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
|
||||
this, "id", "uuid", "name", "protocol", "system", "enabled"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
return accountId == null ? -1 : accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDomainId() {
|
||||
return domainId == null ? -1 : domainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVendorName() {
|
||||
return vendorName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getEntityType() {
|
||||
return HSMProfile.class;
|
||||
}
|
||||
|
||||
public void setRemoved(Date removed) {
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void setVendorName(String vendorName) {
|
||||
this.vendorName = vendorName;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getIsPublic() {
|
||||
return isPublic;
|
||||
}
|
||||
|
||||
public void setIsPublic(boolean isPublic) {
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Database entity for KEK versions.
|
||||
* Tracks multiple KEK versions per KMS key to support gradual rotation.
|
||||
* During rotation, a new version is created (status=Active) and old versions
|
||||
* are marked as Previous (still usable for decryption) or Archived (no longer used).
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "kms_kek_versions")
|
||||
public class KMSKekVersionVO {
|
||||
|
||||
public enum Status {
|
||||
/**
|
||||
* Used for new encryption operations
|
||||
*/
|
||||
Active,
|
||||
/**
|
||||
* Still usable for decryption during key rotation
|
||||
*/
|
||||
Previous,
|
||||
/**
|
||||
* No longer used; all wrapped keys have been re-encrypted
|
||||
*/
|
||||
Archived
|
||||
}
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "uuid", nullable = false)
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "kms_key_id", nullable = false)
|
||||
private Long kmsKeyId;
|
||||
|
||||
@Column(name = "version_number", nullable = false)
|
||||
private Integer versionNumber;
|
||||
|
||||
@Column(name = "kek_label", nullable = false)
|
||||
private String kekLabel;
|
||||
|
||||
@Column(name = "status", nullable = false, length = 32)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private Status status;
|
||||
|
||||
@Column(name = "hsm_profile_id")
|
||||
private Long hsmProfileId;
|
||||
|
||||
@Column(name = GenericDao.CREATED_COLUMN, nullable = false)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date created;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
public KMSKekVersionVO(Long kmsKeyId, Integer versionNumber, String kekLabel) {
|
||||
this();
|
||||
this.kmsKeyId = kmsKeyId;
|
||||
this.versionNumber = versionNumber;
|
||||
this.kekLabel = kekLabel;
|
||||
this.status = Status.Active;
|
||||
}
|
||||
|
||||
public KMSKekVersionVO(Long kmsKeyId, String kekLabel) {
|
||||
this();
|
||||
this.kmsKeyId = kmsKeyId;
|
||||
this.kekLabel = kekLabel;
|
||||
this.status = Status.Active;
|
||||
}
|
||||
|
||||
public KMSKekVersionVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.created = new Date();
|
||||
this.status = Status.Active;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public Long getKmsKeyId() {
|
||||
return kmsKeyId;
|
||||
}
|
||||
|
||||
public void setKmsKeyId(Long kmsKeyId) {
|
||||
this.kmsKeyId = kmsKeyId;
|
||||
}
|
||||
|
||||
public Integer getVersionNumber() {
|
||||
return versionNumber;
|
||||
}
|
||||
|
||||
public void setVersionNumber(Integer versionNumber) {
|
||||
this.versionNumber = versionNumber;
|
||||
}
|
||||
|
||||
public String getKekLabel() {
|
||||
return kekLabel;
|
||||
}
|
||||
|
||||
public void setKekLabel(String kekLabel) {
|
||||
this.kekLabel = kekLabel;
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Long getHsmProfileId() {
|
||||
return hsmProfileId;
|
||||
}
|
||||
|
||||
public void setHsmProfileId(Long hsmProfileId) {
|
||||
this.hsmProfileId = hsmProfileId;
|
||||
}
|
||||
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public Date getRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
public void setRemoved(Date removed) {
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("KMSKekVersion %s",
|
||||
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
|
||||
this, "id", "uuid", "kmsKeyId", "versionNumber", "status", "kekLabel"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,264 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.framework.kms.KeyPurpose;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Database entity for KMS Key (Key Encryption Key) metadata.
|
||||
* Tracks ownership, purpose, and lifecycle of KEKs used in envelope encryption.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "kms_keys")
|
||||
public class KMSKeyVO implements KMSKey {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "uuid", nullable = false)
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "name", nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(name = "description", length = 1024)
|
||||
private String description;
|
||||
|
||||
@Column(name = "kek_label", nullable = false)
|
||||
private String kekLabel;
|
||||
|
||||
@Column(name = "purpose", nullable = false, length = 32)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private KeyPurpose purpose;
|
||||
|
||||
@Column(name = "account_id", nullable = false)
|
||||
private Long accountId;
|
||||
|
||||
@Column(name = "domain_id", nullable = false)
|
||||
private Long domainId;
|
||||
|
||||
@Column(name = "zone_id", nullable = false)
|
||||
private Long zoneId;
|
||||
|
||||
@Column(name = "algorithm", nullable = false, length = 64)
|
||||
private String algorithm;
|
||||
|
||||
@Column(name = "key_bits", nullable = false)
|
||||
private Integer keyBits;
|
||||
|
||||
@Column(name = "enabled", nullable = false)
|
||||
private boolean enabled;
|
||||
|
||||
@Column(name = "hsm_profile_id")
|
||||
private Long hsmProfileId;
|
||||
|
||||
@Column(name = GenericDao.CREATED_COLUMN, nullable = false)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date created;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
public KMSKeyVO(String name, String description, String kekLabel,
|
||||
KeyPurpose purpose, Long accountId, Long domainId,
|
||||
Long zoneId, String algorithm, Integer keyBits
|
||||
) {
|
||||
this();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.kekLabel = kekLabel;
|
||||
this.purpose = purpose;
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.zoneId = zoneId;
|
||||
this.algorithm = algorithm;
|
||||
this.keyBits = keyBits;
|
||||
}
|
||||
|
||||
public KMSKeyVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.created = new Date();
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKekLabel() {
|
||||
return kekLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyPurpose getPurpose() {
|
||||
return purpose;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getKeyBits() {
|
||||
return keyBits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getHsmProfileId() {
|
||||
return hsmProfileId;
|
||||
}
|
||||
|
||||
public void setHsmProfileId(Long hsmProfileId) {
|
||||
this.hsmProfileId = hsmProfileId;
|
||||
}
|
||||
|
||||
public void setRemoved(Date removed) {
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void setKeyBits(Integer keyBits) {
|
||||
this.keyBits = keyBits;
|
||||
}
|
||||
|
||||
public void setAlgorithm(String algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public void setZoneId(Long zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public void setPurpose(KeyPurpose purpose) {
|
||||
this.purpose = purpose;
|
||||
}
|
||||
|
||||
public void setKekLabel(String kekLabel) {
|
||||
this.kekLabel = kekLabel;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(Long accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public void setDomainId(Long domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getEntityType() {
|
||||
return KMSKey.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("KMSKey %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
|
||||
this, "id", "uuid", "name", "purpose",
|
||||
"accountId", "zoneId", "enabled"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Database entity for storing wrapped (encrypted) Data Encryption Keys.
|
||||
* Each entry represents a DEK that has been encrypted by a Key Encryption Key (KEK).
|
||||
* KEK metadata is stored in kms_keys table via the kms_key_id foreign key.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "kms_wrapped_key")
|
||||
public class KMSWrappedKeyVO {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "uuid", nullable = false)
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "kms_key_id")
|
||||
private Long kmsKeyId;
|
||||
|
||||
@Column(name = "kek_version_id")
|
||||
private Long kekVersionId;
|
||||
|
||||
@Column(name = "zone_id", nullable = false)
|
||||
private Long zoneId;
|
||||
|
||||
@Column(name = "wrapped_blob", nullable = false)
|
||||
private byte[] wrappedBlob;
|
||||
|
||||
@Column(name = GenericDao.CREATED_COLUMN, nullable = false)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date created;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
public KMSWrappedKeyVO(KMSKeyVO kmsKey, byte[] wrappedBlob) {
|
||||
this();
|
||||
this.kmsKeyId = kmsKey.getId();
|
||||
this.zoneId = kmsKey.getZoneId();
|
||||
this.wrappedBlob = wrappedBlob != null ? Arrays.copyOf(wrappedBlob, wrappedBlob.length) : null;
|
||||
}
|
||||
|
||||
public KMSWrappedKeyVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.created = new Date();
|
||||
}
|
||||
|
||||
public KMSWrappedKeyVO(KMSKeyVO kmsKey, Long kekVersionId, byte[] wrappedBlob) {
|
||||
this();
|
||||
this.kmsKeyId = kmsKey.getId();
|
||||
this.kekVersionId = kekVersionId;
|
||||
this.zoneId = kmsKey.getZoneId();
|
||||
this.wrappedBlob = wrappedBlob != null ? Arrays.copyOf(wrappedBlob, wrappedBlob.length) : null;
|
||||
}
|
||||
|
||||
public KMSWrappedKeyVO(Long kmsKeyId, Long zoneId, byte[] wrappedBlob) {
|
||||
this();
|
||||
this.kmsKeyId = kmsKeyId;
|
||||
this.zoneId = zoneId;
|
||||
this.wrappedBlob = wrappedBlob != null ? Arrays.copyOf(wrappedBlob, wrappedBlob.length) : null;
|
||||
}
|
||||
|
||||
public KMSWrappedKeyVO(Long kmsKeyId, Long kekVersionId, Long zoneId, byte[] wrappedBlob) {
|
||||
this();
|
||||
this.kmsKeyId = kmsKeyId;
|
||||
this.kekVersionId = kekVersionId;
|
||||
this.zoneId = zoneId;
|
||||
this.wrappedBlob = wrappedBlob != null ? Arrays.copyOf(wrappedBlob, wrappedBlob.length) : null;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public Long getKmsKeyId() {
|
||||
return kmsKeyId;
|
||||
}
|
||||
|
||||
public void setKmsKeyId(Long kmsKeyId) {
|
||||
this.kmsKeyId = kmsKeyId;
|
||||
}
|
||||
|
||||
public Long getKekVersionId() {
|
||||
return kekVersionId;
|
||||
}
|
||||
|
||||
public void setKekVersionId(Long kekVersionId) {
|
||||
this.kekVersionId = kekVersionId;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public void setZoneId(Long zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public byte[] getWrappedBlob() {
|
||||
return wrappedBlob != null ? Arrays.copyOf(wrappedBlob, wrappedBlob.length) : null;
|
||||
}
|
||||
|
||||
public void setWrappedBlob(byte[] wrappedBlob) {
|
||||
this.wrappedBlob = wrappedBlob != null ? Arrays.copyOf(wrappedBlob, wrappedBlob.length) : null;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public Date getRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
public void setRemoved(Date removed) {
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("KMSWrappedKey %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
|
||||
this, "id", "uuid", "kmsKeyId", "kekVersionId", "zoneId", "created", "removed"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms.dao;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.kms.HSMProfileVO;
|
||||
|
||||
public interface HSMProfileDao extends GenericDao<HSMProfileVO, Long> {
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms.dao;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import org.apache.cloudstack.kms.HSMProfileVO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class HSMProfileDaoImpl extends GenericDaoBase<HSMProfileVO, Long> implements HSMProfileDao {
|
||||
public HSMProfileDaoImpl() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms.dao;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.kms.HSMProfileDetailsVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface HSMProfileDetailsDao extends GenericDao<HSMProfileDetailsVO, Long> {
|
||||
List<HSMProfileDetailsVO> listByProfileId(long profileId);
|
||||
|
||||
void persist(long profileId, String name, String value);
|
||||
|
||||
HSMProfileDetailsVO findDetail(long profileId, String name);
|
||||
|
||||
void deleteDetails(long profileId);
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms.dao;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import org.apache.cloudstack.kms.HSMProfileDetailsVO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class HSMProfileDetailsDaoImpl extends GenericDaoBase<HSMProfileDetailsVO, Long> implements HSMProfileDetailsDao {
|
||||
|
||||
protected SearchBuilder<HSMProfileDetailsVO> ProfileSearch;
|
||||
protected SearchBuilder<HSMProfileDetailsVO> DetailSearch;
|
||||
|
||||
public HSMProfileDetailsDaoImpl() {
|
||||
super();
|
||||
|
||||
ProfileSearch = createSearchBuilder();
|
||||
ProfileSearch.and("profileId", ProfileSearch.entity().getResourceId(), Op.EQ);
|
||||
ProfileSearch.done();
|
||||
|
||||
DetailSearch = createSearchBuilder();
|
||||
DetailSearch.and("profileId", DetailSearch.entity().getResourceId(), Op.EQ);
|
||||
DetailSearch.and("name", DetailSearch.entity().getName(), Op.EQ);
|
||||
DetailSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HSMProfileDetailsVO> listByProfileId(long profileId) {
|
||||
SearchCriteria<HSMProfileDetailsVO> sc = ProfileSearch.create();
|
||||
sc.setParameters("profileId", profileId);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void persist(long profileId, String name, String value) {
|
||||
HSMProfileDetailsVO vo = new HSMProfileDetailsVO(profileId, name, value);
|
||||
persist(vo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HSMProfileDetailsVO findDetail(long profileId, String name) {
|
||||
SearchCriteria<HSMProfileDetailsVO> sc = DetailSearch.create();
|
||||
sc.setParameters("profileId", profileId);
|
||||
sc.setParameters("name", name);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDetails(long profileId) {
|
||||
SearchCriteria<HSMProfileDetailsVO> sc = ProfileSearch.create();
|
||||
sc.setParameters("profileId", profileId);
|
||||
remove(sc);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.kms.dao;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.kms.KMSKekVersionVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface KMSKekVersionDao extends GenericDao<KMSKekVersionVO, Long> {
|
||||
|
||||
KMSKekVersionVO getActiveVersion(Long kmsKeyId);
|
||||
|
||||
/**
|
||||
* Returns Active and Previous versions (usable for decryption)
|
||||
*/
|
||||
List<KMSKekVersionVO> getVersionsForDecryption(Long kmsKeyId);
|
||||
|
||||
List<KMSKekVersionVO> listByKmsKeyId(Long kmsKeyId);
|
||||
|
||||
KMSKekVersionVO findByKmsKeyIdAndVersion(Long kmsKeyId, Integer versionNumber);
|
||||
|
||||
KMSKekVersionVO findByKekLabel(String kekLabel);
|
||||
|
||||
List<KMSKekVersionVO> findByStatus(KMSKekVersionVO.Status status);
|
||||
|
||||
List<KMSKekVersionVO> listByHsmProfileId(Long hsmProfileId);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue