server: prevent vm schedule update failure for time when not changed (#11314)
Fixes #11175
Behaviour introduced in #7397 always validates start-end times during
update even when they are not changed which leads to failure to
enable/disable schedule if the start time has passed.
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
diff --git a/server/src/main/java/org/apache/cloudstack/vm/schedule/VMScheduleManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/schedule/VMScheduleManagerImpl.java
index 0bb2f94..4d1fc40 100644
--- a/server/src/main/java/org/apache/cloudstack/vm/schedule/VMScheduleManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/vm/schedule/VMScheduleManagerImpl.java
@@ -18,6 +18,30 @@
*/
package org.apache.cloudstack.vm.schedule;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.TimeZone;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.ApiCommandResourceType;
+import org.apache.cloudstack.api.command.user.vm.CreateVMScheduleCmd;
+import org.apache.cloudstack.api.command.user.vm.DeleteVMScheduleCmd;
+import org.apache.cloudstack.api.command.user.vm.ListVMScheduleCmd;
+import org.apache.cloudstack.api.command.user.vm.UpdateVMScheduleCmd;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.VMScheduleResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.vm.schedule.dao.VMScheduleDao;
+import org.apache.commons.lang.time.DateUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+import org.springframework.scheduling.support.CronExpression;
+
import com.cloud.api.query.MutualExclusiveIdsManagerBase;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
@@ -32,27 +56,6 @@
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.VirtualMachine;
-import org.apache.cloudstack.api.ApiCommandResourceType;
-import org.apache.cloudstack.api.command.user.vm.CreateVMScheduleCmd;
-import org.apache.cloudstack.api.command.user.vm.DeleteVMScheduleCmd;
-import org.apache.cloudstack.api.command.user.vm.ListVMScheduleCmd;
-import org.apache.cloudstack.api.command.user.vm.UpdateVMScheduleCmd;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.VMScheduleResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.vm.schedule.dao.VMScheduleDao;
-import org.apache.commons.lang.time.DateUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Logger;
-import org.springframework.scheduling.support.CronExpression;
-
-import javax.inject.Inject;
-import java.time.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
-import java.util.TimeZone;
public class VMScheduleManagerImpl extends MutualExclusiveIdsManagerBase implements VMScheduleManager, PluggableService {
@@ -208,6 +211,9 @@
Date cmdStartDate = cmd.getStartDate();
Date cmdEndDate = cmd.getEndDate();
Boolean enabled = cmd.getEnabled();
+ final String originalTimeZone = vmSchedule.getTimeZone();
+ final Date originalStartDate = vmSchedule.getStartDate();
+ final Date originalEndDate = vmSchedule.getEndDate();
TimeZone timeZone;
String timeZoneId;
@@ -234,7 +240,13 @@
startDate = Date.from(DateUtil.getZoneDateTime(cmdStartDate, timeZone.toZoneId()).toInstant());
}
- validateStartDateEndDate(Objects.requireNonNullElse(startDate, DateUtils.addMinutes(new Date(), 1)), endDate, timeZone);
+ if (ObjectUtils.anyNotNull(cmdStartDate, cmdEndDate, cmdTimeZone) &&
+ (!Objects.equals(originalTimeZone, timeZoneId) ||
+ !Objects.equals(originalStartDate, startDate) ||
+ !Objects.equals(originalEndDate, endDate))) {
+ validateStartDateEndDate(Objects.requireNonNullElse(startDate, DateUtils.addMinutes(new Date(), 1)),
+ endDate, timeZone);
+ }
if (enabled != null) {
vmSchedule.setEnabled(enabled);