@Summary Create organization @ID create-organization @Security CoderSessionToken @Accept json @Produce json @Tags Organizations @Param request body codersdk.CreateOrganizationRequest true "Create organization request" @Success 201 {object} codersdk.Organization @Router /api/v2/organizations [post]
(rw http.ResponseWriter, r *http.Request)
| 218 | // @Success 201 {object} codersdk.Organization |
| 219 | // @Router /api/v2/organizations [post] |
| 220 | func (api *API) postOrganizations(rw http.ResponseWriter, r *http.Request) { |
| 221 | var ( |
| 222 | // organizationID is required before the audit log entry is created. |
| 223 | organizationID = uuid.New() |
| 224 | ctx = r.Context() |
| 225 | apiKey = httpmw.APIKey(r) |
| 226 | auditor = api.AGPL.Auditor.Load() |
| 227 | aReq, commitAudit = audit.InitRequest[database.Organization](rw, &audit.RequestParams{ |
| 228 | Audit: *auditor, |
| 229 | Log: api.Logger, |
| 230 | Request: r, |
| 231 | Action: database.AuditActionCreate, |
| 232 | OrganizationID: organizationID, |
| 233 | }) |
| 234 | ) |
| 235 | aReq.Old = database.Organization{} |
| 236 | defer commitAudit() |
| 237 | |
| 238 | var req codersdk.CreateOrganizationRequest |
| 239 | if !httpapi.Read(ctx, rw, r, &req) { |
| 240 | return |
| 241 | } |
| 242 | |
| 243 | if req.Name == codersdk.DefaultOrganization { |
| 244 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 245 | Message: fmt.Sprintf("Organization name %q is reserved.", codersdk.DefaultOrganization), |
| 246 | }) |
| 247 | return |
| 248 | } |
| 249 | |
| 250 | _, err := api.Database.GetOrganizationByName(ctx, database.GetOrganizationByNameParams{ |
| 251 | Name: req.Name, |
| 252 | Deleted: false, |
| 253 | }) |
| 254 | if err == nil { |
| 255 | httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{ |
| 256 | Message: "Organization already exists with that name.", |
| 257 | }) |
| 258 | return |
| 259 | } |
| 260 | if !xerrors.Is(err, sql.ErrNoRows) { |
| 261 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ |
| 262 | Message: fmt.Sprintf("Internal error fetching organization %q.", req.Name), |
| 263 | Detail: err.Error(), |
| 264 | }) |
| 265 | return |
| 266 | } |
| 267 | |
| 268 | var organization database.Organization |
| 269 | err = api.Database.InTx(func(tx database.Store) error { |
| 270 | // Serialize creation and reconciliation of the org-member |
| 271 | // system role across coderd instances (e.g. during rolling |
| 272 | // restarts). |
| 273 | err := tx.AcquireLock(ctx, database.LockIDReconcileSystemRoles) |
| 274 | if err != nil { |
| 275 | return xerrors.Errorf("acquire system roles reconciliation lock: %w", err) |
| 276 | } |
| 277 |
nothing calls this directly
no test coverage detected