resolveTemplateMetaUpdate produces a templateMetaUpdate populated with either the request value (when present) or the existing template's value (when the request field is nil). This function validates shape, not contents: it parses the autostop/autostart day-of-week strings into bitmaps and ensures
( template database.Template, scheduleOpts schedule.TemplateScheduleOptions, req codersdk.UpdateTemplateMeta, )
| 60 | // that depends on external interfaces (such as port-sharing licensure) |
| 61 | // are the caller's responsibility. |
| 62 | func resolveTemplateMetaUpdate( |
| 63 | template database.Template, |
| 64 | scheduleOpts schedule.TemplateScheduleOptions, |
| 65 | req codersdk.UpdateTemplateMeta, |
| 66 | ) (templateMetaUpdate, []codersdk.ValidationError) { |
| 67 | var validErrs []codersdk.ValidationError |
| 68 | |
| 69 | out := templateMetaUpdate{ |
| 70 | name: ptr.NilToDefault(req.Name, template.Name), |
| 71 | displayName: ptr.NilToDefault(req.DisplayName, template.DisplayName), |
| 72 | description: ptr.NilToDefault(req.Description, template.Description), |
| 73 | icon: ptr.NilToDefault(req.Icon, template.Icon), |
| 74 | defaultTTLMillis: ptr.NilToDefault(req.DefaultTTLMillis, time.Duration(template.DefaultTTL).Milliseconds()), |
| 75 | activityBumpMillis: ptr.NilToDefault(req.ActivityBumpMillis, time.Duration(template.ActivityBump).Milliseconds()), |
| 76 | failureTTLMillis: ptr.NilToDefault(req.FailureTTLMillis, time.Duration(template.FailureTTL).Milliseconds()), |
| 77 | timeTilDormantMillis: ptr.NilToDefault(req.TimeTilDormantMillis, time.Duration(template.TimeTilDormant).Milliseconds()), |
| 78 | timeTilDormantAutoDeleteMillis: ptr.NilToDefault(req.TimeTilDormantAutoDeleteMillis, time.Duration(template.TimeTilDormantAutoDelete).Milliseconds()), |
| 79 | allowUserAutostart: ptr.NilToDefault(req.AllowUserAutostart, template.AllowUserAutostart), |
| 80 | allowUserAutostop: ptr.NilToDefault(req.AllowUserAutostop, template.AllowUserAutostop), |
| 81 | allowUserCancelWorkspaceJobs: ptr.NilToDefault(req.AllowUserCancelWorkspaceJobs, template.AllowUserCancelWorkspaceJobs), |
| 82 | requireActiveVersion: ptr.NilToDefault(req.RequireActiveVersion, template.RequireActiveVersion), |
| 83 | deprecationMessage: ptr.NilToDefault(req.DeprecationMessage, template.Deprecated), |
| 84 | useClassicTemplateFlow: ptr.NilToDefault(req.UseClassicParameterFlow, template.UseClassicParameterFlow), |
| 85 | disableModuleCache: ptr.NilToDefault(req.DisableModuleCache, template.DisableModuleCache), |
| 86 | groupACL: template.GroupACL, |
| 87 | |
| 88 | // Default to the original values |
| 89 | corsBehavior: template.CorsBehavior, |
| 90 | autostopRequirementDaysOfWeekParsed: scheduleOpts.AutostopRequirement.DaysOfWeek, |
| 91 | autostopRequirementWeeks: scheduleOpts.AutostopRequirement.Weeks, |
| 92 | autostartRequirementDaysOfWeekParsed: scheduleOpts.AutostartRequirement.DaysOfWeek, |
| 93 | updateWorkspaceLastUsedAtIntent: false, |
| 94 | updateWorkspaceDormantAtIntent: false, |
| 95 | } |
| 96 | |
| 97 | // Users should not be able to clear the template name. This is the only field |
| 98 | // that treats a zero value as omitted. |
| 99 | if out.name == "" { |
| 100 | out.name = template.Name |
| 101 | } |
| 102 | |
| 103 | // Override autostop if provided is non-nil |
| 104 | if req.AutostopRequirement != nil { |
| 105 | bitmap, err := codersdk.WeekdaysToBitmap(req.AutostopRequirement.DaysOfWeek) |
| 106 | if err != nil { |
| 107 | validErrs = append(validErrs, codersdk.ValidationError{ |
| 108 | Field: "autostop_requirement.days_of_week", |
| 109 | Detail: err.Error(), |
| 110 | }) |
| 111 | } else { |
| 112 | out.autostopRequirementDaysOfWeekParsed = bitmap |
| 113 | out.autostopRequirementWeeks = req.AutostopRequirement.Weeks |
| 114 | } |
| 115 | |
| 116 | // Always force <= 0 -> 1 |
| 117 | if out.autostopRequirementWeeks <= 0 { |
| 118 | out.autostopRequirementWeeks = defaultRequirementWeeks |
| 119 | } |