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>
This commit is contained in:
Abhishek Kumar 2025-09-09 15:04:28 +05:30 committed by GitHub
parent f4802f30ed
commit fe120b64e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -18,6 +18,30 @@
*/ */
package org.apache.cloudstack.vm.schedule; 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.api.query.MutualExclusiveIdsManagerBase;
import com.cloud.event.ActionEvent; import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
@ -32,27 +56,6 @@ import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.UserVmManager; import com.cloud.vm.UserVmManager;
import com.cloud.vm.VirtualMachine; 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 { public class VMScheduleManagerImpl extends MutualExclusiveIdsManagerBase implements VMScheduleManager, PluggableService {
@ -208,6 +211,9 @@ public class VMScheduleManagerImpl extends MutualExclusiveIdsManagerBase impleme
Date cmdStartDate = cmd.getStartDate(); Date cmdStartDate = cmd.getStartDate();
Date cmdEndDate = cmd.getEndDate(); Date cmdEndDate = cmd.getEndDate();
Boolean enabled = cmd.getEnabled(); Boolean enabled = cmd.getEnabled();
final String originalTimeZone = vmSchedule.getTimeZone();
final Date originalStartDate = vmSchedule.getStartDate();
final Date originalEndDate = vmSchedule.getEndDate();
TimeZone timeZone; TimeZone timeZone;
String timeZoneId; String timeZoneId;
@ -234,7 +240,13 @@ public class VMScheduleManagerImpl extends MutualExclusiveIdsManagerBase impleme
startDate = Date.from(DateUtil.getZoneDateTime(cmdStartDate, timeZone.toZoneId()).toInstant()); 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) { if (enabled != null) {
vmSchedule.setEnabled(enabled); vmSchedule.setEnabled(enabled);