fix vms listing with tags, effectively tagged jobs

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
Abhishek Kumar 2026-04-09 11:12:17 +05:30
parent b7f8fa365d
commit 259ba31e90
5 changed files with 63 additions and 38 deletions

View File

@ -973,12 +973,19 @@ public class ServerAdapter extends ManagerBase {
}
@ApiAccess(command = ListVMsCmd.class)
public List<Vm> listAllInstances(Long offset, Long limit) {
public List<Vm> listAllInstances(boolean includeTags, boolean includeDisks, boolean includeNics,
boolean allContent, Long offset, Long limit) {
Filter filter = new Filter(UserVmJoinVO.class, "id", true, offset, limit);
Pair<List<Long>, String> ownerDetails = getResourceOwnerFilters();
List<UserVmJoinVO> vms = userVmJoinDao.listByHypervisorTypeAndOwners(Hypervisor.HypervisorType.KVM,
ownerDetails.first(), ownerDetails.second(), filter);
return UserVmJoinVOToVmConverter.toVmList(vms, this::getHostById, this::getDetailsByInstanceId);
return UserVmJoinVOToVmConverter.toVmList(vms,
this::getHostById,
this::getDetailsByInstanceId,
includeTags ? this::listTagsByInstanceId : null,
includeDisks ? this::listDiskAttachmentsByInstanceId : null,
includeNics ? this::listNicsByInstance : null,
allContent);
}
@ApiAccess(command = ListVMsCmd.class)
@ -988,7 +995,8 @@ public class ServerAdapter extends ManagerBase {
if (vo == null) {
throw new InvalidParameterValueException("VM with ID " + uuid + " not found");
}
return UserVmJoinVOToVmConverter.toVm(vo, this::getHostById,
return UserVmJoinVOToVmConverter.toVm(vo,
this::getHostById,
this::getDetailsByInstanceId,
includeTags ? this::listTagsByInstanceId : null,
includeDisks ? this::listDiskAttachmentsByInstanceId : null,

View File

@ -122,7 +122,7 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
throws IOException {
try {
ListQuery query = ListQuery.fromRequest(req);
List<StorageDomain> storageDomains = serverAdapter.listStorageDomainsByDcId(id, query.getPage(),
List<StorageDomain> storageDomains = serverAdapter.listStorageDomainsByDcId(id, query.getOffset(),
query.getMax());
NamedList<StorageDomain> response = NamedList.of("storage_domain", storageDomains);
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
@ -138,7 +138,7 @@ public class DataCentersRouteHandler extends ManagerBase implements RouteHandler
throws IOException {
try {
ListQuery query = ListQuery.fromRequest(req);
List<Network> networks = serverAdapter.listNetworksByDcId(id, query.getPage(),
List<Network> networks = serverAdapter.listNetworksByDcId(id, query.getOffset(),
query.getMax());
NamedList<Network> response = NamedList.of("network", networks);
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);

View File

@ -19,7 +19,6 @@ package org.apache.cloudstack.veeam.api;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
@ -42,7 +41,6 @@ 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 org.apache.commons.lang3.StringUtils;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.component.ManagerBase;
@ -233,7 +231,12 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
try {
ListQuery query = ListQuery.fromRequest(req);
final List<Vm> result = serverAdapter.listAllInstances(query.getOffset(), query.getLimit());
final List<Vm> result = serverAdapter.listAllInstances(query.followContains("tags"),
query.followContains("disk_attachments.disk"),
query.followContains("nics.reporteddevices"),
query.isAllContent(),
query.getOffset(),
query.getLimit());
NamedList<Vm> response = NamedList.of("vm", result);
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
} catch (CloudRuntimeException e) {
@ -255,22 +258,13 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
protected void handleGetById(final String id, final HttpServletRequest req, final HttpServletResponse resp,
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
String followStr = req.getParameter("follow");
boolean includeTags = false;
boolean includeDisks = false;
boolean includeNics = false;
if (StringUtils.isNotBlank(followStr)) {
Set<String> followParts = java.util.Arrays.stream(followStr.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(java.util.stream.Collectors.toSet());
includeTags = followParts.contains("tags");
includeDisks = followParts.contains("disk_attachments.disk");
includeNics = followParts.contains("nics.reporteddevices");
}
boolean allContent = Boolean.parseBoolean(req.getParameter("all_content"));
try {
Vm response = serverAdapter.getInstance(id, includeTags, includeDisks, includeNics, allContent);
ListQuery query = ListQuery.fromRequest(req);
Vm response = serverAdapter.getInstance(id,
query.followContains("tags"),
query.followContains("disk_attachments.disk"),
query.followContains("nics.reporteddevices"),
query.isAllContent());
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
} catch (InvalidParameterValueException e) {
io.notFound(resp, e.getMessage(), outFormat);

View File

@ -56,12 +56,13 @@ public final class UserVmJoinVOToVmConverter {
*
* @param src UserVmJoinVO
*/
public static Vm toVm(final UserVmJoinVO src, final Function<Long, HostJoinVO> hostResolver,
final Function<Long, Map<String, String>> detailsResolver,
final Function<Long, List<Tag>> tagsResolver,
final Function<Long, List<DiskAttachment>> disksResolver,
final Function<UserVmJoinVO, List<Nic>> nicsResolver,
final boolean allContent) {
public static Vm toVm(final UserVmJoinVO src,
final Function<Long, HostJoinVO> hostResolver,
final Function<Long, Map<String, String>> detailsResolver,
final Function<Long, List<Tag>> tagsResolver,
final Function<Long, List<DiskAttachment>> disksResolver,
final Function<UserVmJoinVO, List<Nic>> nicsResolver,
final boolean allContent) {
if (src == null) {
return null;
}
@ -190,10 +191,15 @@ public final class UserVmJoinVOToVmConverter {
return initialization;
}
public static List<Vm> toVmList(final List<UserVmJoinVO> srcList, final Function<Long, HostJoinVO> hostResolver,
final Function<Long, Map<String, String>> detailsResolver) {
public static List<Vm> toVmList(final List<UserVmJoinVO> srcList,
final Function<Long, HostJoinVO> hostResolver,
final Function<Long, Map<String, String>> detailsResolver,
final Function<Long, List<Tag>> tagsResolver,
final Function<Long, List<DiskAttachment>> disksResolver,
final Function<UserVmJoinVO, List<Nic>> nicsResolver,
final boolean allContent) {
return srcList.stream()
.map(v -> toVm(v, hostResolver, detailsResolver, null, null, null, false))
.map(v -> toVm(v, hostResolver, detailsResolver, tagsResolver, disksResolver, nicsResolver, allContent))
.collect(Collectors.toList());
}

View File

@ -17,11 +17,15 @@
package org.apache.cloudstack.veeam.api.request;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
@ -31,6 +35,7 @@ public class ListQuery {
Long max;
Long page;
Map<String, String> search;
List<String> follow;
public boolean isAllContent() {
return allContent;
@ -48,16 +53,19 @@ public class ListQuery {
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 void setFollow(String followStr) {
if (StringUtils.isBlank(followStr)) {
this.follow = null;
return;
}
this.follow = Arrays.stream(followStr.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(Collectors.toList());
}
public Long getOffset() {
@ -71,6 +79,13 @@ public class ListQuery {
return max;
}
public boolean followContains(String part) {
if (CollectionUtils.isEmpty(follow)) {
return false;
}
return follow.contains(part);
}
public static ListQuery fromRequest(HttpServletRequest request) {
ListQuery query = new ListQuery();
if (MapUtils.isEmpty(request.getParameterMap())) {
@ -89,6 +104,8 @@ public class ListQuery {
// Ignore invalid max and keep default null value.
}
}
String follow = request.getParameter("follow");
query.setFollow(follow);
Map<String, String> searchItems = getSearchMap(request.getParameter("search"));
if (!searchItems.isEmpty()) {
try {