mirror of https://github.com/apache/cloudstack.git
cleanup; return tags with specific key only
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
d804b7597b
commit
2f673568aa
|
|
@ -63,6 +63,8 @@ public interface ResourceTagDao extends GenericDao<ResourceTagVO, Long> {
|
|||
|
||||
List<? extends ResourceTag> listByResourceUuid(String resourceUuid);
|
||||
|
||||
List<ResourceTagVO> listByResourceTypeAndOwners(ResourceObjectType resourceType, List<Long> accountIds,
|
||||
List<Long> domainIds, Filter filter);
|
||||
List<ResourceTagVO> listByResourceTypeKeyAndOwners(ResourceObjectType resourceType, String key,
|
||||
List<Long> accountIds, List<Long> domainIds, Filter filter);
|
||||
|
||||
ResourceTagVO findByResourceTypeKeyAndValue(ResourceObjectType resourceType, String key, String value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,10 +124,12 @@ public class ResourceTagsDaoImpl extends GenericDaoBase<ResourceTagVO, Long> imp
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceTagVO> listByResourceTypeAndOwners(ResourceObjectType resourceType, List<Long> accountIds,
|
||||
List<Long> domainIds, Filter filter) {
|
||||
public List<ResourceTagVO> listByResourceTypeKeyAndOwners(ResourceObjectType resourceType, String key,
|
||||
List<Long> accountIds, List<Long> domainIds,
|
||||
Filter filter) {
|
||||
SearchBuilder<ResourceTagVO> sb = createSearchBuilder();
|
||||
sb.and("resourceType", sb.entity().getResourceType(), Op.EQ);
|
||||
sb.and("key", sb.entity().getKey(), Op.EQ);
|
||||
boolean accountIdsNotEmpty = CollectionUtils.isNotEmpty(accountIds);
|
||||
boolean domainIdsNotEmpty = CollectionUtils.isNotEmpty(domainIds);
|
||||
if (accountIdsNotEmpty || domainIdsNotEmpty) {
|
||||
|
|
@ -136,8 +138,9 @@ public class ResourceTagsDaoImpl extends GenericDaoBase<ResourceTagVO, Long> imp
|
|||
sb.cp();
|
||||
}
|
||||
sb.done();
|
||||
final SearchCriteria<ResourceTagVO> sc = sb.create();;
|
||||
final SearchCriteria<ResourceTagVO> sc = sb.create();
|
||||
sc.setParameters("resourceType", resourceType);
|
||||
sc.setParameters("key", key);
|
||||
if (accountIdsNotEmpty) {
|
||||
sc.setParameters("account", accountIds.toArray());
|
||||
}
|
||||
|
|
@ -146,4 +149,19 @@ public class ResourceTagsDaoImpl extends GenericDaoBase<ResourceTagVO, Long> imp
|
|||
}
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceTagVO findByResourceTypeKeyAndValue(ResourceObjectType resourceType, String key,
|
||||
String value) {
|
||||
SearchBuilder<ResourceTagVO> sb = createSearchBuilder();
|
||||
sb.and("resourceType", sb.entity().getResourceType(), Op.EQ);
|
||||
sb.and("key", sb.entity().getKey(), Op.EQ);
|
||||
sb.and("value", sb.entity().getValue(), Op.EQ);
|
||||
sb.done();
|
||||
final SearchCriteria<ResourceTagVO> sc = sb.create();
|
||||
sc.setParameters("resourceType", resourceType);
|
||||
sc.setParameters("key", key);
|
||||
sc.setParameters("value", value);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ SELECT
|
|||
`vm_instance`.`display_vm` AS `display_vm`,
|
||||
`vm_instance`.`delete_protection` AS `delete_protection`,
|
||||
`guest_os`.`uuid` AS `guest_os_uuid`,
|
||||
`guest_os`.`display_name` AS `guest_os_display_name`,
|
||||
`vm_instance`.`pod_id` AS `pod_id`,
|
||||
`host_pod_ref`.`uuid` AS `pod_uuid`,
|
||||
`vm_instance`.`private_ip_address` AS `private_ip_address`,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package org.apache.cloudstack.veeam;
|
|||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
|
@ -30,7 +29,6 @@ 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)
|
||||
|
|
@ -60,7 +58,6 @@ public interface RouteHandler extends Adapter {
|
|||
if (!"application/json".equals(mime) && !"application/x-www-form-urlencoded".equals(mime)) {
|
||||
return null;
|
||||
}
|
||||
String result = null;
|
||||
try {
|
||||
StringBuilder data = new StringBuilder();
|
||||
String line;
|
||||
|
|
@ -74,4 +71,9 @@ public interface RouteHandler extends Adapter {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isRequestAsync(HttpServletRequest req) {
|
||||
String asyncStr = req.getParameter("async");
|
||||
return Boolean.TRUE.toString().equals(asyncStr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import javax.servlet.DispatcherType;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.cloudstack.utils.server.ServerPropertiesUtil;
|
||||
import org.apache.cloudstack.veeam.api.ApiService;
|
||||
import org.apache.cloudstack.veeam.api.ApiRouteHandler;
|
||||
import org.apache.cloudstack.veeam.filter.AllowedClientCidrsFilter;
|
||||
import org.apache.cloudstack.veeam.filter.BearerOrBasicAuthFilter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
|
@ -125,12 +125,12 @@ public class VeeamControlServer {
|
|||
// CIDR filter for all routes
|
||||
AllowedClientCidrsFilter cidrFilter = new AllowedClientCidrsFilter(veeamControlService);
|
||||
FilterHolder cidrHolder = new FilterHolder(cidrFilter);
|
||||
ctx.addFilter(cidrHolder, ApiService.BASE_ROUTE + "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
ctx.addFilter(cidrHolder, ApiRouteHandler.BASE_ROUTE + "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
|
||||
// Bearer or Basic Auth for all routes
|
||||
BearerOrBasicAuthFilter authFilter = new BearerOrBasicAuthFilter(veeamControlService);
|
||||
FilterHolder authHolder = new FilterHolder(authFilter);
|
||||
ctx.addFilter(authHolder, ApiService.BASE_ROUTE + "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
ctx.addFilter(authHolder, ApiRouteHandler.BASE_ROUTE + "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
|
||||
// Front controller servlet
|
||||
ctx.addServlet(new ServletHolder(new VeeamControlServlet(routeHandlers)), "/*");
|
||||
|
|
|
|||
|
|
@ -21,10 +21,13 @@ import java.util.List;
|
|||
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.utils.CloudStackVersion;
|
||||
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
|
||||
public interface VeeamControlService extends PluggableService, Configurable {
|
||||
String PLUGIN_NAME = "CloudStack Veeam Control Service";
|
||||
|
||||
ConfigKey<Boolean> Enabled = new ConfigKey<>("Advanced", Boolean.class, "integration.veeam.control.enabled",
|
||||
"false", "Enable the Veeam Integration REST API server", false);
|
||||
ConfigKey<String> BindAddress = new ConfigKey<>("Advanced", String.class, "integration.veeam.control.bind.address",
|
||||
|
|
@ -57,4 +60,16 @@ public interface VeeamControlService extends PluggableService, Configurable {
|
|||
List<String> getAllowedClientCidrs();
|
||||
|
||||
boolean validateCredentials(String username, String password);
|
||||
|
||||
static String getPackageVersion() {
|
||||
return VeeamControlService.class.getPackage().getImplementationVersion();
|
||||
}
|
||||
|
||||
static CloudStackVersion getCSVersion() {
|
||||
try {
|
||||
return CloudStackVersion.parse(getPackageVersion());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,19 +101,6 @@ public class VeeamControlServlet extends HttpServlet {
|
|||
String name = headerNames.nextElement();
|
||||
details.append(name).append("=").append(req.getHeader(name)).append("; ");
|
||||
}
|
||||
// String body = "";
|
||||
// if (!"GET".equalsIgnoreCase(method)) {
|
||||
// StringBuilder bodySb = new StringBuilder();
|
||||
// java.io.BufferedReader reader = req.getReader();
|
||||
// if (reader != null) {
|
||||
// String line;
|
||||
// while ((line = reader.readLine()) != null) {
|
||||
// bodySb.append(line).append('\n');
|
||||
// }
|
||||
// }
|
||||
// body = bodySb.toString().trim();
|
||||
// }
|
||||
// details.append(", Body: ").append(body);
|
||||
LOGGER.debug(details.toString());
|
||||
} catch (Exception e) {
|
||||
LOGGER.debug("Failed to capture request details", e);
|
||||
|
|
@ -135,8 +122,8 @@ public class VeeamControlServlet extends HttpServlet {
|
|||
}
|
||||
|
||||
writer.write(resp, 200, Map.of(
|
||||
"name", "CloudStack Veeam Control Service",
|
||||
"pluginVersion", "0.1"), outFormat);
|
||||
"name", VeeamControlService.PLUGIN_NAME,
|
||||
"pluginVersion", this.getClass().getPackage().getImplementationVersion()), outFormat);
|
||||
}
|
||||
|
||||
public void methodNotAllowed(final HttpServletResponse resp, final String allow, final Negotiation.OutFormat outFormat) throws IOException {
|
||||
|
|
|
|||
|
|
@ -238,7 +238,8 @@ public class ServerAdapter extends ManagerBase {
|
|||
Storage.StoragePoolType.NetworkFilesystem,
|
||||
Storage.StoragePoolType.SharedMountPoint
|
||||
);
|
||||
public static final String WORKER_VM_GUEST_CPU_MODE = "host-passthrough";
|
||||
private static final String VM_TA_KEY = "veeam_tag";
|
||||
private static final String WORKER_VM_GUEST_CPU_MODE = "host-passthrough";
|
||||
|
||||
@Inject
|
||||
RoleService roleService;
|
||||
|
|
@ -413,22 +414,6 @@ public class ServerAdapter extends ManagerBase {
|
|||
accountService.getActiveAccountById(userAccount.getAccountId()));
|
||||
}
|
||||
|
||||
protected Pair<User, Account> getServiceAccount() {
|
||||
String serviceAccountUuid = VeeamControlService.ServiceAccountId.value();
|
||||
if (StringUtils.isEmpty(serviceAccountUuid)) {
|
||||
throw new CloudRuntimeException("Service account is not configured, unable to proceed");
|
||||
}
|
||||
Account account = accountService.getActiveAccountByUuid(serviceAccountUuid);
|
||||
if (account == null) {
|
||||
throw new CloudRuntimeException("Service account with ID " + serviceAccountUuid + " not found, unable to proceed");
|
||||
}
|
||||
User user = accountService.getOneActiveUserForAccount(account);
|
||||
if (user == null) {
|
||||
throw new CloudRuntimeException("No active user found for service account with ID " + serviceAccountUuid);
|
||||
}
|
||||
return new Pair<>(user, account);
|
||||
}
|
||||
|
||||
protected void waitForJobCompletion(long jobId) {
|
||||
long timeoutNanos = TimeUnit.MINUTES.toNanos(5);
|
||||
final long deadline = System.nanoTime() + timeoutNanos;
|
||||
|
|
@ -858,6 +843,22 @@ public class ServerAdapter extends ManagerBase {
|
|||
return vmInstanceDetailsDao.listDetailsKeyPairs(instanceId, true);
|
||||
}
|
||||
|
||||
public Pair<User, Account> getServiceAccount() {
|
||||
String serviceAccountUuid = VeeamControlService.ServiceAccountId.value();
|
||||
if (StringUtils.isEmpty(serviceAccountUuid)) {
|
||||
throw new CloudRuntimeException("Service account is not configured, unable to proceed");
|
||||
}
|
||||
Account account = accountService.getActiveAccountByUuid(serviceAccountUuid);
|
||||
if (account == null) {
|
||||
throw new CloudRuntimeException("Service account with ID " + serviceAccountUuid + " not found, unable to proceed");
|
||||
}
|
||||
User user = accountService.getOneActiveUserForAccount(account);
|
||||
if (user == null) {
|
||||
throw new CloudRuntimeException("No active user found for service account with ID " + serviceAccountUuid);
|
||||
}
|
||||
return new Pair<>(user, account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
getServiceAccount();
|
||||
|
|
@ -1185,15 +1186,13 @@ public class ServerAdapter extends ManagerBase {
|
|||
|
||||
@ApiAccess(command = ListTagsCmd.class)
|
||||
protected List<Tag> listTagsByInstanceId(final long instanceId) {
|
||||
List<? extends ResourceTag> vmResourceTags = resourceTagDao.listBy(instanceId,
|
||||
ResourceTag.ResourceObjectType.UserVm);
|
||||
ResourceTag vmResourceTag = resourceTagDao.findByKey(instanceId,
|
||||
ResourceTag.ResourceObjectType.UserVm, VM_TA_KEY);
|
||||
List<ResourceTagVO> tags = new ArrayList<>();
|
||||
for (ResourceTag t : vmResourceTags) {
|
||||
if (t instanceof ResourceTagVO) {
|
||||
tags.add((ResourceTagVO)t);
|
||||
continue;
|
||||
}
|
||||
tags.add(resourceTagDao.findById(t.getId()));
|
||||
if (vmResourceTag instanceof ResourceTagVO) {
|
||||
tags.add((ResourceTagVO)vmResourceTag);
|
||||
} else {
|
||||
tags.add(resourceTagDao.findById(vmResourceTag.getId()));
|
||||
}
|
||||
return ResourceTagVOToTagConverter.toTags(tags);
|
||||
}
|
||||
|
|
@ -1760,8 +1759,8 @@ public class ServerAdapter extends ManagerBase {
|
|||
List<Tag> tags = new ArrayList<>(getDummyTags().values());
|
||||
Filter filter = new Filter(ResourceTagVO.class, "id", true, offset, limit);
|
||||
Pair<List<Long>, List<Long>> ownerDetails = getResourceOwnerFiltersWithDomainIds();
|
||||
List<ResourceTagVO> vmResourceTags = resourceTagDao.listByResourceTypeAndOwners(
|
||||
ResourceTag.ResourceObjectType.UserVm, ownerDetails.first(), ownerDetails.second(), filter);
|
||||
List<ResourceTagVO> vmResourceTags = resourceTagDao.listByResourceTypeKeyAndOwners(
|
||||
ResourceTag.ResourceObjectType.UserVm, VM_TA_KEY, ownerDetails.first(), ownerDetails.second(), filter);
|
||||
if (CollectionUtils.isNotEmpty(vmResourceTags)) {
|
||||
tags.addAll(ResourceTagVOToTagConverter.toTags(vmResourceTags));
|
||||
}
|
||||
|
|
@ -1775,7 +1774,8 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
Tag tag = getDummyTags().get(uuid);
|
||||
if (tag == null) {
|
||||
ResourceTagVO resourceTagVO = resourceTagDao.findByUuid(uuid);
|
||||
ResourceTagVO resourceTagVO = resourceTagDao.findByResourceTypeKeyAndValue(
|
||||
ResourceTag.ResourceObjectType.UserVm, VM_TA_KEY, uuid);
|
||||
accountService.checkAccess(CallContext.current().getCallingAccount(), null, false,
|
||||
resourceTagVO);
|
||||
if (resourceTagVO != null) {
|
||||
|
|
|
|||
|
|
@ -21,21 +21,21 @@ import java.io.IOException;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.cloudstack.veeam.RouteHandler;
|
||||
import org.apache.cloudstack.veeam.VeeamControlService;
|
||||
import org.apache.cloudstack.veeam.VeeamControlServlet;
|
||||
import org.apache.cloudstack.veeam.adapter.ServerAdapter;
|
||||
import org.apache.cloudstack.veeam.api.dto.Api;
|
||||
import org.apache.cloudstack.veeam.api.dto.ApiSummary;
|
||||
import org.apache.cloudstack.veeam.api.dto.EmptyElement;
|
||||
import org.apache.cloudstack.veeam.api.dto.Link;
|
||||
import org.apache.cloudstack.veeam.api.dto.ProductInfo;
|
||||
import org.apache.cloudstack.veeam.api.dto.Ref;
|
||||
import org.apache.cloudstack.veeam.api.dto.SpecialObjects;
|
||||
import org.apache.cloudstack.veeam.api.dto.SummaryCount;
|
||||
import org.apache.cloudstack.veeam.api.dto.Version;
|
||||
import org.apache.cloudstack.veeam.utils.Negotiation;
|
||||
|
|
@ -43,9 +43,12 @@ import org.apache.cloudstack.veeam.utils.Negotiation;
|
|||
import com.cloud.utils.UuidUtils;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
|
||||
public class ApiService extends ManagerBase implements RouteHandler {
|
||||
public class ApiRouteHandler extends ManagerBase implements RouteHandler {
|
||||
public static final String BASE_ROUTE = "/api";
|
||||
|
||||
@Inject
|
||||
ServerAdapter serverAdapter;
|
||||
|
||||
@Override
|
||||
public boolean canHandle(String method, String path) {
|
||||
return getSanitizedPath(path).startsWith("/api");
|
||||
|
|
@ -63,11 +66,11 @@ public class ApiService extends ManagerBase implements RouteHandler {
|
|||
|
||||
private void handleRootApiRequest(HttpServletRequest req, HttpServletResponse resp, Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK,
|
||||
createDummyApi(VeeamControlService.ContextPath.value() + BASE_ROUTE),
|
||||
createApiObject(VeeamControlService.ContextPath.value() + BASE_ROUTE),
|
||||
outFormat);
|
||||
}
|
||||
|
||||
private static Api createDummyApi(String basePath) {
|
||||
protected Api createApiObject(String basePath) {
|
||||
Api api = new Api();
|
||||
|
||||
/* ---------------- Links ---------------- */
|
||||
|
|
@ -96,30 +99,11 @@ public class ApiService extends ManagerBase implements RouteHandler {
|
|||
ProductInfo productInfo = new ProductInfo();
|
||||
productInfo.setInstanceId(UuidUtils.nameUUIDFromBytes(
|
||||
VeeamControlService.BindAddress.value().getBytes(StandardCharsets.UTF_8)).toString());
|
||||
productInfo.name = "oVirt Engine";
|
||||
productInfo.name = VeeamControlService.PLUGIN_NAME;
|
||||
|
||||
Version version = new Version();
|
||||
version.setBuild("8");
|
||||
version.setFullVersion("4.5.8-0.master.fake.el9");
|
||||
version.setMajor("4");
|
||||
version.setMinor("5");
|
||||
version.setRevision("0");
|
||||
|
||||
productInfo.version = version;
|
||||
productInfo.version = Version.fromPackageAndCSVersion(true);
|
||||
api.setProductInfo(productInfo);
|
||||
|
||||
/* ---------------- Special objects ---------------- */
|
||||
SpecialObjects specialObjects = new SpecialObjects();
|
||||
specialObjects.setBlankTemplate(Ref.of(
|
||||
basePath + "/templates/00000000-0000-0000-0000-000000000000",
|
||||
"00000000-0000-0000-0000-000000000000"
|
||||
));
|
||||
specialObjects.setRootTag(Ref.of(
|
||||
basePath + "/tags/00000000-0000-0000-0000-000000000000",
|
||||
"00000000-0000-0000-0000-000000000000"
|
||||
));
|
||||
api.setSpecialObjects(specialObjects);
|
||||
|
||||
/* ---------------- Summary ---------------- */
|
||||
ApiSummary summary = new ApiSummary();
|
||||
summary.setHosts(new SummaryCount(1, 1));
|
||||
|
|
@ -132,7 +116,7 @@ public class ApiService extends ManagerBase implements RouteHandler {
|
|||
api.setTime(System.currentTimeMillis());
|
||||
|
||||
/* ---------------- Users ---------------- */
|
||||
String userId = UUID.randomUUID().toString();
|
||||
String userId = serverAdapter.getServiceAccount().first().getUuid();
|
||||
api.setAuthenticatedUser(Ref.of(basePath + "/users/" + userId, userId));
|
||||
api.setEffectiveUser(Ref.of(basePath + "/users/" + userId, userId));
|
||||
|
||||
|
|
@ -222,11 +222,6 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
io.notFound(resp, null, outFormat);
|
||||
}
|
||||
|
||||
protected static boolean isRequestAsync(HttpServletRequest req) {
|
||||
String asyncStr = req.getParameter("async");
|
||||
return Boolean.TRUE.toString().equals(asyncStr);
|
||||
}
|
||||
|
||||
protected void handleGet(final HttpServletRequest req, final HttpServletResponse resp,
|
||||
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
|
||||
try {
|
||||
|
|
@ -287,7 +282,7 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleDeleteById(final String id, final HttpServletRequest req, final HttpServletResponse resp,
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
boolean async = isRequestAsync(req);
|
||||
boolean async = RouteHandler.isRequestAsync(req);
|
||||
try {
|
||||
VmAction vm = serverAdapter.deleteInstance(id, async);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, vm, outFormat);
|
||||
|
|
@ -298,7 +293,7 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleStartVmById(final String id, final HttpServletRequest req, final HttpServletResponse resp,
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
boolean async = isRequestAsync(req);
|
||||
boolean async = RouteHandler.isRequestAsync(req);
|
||||
try {
|
||||
VmAction vm = serverAdapter.startInstance(id, async);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_ACCEPTED, vm, outFormat);
|
||||
|
|
@ -309,7 +304,7 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleStopVmById(final String id, final HttpServletRequest req, final HttpServletResponse resp,
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
boolean async = isRequestAsync(req);
|
||||
boolean async = RouteHandler.isRequestAsync(req);
|
||||
try {
|
||||
VmAction vm = serverAdapter.stopInstance(id, async);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_ACCEPTED, vm, outFormat);
|
||||
|
|
@ -320,7 +315,7 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
|
||||
protected void handleShutdownVmById(final String id, final HttpServletRequest req, final HttpServletResponse resp,
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
boolean async = isRequestAsync(req);
|
||||
boolean async = RouteHandler.isRequestAsync(req);
|
||||
try {
|
||||
VmAction vm = serverAdapter.shutdownInstance(id, async);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_ACCEPTED, vm, outFormat);
|
||||
|
|
@ -422,7 +417,7 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
protected void handleDeleteSnapshotById(final String id, final HttpServletRequest req,
|
||||
final HttpServletResponse resp, final Negotiation.OutFormat outFormat, final VeeamControlServlet io)
|
||||
throws IOException {
|
||||
boolean async = isRequestAsync(req);
|
||||
boolean async = RouteHandler.isRequestAsync(req);
|
||||
try {
|
||||
ResourceAction action = serverAdapter.deleteSnapshot(id, async);
|
||||
if (action != null) {
|
||||
|
|
@ -438,7 +433,7 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
protected void handleRestoreSnapshotById(final String id, final HttpServletRequest req,
|
||||
final HttpServletResponse resp, final Negotiation.OutFormat outFormat, final VeeamControlServlet io)
|
||||
throws IOException {
|
||||
boolean async = isRequestAsync(req);
|
||||
boolean async = RouteHandler.isRequestAsync(req);
|
||||
String data = RouteHandler.getRequestData(req, logger);
|
||||
try {
|
||||
ResourceAction response = serverAdapter.revertInstanceToSnapshot(id, async);
|
||||
|
|
|
|||
|
|
@ -34,26 +34,6 @@ import com.cloud.api.query.vo.UserVmJoinVO;
|
|||
|
||||
public class AsyncJobJoinVOToJobConverter {
|
||||
|
||||
public static Job toJob(String uuid, String state, long startTime) {
|
||||
Job job = new Job();
|
||||
final String basePath = VeeamControlService.ContextPath.value();
|
||||
// Fill in dummy data for now, as the AsyncJobJoinVO does not contain all the necessary information to populate a Job object.
|
||||
job.setId(uuid);
|
||||
job.setHref(basePath + JobsRouteHandler.BASE_ROUTE + "/" + uuid);
|
||||
job.setAutoCleared(Boolean.TRUE.toString());
|
||||
job.setExternal(Boolean.TRUE.toString());
|
||||
job.setLastUpdated(System.currentTimeMillis());
|
||||
job.setStartTime(startTime);
|
||||
job.setStatus(state);
|
||||
if ("complete".equalsIgnoreCase(state) || "finished".equalsIgnoreCase(state)) {
|
||||
job.setEndTime(System.currentTimeMillis());
|
||||
}
|
||||
job.setOwner(Ref.of(basePath + "/api/users/" + uuid, uuid));
|
||||
job.setDescription("Something");
|
||||
job.setLink(Collections.emptyList());
|
||||
return job;
|
||||
}
|
||||
|
||||
public static Job toJob(AsyncJobJoinVO vo) {
|
||||
Job job = new Job();
|
||||
final String basePath = VeeamControlService.ContextPath.value();
|
||||
|
|
|
|||
|
|
@ -23,9 +23,12 @@ import java.util.stream.Collectors;
|
|||
|
||||
import org.apache.cloudstack.backup.BackupVO;
|
||||
import org.apache.cloudstack.veeam.VeeamControlService;
|
||||
import org.apache.cloudstack.veeam.api.ApiRouteHandler;
|
||||
import org.apache.cloudstack.veeam.api.VmsRouteHandler;
|
||||
import org.apache.cloudstack.veeam.api.dto.Backup;
|
||||
import org.apache.cloudstack.veeam.api.dto.Disk;
|
||||
import org.apache.cloudstack.veeam.api.dto.Host;
|
||||
import org.apache.cloudstack.veeam.api.dto.NamedList;
|
||||
import org.apache.cloudstack.veeam.api.dto.Vm;
|
||||
|
||||
import com.cloud.api.query.vo.HostJoinVO;
|
||||
|
|
@ -55,6 +58,16 @@ public class BackupVOToBackupConverter {
|
|||
backup.setVm(Vm.of(basePath + VmsRouteHandler.BASE_ROUTE + "/" + vmVO.getUuid(), vmVO.getUuid()));
|
||||
}
|
||||
}
|
||||
if (backupVO.getHostId() != null && hostResolver != null) {
|
||||
final HostJoinVO hostVO = hostResolver.apply(backupVO.getHostId());
|
||||
if (hostVO != null) {
|
||||
backup.setHost(Host.of(basePath + ApiRouteHandler.BASE_ROUTE + "/" + hostVO.getUuid(), hostVO.getUuid()));
|
||||
}
|
||||
}
|
||||
if (disksResolver != null) {
|
||||
List<Disk> disks = disksResolver.apply(backupVO);
|
||||
backup.setDisks(NamedList.of("disks", disks));
|
||||
}
|
||||
return backup;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.apache.cloudstack.veeam.api.dto.Cpu;
|
|||
import org.apache.cloudstack.veeam.api.dto.Link;
|
||||
import org.apache.cloudstack.veeam.api.dto.Ref;
|
||||
import org.apache.cloudstack.veeam.api.dto.Version;
|
||||
import org.apache.cloudstack.veeam.api.dto.Vm;
|
||||
|
||||
import com.cloud.api.query.vo.DataCenterJoinVO;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
|
|
@ -39,19 +40,14 @@ public class ClusterVOToClusterConverter {
|
|||
public static Cluster toCluster(final ClusterVO vo, final Function<Long, DataCenterJoinVO> dataCenterResolver) {
|
||||
final Cluster c = new Cluster();
|
||||
final String basePath = VeeamControlService.ContextPath.value();
|
||||
|
||||
// NOTE: oVirt uses UUIDs. If your ClusterVO id is numeric, generate a stable UUID:
|
||||
// - Prefer: store a UUID in details table and reuse it
|
||||
// - Fallback: name-based UUID from "cluster:<id>"
|
||||
final String clusterId = vo.getUuid();
|
||||
c.setId(clusterId);
|
||||
c.setHref(basePath + ClustersRouteHandler.BASE_ROUTE + "/" + clusterId);
|
||||
|
||||
c.setName(vo.getName());
|
||||
|
||||
// --- sensible defaults (match your sample)
|
||||
c.setBallooningEnabled("true");
|
||||
c.setBiosType("q35_ovmf"); // or "q35_secure_boot" if you want to align with VM BIOS you saw
|
||||
c.setBiosType(Vm.Bios.getDefault().getType());
|
||||
c.setFipsMode("disabled");
|
||||
c.setFirewallType("firewalld");
|
||||
c.setGlusterService("false");
|
||||
|
|
@ -64,19 +60,14 @@ public class ClusterVOToClusterConverter {
|
|||
c.setUpgradePercentComplete("0");
|
||||
c.setVirtService("true");
|
||||
c.setVncEncryption("false");
|
||||
c.setLogMaxMemoryUsedThreshold("95");
|
||||
c.setLogMaxMemoryUsedThresholdType("percentage");
|
||||
|
||||
// --- cpu (best-effort defaults)
|
||||
final Cpu cpu = new Cpu();
|
||||
cpu.setArchitecture("x86_64");
|
||||
cpu.setType("x86_64"); // replace if you can detect host cpu model
|
||||
cpu.setArchitecture(vo.getArch().getType());
|
||||
cpu.setType(vo.getArch().getType()); // replace if you can detect host cpu model
|
||||
c.setCpu(cpu);
|
||||
|
||||
// --- version (ovirt engine version; keep fixed unless you want to expose something else)
|
||||
final Version ver = new Version();
|
||||
ver.setMajor("4");
|
||||
ver.setMinor("8");
|
||||
final Version ver = Version.fromPackageAndCSVersion(false);
|
||||
c.setVersion(ver);
|
||||
|
||||
// --- ksm / memory policy (defaults)
|
||||
|
|
|
|||
|
|
@ -52,12 +52,10 @@ public class DataCenterJoinVOToDataCenterConverter {
|
|||
dc.setQuotaMode("disabled");
|
||||
dc.setStorageFormat("v5");
|
||||
|
||||
// ---- Versions (static but valid) ----
|
||||
final Version v48 = new Version();
|
||||
v48.setMajor("4");
|
||||
v48.setMinor("8");
|
||||
dc.setVersion(v48);
|
||||
dc.setSupportedVersions(new SupportedVersions(List.of(v48)));
|
||||
// ---- Versions ----
|
||||
final Version ver = Version.fromPackageAndCSVersion(false);
|
||||
dc.setVersion(ver);
|
||||
dc.setSupportedVersions(new SupportedVersions(List.of(ver)));
|
||||
|
||||
// ---- mac_pool (static placeholder) ----
|
||||
dc.setMacPool(Ref.of(basePath + "/macpools/default", "default"));
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ public class HostJoinVOToHostConverter {
|
|||
/**
|
||||
* Convert CloudStack HostJoinVO -> oVirt-like Host.
|
||||
*
|
||||
* @param vo HostJoinVO from listHosts (join query)
|
||||
*/
|
||||
public static Host toHost(final HostJoinVO vo) {
|
||||
final Host h = new Host();
|
||||
|
|
@ -49,8 +48,6 @@ public class HostJoinVOToHostConverter {
|
|||
final String basePath = VeeamControlService.ContextPath.value();
|
||||
h.setHref(basePath + HostsRouteHandler.BASE_ROUTE + "/" + hostUuid);
|
||||
|
||||
// --- name / address ---
|
||||
// Prefer DNS name if set; otherwise fall back to IP
|
||||
final String name = vo.getName() != null ? vo.getName() : ("host-" + hostUuid);
|
||||
h.setName(name);
|
||||
|
||||
|
|
@ -75,9 +72,7 @@ public class HostJoinVOToHostConverter {
|
|||
h.setMemory(String.valueOf(vo.getTotalMemory()));
|
||||
h.setMaxSchedulingMemory(String.valueOf(vo.getTotalMemory() - vo.getMemUsedCapacity()));
|
||||
|
||||
// --- OS / versions (optional placeholders) ---
|
||||
// If you want, you can set conservative defaults to match oVirt shape.
|
||||
h.setType("rhel");
|
||||
h.setType("ovirt_node");
|
||||
h.setAutoNumaStatus("unknown");
|
||||
h.setKdumpStatus("disabled");
|
||||
h.setNumaSupported("false");
|
||||
|
|
@ -85,8 +80,6 @@ public class HostJoinVOToHostConverter {
|
|||
h.setUpdateAvailable("false");
|
||||
|
||||
|
||||
// --- links/actions ---
|
||||
// Start minimal (empty). Add actions only if Veeam tries to follow them.
|
||||
h.setActions(null);
|
||||
h.setLink(Collections.emptyList());
|
||||
|
||||
|
|
@ -98,13 +91,13 @@ public class HostJoinVOToHostConverter {
|
|||
}
|
||||
|
||||
private static String mapStatus(final HostJoinVO vo) {
|
||||
// CloudStack examples:
|
||||
// state: Up/Down/Maintenance/Error/Disconnected
|
||||
// status: Up/Down/Connecting/etc
|
||||
if (vo.isInMaintenanceStates()) return "maintenance";
|
||||
if (Status.Up.equals(vo.getStatus()) && ResourceState.Enabled.equals(vo.getResourceState())) return "up";
|
||||
|
||||
// Default
|
||||
if (vo.isInMaintenanceStates()) {
|
||||
return "maintenance";
|
||||
}
|
||||
if (Status.Up.equals(vo.getStatus()) &&
|
||||
ResourceState.Enabled.equals(vo.getResourceState())) {
|
||||
return "up";
|
||||
}
|
||||
return "down";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ public class NetworkVOToNetworkConverter {
|
|||
// Best-effort mapping for vdsm_name
|
||||
dto.setVdsmName(dto.getName());
|
||||
|
||||
// zone -> oVirt datacenter ref
|
||||
if (dcResolver != null) {
|
||||
final DataCenterJoinVO dc = dcResolver.apply(vo.getDataCenterId());
|
||||
if (dc != null) {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ public class NetworkVOToVnicProfileConverter {
|
|||
vnicProfile.setNetwork(Ref.of(basePath + NetworksRouteHandler.BASE_ROUTE + "/" + networkUuid, networkUuid));
|
||||
vnicProfile.setDescription(vo.getDisplayText());
|
||||
|
||||
// zone -> oVirt datacenter ref
|
||||
if (dcResolver != null) {
|
||||
final DataCenterJoinVO dc = dcResolver.apply(vo.getDataCenterId());
|
||||
if (dc != null) {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ import com.cloud.network.dao.NetworkVO;
|
|||
import com.cloud.vm.NicVO;
|
||||
|
||||
public class NicVOToNicConverter {
|
||||
private static final String DEFAULT_INTERFACE_TYPE = "virtio";
|
||||
private static final String DEFAULT_REPORTED_DEVICE_NAME = "eth0";
|
||||
|
||||
public static Nic toNic(final NicVO vo, final String vmUuid, final Function<Long, NetworkVO> networkResolver) {
|
||||
final String basePath = VeeamControlService.ContextPath.value();
|
||||
|
|
@ -56,7 +58,7 @@ public class NicVOToNicConverter {
|
|||
nic.setVm(vm);
|
||||
nic.setHref(vm.getHref() + "/nics/" + vo.getUuid());
|
||||
}
|
||||
nic.setInterfaceType("virtio");
|
||||
nic.setInterfaceType(DEFAULT_INTERFACE_TYPE);
|
||||
ReportedDevice device = getReportedDevice(vo, mac, nic.getVm());
|
||||
nic.setReportedDevices(NamedList.of("reported_device", List.of(device)));
|
||||
if (networkResolver != null) {
|
||||
|
|
@ -73,7 +75,7 @@ public class NicVOToNicConverter {
|
|||
ReportedDevice device = new ReportedDevice();
|
||||
device.setType("network");
|
||||
device.setId(vo.getUuid());
|
||||
device.setName("eth0");
|
||||
device.setName(DEFAULT_REPORTED_DEVICE_NAME);
|
||||
device.setDescription(String.format("%s device", vo.getReserver()));
|
||||
device.setMac(mac);
|
||||
if (ObjectUtils.anyNotNull(vo.getIPv4Address(), vo.getIPv6Address())) {
|
||||
|
|
|
|||
|
|
@ -48,10 +48,11 @@ public class ResourceTagVOToTagConverter {
|
|||
public static Tag toTag(ResourceTagVO vo) {
|
||||
String basePath = VeeamControlService.ContextPath.value();
|
||||
Tag tag = new Tag();
|
||||
tag.setId(vo.getUuid());
|
||||
tag.setName(String.format("%s-%s", vo.getKey(), vo.getValue()).replaceAll("\\s+", ""));
|
||||
String id = vo.getValue();
|
||||
tag.setId(id);
|
||||
tag.setName(vo.getValue());
|
||||
tag.setDescription(String.format("Tag %s with value: %s", vo.getKey(), vo.getValue()));
|
||||
tag.setHref(basePath + TagsRouteHandler.BASE_ROUTE + "/" + vo.getUuid());
|
||||
tag.setHref(basePath + TagsRouteHandler.BASE_ROUTE + "/" + id);
|
||||
if (ResourceTag.ResourceObjectType.UserVm.equals(vo.getResourceType())) {
|
||||
tag.setVm(Ref.of(basePath + VmsRouteHandler.BASE_ROUTE + "/" + vo.getResourceUuid(),
|
||||
vo.getResourceUuid()));
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.cloudstack.veeam.VeeamControlService;
|
||||
import org.apache.cloudstack.veeam.api.ApiService;
|
||||
import org.apache.cloudstack.veeam.api.ApiRouteHandler;
|
||||
import org.apache.cloudstack.veeam.api.DataCentersRouteHandler;
|
||||
import org.apache.cloudstack.veeam.api.dto.DataCenter;
|
||||
import org.apache.cloudstack.veeam.api.dto.Link;
|
||||
|
|
@ -42,7 +42,7 @@ public class StoreVOToStorageDomainConverter {
|
|||
|
||||
StorageDomain sd = new StorageDomain();
|
||||
sd.setId(id);
|
||||
final String href = href(basePath, ApiService.BASE_ROUTE + "/storagedomains/" + id);
|
||||
final String href = href(basePath, ApiRouteHandler.BASE_ROUTE + "/storagedomains/" + id);
|
||||
sd.setHref(href);
|
||||
|
||||
sd.setName(pool.getName());
|
||||
|
|
@ -96,7 +96,7 @@ public class StoreVOToStorageDomainConverter {
|
|||
|
||||
StorageDomain sd = new StorageDomain();
|
||||
sd.setId(id);
|
||||
final String href = href(basePath, ApiService.BASE_ROUTE + "/storagedomains/" + id);
|
||||
final String href = href(basePath, ApiRouteHandler.BASE_ROUTE + "/storagedomains/" + id);
|
||||
sd.setHref(href);
|
||||
|
||||
sd.setName(store.getName());
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.veeam.VeeamControlService;
|
||||
import org.apache.cloudstack.veeam.api.ApiService;
|
||||
import org.apache.cloudstack.veeam.api.ApiRouteHandler;
|
||||
import org.apache.cloudstack.veeam.api.VmsRouteHandler;
|
||||
import org.apache.cloudstack.veeam.api.dto.BaseDto;
|
||||
import org.apache.cloudstack.veeam.api.dto.Cpu;
|
||||
|
|
@ -54,7 +54,6 @@ public final class UserVmJoinVOToVmConverter {
|
|||
/**
|
||||
* Convert CloudStack UserVmJoinVO -> oVirt-like Vm DTO.
|
||||
*
|
||||
* @param src UserVmJoinVO
|
||||
*/
|
||||
public static Vm toVm(final UserVmJoinVO src,
|
||||
final Function<Long, HostJoinVO> hostResolver,
|
||||
|
|
@ -84,7 +83,7 @@ public final class UserVmJoinVOToVmConverter {
|
|||
dst.setStartTime(lastUpdated.getTime());
|
||||
}
|
||||
final Ref template = buildRef(
|
||||
basePath + ApiService.BASE_ROUTE,
|
||||
basePath + ApiRouteHandler.BASE_ROUTE,
|
||||
"templates",
|
||||
src.getTemplateUuid()
|
||||
);
|
||||
|
|
@ -92,20 +91,19 @@ public final class UserVmJoinVOToVmConverter {
|
|||
dst.setOriginalTemplate(template);
|
||||
if (StringUtils.isNotBlank(src.getHostUuid())) {
|
||||
dst.setHost(buildRef(
|
||||
basePath + ApiService.BASE_ROUTE,
|
||||
basePath + ApiRouteHandler.BASE_ROUTE,
|
||||
"hosts",
|
||||
src.getHostUuid()));
|
||||
|
||||
}
|
||||
if (hostResolver != null) {
|
||||
HostJoinVO hostVo = hostResolver.apply(src.getHostId() == null ? src.getLastHostId() : src.getHostId());
|
||||
if (hostVo != null) {
|
||||
dst.setHost(buildRef(
|
||||
basePath + ApiService.BASE_ROUTE,
|
||||
basePath + ApiRouteHandler.BASE_ROUTE,
|
||||
"hosts",
|
||||
hostVo.getUuid()));
|
||||
dst.setCluster(buildRef(
|
||||
basePath + ApiService.BASE_ROUTE,
|
||||
basePath + ApiRouteHandler.BASE_ROUTE,
|
||||
"clusters",
|
||||
hostVo.getClusterUuid()));
|
||||
}
|
||||
|
|
@ -123,9 +121,7 @@ public final class UserVmJoinVOToVmConverter {
|
|||
cpu.setTopology(new Topology(src.getCpu(), 1, 1));
|
||||
dst.setCpu(cpu);
|
||||
Os os = new Os();
|
||||
os.setType(src.getGuestOsId() % 2 == 0
|
||||
? "windows"
|
||||
: "linux");
|
||||
os.setType(src.getGuestOsDisplayName());
|
||||
Os.Boot boot = new Os.Boot();
|
||||
boot.setDevices(NamedList.of("device", List.of("hd")));
|
||||
os.setBoot(boot);
|
||||
|
|
@ -167,7 +163,7 @@ public final class UserVmJoinVOToVmConverter {
|
|||
dst.setTags(NamedList.of("tag", tags));
|
||||
}
|
||||
dst.setCpuProfile(Ref.of(
|
||||
basePath + ApiService.BASE_ROUTE + "/cpuprofiles/" + src.getServiceOfferingUuid(),
|
||||
basePath + ApiRouteHandler.BASE_ROUTE + "/cpuprofiles/" + src.getServiceOfferingUuid(),
|
||||
src.getServiceOfferingUuid()));
|
||||
if (allContent) {
|
||||
dst.setInitialization(getOvfInitialization(dst, src));
|
||||
|
|
@ -204,9 +200,10 @@ public final class UserVmJoinVOToVmConverter {
|
|||
}
|
||||
|
||||
private static String mapStatus(final VirtualMachine.State state) {
|
||||
// CloudStack-ish states -> oVirt-ish up/down
|
||||
if (Arrays.asList(VirtualMachine.State.Running,
|
||||
VirtualMachine.State.Migrating, VirtualMachine.State.Restoring).contains(state)) {
|
||||
if (Arrays.asList(
|
||||
VirtualMachine.State.Running,
|
||||
VirtualMachine.State.Migrating,
|
||||
VirtualMachine.State.Restoring).contains(state)) {
|
||||
return "up";
|
||||
}
|
||||
return "down";
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.veeam.VeeamControlService;
|
||||
import org.apache.cloudstack.veeam.api.ApiService;
|
||||
import org.apache.cloudstack.veeam.api.ApiRouteHandler;
|
||||
import org.apache.cloudstack.veeam.api.DisksRouteHandler;
|
||||
import org.apache.cloudstack.veeam.api.VmsRouteHandler;
|
||||
import org.apache.cloudstack.veeam.api.dto.Disk;
|
||||
|
|
@ -43,7 +43,7 @@ public class VolumeJoinVOToDiskConverter {
|
|||
public static Disk toDisk(final VolumeJoinVO vol, final Function<VolumeJoinVO, Long> physicalSizeResolver) {
|
||||
final Disk disk = new Disk();
|
||||
final String basePath = VeeamControlService.ContextPath.value();
|
||||
final String apiBasePath = basePath + ApiService.BASE_ROUTE;
|
||||
final String apiBasePath = basePath + ApiRouteHandler.BASE_ROUTE;
|
||||
final String diskId = vol.getUuid();
|
||||
final String diskHref = basePath + DisksRouteHandler.BASE_ROUTE + "/" + diskId;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,11 @@ public class Backup extends BaseDto {
|
|||
private String description;
|
||||
private Long creationDate;
|
||||
private Vm vm;
|
||||
private Host host;
|
||||
private String phase;
|
||||
private String fromCheckpointId;
|
||||
private String toCheckpointId;
|
||||
private NamedList<Disk> disks;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
@ -59,6 +61,14 @@ public class Backup extends BaseDto {
|
|||
this.vm = vm;
|
||||
}
|
||||
|
||||
public Host getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(Host host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public String getPhase() {
|
||||
return phase;
|
||||
}
|
||||
|
|
@ -82,4 +92,12 @@ public class Backup extends BaseDto {
|
|||
public void setToCheckpointId(String toCheckpointId) {
|
||||
this.toCheckpointId = toCheckpointId;
|
||||
}
|
||||
|
||||
public NamedList<Disk> getDisks() {
|
||||
return disks;
|
||||
}
|
||||
|
||||
public void setDisks(NamedList<Disk> disks) {
|
||||
this.disks = disks;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,4 +46,10 @@ public class BaseDto {
|
|||
public static Link getActionLink(final String action, final String baseHref) {
|
||||
return Link.of(action, baseHref + "/" + action);
|
||||
}
|
||||
|
||||
protected static <T extends BaseDto> T withHrefAndId(T dto, String href, String id) {
|
||||
dto.setHref(href);
|
||||
dto.setId(id);
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -308,4 +308,8 @@ public class Host extends BaseDto {
|
|||
this.version = version;
|
||||
}
|
||||
}
|
||||
|
||||
public static Host of(String href, String id) {
|
||||
return withHrefAndId(new Host(), href, id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
package org.apache.cloudstack.veeam.api.dto;
|
||||
|
||||
import org.apache.cloudstack.utils.CloudStackVersion;
|
||||
import org.apache.cloudstack.veeam.VeeamControlService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
|
|
@ -70,4 +74,21 @@ public final class Version {
|
|||
public void setRevision(String revision) {
|
||||
this.revision = revision;
|
||||
}
|
||||
|
||||
public static Version fromPackageAndCSVersion(boolean complete) {
|
||||
Version version = new Version();
|
||||
String packageVersion = VeeamControlService.getPackageVersion();
|
||||
if (StringUtils.isNotBlank(packageVersion) && complete) {
|
||||
version.setFullVersion(packageVersion);
|
||||
}
|
||||
CloudStackVersion csVersion = VeeamControlService.getCSVersion();
|
||||
if (csVersion == null) {
|
||||
return version;
|
||||
}
|
||||
version.setMajor(String.valueOf(csVersion.getMajorRelease()));
|
||||
version.setMinor(String.valueOf(csVersion.getMinorRelease()));
|
||||
version.setBuild(String.valueOf(csVersion.getPatchRelease()));
|
||||
version.setRevision(String.valueOf(csVersion.getSecurityRelease()));
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -513,9 +513,6 @@ public final class Vm extends BaseDto {
|
|||
}
|
||||
|
||||
public static Vm of(String href, String id) {
|
||||
Vm vm = new Vm();
|
||||
vm.setHref(href);
|
||||
vm.setId(id);
|
||||
return vm;
|
||||
return withHrefAndId(new Vm(), href, id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.veeam.api.response;
|
||||
|
||||
import org.apache.cloudstack.veeam.api.dto.Fault;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@JacksonXmlRootElement(localName = "fault")
|
||||
public final class FaultResponse {
|
||||
public Fault fault;
|
||||
|
||||
public FaultResponse() {}
|
||||
|
||||
public FaultResponse(final Fault fault) {
|
||||
this.fault = fault;
|
||||
}
|
||||
|
||||
public static FaultResponse of(final String reason, final String detail) {
|
||||
return new FaultResponse(new Fault(reason, detail));
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import com.cloud.utils.UuidUtils;
|
||||
|
||||
public class PathUtil {
|
||||
private static final boolean CONSIDER_ONLY_UUID_AS_ID = false;
|
||||
|
||||
public static List<String> extractIdAndSubPath(final String path, final String baseRoute) {
|
||||
|
||||
|
|
@ -65,7 +66,7 @@ public class PathUtil {
|
|||
}
|
||||
|
||||
// Validate first segment is a UUID
|
||||
if (validParts.isEmpty() || !UuidUtils.isUuid(validParts.get(0))) {
|
||||
if (validParts.isEmpty() || (CONSIDER_ONLY_UUID_AS_ID && !UuidUtils.isUuid(validParts.get(0)))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import java.nio.charset.StandardCharsets;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.cloudstack.veeam.api.dto.Fault;
|
||||
import org.apache.cloudstack.veeam.api.response.FaultResponse;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
|
@ -78,7 +77,7 @@ public final class ResponseWriter {
|
|||
if (fmt == Negotiation.OutFormat.XML) {
|
||||
write(resp, status, fault, fmt);
|
||||
} else {
|
||||
write(resp, status, new FaultResponse(fault), fmt);
|
||||
write(resp, status, fault, fmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<bean id="veeamControlSsoService" class="org.apache.cloudstack.veeam.sso.SsoService"/>
|
||||
<bean id="pkiResourceRouteHandler" class="org.apache.cloudstack.veeam.services.PkiResourceRouteHandler"/>
|
||||
<bean id="veeamControlApiService" class="org.apache.cloudstack.veeam.api.ApiService" />
|
||||
<bean id="apiRouteHandler" class="org.apache.cloudstack.veeam.api.ApiRouteHandler" />
|
||||
<bean id="dataCentersRouteHandler" class="org.apache.cloudstack.veeam.api.DataCentersRouteHandler"/>
|
||||
<bean id="clustersRouteHandler" class="org.apache.cloudstack.veeam.api.ClustersRouteHandler"/>
|
||||
<bean id="hostsRouteHandler" class="org.apache.cloudstack.veeam.api.HostsRouteHandler"/>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,21 @@
|
|||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ovf:Envelope
|
||||
xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1/"
|
||||
|
|
@ -131,6 +131,9 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
|||
@Column(name = "guest_os_uuid")
|
||||
private String guestOsUuid;
|
||||
|
||||
@Column(name = "guest_os_display_name")
|
||||
private String guestOsDisplayName;
|
||||
|
||||
@Column(name = "hypervisor_type")
|
||||
@Convert(converter = HypervisorTypeConverter.class)
|
||||
private HypervisorType hypervisorType;
|
||||
|
|
@ -612,6 +615,10 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
|||
return guestOsUuid;
|
||||
}
|
||||
|
||||
public String getGuestOsDisplayName() {
|
||||
return guestOsDisplayName;
|
||||
}
|
||||
|
||||
public HypervisorType getHypervisorType() {
|
||||
return hypervisorType;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue