mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge remote-tracking branch 'apache/4.19'
This commit is contained in:
commit
5a496e725b
@ -103,7 +103,7 @@ public class AddUserToProjectCmd extends BaseAsyncCmd {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getEventDescription() {
|
public String getEventDescription() {
|
||||||
return "Adding user "+getUsername()+" to Project "+getProjectId();
|
return "Adding user " + getUsername() + " to project: " + getProjectId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -81,7 +81,6 @@ public class DeleteUserFromProjectCmd extends BaseAsyncCmd {
|
|||||||
return "Removing user " + userId + " from project: " + projectId;
|
return "Removing user " + userId + " from project: " + projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getEntityOwnerId() {
|
public long getEntityOwnerId() {
|
||||||
Project project = _projectService.getProject(projectId);
|
Project project = _projectService.getProject(projectId);
|
||||||
|
|||||||
@ -18,6 +18,7 @@ package org.apache.cloudstack.framework.security.keystore;
|
|||||||
|
|
||||||
import com.cloud.agent.api.LogLevel;
|
import com.cloud.agent.api.LogLevel;
|
||||||
import com.cloud.agent.api.LogLevel.Log4jLevel;
|
import com.cloud.agent.api.LogLevel.Log4jLevel;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.component.Manager;
|
import com.cloud.utils.component.Manager;
|
||||||
|
|
||||||
public interface KeystoreManager extends Manager {
|
public interface KeystoreManager extends Manager {
|
||||||
@ -59,7 +60,7 @@ public interface KeystoreManager extends Manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean validateCertificate(String certificate, String key, String domainSuffix);
|
Pair<Boolean, String> validateCertificate(String certificate, String key, String domainSuffix);
|
||||||
|
|
||||||
void saveCertificate(String name, String certificate, String key, String domainSuffix);
|
void saveCertificate(String name, String certificate, String key, String domainSuffix);
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,7 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -45,24 +46,28 @@ public class KeystoreManagerImpl extends ManagerBase implements KeystoreManager
|
|||||||
private KeystoreDao _ksDao;
|
private KeystoreDao _ksDao;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean validateCertificate(String certificate, String key, String domainSuffix) {
|
public Pair<Boolean, String> validateCertificate(String certificate, String key, String domainSuffix) {
|
||||||
|
String errMsg = null;
|
||||||
if (StringUtils.isAnyEmpty(certificate, key, domainSuffix)) {
|
if (StringUtils.isAnyEmpty(certificate, key, domainSuffix)) {
|
||||||
logger.error("Invalid parameter found in (certificate, key, domainSuffix) tuple for domain: " + domainSuffix);
|
errMsg = String.format("Invalid parameter found in (certificate, key, domainSuffix) tuple for domain: %s", domainSuffix);
|
||||||
return false;
|
logger.error(errMsg);
|
||||||
|
return new Pair<>(false, errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String ksPassword = "passwordForValidation";
|
String ksPassword = "passwordForValidation";
|
||||||
byte[] ksBits = CertificateHelper.buildAndSaveKeystore(domainSuffix, certificate, getKeyContent(key), ksPassword);
|
byte[] ksBits = CertificateHelper.buildAndSaveKeystore(domainSuffix, certificate, getKeyContent(key), ksPassword);
|
||||||
KeyStore ks = CertificateHelper.loadKeystore(ksBits, ksPassword);
|
KeyStore ks = CertificateHelper.loadKeystore(ksBits, ksPassword);
|
||||||
if (ks != null)
|
if (ks != null) {
|
||||||
return true;
|
return new Pair<>(true, errMsg);
|
||||||
|
}
|
||||||
logger.error("Unabled to construct keystore for domain: " + domainSuffix);
|
errMsg = String.format("Unable to construct keystore for domain: %s", domainSuffix);
|
||||||
|
logger.error(errMsg);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Certificate validation failed due to exception for domain: " + domainSuffix, e);
|
errMsg = String.format("Certificate validation failed due to exception for domain: %s", domainSuffix);
|
||||||
|
logger.error(errMsg, e);
|
||||||
}
|
}
|
||||||
return false;
|
return new Pair<>(false, errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -55,6 +55,7 @@ import com.vmware.vim25.FileQueryFlags;
|
|||||||
import com.vmware.vim25.FolderFileInfo;
|
import com.vmware.vim25.FolderFileInfo;
|
||||||
import com.vmware.vim25.HostDatastoreBrowserSearchResults;
|
import com.vmware.vim25.HostDatastoreBrowserSearchResults;
|
||||||
import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
|
import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
|
||||||
|
import com.vmware.vim25.VirtualCdromIsoBackingInfo;
|
||||||
import com.vmware.vim25.VirtualMachineConfigSummary;
|
import com.vmware.vim25.VirtualMachineConfigSummary;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.backup.PrepareForBackupRestorationCommand;
|
import org.apache.cloudstack.backup.PrepareForBackupRestorationCommand;
|
||||||
@ -2737,8 +2738,9 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
|||||||
|
|
||||||
private DiskTO[] getDisks(DiskTO[] sortedDisks) {
|
private DiskTO[] getDisks(DiskTO[] sortedDisks) {
|
||||||
return Arrays.stream(sortedDisks).filter(vol -> ((vol.getPath() != null &&
|
return Arrays.stream(sortedDisks).filter(vol -> ((vol.getPath() != null &&
|
||||||
vol.getPath().contains("configdrive"))) || (vol.getType() != Volume.Type.ISO)).toArray(DiskTO[]::new);
|
vol.getPath().contains(ConfigDrive.CONFIGDRIVEDIR))) || (vol.getType() != Volume.Type.ISO)).toArray(DiskTO[]::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureIso(VmwareHypervisorHost hyperHost, VirtualMachineMO vmMo, DiskTO vol,
|
private void configureIso(VmwareHypervisorHost hyperHost, VirtualMachineMO vmMo, DiskTO vol,
|
||||||
VirtualDeviceConfigSpec[] deviceConfigSpecArray, int ideUnitNumber, int i) throws Exception {
|
VirtualDeviceConfigSpec[] deviceConfigSpecArray, int ideUnitNumber, int i) throws Exception {
|
||||||
TemplateObjectTO iso = (TemplateObjectTO) vol.getData();
|
TemplateObjectTO iso = (TemplateObjectTO) vol.getData();
|
||||||
@ -4447,6 +4449,8 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
|||||||
msg = "Have problem in powering off VM " + cmd.getVmName() + ", let the process continue";
|
msg = "Have problem in powering off VM " + cmd.getVmName() + ", let the process continue";
|
||||||
logger.warn(msg);
|
logger.warn(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnectConfigDriveIsoIfExists(vmMo);
|
||||||
return new StopAnswer(cmd, msg, true);
|
return new StopAnswer(cmd, msg, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4465,6 +4469,30 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void disconnectConfigDriveIsoIfExists(VirtualMachineMO vmMo) {
|
||||||
|
try {
|
||||||
|
List<VirtualDevice> isoDevices = vmMo.getIsoDevices();
|
||||||
|
if (CollectionUtils.isEmpty(isoDevices)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (VirtualDevice isoDevice : isoDevices) {
|
||||||
|
if (!(isoDevice.getBacking() instanceof VirtualCdromIsoBackingInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String isoFilePath = ((VirtualCdromIsoBackingInfo)isoDevice.getBacking()).getFileName();
|
||||||
|
if (!isoFilePath.contains(ConfigDrive.CONFIGDRIVEDIR)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
logger.info(String.format("Disconnecting config drive at location: %s", isoFilePath));
|
||||||
|
vmMo.detachIso(isoFilePath, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn(String.format("Couldn't check/disconnect config drive, error: %s", e.getMessage()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected Answer execute(RebootRouterCommand cmd) {
|
protected Answer execute(RebootRouterCommand cmd) {
|
||||||
RebootAnswer answer = (RebootAnswer) execute((RebootCommand) cmd);
|
RebootAnswer answer = (RebootAnswer) execute((RebootCommand) cmd);
|
||||||
|
|
||||||
|
|||||||
@ -88,13 +88,13 @@ public class ActionEventInterceptor implements ComponentMethodInterceptor, Metho
|
|||||||
for (ActionEvent actionEvent : getActionEvents(method)) {
|
for (ActionEvent actionEvent : getActionEvents(method)) {
|
||||||
CallContext ctx = CallContext.current();
|
CallContext ctx = CallContext.current();
|
||||||
long userId = ctx.getCallingUserId();
|
long userId = ctx.getCallingUserId();
|
||||||
long accountId = ctx.getProject() != null ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id.
|
|
||||||
long startEventId = ctx.getStartEventId();
|
long startEventId = ctx.getStartEventId();
|
||||||
String eventDescription = getEventDescription(actionEvent, ctx);
|
String eventDescription = getEventDescription(actionEvent, ctx);
|
||||||
Long eventResourceId = getEventResourceId(actionEvent, ctx);
|
Long eventResourceId = getEventResourceId(actionEvent, ctx);
|
||||||
String eventResourceType = getEventResourceType(actionEvent, ctx);
|
String eventResourceType = getEventResourceType(actionEvent, ctx);
|
||||||
String eventType = getEventType(actionEvent, ctx);
|
String eventType = getEventType(actionEvent, ctx);
|
||||||
boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled();
|
boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled();
|
||||||
|
long accountId = ActionEventUtils.getOwnerAccountId(ctx, eventType, ctx.getCallingAccountId());
|
||||||
|
|
||||||
if (eventType.equals(""))
|
if (eventType.equals(""))
|
||||||
return;
|
return;
|
||||||
@ -118,13 +118,13 @@ public class ActionEventInterceptor implements ComponentMethodInterceptor, Metho
|
|||||||
for (ActionEvent actionEvent : getActionEvents(method)) {
|
for (ActionEvent actionEvent : getActionEvents(method)) {
|
||||||
CallContext ctx = CallContext.current();
|
CallContext ctx = CallContext.current();
|
||||||
long userId = ctx.getCallingUserId();
|
long userId = ctx.getCallingUserId();
|
||||||
long accountId = ctx.getCallingAccountId();
|
|
||||||
long startEventId = ctx.getStartEventId();
|
long startEventId = ctx.getStartEventId();
|
||||||
String eventDescription = getEventDescription(actionEvent, ctx);
|
String eventDescription = getEventDescription(actionEvent, ctx);
|
||||||
Long eventResourceId = getEventResourceId(actionEvent, ctx);
|
Long eventResourceId = getEventResourceId(actionEvent, ctx);
|
||||||
String eventResourceType = getEventResourceType(actionEvent, ctx);
|
String eventResourceType = getEventResourceType(actionEvent, ctx);
|
||||||
String eventType = getEventType(actionEvent, ctx);
|
String eventType = getEventType(actionEvent, ctx);
|
||||||
boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled();
|
boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled();
|
||||||
|
long accountId = ActionEventUtils.getOwnerAccountId(ctx, eventType, ctx.getCallingAccountId());
|
||||||
|
|
||||||
if (eventType.equals(""))
|
if (eventType.equals(""))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import java.lang.reflect.Method;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@ -112,6 +113,8 @@ public class ActionEventUtils {
|
|||||||
*/
|
*/
|
||||||
public static Long onScheduledActionEvent(Long userId, Long accountId, String type, String description, Long resourceId, String resourceType, boolean eventDisplayEnabled, long startEventId) {
|
public static Long onScheduledActionEvent(Long userId, Long accountId, String type, String description, Long resourceId, String resourceType, boolean eventDisplayEnabled, long startEventId) {
|
||||||
Ternary<Long, String, String> resourceDetails = getResourceDetails(resourceId, resourceType, type);
|
Ternary<Long, String, String> resourceDetails = getResourceDetails(resourceId, resourceType, type);
|
||||||
|
CallContext ctx = CallContext.current();
|
||||||
|
accountId = getOwnerAccountId(ctx, type, accountId);
|
||||||
Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Scheduled,
|
Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Scheduled,
|
||||||
eventDisplayEnabled, description, resourceDetails.first(), resourceDetails.third(), startEventId);
|
eventDisplayEnabled, description, resourceDetails.first(), resourceDetails.third(), startEventId);
|
||||||
publishOnEventBus(event, userId, accountId, EventCategory.ACTION_EVENT.getName(), type,
|
publishOnEventBus(event, userId, accountId, EventCategory.ACTION_EVENT.getName(), type,
|
||||||
@ -127,7 +130,7 @@ public class ActionEventUtils {
|
|||||||
public static void onStartedActionEventFromContext(String eventType, String eventDescription, Long resourceId, String resourceType, boolean eventDisplayEnabled) {
|
public static void onStartedActionEventFromContext(String eventType, String eventDescription, Long resourceId, String resourceType, boolean eventDisplayEnabled) {
|
||||||
CallContext ctx = CallContext.current();
|
CallContext ctx = CallContext.current();
|
||||||
long userId = ctx.getCallingUserId();
|
long userId = ctx.getCallingUserId();
|
||||||
long accountId = ctx.getProject() != null ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id.
|
long accountId = getOwnerAccountId(ctx, eventType, ctx.getCallingAccountId());
|
||||||
long startEventId = ctx.getStartEventId();
|
long startEventId = ctx.getStartEventId();
|
||||||
|
|
||||||
if (!eventType.equals(""))
|
if (!eventType.equals(""))
|
||||||
@ -413,7 +416,11 @@ public class ActionEventUtils {
|
|||||||
LOGGER.trace("Caught exception while populating first class entities for event bus, moving on");
|
LOGGER.trace("Caught exception while populating first class entities for event bus, moving on");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getOwnerAccountId(CallContext ctx, String eventType, long callingAccountId) {
|
||||||
|
List<String> mainProjectEvents = List.of(EventTypes.EVENT_PROJECT_CREATE, EventTypes.EVENT_PROJECT_UPDATE, EventTypes.EVENT_PROJECT_DELETE);
|
||||||
|
long accountId = ctx.getProject() != null && !mainProjectEvents.stream().anyMatch(eventType::equalsIgnoreCase) ? ctx.getProject().getProjectAccountId() : callingAccountId; //This should be the entity owner id rather than the Calling User Account Id.
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -293,16 +293,16 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||||||
assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin,
|
assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin,
|
||||||
Optional.ofNullable(finalUser).map(User::getId).orElse(null), null);
|
Optional.ofNullable(finalUser).map(User::getId).orElse(null), null);
|
||||||
|
|
||||||
if (project != null) {
|
if (project != null) {
|
||||||
CallContext.current().setEventDetails("Project id=" + project.getId());
|
CallContext.current().setEventDetails("Project id=" + project.getId());
|
||||||
CallContext.current().putContextParameter(Project.class, project.getUuid());
|
CallContext.current().putContextParameter(Project.class, project.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
//Increment resource count
|
//Increment resource count
|
||||||
_resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project);
|
_resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project);
|
||||||
|
|
||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
messageBus.publish(_name, ProjectManager.MESSAGE_CREATE_TUNGSTEN_PROJECT_EVENT, PublishScope.LOCAL, project);
|
messageBus.publish(_name, ProjectManager.MESSAGE_CREATE_TUNGSTEN_PROJECT_EVENT, PublishScope.LOCAL, project);
|
||||||
@ -1290,7 +1290,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project")
|
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project", async = true)
|
||||||
@DB
|
@DB
|
||||||
public Project activateProject(final long projectId) {
|
public Project activateProject(final long projectId) {
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
package com.cloud.server;
|
package com.cloud.server;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@ -43,6 +44,7 @@ import javax.crypto.spec.SecretKeySpec;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import com.cloud.utils.security.CertificateHelper;
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker;
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
||||||
@ -4572,13 +4574,12 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
|
|
||||||
final String certificate = cmd.getCertificate();
|
final String certificate = cmd.getCertificate();
|
||||||
final String key = cmd.getPrivateKey();
|
final String key = cmd.getPrivateKey();
|
||||||
|
String domainSuffix = cmd.getDomainSuffix();
|
||||||
|
|
||||||
if (cmd.getPrivateKey() != null && !_ksMgr.validateCertificate(certificate, key, cmd.getDomainSuffix())) {
|
validateCertificate(certificate, key, domainSuffix);
|
||||||
throw new InvalidParameterValueException("Failed to pass certificate validation check");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd.getPrivateKey() != null) {
|
if (cmd.getPrivateKey() != null) {
|
||||||
_ksMgr.saveCertificate(ConsoleProxyManager.CERTIFICATE_NAME, certificate, key, cmd.getDomainSuffix());
|
_ksMgr.saveCertificate(ConsoleProxyManager.CERTIFICATE_NAME, certificate, key, domainSuffix);
|
||||||
|
|
||||||
// Reboot ssvm here since private key is present - meaning server cert being passed
|
// Reboot ssvm here since private key is present - meaning server cert being passed
|
||||||
final List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, State.Running, State.Migrating, State.Starting);
|
final List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, State.Running, State.Migrating, State.Starting);
|
||||||
@ -4595,6 +4596,24 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
+ "please give a few minutes for console access and storage services service to be up and working again";
|
+ "please give a few minutes for console access and storage services service to be up and working again";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateCertificate(String certificate, String key, String domainSuffix) {
|
||||||
|
if (key != null) {
|
||||||
|
Pair<Boolean, String> result = _ksMgr.validateCertificate(certificate, key, domainSuffix);
|
||||||
|
if (!result.first()) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Failed to pass certificate validation check with error: %s", result.second()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
logger.debug(String.format("Trying to validate the root certificate format"));
|
||||||
|
CertificateHelper.buildCertificate(certificate);
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
String errorMsg = String.format("Failed to pass certificate validation check with error: Certificate validation failed due to exception: %s", e.getMessage());
|
||||||
|
logger.error(errorMsg);
|
||||||
|
throw new InvalidParameterValueException(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getHypervisors(final Long zoneId) {
|
public List<String> getHypervisors(final Long zoneId) {
|
||||||
final List<String> result = new ArrayList<>();
|
final List<String> result = new ArrayList<>();
|
||||||
|
|||||||
@ -4776,17 +4776,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, dataDiskControllerSetting);
|
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, dataDiskControllerSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
String controllerSetting = StringUtils.defaultIfEmpty(_configDao.getValue(Config.VmwareRootDiskControllerType.key()),
|
|
||||||
Config.VmwareRootDiskControllerType.getDefaultValue());
|
|
||||||
|
|
||||||
// Don't override if VM already has root/data disk controller detail
|
// Don't override if VM already has root/data disk controller detail
|
||||||
if (vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER) == null) {
|
if (vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER) == null) {
|
||||||
vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, controllerSetting);
|
String vmwareRootDiskControllerTypeFromSetting = StringUtils.defaultIfEmpty(_configDao.getValue(Config.VmwareRootDiskControllerType.key()),
|
||||||
|
Config.VmwareRootDiskControllerType.getDefaultValue());
|
||||||
|
vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, vmwareRootDiskControllerTypeFromSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER) == null) {
|
if (vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER) == null) {
|
||||||
if (controllerSetting.equalsIgnoreCase("scsi")) {
|
String finalRootDiskController = vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER);
|
||||||
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
|
// Set the data disk controller detail same as the final scsi root disk controller if VM doesn't have data disk controller detail
|
||||||
|
// This is to ensure the disk controller is available for the data disks, as all the SCSI controllers are created with same controller type
|
||||||
|
String scsiControllerPattern = "(?i)\\b(scsi|lsilogic|lsilogicsas|lsisas1068|buslogic|pvscsi)\\b";
|
||||||
|
if (finalRootDiskController.matches(scsiControllerPattern)) {
|
||||||
|
logger.info(String.format("Data disk controller was not defined, but root disk is using SCSI controller [%s]." +
|
||||||
|
"To ensure disk controllers are available for the data disks, the data disk controller is updated to match the root disk controller.", finalRootDiskController));
|
||||||
|
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, finalRootDiskController);
|
||||||
} else {
|
} else {
|
||||||
|
logger.info("Data disk controller was not defined; defaulting to 'osdefault'.");
|
||||||
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "osdefault");
|
vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "osdefault");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3201,6 +3201,14 @@ public class VirtualMachineMO extends BaseMO {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<VirtualDevice> getIsoDevices() throws Exception {
|
||||||
|
List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
|
||||||
|
if (CollectionUtils.isEmpty(devices)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
return devices.stream().filter(device -> device instanceof VirtualCdrom).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
public VirtualDevice getIsoDevice(int key) throws Exception {
|
public VirtualDevice getIsoDevice(int key) throws Exception {
|
||||||
List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
|
List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
|
||||||
if (devices != null && devices.size() > 0) {
|
if (devices != null && devices.size() > 0) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user