Skip to content

Commit 2f67356

Browse files
committed
cleanup; return tags with specific key only
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent d804b75 commit 2f67356

33 files changed

+229
-220
lines changed

engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagDao.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ public interface ResourceTagDao extends GenericDao<ResourceTagVO, Long> {
6363

6464
List<? extends ResourceTag> listByResourceUuid(String resourceUuid);
6565

66-
List<ResourceTagVO> listByResourceTypeAndOwners(ResourceObjectType resourceType, List<Long> accountIds,
67-
List<Long> domainIds, Filter filter);
66+
List<ResourceTagVO> listByResourceTypeKeyAndOwners(ResourceObjectType resourceType, String key,
67+
List<Long> accountIds, List<Long> domainIds, Filter filter);
68+
69+
ResourceTagVO findByResourceTypeKeyAndValue(ResourceObjectType resourceType, String key, String value);
6870
}

engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagsDaoImpl.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,12 @@ public List<? extends ResourceTag> listByResourceUuid(String resourceUuid) {
124124
}
125125

126126
@Override
127-
public List<ResourceTagVO> listByResourceTypeAndOwners(ResourceObjectType resourceType, List<Long> accountIds,
128-
List<Long> domainIds, Filter filter) {
127+
public List<ResourceTagVO> listByResourceTypeKeyAndOwners(ResourceObjectType resourceType, String key,
128+
List<Long> accountIds, List<Long> domainIds,
129+
Filter filter) {
129130
SearchBuilder<ResourceTagVO> sb = createSearchBuilder();
130131
sb.and("resourceType", sb.entity().getResourceType(), Op.EQ);
132+
sb.and("key", sb.entity().getKey(), Op.EQ);
131133
boolean accountIdsNotEmpty = CollectionUtils.isNotEmpty(accountIds);
132134
boolean domainIdsNotEmpty = CollectionUtils.isNotEmpty(domainIds);
133135
if (accountIdsNotEmpty || domainIdsNotEmpty) {
@@ -136,8 +138,9 @@ public List<ResourceTagVO> listByResourceTypeAndOwners(ResourceObjectType resour
136138
sb.cp();
137139
}
138140
sb.done();
139-
final SearchCriteria<ResourceTagVO> sc = sb.create();;
141+
final SearchCriteria<ResourceTagVO> sc = sb.create();
140142
sc.setParameters("resourceType", resourceType);
143+
sc.setParameters("key", key);
141144
if (accountIdsNotEmpty) {
142145
sc.setParameters("account", accountIds.toArray());
143146
}
@@ -146,4 +149,19 @@ public List<ResourceTagVO> listByResourceTypeAndOwners(ResourceObjectType resour
146149
}
147150
return listBy(sc, filter);
148151
}
152+
153+
@Override
154+
public ResourceTagVO findByResourceTypeKeyAndValue(ResourceObjectType resourceType, String key,
155+
String value) {
156+
SearchBuilder<ResourceTagVO> sb = createSearchBuilder();
157+
sb.and("resourceType", sb.entity().getResourceType(), Op.EQ);
158+
sb.and("key", sb.entity().getKey(), Op.EQ);
159+
sb.and("value", sb.entity().getValue(), Op.EQ);
160+
sb.done();
161+
final SearchCriteria<ResourceTagVO> sc = sb.create();
162+
sc.setParameters("resourceType", resourceType);
163+
sc.setParameters("key", key);
164+
sc.setParameters("value", value);
165+
return findOneBy(sc);
166+
}
149167
}

engine/schema/src/main/resources/META-INF/db/views/cloud.user_vm_view.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ SELECT
5656
`vm_instance`.`display_vm` AS `display_vm`,
5757
`vm_instance`.`delete_protection` AS `delete_protection`,
5858
`guest_os`.`uuid` AS `guest_os_uuid`,
59+
`guest_os`.`display_name` AS `guest_os_display_name`,
5960
`vm_instance`.`pod_id` AS `pod_id`,
6061
`host_pod_ref`.`uuid` AS `pod_uuid`,
6162
`vm_instance`.`private_ip_address` AS `private_ip_address`,

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/RouteHandler.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import java.io.BufferedReader;
2121
import java.io.IOException;
22-
import java.util.regex.Pattern;
2322

2423
import javax.servlet.http.HttpServletRequest;
2524
import javax.servlet.http.HttpServletResponse;
@@ -30,7 +29,6 @@
3029
import com.cloud.utils.component.Adapter;
3130

3231
public interface RouteHandler extends Adapter {
33-
static final Pattern PAGE_PATTERN = Pattern.compile("\\bpage\\s+(\\d+)");
3432
default int priority() { return 0; }
3533
boolean canHandle(String method, String path) throws IOException;
3634
void handle(HttpServletRequest req, HttpServletResponse resp, String path, Negotiation.OutFormat outFormat, VeeamControlServlet io)
@@ -60,7 +58,6 @@ static String getRequestData(HttpServletRequest req) {
6058
if (!"application/json".equals(mime) && !"application/x-www-form-urlencoded".equals(mime)) {
6159
return null;
6260
}
63-
String result = null;
6461
try {
6562
StringBuilder data = new StringBuilder();
6663
String line;
@@ -74,4 +71,9 @@ static String getRequestData(HttpServletRequest req) {
7471
return null;
7572
}
7673
}
74+
75+
static boolean isRequestAsync(HttpServletRequest req) {
76+
String asyncStr = req.getParameter("async");
77+
return Boolean.TRUE.toString().equals(asyncStr);
78+
}
7779
}

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/VeeamControlServer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import javax.servlet.http.HttpServletRequest;
2929

3030
import org.apache.cloudstack.utils.server.ServerPropertiesUtil;
31-
import org.apache.cloudstack.veeam.api.ApiService;
31+
import org.apache.cloudstack.veeam.api.ApiRouteHandler;
3232
import org.apache.cloudstack.veeam.filter.AllowedClientCidrsFilter;
3333
import org.apache.cloudstack.veeam.filter.BearerOrBasicAuthFilter;
3434
import org.apache.commons.lang3.StringUtils;
@@ -125,12 +125,12 @@ public void startIfEnabled() throws Exception {
125125
// CIDR filter for all routes
126126
AllowedClientCidrsFilter cidrFilter = new AllowedClientCidrsFilter(veeamControlService);
127127
FilterHolder cidrHolder = new FilterHolder(cidrFilter);
128-
ctx.addFilter(cidrHolder, ApiService.BASE_ROUTE + "/*", EnumSet.of(DispatcherType.REQUEST));
128+
ctx.addFilter(cidrHolder, ApiRouteHandler.BASE_ROUTE + "/*", EnumSet.of(DispatcherType.REQUEST));
129129

130130
// Bearer or Basic Auth for all routes
131131
BearerOrBasicAuthFilter authFilter = new BearerOrBasicAuthFilter(veeamControlService);
132132
FilterHolder authHolder = new FilterHolder(authFilter);
133-
ctx.addFilter(authHolder, ApiService.BASE_ROUTE + "/*", EnumSet.of(DispatcherType.REQUEST));
133+
ctx.addFilter(authHolder, ApiRouteHandler.BASE_ROUTE + "/*", EnumSet.of(DispatcherType.REQUEST));
134134

135135
// Front controller servlet
136136
ctx.addServlet(new ServletHolder(new VeeamControlServlet(routeHandlers)), "/*");

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/VeeamControlService.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@
2121

2222
import org.apache.cloudstack.framework.config.ConfigKey;
2323
import org.apache.cloudstack.framework.config.Configurable;
24+
import org.apache.cloudstack.utils.CloudStackVersion;
2425

2526
import com.cloud.utils.component.PluggableService;
2627

2728
public interface VeeamControlService extends PluggableService, Configurable {
29+
String PLUGIN_NAME = "CloudStack Veeam Control Service";
30+
2831
ConfigKey<Boolean> Enabled = new ConfigKey<>("Advanced", Boolean.class, "integration.veeam.control.enabled",
2932
"false", "Enable the Veeam Integration REST API server", false);
3033
ConfigKey<String> BindAddress = new ConfigKey<>("Advanced", String.class, "integration.veeam.control.bind.address",
@@ -57,4 +60,16 @@ public interface VeeamControlService extends PluggableService, Configurable {
5760
List<String> getAllowedClientCidrs();
5861

5962
boolean validateCredentials(String username, String password);
63+
64+
static String getPackageVersion() {
65+
return VeeamControlService.class.getPackage().getImplementationVersion();
66+
}
67+
68+
static CloudStackVersion getCSVersion() {
69+
try {
70+
return CloudStackVersion.parse(getPackageVersion());
71+
} catch (Exception e) {
72+
return null;
73+
}
74+
}
6075
}

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/VeeamControlServlet.java

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,19 +101,6 @@ private static void logRequest(HttpServletRequest req, String method, String pat
101101
String name = headerNames.nextElement();
102102
details.append(name).append("=").append(req.getHeader(name)).append("; ");
103103
}
104-
// String body = "";
105-
// if (!"GET".equalsIgnoreCase(method)) {
106-
// StringBuilder bodySb = new StringBuilder();
107-
// java.io.BufferedReader reader = req.getReader();
108-
// if (reader != null) {
109-
// String line;
110-
// while ((line = reader.readLine()) != null) {
111-
// bodySb.append(line).append('\n');
112-
// }
113-
// }
114-
// body = bodySb.toString().trim();
115-
// }
116-
// details.append(", Body: ").append(body);
117104
LOGGER.debug(details.toString());
118105
} catch (Exception e) {
119106
LOGGER.debug("Failed to capture request details", e);
@@ -135,8 +122,8 @@ protected void handleRoot(HttpServletRequest req, HttpServletResponse resp, Nego
135122
}
136123

137124
writer.write(resp, 200, Map.of(
138-
"name", "CloudStack Veeam Control Service",
139-
"pluginVersion", "0.1"), outFormat);
125+
"name", VeeamControlService.PLUGIN_NAME,
126+
"pluginVersion", this.getClass().getPackage().getImplementationVersion()), outFormat);
140127
}
141128

142129
public void methodNotAllowed(final HttpServletResponse resp, final String allow, final Negotiation.OutFormat outFormat) throws IOException {

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/adapter/ServerAdapter.java

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ public class ServerAdapter extends ManagerBase {
238238
Storage.StoragePoolType.NetworkFilesystem,
239239
Storage.StoragePoolType.SharedMountPoint
240240
);
241-
public static final String WORKER_VM_GUEST_CPU_MODE = "host-passthrough";
241+
private static final String VM_TA_KEY = "veeam_tag";
242+
private static final String WORKER_VM_GUEST_CPU_MODE = "host-passthrough";
242243

243244
@Inject
244245
RoleService roleService;
@@ -413,22 +414,6 @@ protected Pair<User, Account> getDefaultServiceAccount() {
413414
accountService.getActiveAccountById(userAccount.getAccountId()));
414415
}
415416

416-
protected Pair<User, Account> getServiceAccount() {
417-
String serviceAccountUuid = VeeamControlService.ServiceAccountId.value();
418-
if (StringUtils.isEmpty(serviceAccountUuid)) {
419-
throw new CloudRuntimeException("Service account is not configured, unable to proceed");
420-
}
421-
Account account = accountService.getActiveAccountByUuid(serviceAccountUuid);
422-
if (account == null) {
423-
throw new CloudRuntimeException("Service account with ID " + serviceAccountUuid + " not found, unable to proceed");
424-
}
425-
User user = accountService.getOneActiveUserForAccount(account);
426-
if (user == null) {
427-
throw new CloudRuntimeException("No active user found for service account with ID " + serviceAccountUuid);
428-
}
429-
return new Pair<>(user, account);
430-
}
431-
432417
protected void waitForJobCompletion(long jobId) {
433418
long timeoutNanos = TimeUnit.MINUTES.toNanos(5);
434419
final long deadline = System.nanoTime() + timeoutNanos;
@@ -858,6 +843,22 @@ protected Map<String, String> getDetailsByInstanceId(Long instanceId) {
858843
return vmInstanceDetailsDao.listDetailsKeyPairs(instanceId, true);
859844
}
860845

846+
public Pair<User, Account> getServiceAccount() {
847+
String serviceAccountUuid = VeeamControlService.ServiceAccountId.value();
848+
if (StringUtils.isEmpty(serviceAccountUuid)) {
849+
throw new CloudRuntimeException("Service account is not configured, unable to proceed");
850+
}
851+
Account account = accountService.getActiveAccountByUuid(serviceAccountUuid);
852+
if (account == null) {
853+
throw new CloudRuntimeException("Service account with ID " + serviceAccountUuid + " not found, unable to proceed");
854+
}
855+
User user = accountService.getOneActiveUserForAccount(account);
856+
if (user == null) {
857+
throw new CloudRuntimeException("No active user found for service account with ID " + serviceAccountUuid);
858+
}
859+
return new Pair<>(user, account);
860+
}
861+
861862
@Override
862863
public boolean start() {
863864
getServiceAccount();
@@ -1185,15 +1186,13 @@ public VmAction shutdownInstance(String uuid, boolean async) {
11851186

11861187
@ApiAccess(command = ListTagsCmd.class)
11871188
protected List<Tag> listTagsByInstanceId(final long instanceId) {
1188-
List<? extends ResourceTag> vmResourceTags = resourceTagDao.listBy(instanceId,
1189-
ResourceTag.ResourceObjectType.UserVm);
1189+
ResourceTag vmResourceTag = resourceTagDao.findByKey(instanceId,
1190+
ResourceTag.ResourceObjectType.UserVm, VM_TA_KEY);
11901191
List<ResourceTagVO> tags = new ArrayList<>();
1191-
for (ResourceTag t : vmResourceTags) {
1192-
if (t instanceof ResourceTagVO) {
1193-
tags.add((ResourceTagVO)t);
1194-
continue;
1195-
}
1196-
tags.add(resourceTagDao.findById(t.getId()));
1192+
if (vmResourceTag instanceof ResourceTagVO) {
1193+
tags.add((ResourceTagVO)vmResourceTag);
1194+
} else {
1195+
tags.add(resourceTagDao.findById(vmResourceTag.getId()));
11971196
}
11981197
return ResourceTagVOToTagConverter.toTags(tags);
11991198
}
@@ -1760,8 +1759,8 @@ public List<Tag> listAllTags(final Long offset, final Long limit) {
17601759
List<Tag> tags = new ArrayList<>(getDummyTags().values());
17611760
Filter filter = new Filter(ResourceTagVO.class, "id", true, offset, limit);
17621761
Pair<List<Long>, List<Long>> ownerDetails = getResourceOwnerFiltersWithDomainIds();
1763-
List<ResourceTagVO> vmResourceTags = resourceTagDao.listByResourceTypeAndOwners(
1764-
ResourceTag.ResourceObjectType.UserVm, ownerDetails.first(), ownerDetails.second(), filter);
1762+
List<ResourceTagVO> vmResourceTags = resourceTagDao.listByResourceTypeKeyAndOwners(
1763+
ResourceTag.ResourceObjectType.UserVm, VM_TA_KEY, ownerDetails.first(), ownerDetails.second(), filter);
17651764
if (CollectionUtils.isNotEmpty(vmResourceTags)) {
17661765
tags.addAll(ResourceTagVOToTagConverter.toTags(vmResourceTags));
17671766
}
@@ -1775,7 +1774,8 @@ public Tag getTag(String uuid) {
17751774
}
17761775
Tag tag = getDummyTags().get(uuid);
17771776
if (tag == null) {
1778-
ResourceTagVO resourceTagVO = resourceTagDao.findByUuid(uuid);
1777+
ResourceTagVO resourceTagVO = resourceTagDao.findByResourceTypeKeyAndValue(
1778+
ResourceTag.ResourceObjectType.UserVm, VM_TA_KEY, uuid);
17791779
accountService.checkAccess(CallContext.current().getCallingAccount(), null, false,
17801780
resourceTagVO);
17811781
if (resourceTagVO != null) {

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/ApiService.java renamed to plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/ApiRouteHandler.java

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,34 @@
2121
import java.nio.charset.StandardCharsets;
2222
import java.util.ArrayList;
2323
import java.util.List;
24-
import java.util.UUID;
2524

25+
import javax.inject.Inject;
2626
import javax.servlet.http.HttpServletRequest;
2727
import javax.servlet.http.HttpServletResponse;
2828

2929
import org.apache.cloudstack.veeam.RouteHandler;
3030
import org.apache.cloudstack.veeam.VeeamControlService;
3131
import org.apache.cloudstack.veeam.VeeamControlServlet;
32+
import org.apache.cloudstack.veeam.adapter.ServerAdapter;
3233
import org.apache.cloudstack.veeam.api.dto.Api;
3334
import org.apache.cloudstack.veeam.api.dto.ApiSummary;
3435
import org.apache.cloudstack.veeam.api.dto.EmptyElement;
3536
import org.apache.cloudstack.veeam.api.dto.Link;
3637
import org.apache.cloudstack.veeam.api.dto.ProductInfo;
3738
import org.apache.cloudstack.veeam.api.dto.Ref;
38-
import org.apache.cloudstack.veeam.api.dto.SpecialObjects;
3939
import org.apache.cloudstack.veeam.api.dto.SummaryCount;
4040
import org.apache.cloudstack.veeam.api.dto.Version;
4141
import org.apache.cloudstack.veeam.utils.Negotiation;
4242

4343
import com.cloud.utils.UuidUtils;
4444
import com.cloud.utils.component.ManagerBase;
4545

46-
public class ApiService extends ManagerBase implements RouteHandler {
46+
public class ApiRouteHandler extends ManagerBase implements RouteHandler {
4747
public static final String BASE_ROUTE = "/api";
4848

49+
@Inject
50+
ServerAdapter serverAdapter;
51+
4952
@Override
5053
public boolean canHandle(String method, String path) {
5154
return getSanitizedPath(path).startsWith("/api");
@@ -63,11 +66,11 @@ public void handle(HttpServletRequest req, HttpServletResponse resp, String path
6366

6467
private void handleRootApiRequest(HttpServletRequest req, HttpServletResponse resp, Negotiation.OutFormat outFormat, VeeamControlServlet io) throws IOException {
6568
io.getWriter().write(resp, HttpServletResponse.SC_OK,
66-
createDummyApi(VeeamControlService.ContextPath.value() + BASE_ROUTE),
69+
createApiObject(VeeamControlService.ContextPath.value() + BASE_ROUTE),
6770
outFormat);
6871
}
6972

70-
private static Api createDummyApi(String basePath) {
73+
protected Api createApiObject(String basePath) {
7174
Api api = new Api();
7275

7376
/* ---------------- Links ---------------- */
@@ -96,30 +99,11 @@ private static Api createDummyApi(String basePath) {
9699
ProductInfo productInfo = new ProductInfo();
97100
productInfo.setInstanceId(UuidUtils.nameUUIDFromBytes(
98101
VeeamControlService.BindAddress.value().getBytes(StandardCharsets.UTF_8)).toString());
99-
productInfo.name = "oVirt Engine";
100-
101-
Version version = new Version();
102-
version.setBuild("8");
103-
version.setFullVersion("4.5.8-0.master.fake.el9");
104-
version.setMajor("4");
105-
version.setMinor("5");
106-
version.setRevision("0");
102+
productInfo.name = VeeamControlService.PLUGIN_NAME;
107103

108-
productInfo.version = version;
104+
productInfo.version = Version.fromPackageAndCSVersion(true);
109105
api.setProductInfo(productInfo);
110106

111-
/* ---------------- Special objects ---------------- */
112-
SpecialObjects specialObjects = new SpecialObjects();
113-
specialObjects.setBlankTemplate(Ref.of(
114-
basePath + "/templates/00000000-0000-0000-0000-000000000000",
115-
"00000000-0000-0000-0000-000000000000"
116-
));
117-
specialObjects.setRootTag(Ref.of(
118-
basePath + "/tags/00000000-0000-0000-0000-000000000000",
119-
"00000000-0000-0000-0000-000000000000"
120-
));
121-
api.setSpecialObjects(specialObjects);
122-
123107
/* ---------------- Summary ---------------- */
124108
ApiSummary summary = new ApiSummary();
125109
summary.setHosts(new SummaryCount(1, 1));
@@ -132,7 +116,7 @@ private static Api createDummyApi(String basePath) {
132116
api.setTime(System.currentTimeMillis());
133117

134118
/* ---------------- Users ---------------- */
135-
String userId = UUID.randomUUID().toString();
119+
String userId = serverAdapter.getServiceAccount().first().getUuid();
136120
api.setAuthenticatedUser(Ref.of(basePath + "/users/" + userId, userId));
137121
api.setEffectiveUser(Ref.of(basePath + "/users/" + userId, userId));
138122

0 commit comments

Comments
 (0)