docs: API enterprise (#5625)

* docs: audit, deploymentconfig, files, parameters

* Swagger comments in workspacebuilds.go

* structs in workspacebuilds.go

* workspaceagents: instance identity

* workspaceagents.go in progress

* workspaceagents.go in progress

* Agents

* workspacebuilds.go

* /workspaces

* templates.go, templateversions.go

* templateversion.go in progress

* cancel

* templateversions

* wip

* Merge

* x-apidocgen

* NullTime hack not needed anymore

* Fix: x-apidocgen

* Members

* Fixes

* Fix

* WIP

* WIP

* Users

* Logout

* User profile

* Status suspend activate

* User roles

* User tokens

* Keys

* SSH key

* All

* Typo

* Fix

* Entitlements

* Groups

* SCIM

* Fix

* Fix

* Clean templates

* Sort API pages

* Fix: HashedSecret

* General is first
This commit is contained in:
Marcin Tojek
2023-01-11 16:05:42 +01:00
committed by GitHub
parent 8e9cbdd71b
commit d9436fab69
31 changed files with 4139 additions and 375 deletions

View File

@ -15,6 +15,13 @@ import (
"github.com/coder/coder/codersdk"
)
// @Summary Get appearance
// @ID get-appearance
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Success 200 {object} codersdk.AppearanceConfig
// @Router /appearance [get]
func (api *API) appearance(rw http.ResponseWriter, r *http.Request) {
api.entitlementsMu.RLock()
isEntitled := api.entitlements.Features[codersdk.FeatureAppearance].Entitlement == codersdk.EntitlementEntitled
@ -74,6 +81,14 @@ func validateHexColor(color string) error {
return err
}
// @Summary Update appearance
// @ID update-appearance
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param request body codersdk.AppearanceConfig true "Update appearance request"
// @Success 200 {object} codersdk.AppearanceConfig
// @Router /appearance [put]
func (api *API) putAppearance(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()

View File

@ -81,7 +81,7 @@ func New(ctx context.Context, options *Options) (*API, error) {
httpmw.ExtractOrganizationParam(api.Database),
)
r.Post("/", api.postGroupByOrganization)
r.Get("/", api.groups)
r.Get("/", api.groupsByOrganization)
r.Route("/{groupName}", func(r chi.Router) {
r.Use(
httpmw.ExtractGroupByNameParam(api.Database),
@ -331,6 +331,13 @@ func (api *API) updateEntitlements(ctx context.Context) error {
return nil
}
// @Summary Get entitlements
// @ID get-entitlements
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Success 200 {object} codersdk.Entitlements
// @Router /entitlements [get]
func (api *API) serveEntitlements(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
api.entitlementsMu.RLock()

View File

@ -17,6 +17,16 @@ import (
"github.com/coder/coder/codersdk"
)
// @Summary Create group for organization
// @ID create-group-for-organization
// @Security CoderSessionToken
// @Accept json
// @Produce json
// @Tags Templates
// @Param request body codersdk.CreateGroupRequest true "Create group request"
// @Param organization path string true "Organization ID"
// @Success 201 {object} codersdk.Group
// @Router /organizations/{organization}/groups [post]
func (api *API) postGroupByOrganization(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
@ -264,6 +274,14 @@ func (api *API) deleteGroup(rw http.ResponseWriter, r *http.Request) {
})
}
// @Summary Get group by name
// @ID get-group-by-name
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param groupName path string true "Group name"
// @Success 200 {object} codersdk.Group
// @Router /groups/{groupName} [get]
func (api *API) group(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
@ -284,6 +302,26 @@ func (api *API) group(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(ctx, rw, http.StatusOK, convertGroup(group, users))
}
// @Summary Get groups by organization
// @ID get-groups-by-organization
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param organization path string true "Organization ID" format(uuid)
// @Success 200 {array} codersdk.Group
// @Router /organizations/{organization}/groups [get]
func (api *API) groupsByOrganization(rw http.ResponseWriter, r *http.Request) {
api.groups(rw, r)
}
// @Summary Get groups
// @ID get-groups
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param organization path string true "Organization ID" format(uuid)
// @Success 200 {array} codersdk.Group
// @Router /groups [get]
func (api *API) groups(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()

View File

@ -48,6 +48,15 @@ var Keys = map[string]ed25519.PublicKey{"2022-08-12": ed25519.PublicKey(key20220
// we generally don't want the old features to immediately break without warning. With a grace
// period on the license, features will continue to work from the old license until its grace
// period, then the users will get a warning allowing them to gracefully stop using the feature.
//
// @Summary Add new license
// @ID add-new-license
// @Security CoderSessionToken
// @Produce json
// @Tags Organizations
// @Param request body codersdk.AddLicenseRequest true "Add license request"
// @Success 201 {object} codersdk.License
// @Router /licenses [post]
func (api *API) postLicense(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if !api.AGPL.Authorize(r, rbac.ActionCreate, rbac.ResourceLicense) {
@ -121,6 +130,13 @@ func (api *API) postLicense(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(ctx, rw, http.StatusCreated, convertLicense(dl, rawClaims))
}
// @Summary Get licenses
// @ID get-licenses
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Success 200 {array} codersdk.License
// @Router /licenses [get]
func (api *API) licenses(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
licenses, err := api.Database.GetLicenses(ctx)
@ -155,6 +171,14 @@ func (api *API) licenses(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(ctx, rw, http.StatusOK, sdkLicenses)
}
// @Summary Delete license
// @ID delete-license
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param id path string true "License ID" format(number)
// @Success 200
// @Router /license/{id} [delete]
func (api *API) deleteLicense(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if !api.AGPL.Authorize(r, rbac.ActionDelete, rbac.ResourceLicense) {

View File

@ -45,6 +45,14 @@ func (api *API) provisionerDaemonsEnabledMW(next http.Handler) http.Handler {
})
}
// @Summary Get provisioner daemons
// @ID get-provisioner-daemons
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param organization path string true "Organization ID" format(uuid)
// @Success 200 {array} codersdk.ProvisionerDaemon
// @Router /organizations/{organization}/provisionerdaemons [get]
func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
org := httpmw.OrganizationParam(r)
@ -82,6 +90,15 @@ func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) {
}
// Serves the provisioner daemon protobuf API over a WebSocket.
//
// @Summary Serve provisioner daemon
// @ID serve-provisioner-daemon
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param organization path string true "Organization ID" format(uuid)
// @Success 101
// @Router /organizations/{organization}/provisionerdaemons/serve [get]
func (api *API) provisionerDaemonServe(rw http.ResponseWriter, r *http.Request) {
tags := map[string]string{}
if r.URL.Query().Has("tag") {

View File

@ -10,6 +10,14 @@ import (
)
// replicas returns the number of replicas that are active in Coder.
//
// @Summary Get active replicas
// @ID get-active-replicas
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Success 200 {array} codersdk.Replica
// @Router /replicas [get]
func (api *API) replicas(rw http.ResponseWriter, r *http.Request) {
if !api.AGPL.Authorize(r, rbac.ActionRead, rbac.ResourceReplicas) {
httpapi.ResourceNotFound(rw)

View File

@ -43,6 +43,14 @@ func (api *API) scimVerifyAuthHeader(r *http.Request) bool {
// Okta to try and create each user individually, this way we don't need to
// implement fetching users twice.
//
// @Summary SCIM 2.0: Get users
// @ID scim-get-users
// @Security CoderSessionToken
// @Produce application/scim+json
// @Tags Enterprise
// @Success 200
// @Router /scim/v2/Users [post]
//
//nolint:revive
func (api *API) scimGetUsers(rw http.ResponseWriter, r *http.Request) {
if !api.scimVerifyAuthHeader(r) {
@ -62,6 +70,19 @@ func (api *API) scimGetUsers(rw http.ResponseWriter, r *http.Request) {
// This is done to always force Okta to try and create the user, this way we
// don't need to implement fetching users twice.
//
// scimGetUsers intentionally always returns no users. This is done to always force
// Okta to try and create each user individually, this way we don't need to
// implement fetching users twice.
//
// @Summary SCIM 2.0: Get user by ID
// @ID scim-get-user-by-id
// @Security CoderSessionToken
// @Produce application/scim+json
// @Tags Enterprise
// @Param id path string true "User ID" format(uuid)
// @Failure 404
// @Router /scim/v2/Users/{id} [get]
//
//nolint:revive
func (api *API) scimGetUser(rw http.ResponseWriter, r *http.Request) {
if !api.scimVerifyAuthHeader(r) {
@ -86,7 +107,7 @@ type SCIMUser struct {
} `json:"name"`
Emails []struct {
Primary bool `json:"primary"`
Value string `json:"value"`
Value string `json:"value" format:"email"`
Type string `json:"type"`
Display string `json:"display"`
} `json:"emails"`
@ -98,6 +119,15 @@ type SCIMUser struct {
}
// scimPostUser creates a new user, or returns the existing user if it exists.
//
// @Summary SCIM 2.0: Create new user
// @ID scim-create-new-user
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param request body coderd.SCIMUser true "New user"
// @Success 200 {object} coderd.SCIMUser
// @Router /scim/v2/Users [post]
func (api *API) scimPostUser(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if !api.scimVerifyAuthHeader(r) {
@ -144,6 +174,16 @@ func (api *API) scimPostUser(rw http.ResponseWriter, r *http.Request) {
}
// scimPatchUser supports suspending and activating users only.
//
// @Summary SCIM 2.0: Update user account
// @ID scim-update-user-status
// @Security CoderSessionToken
// @Produce application/scim+json
// @Tags Enterprise
// @Param id path string true "User ID" format(uuid)
// @Param request body coderd.SCIMUser true "Update user request"
// @Success 200 {object} codersdk.User
// @Router /scim/v2/Users/{id} [patch]
func (api *API) scimPatchUser(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if !api.scimVerifyAuthHeader(r) {

View File

@ -34,7 +34,7 @@ func makeScimUser(t testing.TB) coderd.SCIMUser {
},
Emails: []struct {
Primary bool "json:\"primary\""
Value string "json:\"value\""
Value string "json:\"value\" format:\"email\""
Type string "json:\"type\""
Display string "json:\"display\""
}{

View File

@ -18,6 +18,14 @@ import (
"github.com/coder/coder/codersdk"
)
// @Summary Get template ACLs
// @ID get-template-acls
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param template path string true "Template ID" format(uuid)
// @Success 200 {array} codersdk.TemplateUser
// @Router /templates/{template}/acl [get]
func (api *API) templateACL(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
@ -92,6 +100,15 @@ func (api *API) templateACL(rw http.ResponseWriter, r *http.Request) {
})
}
// @Summary Update template ACL
// @ID update-template-acl
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param template path string true "Template ID" format(uuid)
// @Param request body codersdk.UpdateTemplateACL true "Update template request"
// @Success 200 {object} codersdk.Response
// @Router /templates/{template}/acl [patch]
func (api *API) patchTemplateACL(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()

View File

@ -99,6 +99,14 @@ func (c *committer) CommitQuota(
}, nil
}
// @Summary Get workspace quota by user
// @ID get-workspace-quota-by-user
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param user path string true "User ID, name, or me"
// @Success 200 {object} codersdk.WorkspaceQuota
// @Router /workspace-quota/{user} [get]
func (api *API) workspaceQuota(rw http.ResponseWriter, r *http.Request) {
user := httpmw.UserParam(r)