diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index b6d9843bd7..3281865849 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -75,6 +75,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -145,7 +148,7 @@ const docTemplate = `{ "Applications" ], "summary": "Get applications host", - "operationId": "get-app-host", + "operationId": "get-applications-host", "responses": { "200": { "description": "OK", @@ -223,7 +226,7 @@ const docTemplate = `{ "Audit" ], "summary": "Generate fake audit log", - "operationId": "generate-fake-audit-logs", + "operationId": "generate-fake-audit-log", "parameters": [ { "description": "Audit log request", @@ -336,9 +339,6 @@ const docTemplate = `{ "consumes": [ "application/json" ], - "produces": [ - "text/plain" - ], "tags": [ "General" ], @@ -405,7 +405,7 @@ const docTemplate = `{ "Files" ], "summary": "Upload file", - "operationId": "update-file", + "operationId": "upload-file", "parameters": [ { "type": "string", @@ -500,7 +500,7 @@ const docTemplate = `{ } } }, - "/groups/{groupName}": { + "/groups/{group}": { "get": { "security": [ { @@ -519,7 +519,7 @@ const docTemplate = `{ { "type": "string", "description": "Group name", - "name": "groupName", + "name": "group", "in": "path", "required": true } @@ -532,9 +532,7 @@ const docTemplate = `{ } } } - } - }, - "/license/{id}": { + }, "delete": { "security": [ { @@ -547,21 +545,55 @@ const docTemplate = `{ "tags": [ "Enterprise" ], - "summary": "Delete license", - "operationId": "delete-license", + "summary": "Delete group by name", + "operationId": "delete-group-by-name", "parameters": [ { "type": "string", - "format": "number", - "description": "License ID", - "name": "id", + "description": "Group name", + "name": "group", "in": "path", "required": true } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Update group by name", + "operationId": "update-group-by-name", + "parameters": [ + { + "type": "string", + "description": "Group name", + "name": "group", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } } } } @@ -599,6 +631,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -628,6 +663,38 @@ const docTemplate = `{ } } }, + "/licenses/{id}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Delete license", + "operationId": "delete-license", + "parameters": [ + { + "type": "string", + "format": "number", + "description": "License ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/organizations": { "post": { "security": [ @@ -635,6 +702,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -781,6 +851,48 @@ const docTemplate = `{ } } }, + "/organizations/{organization}/groups/{groupName}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get group by organization and group name", + "operationId": "get-group-by-organization-and-group-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group name", + "name": "groupName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, "/organizations/{organization}/members/roles": { "get": { "security": [ @@ -959,9 +1071,6 @@ const docTemplate = `{ "CoderSessionToken": [] } ], - "produces": [ - "application/json" - ], "tags": [ "Enterprise" ], @@ -1467,6 +1576,26 @@ const docTemplate = `{ } }, "/scim/v2/Users": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/scim+json" + ], + "tags": [ + "Enterprise" + ], + "summary": "SCIM 2.0: Get users", + "operationId": "scim-get-users", + "responses": { + "200": { + "description": "OK" + } + } + }, "post": { "security": [ { @@ -1576,7 +1705,7 @@ const docTemplate = `{ } } }, - "/templates/{id}": { + "/templates/{template}": { "get": { "security": [ { @@ -1596,7 +1725,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true } @@ -1629,7 +1758,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true } @@ -1656,13 +1785,13 @@ const docTemplate = `{ "Templates" ], "summary": "Update template metadata by ID", - "operationId": "update-template-metadata", + "operationId": "update-template-metadata-by-id", "parameters": [ { "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true } @@ -1677,7 +1806,90 @@ const docTemplate = `{ } } }, - "/templates/{id}/daus": { + "/templates/{template}/acl": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get template ACLs", + "operationId": "get-template-acls", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateUser" + } + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Update template ACL", + "operationId": "update-template-acl", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + }, + { + "description": "Update template request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateTemplateACL" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{template}/daus": { "get": { "security": [ { @@ -1697,7 +1909,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true } @@ -1712,7 +1924,7 @@ const docTemplate = `{ } } }, - "/templates/{id}/versions": { + "/templates/{template}/versions": { "get": { "security": [ { @@ -1726,13 +1938,13 @@ const docTemplate = `{ "Templates" ], "summary": "List template versions by template ID", - "operationId": "list-template-versions-by-template-ID", + "operationId": "list-template-versions-by-template-id", "parameters": [ { "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true }, @@ -1784,7 +1996,7 @@ const docTemplate = `{ "Templates" ], "summary": "Update active template version by template ID", - "operationId": "update-active-template-version-by-template-ID", + "operationId": "update-active-template-version-by-template-id", "parameters": [ { "description": "Modified template version", @@ -1799,7 +2011,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true } @@ -1814,7 +2026,7 @@ const docTemplate = `{ } } }, - "/templates/{id}/versions/{templateversionname}": { + "/templates/{template}/versions/{templateversionname}": { "get": { "security": [ { @@ -1834,7 +2046,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true }, @@ -1859,86 +2071,6 @@ const docTemplate = `{ } } }, - "/templates/{template}/acl": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get template ACLs", - "operationId": "get-template-acls", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateUser" - } - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Update template ACL", - "operationId": "update-template-acl", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - }, - { - "description": "Update template request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateTemplateACL" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, "/templateversions/{templateversion}": { "get": { "security": [ @@ -2056,16 +2188,13 @@ const docTemplate = `{ } } }, - "/templateversions/{templateversion}/dry-run/{jobid}": { + "/templateversions/{templateversion}/dry-run/{jobID}": { "get": { "security": [ { "CoderSessionToken": [] } ], - "consumes": [ - "application/json" - ], "produces": [ "application/json" ], @@ -2087,7 +2216,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Job ID", - "name": "jobid", + "name": "jobID", "in": "path", "required": true } @@ -2102,7 +2231,7 @@ const docTemplate = `{ } } }, - "/templateversions/{templateversion}/dry-run/{jobid}/cancel": { + "/templateversions/{templateversion}/dry-run/{jobID}/cancel": { "patch": { "security": [ { @@ -2118,6 +2247,14 @@ const docTemplate = `{ "summary": "Cancel template version dry-run by job ID", "operationId": "cancel-template-version-dry-run-by-job-id", "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobID", + "in": "path", + "required": true + }, { "type": "string", "format": "uuid", @@ -2137,7 +2274,7 @@ const docTemplate = `{ } } }, - "/templateversions/{templateversion}/dry-run/{jobid}/logs": { + "/templateversions/{templateversion}/dry-run/{jobID}/logs": { "get": { "security": [ { @@ -2165,7 +2302,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Job ID", - "name": "jobid", + "name": "jobID", "in": "path", "required": true }, @@ -2201,7 +2338,7 @@ const docTemplate = `{ } } }, - "/templateversions/{templateversion}/dry-run/{jobid}/resources": { + "/templateversions/{templateversion}/dry-run/{jobID}/resources": { "get": { "security": [ { @@ -2229,7 +2366,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Job ID", - "name": "jobid", + "name": "jobID", "in": "path", "required": true } @@ -2620,6 +2757,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -2681,14 +2821,11 @@ const docTemplate = `{ "CoderSessionToken": [] } ], - "produces": [ - "application/json" - ], "tags": [ "Users" ], "summary": "OAuth 2.0 GitHub Callback", - "operationId": "oauth2-github-callback", + "operationId": "oauth-20-github-callback", "responses": { "307": { "description": "Temporary Redirect" @@ -2703,14 +2840,11 @@ const docTemplate = `{ "CoderSessionToken": [] } ], - "produces": [ - "application/json" - ], "tags": [ "Users" ], "summary": "OpenID Connect Callback", - "operationId": "oidc-callback", + "operationId": "openid-connect-callback", "responses": { "307": { "description": "Temporary Redirect" @@ -2954,6 +3088,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -3037,14 +3174,11 @@ const docTemplate = `{ "CoderSessionToken": [] } ], - "produces": [ - "application/json" - ], "tags": [ "Users" ], "summary": "Delete API key", - "operationId": "delete-user-tokens", + "operationId": "delete-api-key", "parameters": [ { "type": "string", @@ -3083,7 +3217,7 @@ const docTemplate = `{ "Users" ], "summary": "Get organizations by user", - "operationId": "get-organizations-by-users", + "operationId": "get-organizations-by-user", "parameters": [ { "type": "string", @@ -3154,7 +3288,7 @@ const docTemplate = `{ "CoderSessionToken": [] } ], - "produces": [ + "consumes": [ "application/json" ], "tags": [ @@ -3194,6 +3328,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -3513,6 +3650,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -3549,6 +3689,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -3585,6 +3728,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -3621,14 +3767,17 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ "Agents" ], - "summary": "Submit workspace application health", - "operationId": "submit-workspace-workspace-agent-health", + "summary": "Submit workspace agent application health", + "operationId": "submit-workspace-agent-application-health", "parameters": [ { "description": "Application health request", @@ -3655,14 +3804,11 @@ const docTemplate = `{ } ], "description": "It accepts a WebSocket connection to an agent that listens to\nincoming connections and publishes node updates.", - "produces": [ - "application/json" - ], "tags": [ "Agents" ], "summary": "Coordinate workspace agent via Tailnet", - "operationId": "get-workspace-agent-git-ssh-key-via-tailnet", + "operationId": "coordinate-workspace-agent-via-tailnet", "responses": { "101": { "description": "Switching Protocols" @@ -3677,9 +3823,6 @@ const docTemplate = `{ "CoderSessionToken": [] } ], - "consumes": [ - "application/json" - ], "produces": [ "application/json" ], @@ -3721,9 +3864,6 @@ const docTemplate = `{ "CoderSessionToken": [] } ], - "consumes": [ - "application/json" - ], "produces": [ "application/json" ], @@ -3749,9 +3889,6 @@ const docTemplate = `{ "CoderSessionToken": [] } ], - "consumes": [ - "application/json" - ], "produces": [ "application/json" ], @@ -3777,6 +3914,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -3784,7 +3924,7 @@ const docTemplate = `{ "Agents" ], "summary": "Submit workspace agent stats", - "operationId": "submit-workspace-workspace-agent-stats", + "operationId": "submit-workspace-agent-stats", "parameters": [ { "description": "Stats request", @@ -3813,6 +3953,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -3820,7 +3963,7 @@ const docTemplate = `{ "Agents" ], "summary": "Submit workspace agent version", - "operationId": "submit-workspace-workspace-agent-version", + "operationId": "submit-workspace-agent-version", "parameters": [ { "description": "Version request", @@ -3842,6 +3985,169 @@ const docTemplate = `{ } } }, + "/workspaceagents/{workspaceagent}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get workspace agent by ID", + "operationId": "get-workspace-agent-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgent" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/connection": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get connection info for workspace agent", + "operationId": "get-connection-info-for-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentConnectionInfo" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/coordinate": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Agents" + ], + "summary": "Coordinate workspace agent", + "operationId": "coordinate-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/workspaceagents/{workspaceagent}/listening-ports": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get listening ports for workspace agent", + "operationId": "get-listening-ports-for-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ListeningPortsResponse" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/pty": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Agents" + ], + "summary": "Open PTY to workspace agent", + "operationId": "open-pty-to-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, "/workspacebuilds/{workspacebuild}": { "get": { "security": [ @@ -4050,7 +4356,7 @@ const docTemplate = `{ "Workspaces" ], "summary": "List workspaces", - "operationId": "get-workspaces", + "operationId": "list-workspaces", "parameters": [ { "type": "string", @@ -4110,7 +4416,7 @@ const docTemplate = `{ } } }, - "/workspaces/{id}": { + "/workspaces/{workspace}": { "get": { "security": [ { @@ -4130,7 +4436,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Workspace ID", - "name": "id", + "name": "workspace", "in": "path", "required": true }, @@ -4149,9 +4455,89 @@ const docTemplate = `{ } } } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Update workspace metadata by ID", + "operationId": "update-workspace-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Metadata update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } } }, - "/workspaces/{id}/builds": { + "/workspaces/{workspace}/autostart": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Update workspace autostart schedule by ID", + "operationId": "update-workspace-autostart-schedule-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Schedule update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceAutostartRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/builds": { "get": { "security": [ { @@ -4171,7 +4557,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Workspace ID", - "name": "id", + "name": "workspace", "in": "path", "required": true }, @@ -4220,6 +4606,9 @@ const docTemplate = `{ "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], @@ -4233,7 +4622,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Workspace ID", - "name": "id", + "name": "workspace", "in": "path", "required": true }, @@ -4257,94 +4646,6 @@ const docTemplate = `{ } } }, - "/workspaces/{workspace}": { - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Workspaces" - ], - "summary": "Update workspace metadata by ID", - "operationId": "update-workspace-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Metadata update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/autostart": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Workspaces" - ], - "summary": "Update workspace autostart schedule by ID", - "operationId": "update-workspace-autostart-schedule-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Schedule update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceAutostartRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/workspaces/{workspace}/extend": { "put": { "security": [ @@ -4402,9 +4703,6 @@ const docTemplate = `{ "consumes": [ "application/json" ], - "produces": [ - "application/json" - ], "tags": [ "Workspaces" ], @@ -4450,7 +4748,7 @@ const docTemplate = `{ "Workspaces" ], "summary": "Watch workspace by ID", - "operationId": "watch-workspace-id", + "operationId": "watch-workspace-by-id", "parameters": [ { "type": "string", @@ -4778,7 +5076,8 @@ const docTemplate = `{ "$ref": "#/definitions/codersdk.AuditDiff" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "ip": { "type": "string" @@ -4787,16 +5086,19 @@ const docTemplate = `{ "type": "boolean" }, "organization_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "request_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "resource_icon": { "type": "string" }, "resource_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "resource_link": { "type": "string" @@ -4812,7 +5114,8 @@ const docTemplate = `{ "type": "integer" }, "time": { - "type": "string" + "type": "string", + "format": "date-time" }, "user": { "$ref": "#/definitions/codersdk.User" @@ -5099,7 +5402,8 @@ const docTemplate = `{ }, "template_version_id": { "description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.", - "type": "string" + "type": "string", + "format": "uuid" } } }, @@ -5135,7 +5439,8 @@ const docTemplate = `{ ] }, "resource_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "resource_type": { "enum": [ @@ -5156,7 +5461,8 @@ const docTemplate = `{ ] }, "time": { - "type": "string" + "type": "string", + "format": "date-time" } } }, @@ -5231,7 +5537,8 @@ const docTemplate = `{ } }, "template_version_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "transition": { "enum": [ @@ -5255,7 +5562,8 @@ const docTemplate = `{ "type": "integer" }, "date": { - "type": "string" + "type": "string", + "format": "date-time" } } }, @@ -5856,6 +6164,47 @@ const docTemplate = `{ } } }, + "codersdk.ListeningPort": { + "type": "object", + "properties": { + "network": { + "description": "only \"tcp\" at the moment", + "allOf": [ + { + "$ref": "#/definitions/codersdk.ListeningPortNetwork" + } + ] + }, + "port": { + "type": "integer" + }, + "process_name": { + "description": "may be empty", + "type": "string" + } + } + }, + "codersdk.ListeningPortNetwork": { + "type": "string", + "enum": [ + "tcp" + ], + "x-enum-varnames": [ + "ListeningPortNetworkTCP" + ] + }, + "codersdk.ListeningPortsResponse": { + "type": "object", + "properties": { + "ports": { + "description": "If there are no ports in the list, nothing should be displayed in the UI.\nThere must not be a \"no ports available\" message or anything similar, as\nthere will always be no ports displayed on platforms where our port\ndetection logic is unsupported.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ListeningPort" + } + } + } + }, "codersdk.LogLevel": { "type": "string", "enum": [ @@ -6447,7 +6796,8 @@ const docTemplate = `{ ], "properties": { "deadline": { - "type": "string" + "type": "string", + "format": "date-time" } } }, @@ -7241,6 +7591,14 @@ const docTemplate = `{ } } }, + "codersdk.WorkspaceAgentConnectionInfo": { + "type": "object", + "properties": { + "derp_map": { + "$ref": "#/definitions/tailcfg.DERPMap" + } + } + }, "codersdk.WorkspaceAgentGitAuthResponse": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 2f78661e39..d97e53fe6b 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -59,6 +59,7 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Enterprise"], "summary": "Update appearance", @@ -119,7 +120,7 @@ "produces": ["application/json"], "tags": ["Applications"], "summary": "Get applications host", - "operationId": "get-app-host", + "operationId": "get-applications-host", "responses": { "200": { "description": "OK", @@ -189,7 +190,7 @@ "consumes": ["application/json"], "tags": ["Audit"], "summary": "Generate fake audit log", - "operationId": "generate-fake-audit-logs", + "operationId": "generate-fake-audit-log", "parameters": [ { "description": "Audit log request", @@ -286,7 +287,6 @@ } ], "consumes": ["application/json"], - "produces": ["text/plain"], "tags": ["General"], "summary": "Report CSP violations", "operationId": "report-csp-violations", @@ -341,7 +341,7 @@ "produces": ["application/json"], "tags": ["Files"], "summary": "Upload file", - "operationId": "update-file", + "operationId": "upload-file", "parameters": [ { "type": "string", @@ -430,7 +430,7 @@ } } }, - "/groups/{groupName}": { + "/groups/{group}": { "get": { "security": [ { @@ -445,7 +445,7 @@ { "type": "string", "description": "Group name", - "name": "groupName", + "name": "group", "in": "path", "required": true } @@ -458,9 +458,7 @@ } } } - } - }, - "/license/{id}": { + }, "delete": { "security": [ { @@ -469,21 +467,51 @@ ], "produces": ["application/json"], "tags": ["Enterprise"], - "summary": "Delete license", - "operationId": "delete-license", + "summary": "Delete group by name", + "operationId": "delete-group-by-name", "parameters": [ { "type": "string", - "format": "number", - "description": "License ID", - "name": "id", + "description": "Group name", + "name": "group", "in": "path", "required": true } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update group by name", + "operationId": "update-group-by-name", + "parameters": [ + { + "type": "string", + "description": "Group name", + "name": "group", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } } } } @@ -517,6 +545,7 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Organizations"], "summary": "Add new license", @@ -542,6 +571,34 @@ } } }, + "/licenses/{id}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Delete license", + "operationId": "delete-license", + "parameters": [ + { + "type": "string", + "format": "number", + "description": "License ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/organizations": { "post": { "security": [ @@ -549,6 +606,7 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Organizations"], "summary": "Create organization", @@ -677,6 +735,44 @@ } } }, + "/organizations/{organization}/groups/{groupName}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get group by organization and group name", + "operationId": "get-group-by-organization-and-group-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group name", + "name": "groupName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, "/organizations/{organization}/members/roles": { "get": { "security": [ @@ -837,7 +933,6 @@ "CoderSessionToken": [] } ], - "produces": ["application/json"], "tags": ["Enterprise"], "summary": "Serve provisioner daemon", "operationId": "serve-provisioner-daemon", @@ -1279,6 +1374,22 @@ } }, "/scim/v2/Users": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/scim+json"], + "tags": ["Enterprise"], + "summary": "SCIM 2.0: Get users", + "operationId": "scim-get-users", + "responses": { + "200": { + "description": "OK" + } + } + }, "post": { "security": [ { @@ -1376,7 +1487,7 @@ } } }, - "/templates/{id}": { + "/templates/{template}": { "get": { "security": [ { @@ -1392,7 +1503,7 @@ "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true } @@ -1421,7 +1532,7 @@ "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true } @@ -1444,13 +1555,13 @@ "produces": ["application/json"], "tags": ["Templates"], "summary": "Update template metadata by ID", - "operationId": "update-template-metadata", + "operationId": "update-template-metadata-by-id", "parameters": [ { "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true } @@ -1465,7 +1576,80 @@ } } }, - "/templates/{id}/daus": { + "/templates/{template}/acl": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get template ACLs", + "operationId": "get-template-acls", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateUser" + } + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update template ACL", + "operationId": "update-template-acl", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + }, + { + "description": "Update template request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateTemplateACL" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{template}/daus": { "get": { "security": [ { @@ -1481,7 +1665,7 @@ "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true } @@ -1496,7 +1680,7 @@ } } }, - "/templates/{id}/versions": { + "/templates/{template}/versions": { "get": { "security": [ { @@ -1506,13 +1690,13 @@ "produces": ["application/json"], "tags": ["Templates"], "summary": "List template versions by template ID", - "operationId": "list-template-versions-by-template-ID", + "operationId": "list-template-versions-by-template-id", "parameters": [ { "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true }, @@ -1558,7 +1742,7 @@ "produces": ["application/json"], "tags": ["Templates"], "summary": "Update active template version by template ID", - "operationId": "update-active-template-version-by-template-ID", + "operationId": "update-active-template-version-by-template-id", "parameters": [ { "description": "Modified template version", @@ -1573,7 +1757,7 @@ "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true } @@ -1588,7 +1772,7 @@ } } }, - "/templates/{id}/versions/{templateversionname}": { + "/templates/{template}/versions/{templateversionname}": { "get": { "security": [ { @@ -1604,7 +1788,7 @@ "type": "string", "format": "uuid", "description": "Template ID", - "name": "id", + "name": "template", "in": "path", "required": true }, @@ -1629,78 +1813,6 @@ } } }, - "/templates/{template}/acl": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get template ACLs", - "operationId": "get-template-acls", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateUser" - } - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update template ACL", - "operationId": "update-template-acl", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - }, - { - "description": "Update template request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateTemplateACL" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, "/templateversions/{templateversion}": { "get": { "security": [ @@ -1804,14 +1916,13 @@ } } }, - "/templateversions/{templateversion}/dry-run/{jobid}": { + "/templateversions/{templateversion}/dry-run/{jobID}": { "get": { "security": [ { "CoderSessionToken": [] } ], - "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Templates"], "summary": "Get template version dry-run by job ID", @@ -1829,7 +1940,7 @@ "type": "string", "format": "uuid", "description": "Job ID", - "name": "jobid", + "name": "jobID", "in": "path", "required": true } @@ -1844,7 +1955,7 @@ } } }, - "/templateversions/{templateversion}/dry-run/{jobid}/cancel": { + "/templateversions/{templateversion}/dry-run/{jobID}/cancel": { "patch": { "security": [ { @@ -1856,6 +1967,14 @@ "summary": "Cancel template version dry-run by job ID", "operationId": "cancel-template-version-dry-run-by-job-id", "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobID", + "in": "path", + "required": true + }, { "type": "string", "format": "uuid", @@ -1875,7 +1994,7 @@ } } }, - "/templateversions/{templateversion}/dry-run/{jobid}/logs": { + "/templateversions/{templateversion}/dry-run/{jobID}/logs": { "get": { "security": [ { @@ -1899,7 +2018,7 @@ "type": "string", "format": "uuid", "description": "Job ID", - "name": "jobid", + "name": "jobID", "in": "path", "required": true }, @@ -1935,7 +2054,7 @@ } } }, - "/templateversions/{templateversion}/dry-run/{jobid}/resources": { + "/templateversions/{templateversion}/dry-run/{jobID}/resources": { "get": { "security": [ { @@ -1959,7 +2078,7 @@ "type": "string", "format": "uuid", "description": "Job ID", - "name": "jobid", + "name": "jobID", "in": "path", "required": true } @@ -2306,6 +2425,7 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Authorization"], "summary": "Log in user", @@ -2359,10 +2479,9 @@ "CoderSessionToken": [] } ], - "produces": ["application/json"], "tags": ["Users"], "summary": "OAuth 2.0 GitHub Callback", - "operationId": "oauth2-github-callback", + "operationId": "oauth-20-github-callback", "responses": { "307": { "description": "Temporary Redirect" @@ -2377,10 +2496,9 @@ "CoderSessionToken": [] } ], - "produces": ["application/json"], "tags": ["Users"], "summary": "OpenID Connect Callback", - "operationId": "oidc-callback", + "operationId": "openid-connect-callback", "responses": { "307": { "description": "Temporary Redirect" @@ -2596,6 +2714,7 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Users"], "summary": "Create token API key", @@ -2671,10 +2790,9 @@ "CoderSessionToken": [] } ], - "produces": ["application/json"], "tags": ["Users"], "summary": "Delete API key", - "operationId": "delete-user-tokens", + "operationId": "delete-api-key", "parameters": [ { "type": "string", @@ -2709,7 +2827,7 @@ "produces": ["application/json"], "tags": ["Users"], "summary": "Get organizations by user", - "operationId": "get-organizations-by-users", + "operationId": "get-organizations-by-user", "parameters": [ { "type": "string", @@ -2776,7 +2894,7 @@ "CoderSessionToken": [] } ], - "produces": ["application/json"], + "consumes": ["application/json"], "tags": ["Users"], "summary": "Update user password", "operationId": "update-user-password", @@ -2812,6 +2930,7 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Users"], "summary": "Update user profile", @@ -3097,6 +3216,7 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Agents"], "summary": "Authenticate agent on AWS instance", @@ -3129,6 +3249,7 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Agents"], "summary": "Authenticate agent on Azure instance", @@ -3161,6 +3282,7 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Agents"], "summary": "Authenticate agent on Google Cloud instance", @@ -3193,10 +3315,11 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Agents"], - "summary": "Submit workspace application health", - "operationId": "submit-workspace-workspace-agent-health", + "summary": "Submit workspace agent application health", + "operationId": "submit-workspace-agent-application-health", "parameters": [ { "description": "Application health request", @@ -3223,10 +3346,9 @@ } ], "description": "It accepts a WebSocket connection to an agent that listens to\nincoming connections and publishes node updates.", - "produces": ["application/json"], "tags": ["Agents"], "summary": "Coordinate workspace agent via Tailnet", - "operationId": "get-workspace-agent-git-ssh-key-via-tailnet", + "operationId": "coordinate-workspace-agent-via-tailnet", "responses": { "101": { "description": "Switching Protocols" @@ -3241,7 +3363,6 @@ "CoderSessionToken": [] } ], - "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Agents"], "summary": "Get workspace agent Git auth", @@ -3279,7 +3400,6 @@ "CoderSessionToken": [] } ], - "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Agents"], "summary": "Get workspace agent Git SSH key", @@ -3301,7 +3421,6 @@ "CoderSessionToken": [] } ], - "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Agents"], "summary": "Get authorized workspace agent metadata", @@ -3323,10 +3442,11 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Agents"], "summary": "Submit workspace agent stats", - "operationId": "submit-workspace-workspace-agent-stats", + "operationId": "submit-workspace-agent-stats", "parameters": [ { "description": "Stats request", @@ -3355,10 +3475,11 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Agents"], "summary": "Submit workspace agent version", - "operationId": "submit-workspace-workspace-agent-version", + "operationId": "submit-workspace-agent-version", "parameters": [ { "description": "Version request", @@ -3380,6 +3501,153 @@ } } }, + "/workspaceagents/{workspaceagent}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get workspace agent by ID", + "operationId": "get-workspace-agent-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgent" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/connection": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get connection info for workspace agent", + "operationId": "get-connection-info-for-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentConnectionInfo" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/coordinate": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Agents"], + "summary": "Coordinate workspace agent", + "operationId": "coordinate-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/workspaceagents/{workspaceagent}/listening-ports": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get listening ports for workspace agent", + "operationId": "get-listening-ports-for-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ListeningPortsResponse" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/pty": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Agents"], + "summary": "Open PTY to workspace agent", + "operationId": "open-pty-to-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, "/workspacebuilds/{workspacebuild}": { "get": { "security": [ @@ -3564,7 +3832,7 @@ "produces": ["application/json"], "tags": ["Workspaces"], "summary": "List workspaces", - "operationId": "get-workspaces", + "operationId": "list-workspaces", "parameters": [ { "type": "string", @@ -3619,7 +3887,7 @@ } } }, - "/workspaces/{id}": { + "/workspaces/{workspace}": { "get": { "security": [ { @@ -3635,7 +3903,7 @@ "type": "string", "format": "uuid", "description": "Workspace ID", - "name": "id", + "name": "workspace", "in": "path", "required": true }, @@ -3654,9 +3922,81 @@ } } } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Workspaces"], + "summary": "Update workspace metadata by ID", + "operationId": "update-workspace-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Metadata update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } } }, - "/workspaces/{id}/builds": { + "/workspaces/{workspace}/autostart": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Workspaces"], + "summary": "Update workspace autostart schedule by ID", + "operationId": "update-workspace-autostart-schedule-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Schedule update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceAutostartRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/builds": { "get": { "security": [ { @@ -3672,7 +4012,7 @@ "type": "string", "format": "uuid", "description": "Workspace ID", - "name": "id", + "name": "workspace", "in": "path", "required": true }, @@ -3721,6 +4061,7 @@ "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Builds"], "summary": "Create workspace build", @@ -3730,7 +4071,7 @@ "type": "string", "format": "uuid", "description": "Workspace ID", - "name": "id", + "name": "workspace", "in": "path", "required": true }, @@ -3754,82 +4095,6 @@ } } }, - "/workspaces/{workspace}": { - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Update workspace metadata by ID", - "operationId": "update-workspace-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Metadata update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/autostart": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Update workspace autostart schedule by ID", - "operationId": "update-workspace-autostart-schedule-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Schedule update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceAutostartRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/workspaces/{workspace}/extend": { "put": { "security": [ @@ -3879,7 +4144,6 @@ } ], "consumes": ["application/json"], - "produces": ["application/json"], "tags": ["Workspaces"], "summary": "Update workspace TTL by ID", "operationId": "update-workspace-ttl-by-id", @@ -3919,7 +4183,7 @@ "produces": ["text/event-stream"], "tags": ["Workspaces"], "summary": "Watch workspace by ID", - "operationId": "watch-workspace-id", + "operationId": "watch-workspace-by-id", "parameters": [ { "type": "string", @@ -4222,7 +4486,8 @@ "$ref": "#/definitions/codersdk.AuditDiff" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "ip": { "type": "string" @@ -4231,16 +4496,19 @@ "type": "boolean" }, "organization_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "request_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "resource_icon": { "type": "string" }, "resource_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "resource_link": { "type": "string" @@ -4256,7 +4524,8 @@ "type": "integer" }, "time": { - "type": "string" + "type": "string", + "format": "date-time" }, "user": { "$ref": "#/definitions/codersdk.User" @@ -4515,7 +4784,8 @@ }, "template_version_id": { "description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.", - "type": "string" + "type": "string", + "format": "uuid" } } }, @@ -4545,7 +4815,8 @@ ] }, "resource_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "resource_type": { "enum": [ @@ -4566,7 +4837,8 @@ ] }, "time": { - "type": "string" + "type": "string", + "format": "date-time" } } }, @@ -4631,7 +4903,8 @@ } }, "template_version_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "transition": { "enum": ["create", "start", "stop", "delete"], @@ -4650,7 +4923,8 @@ "type": "integer" }, "date": { - "type": "string" + "type": "string", + "format": "date-time" } } }, @@ -5245,6 +5519,43 @@ } } }, + "codersdk.ListeningPort": { + "type": "object", + "properties": { + "network": { + "description": "only \"tcp\" at the moment", + "allOf": [ + { + "$ref": "#/definitions/codersdk.ListeningPortNetwork" + } + ] + }, + "port": { + "type": "integer" + }, + "process_name": { + "description": "may be empty", + "type": "string" + } + } + }, + "codersdk.ListeningPortNetwork": { + "type": "string", + "enum": ["tcp"], + "x-enum-varnames": ["ListeningPortNetworkTCP"] + }, + "codersdk.ListeningPortsResponse": { + "type": "object", + "properties": { + "ports": { + "description": "If there are no ports in the list, nothing should be displayed in the UI.\nThere must not be a \"no ports available\" message or anything similar, as\nthere will always be no ports displayed on platforms where our port\ndetection logic is unsupported.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ListeningPort" + } + } + } + }, "codersdk.LogLevel": { "type": "string", "enum": ["trace", "debug", "info", "warn", "error"], @@ -5772,7 +6083,8 @@ "required": ["deadline"], "properties": { "deadline": { - "type": "string" + "type": "string", + "format": "date-time" } } }, @@ -6521,6 +6833,14 @@ } } }, + "codersdk.WorkspaceAgentConnectionInfo": { + "type": "object", + "properties": { + "derp_map": { + "$ref": "#/definitions/tailcfg.DERPMap" + } + } + }, "codersdk.WorkspaceAgentGitAuthResponse": { "type": "object", "properties": { diff --git a/coderd/apikey.go b/coderd/apikey.go index e4cbd7552c..5e9aee7c58 100644 --- a/coderd/apikey.go +++ b/coderd/apikey.go @@ -29,6 +29,7 @@ import ( // @Summary Create token API key // @ID create-token-api-key // @Security CoderSessionToken +// @Accept json // @Produce json // @Tags Users // @Param user path string true "User ID, name, or me" @@ -209,9 +210,8 @@ func (api *API) tokens(rw http.ResponseWriter, r *http.Request) { } // @Summary Delete API key -// @ID delete-user-tokens +// @ID delete-api-key // @Security CoderSessionToken -// @Produce json // @Tags Users // @Param user path string true "User ID, name, or me" // @Param keyid path string true "Key ID" format(uuid) diff --git a/coderd/audit.go b/coderd/audit.go index 08f070fdb9..d8b764c8ea 100644 --- a/coderd/audit.go +++ b/coderd/audit.go @@ -89,7 +89,7 @@ func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) { } // @Summary Generate fake audit log -// @ID generate-fake-audit-logs +// @ID generate-fake-audit-log // @Security CoderSessionToken // @Accept json // @Tags Audit diff --git a/coderd/coderdtest/swagger_test.go b/coderd/coderdtest/swagger_test.go new file mode 100644 index 0000000000..ef8dd88f79 --- /dev/null +++ b/coderd/coderdtest/swagger_test.go @@ -0,0 +1,66 @@ +package coderdtest_test + +import ( + "go/ast" + "go/parser" + "go/token" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/coder/coder/coderd/coderdtest" +) + +func TestEndpointsDocumented(t *testing.T) { + t.Parallel() + + swaggerComments, err := coderdtest.ParseSwaggerComments("..") + require.NoError(t, err, "can't parse swagger comments") + + _, _, api := coderdtest.NewWithAPI(t, nil) + coderdtest.VerifySwaggerDefinitions(t, api.APIHandler, swaggerComments) +} + +func TestSDKFieldsFormatted(t *testing.T) { + t.Parallel() + + fileSet := token.NewFileSet() + nodes, err := parser.ParseDir(fileSet, "../../codersdk", nil, parser.ParseComments) + require.NoError(t, err, "parser.ParseDir failed") + + for _, node := range nodes { + ast.Inspect(node, func(n ast.Node) bool { + typeSpec, ok := n.(*ast.TypeSpec) + if !ok { + return true + } + structureName := typeSpec.Name + + structType, ok := typeSpec.Type.(*ast.StructType) + if !ok { + return true // not a structure + } + + for _, field := range structType.Fields.List { + selectorExpr, ok := field.Type.(*ast.SelectorExpr) + if !ok { + continue // rather a basic, or primitive + } + + if field.Tag == nil || !strings.Contains(field.Tag.Value, `json:"`) { + continue // not a JSON property + } + + switch selectorExpr.Sel.Name { + case "UUID": + assert.Contains(t, field.Tag.Value, `format:"uuid"`, `Swagger formatting requires to annotate the field with - format:"uuid". Location: %s/%s`, structureName, field.Names) + case "Time": + assert.Contains(t, field.Tag.Value, `format:"date-time"`, `Swagger formatting requires to annotate the field with - format:"date-time". Location: %s/%s`, structureName, field.Names) + } + } + return true + }) + } +} diff --git a/coderd/coderdtest/swaggerparser.go b/coderd/coderdtest/swaggerparser.go new file mode 100644 index 0000000000..ccdb082d4a --- /dev/null +++ b/coderd/coderdtest/swaggerparser.go @@ -0,0 +1,318 @@ +package coderdtest + +import ( + "go/ast" + "go/parser" + "go/token" + "net/http" + "regexp" + "strings" + "testing" + + "github.com/go-chi/chi/v5" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/xerrors" +) + +type SwaggerComment struct { + summary string + id string + security string + tags string + accept string + produce string + + method string + router string + + successes []response + failures []response + + parameters []parameter + + raw []*ast.Comment +} + +type parameter struct { + name string + kind string +} + +type response struct { + status string + kind string // {object} or {array} + model string +} + +func ParseSwaggerComments(dirs ...string) ([]SwaggerComment, error) { + fileSet := token.NewFileSet() + + var swaggerComments []SwaggerComment + for _, dir := range dirs { + nodes, err := parser.ParseDir(fileSet, dir, nil, parser.ParseComments) + if err != nil { + return nil, xerrors.Errorf(`parser.ParseDir failed for "%s": %w`, dir, err) + } + + for _, node := range nodes { + ast.Inspect(node, func(n ast.Node) bool { + commentGroup, ok := n.(*ast.CommentGroup) + if !ok { + return true + } + + var isSwaggerComment bool + for _, line := range commentGroup.List { + text := strings.TrimSpace(line.Text) + if strings.HasPrefix(text, "//") && strings.Contains(text, "@Router") { + isSwaggerComment = true + break + } + } + + if isSwaggerComment { + swaggerComments = append(swaggerComments, parseSwaggerComment(commentGroup)) + } + return true + }) + } + } + return swaggerComments, nil +} + +func parseSwaggerComment(commentGroup *ast.CommentGroup) SwaggerComment { + c := SwaggerComment{ + raw: commentGroup.List, + parameters: []parameter{}, + successes: []response{}, + failures: []response{}, + } + for _, line := range commentGroup.List { + // @ [args...] + splitN := strings.SplitN(strings.TrimSpace(line.Text), " ", 3) + if len(splitN) < 2 { + continue // comment prefix without any content + } + + if !strings.HasPrefix(splitN[1], "@") { + continue // not a swagger annotation + } + + annotationName := splitN[1] + annotationArgs := splitN[2] + args := strings.Split(splitN[2], " ") + + switch annotationName { + case "@Router": + c.router = args[0] + c.method = args[1][1 : len(args[1])-1] + case "@Success", "@Failure": + var r response + if len(args) > 0 { + r.status = args[0] + } + if len(args) > 1 { + r.kind = args[1] + } + if len(args) > 2 { + r.model = args[2] + } + + if annotationName == "@Success" { + c.successes = append(c.successes, r) + } else if annotationName == "@Failure" { + c.failures = append(c.failures, r) + } + case "@Param": + p := parameter{ + name: args[0], + kind: args[1], + } + c.parameters = append(c.parameters, p) + case "@Summary": + c.summary = annotationArgs + case "@ID": + c.id = annotationArgs + case "@Tags": + c.tags = annotationArgs + case "@Security": + c.security = annotationArgs + case "@Accept": + c.accept = annotationArgs + case "@Produce": + c.produce = annotationArgs + } + } + return c +} + +func VerifySwaggerDefinitions(t *testing.T, router chi.Router, swaggerComments []SwaggerComment) { + assertUniqueRoutes(t, swaggerComments) + + err := chi.Walk(router, func(method, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error { + method = strings.ToLower(method) + if route != "/" && strings.HasSuffix(route, "/") { + route = route[:len(route)-1] + } + + t.Run(method+" "+route, func(t *testing.T) { + t.Parallel() + + c := findSwaggerCommentByMethodAndRoute(swaggerComments, method, route) + assert.NotNil(t, c, "Missing @Router annotation") + if c == nil { + return // do not fail next assertion for this route + } + + assertConsistencyBetweenRouteIDAndSummary(t, *c) + assertSuccessOrFailureDefined(t, *c) + assertRequiredAnnotations(t, *c) + assertGoCommentFirst(t, *c) + assertPathParametersDefined(t, *c) + assertSecurityDefined(t, *c) + assertAccept(t, *c) + assertProduce(t, *c) + }) + return nil + }) + require.NoError(t, err, "chi.Walk should not fail") +} + +func assertUniqueRoutes(t *testing.T, comments []SwaggerComment) { + m := map[string]struct{}{} + + for _, c := range comments { + key := c.method + " " + c.router + _, alreadyDefined := m[key] + assert.False(t, alreadyDefined, "defined route must be unique (method: %s, route: %s)", c.method, c.router) + if !alreadyDefined { + m[key] = struct{}{} + } + } +} + +func findSwaggerCommentByMethodAndRoute(comments []SwaggerComment, method, route string) *SwaggerComment { + for _, c := range comments { + if c.method == method && c.router == route { + return &c + } + } + return nil +} + +var nonAlphanumericRegex = regexp.MustCompile(`[^a-zA-Z0-9-]+`) + +func assertConsistencyBetweenRouteIDAndSummary(t *testing.T, comment SwaggerComment) { + exp := strings.ToLower(comment.summary) + exp = strings.ReplaceAll(exp, " ", "-") + exp = nonAlphanumericRegex.ReplaceAllString(exp, "") + + assert.Equal(t, exp, comment.id, "Router ID must match summary") +} + +func assertSuccessOrFailureDefined(t *testing.T, comment SwaggerComment) { + assert.True(t, len(comment.successes) > 0 || len(comment.failures) > 0, "At least one @Success or @Failure annotation must be defined") +} + +func assertRequiredAnnotations(t *testing.T, comment SwaggerComment) { + assert.NotEmpty(t, comment.id, "@ID must be defined") + assert.NotEmpty(t, comment.summary, "@Summary must be defined") + assert.NotEmpty(t, comment.tags, "@Tags must be defined") +} + +func assertGoCommentFirst(t *testing.T, comment SwaggerComment) { + var inSwaggerBlock bool + + for _, line := range comment.raw { + text := strings.TrimSpace(line.Text) + + if inSwaggerBlock { + if !strings.HasPrefix(text, "// @") { + assert.Fail(t, "Go function comment must be placed before swagger comments") + return + } + } + if strings.HasPrefix(text, "// @Summary") { + inSwaggerBlock = true + } + } +} + +var urlParameterRegexp = regexp.MustCompile(`{[^{}]*}`) + +func assertPathParametersDefined(t *testing.T, comment SwaggerComment) { + matches := urlParameterRegexp.FindAllString(comment.router, -1) + if matches == nil { + return // router does not require any parameters + } + + for _, m := range matches { + var matched bool + for _, p := range comment.parameters { + if p.kind == "path" && "{"+p.name+"}" == m { + matched = true + break + } + } + + if !matched { + assert.Failf(t, "Missing @Param annotation", "Path parameter: %s", m) + } + } +} + +func assertSecurityDefined(t *testing.T, comment SwaggerComment) { + if comment.router == "/updatecheck" || + comment.router == "/buildinfo" || + comment.router == "/" { + return // endpoints do not require authorization + } + assert.Equal(t, "CoderSessionToken", comment.security, "@Security must be equal CoderSessionToken") +} + +func assertAccept(t *testing.T, comment SwaggerComment) { + var hasRequestBody bool + for _, c := range comment.parameters { + if c.name == "request" && c.kind == "body" || + c.name == "file" && c.kind == "formData" { + hasRequestBody = true + break + } + } + + var hasAccept bool + if comment.accept != "" { + hasAccept = true + } + + if comment.method == "get" { + assert.Empty(t, comment.accept, "GET route does not require the @Accept annotation") + assert.False(t, hasRequestBody, "GET route does not require the request body") + } else { + assert.False(t, hasRequestBody && !hasAccept, "Route with the request body requires the @Accept annotation") + assert.False(t, !hasRequestBody && hasAccept, "Route with @Accept annotation requires the request body or file formData parameter") + } +} + +func assertProduce(t *testing.T, comment SwaggerComment) { + var hasResponseModel bool + for _, r := range comment.successes { + if r.model != "" { + hasResponseModel = true + break + } + } + + if hasResponseModel { + assert.True(t, comment.produce != "", "Route must have @Produce annotation as it responds with a model structure") + } else { + if (comment.router == "/workspaceagents/me/app-health" && comment.method == "post") || + (comment.router == "/workspaceagents/me/version" && comment.method == "post") || + (comment.router == "/licenses/{id}" && comment.method == "delete") { + return // Exception: HTTP 200 is returned without response entity + } + + assert.True(t, comment.produce == "", "Response model is undefined, so we can't predict the content type", comment) + } +} diff --git a/coderd/csp.go b/coderd/csp.go index ae3a0cbd99..346cd90622 100644 --- a/coderd/csp.go +++ b/coderd/csp.go @@ -20,7 +20,6 @@ type cspViolation struct { // @ID report-csp-violations // @Security CoderSessionToken // @Accept json -// @Produce text/plain // @Tags General // @Param request body cspViolation true "Violation report" // @Success 200 diff --git a/coderd/files.go b/coderd/files.go index c128d1bd6e..bf8a98f605 100644 --- a/coderd/files.go +++ b/coderd/files.go @@ -25,7 +25,7 @@ const ( // @Summary Upload file // @Description Swagger notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`. -// @ID update-file +// @ID upload-file // @Security CoderSessionToken // @Produce json // @Accept application/x-tar diff --git a/coderd/gitsshkey.go b/coderd/gitsshkey.go index 9e68d7a642..5e0dfcfef5 100644 --- a/coderd/gitsshkey.go +++ b/coderd/gitsshkey.go @@ -119,7 +119,6 @@ func (api *API) gitSSHKey(rw http.ResponseWriter, r *http.Request) { // @Summary Get workspace agent Git SSH key // @ID get-workspace-agent-git-ssh-key // @Security CoderSessionToken -// @Accept json // @Produce json // @Tags Agents // @Success 200 {object} codersdk.AgentGitSSHKey diff --git a/coderd/organizations.go b/coderd/organizations.go index 84bf119734..7df9da184e 100644 --- a/coderd/organizations.go +++ b/coderd/organizations.go @@ -40,6 +40,7 @@ func (api *API) organization(rw http.ResponseWriter, r *http.Request) { // @Summary Create organization // @ID create-organization // @Security CoderSessionToken +// @Accept json // @Produce json // @Tags Organizations // @Param request body codersdk.CreateOrganizationRequest true "Create organization request" diff --git a/coderd/templates.go b/coderd/templates.go index c15a278810..8b8296fdbe 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -23,15 +23,16 @@ import ( "github.com/coder/coder/examples" ) +// Returns a single template. +// // @Summary Get template metadata by ID // @ID get-template-metadata-by-id // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template ID" format(uuid) +// @Param template path string true "Template ID" format(uuid) // @Success 200 {object} codersdk.Template -// @Router /templates/{id} [get] -// Returns a single template. +// @Router /templates/{template} [get] func (api *API) template(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() template := httpmw.TemplateParam(r) @@ -75,9 +76,9 @@ func (api *API) template(rw http.ResponseWriter, r *http.Request) { // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template ID" format(uuid) +// @Param template path string true "Template ID" format(uuid) // @Success 200 {object} codersdk.Response -// @Router /templates/{id} [delete] +// @Router /templates/{template} [delete] func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -131,6 +132,9 @@ func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { }) } +// Create a new template in an organization. +// Returns a single template. +// // @Summary Create template by organization // @ID create-template-by-organization // @Security CoderSessionToken @@ -141,8 +145,6 @@ func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { // @Param organization path string true "Organization ID" // @Success 200 {object} codersdk.Template // @Router /organizations/{organization}/templates [post] -// Returns a single template. -// Create a new template in an organization. func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -461,13 +463,13 @@ func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Re } // @Summary Update template metadata by ID -// @ID update-template-metadata +// @ID update-template-metadata-by-id // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template ID" format(uuid) +// @Param template path string true "Template ID" format(uuid) // @Success 200 {object} codersdk.Template -// @Router /templates/{id} [patch] +// @Router /templates/{template} [patch] func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -593,9 +595,9 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template ID" format(uuid) +// @Param template path string true "Template ID" format(uuid) // @Success 200 {object} codersdk.TemplateDAUsResponse -// @Router /templates/{id}/daus [get] +// @Router /templates/{template}/daus [get] func (api *API) templateDAUs(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() template := httpmw.TemplateParam(r) diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 15ac9a5027..03aba85a3e 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -353,13 +353,12 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques // @Summary Get template version dry-run by job ID // @ID get-template-version-dry-run-by-job-id // @Security CoderSessionToken -// @Accept json // @Produce json // @Tags Templates // @Param templateversion path string true "Template version ID" format(uuid) -// @Param jobid path string true "Job ID" format(uuid) +// @Param jobID path string true "Job ID" format(uuid) // @Success 200 {object} codersdk.ProvisionerJob -// @Router /templateversions/{templateversion}/dry-run/{jobid} [get] +// @Router /templateversions/{templateversion}/dry-run/{jobID} [get] func (api *API) templateVersionDryRun(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() job, ok := api.fetchTemplateVersionDryRunJob(rw, r) @@ -376,9 +375,9 @@ func (api *API) templateVersionDryRun(rw http.ResponseWriter, r *http.Request) { // @Produce json // @Tags Templates // @Param templateversion path string true "Template version ID" format(uuid) -// @Param jobid path string true "Job ID" format(uuid) +// @Param jobID path string true "Job ID" format(uuid) // @Success 200 {array} codersdk.WorkspaceResource -// @Router /templateversions/{templateversion}/dry-run/{jobid}/resources [get] +// @Router /templateversions/{templateversion}/dry-run/{jobID}/resources [get] func (api *API) templateVersionDryRunResources(rw http.ResponseWriter, r *http.Request) { job, ok := api.fetchTemplateVersionDryRunJob(rw, r) if !ok { @@ -394,12 +393,12 @@ func (api *API) templateVersionDryRunResources(rw http.ResponseWriter, r *http.R // @Produce json // @Tags Templates // @Param templateversion path string true "Template version ID" format(uuid) -// @Param jobid path string true "Job ID" format(uuid) +// @Param jobID path string true "Job ID" format(uuid) // @Param before query int false "Before Unix timestamp" // @Param after query int false "After Unix timestamp" // @Param follow query bool false "Follow log stream" // @Success 200 {array} codersdk.ProvisionerJobLog -// @Router /templateversions/{templateversion}/dry-run/{jobid}/logs [get] +// @Router /templateversions/{templateversion}/dry-run/{jobID}/logs [get] func (api *API) templateVersionDryRunLogs(rw http.ResponseWriter, r *http.Request) { job, ok := api.fetchTemplateVersionDryRunJob(rw, r) if !ok { @@ -414,9 +413,10 @@ func (api *API) templateVersionDryRunLogs(rw http.ResponseWriter, r *http.Reques // @Security CoderSessionToken // @Produce json // @Tags Templates +// @Param jobID path string true "Job ID" format(uuid) // @Param templateversion path string true "Template version ID" format(uuid) // @Success 200 {object} codersdk.Response -// @Router /templateversions/{templateversion}/dry-run/{jobid}/cancel [patch] +// @Router /templateversions/{templateversion}/dry-run/{jobID}/cancel [patch] func (api *API) patchTemplateVersionDryRunCancel(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() templateVersion := httpmw.TemplateVersionParam(r) @@ -536,16 +536,16 @@ func (api *API) fetchTemplateVersionDryRunJob(rw http.ResponseWriter, r *http.Re } // @Summary List template versions by template ID -// @ID list-template-versions-by-template-ID +// @ID list-template-versions-by-template-id // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template ID" format(uuid) +// @Param template path string true "Template ID" format(uuid) // @Param after_id query string false "After ID" format(uuid) // @Param limit query int false "Page limit" // @Param offset query int false "Page offset" // @Success 200 {array} codersdk.TemplateVersion -// @Router /templates/{id}/versions [get] +// @Router /templates/{template}/versions [get] func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() template := httpmw.TemplateParam(r) @@ -648,10 +648,10 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template ID" format(uuid) +// @Param template path string true "Template ID" format(uuid) // @Param templateversionname path string true "Template version name" // @Success 200 {array} codersdk.TemplateVersion -// @Router /templates/{id}/versions/{templateversionname} [get] +// @Router /templates/{template}/versions/{templateversionname} [get] func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() template := httpmw.TemplateParam(r) @@ -828,15 +828,15 @@ func (api *API) previousTemplateVersionByOrganizationAndName(rw http.ResponseWri } // @Summary Update active template version by template ID -// @ID update-active-template-version-by-template-ID +// @ID update-active-template-version-by-template-id // @Security CoderSessionToken // @Accept json // @Produce json // @Tags Templates // @Param request body codersdk.UpdateActiveTemplateVersion true "Modified template version" -// @Param id path string true "Template ID" format(uuid) +// @Param template path string true "Template ID" format(uuid) // @Success 200 {object} codersdk.Response -// @Router /templates/{id}/versions [patch] +// @Router /templates/{template}/versions [patch] func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -911,6 +911,8 @@ func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Reque }) } +// 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 @@ -921,8 +923,6 @@ func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Reque // @Param request body codersdk.CreateTemplateVersionDryRunRequest true "Create template version request" // @Success 201 {object} codersdk.TemplateVersion // @Router /organizations/{organization}/templateversions [post] -// -// postTemplateVersionsByOrganization creates a new version of a template. An import job is queued to parse the storage method provided. func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -1207,6 +1207,12 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user)) } +// templateVersionResources returns the workspace agent resources associated +// with a template version. A template can specify more than one resource to be +// provisioned, each resource can have an agent that dials back to coderd. The +// agents returned are informative of the template version, and do not return +// agents associated with any particular workspace. +// // @Summary Get resources by template version // @ID get-resources-by-template-version // @Security CoderSessionToken @@ -1215,12 +1221,6 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht // @Param templateversion path string true "Template version ID" format(uuid) // @Success 200 {array} codersdk.WorkspaceResource // @Router /templateversions/{templateversion}/resources [get] -// -// templateVersionResources returns the workspace agent resources associated -// with a template version. A template can specify more than one resource to be -// provisioned, each resource can have an agent that dials back to coderd. The -// agents returned are informative of the template version, and do not return -// agents associated with any particular workspace. func (api *API) templateVersionResources(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -1244,6 +1244,11 @@ func (api *API) templateVersionResources(rw http.ResponseWriter, r *http.Request api.provisionerJobResources(rw, r, job) } +// templateVersionLogs returns the logs returned by the provisioner for the given +// template version. These logs are only associated with the template version, +// and not any build logs for a workspace. +// Eg: Logs returned from 'terraform plan' when uploading a new terraform file. +// // @Summary Get logs by template version // @ID get-logs-by-template-version // @Security CoderSessionToken @@ -1255,11 +1260,6 @@ func (api *API) templateVersionResources(rw http.ResponseWriter, r *http.Request // @Param follow query bool false "Follow log stream" // @Success 200 {array} codersdk.ProvisionerJobLog // @Router /templateversions/{templateversion}/logs [get] -// -// templateVersionLogs returns the logs returned by the provisioner for the given -// template version. These logs are only associated with the template version, -// and not any build logs for a workspace. -// Eg: Logs returned from 'terraform plan' when uploading a new terraform file. func (api *API) templateVersionLogs(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/coderd/userauth.go b/coderd/userauth.go index e1ee92d0eb..e2f79641bf 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -59,9 +59,8 @@ func (api *API) userAuthMethods(rw http.ResponseWriter, r *http.Request) { } // @Summary OAuth 2.0 GitHub Callback -// @ID oauth2-github-callback +// @ID oauth-20-github-callback // @Security CoderSessionToken -// @Produce json // @Tags Users // @Success 307 // @Router /users/oauth2/github/callback [get] @@ -218,9 +217,8 @@ type OIDCConfig struct { } // @Summary OpenID Connect Callback -// @ID oidc-callback +// @ID openid-connect-callback // @Security CoderSessionToken -// @Produce json // @Tags Users // @Success 307 // @Router /users/oidc/callback [get] diff --git a/coderd/users.go b/coderd/users.go index 0485a1e3ec..ad2749163f 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -435,6 +435,7 @@ func (api *API) userByName(rw http.ResponseWriter, r *http.Request) { // @Summary Update user profile // @ID update-user-profile // @Security CoderSessionToken +// @Accept json // @Produce json // @Tags Users // @Param user path string true "User ID, name, or me" @@ -617,7 +618,7 @@ func (api *API) putUserStatus(status database.UserStatus) func(rw http.ResponseW // @Summary Update user password // @ID update-user-password // @Security CoderSessionToken -// @Produce json +// @Accept json // @Tags Users // @Param user path string true "User ID, name, or me" // @Param request body codersdk.UpdateUserPasswordRequest true "Update password request" @@ -908,7 +909,7 @@ func (api *API) updateSiteUserRoles(ctx context.Context, args database.UpdateUse // Returns organizations the parameterized user has access to. // // @Summary Get organizations by user -// @ID get-organizations-by-users +// @ID get-organizations-by-user // @Security CoderSessionToken // @Produce json // @Tags Users @@ -990,6 +991,7 @@ func (api *API) organizationByUserAndName(rw http.ResponseWriter, r *http.Reques // @Summary Log in user // @ID log-in-user // @Security CoderSessionToken +// @Accept json // @Produce json // @Tags Authorization // @Param request body codersdk.LoginWithPasswordRequest true "Login request" diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index 1464f3282f..e05c3d19a2 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -35,6 +35,14 @@ import ( "github.com/coder/coder/tailnet" ) +// @Summary Get workspace agent by ID +// @ID get-workspace-agent-by-id +// @Security CoderSessionToken +// @Produce json +// @Tags Agents +// @Param workspaceagent path string true "Workspace agent ID" format(uuid) +// @Success 200 {object} codersdk.WorkspaceAgent +// @Router /workspaceagents/{workspaceagent} [get] func (api *API) workspaceAgent(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceAgent := httpmw.WorkspaceAgentParam(r) @@ -66,7 +74,6 @@ func (api *API) workspaceAgent(rw http.ResponseWriter, r *http.Request) { // @Summary Get authorized workspace agent metadata // @ID get-authorized-workspace-agent-metadata // @Security CoderSessionToken -// @Accept json // @Produce json // @Tags Agents // @Success 200 {object} codersdk.WorkspaceAgentMetadata @@ -147,9 +154,10 @@ func (api *API) workspaceAgentMetadata(rw http.ResponseWriter, r *http.Request) } // @Summary Submit workspace agent version -// @ID submit-workspace-workspace-agent-version +// @ID submit-workspace-agent-version // @Security CoderSessionToken -// @Produce application/json +// @Accept json +// @Produce json // @Tags Agents // @Param request body codersdk.PostWorkspaceAgentVersionRequest true "Version request" // @Success 200 @@ -198,6 +206,14 @@ func (api *API) postWorkspaceAgentVersion(rw http.ResponseWriter, r *http.Reques // workspaceAgentPTY spawns a PTY and pipes it over a WebSocket. // This is used for the web terminal. +// +// @Summary Open PTY to workspace agent +// @ID open-pty-to-workspace-agent +// @Security CoderSessionToken +// @Tags Agents +// @Param workspaceagent path string true "Workspace agent ID" format(uuid) +// @Success 101 +// @Router /workspaceagents/{workspaceagent}/pty [get] func (api *API) workspaceAgentPTY(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() @@ -276,6 +292,14 @@ func (api *API) workspaceAgentPTY(rw http.ResponseWriter, r *http.Request) { agent.Bicopy(ctx, wsNetConn, ptNetConn) } +// @Summary Get listening ports for workspace agent +// @ID get-listening-ports-for-workspace-agent +// @Security CoderSessionToken +// @Produce json +// @Tags Agents +// @Param workspaceagent path string true "Workspace agent ID" format(uuid) +// @Success 200 {object} codersdk.ListeningPortsResponse +// @Router /workspaceagents/{workspaceagent}/listening-ports [get] func (api *API) workspaceAgentListeningPorts(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspace := httpmw.WorkspaceParam(r) @@ -443,6 +467,14 @@ func (api *API) dialWorkspaceAgentTailnet(r *http.Request, agentID uuid.UUID) (* }, nil } +// @Summary Get connection info for workspace agent +// @ID get-connection-info-for-workspace-agent +// @Security CoderSessionToken +// @Produce json +// @Tags Agents +// @Param workspaceagent path string true "Workspace agent ID" format(uuid) +// @Success 200 {object} codersdk.WorkspaceAgentConnectionInfo +// @Router /workspaceagents/{workspaceagent}/connection [get] func (api *API) workspaceAgentConnection(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspace := httpmw.WorkspaceParam(r) @@ -458,9 +490,8 @@ func (api *API) workspaceAgentConnection(rw http.ResponseWriter, r *http.Request // @Summary Coordinate workspace agent via Tailnet // @Description It accepts a WebSocket connection to an agent that listens to // @Description incoming connections and publishes node updates. -// @ID get-workspace-agent-git-ssh-key-via-tailnet +// @ID coordinate-workspace-agent-via-tailnet // @Security CoderSessionToken -// @Produce json // @Tags Agents // @Success 101 // @Router /workspaceagents/me/coordinate [get] @@ -622,6 +653,14 @@ func (api *API) workspaceAgentCoordinate(rw http.ResponseWriter, r *http.Request // workspaceAgentClientCoordinate accepts a WebSocket that reads node network updates. // After accept a PubSub starts listening for new connection node updates // which are written to the WebSocket. +// +// @Summary Coordinate workspace agent +// @ID coordinate-workspace-agent +// @Security CoderSessionToken +// @Tags Agents +// @Param workspaceagent path string true "Workspace agent ID" format(uuid) +// @Success 101 +// @Router /workspaceagents/{workspaceagent}/coordinate [get] func (api *API) workspaceAgentClientCoordinate(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() @@ -784,8 +823,9 @@ func convertWorkspaceAgent(derpMap *tailcfg.DERPMap, coordinator tailnet.Coordin } // @Summary Submit workspace agent stats -// @ID submit-workspace-workspace-agent-stats +// @ID submit-workspace-agent-stats // @Security CoderSessionToken +// @Accept json // @Produce application/json // @Tags Agents // @Param request body codersdk.AgentStats true "Stats request" @@ -860,9 +900,10 @@ func (api *API) workspaceAgentReportStats(rw http.ResponseWriter, r *http.Reques }) } -// @Summary Submit workspace application health -// @ID submit-workspace-workspace-agent-health +// @Summary Submit workspace agent application health +// @ID submit-workspace-agent-application-health // @Security CoderSessionToken +// @Accept json // @Produce application/json // @Tags Agents // @Param request body codersdk.PostWorkspaceAppHealthsRequest true "Application health request" @@ -989,7 +1030,6 @@ func (api *API) postWorkspaceAppHealth(rw http.ResponseWriter, r *http.Request) // @Summary Get workspace agent Git auth // @ID get-workspace-agent-git-auth // @Security CoderSessionToken -// @Accept json // @Produce json // @Tags Agents // @Param url query string true "Git URL" format(uri) diff --git a/coderd/workspaceapps.go b/coderd/workspaceapps.go index 20fdfefdb0..fe6cd564df 100644 --- a/coderd/workspaceapps.go +++ b/coderd/workspaceapps.go @@ -66,7 +66,7 @@ var nonCanonicalHeaders = map[string]string{ } // @Summary Get applications host -// @ID get-app-host +// @ID get-applications-host // @Security CoderSessionToken // @Produce json // @Tags Applications @@ -614,6 +614,13 @@ func (api *API) setWorkspaceAppCookie(rw http.ResponseWriter, r *http.Request, t return true } +// workspaceApplicationAuth is an endpoint on the main router that handles +// redirects from the subdomain handler. +// +// This endpoint is under /api so we don't return the friendly error page here. +// Any errors on this endpoint should be errors that are unlikely to happen +// in production unless the user messes with the URL. +// // @Summary Redirect to URI with encrypted API key // @ID redirect-to-uri-with-encrypted-api-key // @Security CoderSessionToken @@ -621,13 +628,6 @@ func (api *API) setWorkspaceAppCookie(rw http.ResponseWriter, r *http.Request, t // @Param redirect_uri query string false "Redirect destination" // @Success 307 // @Router /applications/auth-redirect [get] -// -// workspaceApplicationAuth is an endpoint on the main router that handles -// redirects from the subdomain handler. -// -// This endpoint is under /api so we don't return the friendly error page here. -// Any errors on this endpoint should be errors that are unlikely to happen -// in production unless the user messes with the URL. func (api *API) workspaceApplicationAuth(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() if api.AppHostname == "" { diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index 340eba2dff..01a2a1c72e 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -77,13 +77,13 @@ func (api *API) workspaceBuild(rw http.ResponseWriter, r *http.Request) { // @Security CoderSessionToken // @Produce json // @Tags Builds -// @Param id path string true "Workspace ID" format(uuid) +// @Param workspace path string true "Workspace ID" format(uuid) // @Param after_id query string false "After ID" format(uuid) // @Param limit query int false "Page limit" // @Param offset query int false "Page offset" // @Param since query string false "Since timestamp" format(date-time) // @Success 200 {array} codersdk.WorkspaceBuild -// @Router /workspaces/{id}/builds [get] +// @Router /workspaces/{workspace}/builds [get] func (api *API) workspaceBuilds(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspace := httpmw.WorkspaceParam(r) @@ -290,13 +290,13 @@ func (api *API) workspaceBuildByBuildNumber(rw http.ResponseWriter, r *http.Requ // @Summary Create workspace build // @ID create-workspace-build // @Security CoderSessionToken -// @Accepts json +// @Accept json // @Produce json // @Tags Builds -// @Param id path string true "Workspace ID" format(uuid) +// @Param workspace path string true "Workspace ID" format(uuid) // @Param request body codersdk.CreateWorkspaceBuildRequest true "Create workspace build request" // @Success 200 {object} codersdk.WorkspaceBuild -// @Router /workspaces/{id}/builds [post] +// @Router /workspaces/{workspace}/builds [post] func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() apiKey := httpmw.APIKey(r) diff --git a/coderd/workspaceresourceauth.go b/coderd/workspaceresourceauth.go index 8da31d1cdd..2ecc48a56a 100644 --- a/coderd/workspaceresourceauth.go +++ b/coderd/workspaceresourceauth.go @@ -23,6 +23,7 @@ import ( // @Summary Authenticate agent on Azure instance // @ID authenticate-agent-on-azure-instance // @Security CoderSessionToken +// @Accept json // @Produce json // @Tags Agents // @Param request body codersdk.AzureInstanceIdentityToken true "Instance identity token" @@ -45,18 +46,19 @@ func (api *API) postWorkspaceAuthAzureInstanceIdentity(rw http.ResponseWriter, r api.handleAuthInstanceID(rw, r, instanceID) } +// AWS supports instance identity verification: +// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html +// Using this, we can exchange a signed instance payload for an agent token. +// // @Summary Authenticate agent on AWS instance // @ID authenticate-agent-on-aws-instance // @Security CoderSessionToken +// @Accept json // @Produce json // @Tags Agents // @Param request body codersdk.AWSInstanceIdentityToken true "Instance identity token" // @Success 200 {object} codersdk.WorkspaceAgentAuthenticateResponse // @Router /workspaceagents/aws-instance-identity [post] -// -// AWS supports instance identity verification: -// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html -// Using this, we can exchange a signed instance payload for an agent token. func (api *API) postWorkspaceAuthAWSInstanceIdentity(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var req codersdk.AWSInstanceIdentityToken @@ -74,18 +76,19 @@ func (api *API) postWorkspaceAuthAWSInstanceIdentity(rw http.ResponseWriter, r * api.handleAuthInstanceID(rw, r, identity.InstanceID) } +// Google Compute Engine supports instance identity verification: +// https://cloud.google.com/compute/docs/instances/verifying-instance-identity +// Using this, we can exchange a signed instance payload for an agent token. +// // @Summary Authenticate agent on Google Cloud instance // @ID authenticate-agent-on-google-cloud-instance // @Security CoderSessionToken +// @Accept json // @Produce json // @Tags Agents // @Param request body codersdk.GoogleInstanceIdentityToken true "Instance identity token" // @Success 200 {object} codersdk.WorkspaceAgentAuthenticateResponse // @Router /workspaceagents/google-instance-identity [post] -// -// Google Compute Engine supports instance identity verification: -// https://cloud.google.com/compute/docs/instances/verifying-instance-identity -// Using this, we can exchange a signed instance payload for an agent token. func (api *API) postWorkspaceAuthGoogleInstanceIdentity(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var req codersdk.GoogleInstanceIdentityToken diff --git a/coderd/workspaces.go b/coderd/workspaces.go index 23242f619f..0f040f783c 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -48,10 +48,10 @@ var ( // @Security CoderSessionToken // @Produce json // @Tags Workspaces -// @Param id path string true "Workspace ID" format(uuid) +// @Param workspace path string true "Workspace ID" format(uuid) // @Param include_deleted query bool false "Return data instead of HTTP 404 if the workspace is deleted" // @Success 200 {object} codersdk.Workspace -// @Router /workspaces/{id} [get] +// @Router /workspaces/{workspace} [get] func (api *API) workspace(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspace := httpmw.WorkspaceParam(r) @@ -101,8 +101,11 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) { )) } +// workspaces returns all workspaces a user can read. +// Optional filters with query params +// // @Summary List workspaces -// @ID get-workspaces +// @ID list-workspaces // @Security CoderSessionToken // @Produce json // @Tags Workspaces @@ -113,9 +116,6 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) { // @Param has_agent query string false "Filter by agent status" Enums(connected,connecting,disconnected,timeout) // @Success 200 {object} codersdk.WorkspacesResponse // @Router /workspaces [get] -// -// workspaces returns all workspaces a user can read. -// Optional filters with query params func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() apiKey := httpmw.APIKey(r) @@ -266,6 +266,8 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request) )) } +// Create a new workspace for the currently authenticated user. +// // @Summary Create user workspace by organization // @ID create-user-workspace-by-organization // @Security CoderSessionToken @@ -275,8 +277,6 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request) // @Param user path string true "Username, UUID, or me" // @Success 200 {object} codersdk.Workspace // @Router /organizations/{organization}/members/{user}/workspaces [post] -// -// Create a new workspace for the currently authenticated user. func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -558,7 +558,6 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req // @ID update-workspace-metadata-by-id // @Security CoderSessionToken // @Accept json -// @Produce json // @Tags Workspaces // @Param workspace path string true "Workspace ID" format(uuid) // @Param request body codersdk.UpdateWorkspaceRequest true "Metadata update request" @@ -648,7 +647,6 @@ func (api *API) patchWorkspace(rw http.ResponseWriter, r *http.Request) { // @ID update-workspace-autostart-schedule-by-id // @Security CoderSessionToken // @Accept json -// @Produce json // @Tags Workspaces // @Param workspace path string true "Workspace ID" format(uuid) // @Param request body codersdk.UpdateWorkspaceAutostartRequest true "Schedule update request" @@ -711,7 +709,6 @@ func (api *API) putWorkspaceAutostart(rw http.ResponseWriter, r *http.Request) { // @ID update-workspace-ttl-by-id // @Security CoderSessionToken // @Accept json -// @Produce json // @Tags Workspaces // @Param workspace path string true "Workspace ID" format(uuid) // @Param request body codersdk.UpdateWorkspaceTTLRequest true "Workspace TTL update request" @@ -875,7 +872,7 @@ func (api *API) putExtendWorkspace(rw http.ResponseWriter, r *http.Request) { } // @Summary Watch workspace by ID -// @ID watch-workspace-id +// @ID watch-workspace-by-id // @Security CoderSessionToken // @Produce text/event-stream // @Tags Workspaces diff --git a/codersdk/audit.go b/codersdk/audit.go index da8f88df04..4ae98466c3 100644 --- a/codersdk/audit.go +++ b/codersdk/audit.go @@ -88,14 +88,14 @@ type AuditDiffField struct { } type AuditLog struct { - ID uuid.UUID `json:"id"` - RequestID uuid.UUID `json:"request_id"` - Time time.Time `json:"time"` - OrganizationID uuid.UUID `json:"organization_id"` + ID uuid.UUID `json:"id" format:"uuid"` + RequestID uuid.UUID `json:"request_id" format:"uuid"` + Time time.Time `json:"time" format:"date-time"` + OrganizationID uuid.UUID `json:"organization_id" format:"uuid"` IP netip.Addr `json:"ip"` UserAgent string `json:"user_agent"` ResourceType ResourceType `json:"resource_type"` - ResourceID uuid.UUID `json:"resource_id"` + ResourceID uuid.UUID `json:"resource_id" format:"uuid"` // ResourceTarget is the name of the resource. ResourceTarget string `json:"resource_target"` ResourceIcon string `json:"resource_icon"` @@ -123,8 +123,8 @@ type AuditLogResponse struct { type CreateTestAuditLogRequest struct { Action AuditAction `json:"action,omitempty" enums:"create,write,delete,start,stop"` ResourceType ResourceType `json:"resource_type,omitempty" enums:"organization,template,template_version,user,workspace,workspace_build,git_ssh_key,api_key,group"` - ResourceID uuid.UUID `json:"resource_id,omitempty"` - Time time.Time `json:"time,omitempty"` + ResourceID uuid.UUID `json:"resource_id,omitempty" format:"uuid"` + Time time.Time `json:"time,omitempty" format:"date-time"` } // AuditLogs retrieves audit logs from the given page. diff --git a/codersdk/organizations.go b/codersdk/organizations.go index 27a30f8a14..1c21f5cc39 100644 --- a/codersdk/organizations.go +++ b/codersdk/organizations.go @@ -67,7 +67,7 @@ type CreateTemplateRequest struct { // This is required on creation to enable a user-flow of validating a // template works. There is no reason the data-model cannot support empty // templates, but it doesn't make sense for users. - VersionID uuid.UUID `json:"template_version_id" validate:"required"` + VersionID uuid.UUID `json:"template_version_id" validate:"required" format:"uuid"` ParameterValues []CreateParameterRequest `json:"parameter_values,omitempty"` // DefaultTTLMillis allows optionally specifying the default TTL @@ -81,7 +81,7 @@ type CreateTemplateRequest struct { // CreateWorkspaceRequest provides options for creating a new workspace. type CreateWorkspaceRequest struct { - TemplateID uuid.UUID `json:"template_id" validate:"required"` + TemplateID uuid.UUID `json:"template_id" validate:"required" format:"uuid"` Name string `json:"name" validate:"workspace_name,required"` AutostartSchedule *string `json:"autostart_schedule"` TTLMillis *int64 `json:"ttl_ms,omitempty"` diff --git a/codersdk/pagination.go b/codersdk/pagination.go index 7e6cf8d1dd..2201277aec 100644 --- a/codersdk/pagination.go +++ b/codersdk/pagination.go @@ -14,7 +14,7 @@ type Pagination struct { // Offset for better performance. To use it as an alternative, // set AfterID to the last UUID returned by the previous // request. - AfterID uuid.UUID `json:"after_id,omitempty"` + AfterID uuid.UUID `json:"after_id,omitempty" format:"uuid"` // Limit sets the maximum number of users to be returned // in a single page. If the limit is <= 0, there is no limit // and all users are returned. diff --git a/codersdk/templates.go b/codersdk/templates.go index bf00bd7e3d..44471a234e 100644 --- a/codersdk/templates.go +++ b/codersdk/templates.go @@ -176,7 +176,7 @@ func (c *Client) UpdateActiveTemplateVersion(ctx context.Context, template uuid. // TemplateVersionsByTemplateRequest defines the request parameters for // TemplateVersionsByTemplate. type TemplateVersionsByTemplateRequest struct { - TemplateID uuid.UUID `json:"template_id" validate:"required"` + TemplateID uuid.UUID `json:"template_id" validate:"required" format:"uuid"` Pagination } @@ -210,7 +210,7 @@ func (c *Client) TemplateVersionByName(ctx context.Context, template uuid.UUID, } type DAUEntry struct { - Date time.Time `json:"date"` + Date time.Time `json:"date" format:"date-time"` Amount int `json:"amount"` } diff --git a/codersdk/workspaces.go b/codersdk/workspaces.go index 75901bc492..3c1f1a8bda 100644 --- a/codersdk/workspaces.go +++ b/codersdk/workspaces.go @@ -47,7 +47,7 @@ type WorkspacesResponse struct { // CreateWorkspaceBuildRequest provides options to update the latest workspace build. type CreateWorkspaceBuildRequest struct { - TemplateVersionID uuid.UUID `json:"template_version_id,omitempty"` + TemplateVersionID uuid.UUID `json:"template_version_id,omitempty" format:"uuid"` Transition WorkspaceTransition `json:"transition" validate:"oneof=create start stop delete,required"` DryRun bool `json:"dry_run,omitempty"` ProvisionerState []byte `json:"state,omitempty"` @@ -245,7 +245,7 @@ func (c *Client) UpdateWorkspaceTTL(ctx context.Context, id uuid.UUID, req Updat // PutExtendWorkspaceRequest is a request to extend the deadline of // the active workspace build. type PutExtendWorkspaceRequest struct { - Deadline time.Time `json:"deadline" validate:"required"` + Deadline time.Time `json:"deadline" validate:"required" format:"date-time"` } // PutExtendWorkspace updates the deadline for resources of the latest workspace build. diff --git a/docs/api/agents.md b/docs/api/agents.md index dbbbe61c8d..e53421a6ee 100644 --- a/docs/api/agents.md +++ b/docs/api/agents.md @@ -142,7 +142,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/google-instance-ide To perform this operation, you must be authenticated. [Learn more](authentication.md). -## Submit workspace application health +## Submit workspace agent application health ### Code samples @@ -437,3 +437,271 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/me/report-stats \ | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.AgentStatsResponse](schemas.md#codersdkagentstatsresponse) | To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Get workspace agent by ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspaceagents/{workspaceagent}` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------------ | -------- | ------------------ | +| `workspaceagent` | path | string(uuid) | true | Workspace agent ID | + +### Example responses + +> 200 Response + +```json +{ + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "instance_id": "string", + "last_connected_at": "2019-08-24T14:15:22Z", + "latency": { + "property1": { + "latency_ms": 0, + "preferred": true + }, + "property2": { + "latency_ms": 0, + "preferred": true + } + }, + "name": "string", + "operating_system": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "startup_script": "string", + "status": "connecting", + "troubleshooting_url": "string", + "updated_at": "2019-08-24T14:15:22Z", + "version": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgent](schemas.md#codersdkworkspaceagent) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Get connection info for workspace agent + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/connection \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspaceagents/{workspaceagent}/connection` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------------ | -------- | ------------------ | +| `workspaceagent` | path | string(uuid) | true | Workspace agent ID | + +### Example responses + +> 200 Response + +```json +{ + "derp_map": { + "omitDefaultRegions": true, + "regions": { + "property1": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + } + ], + "regionCode": "string", + "regionID": 0, + "regionName": "string" + }, + "property2": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + } + ], + "regionCode": "string", + "regionID": 0, + "regionName": "string" + } + } + } +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentConnectionInfo](schemas.md#codersdkworkspaceagentconnectioninfo) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Coordinate workspace agent + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/coordinate \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspaceagents/{workspaceagent}/coordinate` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------------ | -------- | ------------------ | +| `workspaceagent` | path | string(uuid) | true | Workspace agent ID | + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------------------ | ------------------- | ------ | +| 101 | [Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) | Switching Protocols | | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Get listening ports for workspace agent + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/listening-ports \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspaceagents/{workspaceagent}/listening-ports` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------------ | -------- | ------------------ | +| `workspaceagent` | path | string(uuid) | true | Workspace agent ID | + +### Example responses + +> 200 Response + +```json +{ + "ports": [ + { + "network": "tcp", + "port": 0, + "process_name": "string" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.ListeningPortsResponse](schemas.md#codersdklisteningportsresponse) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Open PTY to workspace agent + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/pty \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspaceagents/{workspaceagent}/pty` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------------ | -------- | ------------------ | +| `workspaceagent` | path | string(uuid) | true | Workspace agent ID | + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------------------ | ------------------- | ------ | +| 101 | [Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) | Switching Protocols | | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). diff --git a/docs/api/audit.md b/docs/api/audit.md index 743807ee32..22ddec0b69 100644 --- a/docs/api/audit.md +++ b/docs/api/audit.md @@ -47,18 +47,18 @@ curl -X GET http://coder-server:8080/api/v2/audit?q=string \ "secret": true } }, - "id": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "ip": "string", "is_deleted": true, - "organization_id": "string", - "request_id": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", "resource_icon": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "resource_link": "string", "resource_target": "string", "resource_type": "organization", "status_code": 0, - "time": "string", + "time": "2019-08-24T14:15:22Z", "user": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", @@ -108,9 +108,9 @@ curl -X POST http://coder-server:8080/api/v2/audit/testgenerate \ ```json { "action": "create", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "resource_type": "organization", - "time": "string" + "time": "2019-08-24T14:15:22Z" } ``` diff --git a/docs/api/builds.md b/docs/api/builds.md index d69028c041..77e7f666b8 100644 --- a/docs/api/builds.md +++ b/docs/api/builds.md @@ -740,22 +740,22 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/workspaces/{id}/builds \ +curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /workspaces/{id}/builds` +`GET /workspaces/{workspace}/builds` ### Parameters -| Name | In | Type | Required | Description | -| ---------- | ----- | ----------------- | -------- | --------------- | -| `id` | path | string(uuid) | true | Workspace ID | -| `after_id` | query | string(uuid) | false | After ID | -| `limit` | query | integer | false | Page limit | -| `offset` | query | integer | false | Page offset | -| `since` | query | string(date-time) | false | Since timestamp | +| Name | In | Type | Required | Description | +| ----------- | ----- | ----------------- | -------- | --------------- | +| `workspace` | path | string(uuid) | true | Workspace ID | +| `after_id` | query | string(uuid) | false | After ID | +| `limit` | query | integer | false | Page limit | +| `offset` | query | integer | false | Page offset | +| `since` | query | string(date-time) | false | Since timestamp | ### Example responses @@ -1019,13 +1019,13 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X POST http://coder-server:8080/api/v2/workspaces/{id}/builds \ +curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`POST /workspaces/{id}/builds` +`POST /workspaces/{workspace}/builds` > Body parameter @@ -1043,17 +1043,17 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{id}/builds \ } ], "state": [0], - "template_version_id": "string", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "transition": "create" } ``` ### Parameters -| Name | In | Type | Required | Description | -| ------ | ---- | -------------------------------------------------------------------------------------- | -------- | ------------------------------ | -| `id` | path | string(uuid) | true | Workspace ID | -| `body` | body | [codersdk.CreateWorkspaceBuildRequest](schemas.md#codersdkcreateworkspacebuildrequest) | true | Create workspace build request | +| Name | In | Type | Required | Description | +| ----------- | ---- | -------------------------------------------------------------------------------------- | -------- | ------------------------------ | +| `workspace` | path | string(uuid) | true | Workspace ID | +| `body` | body | [codersdk.CreateWorkspaceBuildRequest](schemas.md#codersdkcreateworkspacebuildrequest) | true | Create workspace build request | ### Example responses diff --git a/docs/api/enterprise.md b/docs/api/enterprise.md index b6df74df03..55296663c5 100644 --- a/docs/api/enterprise.md +++ b/docs/api/enterprise.md @@ -242,18 +242,18 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/groups/{groupName} \ +curl -X GET http://coder-server:8080/api/v2/groups/{group} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /groups/{groupName}` +`GET /groups/{group}` ### Parameters -| Name | In | Type | Required | Description | -| ----------- | ---- | ------ | -------- | ----------- | -| `groupName` | path | string | true | Group name | +| Name | In | Type | Required | Description | +| ------- | ---- | ------ | -------- | ----------- | +| `group` | path | string | true | Group name | ### Example responses @@ -295,29 +295,121 @@ curl -X GET http://coder-server:8080/api/v2/groups/{groupName} \ To perform this operation, you must be authenticated. [Learn more](authentication.md). -## Delete license +## Delete group by name ### Code samples ```shell # Example request using curl -curl -X DELETE http://coder-server:8080/api/v2/license/{id} \ +curl -X DELETE http://coder-server:8080/api/v2/groups/{group} \ + -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`DELETE /license/{id}` +`DELETE /groups/{group}` ### Parameters -| Name | In | Type | Required | Description | -| ---- | ---- | -------------- | -------- | ----------- | -| `id` | path | string(number) | true | License ID | +| Name | In | Type | Required | Description | +| ------- | ---- | ------ | -------- | ----------- | +| `group` | path | string | true | Group name | + +### Example responses + +> 200 Response + +```json +{ + "avatar_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string" + } + ], + "status": "active", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0 +} +``` ### Responses -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | ------ | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | | +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Group](schemas.md#codersdkgroup) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Update group by name + +### Code samples + +```shell +# Example request using curl +curl -X PATCH http://coder-server:8080/api/v2/groups/{group} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PATCH /groups/{group}` + +### Parameters + +| Name | In | Type | Required | Description | +| ------- | ---- | ------ | -------- | ----------- | +| `group` | path | string | true | Group name | + +### Example responses + +> 200 Response + +```json +{ + "avatar_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string" + } + ], + "status": "active", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0 +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Group](schemas.md#codersdkgroup) | To perform this operation, you must be authenticated. [Learn more](authentication.md). @@ -369,6 +461,32 @@ Status Code **200** To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Delete license + +### Code samples + +```shell +# Example request using curl +curl -X DELETE http://coder-server:8080/api/v2/licenses/{id} \ + -H 'Coder-Session-Token: API_KEY' +``` + +`DELETE /licenses/{id}` + +### Parameters + +| Name | In | Type | Required | Description | +| ---- | ---- | -------------- | -------- | ----------- | +| `id` | path | string(number) | true | License ID | + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Get groups by organization ### Code samples @@ -462,6 +580,66 @@ Status Code **200** To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Get group by organization and group name + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/groups/{groupName} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /organizations/{organization}/groups/{groupName}` + +### Parameters + +| Name | In | Type | Required | Description | +| -------------- | ---- | ------------ | -------- | --------------- | +| `organization` | path | string(uuid) | true | Organization ID | +| `groupName` | path | string | true | Group name | + +### Example responses + +> 200 Response + +```json +{ + "avatar_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string" + } + ], + "status": "active", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0 +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Group](schemas.md#codersdkgroup) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Get provisioner daemons ### Code samples @@ -609,6 +787,26 @@ Status Code **200** To perform this operation, you must be authenticated. [Learn more](authentication.md). +## SCIM 2.0: Get users + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/scim/v2/Users \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /scim/v2/Users` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## SCIM 2.0: Create new user ### Code samples diff --git a/docs/api/schemas.md b/docs/api/schemas.md index a4d497a05c..cb36333e07 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -323,18 +323,18 @@ "secret": true } }, - "id": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "ip": "string", "is_deleted": true, - "organization_id": "string", - "request_id": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", "resource_icon": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "resource_link": "string", "resource_target": "string", "resource_type": "organization", "status_code": 0, - "time": "string", + "time": "2019-08-24T14:15:22Z", "user": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", @@ -399,18 +399,18 @@ "secret": true } }, - "id": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "ip": "string", "is_deleted": true, - "organization_id": "string", - "request_id": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", "resource_icon": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "resource_link": "string", "resource_target": "string", "resource_type": "organization", "status_code": 0, - "time": "string", + "time": "2019-08-24T14:15:22Z", "user": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", @@ -731,7 +731,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a "source_value": "string" } ], - "template_version_id": "string" + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1" } ``` @@ -778,9 +778,9 @@ CreateParameterRequest is a structure used to create a new parameter value for a ```json { "action": "create", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "resource_type": "organization", - "time": "string" + "time": "2019-08-24T14:15:22Z" } ``` @@ -871,7 +871,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a } ], "state": [0], - "template_version_id": "string", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", "transition": "create" } ``` @@ -901,7 +901,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a ```json { "amount": 0, - "date": "string" + "date": "2019-08-24T14:15:22Z" } ``` @@ -2561,6 +2561,58 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `uploaded_at` | string | false | | | | `uuid` | string | false | | | +## codersdk.ListeningPort + +```json +{ + "network": "tcp", + "port": 0, + "process_name": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------------- | -------------------------------------------------------------- | -------- | ------------ | ------------------------ | +| `network` | [codersdk.ListeningPortNetwork](#codersdklisteningportnetwork) | false | | only "tcp" at the moment | +| `port` | integer | false | | | +| `process_name` | string | false | | may be empty | + +## codersdk.ListeningPortNetwork + +```json +"tcp" +``` + +### Properties + +#### Enumerated Values + +| Value | +| ----- | +| `tcp` | + +## codersdk.ListeningPortsResponse + +```json +{ + "ports": [ + { + "network": "tcp", + "port": 0, + "process_name": "string" + } + ] +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------- | --------------------------------------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `ports` | array of [codersdk.ListeningPort](#codersdklisteningport) | false | | If there are no ports in the list, nothing should be displayed in the UI. There must not be a "no ports available" message or anything similar, as there will always be no ports displayed on platforms where our port detection logic is unsupported. | + ## codersdk.LogLevel ```json @@ -3463,7 +3515,7 @@ Parameter represents a set value for the scope. ```json { - "deadline": "string" + "deadline": "2019-08-24T14:15:22Z" } ``` @@ -3907,7 +3959,7 @@ Parameter represents a set value for the scope. "entries": [ { "amount": 0, - "date": "string" + "date": "2019-08-24T14:15:22Z" } ] } @@ -4617,6 +4669,70 @@ Parameter represents a set value for the scope. | --------------- | ------ | -------- | ------------ | ----------- | | `session_token` | string | false | | | +## codersdk.WorkspaceAgentConnectionInfo + +```json +{ + "derp_map": { + "omitDefaultRegions": true, + "regions": { + "property1": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + } + ], + "regionCode": "string", + "regionID": 0, + "regionName": "string" + }, + "property2": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + } + ], + "regionCode": "string", + "regionID": 0, + "regionName": "string" + } + } + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------- | ---------------------------------- | -------- | ------------ | ----------- | +| `derp_map` | [tailcfg.DERPMap](#tailcfgderpmap) | false | | | + ## codersdk.WorkspaceAgentGitAuthResponse ```json diff --git a/docs/api/templates.md b/docs/api/templates.md index dc29086ca6..268bd91d56 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -204,7 +204,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa "source_value": "string" } ], - "template_version_id": "string" + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1" } ``` @@ -630,18 +630,18 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templates/{id} \ +curl -X GET http://coder-server:8080/api/v2/templates/{template} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /templates/{id}` +`GET /templates/{template}` ### Parameters -| Name | In | Type | Required | Description | -| ---- | ---- | ------------ | -------- | ----------- | -| `id` | path | string(uuid) | true | Template ID | +| Name | In | Type | Required | Description | +| ---------- | ---- | ------------ | -------- | ----------- | +| `template` | path | string(uuid) | true | Template ID | ### Example responses @@ -692,18 +692,18 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X DELETE http://coder-server:8080/api/v2/templates/{id} \ +curl -X DELETE http://coder-server:8080/api/v2/templates/{template} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`DELETE /templates/{id}` +`DELETE /templates/{template}` ### Parameters -| Name | In | Type | Required | Description | -| ---- | ---- | ------------ | -------- | ----------- | -| `id` | path | string(uuid) | true | Template ID | +| Name | In | Type | Required | Description | +| ---------- | ---- | ------------ | -------- | ----------- | +| `template` | path | string(uuid) | true | Template ID | ### Example responses @@ -736,18 +736,18 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X PATCH http://coder-server:8080/api/v2/templates/{id} \ +curl -X PATCH http://coder-server:8080/api/v2/templates/{template} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`PATCH /templates/{id}` +`PATCH /templates/{template}` ### Parameters -| Name | In | Type | Required | Description | -| ---- | ---- | ------------ | -------- | ----------- | -| `id` | path | string(uuid) | true | Template ID | +| Name | In | Type | Required | Description | +| ---------- | ---- | ------------ | -------- | ----------- | +| `template` | path | string(uuid) | true | Template ID | ### Example responses @@ -798,18 +798,18 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templates/{id}/daus \ +curl -X GET http://coder-server:8080/api/v2/templates/{template}/daus \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /templates/{id}/daus` +`GET /templates/{template}/daus` ### Parameters -| Name | In | Type | Required | Description | -| ---- | ---- | ------------ | -------- | ----------- | -| `id` | path | string(uuid) | true | Template ID | +| Name | In | Type | Required | Description | +| ---------- | ---- | ------------ | -------- | ----------- | +| `template` | path | string(uuid) | true | Template ID | ### Example responses @@ -820,7 +820,7 @@ curl -X GET http://coder-server:8080/api/v2/templates/{id}/daus \ "entries": [ { "amount": 0, - "date": "string" + "date": "2019-08-24T14:15:22Z" } ] } @@ -840,18 +840,18 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templates/{id}/versions \ +curl -X GET http://coder-server:8080/api/v2/templates/{template}/versions \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /templates/{id}/versions` +`GET /templates/{template}/versions` ### Parameters | Name | In | Type | Required | Description | | ---------- | ----- | ------------ | -------- | ----------- | -| `id` | path | string(uuid) | true | Template ID | +| `template` | path | string(uuid) | true | Template ID | | `after_id` | query | string(uuid) | false | After ID | | `limit` | query | integer | false | Page limit | | `offset` | query | integer | false | Page offset | @@ -971,13 +971,13 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X PATCH http://coder-server:8080/api/v2/templates/{id}/versions \ +curl -X PATCH http://coder-server:8080/api/v2/templates/{template}/versions \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`PATCH /templates/{id}/versions` +`PATCH /templates/{template}/versions` > Body parameter @@ -989,10 +989,10 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{id}/versions \ ### Parameters -| Name | In | Type | Required | Description | -| ------ | ---- | -------------------------------------------------------------------------------------- | -------- | ------------------------- | -| `id` | path | string(uuid) | true | Template ID | -| `body` | body | [codersdk.UpdateActiveTemplateVersion](schemas.md#codersdkupdateactivetemplateversion) | true | Modified template version | +| Name | In | Type | Required | Description | +| ---------- | ---- | -------------------------------------------------------------------------------------- | -------- | ------------------------- | +| `template` | path | string(uuid) | true | Template ID | +| `body` | body | [codersdk.UpdateActiveTemplateVersion](schemas.md#codersdkupdateactivetemplateversion) | true | Modified template version | ### Example responses @@ -1025,18 +1025,18 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templates/{id}/versions/{templateversionname} \ +curl -X GET http://coder-server:8080/api/v2/templates/{template}/versions/{templateversionname} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /templates/{id}/versions/{templateversionname}` +`GET /templates/{template}/versions/{templateversionname}` ### Parameters | Name | In | Type | Required | Description | | --------------------- | ---- | ------------ | -------- | --------------------- | -| `id` | path | string(uuid) | true | Template ID | +| `template` | path | string(uuid) | true | Template ID | | `templateversionname` | path | string | true | Template version name | ### Example responses @@ -1340,19 +1340,19 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobid} \ +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobID} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /templateversions/{templateversion}/dry-run/{jobid}` +`GET /templateversions/{templateversion}/dry-run/{jobID}` ### Parameters | Name | In | Type | Required | Description | | ----------------- | ---- | ------------ | -------- | ------------------- | | `templateversion` | path | string(uuid) | true | Template version ID | -| `jobid` | path | string(uuid) | true | Job ID | +| `jobID` | path | string(uuid) | true | Job ID | ### Example responses @@ -1390,17 +1390,18 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobid}/cancel \ +curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobID}/cancel \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`PATCH /templateversions/{templateversion}/dry-run/{jobid}/cancel` +`PATCH /templateversions/{templateversion}/dry-run/{jobID}/cancel` ### Parameters | Name | In | Type | Required | Description | | ----------------- | ---- | ------------ | -------- | ------------------- | +| `jobID` | path | string(uuid) | true | Job ID | | `templateversion` | path | string(uuid) | true | Template version ID | ### Example responses @@ -1434,19 +1435,19 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobid}/logs \ +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobID}/logs \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /templateversions/{templateversion}/dry-run/{jobid}/logs` +`GET /templateversions/{templateversion}/dry-run/{jobID}/logs` ### Parameters | Name | In | Type | Required | Description | | ----------------- | ----- | ------------ | -------- | --------------------- | | `templateversion` | path | string(uuid) | true | Template version ID | -| `jobid` | path | string(uuid) | true | Job ID | +| `jobID` | path | string(uuid) | true | Job ID | | `before` | query | integer | false | Before Unix timestamp | | `after` | query | integer | false | After Unix timestamp | | `follow` | query | boolean | false | Follow log stream | @@ -1508,19 +1509,19 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobid}/resources \ +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobID}/resources \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /templateversions/{templateversion}/dry-run/{jobid}/resources` +`GET /templateversions/{templateversion}/dry-run/{jobID}/resources` ### Parameters | Name | In | Type | Required | Description | | ----------------- | ---- | ------------ | -------- | ------------------- | | `templateversion` | path | string(uuid) | true | Template version ID | -| `jobid` | path | string(uuid) | true | Job ID | +| `jobID` | path | string(uuid) | true | Job ID | ### Example responses diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index c97140e001..a977d43936 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -511,18 +511,18 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/workspaces/{id} \ +curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /workspaces/{id}` +`GET /workspaces/{workspace}` ### Parameters | Name | In | Type | Required | Description | | ----------------- | ----- | ------------ | -------- | ----------------------------------------------------------- | -| `id` | path | string(uuid) | true | Workspace ID | +| `workspace` | path | string(uuid) | true | Workspace ID | | `include_deleted` | query | boolean | false | Return data instead of HTTP 404 if the workspace is deleted | ### Example responses @@ -755,7 +755,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/extend \ ```json { - "deadline": "string" + "deadline": "2019-08-24T14:15:22Z" } ``` diff --git a/enterprise/coderd/appearance.go b/enterprise/coderd/appearance.go index fef1c2ff5e..e60e7a2ed5 100644 --- a/enterprise/coderd/appearance.go +++ b/enterprise/coderd/appearance.go @@ -84,6 +84,7 @@ func validateHexColor(color string) error { // @Summary Update appearance // @ID update-appearance // @Security CoderSessionToken +// @Accept json // @Produce json // @Tags Enterprise // @Param request body codersdk.AppearanceConfig true "Update appearance request" diff --git a/enterprise/coderd/coderd.go b/enterprise/coderd/coderd.go index 32184e43cd..4c0f9eb2a0 100644 --- a/enterprise/coderd/coderd.go +++ b/enterprise/coderd/coderd.go @@ -87,7 +87,7 @@ func New(ctx context.Context, options *Options) (*API, error) { httpmw.ExtractGroupByNameParam(api.Database), ) - r.Get("/", api.group) + r.Get("/", api.groupByOrganization) }) }) r.Route("/organizations/{organization}/provisionerdaemons", func(r chi.Router) { diff --git a/enterprise/coderd/coderdenttest/swagger_test.go b/enterprise/coderd/coderdenttest/swagger_test.go new file mode 100644 index 0000000000..c4ad0a8dd5 --- /dev/null +++ b/enterprise/coderd/coderdenttest/swagger_test.go @@ -0,0 +1,20 @@ +package coderdenttest_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/coder/coder/coderd/coderdtest" + "github.com/coder/coder/enterprise/coderd/coderdenttest" +) + +func TestEnterpriseEndpointsDocumented(t *testing.T) { + t.Parallel() + + swaggerComments, err := coderdtest.ParseSwaggerComments("..", "../../../coderd") + require.NoError(t, err, "can't parse swagger comments") + + _, _, api := coderdenttest.NewWithAPI(t, nil) + coderdtest.VerifySwaggerDefinitions(t, api.AGPL.APIHandler, swaggerComments) +} diff --git a/enterprise/coderd/groups.go b/enterprise/coderd/groups.go index ce0f92fc22..288ae94836 100644 --- a/enterprise/coderd/groups.go +++ b/enterprise/coderd/groups.go @@ -80,6 +80,14 @@ func (api *API) postGroupByOrganization(rw http.ResponseWriter, r *http.Request) httpapi.Write(ctx, rw, http.StatusCreated, convertGroup(group, nil)) } +// @Summary Update group by name +// @ID update-group-by-name +// @Security CoderSessionToken +// @Produce json +// @Tags Enterprise +// @Param group path string true "Group name" +// @Success 200 {object} codersdk.Group +// @Router /groups/{group} [patch] func (api *API) patchGroup(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -236,6 +244,14 @@ func (api *API) patchGroup(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, convertGroup(group, members)) } +// @Summary Delete group by name +// @ID delete-group-by-name +// @Security CoderSessionToken +// @Produce json +// @Tags Enterprise +// @Param group path string true "Group name" +// @Success 200 {object} codersdk.Group +// @Router /groups/{group} [delete] func (api *API) deleteGroup(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -274,14 +290,27 @@ func (api *API) deleteGroup(rw http.ResponseWriter, r *http.Request) { }) } +// @Summary Get group by organization and group name +// @ID get-group-by-organization-and-group-name +// @Security CoderSessionToken +// @Produce json +// @Tags Enterprise +// @Param organization path string true "Organization ID" format(uuid) +// @Param groupName path string true "Group name" +// @Success 200 {object} codersdk.Group +// @Router /organizations/{organization}/groups/{groupName} [get] +func (api *API) groupByOrganization(rw http.ResponseWriter, r *http.Request) { + api.group(rw, r) +} + // @Summary Get group by name // @ID get-group-by-name // @Security CoderSessionToken // @Produce json // @Tags Enterprise -// @Param groupName path string true "Group name" +// @Param group path string true "Group name" // @Success 200 {object} codersdk.Group -// @Router /groups/{groupName} [get] +// @Router /groups/{group} [get] func (api *API) group(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/enterprise/coderd/licenses.go b/enterprise/coderd/licenses.go index 0ef3a564f9..ef3f6c9d44 100644 --- a/enterprise/coderd/licenses.go +++ b/enterprise/coderd/licenses.go @@ -52,6 +52,7 @@ var Keys = map[string]ed25519.PublicKey{"2022-08-12": ed25519.PublicKey(key20220 // @Summary Add new license // @ID add-new-license // @Security CoderSessionToken +// @Accept json // @Produce json // @Tags Organizations // @Param request body codersdk.AddLicenseRequest true "Add license request" @@ -178,7 +179,7 @@ func (api *API) licenses(rw http.ResponseWriter, r *http.Request) { // @Tags Enterprise // @Param id path string true "License ID" format(number) // @Success 200 -// @Router /license/{id} [delete] +// @Router /licenses/{id} [delete] func (api *API) deleteLicense(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() if !api.AGPL.Authorize(r, rbac.ActionDelete, rbac.ResourceLicense) { diff --git a/enterprise/coderd/provisionerdaemons.go b/enterprise/coderd/provisionerdaemons.go index d49a96ab13..cbf15787a3 100644 --- a/enterprise/coderd/provisionerdaemons.go +++ b/enterprise/coderd/provisionerdaemons.go @@ -94,7 +94,6 @@ func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) { // @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 diff --git a/enterprise/coderd/scim.go b/enterprise/coderd/scim.go index b72486fb28..8912c3fafa 100644 --- a/enterprise/coderd/scim.go +++ b/enterprise/coderd/scim.go @@ -49,7 +49,7 @@ func (api *API) scimVerifyAuthHeader(r *http.Request) bool { // @Produce application/scim+json // @Tags Enterprise // @Success 200 -// @Router /scim/v2/Users [post] +// @Router /scim/v2/Users [get] // //nolint:revive func (api *API) scimGetUsers(rw http.ResponseWriter, r *http.Request) { diff --git a/enterprise/coderd/templates.go b/enterprise/coderd/templates.go index 397101c51f..961ee09f0b 100644 --- a/enterprise/coderd/templates.go +++ b/enterprise/coderd/templates.go @@ -103,6 +103,7 @@ func (api *API) templateACL(rw http.ResponseWriter, r *http.Request) { // @Summary Update template ACL // @ID update-template-acl // @Security CoderSessionToken +// @Accept json // @Produce json // @Tags Enterprise // @Param template path string true "Template ID" format(uuid)