mirror of https://github.com/apache/cloudstack.git
fixes
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
260e6bc5bf
commit
bad164c991
|
|
@ -150,7 +150,7 @@ public abstract class BaseDeployVMCmd extends BaseAsyncCreateCustomIdCmd impleme
|
|||
protected String userData;
|
||||
|
||||
@Parameter(name = ApiConstants.USER_DATA_ID, type = CommandType.UUID, entityType = UserDataResponse.class, description = "the ID of the Userdata", since = "4.18")
|
||||
private Long userdataId;
|
||||
protected Long userdataId;
|
||||
|
||||
@Parameter(name = ApiConstants.USER_DATA_DETAILS, type = CommandType.MAP, description = "used to specify the parameters values for the variables in userdata.", since = "4.18")
|
||||
private Map userdataDetails;
|
||||
|
|
@ -200,7 +200,7 @@ public abstract class BaseDeployVMCmd extends BaseAsyncCreateCustomIdCmd impleme
|
|||
@ACL
|
||||
@Parameter(name = ApiConstants.AFFINITY_GROUP_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AffinityGroupResponse.class, description = "comma separated list of affinity groups id that are going to be applied to the virtual machine."
|
||||
+ " Mutually exclusive with affinitygroupnames parameter")
|
||||
private List<Long> affinityGroupIdList;
|
||||
protected List<Long> affinityGroupIdList;
|
||||
|
||||
@ACL
|
||||
@Parameter(name = ApiConstants.AFFINITY_GROUP_NAMES, type = CommandType.LIST, collectionType = CommandType.STRING, entityType = AffinityGroupResponse.class, description = "comma separated list of affinity groups names that are going to be applied to the virtual machine."
|
||||
|
|
|
|||
|
|
@ -155,6 +155,14 @@ public class DeployVMCmd extends BaseDeployVMCmd {
|
|||
this.displayVm = displayVm;
|
||||
}
|
||||
|
||||
public void setUserDataId(Long userDataId) {
|
||||
this.userdataId = userDataId;
|
||||
}
|
||||
|
||||
public void setAffinityGroupIds(List<Long> ids) {
|
||||
this.affinityGroupIdList = ids;
|
||||
}
|
||||
|
||||
public void setDetails(Map details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.cloud.cpu.CPU;
|
|||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
||||
|
|
@ -62,5 +63,5 @@ public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
|||
|
||||
List<Long> listEnabledClusterIdsByZoneHypervisorArch(Long zoneId, HypervisorType hypervisorType, CPU.CPUArch arch);
|
||||
|
||||
List<ClusterVO> listByHypervisorType(HypervisorType hypervisorType);
|
||||
List<ClusterVO> listByHypervisorType(HypervisorType hypervisorType, Filter filter);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
|||
import com.cloud.org.Grouping;
|
||||
import com.cloud.org.Managed;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
|
|
@ -415,9 +416,9 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ClusterVO> listByHypervisorType(HypervisorType hypervisorType) {
|
||||
public List<ClusterVO> listByHypervisorType(HypervisorType hypervisorType, Filter filter) {
|
||||
SearchCriteria<ClusterVO> sc = ZoneHyTypeSearch.create();
|
||||
sc.setParameters("hypervisorType", hypervisorType.toString());
|
||||
return listBy(sc);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import com.cloud.network.Network;
|
|||
import com.cloud.network.Network.GuestType;
|
||||
import com.cloud.network.Network.State;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.fsm.StateDao;
|
||||
|
|
@ -96,9 +97,11 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
|
|||
|
||||
boolean update(Long networkId, NetworkVO network, Map<String, String> serviceProviderMap);
|
||||
|
||||
List<NetworkVO> listByZoneAndTrafficType(long zoneId, TrafficType trafficType, Filter filter);
|
||||
|
||||
List<NetworkVO> listByZoneAndTrafficType(long zoneId, TrafficType trafficType);
|
||||
|
||||
List<NetworkVO> listByTrafficType(TrafficType trafficType);
|
||||
List<NetworkVO> listByTrafficType(TrafficType trafficType, Filter filter);
|
||||
|
||||
void setCheckForGc(long networkId);
|
||||
|
||||
|
|
|
|||
|
|
@ -632,20 +632,25 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkVO> listByZoneAndTrafficType(final long zoneId, final TrafficType trafficType) {
|
||||
public List<NetworkVO> listByZoneAndTrafficType(final long zoneId, final TrafficType trafficType, Filter filter) {
|
||||
final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("datacenter", zoneId);
|
||||
sc.setParameters("trafficType", trafficType);
|
||||
|
||||
return listBy(sc, null);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkVO> listByTrafficType(final TrafficType trafficType) {
|
||||
public List<NetworkVO> listByZoneAndTrafficType(final long zoneId, final TrafficType trafficType) {
|
||||
return listByZoneAndTrafficType(zoneId, trafficType, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkVO> listByTrafficType(final TrafficType trafficType, Filter filter) {
|
||||
final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("trafficType", trafficType);
|
||||
|
||||
return listBy(sc, null);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import java.util.Set;
|
|||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.server.ResourceTag.ResourceObjectType;
|
||||
import com.cloud.tags.ResourceTagVO;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.api.response.ResourceTagResponse;
|
||||
|
||||
|
|
@ -61,5 +62,5 @@ public interface ResourceTagDao extends GenericDao<ResourceTagVO, Long> {
|
|||
|
||||
List<? extends ResourceTag> listByResourceUuid(String resourceUuid);
|
||||
|
||||
List<ResourceTagVO> listByResourceType(ResourceObjectType resourceType);
|
||||
List<ResourceTagVO> listByResourceType(ResourceObjectType resourceType, Filter filter);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import org.springframework.stereotype.Component;
|
|||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.server.ResourceTag.ResourceObjectType;
|
||||
import com.cloud.tags.ResourceTagVO;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
|
@ -122,9 +123,9 @@ public class ResourceTagsDaoImpl extends GenericDaoBase<ResourceTagVO, Long> imp
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceTagVO> listByResourceType(ResourceObjectType resourceType) {
|
||||
public List<ResourceTagVO> listByResourceType(ResourceObjectType resourceType, Filter filter) {
|
||||
SearchCriteria<ResourceTagVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("resourceType", resourceType);
|
||||
return listBy(sc);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package org.apache.cloudstack.veeam;
|
|||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
|
@ -30,6 +30,7 @@ import org.apache.logging.log4j.Logger;
|
|||
import com.cloud.utils.component.Adapter;
|
||||
|
||||
public interface RouteHandler extends Adapter {
|
||||
static final Pattern PAGE_PATTERN = Pattern.compile("\\bpage\\s+(\\d+)");
|
||||
default int priority() { return 0; }
|
||||
boolean canHandle(String method, String path) throws IOException;
|
||||
void handle(HttpServletRequest req, HttpServletResponse resp, String path, Negotiation.OutFormat outFormat, VeeamControlServlet io)
|
||||
|
|
@ -73,10 +74,4 @@ public interface RouteHandler extends Adapter {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static Map<String, String> getRequestParams(HttpServletRequest req) {
|
||||
return req.getParameterMap().entrySet().stream()
|
||||
.filter(e -> e.getValue() != null && e.getValue().length > 0)
|
||||
.collect(java.util.stream.Collectors.toMap(Map.Entry::getKey, e -> e.getValue()[0]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ import org.apache.cloudstack.acl.RolePermissionEntity;
|
|||
import org.apache.cloudstack.acl.RoleService;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.acl.Rule;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupVO;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiServerService;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
|
|
@ -116,20 +119,19 @@ import org.apache.cloudstack.veeam.api.dto.Vm;
|
|||
import org.apache.cloudstack.veeam.api.dto.VmAction;
|
||||
import org.apache.cloudstack.veeam.api.dto.VnicProfile;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.cloud.api.query.dao.AsyncJobJoinDao;
|
||||
import com.cloud.api.query.dao.DataCenterJoinDao;
|
||||
import com.cloud.api.query.dao.HostJoinDao;
|
||||
import com.cloud.api.query.dao.ImageStoreJoinDao;
|
||||
import com.cloud.api.query.dao.StoragePoolJoinDao;
|
||||
import com.cloud.api.query.dao.UserVmJoinDao;
|
||||
import com.cloud.api.query.dao.VolumeJoinDao;
|
||||
import com.cloud.api.query.vo.AsyncJobJoinVO;
|
||||
import com.cloud.api.query.vo.DataCenterJoinVO;
|
||||
import com.cloud.api.query.vo.HostJoinVO;
|
||||
import com.cloud.api.query.vo.ImageStoreJoinVO;
|
||||
import com.cloud.api.query.vo.StoragePoolJoinVO;
|
||||
import com.cloud.api.query.vo.UserVmJoinVO;
|
||||
import com.cloud.api.query.vo.VolumeJoinVO;
|
||||
|
|
@ -152,6 +154,7 @@ import com.cloud.org.Grouping;
|
|||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectService;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Volume;
|
||||
|
|
@ -166,15 +169,18 @@ import com.cloud.user.Account;
|
|||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccount;
|
||||
import com.cloud.user.UserDataVO;
|
||||
import com.cloud.user.dao.UserDataDao;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.EnumUtils;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.Ternary;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.UserVmService;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
|
|
@ -183,8 +189,7 @@ import com.cloud.vm.dao.VMInstanceDetailsDao;
|
|||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
// ToDo: fix list APIs to support pagination, etc
|
||||
// ToDo: check access on objects
|
||||
// ToDo: check access for list APIs when not ROOT admin
|
||||
|
||||
public class ServerAdapter extends ManagerBase {
|
||||
private static final String SERVICE_ACCOUNT_NAME = "veemserviceuser";
|
||||
|
|
@ -206,7 +211,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
ResizeVolumeCmd.class,
|
||||
ListNetworksCmd.class
|
||||
);
|
||||
public static final String GUEST_CPU_MODE = "host-passthrough";
|
||||
public static final String WORKER_VM_GUEST_CPU_MODE = "host-passthrough";
|
||||
|
||||
@Inject
|
||||
RoleService roleService;
|
||||
|
|
@ -223,9 +228,6 @@ public class ServerAdapter extends ManagerBase {
|
|||
@Inject
|
||||
StoragePoolJoinDao storagePoolJoinDao;
|
||||
|
||||
@Inject
|
||||
ImageStoreJoinDao imageStoreJoinDao;
|
||||
|
||||
@Inject
|
||||
ClusterDao clusterDao;
|
||||
|
||||
|
|
@ -275,7 +277,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
VMTemplateDao templateDao;
|
||||
|
||||
@Inject
|
||||
UserVmService userVmService;
|
||||
UserVmManager userVmManager;
|
||||
|
||||
@Inject
|
||||
NicDao nicDao;
|
||||
|
|
@ -304,6 +306,12 @@ public class ServerAdapter extends ManagerBase {
|
|||
@Inject
|
||||
ProjectService projectService;
|
||||
|
||||
@Inject
|
||||
AffinityGroupDao affinityGroupDao;
|
||||
|
||||
@Inject
|
||||
UserDataDao userDataDao;
|
||||
|
||||
protected static Tag getDummyTagByName(String name) {
|
||||
Tag tag = new Tag();
|
||||
String id = UUID.nameUUIDFromBytes(String.format("veeam:%s", name.toLowerCase()).getBytes()).toString();
|
||||
|
|
@ -429,15 +437,22 @@ public class ServerAdapter extends ManagerBase {
|
|||
waitForJobCompletion(job.getId());
|
||||
}
|
||||
|
||||
protected void validateServiceAccountAdminAccess() {
|
||||
Pair<User, Account> serviceAccount = getServiceAccount();
|
||||
if (!accountService.isAdmin(serviceAccount.second().getId())) {
|
||||
throw new InvalidParameterValueException("Service account does not have access");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
getServiceAccount();
|
||||
//find public custom disk offering
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<DataCenter> listAllDataCenters() {
|
||||
final List<DataCenterJoinVO> clusters = dataCenterJoinDao.listAll();
|
||||
public List<DataCenter> listAllDataCenters(Long offset, Long limit) {
|
||||
Filter filter = new Filter(DataCenterJoinVO.class, "id", true, offset, limit);
|
||||
final List<DataCenterJoinVO> clusters = dataCenterJoinDao.listAll(filter);
|
||||
return DataCenterJoinVOToDataCenterConverter.toDCList(clusters);
|
||||
}
|
||||
|
||||
|
|
@ -449,81 +464,92 @@ public class ServerAdapter extends ManagerBase {
|
|||
return DataCenterJoinVOToDataCenterConverter.toDataCenter(vo);
|
||||
}
|
||||
|
||||
public List<StorageDomain> listStorageDomainsByDcId(final String uuid) {
|
||||
final DataCenterJoinVO dataCenterVO = dataCenterJoinDao.findByUuid(uuid);
|
||||
public List<StorageDomain> listStorageDomainsByDcId(final String uuid, final Long offset, final Long limit) {
|
||||
final DataCenterVO dataCenterVO = dataCenterDao.findByUuid(uuid);
|
||||
if (dataCenterVO == null) {
|
||||
throw new InvalidParameterValueException("DataCenter with ID " + uuid + " not found");
|
||||
}
|
||||
List<StoragePoolJoinVO> storagePoolVOS = storagePoolJoinDao.listAll();
|
||||
List<StorageDomain> storageDomains = StoreVOToStorageDomainConverter.toStorageDomainListFromPools(storagePoolVOS);
|
||||
List<ImageStoreJoinVO> imageStoreJoinVOS = imageStoreJoinDao.listAll();
|
||||
storageDomains.addAll(StoreVOToStorageDomainConverter.toStorageDomainListFromStores(imageStoreJoinVOS));
|
||||
return storageDomains;
|
||||
validateServiceAccountAdminAccess();
|
||||
Filter filter = new Filter(StoragePoolJoinVO.class, "id", true, offset, limit);
|
||||
List<StoragePoolJoinVO> storagePoolVOS = storagePoolJoinDao.listByZoneAndProvider(dataCenterVO.getId(), filter);
|
||||
return StoreVOToStorageDomainConverter.toStorageDomainListFromPools(storagePoolVOS);
|
||||
}
|
||||
|
||||
public List<Network> listNetworksByDcId(final String uuid) {
|
||||
public List<Network> listNetworksByDcId(final String uuid, final Long offset, final Long limit) {
|
||||
final DataCenterJoinVO dataCenterVO = dataCenterJoinDao.findByUuid(uuid);
|
||||
if (dataCenterVO == null) {
|
||||
throw new InvalidParameterValueException("DataCenter with ID " + uuid + " not found");
|
||||
}
|
||||
List<NetworkVO> networks = networkDao.listByZoneAndTrafficType(dataCenterVO.getId(), Networks.TrafficType.Guest);
|
||||
validateServiceAccountAdminAccess();
|
||||
Filter filter = new Filter(NetworkVO.class, "id", true, offset, limit);
|
||||
List<NetworkVO> networks = networkDao.listByZoneAndTrafficType(dataCenterVO.getId(), Networks.TrafficType.Guest, filter);
|
||||
return NetworkVOToNetworkConverter.toNetworkList(networks, (dcId) -> dataCenterVO);
|
||||
}
|
||||
|
||||
public List<Cluster> listAllClusters() {
|
||||
final List<ClusterVO> clusters = clusterDao.listByHypervisorType(Hypervisor.HypervisorType.KVM);
|
||||
public List<Cluster> listAllClusters(Long offset, Long limit) {
|
||||
validateServiceAccountAdminAccess();
|
||||
Filter filter = new Filter(ClusterVO.class, "id", true, offset, limit);
|
||||
final List<ClusterVO> clusters = clusterDao.listByHypervisorType(Hypervisor.HypervisorType.KVM, filter);
|
||||
return ClusterVOToClusterConverter.toClusterList(clusters, this::getZoneById);
|
||||
}
|
||||
|
||||
public Cluster getCluster(String uuid) {
|
||||
validateServiceAccountAdminAccess();
|
||||
final ClusterVO vo = clusterDao.findByUuid(uuid);
|
||||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Cluster with ID " + uuid + " not found");
|
||||
}
|
||||
return ClusterVOToClusterConverter.toCluster(vo, this::getZoneById);
|
||||
return ClusterVOToClusterConverter.toCluster(vo, this::getZoneById);
|
||||
}
|
||||
|
||||
public List<Host> listAllHosts() {
|
||||
final List<HostJoinVO> hosts = hostJoinDao.listRoutingHostsByHypervisor(Hypervisor.HypervisorType.KVM);
|
||||
public List<Host> listAllHosts(Long offset, Long limit) {
|
||||
validateServiceAccountAdminAccess();
|
||||
Filter filter = new Filter(HostJoinVO.class, "id", true, offset, limit);
|
||||
final List<HostJoinVO> hosts = hostJoinDao.listRoutingHostsByHypervisor(Hypervisor.HypervisorType.KVM, filter);
|
||||
return HostJoinVOToHostConverter.toHostList(hosts);
|
||||
}
|
||||
|
||||
public Host getHost(String uuid) {
|
||||
validateServiceAccountAdminAccess();
|
||||
final HostJoinVO vo = hostJoinDao.findByUuid(uuid);
|
||||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Host with ID " + uuid + " not found");
|
||||
}
|
||||
return HostJoinVOToHostConverter.toHost(vo);
|
||||
return HostJoinVOToHostConverter.toHost(vo);
|
||||
}
|
||||
|
||||
public List<Network> listAllNetworks() {
|
||||
final List<NetworkVO> networks = networkDao.listAll();
|
||||
public List<Network> listAllNetworks(Long offset, Long limit) {
|
||||
Filter filter = new Filter(NetworkVO.class, "id", true, offset, limit);
|
||||
final List<NetworkVO> networks = networkDao.listByTrafficType(Networks.TrafficType.Guest, filter);
|
||||
return NetworkVOToNetworkConverter.toNetworkList(networks, this::getZoneById);
|
||||
}
|
||||
|
||||
public Network getNetwork(String uuid) {
|
||||
final NetworkVO vo = networkDao.findByUuid(uuid);
|
||||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Host with ID " + uuid + " not found");
|
||||
throw new InvalidParameterValueException("Network with ID " + uuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), null, false, vo);
|
||||
return NetworkVOToNetworkConverter.toNetwork(vo, this::getZoneById);
|
||||
}
|
||||
|
||||
public List<VnicProfile> listAllVnicProfiles() {
|
||||
final List<NetworkVO> networks = networkDao.listByTrafficType(Networks.TrafficType.Guest);
|
||||
public List<VnicProfile> listAllVnicProfiles(Long offset, Long limit) {
|
||||
Filter filter = new Filter(NetworkVO.class, "id", true, offset, limit);
|
||||
final List<NetworkVO> networks = networkDao.listByTrafficType(Networks.TrafficType.Guest, filter);
|
||||
return NetworkVOToVnicProfileConverter.toVnicProfileList(networks, this::getZoneById);
|
||||
}
|
||||
|
||||
public VnicProfile getVnicProfile(String uuid) {
|
||||
final NetworkVO vo = networkDao.findByUuid(uuid);
|
||||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Host with ID " + uuid + " not found");
|
||||
throw new InvalidParameterValueException("Nic profile with ID " + uuid + " not found");
|
||||
}
|
||||
return NetworkVOToVnicProfileConverter.toVnicProfile(vo, this::getZoneById);
|
||||
}
|
||||
|
||||
public List<Vm> listAllInstances() {
|
||||
List<UserVmJoinVO> vms = userVmJoinDao.listByHypervisorType(Hypervisor.HypervisorType.KVM);
|
||||
public List<Vm> listAllInstances(Long offset, Long limit) {
|
||||
Filter filter = new Filter(UserVmJoinVO.class, "id", true, offset, limit);
|
||||
List<UserVmJoinVO> vms = userVmJoinDao.listByHypervisorType(Hypervisor.HypervisorType.KVM, filter);
|
||||
return UserVmJoinVOToVmConverter.toVmList(vms, this::getHostById, this::getDetailsByInstanceId);
|
||||
}
|
||||
|
||||
|
|
@ -539,17 +565,24 @@ public class ServerAdapter extends ManagerBase {
|
|||
allContent);
|
||||
}
|
||||
|
||||
Ternary<Long, String, Long> getVmOwner(Vm request) {
|
||||
Account getOwnerForInstanceCreation(Vm request) {
|
||||
if (!VeeamControlService.InstanceRestoreAssignOwner.value()) {
|
||||
return new Ternary<>(null, null, null);
|
||||
return null;
|
||||
}
|
||||
String accountUuid = request.getAccountId();
|
||||
if (StringUtils.isBlank(accountUuid)) {
|
||||
return new Ternary<>(null, null, null);
|
||||
return null;
|
||||
}
|
||||
Account account = accountService.getActiveAccountByUuid(accountUuid);
|
||||
if (account == null) {
|
||||
logger.warn("Account with ID {} not found, unable to determine owner for VM creation request", accountUuid);
|
||||
return null;
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
Ternary<Long, String, Long> getOwnerDetailsForInstanceCreation(Account account) {
|
||||
if (account == null) {
|
||||
return new Ternary<>(null, null, null);
|
||||
}
|
||||
String accountName = account.getAccountName();
|
||||
|
|
@ -576,7 +609,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
throw new InvalidParameterValueException("Invalid name specified for the VM");
|
||||
}
|
||||
String displayName = name;
|
||||
name = name.replaceAll("_", "-");
|
||||
name = name.replace("_", "-");
|
||||
Long zoneId = null;
|
||||
Long clusterId = null;
|
||||
if (request.getCluster() != null && StringUtils.isNotEmpty(request.getCluster().getId())) {
|
||||
|
|
@ -589,6 +622,10 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (zoneId == null) {
|
||||
throw new InvalidParameterValueException("Failed to determine datacenter for VM creation request");
|
||||
}
|
||||
DataCenterVO zone = dataCenterDao.findById(zoneId);
|
||||
if (zone == null) {
|
||||
throw new InvalidParameterValueException("DataCenter could not be determined for the request");
|
||||
}
|
||||
Integer cpu = null;
|
||||
try {
|
||||
cpu = Integer.valueOf(request.getCpu().getTopology().getSockets());
|
||||
|
|
@ -605,12 +642,14 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (memory == null) {
|
||||
throw new InvalidParameterValueException("Memory must be specified");
|
||||
}
|
||||
int memoryMB = (int)(memory / (1024L * 1024L));
|
||||
String userdata = null;
|
||||
if (request.getInitialization() != null) {
|
||||
userdata = request.getInitialization().getCustomScript();
|
||||
}
|
||||
Pair<ApiConstants.BootType, ApiConstants.BootMode> bootOptions = Vm.Bios.retrieveBootOptions(request.getBios());
|
||||
Ternary<Long, String, Long> owner = getVmOwner(request);
|
||||
Account owner = getOwnerForInstanceCreation(request);
|
||||
Ternary<Long, String, Long> ownerDetails = getOwnerDetailsForInstanceCreation(owner);
|
||||
String serviceOfferingUuid = null;
|
||||
if (request.getCpuProfile() != null && StringUtils.isNotEmpty(request.getCpuProfile().getId())) {
|
||||
serviceOfferingUuid = request.getCpuProfile().getId();
|
||||
|
|
@ -620,29 +659,68 @@ public class ServerAdapter extends ManagerBase {
|
|||
templateUuid = request.getTemplate().getId();
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
return createInstance(zoneId, clusterId, owner.first(), owner.second(), owner.third(), name, displayName,
|
||||
serviceOfferingUuid, cpu, memory, templateUuid, userdata, bootOptions.first(), bootOptions.second());
|
||||
return createInstance(zone, clusterId, owner, ownerDetails.first(), ownerDetails.second(),
|
||||
ownerDetails.third(), name, displayName, serviceOfferingUuid, cpu, memoryMB, templateUuid,
|
||||
userdata, bootOptions.first(), bootOptions.second(), request.getAffinityGroupId(),
|
||||
request.getUserDataId(), request.getDetails());
|
||||
} finally {
|
||||
CallContext.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
protected ServiceOffering getServiceOfferingIdForVmCreation(String serviceOfferingUuid, long zoneId, int cpu, long memory) {
|
||||
if (StringUtils.isNotBlank(serviceOfferingUuid)) {
|
||||
ServiceOffering offering = serviceOfferingDao.findByUuid(serviceOfferingUuid);
|
||||
if (offering != null && !offering.isCustomized()) {
|
||||
// ToDo: check offering is available in the specified zone and matches the requested cpu/memory if it's not a custom offering
|
||||
return offering;
|
||||
protected ServiceOffering getServiceOfferingFromRequest(com.cloud.dc.DataCenter zone, Account account,
|
||||
String uuid, int cpu, int memory) {
|
||||
if (StringUtils.isBlank(uuid)) {
|
||||
return null;
|
||||
}
|
||||
ServiceOfferingVO offering = serviceOfferingDao.findByUuid(uuid);
|
||||
if (offering == null) {
|
||||
logger.warn("Service offering with ID {} linked with the VM request not found", uuid);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
accountService.checkAccess(account, offering, zone);
|
||||
} catch (PermissionDeniedException e) {
|
||||
logger.warn("Service offering with ID {} linked with the VM request is not accessible for the account {}. Offering: {}, zone: {}",
|
||||
uuid, account, offering, zone);
|
||||
return null;
|
||||
}
|
||||
if (!offering.isCustomized() && (offering.getCpu() != cpu || offering.getRamSize() != memory)) {
|
||||
logger.warn("Service offering with ID {} linked with the VM request has different CPU or memory than requested. Offering: {}, requested CPU: {}, requested memory: {}",
|
||||
uuid, offering, cpu, memory);
|
||||
return null;
|
||||
}
|
||||
if (offering.isCustomized()) {
|
||||
Map<String, String> params = Map.of(
|
||||
VmDetailConstants.CPU_NUMBER, String.valueOf(cpu),
|
||||
VmDetailConstants.MEMORY, String.valueOf(memory)
|
||||
);
|
||||
try {
|
||||
userVmManager.validateCustomParameters(offering, params);
|
||||
offering.setCpu(cpu);
|
||||
offering.setRamSize(memory);
|
||||
} catch (InvalidParameterValueException e) {
|
||||
logger.warn("Service offering with ID {} linked with the VM request is customized but does not support requested CPU or memory. Offering: {}, requested CPU: {}, requested memory: {}",
|
||||
uuid, offering, cpu, memory);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return offering;
|
||||
}
|
||||
|
||||
protected ServiceOffering getServiceOfferingIdForVmCreation(com.cloud.dc.DataCenter zone, Account account,
|
||||
String serviceOfferingUuid, int cpu, int memory) {
|
||||
ServiceOffering offering = getServiceOfferingFromRequest(zone, account, serviceOfferingUuid, cpu, memory);
|
||||
if (offering != null) {
|
||||
return offering;
|
||||
}
|
||||
ListServiceOfferingsCmd cmd = new ListServiceOfferingsCmd();
|
||||
ComponentContext.inject(cmd);
|
||||
cmd.setZoneId(zoneId);
|
||||
cmd.setZoneId(zone.getId());
|
||||
cmd.setCpuNumber(cpu);
|
||||
Integer memoryMB = (int)(memory / (1024L * 1024L));
|
||||
cmd.setMemory(memoryMB);
|
||||
cmd.setMemory(memory);
|
||||
ListResponse<ServiceOfferingResponse> offerings = queryService.searchForServiceOfferings(cmd);
|
||||
if (offerings.getResponses().isEmpty()) {
|
||||
return null;
|
||||
|
|
@ -651,7 +729,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
return serviceOfferingDao.findByUuid(uuid);
|
||||
}
|
||||
|
||||
protected VMTemplateVO getTemplateForVmCreation(String templateUuid) {
|
||||
protected VMTemplateVO getTemplateForInstanceCreation(String templateUuid) {
|
||||
if (StringUtils.isBlank(templateUuid)) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -663,17 +741,20 @@ public class ServerAdapter extends ManagerBase {
|
|||
return template;
|
||||
}
|
||||
|
||||
protected Vm createInstance(Long zoneId, Long clusterId, Long domainId, String accountName, Long projectId,
|
||||
String name, String displayName, String serviceOfferingUuid, int cpu, long memory, String templateUuid,
|
||||
String userdata, ApiConstants.BootType bootType, ApiConstants.BootMode bootMode) {
|
||||
ServiceOffering serviceOffering = getServiceOfferingIdForVmCreation(serviceOfferingUuid, zoneId, cpu, memory);
|
||||
protected Vm createInstance(com.cloud.dc.DataCenter zone, Long clusterId, Account owner, Long domainId,
|
||||
String accountName, Long projectId, String name, String displayName, String serviceOfferingUuid,
|
||||
int cpu, int memory, String templateUuid, String userdata, ApiConstants.BootType bootType,
|
||||
ApiConstants.BootMode bootMode, String affinityGroupId, String userDataId, Map<String, String> details) {
|
||||
Account account = owner != null ? owner : CallContext.current().getCallingAccount();
|
||||
ServiceOffering serviceOffering = getServiceOfferingIdForVmCreation(zone, account, serviceOfferingUuid, cpu,
|
||||
memory);
|
||||
if (serviceOffering == null) {
|
||||
throw new CloudRuntimeException("No service offering found for VM creation with specified CPU and memory");
|
||||
}
|
||||
DeployVMCmdByAdmin cmd = new DeployVMCmdByAdmin();
|
||||
cmd.setHttpMethod(BaseCmd.HTTPMethod.POST.name());
|
||||
ComponentContext.inject(cmd);
|
||||
cmd.setZoneId(zoneId);
|
||||
cmd.setZoneId(zone.getId());
|
||||
cmd.setClusterId(clusterId);
|
||||
if (domainId != null && StringUtils.isNotEmpty(accountName)) {
|
||||
cmd.setDomainId(domainId);
|
||||
|
|
@ -696,22 +777,39 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (bootMode != null) {
|
||||
cmd.setBootMode(bootMode.toString());
|
||||
}
|
||||
VMTemplateVO template = getTemplateForVmCreation(templateUuid);
|
||||
VMTemplateVO template = getTemplateForInstanceCreation(templateUuid);
|
||||
if (template != null) {
|
||||
cmd.setTemplateId(template.getId());
|
||||
}
|
||||
// ToDo: handle any other field?
|
||||
// Handle custom offerings
|
||||
if (StringUtils.isNotBlank(affinityGroupId)) {
|
||||
AffinityGroupVO group = affinityGroupDao.findByUuid(affinityGroupId);
|
||||
if (group == null) {
|
||||
logger.warn("Failed to find affinity group with ID {} specified in Instance creation request, " +
|
||||
"skipping affinity group assignment", affinityGroupId);
|
||||
} else {
|
||||
cmd.setAffinityGroupIds(List.of(group.getId()));
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(userDataId)) {
|
||||
UserDataVO userData = userDataDao.findByUuid(userDataId);
|
||||
if (userData == null) {
|
||||
logger.warn("Failed to find userdata with ID {} specified in Instance creation request, " +
|
||||
"skipping userdata assignment", userDataId);
|
||||
} else {
|
||||
cmd.setUserDataId(userData.getId());
|
||||
}
|
||||
}
|
||||
cmd.setHypervisor(Hypervisor.HypervisorType.KVM.name());
|
||||
Map<String, String> instanceDetails = getDetailsForInstanceCreation(userdata, serviceOffering, details);
|
||||
if (MapUtils.isNotEmpty(instanceDetails)) {
|
||||
Map<Integer, Map<String, String>> map = new HashMap<>();
|
||||
map.put(0, details);
|
||||
cmd.setDetails(map);
|
||||
}
|
||||
cmd.setBlankInstance(true);
|
||||
Map<String, String> details = new HashMap<>();
|
||||
details.put(VmDetailConstants.GUEST_CPU_MODE, GUEST_CPU_MODE);
|
||||
Map<Integer, Map<String, String>> map = new HashMap<>();
|
||||
map.put(0, details);
|
||||
cmd.setDetails(map);
|
||||
try {
|
||||
UserVm vm = userVmService.createVirtualMachine(cmd);
|
||||
vm = userVmService.finalizeCreateVirtualMachine(vm.getId());
|
||||
UserVm vm = userVmManager.createVirtualMachine(cmd);
|
||||
vm = userVmManager.finalizeCreateVirtualMachine(vm.getId());
|
||||
UserVmJoinVO vo = userVmJoinDao.findById(vm.getId());
|
||||
return UserVmJoinVOToVmConverter.toVm(vo, this::getHostById, this::getDetailsByInstanceId,
|
||||
this::listDiskAttachmentsByInstanceId, this::listNicsByInstance, false);
|
||||
|
|
@ -720,6 +818,35 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<String, String> getDetailsForInstanceCreation(String userdata, ServiceOffering serviceOffering,
|
||||
Map<String, String> existingDetails) {
|
||||
Map<String, String> details = new HashMap<>();
|
||||
List<String> detailsTobeSkipped = List.of(
|
||||
ApiConstants.BootType.BIOS.toString(),
|
||||
ApiConstants.BootType.UEFI.toString());
|
||||
if (MapUtils.isNotEmpty(existingDetails)) {
|
||||
for (Map.Entry<String, String> entry : existingDetails.entrySet()) {
|
||||
if (detailsTobeSkipped.contains(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
details.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotEmpty(userdata)) {
|
||||
// Assumption: Only worker VM will have userdata and it needs CPU mode
|
||||
details.put(VmDetailConstants.GUEST_CPU_MODE, WORKER_VM_GUEST_CPU_MODE);
|
||||
}
|
||||
if (serviceOffering.isCustomized()) {
|
||||
details.put(VmDetailConstants.CPU_NUMBER, String.valueOf(serviceOffering.getCpu()));
|
||||
details.put(VmDetailConstants.MEMORY, String.valueOf(serviceOffering.getRamSize()));
|
||||
if (serviceOffering.getSpeed() == null && !details.containsKey(VmDetailConstants.CPU_SPEED)) {
|
||||
details.put(VmDetailConstants.CPU_SPEED, String.valueOf(1000));
|
||||
}
|
||||
}
|
||||
return details;
|
||||
}
|
||||
|
||||
public Vm updateInstance(String uuid, Vm request) {
|
||||
logger.warn("Received request to update VM with ID {}. No action, returning existing VM data.", uuid);
|
||||
return getInstance(uuid, false, false, false);
|
||||
|
|
@ -856,51 +983,27 @@ public class ServerAdapter extends ManagerBase {
|
|||
return volumeApiService.getVolumePhysicalSize(vo.getFormat(), vo.getPath(), vo.getChainInfo());
|
||||
}
|
||||
|
||||
public List<Disk> listAllDisks() {
|
||||
List<VolumeJoinVO> kvmVolumes = volumeJoinDao.listByHypervisor(Hypervisor.HypervisorType.KVM);
|
||||
public List<Disk> listAllDisks(Long offset, Long limit) {
|
||||
Filter filter = new Filter(VolumeJoinVO.class, "id", true, offset, limit);
|
||||
List<VolumeJoinVO> kvmVolumes = volumeJoinDao.listByHypervisor(Hypervisor.HypervisorType.KVM, filter);
|
||||
return VolumeJoinVOToDiskConverter.toDiskList(kvmVolumes, this::getVolumePhysicalSize);
|
||||
}
|
||||
|
||||
public Disk getDisk(String uuid) {
|
||||
VolumeJoinVO vo = volumeJoinDao.findByUuid(uuid);
|
||||
VolumeVO vo = volumeDao.findByUuid(uuid);
|
||||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Disk with ID " + uuid + " not found");
|
||||
}
|
||||
return VolumeJoinVOToDiskConverter.toDisk(vo, this::getVolumePhysicalSize);
|
||||
accountService.checkAccess(getServiceAccount().second(), null, false, vo);
|
||||
return VolumeJoinVOToDiskConverter.toDisk(volumeJoinDao.findByUuid(uuid), this::getVolumePhysicalSize);
|
||||
}
|
||||
|
||||
public Disk copyDisk(String uuid) {
|
||||
throw new InvalidParameterValueException("Copy Disk with ID " + uuid + " not implemented");
|
||||
// VolumeVO vo = volumeDao.findByUuid(uuid);
|
||||
// if (vo == null) {
|
||||
// throw new InvalidParameterValueException("Disk with ID " + uuid + " not found");
|
||||
// }
|
||||
// Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
// CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
// try {
|
||||
// Volume volume = volumeApiService.copyVolume(vo.getId(), vo.getName() + "_copy", null, null);
|
||||
// VolumeJoinVO copiedVolumeVO = volumeJoinDao.findById(volume.getId());
|
||||
// return VolumeJoinVOToDiskConverter.toDisk(copiedVolumeVO);
|
||||
// } finally {
|
||||
// CallContext.unregister();
|
||||
// }
|
||||
}
|
||||
|
||||
public Disk reduceDisk(String uuid) {
|
||||
throw new InvalidParameterValueException("Reduce Disk with ID " + uuid + " not implemented");
|
||||
// VolumeVO vo = volumeDao.findByUuid(uuid);
|
||||
// if (vo == null) {
|
||||
// throw new InvalidParameterValueException("Disk with ID " + uuid + " not found");
|
||||
// }
|
||||
// Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
// CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
// try {
|
||||
// Volume volume = volumeApiService.reduceDisk(vo.getId(), vo.getName() + "_copy", null, null);
|
||||
// VolumeJoinVO copiedVolumeVO = volumeJoinDao.findById(volume.getId());
|
||||
// return VolumeJoinVOToDiskConverter.toDisk(copiedVolumeVO);
|
||||
// } finally {
|
||||
// CallContext.unregister();
|
||||
// }
|
||||
}
|
||||
|
||||
protected List<DiskAttachment> listDiskAttachmentsByInstanceId(final long instanceId) {
|
||||
|
|
@ -913,6 +1016,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + uuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), null, false, vo);
|
||||
return listDiskAttachmentsByInstanceId(vo.getId());
|
||||
}
|
||||
|
||||
|
|
@ -953,6 +1057,8 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vmVo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + vmUuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
accountService.checkAccess(serviceUserAccount.second(), SecurityChecker.AccessType.OperateEntry, false, vmVo);
|
||||
if (request == null || request.getDisk() == null || StringUtils.isEmpty(request.getDisk().getId())) {
|
||||
throw new InvalidParameterValueException("Request disk data is empty");
|
||||
}
|
||||
|
|
@ -960,7 +1066,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (volumeVO == null) {
|
||||
throw new InvalidParameterValueException("Disk with ID " + request.getDisk().getId() + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
accountService.checkAccess(serviceUserAccount.second(), SecurityChecker.AccessType.OperateEntry, false, vmVo);
|
||||
if (vmVo.getAccountId() != volumeVO.getAccountId()) {
|
||||
if (VeeamControlService.InstanceRestoreAssignOwner.value()) {
|
||||
assignVolumeToAccount(volumeVO, vmVo.getAccountId(), serviceUserAccount);
|
||||
|
|
@ -1013,18 +1119,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (StringUtils.isBlank(sizeStr)) {
|
||||
throw new InvalidParameterValueException("Provisioned size must be specified");
|
||||
}
|
||||
long provisionedSizeInGb;
|
||||
try {
|
||||
provisionedSizeInGb = Long.parseLong(sizeStr);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new InvalidParameterValueException("Invalid provisioned size: " + sizeStr);
|
||||
}
|
||||
if (provisionedSizeInGb <= 0) {
|
||||
throw new InvalidParameterValueException("Provisioned size must be greater than zero");
|
||||
}
|
||||
// round-up provisionedSizeInGb to the next whole GB
|
||||
long GB = 1024L * 1024L * 1024L;
|
||||
provisionedSizeInGb = Math.max(1L, (provisionedSizeInGb + GB - 1) / GB);
|
||||
long provisionedSizeInGb = getProvisionedSizeInGb(sizeStr);
|
||||
Long initialSize = null;
|
||||
if (StringUtils.isNotBlank(request.getInitialSize())) {
|
||||
try {
|
||||
|
|
@ -1049,6 +1144,22 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
}
|
||||
|
||||
private static long getProvisionedSizeInGb(String sizeStr) {
|
||||
long provisionedSizeInGb;
|
||||
try {
|
||||
provisionedSizeInGb = Long.parseLong(sizeStr);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new InvalidParameterValueException("Invalid provisioned size: " + sizeStr);
|
||||
}
|
||||
if (provisionedSizeInGb <= 0) {
|
||||
throw new InvalidParameterValueException("Provisioned size must be greater than zero");
|
||||
}
|
||||
// round-up provisionedSizeInGb to the next whole GB
|
||||
long GB = 1024L * 1024L * 1024L;
|
||||
provisionedSizeInGb = Math.max(1L, (provisionedSizeInGb + GB - 1) / GB);
|
||||
return provisionedSizeInGb;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Disk createDisk(Account serviceAccount, StoragePoolVO pool, String name, Long diskOfferingId, long sizeInGb, Long initialSize) {
|
||||
Volume volume;
|
||||
|
|
@ -1084,6 +1195,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + uuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), null, false, vo);
|
||||
return listNicsByInstance(vo.getId(), vo.getUuid());
|
||||
}
|
||||
|
||||
|
|
@ -1119,7 +1231,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
cmd.setAccountName(account.getAccountName());
|
||||
}
|
||||
cmd.setSkipNetwork(true);
|
||||
userVmService.moveVmToUser(cmd);
|
||||
userVmManager.moveVmToUser(cmd);
|
||||
} catch (ResourceAllocationException | CloudRuntimeException | ResourceUnavailableException |
|
||||
InsufficientCapacityException e) {
|
||||
logger.error("Failed to assign {} to {}: {}", vmVO, account, e.getMessage(), e);
|
||||
|
|
@ -1133,6 +1245,8 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vmVo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + vmUuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
accountService.checkAccess(serviceUserAccount.second(), SecurityChecker.AccessType.OperateEntry, false, vmVo);
|
||||
if (request == null || request.getVnicProfile() == null || StringUtils.isEmpty(request.getVnicProfile().getId())) {
|
||||
throw new InvalidParameterValueException("Request nic data is empty");
|
||||
}
|
||||
|
|
@ -1140,7 +1254,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (networkVO == null) {
|
||||
throw new InvalidParameterValueException("VNic profile " + request.getVnicProfile().getId() + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
accountService.checkAccess(serviceUserAccount.second(), SecurityChecker.AccessType.OperateEntry, false, networkVO);
|
||||
if (vmVo.getAccountId() != networkVO.getAccountId() &&
|
||||
networkVO.getAccountId() != Account.ACCOUNT_ID_SYSTEM &&
|
||||
VeeamControlService.InstanceRestoreAssignOwner.value() &&
|
||||
|
|
@ -1156,7 +1270,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (request.getMac() != null && StringUtils.isNotBlank(request.getMac().getAddress())) {
|
||||
cmd.setMacAddress(request.getMac().getAddress());
|
||||
}
|
||||
userVmService.addNicToVirtualMachine(cmd);
|
||||
userVmManager.addNicToVirtualMachine(cmd);
|
||||
NicVO nic = nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(networkVO.getId(), vmVo.getId());
|
||||
if (nic == null) {
|
||||
throw new CloudRuntimeException("Failed to attach NIC to VM");
|
||||
|
|
@ -1167,8 +1281,9 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
}
|
||||
|
||||
public List<ImageTransfer> listAllImageTransfers() {
|
||||
List<ImageTransferVO> imageTransfers = imageTransferDao.listAll();
|
||||
public List<ImageTransfer> listAllImageTransfers(Long offset, Long limit) {
|
||||
Filter filter = new Filter(ImageTransferVO.class, "id", true, offset, limit);
|
||||
List<ImageTransferVO> imageTransfers = imageTransferDao.listAll(filter);
|
||||
return ImageTransferVOToImageTransferConverter.toImageTransferList(imageTransfers, this::getHostById, this::getVolumeById);
|
||||
}
|
||||
|
||||
|
|
@ -1177,6 +1292,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Image transfer with ID " + uuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), null, false, vo);
|
||||
return ImageTransferVOToImageTransferConverter.toImageTransfer(vo, this::getHostById, this::getVolumeById);
|
||||
}
|
||||
|
||||
|
|
@ -1191,6 +1307,8 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (volumeVO == null) {
|
||||
throw new InvalidParameterValueException("Disk with ID " + request.getDisk().getId() + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
accountService.checkAccess(serviceUserAccount.second(), null, false, volumeVO);
|
||||
Direction direction = EnumUtils.fromString(Direction.class, request.getDirection());
|
||||
if (direction == null) {
|
||||
throw new InvalidParameterValueException("Invalid or missing direction");
|
||||
|
|
@ -1204,7 +1322,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
backupId = backupVO.getId();
|
||||
}
|
||||
return createImageTransfer(backupId, volumeVO.getId(), direction, format);
|
||||
return createImageTransfer(backupId, volumeVO.getId(), direction, format, serviceUserAccount);
|
||||
}
|
||||
|
||||
public boolean cancelImageTransfer(String uuid) {
|
||||
|
|
@ -1212,6 +1330,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Image transfer with ID " + uuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), SecurityChecker.AccessType.OperateEntry, false, vo);
|
||||
return kvmBackupExportService.cancelImageTransfer(vo.getId());
|
||||
}
|
||||
|
||||
|
|
@ -1220,11 +1339,12 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Image transfer with ID " + uuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), SecurityChecker.AccessType.OperateEntry, false, vo);
|
||||
return kvmBackupExportService.finalizeImageTransfer(vo.getId());
|
||||
}
|
||||
|
||||
private ImageTransfer createImageTransfer(Long backupId, Long volumeId, Direction direction, Format format) {
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
private ImageTransfer createImageTransfer(Long backupId, Long volumeId, Direction direction, Format format,
|
||||
Pair<User, Account> serviceUserAccount) {
|
||||
CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
org.apache.cloudstack.backup.ImageTransfer imageTransfer =
|
||||
|
|
@ -1268,7 +1388,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
return vmInstanceDetailsDao.listDetailsKeyPairs(instanceId, true);
|
||||
}
|
||||
|
||||
public List<Job> listAllJobs() {
|
||||
public List<Job> listPendingJobs() {
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
List<Long> jobIds = asyncJobDao.listPendingJobIdsForAccount(serviceUserAccount.second().getId());
|
||||
List<AsyncJobJoinVO> jobJoinVOs = asyncJobJoinDao.listByIds(jobIds);
|
||||
|
|
@ -1280,6 +1400,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Job with ID " + uuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), null, false, vo);
|
||||
return AsyncJobJoinVOToJobConverter.toJob(vo);
|
||||
}
|
||||
|
||||
|
|
@ -1298,6 +1419,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
throw new InvalidParameterValueException("VM with ID " + vmUuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
accountService.checkAccess(serviceUserAccount.second(), SecurityChecker.AccessType.OperateEntry, false, vmVo);
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
CreateVMSnapshotCmd cmd = new CreateVMSnapshotCmd();
|
||||
|
|
@ -1329,6 +1451,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Snapshot with ID " + uuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), null, false, vo);
|
||||
UserVmVO vm = userVmDao.findById(vo.getVmId());
|
||||
return VmSnapshotVOToSnapshotConverter.toSnapshot(vo, vm.getUuid());
|
||||
}
|
||||
|
|
@ -1340,6 +1463,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
throw new InvalidParameterValueException("Snapshot with ID " + uuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
accountService.checkAccess(serviceUserAccount.second(), SecurityChecker.AccessType.OperateEntry, false, vo);
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
DeleteVMSnapshotCmd cmd = new DeleteVMSnapshotCmd();
|
||||
|
|
@ -1372,6 +1496,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
throw new InvalidParameterValueException("Snapshot with ID " + uuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
accountService.checkAccess(serviceUserAccount.second(), SecurityChecker.AccessType.OperateEntry, false, vo);
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
RevertToVMSnapshotCmd cmd = new RevertToVMSnapshotCmd();
|
||||
|
|
@ -1412,6 +1537,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
throw new InvalidParameterValueException("VM with ID " + vmUuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
accountService.checkAccess(serviceUserAccount.second(), SecurityChecker.AccessType.OperateEntry, false, vmVo);
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
StartBackupCmd cmd = new StartBackupCmd();
|
||||
|
|
@ -1442,6 +1568,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Backup with ID " + uuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), null, false, vo);
|
||||
return BackupVOToBackupConverter.toBackup(vo, id -> userVmDao.findById(id), this::getHostById,
|
||||
this::getBackupDisks);
|
||||
}
|
||||
|
|
@ -1461,6 +1588,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
throw new InvalidParameterValueException("Backup with ID " + backupUuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
accountService.checkAccess(serviceUserAccount.second(), SecurityChecker.AccessType.OperateEntry, false, backup);
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
FinalizeBackupCmd cmd = new FinalizeBackupCmd();
|
||||
|
|
@ -1495,6 +1623,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + uuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), null, false, vo);
|
||||
Checkpoint checkpoint = UserVmVOToCheckpointConverter.toCheckpoint(vo);
|
||||
if (checkpoint == null) {
|
||||
return Collections.emptyList();
|
||||
|
|
@ -1507,6 +1636,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + vmUuid + " not found");
|
||||
}
|
||||
accountService.checkAccess(getServiceAccount().second(), SecurityChecker.AccessType.OperateEntry, false, vo);
|
||||
if (!Objects.equals(vo.getActiveCheckpointId(), checkpointId)) {
|
||||
logger.warn("Checkpoint ID {} does not match active checkpoint for VM {}", checkpointId, vmUuid);
|
||||
return;
|
||||
|
|
@ -1525,9 +1655,11 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
}
|
||||
|
||||
public List<Tag> listAllTags() {
|
||||
public List<Tag> listAllTags(final Long offset, final Long limit) {
|
||||
List<Tag> tags = new ArrayList<>(getDummyTags().values());
|
||||
List<ResourceTagVO> vmResourceTags = resourceTagDao.listByResourceType(ResourceTag.ResourceObjectType.UserVm);
|
||||
Filter filter = new Filter(ResourceTagVO.class, "id", true, offset, limit);
|
||||
List<ResourceTagVO> vmResourceTags = resourceTagDao.listByResourceType(ResourceTag.ResourceObjectType.UserVm,
|
||||
filter);
|
||||
if (CollectionUtils.isNotEmpty(vmResourceTags)) {
|
||||
tags.addAll(ResourceTagVOToTagConverter.toTags(vmResourceTags));
|
||||
}
|
||||
|
|
@ -1541,6 +1673,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
Tag tag = getDummyTags().get(uuid);
|
||||
if (tag == null) {
|
||||
ResourceTagVO resourceTagVO = resourceTagDao.findByUuid(uuid);
|
||||
accountService.checkAccess(getServiceAccount().second(), null, false, resourceTagVO);
|
||||
if (resourceTagVO != null) {
|
||||
tag = ResourceTagVOToTagConverter.toTag(resourceTagVO);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,16 +76,12 @@ public class ApiService extends ManagerBase implements RouteHandler {
|
|||
add(links, basePath + "/clusters?search={query}", "clusters/search");
|
||||
add(links, basePath + "/datacenters", "datacenters");
|
||||
add(links, basePath + "/datacenters?search={query}", "datacenters/search");
|
||||
add(links, basePath + "/events", "events");
|
||||
add(links, basePath + "/events;from={event_id}?search={query}", "events/search");
|
||||
add(links, basePath + "/hosts", "hosts");
|
||||
add(links, basePath + "/hosts?search={query}", "hosts/search");
|
||||
add(links, basePath + "/networks", "networks");
|
||||
add(links, basePath + "/networks?search={query}", "networks/search");
|
||||
add(links, basePath + "/storagedomains", "storagedomains");
|
||||
add(links, basePath + "/storagedomains?search={query}", "storagedomains/search");
|
||||
add(links, basePath + "/templates", "templates");
|
||||
add(links, basePath + "/templates?search={query}", "templates/search");
|
||||
add(links, basePath + "/vms", "vms");
|
||||
add(links, basePath + "/vms?search={query}", "vms/search");
|
||||
add(links, basePath + "/disks", "disks");
|
||||
|
|
|
|||
|
|
@ -29,11 +29,13 @@ import org.apache.cloudstack.veeam.VeeamControlServlet;
|
|||
import org.apache.cloudstack.veeam.adapter.ServerAdapter;
|
||||
import org.apache.cloudstack.veeam.api.dto.Cluster;
|
||||
import org.apache.cloudstack.veeam.api.dto.NamedList;
|
||||
import org.apache.cloudstack.veeam.api.request.ListQuery;
|
||||
import org.apache.cloudstack.veeam.utils.Negotiation;
|
||||
import org.apache.cloudstack.veeam.utils.PathUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
|
||||
public class ClustersRouteHandler extends ManagerBase implements RouteHandler {
|
||||
|
|
@ -84,9 +86,14 @@ public class ClustersRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
final List<Cluster> result = serverAdapter.listAllClusters();
|
||||
NamedList<Cluster> response = NamedList.of("cluster", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
try {
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
final List<Cluster> result = serverAdapter.listAllClusters(query.getOffset(), query.getLimit());
|
||||
NamedList<Cluster> response = NamedList.of("cluster", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
} catch (PermissionDeniedException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleGetById(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
|
|
@ -96,6 +103,8 @@ public class ClustersRouteHandler extends ManagerBase implements RouteHandler {
|
|||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
} catch (InvalidParameterValueException e) {
|
||||
io.notFound(resp, e.getMessage(), outFormat);
|
||||
} catch (PermissionDeniedException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,11 +31,13 @@ import org.apache.cloudstack.veeam.api.dto.DataCenter;
|
|||
import org.apache.cloudstack.veeam.api.dto.NamedList;
|
||||
import org.apache.cloudstack.veeam.api.dto.Network;
|
||||
import org.apache.cloudstack.veeam.api.dto.StorageDomain;
|
||||
import org.apache.cloudstack.veeam.api.request.ListQuery;
|
||||
import org.apache.cloudstack.veeam.utils.Negotiation;
|
||||
import org.apache.cloudstack.veeam.utils.PathUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
|
||||
public class DataCentersRouteHandler extends ManagerBase implements RouteHandler {
|
||||
|
|
@ -81,11 +83,11 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
|
|||
} else if (idAndSubPath.size() == 2) {
|
||||
String subPath = idAndSubPath.get(1);
|
||||
if ("storagedomains".equals(subPath)) {
|
||||
handleGetStorageDomainsByDcId(id, resp, outFormat, io);
|
||||
handleGetStorageDomainsByDcId(id, req, resp, outFormat, io);
|
||||
return;
|
||||
}
|
||||
if ("networks".equals(subPath)) {
|
||||
handleGetNetworksByDcId(id, resp, outFormat, io);
|
||||
handleGetNetworksByDcId(id, req, resp, outFormat, io);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +98,8 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
|
|||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
final List<DataCenter> result = serverAdapter.listAllDataCenters();
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
final List<DataCenter> result = serverAdapter.listAllDataCenters(query.getOffset(), query.getLimit());
|
||||
NamedList<DataCenter> response = NamedList.of("data_center", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
}
|
||||
|
|
@ -111,25 +114,35 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
|
|||
}
|
||||
}
|
||||
|
||||
protected void handleGetStorageDomainsByDcId(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
final VeeamControlServlet io) throws IOException {
|
||||
protected void handleGetStorageDomainsByDcId(final String id, final HttpServletRequest req,
|
||||
final HttpServletResponse resp, final Negotiation.OutFormat outFormat, final VeeamControlServlet io)
|
||||
throws IOException {
|
||||
try {
|
||||
List<StorageDomain> storageDomains = serverAdapter.listStorageDomainsByDcId(id);
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
List<StorageDomain> storageDomains = serverAdapter.listStorageDomainsByDcId(id, query.getPage(),
|
||||
query.getMax());
|
||||
NamedList<StorageDomain> response = NamedList.of("storage_domain", storageDomains);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
} catch (InvalidParameterValueException e) {
|
||||
io.notFound(resp, e.getMessage(), outFormat);
|
||||
} catch (PermissionDeniedException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleGetNetworksByDcId(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
final VeeamControlServlet io) throws IOException {
|
||||
protected void handleGetNetworksByDcId(final String id, final HttpServletRequest req,
|
||||
final HttpServletResponse resp, final Negotiation.OutFormat outFormat, final VeeamControlServlet io)
|
||||
throws IOException {
|
||||
try {
|
||||
List<Network> networks = serverAdapter.listNetworksByDcId(id);
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
List<Network> networks = serverAdapter.listNetworksByDcId(id, query.getPage(),
|
||||
query.getMax());
|
||||
NamedList<Network> response = NamedList.of("network", networks);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
} catch (InvalidParameterValueException e) {
|
||||
io.notFound(resp, e.getMessage(), outFormat);
|
||||
} catch (PermissionDeniedException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.cloudstack.veeam.VeeamControlServlet;
|
|||
import org.apache.cloudstack.veeam.adapter.ServerAdapter;
|
||||
import org.apache.cloudstack.veeam.api.dto.Disk;
|
||||
import org.apache.cloudstack.veeam.api.dto.NamedList;
|
||||
import org.apache.cloudstack.veeam.api.request.ListQuery;
|
||||
import org.apache.cloudstack.veeam.utils.Negotiation;
|
||||
import org.apache.cloudstack.veeam.utils.PathUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
|
@ -120,7 +121,8 @@ public class DisksRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
final List<Disk> result = serverAdapter.listAllDisks();
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
final List<Disk> result = serverAdapter.listAllDisks(query.getOffset(), query.getLimit());
|
||||
NamedList<Disk> response = NamedList.of("disk", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,11 +29,13 @@ import org.apache.cloudstack.veeam.VeeamControlServlet;
|
|||
import org.apache.cloudstack.veeam.adapter.ServerAdapter;
|
||||
import org.apache.cloudstack.veeam.api.dto.Host;
|
||||
import org.apache.cloudstack.veeam.api.dto.NamedList;
|
||||
import org.apache.cloudstack.veeam.api.request.ListQuery;
|
||||
import org.apache.cloudstack.veeam.utils.Negotiation;
|
||||
import org.apache.cloudstack.veeam.utils.PathUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
|
||||
public class HostsRouteHandler extends ManagerBase implements RouteHandler {
|
||||
|
|
@ -84,9 +86,14 @@ public class HostsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
final List<Host> result = serverAdapter.listAllHosts();
|
||||
NamedList<Host> response = NamedList.of("host", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
try {
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
final List<Host> result = serverAdapter.listAllHosts(query.getOffset(), query.getLimit());
|
||||
NamedList<Host> response = NamedList.of("host", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
} catch (PermissionDeniedException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleGetById(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
|
|
@ -96,6 +103,8 @@ public class HostsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
} catch (InvalidParameterValueException e) {
|
||||
io.notFound(resp, e.getMessage(), outFormat);
|
||||
} catch (PermissionDeniedException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.cloudstack.veeam.VeeamControlServlet;
|
|||
import org.apache.cloudstack.veeam.adapter.ServerAdapter;
|
||||
import org.apache.cloudstack.veeam.api.dto.ImageTransfer;
|
||||
import org.apache.cloudstack.veeam.api.dto.NamedList;
|
||||
import org.apache.cloudstack.veeam.api.request.ListQuery;
|
||||
import org.apache.cloudstack.veeam.utils.Negotiation;
|
||||
import org.apache.cloudstack.veeam.utils.PathUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
|
@ -105,7 +106,8 @@ public class ImageTransfersRouteHandler extends ManagerBase implements RouteHand
|
|||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
final List<ImageTransfer> result = serverAdapter.listAllImageTransfers();
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
final List<ImageTransfer> result = serverAdapter.listAllImageTransfers(query.getOffset(), query.getLimit());
|
||||
NamedList<ImageTransfer> response = NamedList.of("image_transfer", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public class JobsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
final List<Job> result = serverAdapter.listAllJobs();
|
||||
final List<Job> result = serverAdapter.listPendingJobs();
|
||||
NamedList<Job> response = NamedList.of("job", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.cloudstack.veeam.VeeamControlServlet;
|
|||
import org.apache.cloudstack.veeam.adapter.ServerAdapter;
|
||||
import org.apache.cloudstack.veeam.api.dto.NamedList;
|
||||
import org.apache.cloudstack.veeam.api.dto.Network;
|
||||
import org.apache.cloudstack.veeam.api.request.ListQuery;
|
||||
import org.apache.cloudstack.veeam.utils.Negotiation;
|
||||
import org.apache.cloudstack.veeam.utils.PathUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
|
@ -84,7 +85,8 @@ public class NetworksRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
final List<Network> result = serverAdapter.listAllNetworks();
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
final List<Network> result = serverAdapter.listAllNetworks(query.getOffset(), query.getLimit());
|
||||
NamedList<Network> response = NamedList.of("network", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.cloudstack.veeam.VeeamControlServlet;
|
|||
import org.apache.cloudstack.veeam.adapter.ServerAdapter;
|
||||
import org.apache.cloudstack.veeam.api.dto.NamedList;
|
||||
import org.apache.cloudstack.veeam.api.dto.Tag;
|
||||
import org.apache.cloudstack.veeam.api.request.ListQuery;
|
||||
import org.apache.cloudstack.veeam.utils.Negotiation;
|
||||
import org.apache.cloudstack.veeam.utils.PathUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
|
@ -85,7 +86,8 @@ public class TagsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
final List<Tag> result = serverAdapter.listAllTags();
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
final List<Tag> result = serverAdapter.listAllTags(query.getOffset(), query.getLimit());
|
||||
NamedList<Tag> response = NamedList.of("tag", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,10 +38,7 @@ import org.apache.cloudstack.veeam.api.dto.ResourceAction;
|
|||
import org.apache.cloudstack.veeam.api.dto.Snapshot;
|
||||
import org.apache.cloudstack.veeam.api.dto.Vm;
|
||||
import org.apache.cloudstack.veeam.api.dto.VmAction;
|
||||
import org.apache.cloudstack.veeam.api.request.VmListQuery;
|
||||
import org.apache.cloudstack.veeam.api.request.VmSearchExpr;
|
||||
import org.apache.cloudstack.veeam.api.request.VmSearchFilters;
|
||||
import org.apache.cloudstack.veeam.api.request.VmSearchParser;
|
||||
import org.apache.cloudstack.veeam.api.request.ListQuery;
|
||||
import org.apache.cloudstack.veeam.utils.Negotiation;
|
||||
import org.apache.cloudstack.veeam.utils.PathUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
|
@ -54,24 +51,10 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|||
|
||||
public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
||||
public static final String BASE_ROUTE = "/api/vms";
|
||||
private static final int DEFAULT_MAX = 50;
|
||||
private static final int HARD_CAP_MAX = 1000;
|
||||
private static final int DEFAULT_PAGE = 1;
|
||||
|
||||
@Inject
|
||||
ServerAdapter serverAdapter;
|
||||
|
||||
private VmSearchParser searchParser;
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
|
||||
this.searchParser = new VmSearchParser(Set.of(
|
||||
"id", "name", "status", "cluster", "host", "template"
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 5;
|
||||
|
|
@ -248,59 +231,12 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
final VmListQuery q = fromRequest(req);
|
||||
|
||||
// Validate max/page early (optional strictness)
|
||||
if (q.getMax() != null && q.getMax() <= 0) {
|
||||
io.notFound(resp, "Invalid 'max' (must be > 0)", outFormat);
|
||||
return;
|
||||
}
|
||||
if (q.getPage() != null && q.getPage() <= 0) {
|
||||
io.notFound(resp, "Invalid 'page' (must be > 0)", outFormat);
|
||||
return;
|
||||
}
|
||||
|
||||
final int limit = q.resolvedMax(DEFAULT_MAX, HARD_CAP_MAX);
|
||||
final int offset = q.offset(DEFAULT_MAX, HARD_CAP_MAX, DEFAULT_PAGE);
|
||||
|
||||
final VmSearchExpr expr;
|
||||
try {
|
||||
expr = searchParser.parse(q.getSearch());
|
||||
} catch (VmSearchParser.VmSearchParseException e) {
|
||||
io.notFound(resp, "Invalid search: " + e.getMessage(), outFormat);
|
||||
return;
|
||||
}
|
||||
|
||||
final VmSearchFilters filters;
|
||||
try {
|
||||
filters = VmSearchFilters.fromAndOnly(expr); // AND-only v1
|
||||
} catch (VmSearchParser.VmSearchParseException e) {
|
||||
io.notFound(resp, "Unsupported search: " + e.getMessage(), outFormat);
|
||||
return;
|
||||
}
|
||||
|
||||
final List<Vm> result = serverAdapter.listAllInstances();
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
final List<Vm> result = serverAdapter.listAllInstances(query.getOffset(), query.getLimit());
|
||||
NamedList<Vm> response = NamedList.of("vm", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
}
|
||||
|
||||
protected static VmListQuery fromRequest(final HttpServletRequest req) {
|
||||
final VmListQuery q = new VmListQuery();
|
||||
q.setSearch(req.getParameter("search"));
|
||||
q.setMax(parseIntOrNull(req.getParameter("max")));
|
||||
q.setPage(parseIntOrNull(req.getParameter("page")));
|
||||
return q;
|
||||
}
|
||||
|
||||
protected static Integer parseIntOrNull(final String s) {
|
||||
if (s == null || s.trim().isEmpty()) return null;
|
||||
try {
|
||||
return Integer.parseInt(s.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return Integer.valueOf(-1); // will be rejected by validation above
|
||||
}
|
||||
}
|
||||
|
||||
protected void handlePost(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
String data = RouteHandler.getRequestData(req, logger);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.cloudstack.veeam.VeeamControlServlet;
|
|||
import org.apache.cloudstack.veeam.adapter.ServerAdapter;
|
||||
import org.apache.cloudstack.veeam.api.dto.NamedList;
|
||||
import org.apache.cloudstack.veeam.api.dto.VnicProfile;
|
||||
import org.apache.cloudstack.veeam.api.request.ListQuery;
|
||||
import org.apache.cloudstack.veeam.utils.Negotiation;
|
||||
import org.apache.cloudstack.veeam.utils.PathUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
|
@ -84,7 +85,8 @@ public class VnicProfilesRouteHandler extends ManagerBase implements RouteHandle
|
|||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
final List<VnicProfile> result = serverAdapter.listAllVnicProfiles();
|
||||
ListQuery query = ListQuery.fromRequest(req);
|
||||
final List<VnicProfile> result = serverAdapter.listAllVnicProfiles(query.getOffset(), query.getLimit());
|
||||
NamedList<VnicProfile> response = NamedList.of("vnic_profile", result);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ public class HostJoinVOToHostConverter {
|
|||
|
||||
// --- Memory ---
|
||||
h.setMemory(String.valueOf(vo.getTotalMemory()));
|
||||
h.setMaxSchedulingMemory(String.valueOf(vo.getTotalMemory() - vo.getMemUsedCapacity())); // ToDo: check
|
||||
h.setMaxSchedulingMemory(String.valueOf(vo.getTotalMemory() - vo.getMemUsedCapacity()));
|
||||
|
||||
// --- OS / versions (optional placeholders) ---
|
||||
// If you want, you can set conservative defaults to match oVirt shape.
|
||||
|
|
|
|||
|
|
@ -129,8 +129,9 @@ public final class UserVmJoinVOToVmConverter {
|
|||
os.setBoot(boot);
|
||||
dst.setOs(os);
|
||||
Vm.Bios bios = Vm.Bios.getDefault();
|
||||
Map<String, String> details = null;
|
||||
if (detailsResolver != null) {
|
||||
Map<String, String> details = detailsResolver.apply(src.getId());
|
||||
details = detailsResolver.apply(src.getId());
|
||||
Vm.Bios.updateBios(bios, MapUtils.getString(details, ApiConstants.BootType.UEFI.toString()));
|
||||
}
|
||||
dst.setBios(bios);
|
||||
|
|
@ -167,6 +168,11 @@ public final class UserVmJoinVOToVmConverter {
|
|||
dst.setInitialization(getOvfInitialization(dst, src));
|
||||
}
|
||||
|
||||
dst.setAccountId(src.getAccountUuid());
|
||||
dst.setAffinityGroupId(src.getAffinityGroupUuid());
|
||||
dst.setUserDataId(src.getUserDataUuid());
|
||||
dst.setDetails(details);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ import java.io.ByteArrayInputStream;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -36,6 +38,7 @@ import javax.xml.xpath.XPathExpressionException;
|
|||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.w3c.dom.Document;
|
||||
|
|
@ -195,6 +198,22 @@ public class OvfXmlUtil {
|
|||
sb.append("</Entry>");
|
||||
}
|
||||
sb.append("</DataDiskOfferingIdMap>");
|
||||
if (MapUtils.isNotEmpty(vm.getDetails())) {
|
||||
sb.append("<Details>");
|
||||
for (Map.Entry<String, String> entry : vm.getDetails().entrySet()) {
|
||||
sb.append("<Detail>");
|
||||
sb.append("<Key>").append(escapeText(entry.getKey())).append("</Key>");
|
||||
sb.append("<Value>").append(escapeText(entry.getValue())).append("</Value>");
|
||||
sb.append("</Detail>");
|
||||
}
|
||||
sb.append("</Details>");
|
||||
}
|
||||
if (vo.getUserDataId() != null) {
|
||||
sb.append("<UserDataId>").append(escapeText(vo.getUserDataUuid())).append("</UserDataId>");
|
||||
}
|
||||
if (vo.getAffinityGroupId() != null) {
|
||||
sb.append("<AffinityGroupId>").append(escapeText(vo.getAffinityGroupUuid())).append("</AffinityGroupId>");
|
||||
}
|
||||
sb.append("</CloudStack>");
|
||||
sb.append("</Section>");
|
||||
}
|
||||
|
|
@ -518,14 +537,35 @@ public class OvfXmlUtil {
|
|||
if (StringUtils.isNotBlank(serviceOfferingId)) {
|
||||
vm.setCpuProfile(Ref.of("", serviceOfferingId));
|
||||
}
|
||||
}
|
||||
|
||||
private static String xpathString(XPath xpath, Document doc, String expression) {
|
||||
String affinityGroupId = xpathString(xpath, metadataSection, ".//*[local-name()='AffinityGroupId']/text()");
|
||||
if (StringUtils.isNotBlank(affinityGroupId)) {
|
||||
vm.setAffinityGroupId(affinityGroupId);
|
||||
}
|
||||
String userDataId = xpathString(xpath, metadataSection, ".//*[local-name()='UserDataId']/text()");
|
||||
if (StringUtils.isNotBlank(userDataId)) {
|
||||
vm.setUserDataId(userDataId);
|
||||
}
|
||||
final Map<String, String> details = new HashMap<>();
|
||||
try {
|
||||
String value = (String) xpath.evaluate(expression, doc, XPathConstants.STRING);
|
||||
return StringUtils.isBlank(value) ? null : value.trim();
|
||||
} catch (XPathExpressionException e) {
|
||||
return null;
|
||||
NodeList detailNodes = (NodeList) xpath.evaluate(
|
||||
".//*[local-name()='Details']/*[local-name()='Detail']",
|
||||
metadataSection,
|
||||
XPathConstants.NODESET
|
||||
);
|
||||
|
||||
for (int i = 0; i < detailNodes.getLength(); i++) {
|
||||
Node detailNode = detailNodes.item(i);
|
||||
String key = xpathString(xpath, detailNode, "./*[local-name()='Key']/text()");
|
||||
if (StringUtils.isBlank(key)) {
|
||||
continue;
|
||||
}
|
||||
String value = xpathString(xpath, detailNode, "./*[local-name()='Value']/text()");
|
||||
details.put(key, defaultString(value));
|
||||
}
|
||||
} catch (XPathExpressionException ignored) {
|
||||
}
|
||||
if (!details.isEmpty()) {
|
||||
vm.setDetails(details);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.cloudstack.veeam.api.dto;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
|
||||
|
|
@ -79,6 +80,9 @@ public final class Vm extends BaseDto {
|
|||
|
||||
// CloudStack-specific fields
|
||||
private String accountId;
|
||||
private String affinityGroupId;
|
||||
private String userDataId;
|
||||
private Map<String, String> details;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
@ -297,6 +301,33 @@ public final class Vm extends BaseDto {
|
|||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public String getAffinityGroupId() {
|
||||
return affinityGroupId;
|
||||
}
|
||||
|
||||
public void setAffinityGroupId(String affinityGroupId) {
|
||||
this.affinityGroupId = affinityGroupId;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public String getUserDataId() {
|
||||
return userDataId;
|
||||
}
|
||||
|
||||
public void setUserDataId(String userDataId) {
|
||||
this.userDataId = userDataId;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public Map<String, String> getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
public void setDetails(Map<String, String> details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public static final class Bios {
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
// 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.veeam.api.request;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ListQuery {
|
||||
boolean allContent;
|
||||
Long max;
|
||||
Long page;
|
||||
Map<String, String> search;
|
||||
|
||||
public boolean isAllContent() {
|
||||
return allContent;
|
||||
}
|
||||
|
||||
public void setAllContent(boolean allContent) {
|
||||
this.allContent = allContent;
|
||||
}
|
||||
|
||||
public Long getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public void setMax(Long max) {
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public Map<String, String> getSearch() {
|
||||
return search;
|
||||
}
|
||||
|
||||
public void setSearch(Map<String, String> search) {
|
||||
this.search = search;
|
||||
}
|
||||
|
||||
public Long getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
public Long getOffset() {
|
||||
if (page == null || max == null) {
|
||||
return null;
|
||||
}
|
||||
return Math.max(0, (page - 1)) * max;
|
||||
}
|
||||
|
||||
public Long getLimit() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public static ListQuery fromRequest(HttpServletRequest request) {
|
||||
ListQuery query = new ListQuery();
|
||||
if (MapUtils.isEmpty(request.getParameterMap())) {
|
||||
return query;
|
||||
}
|
||||
|
||||
String allContent = request.getParameter("all_content");
|
||||
if (StringUtils.isNotBlank(allContent)) {
|
||||
query.setAllContent(Boolean.parseBoolean(allContent));
|
||||
}
|
||||
String max = request.getParameter("max");
|
||||
if (StringUtils.isNotBlank(max)) {
|
||||
try {
|
||||
query.setMax(Long.parseLong(max));
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore invalid max and keep default null value.
|
||||
}
|
||||
}
|
||||
Map<String, String> searchItems = getSearchMap(request.getParameter("search"));
|
||||
if (!searchItems.isEmpty()) {
|
||||
try {
|
||||
query.setMax(Long.parseLong(searchItems.get("page")));
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore invalid page and keep default null value.
|
||||
}
|
||||
query.setSearch(searchItems);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
// Parse search clause. Only keep items which use simple '=' operator, and ignore others. For example:
|
||||
// name=myvm and status=up --> {name=myvm, status=up}
|
||||
// name=myvm and status!=down --> {name=myvm} (ignore status!=down because it uses '!=' operator)
|
||||
@NotNull
|
||||
private static Map<String, String> getSearchMap(String searchClause) {
|
||||
Map<String, String> searchItems = new LinkedHashMap<>();
|
||||
if (StringUtils.isBlank(searchClause)) {
|
||||
return searchItems;
|
||||
}
|
||||
String[] terms = searchClause.trim().split("(?i)\\s+and\\s+");
|
||||
for (String term : terms) {
|
||||
if (term == null) {
|
||||
continue;
|
||||
}
|
||||
String trimmedTerm = term.trim();
|
||||
if (trimmedTerm.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int eqIdx = trimmedTerm.indexOf('=');
|
||||
if (eqIdx <= 0 || eqIdx != trimmedTerm.lastIndexOf('=')) {
|
||||
continue;
|
||||
}
|
||||
char prev = trimmedTerm.charAt(eqIdx - 1);
|
||||
if (prev == '!' || prev == '<' || prev == '>') {
|
||||
continue;
|
||||
}
|
||||
|
||||
String key = trimmedTerm.substring(0, eqIdx).trim();
|
||||
String value = trimmedTerm.substring(eqIdx + 1).trim();
|
||||
if (!key.isEmpty() && !value.isEmpty()) {
|
||||
searchItems.put(key, value);
|
||||
}
|
||||
}
|
||||
return searchItems;
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ import org.apache.cloudstack.api.response.HostResponse;
|
|||
import com.cloud.api.query.vo.HostJoinVO;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface HostJoinDao extends GenericDao<HostJoinVO, Long> {
|
||||
|
|
@ -42,6 +43,6 @@ public interface HostJoinDao extends GenericDao<HostJoinVO, Long> {
|
|||
|
||||
List<HostJoinVO> findByClusterId(Long clusterId, Host.Type type);
|
||||
|
||||
List<HostJoinVO> listRoutingHostsByHypervisor(Hypervisor.HypervisorType hypervisorType);
|
||||
List<HostJoinVO> listRoutingHostsByHypervisor(Hypervisor.HypervisorType hypervisorType, Filter filter);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import com.cloud.host.dao.HostDetailsDao;
|
|||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.StorageStats;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
|
@ -414,7 +415,7 @@ public class HostJoinDaoImpl extends GenericDaoBase<HostJoinVO, Long> implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<HostJoinVO> listRoutingHostsByHypervisor(Hypervisor.HypervisorType hypervisorType) {
|
||||
public List<HostJoinVO> listRoutingHostsByHypervisor(Hypervisor.HypervisorType hypervisorType, Filter filter) {
|
||||
SearchBuilder<HostJoinVO> sb = createSearchBuilder();
|
||||
sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
|
||||
sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -423,6 +424,6 @@ public class HostJoinDaoImpl extends GenericDaoBase<HostJoinVO, Long> implements
|
|||
SearchCriteria<HostJoinVO> sc = sb.create();
|
||||
sc.setParameters("type", Host.Type.Routing);
|
||||
sc.setParameters("hypervisorType", hypervisorType);
|
||||
return listBy(sc);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import org.apache.cloudstack.api.response.StoragePoolResponse;
|
|||
|
||||
import com.cloud.api.query.vo.StoragePoolJoinVO;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
||||
|
|
@ -44,4 +45,6 @@ public interface StoragePoolJoinDao extends GenericDao<StoragePoolJoinVO, Long>
|
|||
|
||||
List<StoragePoolVO> findStoragePoolByScopeAndRuleTags(Long datacenterId, Long podId, Long clusterId, ScopeType scopeType, List<String> tags);
|
||||
|
||||
List<StoragePoolJoinVO> listByZoneAndProvider(long zoneId, Filter filter);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import com.cloud.storage.StorageStats;
|
|||
import com.cloud.storage.VolumeApiServiceImpl;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
|
@ -410,4 +411,13 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase<StoragePoolJoinVO, Lo
|
|||
return filteredPools;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolJoinVO> listByZoneAndProvider(long zoneId, Filter filter) {
|
||||
SearchBuilder<StoragePoolJoinVO> sb = createSearchBuilder();
|
||||
sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
|
||||
sb.done();
|
||||
SearchCriteria<StoragePoolJoinVO> sc = sb.create();
|
||||
sc.setParameters("zoneId", zoneId);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import com.cloud.api.query.vo.UserVmJoinVO;
|
|||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.api.ApiConstants.VMDetails;
|
||||
|
|
@ -51,5 +52,5 @@ public interface UserVmJoinDao extends GenericDao<UserVmJoinVO, Long> {
|
|||
|
||||
List<UserVmJoinVO> listLeaseInstancesExpiringInDays(int days);
|
||||
|
||||
List<UserVmJoinVO> listByHypervisorType(Hypervisor.HypervisorType hypervisorType);
|
||||
List<UserVmJoinVO> listByHypervisorType(Hypervisor.HypervisorType hypervisorType, Filter filter);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ import com.cloud.user.UserStatisticsVO;
|
|||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.user.dao.UserStatisticsDao;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
|
|
@ -498,7 +499,7 @@ public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJo
|
|||
}
|
||||
|
||||
if (userVm.getUserDataId() != null) {
|
||||
userVmResponse.setUserDataId(userVm.getUserDataUUid());
|
||||
userVmResponse.setUserDataId(userVm.getUserDataUuid());
|
||||
userVmResponse.setUserDataName(userVm.getUserDataName());
|
||||
userVmResponse.setUserDataDetails(userVm.getUserDataDetails());
|
||||
userVmResponse.setUserDataPolicy(userVm.getUserDataPolicy());
|
||||
|
|
@ -835,12 +836,12 @@ public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJo
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<UserVmJoinVO> listByHypervisorType(Hypervisor.HypervisorType hypervisorType) {
|
||||
public List<UserVmJoinVO> listByHypervisorType(Hypervisor.HypervisorType hypervisorType, Filter filter) {
|
||||
SearchBuilder<UserVmJoinVO> sb = createSearchBuilder();
|
||||
sb.and("hypervisorType", sb.entity().getHypervisorType(), Op.EQ);
|
||||
sb.done();
|
||||
SearchCriteria<UserVmJoinVO> sc = sb.create();
|
||||
sc.setParameters("hypervisorType", hypervisorType);
|
||||
return listBy(sc);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import org.apache.cloudstack.api.response.VolumeResponse;
|
|||
import com.cloud.api.query.vo.VolumeJoinVO;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface VolumeJoinDao extends GenericDao<VolumeJoinVO, Long> {
|
||||
|
|
@ -38,5 +39,5 @@ public interface VolumeJoinDao extends GenericDao<VolumeJoinVO, Long> {
|
|||
|
||||
List<VolumeJoinVO> listByInstanceId(long instanceId);
|
||||
|
||||
List<VolumeJoinVO> listByHypervisor(Hypervisor.HypervisorType hypervisorType);
|
||||
List<VolumeJoinVO> listByHypervisor(Hypervisor.HypervisorType hypervisorType, Filter filter);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import com.cloud.storage.Volume;
|
|||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.VmDiskStatisticsVO;
|
||||
import com.cloud.user.dao.VmDiskStatisticsDao;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
|
@ -381,7 +382,7 @@ public class VolumeJoinDaoImpl extends GenericDaoBaseWithTagInformation<VolumeJo
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<VolumeJoinVO> listByHypervisor(Hypervisor.HypervisorType hypervisorType) {
|
||||
public List<VolumeJoinVO> listByHypervisor(Hypervisor.HypervisorType hypervisorType, Filter filter) {
|
||||
SearchBuilder<VolumeJoinVO> sb = createSearchBuilder();
|
||||
sb.and("vmType", sb.entity().getVmType(), SearchCriteria.Op.EQ);
|
||||
sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -389,7 +390,7 @@ public class VolumeJoinDaoImpl extends GenericDaoBaseWithTagInformation<VolumeJo
|
|||
SearchCriteria<VolumeJoinVO> sc = sb.create();
|
||||
sc.setParameters("vmType", VirtualMachine.Type.User);
|
||||
sc.setParameters("hypervisorType", hypervisorType);
|
||||
return search(sc, null);
|
||||
return search(sc, filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -429,7 +429,7 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
|||
private int jobStatus;
|
||||
|
||||
@Column(name = "affinity_group_id")
|
||||
private long affinityGroupId;
|
||||
private Long affinityGroupId;
|
||||
|
||||
@Column(name = "affinity_group_uuid")
|
||||
private String affinityGroupUuid;
|
||||
|
|
@ -1012,7 +1012,7 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
|||
return ip6Cidr;
|
||||
}
|
||||
|
||||
public long getAffinityGroupId() {
|
||||
public Long getAffinityGroupId() {
|
||||
return affinityGroupId;
|
||||
}
|
||||
|
||||
|
|
@ -1057,7 +1057,7 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
|||
return userDataId;
|
||||
}
|
||||
|
||||
public String getUserDataUUid() {
|
||||
public String getUserDataUuid() {
|
||||
return userDataUuid;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import org.apache.cloudstack.api.response.CheckpointResponse;
|
|||
import org.apache.cloudstack.api.response.ImageTransferResponse;
|
||||
import org.apache.cloudstack.backup.dao.BackupDao;
|
||||
import org.apache.cloudstack.backup.dao.ImageTransferDao;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
|
|
@ -67,6 +68,8 @@ import com.cloud.storage.VolumeStats;
|
|||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.dao.VolumeDetailsDao;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
|
@ -104,6 +107,9 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup
|
|||
@Inject
|
||||
private PrimaryDataStoreDao primaryDataStoreDao;
|
||||
|
||||
@Inject
|
||||
AccountService accountService;
|
||||
|
||||
private Timer imageTransferTimer;
|
||||
|
||||
private boolean isKVMBackupExportServiceSupported(Long zoneId) {
|
||||
|
|
@ -493,8 +499,10 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup
|
|||
|
||||
@Override
|
||||
public ImageTransfer createImageTransfer(long volumeId, Long backupId, ImageTransfer.Direction direction, ImageTransfer.Format format) {
|
||||
User callingUser = CallContext.current().getCallingUser();
|
||||
ImageTransfer imageTransfer;
|
||||
VolumeVO volume = volumeDao.findById(volumeId);
|
||||
accountService.checkAccess(callingUser, volume);
|
||||
|
||||
if (volume == null) {
|
||||
throw new CloudRuntimeException("Volume not found with the specified Id");
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import com.cloud.network.dao.NetworkAccountVO;
|
|||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
|
||||
|
|
@ -160,13 +161,18 @@ public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implemen
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkVO> listByZoneAndTrafficType(final long zoneId, final TrafficType trafficType, Filter filter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkVO> listByZoneAndTrafficType(final long zoneId, final TrafficType trafficType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkVO> listByTrafficType(final TrafficType trafficType) {
|
||||
public List<NetworkVO> listByTrafficType(final TrafficType trafficType, Filter filter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue