feat: add user quiet hours schedule and restart requirement feature flag (#8115)

This commit is contained in:
Dean Sheather
2023-07-20 23:35:41 +10:00
committed by GitHub
parent 4821e2e6d8
commit dc8b73168e
67 changed files with 4340 additions and 767 deletions
+84 -16
View File
@@ -213,17 +213,21 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
}
var (
defaultTTL time.Duration
maxTTL time.Duration
failureTTL time.Duration
inactivityTTL time.Duration
lockedTTL time.Duration
defaultTTL time.Duration
// TODO(@dean): remove max_ttl once restart_requirement is ready
maxTTL time.Duration
restartRequirementDaysOfWeek []string
restartRequirementWeeks int64
failureTTL time.Duration
inactivityTTL time.Duration
lockedTTL time.Duration
)
if createTemplate.DefaultTTLMillis != nil {
defaultTTL = time.Duration(*createTemplate.DefaultTTLMillis) * time.Millisecond
}
if createTemplate.MaxTTLMillis != nil {
maxTTL = time.Duration(*createTemplate.MaxTTLMillis) * time.Millisecond
if createTemplate.RestartRequirement != nil {
restartRequirementDaysOfWeek = createTemplate.RestartRequirement.DaysOfWeek
restartRequirementWeeks = createTemplate.RestartRequirement.Weeks
}
if createTemplate.FailureTTLMillis != nil {
failureTTL = time.Duration(*createTemplate.FailureTTLMillis) * time.Millisecond
@@ -235,7 +239,10 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
lockedTTL = time.Duration(*createTemplate.LockedTTLMillis) * time.Millisecond
}
var validErrs []codersdk.ValidationError
var (
validErrs []codersdk.ValidationError
restartRequirementDaysOfWeekParsed uint8
)
if defaultTTL < 0 {
validErrs = append(validErrs, codersdk.ValidationError{Field: "default_ttl_ms", Detail: "Must be a positive integer."})
}
@@ -245,6 +252,21 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
if maxTTL != 0 && defaultTTL > maxTTL {
validErrs = append(validErrs, codersdk.ValidationError{Field: "default_ttl_ms", Detail: "Must be less than or equal to max_ttl_ms if max_ttl_ms is set."})
}
if len(restartRequirementDaysOfWeek) > 0 {
restartRequirementDaysOfWeekParsed, err = codersdk.WeekdaysToBitmap(restartRequirementDaysOfWeek)
if err != nil {
validErrs = append(validErrs, codersdk.ValidationError{Field: "restart_requirement.days_of_week", Detail: err.Error()})
}
}
if createTemplate.MaxTTLMillis != nil {
maxTTL = time.Duration(*createTemplate.MaxTTLMillis) * time.Millisecond
}
if restartRequirementWeeks < 0 {
validErrs = append(validErrs, codersdk.ValidationError{Field: "restart_requirement.weeks", Detail: "Must be a positive integer."})
}
if restartRequirementWeeks > schedule.MaxTemplateRestartRequirementWeeks {
validErrs = append(validErrs, codersdk.ValidationError{Field: "restart_requirement.weeks", Detail: fmt.Sprintf("Must be less than %d.", schedule.MaxTemplateRestartRequirementWeeks)})
}
if failureTTL < 0 {
validErrs = append(validErrs, codersdk.ValidationError{Field: "failure_ttl_ms", Detail: "Must be a positive integer."})
}
@@ -306,14 +328,18 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
return xerrors.Errorf("get template by id: %s", err)
}
dbTemplate, err = (*api.TemplateScheduleStore.Load()).SetTemplateScheduleOptions(ctx, tx, dbTemplate, schedule.TemplateScheduleOptions{
dbTemplate, err = (*api.TemplateScheduleStore.Load()).Set(ctx, tx, dbTemplate, schedule.TemplateScheduleOptions{
UserAutostartEnabled: allowUserAutostart,
UserAutostopEnabled: allowUserAutostop,
DefaultTTL: defaultTTL,
MaxTTL: maxTTL,
// Some of these values are enterprise-only, but the
// TemplateScheduleStore will handle avoiding setting them if
// unlicensed.
MaxTTL: maxTTL,
RestartRequirement: schedule.TemplateRestartRequirement{
DaysOfWeek: restartRequirementDaysOfWeekParsed,
Weeks: restartRequirementWeeks,
},
FailureTTL: failureTTL,
InactivityTTL: inactivityTTL,
LockedTTL: lockedTTL,
@@ -459,12 +485,24 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
defer commitAudit()
aReq.Old = template
scheduleOpts, err := (*api.TemplateScheduleStore.Load()).Get(ctx, api.Database, template.ID)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching template schedule options.",
Detail: err.Error(),
})
return
}
var req codersdk.UpdateTemplateMeta
if !httpapi.Read(ctx, rw, r, &req) {
return
}
var validErrs []codersdk.ValidationError
var (
validErrs []codersdk.ValidationError
restartRequirementDaysOfWeekParsed uint8
)
if req.DefaultTTLMillis < 0 {
validErrs = append(validErrs, codersdk.ValidationError{Field: "default_ttl_ms", Detail: "Must be a positive integer."})
}
@@ -474,6 +512,24 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
if req.MaxTTLMillis != 0 && req.DefaultTTLMillis > req.MaxTTLMillis {
validErrs = append(validErrs, codersdk.ValidationError{Field: "default_ttl_ms", Detail: "Must be less than or equal to max_ttl_ms if max_ttl_ms is set."})
}
if req.RestartRequirement == nil {
req.RestartRequirement = &codersdk.TemplateRestartRequirement{
DaysOfWeek: codersdk.BitmapToWeekdays(scheduleOpts.RestartRequirement.DaysOfWeek),
Weeks: scheduleOpts.RestartRequirement.Weeks,
}
}
if len(req.RestartRequirement.DaysOfWeek) > 0 {
restartRequirementDaysOfWeekParsed, err = codersdk.WeekdaysToBitmap(req.RestartRequirement.DaysOfWeek)
if err != nil {
validErrs = append(validErrs, codersdk.ValidationError{Field: "restart_requirement.days_of_week", Detail: err.Error()})
}
}
if req.RestartRequirement.Weeks < 0 {
validErrs = append(validErrs, codersdk.ValidationError{Field: "restart_requirement.weeks", Detail: "Must be a positive integer."})
}
if req.RestartRequirement.Weeks > schedule.MaxTemplateRestartRequirementWeeks {
validErrs = append(validErrs, codersdk.ValidationError{Field: "restart_requirement.weeks", Detail: fmt.Sprintf("Must be less than %d.", schedule.MaxTemplateRestartRequirementWeeks)})
}
if req.FailureTTLMillis < 0 {
validErrs = append(validErrs, codersdk.ValidationError{Field: "failure_ttl_ms", Detail: "Must be a positive integer."})
}
@@ -496,7 +552,7 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
}
var updated database.Template
err := api.Database.InTx(func(tx database.Store) error {
err = api.Database.InTx(func(tx database.Store) error {
if req.Name == template.Name &&
req.Description == template.Description &&
req.DisplayName == template.DisplayName &&
@@ -506,6 +562,8 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
req.AllowUserCancelWorkspaceJobs == template.AllowUserCancelWorkspaceJobs &&
req.DefaultTTLMillis == time.Duration(template.DefaultTTL).Milliseconds() &&
req.MaxTTLMillis == time.Duration(template.MaxTTL).Milliseconds() &&
restartRequirementDaysOfWeekParsed == scheduleOpts.RestartRequirement.DaysOfWeek &&
req.RestartRequirement.Weeks == scheduleOpts.RestartRequirement.Weeks &&
req.FailureTTLMillis == time.Duration(template.FailureTTL).Milliseconds() &&
req.InactivityTTLMillis == time.Duration(template.InactivityTTL).Milliseconds() &&
req.LockedTTLMillis == time.Duration(template.LockedTTL).Milliseconds() {
@@ -545,12 +603,14 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
if defaultTTL != time.Duration(template.DefaultTTL) ||
maxTTL != time.Duration(template.MaxTTL) ||
restartRequirementDaysOfWeekParsed != scheduleOpts.RestartRequirement.DaysOfWeek ||
req.RestartRequirement.Weeks != scheduleOpts.RestartRequirement.Weeks ||
failureTTL != time.Duration(template.FailureTTL) ||
inactivityTTL != time.Duration(template.InactivityTTL) ||
lockedTTL != time.Duration(template.LockedTTL) ||
req.AllowUserAutostart != template.AllowUserAutostart ||
req.AllowUserAutostop != template.AllowUserAutostop {
updated, err = (*api.TemplateScheduleStore.Load()).SetTemplateScheduleOptions(ctx, tx, updated, schedule.TemplateScheduleOptions{
updated, err = (*api.TemplateScheduleStore.Load()).Set(ctx, tx, updated, schedule.TemplateScheduleOptions{
// Some of these values are enterprise-only, but the
// TemplateScheduleStore will handle avoiding setting them if
// unlicensed.
@@ -558,9 +618,13 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
UserAutostopEnabled: req.AllowUserAutostop,
DefaultTTL: defaultTTL,
MaxTTL: maxTTL,
FailureTTL: failureTTL,
InactivityTTL: inactivityTTL,
LockedTTL: lockedTTL,
RestartRequirement: schedule.TemplateRestartRequirement{
DaysOfWeek: restartRequirementDaysOfWeekParsed,
Weeks: req.RestartRequirement.Weeks,
},
FailureTTL: failureTTL,
InactivityTTL: inactivityTTL,
LockedTTL: lockedTTL,
})
if err != nil {
return xerrors.Errorf("set template schedule options: %w", err)
@@ -694,5 +758,9 @@ func (api *API) convertTemplate(
FailureTTLMillis: time.Duration(template.FailureTTL).Milliseconds(),
InactivityTTLMillis: time.Duration(template.InactivityTTL).Milliseconds(),
LockedTTLMillis: time.Duration(template.LockedTTL).Milliseconds(),
RestartRequirement: codersdk.TemplateRestartRequirement{
DaysOfWeek: codersdk.BitmapToWeekdays(uint8(template.RestartRequirementDaysOfWeek)),
Weeks: template.RestartRequirementWeeks,
},
}
}