Create a new template in an organization. Returns a single template. @Summary Create template by organization @ID create-template-by-organization @Security CoderSessionToken @Accept json @Produce json @Tags Templates @Param request body codersdk.CreateTemplateRequest true "Request body" @Param orga
(rw http.ResponseWriter, r *http.Request)
| 181 | // @Success 200 {object} codersdk.Template |
| 182 | // @Router /api/v2/organizations/{organization}/templates [post] |
| 183 | func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Request) { |
| 184 | var ( |
| 185 | ctx = r.Context() |
| 186 | portSharer = *api.PortSharer.Load() |
| 187 | createTemplate codersdk.CreateTemplateRequest |
| 188 | organization = httpmw.OrganizationParam(r) |
| 189 | apiKey = httpmw.APIKey(r) |
| 190 | auditor = *api.Auditor.Load() |
| 191 | templateAudit, commitTemplateAudit = audit.InitRequest[database.Template](rw, &audit.RequestParams{ |
| 192 | Audit: auditor, |
| 193 | Log: api.Logger, |
| 194 | Request: r, |
| 195 | Action: database.AuditActionCreate, |
| 196 | OrganizationID: organization.ID, |
| 197 | }) |
| 198 | templateVersionAudit, commitTemplateVersionAudit = audit.InitRequest[database.TemplateVersion](rw, &audit.RequestParams{ |
| 199 | Audit: auditor, |
| 200 | Log: api.Logger, |
| 201 | Request: r, |
| 202 | Action: database.AuditActionWrite, |
| 203 | OrganizationID: organization.ID, |
| 204 | }) |
| 205 | ) |
| 206 | defer commitTemplateAudit() |
| 207 | defer commitTemplateVersionAudit() |
| 208 | |
| 209 | if !httpapi.Read(ctx, rw, r, &createTemplate) { |
| 210 | return |
| 211 | } |
| 212 | |
| 213 | // Default is false as dynamic parameters are now the preferred approach. |
| 214 | useClassicParameterFlow := ptr.NilToDefault(createTemplate.UseClassicParameterFlow, false) |
| 215 | |
| 216 | // Make a temporary struct to represent the template. This is used for |
| 217 | // auditing if any of the following checks fail. It will be overwritten when |
| 218 | // the template is inserted into the db. |
| 219 | templateAudit.New = database.Template{ |
| 220 | OrganizationID: organization.ID, |
| 221 | Name: createTemplate.Name, |
| 222 | Description: createTemplate.Description, |
| 223 | CreatedBy: apiKey.UserID, |
| 224 | Icon: createTemplate.Icon, |
| 225 | DisplayName: createTemplate.DisplayName, |
| 226 | UseClassicParameterFlow: useClassicParameterFlow, |
| 227 | } |
| 228 | |
| 229 | _, err := api.Database.GetTemplateByOrganizationAndName(ctx, database.GetTemplateByOrganizationAndNameParams{ |
| 230 | OrganizationID: organization.ID, |
| 231 | Name: createTemplate.Name, |
| 232 | }) |
| 233 | if err == nil { |
| 234 | httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{ |
| 235 | Message: fmt.Sprintf("Template with name %q already exists.", createTemplate.Name), |
| 236 | Validations: []codersdk.ValidationError{{ |
| 237 | Field: "name", |
| 238 | Detail: "This value is already in use and should be unique.", |
| 239 | }}, |
| 240 | }) |
nothing calls this directly
no test coverage detected