postTemplateVersionsByOrganization creates a new version of a template. An import job is queued to parse the storage method provided. @Summary Create template version by organization @ID create-template-version-by-organization @Security CoderSessionToken @Accept json @Produce json @Tags Templates @
(rw http.ResponseWriter, r *http.Request)
| 1461 | // @Success 201 {object} codersdk.TemplateVersion |
| 1462 | // @Router /api/v2/organizations/{organization}/templateversions [post] |
| 1463 | func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *http.Request) { |
| 1464 | var ( |
| 1465 | ctx = r.Context() |
| 1466 | apiKey = httpmw.APIKey(r) |
| 1467 | organization = httpmw.OrganizationParam(r) |
| 1468 | auditor = *api.Auditor.Load() |
| 1469 | aReq, commitAudit = audit.InitRequest[database.TemplateVersion](rw, &audit.RequestParams{ |
| 1470 | Audit: auditor, |
| 1471 | Log: api.Logger, |
| 1472 | Request: r, |
| 1473 | Action: database.AuditActionCreate, |
| 1474 | OrganizationID: organization.ID, |
| 1475 | }) |
| 1476 | |
| 1477 | req codersdk.CreateTemplateVersionRequest |
| 1478 | ) |
| 1479 | defer commitAudit() |
| 1480 | |
| 1481 | if !httpapi.Read(ctx, rw, r, &req) { |
| 1482 | return |
| 1483 | } |
| 1484 | |
| 1485 | dynamicTemplate := true // Default to using dynamic templates |
| 1486 | if req.TemplateID != uuid.Nil { |
| 1487 | tpl, err := api.Database.GetTemplateByID(ctx, req.TemplateID) |
| 1488 | if httpapi.Is404Error(err) { |
| 1489 | httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{ |
| 1490 | Message: "Template does not exist.", |
| 1491 | }) |
| 1492 | return |
| 1493 | } |
| 1494 | if err != nil { |
| 1495 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ |
| 1496 | Message: "Internal error fetching template.", |
| 1497 | Detail: err.Error(), |
| 1498 | }) |
| 1499 | return |
| 1500 | } |
| 1501 | dynamicTemplate = !tpl.UseClassicParameterFlow |
| 1502 | } |
| 1503 | |
| 1504 | if req.ExampleID != "" && req.FileID != uuid.Nil { |
| 1505 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 1506 | Message: "You cannot specify both an example_id and a file_id.", |
| 1507 | }) |
| 1508 | return |
| 1509 | } |
| 1510 | |
| 1511 | var file database.File |
| 1512 | var err error |
| 1513 | // if example id is specified we need to copy the embedded tar into a new file in the database |
| 1514 | if req.ExampleID != "" { |
| 1515 | if !api.Authorize(r, policy.ActionCreate, rbac.ResourceFile.WithOwner(apiKey.UserID.String())) { |
| 1516 | httpapi.Forbidden(rw) |
| 1517 | return |
| 1518 | } |
| 1519 | // ensure we can read the file that either already exists or will be created |
| 1520 | if !api.Authorize(r, policy.ActionRead, rbac.ResourceFile.WithOwner(apiKey.UserID.String())) { |
nothing calls this directly
no test coverage detected